image_sorting/modify_mtime.py

116 lines
4.9 KiB
Python
Executable File

#!/usr/bin/python3
"""
This helper script will change the modify date (mtime) of all files of the cwd by a given amount of time.
Copyright (C) 2024 Benjamin Burkhardt
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
"""
Useful links:
- https://docs.python.org/3/library/argparse.html#argparse-type
- https://stackoverflow.com/questions/4541629/how-to-create-a-datetime-equal-to-15-minutes-ago
- https://docs.python.org/3/library/datetime.html
- https://www.tutorialspoint.com/How-to-get-file-creation-and-modification-date-times-in-Python
- https://docs.python.org/3/library/os.html#os.utime
- https://de.wikipedia.org/wiki/Modification,_Access,_Change
- https://en.wikipedia.org/wiki/Unit_prefix
"""
import argparse
import datetime
import os
# create a list named all_files with absolute paths of all files of the cwd
all_files = os.listdir()
# set up the ArgumentParser for the CLI
parser = argparse.ArgumentParser(
description='modify_mtime.py Copyright (C) 2024 Benjamin Burkhardt\r\n'
'This program comes with ABSOLUTELY NO WARRANTY and is licensed under the '
'GNU General Public License 3.\r\n'
'You should have received a copy of the GNU General Public License\r\n'
'along with this program. If not, see <https://www.gnu.org/licenses/>.\r\n'
'\r\n'
'This helper script will change the modify date (mtime) of all files of the cwd by a '
'given amount of time.\r\n'
'The time arguments shall be given as positive or negative integers.\r\n'
'BE AWARE THAT ALL CHANGES TO THE FILES CANNOT BE UNDONE! USE AT YOUR OWN RISK!',
epilog='by Benjamin Burkhardt, 2024',
add_help=False,
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-mus', '--microseconds', type=int, default=0)
parser.add_argument('-ms', '--milliseconds', type=int, default=0)
parser.add_argument('-s', '--seconds', type=int, default=0)
parser.add_argument('-m', '--minutes', type=int, default=0)
parser.add_argument('-h', '--hours', type=int, default=0)
parser.add_argument('-d', '--days', type=int, default=0, help='one day consists of exactly 24 hours')
parser.add_argument('-y', '--years', type=int, default=0, help='one year = 365 days')
parser.add_argument('-v', '--verbose', action='store_true', help='enable verbose output') # on/off flag
parser.add_argument('--help', action='store_true', help='display this help message and exit') # on/off flag
# parse given arguments
args = parser.parse_args()
# print help and exit if prompted to
if args.help:
parser.print_help()
exit(0)
# calculate the time to alter the mtime of all files (in microseconds)
alter_time = args.microseconds
alter_time += args.milliseconds * 1000
alter_time += args.seconds * 1000 * 1000
alter_time += args.minutes * 1000 * 1000 * 60
alter_time += args.hours * 1000 * 1000 * 60 * 60
alter_time += args.days * 1000 * 1000 * 60 * 60 * 24
alter_time += args.years * 1000 * 1000 * 60 * 60 * 24 * 365
alter_timedelta = datetime.timedelta(microseconds=alter_time) # convert to timedelta format
# log the alter_time in verbose mode
if args.verbose:
print(f'[DEBUG] Calculated time to alter all files in cwd: {alter_time}µs | alter_time = {alter_timedelta}')
# log start of the manipulation process in verbose mode
if args.verbose:
print(f'[DEBUG] Starting the mtime manipulation process')
for file_path in all_files:
# get all timestamps
file_stinfo = os.stat(file_path)
atime_timestamp_old = file_stinfo.st_atime
mtime_timestamp_old = file_stinfo.st_mtime
# calculate the new mtime timestamp
mtime_datetime_old = datetime.datetime.fromtimestamp(mtime_timestamp_old) # get the current modified date
mtime_datetime_new = mtime_datetime_old + alter_timedelta
mtime_timestamp_new = mtime_datetime_new.timestamp()
# set the new mtime (atime stays unchanged)
os.utime(file_path, (atime_timestamp_old, mtime_timestamp_new))
if args.verbose:
longest_filename_len = max([len(f) for f in all_files])
if mtime_timestamp_old == mtime_timestamp_new:
print(f'{file_path.ljust(longest_filename_len + 1)}: mtime timestamp left unchanged')
else:
print(
f'{file_path}: mtime timestamp changed from {mtime_timestamp_old} -> {mtime_timestamp_new}'
f' ({mtime_datetime_old} -> {mtime_datetime_new})'
)