예제 #1
0
 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]
예제 #2
0
 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:]]
예제 #3
0
 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()
예제 #4
0
 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
예제 #5
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
예제 #6
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()
예제 #7
0
    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
예제 #8
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
예제 #9
0
 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
예제 #10
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
예제 #11
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()
예제 #12
0
    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
예제 #13
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
예제 #14
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
예제 #15
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
예제 #16
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
예제 #17
0
    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