def _parse_args(self, args): normalize = False if args[0] == '-n': normalize = True args = args[1:] if len(args) <= 0: OUTPUT.error('Must provide at least one file matching argument') return False, [] return True, [normalize, *args]
def _parse_args(self, args): if len(args) <= 0: OUTPUT.error('Must provide at least one of `a` or `t` arguments.') return False, [] tags = [] for i in args[0]: if i not in TAG_TYPES: OUTPUT.error('Invalid tag types ({0}) must be at least one of `a` or `t`.'.format(args[0])) return False, [] tags.append(TAG_TYPES[i]) return True, [tags, args[1:]]
def _cmd(self, history, args): tags = {} match_all = False match_exact = False for a in args: if a == '-a': match_all = True elif a == '-e': match_exact = True else: p = a.find('=') if p > 0: tag = a[0:p] value = a[p + 1:] tags[tag] = value else: OUTPUT.error('Invalid argument format: {0}'.format(a)) if match_all: matches = history.get_tag_matches(tags, match_exact) else: matches = set() for k, v in tags.items(): m = history.get_tag_matches({k: v}, match_exact) matches = matches.union(m) OUTPUT.dict_start('Tag Matches') OUTPUT.list_section('Source Files', matches) OUTPUT.dict_end()
def _cmd(self, history, args): for fn in history.get_source_files(): tn = history.get_transcoded_to(fn) if tn is None: continue local_tn = reverse_tcode(tn) if (not _do_check_file(fn, args) and not _do_check_file(tn, args) and not _do_check_file(reverse_tcode(tn), args) ): continue print(fn) fn_tags = history.get_tags_for(fn) print('- Tags: {0}'.format(repr(fn_tags))) adjusted_tags = False while True: tag_name = prompt_value('Tag to edit (empty to continue)') if tag_name is None: break tag_name = tag_name.strip() tag_value = prompt_value('New value') if tag_value is None: if tag_name in fn_tags: del fn_tags[tag_name] adjusted_tags = True else: fn_tags[tag_name] = tag_value adjusted_tags = True if adjusted_tags: if FF_PROBES.is_supported(fn): # Fix the source, too. try: set_tags_on_file(fn, fn_tags) # TODO This will make the checksums wrong, but, meh. except Exception as e: OUTPUT.error("Couldn't update tags on source file {0} ({1})".format( fn, e )) set_tags_on_file(local_tn, fn_tags) history.set_tags_for(fn, fn_tags) return 0
def _cmd(self, history, args): tag_names = args[0] args = args[1] for fn in history.get_source_files_without_tag_names(tag_names): tn = history.get_transcoded_to(fn) if tn is None: continue if not _do_check_file(fn, args) and not _do_check_file(tn, args): continue print(fn) print(' -> {0}'.format(tn)) fn_tags = history.get_tags_for(fn) print('- Tags: {0}'.format(repr(fn_tags))) adjusted_tags = False for t in tag_names: if t not in fn_tags or len(fn_tags[t].strip()) <= 0: tv = prompt_value(t) if tv is not None: fn_tags[t] = tv adjusted_tags = True else: print("Already handled {0}".format(t)) if adjusted_tags: if FF_PROBES.is_supported(fn): # Fix the source, too. try: set_tags_on_file(fn, fn_tags) # TODO This will make the checksums wrong, but, meh. except Exception as e: OUTPUT.error("Couldn't update tags on source file {0} ({1})".format( fn, e )) set_tags_on_file(tn, fn_tags) history.set_tags_for(fn, fn_tags) print("Finished with tag handling") return 0
def _cmd(self, history, args): if len(args) == 0: args = history.get_transcoded_filenames() OUTPUT.dict_start('transcoded_from') for tn in args: sources = [] sn = history.get_source_file_for_transcoded_filename(tn) if sn is not None: sources.append(sn) # Get the duplicates, so it traces all the files. sources.extend(history.get_duplicate_filenames(sn)) OUTPUT.list_section(tn, sources) OUTPUT.dict_end()
def _cmd(self, history, args): # FIXME HAAAAAACK # This should be fetched from elsewhere. base_destdir = sys.argv[1] OUTPUT.list_start('orphans') for dir_path, dir_names, file_names in os.walk(base_destdir): for filename in file_names: fqn = os.path.join(dir_path, filename) if is_media_file_supported(fqn) and os.path.isfile(fqn): src = history.get_source_file_for_transcoded_filename(fqn) if not src: OUTPUT.list_item(fqn) if '-f' in args: os.unlink(fqn) OUTPUT.list_end() return 0
def process(self, arg): if arg is None: OUTPUT.error('Must provide an argument for the option -t') return False, None p = arg.find(':') if p < 0: OUTPUT.error('Must provide a value') return False tag_name = arg[0:p].strip() if len(tag_name) <= 0: OUTPUT.error('Tag name cannot be zero-length') return False tag_value = None if p < len(arg): tag_value = arg[p + 1:].strip() if len(tag_value) <= 0: tag_value = None REPLACED_TAGS[tag_name] = tag_value return True
def _cmd(self, history, args): count = 0 if len(args) > 0: names = set() for name_like in args: names = names.union(history.get_source_files(name_like)) else: names = history.get_source_files() OUTPUT.dict_start('Sources') for fn in names: count += 1 OUTPUT.dict_start(fn) OUTPUT.dict_item('transcode', repr(history.get_transcoded_to(fn))) OUTPUT.list_section('duplicates', history.get_duplicate_filenames(fn)) OUTPUT.dict_end() if count <= 0: OUTPUT.error('No matching files in database') OUTPUT.dict_end() return 0
def _cmd(self, history, args): OUTPUT.list_start("Source-Info") for fn in args: OUTPUT.dict_start(fn) if not history.is_processed(fn): OUTPUT.dict_item('marked', False) sn = history.get_source_file_for_transcoded_filename(fn) OUTPUT.dict_item('transcoded_from', sn) continue OUTPUT.dict_item('marked', True) OUTPUT.dict_item('transcoded_to', history.get_transcoded_to(fn)) fn_keys = history.get_keywords_for(fn) dups = history.get_duplicates(fn) OUTPUT.dict_start('duplicates') for dn in dups: OUTPUT.dict_start(dn) dn_keys = history.get_keywords_for(dn) OUTPUT.list_section('common_keywords', list(dn_keys.intersection(fn_keys))) OUTPUT.dict_end() OUTPUT.dict_end() OUTPUT.dict_section('tags', history.get_tags_for(fn)) OUTPUT.list_section('keywords', list(fn_keys)) OUTPUT.dict_end() return 0
def print_entries(entries, history): if isinstance(entries, MediaEntry): entries = [entries] OUTPUT.start() OUTPUT.list_start("Source-Info") for entry in entries: assert isinstance(entry, MediaEntry) OUTPUT.dict_start(entry.source) OUTPUT.dict_item('marked', entry.is_marked) OUTPUT.dict_item('transcoded_to', entry.transcoded_to) OUTPUT.dict_item( 'transcoded_exists', os.path.isfile(entry.transcoded_to) if entry.transcoded_to else False) OUTPUT.dict_item('source_exists', os.path.isfile(entry.source)) OUTPUT.list_start('duplicates') for dn in entry.duplicate_filenames: #OUTPUT.dict_start(dn) #dn_keys = history.get_keywords_for(dn) #OUTPUT.list_section('common_keywords', list(dn_keys.intersection(fn_keys))) #OUTPUT.dict_end() OUTPUT.list_item(dn) OUTPUT.list_end() OUTPUT.dict_section('tags', entry.tags) # OUTPUT.list_section('keywords', entry.keywords) OUTPUT.dict_end() OUTPUT.list_end() OUTPUT.end()
def _cmd(self, history, args): force = False if args[0] == '-f': force = True args = args[1:] OUTPUT.list_start('affected_files') for fn in history.get_source_files(): tn = history.get_transcoded_to(fn) if tn is None: continue if not _do_check_file(fn, args) and not _do_check_file(tn, args): continue try: probe = probe_media_file(fn) except Exception as e: OUTPUT.error('Problem loading file {0}: {1}'.format(fn, e)) # traceback.print_exc() continue OUTPUT.list_dict_start() OUTPUT.dict_item('source_file', fn) OUTPUT.dict_item('transcoded_file', tn) fn_tags = history.get_tags_for(fn) probe_tags = probe.get_tags() new_tags = dict(fn_tags) altered_tags = False for tag_name, tag_value in probe_tags.items(): if force or tag_name not in fn_tags: if tag_name not in fn_tags or fn_tags[ tag_name] != tag_value: altered_tags = True new_tags[tag_name] = tag_value if altered_tags: OUTPUT.dict_start('original_tags') for tag_name, tag_value in fn_tags.items(): OUTPUT.dict_item(tag_name, tag_value) OUTPUT.dict_end() OUTPUT.dict_start('updated_tags') for tag_name, tag_value in new_tags.items(): OUTPUT.dict_item(tag_name, tag_value) OUTPUT.dict_end() set_tags_on_file(tn, new_tags) history.set_tags_for(fn, new_tags) OUTPUT.dict_end() OUTPUT.list_end() return 0
def _cmd(self, history, args): probe_cache = MediaCache(history) OUTPUT.list_start('abandoned_sources') for fn in history.get_source_files(): if os.path.isfile(fn): continue OUTPUT.list_dict_start() OUTPUT.dict_item('source', fn) tn = history.get_transcoded_to(fn) OUTPUT.dict_item('transcoded', tn) tn_exists = tn is not None and os.path.isfile(tn) OUTPUT.dict_item('transcoded_exists', tn_exists) if '-f' in args: if tn_exists and '-t' in args: OUTPUT.dict_item('transcoded_deleted', True) os.unlink(tn) else: OUTPUT.dict_item('transcoded_deleted', False) if tn: history.delete_transcoded_to(fn) history.delete_source_record(fn) else: OUTPUT.dict_item('transcoded_deleted', False) OUTPUT.list_dict_end() probe_cache.commit() OUTPUT.list_end() return 0
def _cmd(self, history, args): # FIXME HAAAAAACK # This should be fetched from elsewhere. base_destdir = sys.argv[1] probe_cache = MediaCache(history) normalize = args[0] search_for = args[1:] OUTPUT.list_start('transcoded_files') for fn in history.get_source_files(): if not _do_check_file(fn, search_for): continue current = probe_cache.get(fn) OUTPUT.list_dict_start() OUTPUT.dict_item('source_file', fn) destfile = transcode.transcode_correct_format( history, current.probe, get_destdir(base_destdir), verbose=False) OUTPUT.dict_item('transcoded_file', destfile) if destfile != current.transcoded_to: if os.path.exists(current.transcoded_to): os.replace(destfile, current.transcoded_to) destfile = current.transcoded_to else: current.set_transcoded_to(destfile) if normalize: output_fd, output_file = tempfile.mkstemp( suffix=os.path.splitext(destfile)[1]) try: headroom = 0.1 print("Normalizing file by {1:#.1f} into {0}".format( output_file, headroom)) os.close(output_fd) increase = normalize_audio(destfile, output_file, headroom) if increase is None: print("Can't normalize.") else: print("Increased volume by {0}dB".format(increase)) shutil.copyfile(output_file, destfile) finally: os.unlink(output_file) OUTPUT.dict_end() OUTPUT.list_end() probe_cache.commit() return 0
def _cmd(self, history, args): del_db = False del_files = False argp = 0 while argp < len(args): if args[argp] == '--db': del_db = True elif args[argp] == '--files': del_files = True else: break argp += 1 args = args[argp:] OUTPUT.list_start('deleted_transcoded_files') for fn in history.get_source_files(): tn = history.get_transcoded_to(fn) if tn is None: continue if not _do_check_file(fn, args) and not _do_check_file(tn, args): continue OUTPUT.list_dict_start() OUTPUT.dict_item('source_file', fn) OUTPUT.dict_item('transcoded_file', tn) did_delete = False if del_db: did_delete = history.delete_transcoded_to(fn) OUTPUT.dict_item('deleted_transcode_db_record', did_delete) did_delete = False if del_files: if os.path.isfile(tn): did_delete = True os.unlink(tn) OUTPUT.dict_item('deleted_transcode_file', did_delete) OUTPUT.dict_end() OUTPUT.list_end() return 0
def _parse_args(self, args): if len(args) <= 0: OUTPUT.error('Must provide at least one file matching argument') return False, [] return True, args
def _cmd(self, history, args): OUTPUT.list_start('affected_files') for fn in history.get_source_files(): tn = history.get_transcoded_to(fn) if tn is None: continue if not _do_check_file(fn, args) and not _do_check_file(tn, args): continue OUTPUT.list_dict_start() OUTPUT.dict_item('source_file', fn) OUTPUT.dict_item('transcoded_file', tn) fn_tags = history.get_tags_for(fn) new_tags = dict(fn_tags) adjusted_tags = False for tag_name, tag_value in REPLACED_TAGS.items(): if not (tag_name in fn_tags and fn_tags[tag_name] == tag_value): adjusted_tags = True new_tags[tag_name] = tag_value if adjusted_tags: OUTPUT.dict_start('original_tags') for tag_name, tag_value in fn_tags.items(): OUTPUT.dict_item(tag_name, tag_value) OUTPUT.dict_end() OUTPUT.dict_start('updated_tags') for tag_name, tag_value in new_tags.items(): OUTPUT.dict_item(tag_name, tag_value) OUTPUT.dict_end() if not PRETEND_MODE: if FF_PROBES.is_supported(fn): # Fix the source, too. try: set_tags_on_file(fn, new_tags) # TODO This will make the checksums wrong, but, meh. except Exception as e: OUTPUT.error( "Couldn't update tags on source file {0} ({1})" .format(fn, e)) set_tags_on_file(tn, new_tags) history.set_tags_for(fn, new_tags) OUTPUT.dict_end() OUTPUT.list_end() return 0