#!/usr/bin/env python3 # Startdate: 2021-01-29 15:35 # Purpose: generate symlink forest of a directory path # methodology: # 1. read exif data first, YYYY/MM # 2. use timestamp of file, and log warnings # Usage: # ./generate.py -i /mnt/bgstack15/Backups/bgstack15/Images/Photos/camera/2018/ -o /mnt/public/www/gallery/my2018 -n -d2 -x 'October' -s --nr from argparse import ArgumentParser, RawDescriptionHelpFormatter from genlib import * generate_version="2021-02-25a" # WORKHERE the if __main__ thing: parser = ArgumentParser(description="Make symlink forest for images", formatter_class=RawDescriptionHelpFormatter, epilog="""FORMATTING Format string will be interpreted as a python f-string, so wrap variable names with curly braces. Default format is "{Y}/{M}" {Y} is 4-digit year {M} is month (affected by padding) {D} is day (affected by padding)""") parser.add_argument("-d","--debug",nargs='?', default=0, type=int, choices=range(0,11), help="Set debug level") parser.add_argument("-v","--version", action="version", version="%(prog)s " + generate_version) g_dryrun = parser.add_mutually_exclusive_group() g_dryrun.add_argument("-n","--dryrun", action="store_true", help="Make no changes (default)") g_dryrun.add_argument("-a","--apply", action="store_true", help="Actually make changes") g_zeropad = parser.add_mutually_exclusive_group() g_zeropad.add_argument("-z","-0","--zeropad",action="store_true", help="Zero pad month and day strings (default)") g_zeropad.add_argument("--nz","--nozeropad","--no-zeropad",action="store_true", help="Do not zero pad") g_action = parser.add_mutually_exclusive_group() g_action.add_argument("-c","--copy", action="store_true", help="Copy files instead of symlinks. Not recommended.") g_action.add_argument("-s","--symlink", action="store_true", help="Make symlinks (default)") g_action.add_argument("-m","--move", action="store_true", help="Move files. Not recommended.") g_relative = parser.add_mutually_exclusive_group() g_relative.add_argument("-r","--relative", action="store_true",help="Make relative symlinks if possible.") g_relative.add_argument("--nr","--norelative","--no-relative", action="store_true",help="Make absolute symlinks (default)") parser.add_argument("-i","--indir",required=True) parser.add_argument("-o","--outdir",required=True) parser.add_argument("-x","--exclude",action="append",help="Exclude pathname matches. Can be used multiple times.") parser.add_argument("-f","--format",action="store",default="{Y}/{M}",help="Subdirectories should follow this pattern. See FORMATTING heading.") # pull useful values out of the argparse entry args = parser.parse_args() debuglevel=0 if args.debug is None: debuglevel = 10 elif args.debug: debuglevel = args.debug indir = args.indir outdir = args.outdir dryrun = args.dryrun or not args.apply # the mutually exclusive group handles this OK eprint(args) zero_pad = args.zeropad or not args.nz if args.copy: action = "copy" elif args.symlink: action = "symlink" elif args.move: action = "move" relative_symlinks = not (not args.relative or args.nr) excludes = [] try: for i in args.exclude: excludes.append(i) except: # no exclusions pass subdirformat=args.format if debuglevel >= 10: eprint(args) if len(excludes) > 0: eprint("Excluding path matches:", excludes) # MAIN these_files = limit( list_files( indir, debuglevel=debuglevel, excludes=excludes ), ["image","video"] ) print("FOUND FILE COUNT:",len(these_files)) make_forest( outdir, these_files, subdirformat = subdirformat, action = action, dryrun = dryrun, debuglevel = debuglevel, zero_pad = zero_pad, relative_symlinks = relative_symlinks )