Skip to content

Instantly share code, notes, and snippets.

@adibPr
Last active June 2, 2022 15:10
Show Gist options
  • Save adibPr/5ae61b5f5aa2b3fa64aa0e1d57f9abe0 to your computer and use it in GitHub Desktop.
Save adibPr/5ae61b5f5aa2b3fa64aa0e1d57f9abe0 to your computer and use it in GitHub Desktop.
A simple script to compare states between to time, and return it's file difference
import os
import sys
import argparse
import logging
import pickle
from pathlib import Path
import fnmatch
from watchdog.utils.dirsnapshot import DirectorySnapshot, DirectorySnapshotDiff
path_this = os.path.abspath(os.path.dirname(__file__))
path_run = os.path.abspath('.')
path_snapshot = os.path.join(path_run, '.sns.pkl')
sys.path.append(path_this)
logger = logging.getLogger ('snapshot')
logger.setLevel (logging.DEBUG)
formatter = logging.Formatter (
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
ch = logging.StreamHandler ()
ch.setLevel (logging.DEBUG)
ch.setFormatter (formatter)
logger.addHandler (ch)
def get_diff(path,
path_snapshot=path_snapshot,
w_save=False):
# make it absolute, so it can safely being dumped
path = os.path.abspath(path)
logger.debug('Creating snapshot for {}'.format(path))
new_snapshot = DirectorySnapshot(path)
# check old snapshot, find diff if exist
if Path(path_snapshot).is_file():
logger.debug('Old snapshot exist')
with open(path_snapshot, 'rb') as f_:
old_path, old_snapshot = pickle.load(f_)
if not os.path.samefile(old_path, path):
logger.warning("Old snapshot is differ from current path, aborting")
logger.warning("Delete the old snapshot first")
return []
diff = DirectorySnapshotDiff(old_snapshot, new_snapshot)
logger.debug("Found {} new created, {} modified".format(
len(diff.files_created), len(diff.files_modified)
))
final_data = diff.files_created + diff.files_modified
final_data += [_[1] for _ in diff.files_moved]
else:
logger.warning("Old snapshot doesn't exist")
final_data = []
# saving
if w_save:
logger.debug("Saving current snapshot to {}".format(path_snapshot))
with open(path_snapshot, 'wb') as f_:
pickle.dump((path, new_snapshot), f_)
return final_data
def parse_args():
parser = argparse.ArgumentParser(description='Get list of modified files')
parser.add_argument('path', type=str, help='The path (relative or absoulte) to the directory need to process')
parser.add_argument('-s', '--snapshot', help='Using this snapshot as comparison, default .sns.pkl', default=path_snapshot, dest='path_snapshot')
parser.add_argument('-d', '--dry', help='Do not save after comparing snapshot', action='store_false', dest='w_save')
parser.add_argument('--log-level', choices=['debug', 'none'], default='none', help='Log level of the program')
parser.add_argument('-m', '--match', help='Match based on this pattern using glob, default *', default='*', dest='pattern')
args = parser.parse_args()
return vars(args)
if __name__ == '__main__':
args = parse_args()
log_level = args.pop('log_level')
if log_level.lower() == 'none':
logger.handlers.clear()
pattern = args.pop('pattern')
diff = get_diff(**args)
diff = fnmatch.filter(diff, pattern)
if diff: print('\n'.join(diff))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment