2024-08-14 13:34:32 +00:00
#!/usr/bin/python3
"""
This helper script is able to extract a date and time from the name of all files in a directory and set their respective UNIX mtime ( the modified timestamp ) .
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 / datetime . html #strftime-and-strptime-behavior
- https : / / www . datacamp . com / tutorial / converting - strings - datetime - objects
- https : / / scrapfly . io / blog / parsing - datetime - strings - with - python - and - dateparser /
- https : / / stackoverflow . com / questions / 466345 / convert - string - jun - 1 - 2005 - 133 pm - into - datetime
"""
from datetime import datetime
from argparse import ArgumentParser , RawTextHelpFormatter
import os
2024-08-14 15:24:51 +00:00
import sys
2024-08-14 13:34:32 +00:00
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 '
2024-08-14 15:24:51 +00:00
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 )
2024-08-14 13:34:32 +00:00
# set up the ArgumentParser for the CLI
parser = ArgumentParser (
description = ' filename2mtime.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 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 '
2024-08-14 15:24:51 +00:00
' BE AWARE THAT ALL CHANGES TO THE FILES CANNOT BE UNDONE! USE AT YOUR OWN RISK! ' ,
2024-08-14 13:34:32 +00:00
epilog = ' by Benjamin Burkhardt, 2024 ' ,
add_help = False ,
formatter_class = RawTextHelpFormatter )
2024-08-14 15:24:51 +00:00
parser . add_argument ( ' -f ' , ' --format ' , type = str , default = " " , help = " give the format of the strings \r \n see 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
2024-08-14 13:34:32 +00:00
# parse given arguments
args = parser . parse_args ( )
# print help and exit if prompted to
2024-08-14 15:24:51 +00:00
if args . help or not len ( sys . argv ) > 1 :
2024-08-14 13:34:32 +00:00
parser . print_help ( )
exit ( 0 )
2024-08-14 15:24:51 +00:00
# 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 ) )