def analyse(src_path, files, title, description, author): """ Checks exif for all files in src_path :param src_path: Path to the image files :param files: List with valid file names :param title: String with new title, or None, if tag should not be changed :param description: String with new description, or None, if tag should not be changed :param author: String for author tag. Can be None Returns list with dict() for every image file, for instance: return [ dict(name='image001.jpg', title=dict(old=None, new="new title', changed=True, overwrite=True), description=dict(old=None, new="new title', changed=True, overwrite=True) author=dict(old=None, new="new author', changed=True, overwrite=True) ) ] 'changed' is True, if tag will be set 'overwrite' is True, if old value would be overwritten (needs force) """ src_dir = task.get_task_path(task.get_actual()['task']) + '/' + DIR_FINAL # files = list_jpg(src_dir) exifs = images_get_exifs(src_dir, files, report=False) ret = [] for each in exifs: ret.append(dict(name=each['name'], title=_analyze_tag(title, each['title']), description=_analyze_tag(description, each['description']), author=_analyze_tag(author, each['author']))) # print('analyse() ret=' + str(ret)) return ret
def analyse(_task, _dest): """ Checks export to dest from given task. task: dictionary with keys 'task' (foldername/taskname), 'name' (task name), 'folder' (folder name) dest: String with absolut path Returns list with dict() for every source file, for instance: return [dict(name='image001.jpg', exists='true', src_time=1474878288.2156258, dst_time=1474878288.2156258)] or dst_time=None """ src_dir = task.get_task_path(task.get_actual()['task']) + '/' + DIR_FINAL files = list_jpg(src_dir) # for file in files: # print('export_analyse() file=' + str(file) + ' ' # + time_readable(os.path.getatime(src_dir + '/' + file))) ret = [] for file in files: exists = os.path.exists(_dest + '/' + file) if exists: dst_time = os.path.getatime(_dest + '/' + file) else: dst_time = None ret.append( dict(name=file, exists=exists, src_time=os.path.getatime(src_dir + '/' + file), dst_time=dst_time)) # print('export_analyse() ret=' + str(ret)) return ret
def tasks(): """ Reports infos about all tasks. """ actual = task.get_actual() # dir02 = os.listdir(get_path(DIR_02)) dir02 = [f.name for f in os.scandir(get_path(DIR_02)) if f.is_dir()] dir02.sort() for each_folder in dir02: print(' ' + each_folder) # tasks = os.listdir(get_path(DIR_02) + '/' + each_folder) tasks = [ f.name for f in os.scandir(get_path(DIR_02) + '/' + each_folder) if f.is_dir() ] tasks.sort() for each_task in tasks: stats = get_short_status( get_path(DIR_02) + '/' + each_folder + '/' + each_task) jpgs = len([s for s in stats if s['jpg']]) raws = len([s for s in stats if s['raw']]) finals = len([s for s in stats if s['final']]) if jpgs == 0: jtext = '---' else: jtext = '{:>3}'.format(str(jpgs)) if raws == 0: rtext = '---' else: rtext = '{:>3}'.format(str(raws)) if finals == 0: ftext = '---' else: ftext = '{:>3}'.format(str(finals)) if actual['folder'] == each_folder and \ actual['name'] == each_task: start = '* ' else: start = ' ' print(start + jtext + ' ' + rtext + ' ' + ftext + ' ' + str(each_task))
def tasks(): """ Reports infos about all tasks. """ actual = task.get_actual() # dir02 = os.listdir(get_path(DIR_02)) dir02 = [f.name for f in os.scandir(get_path(DIR_02)) if f.is_dir()] dir02.sort() for each_folder in dir02: print(' ' + each_folder) # tasks = os.listdir(get_path(DIR_02) + '/' + each_folder) tasks = [f.name for f in os.scandir(get_path(DIR_02) + '/' + each_folder) if f.is_dir()] tasks.sort() for each_task in tasks: stats = get_short_status(get_path(DIR_02) + '/' + each_folder + '/' + each_task) jpgs = len([s for s in stats if s['jpg']]) raws = len([s for s in stats if s['raw']]) finals = len([s for s in stats if s['final']]) if jpgs == 0: jtext = '---' else: jtext = '{:>3}'.format(str(jpgs)) if raws == 0: rtext = '---' else: rtext = '{:>3}'.format(str(raws)) if finals == 0: ftext = '---' else: ftext = '{:>3}'.format(str(finals)) if actual['folder'] == each_folder and \ actual['name'] == each_task: start = '* ' else: start = ' ' print(start + jtext + ' ' + rtext + ' ' + ftext + ' ' + str(each_task))
def analyse(_task, _dest): """ Checks export to dest from given task. task: dictionary with keys 'task' (foldername/taskname), 'name' (task name), 'folder' (folder name) dest: String with absolut path Returns list with dict() for every source file, for instance: return [dict(name='image001.jpg', exists='true', src_time=1474878288.2156258, dst_time=1474878288.2156258)] or dst_time=None """ src_dir = task.get_task_path(task.get_actual()['task']) + '/' + DIR_FINAL files = list_jpg(src_dir) # for file in files: # print('export_analyse() file=' + str(file) + ' ' # + time_readable(os.path.getatime(src_dir + '/' + file))) ret = [] for file in files: exists = os.path.exists(_dest + '/' + file) if exists: dst_time = os.path.getatime(_dest + '/' + file) else: dst_time = None ret.append(dict( name=file, exists=exists, src_time=os.path.getatime(src_dir + '/' + file), dst_time=dst_time )) # print('export_analyse() ret=' + str(ret)) return ret
def cmd_show(cmd_list): """ Processing step reporting """ atom_short = dict(name='short', short='s', args=NONE_PARAM) atom_none = dict(name='', short='', args=OPTIONAL_PARAM) # atomNone must be mandatory for rules with more than one path ret = check_rules(cmd_list, [[ dict(atom=atom_none, obligat=True), dict(atom=atom_short, obligat=False) ]]) if ret['message'] is not None: return if ret['options'][''] == 'inbox': if 'short' in ret['options']: show.in_summary(plump.get_path(plump.DIR_00)) else: show.show_in(plump.get_path(plump.DIR_00)) return if ret['options'][''] == 'import': if 'short' in ret['options']: show.in_summary(plump.get_path(plump.DIR_01)) else: show.show_in(plump.get_path(plump.DIR_01)) return if ret['options'][''] == 'in': if 'short' in ret['options']: print('inbox:') show.in_summary(plump.get_path(plump.DIR_00)) print('import:') show.in_summary(plump.get_path(plump.DIR_01)) else: print('inbox:') show.show_in(plump.get_path(plump.DIR_00)) print('import:') show.show_in(plump.get_path(plump.DIR_01)) return if ret['options'][''] == 'tasks': if 'short' in ret['options']: show.tasks_summary() else: show.tasks() return # if 'task' in args['args'] or len(args['args']) == 0: if ret['options'][''] in ('task', None): if task.get_actual() is None: print('No actual task. ' + 'Use "task --create <task>" to create one.') else: print('Actual task is ' + task.get_actual()['task'] + '.') if 'short' in ret['options']: show.task_summary( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task']) else: show.show_task( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'], False) return
def cmd_task(cmd_list): """ Task manipulation. """ # Command needs an existing fow. if not plump.is_fow(): return # 0: No param allowed, 1: param optional, 2: param obligatory # if not checkArgs(_arg_dict, # {'-t': 0, '--test': 0, '-p': 2, '--path': 2}): # return atom_none = dict(name='', short='', args=NONE_PARAM) atom_create = dict(name='create', short='c', args=MANDATORY_PARAM) atom_activate = dict(name='activate', short='a', args=MANDATORY_PARAM) atom_next = dict(name='next', short='n', args=NONE_PARAM) atom_previous = dict(name='previous', short='p', args=NONE_PARAM) atom_short = dict(name='short', short='s', args=NONE_PARAM) atom_long = dict(name='long', short='l', args=NONE_PARAM) atom_raw_import = dict(name='raw-import', short='r', args=NONE_PARAM) atom_fill_final = dict(name='fill-final', short='f', args=NONE_PARAM) atom_test = dict(name='test', short='t', args=NONE_PARAM) ret = check_rules(cmd_list, [[dict(atom=atom_create, obligat=True)], [dict(atom=atom_activate, obligat=True)], [ dict(atom=atom_none, obligat=True), dict(atom=atom_short, obligat=False) ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_long, obligat=False) ], [dict(atom=atom_next, obligat=True)], [dict(atom=atom_previous, obligat=True)], [ dict(atom=atom_raw_import, obligat=True), dict(atom=atom_test, obligat=False) ], [ dict(atom=atom_fill_final, obligat=True), dict(atom=atom_test, obligat=False) ]]) if ret['message'] is not None: return # print("cmd_task() ret={}".format(str(ret))) # --- Options to change the actual task (activate or create)---# if 'create' in ret['options'] or 'activate' in ret['options']: if 'create' in ret['options']: path_arg = ret['options']['create'] else: path_arg = ret['options']['activate'] # arg for option '' is the path, Path may not end with '/' if path_arg is not None and len(path_arg) > 0 and path_arg[-1] == '/': path_arg = path_arg[0:-1] # Extract folder and task name if path_arg.count('/') > 2: print('Path too long, use [[' + plump.DIR_02 + ']/<folder>/]]<task>') return # print("cmd_task() path_arg={}".format(str(path_arg))) # Dictionary with all task parts path = dict(folder=None, task=None, ft=None, path=None) if path_arg.count('/') == 2: # print(args['args'][0]) if not path_arg.startswith(plump.DIR_02 + '/'): print('Invalid path. Try [[' + plump.DIR_02 + '/]<folder>/]]<task>.') return else: parts = path_arg.split('/') path['folder'] = parts[-2] path['task'] = parts[-1] elif path_arg.count('/') == 1: parts = path_arg.split('/') path['folder'] = parts[-2] path['task'] = parts[-1] else: path['task'] = path_arg # If only task is given, take the active folder if path['folder'] is None: if task.get_actual() is None: print('No actual task set, please specify the folder, too: ' + '[[' + plump.DIR_02 + '/]<folder>/]]<task>') return path['folder'] = task.get_actual()['folder'] # For convenience usage path['ft'] = path['folder'] + '/' + path['task'] path['path'] = plump.get_path(plump.DIR_02) + '/' + path['ft'] # task --create <task> if 'create' in ret['options']: if os.path.exists(path['path']): print('task ' + str(path['ft']) + ' already exists.' + ' Choose a different name to create a new task.') return os.makedirs(path['path']) os.mkdir(path['path'] + '/' + plump.DIR_FINAL) os.mkdir(path['path'] + '/' + plump.DIR_JPG) os.mkdir(path['path'] + '/' + plump.DIR_RAW) os.mkdir(path['path'] + '/' + plump.DIR_WORK) os.mkdir(path['path'] + '/' + plump.DIR_VIDEO) config.set_item(plump.TASK, path['ft']) return if 'activate' in ret['options']: # print('path =' + str(path)) if not os.path.exists(path['path']): print( 'task ' + str(path['ft']) + ' does not exist.' + ' To create a new task use "task --create [<folder>/]<task>"' ) return config.set_item(plump.TASK, path['ft']) return # --- Options for the actual task ---# # task --short # task # task --long if 'short' in ret['options'] or 'long' in ret['options'] or len( ret['options']) == 1: if task.get_actual() is None: print('No actual task. ' + 'Use "task --create <task>" to create one.') else: if 'short' in ret['options']: print('Actual task {}. Showing a summary.'.format( task.get_actual()['task'])) show.task_summary( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task']) elif 'long' in ret['options']: print('Actual task is {}. Listing all image files.'.format( task.get_actual()['task'])) show.show_task( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'], False) else: print( 'Actual task is {}. Listing image files in final.'.format( task.get_actual()['task'])) show.show_task( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'], True) return # task --raw-import # task --raw-import --test if 'raw-import' in ret['options']: if task.get_actual() is None: print('No actual task set, please specify the folder, too: ' + '[' + plump.get_path(plump.DIR_02) + '/]<folder>/<task>') return task.move_corresponding_raws( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_JPG, plump.get_path(plump.DIR_01) + '/' + plump.DIR_RAW, plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_RAW, 'test' in ret['options']) return # task --fill-final # task --fill-final --test if 'fill-final' in ret['options']: if task.get_actual() is None: print('No actual task set, please specify the folder, too: ' + '[' + plump.get_path(plump.DIR_02) + '/]<folder>/<task>') return plump.copy_missing_jpgs( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_JPG, plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_FINAL, 'test' in ret['options']) return # task --next # task --previous if 'next' in ret['options'] or 'previous' in ret['options']: if 'previous' in ret['options']: offset = -1 else: offset = 1 old_triple = task.get_task_triple(offset) if old_triple is None: print('No actual task found.') return if old_triple['p_task'] is None: print('Seems to be only one task. Switching not possible.') return config.set_item( plump.TASK, '{0}/{1}'.format(old_triple['a_task']['subdir'], old_triple['a_task']['task'])) new_triple = task.get_task_triple(0) print(' {0}/{1}'.format(str(new_triple['p_task']['subdir']), str(new_triple['p_task']['task']))) print('* {0}/{1}'.format(str(new_triple['a_task']['subdir']), str(new_triple['a_task']['task']))) print(' {0}/{1}'.format(str(new_triple['n_task']['subdir']), str(new_triple['n_task']['task']))) return
def cmd_gps(cmd_list): """ Adds geo locations from gps files """ atom_none = dict(name='', short='', args=NONE_PARAM) atom_path = dict(name='path', short='p', args=MANDATORY_PARAM) atom_source = dict(name='source', short='s', args=MANDATORY_PARAM) atom_write = dict(name='write', short='w', args=NONE_PARAM) atom_test = dict(name='test', short='t', args=NONE_PARAM) atom_map = dict(name='map', short='m', args=NONE_PARAM) atom_force = dict(name='force', short='f', args=NONE_PARAM) atom_verbose = dict(name='verbose', short='v', args=NONE_PARAM) ret = check_rules(cmd_list, [[ dict(atom=atom_none, obligat=True), dict(atom=atom_source, obligat=False), dict(atom=atom_write, obligat=False), dict(atom=atom_test, obligat=False), dict(atom=atom_write, obligat=False), dict(atom=atom_verbose, obligat=False), dict(atom=atom_force, obligat=False) ], [ dict(atom=atom_path, obligat=True), dict(atom=atom_source, obligat=False), dict(atom=atom_test, obligat=False), dict(atom=atom_verbose, obligat=False), dict(atom=atom_force, obligat=False) ], [ dict(atom=atom_map, obligat=True), dict(atom=atom_path, obligat=False) ]]) if ret['message'] is not None: return # print('cmd_gps() options_matrix=' + str(options_matrix)) # arg validation # image path as destination # image path as path argument # if 'path' in options['names']: if 'path' in ret['options']: if not os.path.exists(plump.get_path(ret['options'][''])): print((( "'{0}' is not an existing sub dir within this fow. " + "Maybe the directory is temporary not available or you have to " + "write the correct path.")).format(str(ret['options']['']))) return # Validated absolute path to the images image_path = plump.get_path(ret['options']['']) # elif ret['options'][''] is not None: # key = 'gps.{}'.format(ret['options']['']) # if config.read_item(key) is None: # print( # "Value {0} not configured. Maybe you have to set it first with # config -s '{0}=fow-subdir-to-images'".format( # key)) # return # if not os.path.exists(plump.get_path(config.read_item(key))): # print((("Destination points to a non existing sub dir: '{0}'. " + # "Maybe the directory is temporary not available or you have to" + # " change the destination with 'config -s {1}=fow-subdir-to-images'")) # .format(str(config.read_item(key)), key)) # return # # Validated absolute path to the images # image_path = plump.get_path(config.read_item(key)) # image path is the actual final else: if task.get_actual() is None: print('No active task.') return elif not os.path.exists(task.get_actual()['path']): print( "Actual task '{0}' is not an existing sub dir within this fow." .format(str(task.get_actual()['path']))) return else: image_path = '{}/{}'.format(task.get_actual()['path'], plump.DIR_FINAL) # Now we have a valid, existing absolute path to the images # Just show map if 'map' in ret['options']: fow_gps.map(image_path) return # track path as source argument if 'source' in ret['options']: if not os.path.exists(ret['options']['source']): print("'{0}' is not an existing, accessible directory. ".format( str(ret['options']['source']))) return # Validated absolute path to the images track_path = ret['options']['source'] else: if config.read_item(plump.GPS_TRACK_PATH) is None: print( '{0} not set. Define the path to tracks folder with config -s {0}=/your/tracks/path' .format(plump.GPS_TRACK_PATH)) return elif not os.path.exists(config.read_item(plump.GPS_TRACK_PATH)): print(( "Invalid path to track files: '{0}'. May the directory is temporary not available or you have to" + " change it with 'config -s {1}=/your/tracks/path'").format( str(config.read_item(plump.GPS_TRACK_PATH)), plump.GPS_TRACK_PATH)) return # Validated absolute path to the images track_path = config.read_item(plump.GPS_TRACK_PATH) # gps --write if 'write' in ret['options']: if not os.path.exists( os.path.join(task.get_actual()['path'], plump.DIR_WORK)): print("Missing sub directory {}.".format(plump.DIR_WORK)) return else: write_path = os.path.join(task.get_actual()['path'], plump.DIR_WORK) else: write_path = None analysis = fow_gps.analyse(track_path, image_path, write_path) # print('cmd_gps() analysis=' + str(analysis)) # gps --verbose if 'verbose' in ret['options']: verbose = True else: verbose = False # gps --test if 'test' in ret['options']: fow_gps.test(analysis, verbose, write_path) return # gps else: fow_gps.do(analysis, True, verbose, write_path)
def cmd_exif(cmd_list): """ Set exif values """ atom_none = dict(name='', short='', args=OPTIONAL_PARAM) atom_title = dict(name='title', short='t', args=MANDATORY_PARAM) atom_description = dict(name='description', short='d', args=MANDATORY_PARAM) atom_author = dict(name='author', short='a', args=NONE_PARAM) atom_check = dict(name='check', short='c', args=NONE_PARAM) atom_force = dict(name='force', short='f', args=NONE_PARAM) atom_verbose = dict(name='verbose', short='v', args=NONE_PARAM) # If none has an optional parameter, no other option in the same rule should have an optional parameter, too. ret = check_rules(cmd_list, [[ dict(atom=atom_none, obligat=True), dict(atom=atom_verbose, obligat=False), ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_title, obligat=True), dict(atom=atom_description, obligat=False), dict(atom=atom_author, obligat=False), dict(atom=atom_check, obligat=False), dict(atom=atom_force, obligat=False), dict(atom=atom_verbose, obligat=False), ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_title, obligat=False), dict(atom=atom_description, obligat=True), dict(atom=atom_author, obligat=False), dict(atom=atom_check, obligat=False), dict(atom=atom_force, obligat=False), dict(atom=atom_verbose, obligat=False), ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_title, obligat=False), dict(atom=atom_description, obligat=False), dict(atom=atom_author, obligat=True), dict(atom=atom_check, obligat=False), dict(atom=atom_force, obligat=False), dict(atom=atom_verbose, obligat=False), ]]) if ret['message'] is not None: return # Get author if 'author' in ret['options']: try: author = config.read_pickle()["{}.{}".format( plump.EXIF_PREFIX, 'author')] if len(str(author)) == 0: print( "Destination value not defined. Create it with config -s '{}.author=<value>' first." .format(plump.EXIF_PREFIX)) return # Replace year author = author.replace("{YYYY}", str(datetime.now().year)) except (TypeError, KeyError): print( "xDestination value not defined. Create it with config -s '{}.author=<value>' first." .format(plump.EXIF_PREFIX)) return else: author = None if not task.check_actual(): return src_dir = task.get_actual()['task'] + '/' + plump.DIR_FINAL src_path = task.get_task_path(src_dir) # None, '*', 1,2,3 or a file name files = fow_exif.check_images(src_path, ret['options']['']) # print("cmd_exif() files={}".format(str(files))) if files is None: print("No images found") return if 'title' in ret['options']: title = ret['options']['title'] else: title = None if 'description' in ret['options']: description = ret['options']['description'] else: description = None analysis = fow_exif.analyse(src_path, files, title, description, author) # print("cmd_exif() value=" + str(analysis)) if title is None and description is None and author is None: fow_exif.show(analysis, src_dir, 'verbose' in ret['options']) return if 'check' in ret['options']: fow_exif.test(analysis, src_dir, title is not None, description is not None, author is not None, 'force' in ret['options'], 'verbose' in ret['options']) return # exif --force if 'force' not in ret['options']: overwritten_tags = [ a for a in analysis if a['title']['overwrite'] or a['description']['overwrite'] or a['author']['overwrite'] ] if len(overwritten_tags) > 0: print("Value(s) would be overwritten, use --force to to this.") return # Do it! fow_exif.do(analysis, src_path, title is not None, description is not None, author is not None, 'verbose' in ret['options'])
def cmd_export(cmd_list): """ Copy finals to external destinations. """ # 0: No param allowed, 1: param optional, 2: param obligatory # if not checkArgs(_arg_dict, # {'-t': 0, '--test': 0, '-p': 2, '--path': 2}): # return atom_path = dict(name='path', short='p', args=MANDATORY_PARAM) atom_force = dict(name='force', short='f', args=NONE_PARAM) atom_test = dict(name='test', short='t', args=NONE_PARAM) atom_none = dict(name='', short='', args=MANDATORY_PARAM) ret = check_rules(cmd_list, [[ dict(atom=atom_path, obligat=True), dict(atom=atom_force, obligat=False), dict(atom=atom_test, obligat=False) ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_force, obligat=False), dict(atom=atom_test, obligat=False) ]]) if ret['message'] is not None: return # Get destination if 'path' in ret['options']: destination = ret['options']['path'] else: try: destination = config.read_pickle()[plump.EXPORT_PREFIX + '.' + ret['options']['']] except: print( "Destination value not defined. Create it with config -s='export.{}' first." .format(ret['options'][''])) return if destination is None: print('Destination not valid. See "help export".') return # Extract task specific subdirectory {1} or {2}, if given m = re.compile('(.*)(/{[12]}/?)').match(destination) # Direct path if m is None: if not os.path.exists(destination): print('Destination directory not reachable: ' + destination) return # Task specific path else: root_dir = m.group(1) if os.path.exists(m.group(1)): # Resolve subdirectory placeholder: task name if destination.endswith(('{1}', '{1}/')): destination = root_dir + '/' + task.get_actual()['name'] # Resolve subdirectory placeholder: folder + task name elif destination.endswith(('{2}', '{2}/')): destination = root_dir + '/' + task.get_actual()['task'] else: print('Destination root directory not reachable: ' + root_dir) return print('destination={}'.format(destination)) if not task.check_actual(): return src_dir = task.get_actual()['task'] + '/' + plump.DIR_FINAL src_path = task.get_task_path(src_dir) files = plump.list_jpg(src_path) # [dict(name='image001.jpg', exists='true')] analysis = export.analyse(task.get_actual(), destination) if 'test' in ret['options']: export.test(analysis, src_dir, destination) return # export --force if 'force' in ret['options']: print( str(len(files)) + ' images in ' + task.get_actual()['task'] + '/' + plump.DIR_FINAL) print('Destination: ' + destination) export.copy(analysis, src_path, destination) # export else: exists = False for item in analysis: if item['exists']: exists = True if exists: print('Files would be overwritten! ' + 'Use --test to list the file(s) ' + 'or use --force to overwrite the image(s). ') else: print( str(len(files)) + ' images in ' + task.get_actual()['task'] + '/' + plump.DIR_FINAL) print('Destination: ' + destination) export.copy(analysis, src_path, destination)
def cmd_show(cmd_list): """ Processing step reporting """ atom_short = dict(name='short', short='s', args=NONE_PARAM) atom_none = dict(name='', short='', args=OPTIONAL_PARAM) # atomNone must be mandatory for rules with more than one path ret = check_rules(cmd_list, [ [ dict(atom=atom_none, obligat=True), dict(atom=atom_short, obligat=False) ] ]) if ret['message'] is not None: return if ret['options'][''] == 'inbox': if 'short' in ret['options']: show.in_summary(plump.get_path(plump.DIR_00)) else: show.show_in(plump.get_path(plump.DIR_00)) return if ret['options'][''] == 'import': if 'short' in ret['options']: show.in_summary(plump.get_path(plump.DIR_01)) else: show.show_in(plump.get_path(plump.DIR_01)) return if ret['options'][''] == 'in': if 'short' in ret['options']: print('inbox:') show.in_summary(plump.get_path(plump.DIR_00)) print('import:') show.in_summary(plump.get_path(plump.DIR_01)) else: print('inbox:') show.show_in(plump.get_path(plump.DIR_00)) print('import:') show.show_in(plump.get_path(plump.DIR_01)) return if ret['options'][''] == 'tasks': if 'short' in ret['options']: show.tasks_summary() else: show.tasks() return # if 'task' in args['args'] or len(args['args']) == 0: if ret['options'][''] in ('task', None): if task.get_actual() is None: print('No actual task. ' + 'Use "task --create <task>" to create one.') else: print('Actual task is ' + task.get_actual()['task'] + '.') if 'short' in ret['options']: show.task_summary(plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task']) else: show.show_task(plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'], False) return
def cmd_gps(cmd_list): """ Adds geo locations from gps files """ atom_none = dict(name='', short='', args=NONE_PARAM) atom_path = dict(name='path', short='p', args=MANDATORY_PARAM) atom_source = dict(name='source', short='s', args=MANDATORY_PARAM) atom_write = dict(name='write', short='w', args=NONE_PARAM) atom_test = dict(name='test', short='t', args=NONE_PARAM) atom_map = dict(name='map', short='m', args=NONE_PARAM) atom_force = dict(name='force', short='f', args=NONE_PARAM) atom_verbose = dict(name='verbose', short='v', args=NONE_PARAM) ret = check_rules(cmd_list, [ [ dict(atom=atom_none, obligat=True), dict(atom=atom_source, obligat=False), dict(atom=atom_write, obligat=False), dict(atom=atom_test, obligat=False), dict(atom=atom_write, obligat=False), dict(atom=atom_verbose, obligat=False), dict(atom=atom_force, obligat=False) ], [ dict(atom=atom_path, obligat=True), dict(atom=atom_source, obligat=False), dict(atom=atom_test, obligat=False), dict(atom=atom_verbose, obligat=False), dict(atom=atom_force, obligat=False) ], [ dict(atom=atom_map, obligat=True), dict(atom=atom_path, obligat=False) ] ]) if ret['message'] is not None: return # print('cmd_gps() options_matrix=' + str(options_matrix)) # arg validation # image path as destination # image path as path argument # if 'path' in options['names']: if 'path' in ret['options']: if not os.path.exists(plump.get_path(ret['options'][''])): print((("'{0}' is not an existing sub dir within this fow. " + "Maybe the directory is temporary not available or you have to " + "write the correct path.")) .format(str(ret['options']['']))) return # Validated absolute path to the images image_path = plump.get_path(ret['options']['']) # elif ret['options'][''] is not None: # key = 'gps.{}'.format(ret['options']['']) # if config.read_item(key) is None: # print( # "Value {0} not configured. Maybe you have to set it first with # config -s '{0}=fow-subdir-to-images'".format( # key)) # return # if not os.path.exists(plump.get_path(config.read_item(key))): # print((("Destination points to a non existing sub dir: '{0}'. " + # "Maybe the directory is temporary not available or you have to" + # " change the destination with 'config -s {1}=fow-subdir-to-images'")) # .format(str(config.read_item(key)), key)) # return # # Validated absolute path to the images # image_path = plump.get_path(config.read_item(key)) # image path is the actual final else: if task.get_actual() is None: print('No active task.') return elif not os.path.exists(task.get_actual()['path']): print("Actual task '{0}' is not an existing sub dir within this fow." .format(str(task.get_actual()['path']))) return else: image_path = '{}/{}'.format(task.get_actual()['path'], plump.DIR_FINAL) # Now we have a valid, existing absolute path to the images # Just show map if 'map' in ret['options']: fow_gps.map(image_path) return # track path as source argument if 'source' in ret['options']: if not os.path.exists(ret['options']['source']): print("'{0}' is not an existing, accessible directory. " .format(str(ret['options']['source']))) return # Validated absolute path to the images track_path = ret['options']['source'] else: if config.read_item(plump.GPS_TRACK_PATH) is None: print('{0} not set. Define the path to tracks folder with config -s {0}=/your/tracks/path' .format(plump.GPS_TRACK_PATH)) return elif not os.path.exists(config.read_item(plump.GPS_TRACK_PATH)): print(("Invalid path to track files: '{0}'. May the directory is temporary not available or you have to" + " change it with 'config -s {1}=/your/tracks/path'") .format(str(config.read_item(plump.GPS_TRACK_PATH)), plump.GPS_TRACK_PATH)) return # Validated absolute path to the images track_path = config.read_item(plump.GPS_TRACK_PATH) # gps --write if 'write' in ret['options']: if not os.path.exists(os.path.join(task.get_actual()['path'], plump.DIR_WORK)): print("Missing sub directory {}.".format(plump.DIR_WORK)) return else: write_path = os.path.join(task.get_actual()['path'], plump.DIR_WORK) else: write_path = None analysis = fow_gps.analyse(track_path, image_path, write_path) # print('cmd_gps() analysis=' + str(analysis)) # gps --verbose if 'verbose' in ret['options']: verbose = True else: verbose = False # gps --test if 'test' in ret['options']: fow_gps.test(analysis, verbose, write_path) return # gps else: fow_gps.do(analysis, True, verbose, write_path)
def cmd_task(cmd_list): """ Task manipulation. """ # Command needs an existing fow. if not plump.is_fow(): return # 0: No param allowed, 1: param optional, 2: param obligatory # if not checkArgs(_arg_dict, # {'-t': 0, '--test': 0, '-p': 2, '--path': 2}): # return atom_none = dict(name='', short='', args=NONE_PARAM) atom_create = dict(name='create', short='c', args=MANDATORY_PARAM) atom_activate = dict(name='activate', short='a', args=MANDATORY_PARAM) atom_next = dict(name='next', short='n', args=NONE_PARAM) atom_previous = dict(name='previous', short='p', args=NONE_PARAM) atom_short = dict(name='short', short='s', args=NONE_PARAM) atom_long = dict(name='long', short='l', args=NONE_PARAM) atom_raw_import = dict(name='raw-import', short='r', args=NONE_PARAM) atom_fill_final = dict(name='fill-final', short='f', args=NONE_PARAM) atom_test = dict(name='test', short='t', args=NONE_PARAM) ret = check_rules(cmd_list, [ [ dict(atom=atom_create, obligat=True) ], [ dict(atom=atom_activate, obligat=True) ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_short, obligat=False) ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_long, obligat=False) ], [ dict(atom=atom_next, obligat=True) ], [ dict(atom=atom_previous, obligat=True) ], [ dict(atom=atom_raw_import, obligat=True), dict(atom=atom_test, obligat=False) ], [ dict(atom=atom_fill_final, obligat=True), dict(atom=atom_test, obligat=False) ] ]) if ret['message'] is not None: return # print("cmd_task() ret={}".format(str(ret))) # --- Options to change the actual task (activate or create)---# if 'create' in ret['options'] or 'activate' in ret['options']: if 'create' in ret['options']: path_arg = ret['options']['create'] else: path_arg = ret['options']['activate'] # arg for option '' is the path, Path may not end with '/' if path_arg is not None and len(path_arg) > 0 and path_arg[-1] == '/': path_arg = path_arg[0:-1] # Extract folder and task name if path_arg.count('/') > 2: print('Path too long, use [[' + plump.DIR_02 + ']/<folder>/]]<task>') return # print("cmd_task() path_arg={}".format(str(path_arg))) # Dictionary with all task parts path = dict(folder=None, task=None, ft=None, path=None) if path_arg.count('/') == 2: # print(args['args'][0]) if not path_arg.startswith(plump.DIR_02 + '/'): print('Invalid path. Try [[' + plump.DIR_02 + '/]<folder>/]]<task>.') return else: parts = path_arg.split('/') path['folder'] = parts[-2] path['task'] = parts[-1] elif path_arg.count('/') == 1: parts = path_arg.split('/') path['folder'] = parts[-2] path['task'] = parts[-1] else: path['task'] = path_arg # If only task is given, take the active folder if path['folder'] is None: if task.get_actual() is None: print('No actual task set, please specify the folder, too: ' + '[[' + plump.DIR_02 + '/]<folder>/]]<task>') return path['folder'] = task.get_actual()['folder'] # For convenience usage path['ft'] = path['folder'] + '/' + path['task'] path['path'] = plump.get_path(plump.DIR_02) + '/' + path['ft'] # task --create <task> if 'create' in ret['options']: if os.path.exists(path['path']): print('task ' + str(path['ft']) + ' already exists.' + ' Choose a different name to create a new task.') return os.makedirs(path['path']) os.mkdir(path['path'] + '/' + plump.DIR_FINAL) os.mkdir(path['path'] + '/' + plump.DIR_JPG) os.mkdir(path['path'] + '/' + plump.DIR_RAW) os.mkdir(path['path'] + '/' + plump.DIR_WORK) os.mkdir(path['path'] + '/' + plump.DIR_VIDEO) config.set_item(plump.TASK, path['ft']) return if 'activate' in ret['options']: # print('path =' + str(path)) if not os.path.exists(path['path']): print('task ' + str(path['ft']) + ' does not exist.' + ' To create a new task use "task --create [<folder>/]<task>"') return config.set_item(plump.TASK, path['ft']) return # --- Options for the actual task ---# # task --short # task # task --long if 'short' in ret['options'] or 'long' in ret['options'] or len(ret['options']) == 1: if task.get_actual() is None: print('No actual task. ' + 'Use "task --create <task>" to create one.') else: if 'short' in ret['options']: print('Actual task {}. Showing a summary.'.format(task.get_actual()['task'])) show.task_summary( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task']) elif 'long' in ret['options']: print('Actual task is {}. Listing all image files.'.format(task.get_actual()['task'])) show.show_task( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'], False) else: print('Actual task is {}. Listing image files in final.'.format(task.get_actual()['task'])) show.show_task(plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'], True) return # task --raw-import # task --raw-import --test if 'raw-import' in ret['options']: if task.get_actual() is None: print('No actual task set, please specify the folder, too: ' + '[' + plump.get_path(plump.DIR_02) + '/]<folder>/<task>') return task.move_corresponding_raws( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_JPG, plump.get_path(plump.DIR_01) + '/' + plump.DIR_RAW, plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_RAW, 'test' in ret['options']) return # task --fill-final # task --fill-final --test if 'fill-final' in ret['options']: if task.get_actual() is None: print('No actual task set, please specify the folder, too: ' + '[' + plump.get_path(plump.DIR_02) + '/]<folder>/<task>') return plump.copy_missing_jpgs( plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_JPG, plump.get_path(plump.DIR_02) + '/' + task.get_actual()['task'] + '/' + plump.DIR_FINAL, 'test' in ret['options']) return # task --next # task --previous if 'next' in ret['options'] or 'previous' in ret['options']: if 'previous' in ret['options']: offset = -1 else: offset = 1 old_triple = task.get_task_triple(offset) if old_triple is None: print('No actual task found.') return if old_triple['p_task'] is None: print('Seems to be only one task. Switching not possible.') return config.set_item(plump.TASK, '{0}/{1}'.format(old_triple['a_task']['subdir'], old_triple['a_task']['task'])) new_triple = task.get_task_triple(0) print(' {0}/{1}'.format(str(new_triple['p_task']['subdir']), str(new_triple['p_task']['task']))) print('* {0}/{1}'.format(str(new_triple['a_task']['subdir']), str(new_triple['a_task']['task']))) print(' {0}/{1}'.format(str(new_triple['n_task']['subdir']), str(new_triple['n_task']['task']))) return
def cmd_export(cmd_list): """ Copy finals to external destinations. """ # 0: No param allowed, 1: param optional, 2: param obligatory # if not checkArgs(_arg_dict, # {'-t': 0, '--test': 0, '-p': 2, '--path': 2}): # return atom_path = dict(name='path', short='p', args=MANDATORY_PARAM) atom_force = dict(name='force', short='f', args=NONE_PARAM) atom_test = dict(name='test', short='t', args=NONE_PARAM) atom_none = dict(name='', short='', args=MANDATORY_PARAM) ret = check_rules(cmd_list, [ [ dict(atom=atom_path, obligat=True), dict(atom=atom_force, obligat=False), dict(atom=atom_test, obligat=False) ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_force, obligat=False), dict(atom=atom_test, obligat=False) ] ]) if ret['message'] is not None: return # Get destination if 'path' in ret['options']: destination = ret['options']['path'] else: try: destination = config.read_pickle()[plump.EXPORT_PREFIX + '.' + ret['options']['']] except: print("Destination value not defined. Create it with config -s='export.{}' first." .format(ret['options'][''])) return if destination is None: print('Destination not valid. See "help export".') return # Extract task specific subdirectory {1} or {2}, if given m = re.compile('(.*)(/{[12]}/?)').match(destination) # Direct path if m is None: if not os.path.exists(destination): print('Destination directory not reachable: ' + destination) return # Task specific path else: root_dir = m.group(1) if os.path.exists(m.group(1)): # Resolve subdirectory placeholder: task name if destination.endswith(('{1}', '{1}/')): destination = root_dir + '/' + task.get_actual()['name'] # Resolve subdirectory placeholder: folder + task name elif destination.endswith(('{2}', '{2}/')): destination = root_dir + '/' + task.get_actual()['task'] else: print('Destination root directory not reachable: ' + root_dir) return print('destination={}'.format(destination)) if not task.check_actual(): return src_dir = task.get_actual()['task'] + '/' + plump.DIR_FINAL src_path = task.get_task_path(src_dir) files = plump.list_jpg(src_path) # [dict(name='image001.jpg', exists='true')] analysis = export.analyse(task.get_actual(), destination) if 'test' in ret['options']: export.test(analysis, src_dir, destination) return # export --force if 'force' in ret['options']: print(str(len(files)) + ' images in ' + task.get_actual()['task'] + '/' + plump.DIR_FINAL) print('Destination: ' + destination) export.copy(analysis, src_path, destination) # export else: exists = False for item in analysis: if item['exists']: exists = True if exists: print('Files would be overwritten! ' + 'Use --test to list the file(s) ' + 'or use --force to overwrite the image(s). ') else: print(str(len(files)) + ' images in ' + task.get_actual()['task'] + '/' + plump.DIR_FINAL) print('Destination: ' + destination) export.copy(analysis, src_path, destination)
def cmd_exif(cmd_list): """ Set exif values """ atom_none = dict(name='', short='', args=OPTIONAL_PARAM) atom_title = dict(name='title', short='t', args=MANDATORY_PARAM) atom_description = dict(name='description', short='d', args=MANDATORY_PARAM) atom_author = dict(name='author', short='a', args=NONE_PARAM) atom_check = dict(name='check', short='c', args=NONE_PARAM) atom_force = dict(name='force', short='f', args=NONE_PARAM) atom_verbose = dict(name='verbose', short='v', args=NONE_PARAM) # If none has an optional parameter, no other option in the same rule should have an optional parameter, too. ret = check_rules(cmd_list, [ [ dict(atom=atom_none, obligat=True), dict(atom=atom_verbose, obligat=False), ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_title, obligat=True), dict(atom=atom_description, obligat=False), dict(atom=atom_author, obligat=False), dict(atom=atom_check, obligat=False), dict(atom=atom_force, obligat=False), dict(atom=atom_verbose, obligat=False), ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_title, obligat=False), dict(atom=atom_description, obligat=True), dict(atom=atom_author, obligat=False), dict(atom=atom_check, obligat=False), dict(atom=atom_force, obligat=False), dict(atom=atom_verbose, obligat=False), ], [ dict(atom=atom_none, obligat=True), dict(atom=atom_title, obligat=False), dict(atom=atom_description, obligat=False), dict(atom=atom_author, obligat=True), dict(atom=atom_check, obligat=False), dict(atom=atom_force, obligat=False), dict(atom=atom_verbose, obligat=False), ] ]) if ret['message'] is not None: return # Get author if 'author' in ret['options']: try: author = config.read_pickle()["{}.{}".format(plump.EXIF_PREFIX, 'author')] if len(str(author)) == 0: print("Destination value not defined. Create it with config -s '{}.author=<value>' first." .format(plump.EXIF_PREFIX)) return # Replace year author = author.replace("{YYYY}", str(datetime.now().year)) except (TypeError, KeyError): print("xDestination value not defined. Create it with config -s '{}.author=<value>' first." .format(plump.EXIF_PREFIX)) return else: author = None if not task.check_actual(): return src_dir = task.get_actual()['task'] + '/' + plump.DIR_FINAL src_path = task.get_task_path(src_dir) # None, '*', 1,2,3 or a file name files = fow_exif.check_images(src_path, ret['options']['']) # print("cmd_exif() files={}".format(str(files))) if files is None: print("No images found") return if 'title' in ret['options']: title = ret['options']['title'] else: title = None if 'description' in ret['options']: description = ret['options']['description'] else: description = None analysis = fow_exif.analyse(src_path, files, title, description, author) # print("cmd_exif() value=" + str(analysis)) if title is None and description is None and author is None: fow_exif.show(analysis, src_dir, 'verbose' in ret['options']) return if 'check' in ret['options']: fow_exif.test(analysis, src_dir, title is not None, description is not None, author is not None, 'force' in ret['options'], 'verbose' in ret['options']) return # exif --force if 'force' not in ret['options']: overwritten_tags = [a for a in analysis if a['title']['overwrite'] or a['description']['overwrite'] or a['author']['overwrite']] if len(overwritten_tags) > 0: print("Value(s) would be overwritten, use --force to to this.") return # Do it! fow_exif.do(analysis, src_path, title is not None, description is not None, author is not None, 'verbose' in ret['options'])