Last active
November 15, 2024 15:23
-
-
Save ddrscott/7e5e2ffb39b391462421baf0d280f87e to your computer and use it in GitHub Desktop.
Checks files in the specified directory and determines if changes have occurred within the given age limit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Copyright (c) <year> <copyright holders> | |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import glob | |
from textwrap import dedent | |
from datetime import datetime, timedelta | |
def check_files(directory, max_age_minutes, last_state_file): | |
""" | |
Checks files in the specified directory and determines if changes have occurred within the given age limit. | |
Hidden files ignored by default. | |
Args: | |
directory (str): The path to the directory containing the files. | |
max_age_minutes (float): The maximum age in minutes for a file to be considered as having changes detected. | |
last_state_file (str): The path to the file that stores the last done time. | |
Usage: | |
python script.py <directory> <max_age_minutes> [last_state_file] | |
<directory>: The path to the directory containing the files. | |
<max_age_minutes>: The maximum age in minutes for a file to be considered as having changes detected. | |
[last_state_file]: Optional. The path to the file that stores the last done time (default is '.last_state'). | |
Returns: | |
bool: True if all files are older than the max age and the last done time is updated, otherwise False. | |
""" | |
# List all files in the directory and sort them by modification time | |
# print(f"Checking files in directory: {glob.glob(os.path.join(directory, '*.*')) }") | |
files = [ | |
(f, os.path.getmtime(f)) | |
for f in glob.glob(os.path.join(directory, '*.*')) | |
if os.path.isfile(f) | |
] | |
if not files: | |
print("No files found in the specified directory.") | |
return | |
# Read the last state time if it exists | |
last_done_time = read_last_state(last_state_file) | |
newest_file_time = max(files, key=lambda x: x[1])[1] | |
all_files_old = True | |
for file, mod_time in files: | |
mod_time_datetime = datetime.fromtimestamp(mod_time) | |
age_minutes = (datetime.now() - mod_time_datetime).total_seconds() / 60 | |
if age_minutes < max_age_minutes: | |
all_files_old = False | |
break | |
if all_files_old: | |
if last_done_time is None or (newest_file_time > last_done_time.timestamp()): | |
print("all done") | |
update_last_state(last_state_file) | |
return True | |
else: | |
print("waiting for next batch...") | |
else: | |
print(f"changes detected: {all_files_old=}, {file=}, {age_minutes:.2f} minutes old") | |
return False | |
def read_last_state(last_state_file): | |
""" | |
Reads the last state time from the specified file. | |
Args: | |
last_state_file (str): The path to the file that stores the last done time. | |
Returns: | |
datetime: The last done time if it exists and is valid, otherwise None. | |
""" | |
if os.path.exists(last_state_file): | |
try: | |
with open(last_state_file, 'r') as f: | |
return datetime.fromisoformat(f.read().strip()) | |
except ValueError: | |
pass # Ignore invalid date format | |
return None | |
def update_last_state(last_state_file): | |
""" | |
Updates the last state time in the specified file to the current time. | |
Args: | |
last_state_file (str): The path to the file that stores the last done time. | |
""" | |
with open(last_state_file, 'w') as f: | |
f.write(datetime.now().isoformat()) | |
def remove_last_state(last_state_file): | |
""" | |
Removes the specified last state file if it exists. | |
Args: | |
last_state_file (str): The path to the file that stores the last done time. | |
""" | |
if os.path.exists(last_state_file): | |
os.remove(last_state_file) | |
# Example usage | |
if __name__ == "__main__": | |
import sys | |
if len(sys.argv) < 3 or len(sys.argv) > 4: | |
print(dedent(check_files.__doc__)) | |
sys.exit(1) | |
directory = sys.argv[1] | |
max_age_minutes = float(sys.argv[2]) | |
last_state_file = os.path.join(directory,'.last_state') if len(sys.argv) == 3 else sys.argv[3] | |
check_files(directory, max_age_minutes, last_state_file) |
check_files
will return True when changes have been detected.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@chordol @graham-allen-partners Enjoy!
Example Use:
Watch
tmp
for any changing files. Swap "all done" message with a function call or anything else.