Compare commits

..

4 Commits

Author SHA1 Message Date
1c0532a7af Added the helper to the README.md 2024-09-02 23:03:09 +02:00
3e5bc7721d Added new script to set an absolute mtime to a specific file 2024-09-02 23:01:51 +02:00
c5cc433e2f Added script to README.md 2024-08-14 17:26:33 +02:00
e716611863 Added new script 2024-08-14 17:24:51 +02:00
3 changed files with 178 additions and 5 deletions

View File

@@ -12,6 +12,8 @@ Be careful! Some of the scripts in here do changes that are irrevertible. Make s
- `mtime2exifcreatedate.sh`: iterates over all files in a directory (every!) and (over-)writes the EXIF `CreateDate` tag to the modification time of the file
- `modify_mtime.py`: changes the modify date (mtime) of all files of the cwd by a given amount of time
- `filename2mtime.py`: extract a date and time from the name of all files in a directory and set their respective UNIX mtime (the modified timestamp).
- `set_mtime.py`: sets the modify date (mtime) of a selected file
## LICENSE

View File

@@ -30,8 +30,9 @@ Useful links:
from datetime import datetime
from argparse import ArgumentParser, RawTextHelpFormatter
import os
import sys
# define some shell color codes
class COLORS:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
@@ -43,6 +44,16 @@ class COLORS:
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
class LOGGER:
def __init__(self, verbose: bool = False):
self.verbose = verbose
def log(self, to_log, verbose=False, end="\n"):
to_log = to_log + COLORS.ENDC
if (self.verbose and verbose) or not verbose: # only print if it's not verbose or verbose is enabled
print(to_log, end=end)
# set up the ArgumentParser for the CLI
parser = ArgumentParser(
description='filename2mtime.py Copyright (C) 2024 Benjamin Burkhardt\r\n'
@@ -53,20 +64,62 @@ parser = ArgumentParser(
'\r\n'
'This helper script is able to extract a date and time from the name of all \r\n'
'files in a directory and set their respective UNIX mtime (the modified timestamp).\r\n'
'BE AWARE THAT ALL CHANGES TO THE FILES CANNOT BE UNDONE! USE AT YOUR OWN RISK!',
'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=RawTextHelpFormatter)
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
parser.add_argument('-f', '--format', type=str, default="", help="give the format of the strings\r\nsee https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior for more details")
parser.add_argument('-e', '--format-error-exit', action='store_true', default=False, help='exit if the format does not fit to one file') # on/off flag
parser.add_argument('-v', '--verbose', action='store_true', default=False, help='enable verbose output') # on/off flag
parser.add_argument('-h', '--help', action='store_true', default=False, 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:
if args.help or not len(sys.argv) > 1:
parser.print_help()
exit(0)
# set up logger
logger = LOGGER(args.verbose)
# check for an empty format
if args.format == '' and not args.auto_format:
logger.log(COLORS.FAIL + 'You need to specify a format.')
parser.print_usage()
exit(1)
# Start of the real program, format is surely set
all_files = os.listdir()
parsed_datetimes = {}
longest_filename_len = max([len(f) for f in all_files])
for f in all_files:
try:
parsed_datetimes[f] = datetime.strptime(f, args.format)
logger.log(f"Detecting: {f} -> {parsed_datetimes[f]}", verbose=True)
except ValueError:
if args.format_error_exit:
logger.log(f"{COLORS.WARNING}{f.ljust(longest_filename_len + 1)}: Failed to parse the date and time.")
logger.log(f"{COLORS.FAIL}EXITING (as -e flag was set)!")
exit(1)
else:
logger.log(f"{f.ljust(longest_filename_len + 1)}: {COLORS.WARNING}Failed to parse the date and time.")
for f, dt in parsed_datetimes.items():
# get atime timestamp (as os.utime requires this as an argument - we leave it unchanged)
atime_timestamp = os.stat(f).st_atime
# get the mtime timestamp from the respective datetime object
mtime_timestamp = dt.timestamp()
# set the new mtime (atime stays unchanged)
os.utime(f, (atime_timestamp, mtime_timestamp))

118
set_mtime.py Executable file
View File

@@ -0,0 +1,118 @@
#!/usr/bin/python3
"""
This helper script will set the modify date (mtime) of a selected file.
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://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
class COLORS:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
class LOGGER:
def __init__(self, verbose: bool = False):
self.verbose = verbose
def log(self, to_log, verbose=False, end="\n"):
to_log = to_log + COLORS.ENDC
if (self.verbose and verbose) or not verbose: # only print if it's not verbose or verbose is enabled
print(to_log, end=end)
# 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 set the modify date (mtime) of a selected file.\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('-f', '--file', type=str, default='')
parser.add_argument('-mus', '--microsecond', type=int, default=0)
parser.add_argument('-ms', '--millisecond', type=int, default=0)
parser.add_argument('-s', '--second', type=int, default=0)
parser.add_argument('-m', '--minute', type=int, default=0)
parser.add_argument('-h', '--hour', type=int, default=0)
parser.add_argument('-d', '--day', type=int, default=0, help='REQUIRED')
parser.add_argument('-mo', '--month', type=int, default=0, help='REQUIRED')
parser.add_argument('-y', '--year', type=int, default=0, help='REQUIRED')
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()
# set up logger
logger = LOGGER(args.verbose)
# print help and exit if prompted to
if args.help:
parser.print_help()
exit(0)
# check for an empty filename argument
if args.file == '':
logger.log(COLORS.FAIL + 'You need to specify a filename to set the modification time of it.')
parser.print_usage()
exit(1)
# check for missing year, month or day args
if args.year == 0 or args.month == 0 or args.day == 0:
logger.log(COLORS.FAIL + 'You need to give at least the --year, --month and --day arguments!')
parser.print_usage()
exit(1)
# create the datetime object with the given date
new_absolute_time = datetime.datetime(year=args.year, month=args.month, day=args.day, hour=args.hour, minute=args.minute, second=args.second, microsecond=args.millisecond*1000+args.microsecond)
# log start of the manipulation process in verbose mode
if args.verbose:
print(f'[DEBUG] Setting the new mtime')
# Now set it!
atime_timestamp = os.stat(args.file).st_atime # get atime timestamp (as os.utime requires this as an argument - we leave it unchanged)
mtime_timestamp = new_absolute_time.timestamp() # get the mtime timestamp from the respective datetime object
os.utime(args.file, (atime_timestamp, mtime_timestamp)) # set the new mtime (atime stays unchanged)