コード例 #1
0
 def report(*args, **kwargs):
     force = False
     if 'force' in kwargs:
         force = kwargs['force']
         kwargs.pop('force')
     if force or not silent:
         cyan(*args, **kwargs)
コード例 #2
0
ファイル: song.py プロジェクト: krissterckx/win_audio
 def print_tags(self,
                detailed=False,
                as_json=False,
                as_pprint=False,
                to_file=None,
                extended=False,
                header=True,
                subscript=None,
                highlight_title=False):
     if header and not to_file:
         stdout()
         if subscript:
             green(self.full_path(), end='')
             cyan(' (' + subscript + ')')
         else:
             green(self.full_path())
     track = self.get('TRACKNUMBER')
     fix_track = False
     if track.startswith('T'):
         track = track[1:]
         fix_track = True
     if fix_track:
         self.set('TRACKNUMBER', track)
     if detailed:
         self.print(extended, highlight_title)
     elif as_json or as_pprint:
         self.print_json(extended, as_pprint, to_file)
     else:
         self.echo()
コード例 #3
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
def test_file_manipulation_1():
    dryrun = False
    verbose = False
    silent = True
    safe_remove = False

    new_file('test1.txt', 'test1\n')
    duplicate_file('.',
                   'test1.txt',
                   'test2.txt',
                   dryrun=dryrun,
                   verbose=verbose,
                   silent=silent)
    rename_file('.',
                'test1.txt',
                'test3.txt',
                dryrun=dryrun,
                verbose=verbose,
                silent=silent)
    rename_file(
        '.',
        'test2.txt',
        'test3.txt',  # will give test3 (1).txt
        dryrun=dryrun,
        verbose=verbose,
        silent=silent)
    remove_file('.',
                'test3.txt',
                safe_remove=safe_remove,
                dryrun=dryrun,
                verbose=verbose,
                silent=silent)
    remove_file('.',
                'test3 (1).txt',
                safe_remove=safe_remove,
                dryrun=dryrun,
                verbose=verbose,
                silent=silent)
    cyan('test_file_manipulation_1 OK')
コード例 #4
0
ファイル: song.py プロジェクト: krissterckx/win_audio
 def diff(self,
          other,
          my_name=None,
          other_name=None,
          extended=False,
          print_on_diff=True,
          print_on_diff_f=None):
     diff = False
     tags = self.get_tag_keys(extended)
     my_name = my_name or self.name()
     other_name = other_name or other.name()
     for tag in tags:
         if self.get(tag) != other.get(tag):
             if not diff and print_on_diff:
                 if print_on_diff_f:
                     stdout(print_on_diff_f)
                 else:
                     cyan(tag, 'diff:',
                          self.get(tag), '(' + my_name + ') !=',
                          other.get(tag), '(' + other_name + ')')
             diff = True
             break
     return diff
コード例 #5
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
def test_file_manipulation_2():
    dryrun = False
    verbose = False
    silent = True
    safe_remove = False

    new_file('test1.txt', 'test1\n')
    copy_file('test1.txt',
              'test2.txt',
              dryrun=dryrun,
              verbose=verbose,
              silent=silent)
    move_file('test1.txt',
              'test3.txt',
              dryrun=dryrun,
              verbose=verbose,
              silent=silent)
    move_file(
        'test2.txt',
        'test3.txt',  # will vive test3 (1).txt file
        dryrun=dryrun,
        verbose=verbose,
        silent=silent)
    remove_file('.',
                'test3.txt',
                safe_remove=safe_remove,
                dryrun=dryrun,
                verbose=verbose,
                silent=silent)
    remove_file('.',
                'test3 (1).txt',
                safe_remove=safe_remove,
                dryrun=dryrun,
                verbose=verbose,
                silent=silent)
    cyan('test_file_manipulation_2 OK')
コード例 #6
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
def test_to_camel_case():
    assert_equal('Max Don\'t Have Sex With Your Ex',
                 to_camel_case("Max Don’t Have Sex With Your Ex"))
    assert_equal('Please Don\'t Go', to_camel_case('Please Don\'t Go'))
    assert_equal('An Angel \'s Love', to_camel_case('An angel \'s love'))
    assert_equal('The Cook And The Thief',
                 to_camel_case('The cook and the thief'))
    assert_equal('Kris\'s Book', to_camel_case('Kris\'s book'))
    assert_equal('I\'m Singin\' ABC', to_camel_case('I\'M singin\' ABC'))
    assert_equal('I Am The DJ', to_camel_case('I am the DJ'))
    assert_equal('I\'m From The 80ies', to_camel_case('I\'m from the 80ies'))
    assert_equal('You\'re From The 70s', to_camel_case('You\'re from the 70s'))
    assert_equal('DON\'T YOU', to_camel_case('DON\'T YOU'))
    assert_equal('L\'Envie Des Etoilles',
                 to_camel_case('L\'Envie des Etoilles'))
    assert_equal('S\'Express', to_camel_case('S\'Express'))
    assert_equal('Charlotte De Witte', to_camel_case('Charlotte de Witte'))
    assert_equal('X (Extasy)', to_camel_case('x (Extasy)'))
    assert_equal('Annie x Billie', to_camel_case('Annie x Billie'))
    assert_equal('deadmau5 Preserved',
                 to_camel_case('deadmau5 preserved', ['deadmau5']))
    assert_equal('As Is feat.', to_camel_case('As is feat.'))
    assert_equal('Du Bist Hanz', to_camel_case('du bist hanz'))
    cyan('test_to_camel_case OK')
コード例 #7
0
ファイル: audit_songs.py プロジェクト: krissterckx/win_audio
 def report(*args, **kwargs):
     if not silent:
         cyan(*args, **kwargs)
コード例 #8
0
 def report(*report_args, **report_kwargs):
     if not silent:
         cyan(*report_args, **report_kwargs)
コード例 #9
0
def fix_indexed_songs(path,
                      song_fs,
                      dryrun=True,
                      safe_remove=True,
                      verbose=False,
                      silent=False,
                      debug=False):
    def report(*args, **kwargs):
        force = False
        if 'force' in kwargs:
            force = kwargs['force']
            kwargs.pop('force')
        if force or not silent:
            cyan(*args, **kwargs)

    def retag(song, new_title):
        if not silent:
            stdout('Retagging to', new_title)
        song.set('TITLE', new_title)
        song.save(dryrun)

    cnt = 0

    for song_f in song_fs:
        for i in range(99):
            suffix = ' (' + str(i) + ')' + SONG_FILE_EXT
            if song_f.endswith(suffix):
                stripped = song_f[:-len(suffix)]
                stripped_f = stripped + SONG_FILE_EXT
                s = Song(path=path, song_f=song_f, debug=debug)

                if stripped_f in song_fs:
                    report('Resolving conflict with', stripped_f)
                    t = s.parse_track_nbr()
                    s_stripped = Song(path=path,
                                      song_f=stripped_f,
                                      debug=debug)
                    t_stripped = s_stripped.parse_track_nbr()
                    stripped_j = song_f[:-len(SONG_FILE_EXT)]  # reasonable
                    stripped_j_f = song_f  # -                   defaults
                    for j in range(2, 99):
                        stripped_j = stripped + ' -' + str(j) + '-'
                        stripped_j_f = stripped_j + SONG_FILE_EXT
                        if stripped_j_f not in song_fs:
                            break
                    if t < t_stripped:
                        report(
                            'New',
                            song_f,
                            'becomes',
                            stripped_f,
                            # and original stripped becomes stripped_j
                            'as its track number is lower',
                            force=True)
                        retag(s, stripped)
                        rename_file(path,
                                    song_f,
                                    stripped_f,
                                    dryrun=dryrun,
                                    verbose=verbose,
                                    silent=silent,
                                    debug=debug)
                        retag(s_stripped, stripped_j)
                        rename_file(path,
                                    stripped_f,
                                    stripped_j_f,
                                    dryrun=dryrun,
                                    safe_rename=not dryrun,
                                    verbose=verbose,
                                    silent=silent,
                                    debug=debug)
                    elif t > t_stripped:
                        report(
                            'New',
                            song_f,
                            'becomes',
                            stripped_j_f,
                            # and original stripped remains
                            'as its track number is higher',
                            force=True)
                        retag(s, stripped_j)
                        rename_file(path,
                                    song_f,
                                    stripped_j_f,
                                    dryrun=dryrun,
                                    verbose=verbose,
                                    silent=silent,
                                    debug=debug)
                    else:
                        report('Track numbers match!')
                        report('Comparing sample rates')
                        s1 = int(s.get('#samplerate'))
                        s2 = int(s_stripped.get('#samplerate'))
                        if s1 > s2:
                            report('New',
                                   song_f,
                                   'wins (' + str(s1),
                                   'over',
                                   str(s2) + ')',
                                   force=True)
                            alert('Removing', path, stripped_f)
                            remove_file(path,
                                        stripped_f,
                                        safe_remove=safe_remove,
                                        dryrun=dryrun,
                                        verbose=verbose,
                                        silent=silent,
                                        debug=debug)
                            retag(s, stripped)
                            rename_file(path,
                                        song_f,
                                        stripped,
                                        dryrun=dryrun,
                                        safe_rename=not dryrun,
                                        verbose=verbose,
                                        silent=silent,
                                        debug=debug)
                        elif s1 < s2:
                            report('Existing',
                                   stripped_f,
                                   'wins (' + str(s2),
                                   'over',
                                   str(s1) + ')',
                                   force=True)
                            alert('Removing', path, song_f)
                            remove_file(path,
                                        song_f,
                                        safe_remove=safe_remove,
                                        dryrun=dryrun,
                                        verbose=verbose,
                                        silent=silent,
                                        debug=debug)
                        else:
                            report('Sample rates match!')
                            report('Comparing length')
                            l1 = int(s.get('#length'))
                            l2 = int(s_stripped.get('#length'))
                            if l1 > l2:
                                cyan('New',
                                     song_f,
                                     'wins (' + str(l1),
                                     'over',
                                     str(l2) + ')',
                                     force=True)
                                alert('Removing', path, song_f)
                                remove_file(path,
                                            stripped_f,
                                            safe_remove=safe_remove,
                                            dryrun=dryrun,
                                            verbose=verbose,
                                            silent=silent,
                                            debug=debug)
                                retag(s, stripped)
                                rename_file(path,
                                            song_f,
                                            stripped_f,
                                            dryrun=dryrun,
                                            safe_rename=not dryrun,
                                            verbose=verbose,
                                            silent=silent,
                                            debug=debug)
                            else:
                                report('Existing',
                                       stripped_f,
                                       'wins (' + str(l2),
                                       'over',
                                       str(l1) + ')',
                                       force=True)
                                alert('Removing', path, song_f)
                                remove_file(path,
                                            song_f,
                                            safe_remove=safe_remove,
                                            dryrun=dryrun,
                                            verbose=verbose,
                                            silent=silent,
                                            debug=debug)
                else:
                    report('Fixing', song_f, 'to', stripped + SONG_FILE_EXT)
                    retag(s, stripped)
                    rename_file(path,
                                song_f,
                                stripped_f,
                                dryrun=dryrun,
                                verbose=verbose,
                                silent=silent,
                                debug=debug)

                cnt += 1

            if not dryrun and cnt:
                break

        if not dryrun and cnt:
            break

    return cnt
コード例 #10
0
ファイル: review_songs.py プロジェクト: krissterckx/win_audio
def main():
    program = 'review_songs'
    description = '''
    Review songs based on user input
    '''

    parser = argparse.ArgumentParser(prog=program,
                                     description=description)
    parser.add_argument('-j', '--project-filter', type=str,
                        help='Set project filter')
    parser.add_argument('-a', '--artist-filter', type=str,
                        help='Set artist filter')
    parser.add_argument('-b', '--album-filter', type=str,
                        help='Set album filter')
    parser.add_argument('-c', '-t', '--title-filter', type=str,
                        help='Set title filter')
    parser.add_argument('-x', '--path', type=str, help='Sets root path')
    parser.add_argument('-r', '--review-stamps',
                        help='Create/Use review stamps', action='store_true')
    parser.add_argument('-v', '--verbose',
                        help='Enable verbose', action='store_true')
    parser.add_argument('-s', '--silent',
                        help='Enable silence', action='store_true')
    parser.add_argument('-rs', '--radio-silent', help='Enable radio silence',
                        action='store_true')
    parser.add_argument('-d', '--debug',
                        help='Enable debug', action='store_true')

    args = parser.parse_args()
    root = args.path or get_default_root()
    radio_silent = args.radio_silent or get_env_var('RADIO_SILENT')
    silent = args.silent or get_env_var('SILENT') or radio_silent
    debug = args.debug or get_env_var('DEBUG')
    verbose = args.verbose or get_env_var('VERBOSE') or debug

    assert_non_empty_dir(root)

    project_filter = args.project_filter
    artist_filter = args.artist_filter
    album_filter = args.album_filter
    title_filter = args.title_filter
    review_stamps = args.review_stamps

    if title_filter and title_filter.lower().endswith(SONG_FILE_EXT):
        title_filter = title_filter[:-len(SONG_FILE_EXT)]

    for dir_name, _, song_fs in os.walk(root):
        # gotcha... this doesn't work if i specify a full detailed path, up
        # to the album dir ...
        process, project, artist, album = process_songs_dir(
            root, dir_name, project_filter, artist_filter, album_filter)

        if process:
            path = root + '/' + project + '/' + artist + '/' + album
            reviewed_mark = path + '/.reviewed'
            if review_stamps and is_file(reviewed_mark):
                if debug:
                    cyan('Skipping', project, '/', artist, '/', album)
            else:
                review_songs(path, song_fs, title_filter,
                             verbose=verbose, silent=silent,
                             radio_silent=radio_silent,
                             debug=debug)
                if review_stamps:
                    new_mark_file(reviewed_mark)
コード例 #11
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
def test_file_extension():
    f = 'grease/is/the.word'
    f_base, f_ext = split_file_extension(f)
    assert_equal('grease/is/the', f_base)
    assert_equal('.word', f_ext)
    cyan('test_file_extension OK')
コード例 #12
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
def test_error():
    error('wooo...bad (just kidding)')
    error('wooo...bad', end=' (just kidding!)\n')
    cyan('test_error OK')
コード例 #13
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
def test_windows():
    f_yellow('You are on {}Windows', '' if is_windows() else 'non-')
    cyan('test_windows OK')
コード例 #14
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
def test_colours():
    stdout('USA is ', end='')
    red('stars ', end='')
    stdout('and ', end='')
    blue('stripes')
    cyan('test_colours OK')
コード例 #15
0
ファイル: audit_songs.py プロジェクト: krissterckx/win_audio
def audit_song(root,
               project,
               artist_d,
               album_d,
               song_f,
               reset_artist_ref,
               reset_album_ref,
               dir_structure_as_ref=False,
               set_artist=None,
               set_album=None,
               set_song=None,
               force_write=False,
               dryrun=True,
               verbose=False,
               silent=False,
               debug=False):
    global errors_fixed, errors_unresolved, sung_it

    def debug_out(*args, **kwargs):
        if debug:
            stdout(ConsoleColors.ENDC, end='')
            stdout(*args, **kwargs)

    debug_out('audit_song:', root, project, artist_d, album_d, song_f)

    song = Song(root, project, artist_d, album_d, song_f=song_f, debug=debug)

    title_f = song_f[:-len(SONG_FILE_EXT)]
    pre_errors_fixed = errors_fixed

    keep = {}
    init_the_song = '*** UNINITIALIZED ***'
    sung_it = False

    def keep_it():
        for _tag in ('TITLE', 'ALBUM', 'ARTIST', 'ALBUMARTIST'):
            keep[_tag] = song.get(_tag)

    def force_it():
        keep['TITLE'] = ''
        sing_it()
        cyan('FORCE-WRITING TITLE ', end='')

    def save_it():
        song.save(dryrun)

    def print_it(p_tags=None, offset=4):
        p_tags = p_tags or song.get_tags()
        for _tag in Song.get_tag_keys():
            if _tag == 'TRACKNUMBER':
                continue  # skip
            stdout(' ' * offset + _tag + ': \'' + p_tags[_tag] + '\'')

    def sing_it(force=False):
        global sung_it  # python 3 can do nonlocal but in py2 is readonly
        elaborated = False
        if not silent and (force or not sung_it):
            if elaborated:
                stdout(init_the_song, end='')  # sing it
            else:
                yellow('Fixing', project, '/', artist_d, '/', album_d, '/',
                       song_f)
            sung_it = True

    def did_it():
        for _tag in ('TITLE', 'ALBUM', 'ARTIST', 'ALBUMARTIST'):
            if song.get(_tag) != keep[_tag]:
                return True
        return False

    def report(*args, **kwargs):
        if not silent:
            cyan(*args, **kwargs)

    def replace_name(name):
        set_name = None
        suffix = None

        if name.endswith('-'):  # -X- assumed
            for i in range(999):
                s = ' -{}-'.format(i)
                if name.endswith(s):
                    suffix = s
                    truncated_name = name[:-len(s)]
                    debug_out('Checking', truncated_name, 'instead of', name)
                    name = truncated_name
                    break

        e = to_camel_case(name, PRESERVED_NAMES)
        if e != name:
            set_name = e
            name = set_name

        done = False
        while not done:
            done = True
            for c in (' ', ',', ';', ':', '&'):
                while name.endswith(c):
                    set_name = name[:-1]
                    done = False
                    name = set_name

        if name == '?':
            set_name = 'Q'
        else:
            prev_name = name
            for c in REPLACE_CHARS:
                name = name.replace(c, REPLACE_CHARS[c])
            if name != prev_name:
                set_name = name

        if set_name and suffix:
            set_name += suffix

        if set_name:
            debug_out('replace_name: replaced', name, 'to', set_name)

        return set_name

    def fix_dir_name(name):
        if name.endswith('.'):
            # WINDOWS DOESN'T DEAL WITH DOTS AT END OF A DIRECTORY...
            name = name[:-1] + '. ()'
        return name

    def tag_to_filesystem_name(name, is_dir):
        if is_dir:
            name = fix_dir_name(name)
        for c in TOLERATED_CHARS_IN_TAGS_REPLACED_TO_IN_FILESYSTEM:
            name = name.replace(
                c, TOLERATED_CHARS_IN_TAGS_REPLACED_TO_IN_FILESYSTEM[c])
        for c in ascii_letters:
            name = name.replace(c + '- ', c + ' - ')
        return name

    def fix_artist_tag():
        artist = song.get('ALBUMARTIST')
        t = FIX_ARTIST_TAGS.get(artist)
        if t:
            sing_it()
            report('FIXING ARTIST ', end='')
            song.set('ALBUMARTIST', t)
            return t
        else:
            return None

    def fix_artist_dir():
        d = FIX_ARTIST_DIRS.get(artist_d)
        if d:
            sing_it()
            report('FIX_ARTIST_DIR [Renaming dir', artist_d, 'to', d + ']')
            # mind, actual rename is not done here!
            return d
        return None

    def fix_album_tag():
        album = song.get('ALBUM')
        t = FIX_ALBUM_TAGS.get(album)
        if t:
            sing_it()
            report('FIXING ALBUM ', end='')
            song.set('ALBUM', t)
            return t
        else:
            return None

    def fix_tags_for_camel_case_and_more():
        for tag in ('TITLE', 'ALBUM', 'ARTIST', 'ALBUMARTIST'):
            t_tag = song.get(tag)

            debug_out('Processing', tag, '=', t_tag)

            if t_tag:
                new_tag = replace_name(t_tag)

                # replace comma's in artist
                if tag == 'ALBUMARTIST':
                    t_cur = new_tag if new_tag else t_tag
                    t_new = t_cur
                    for c in REPLACE_CHARS_IN_ARTISTS_ONLY:
                        t_new = t_new.replace(c,
                                              REPLACE_CHARS_IN_ARTISTS_ONLY[c])
                    if t_new != t_cur:
                        new_tag = t_new
                        sing_it()
                        report('FIXING ALBUMARTIST [' + new_tag + '] ', end='')
                        song.set(tag, new_tag, straight_overwrite_artist=True)

                # extra logic (eventually can go)
                def retag(name):
                    for r in REPLACE_CHARS_IN_TAGS_ONLY:
                        name = name.replace(r, REPLACE_CHARS_IN_TAGS_ONLY[r])
                    return name

                if new_tag:
                    new_tag = retag(new_tag)
                else:
                    old_t = t_tag
                    t_tag = retag(t_tag)
                    if t_tag != old_t:
                        new_tag = t_tag
                # end of extra logic (eventually can go)

                if new_tag:
                    sing_it()
                    report('FIXING NAME [' + new_tag + '] ', end='')
                    song.set(tag, new_tag)

    def fix_dirs_for_camel_case_and_more():
        debug_out('fix_dirs_for_camel_case_and_more')

        return (replace_name(set_artist if set_artist else artist_d),
                replace_name(set_album if set_album else album_d),
                replace_name(set_song if set_song else title_f))

    def fix_collection_albums():
        debug_out('fix_collection_albums')

        if song.get('ALBUM') in COLLECTION_ALBUMS:
            album_t = song.get('ALBUM')
            overwrite = u(a_else_b(COLLECTION_ALBUMS[album_t], album_t))

            if song.get('ALBUMARTIST') != overwrite:
                sing_it()
                report('COLLECTION:RENAMING ', end='')
                song.set('ALBUM', overwrite)
                song.set('ALBUMARTIST', overwrite)

            if overwrite not in song.get('ARTIST'):
                sing_it()
                if song.get('ARTIST').endswith(keep['ALBUM']):
                    report('COLLECTION:STRIPPING ', end='')
                    song.set('ARTIST',
                             song.get('ARTIST')[:-(len(keep['ALBUM']) + 2)])
                song.set('ARTIST', song.get('ARTIST') + ', ' + overwrite)
                report('COLLECTION:MARKING ', end='')

    def truncate_artists():
        while True:
            song_artist = song.get('ALBUMARTIST')
            artist = song.get('ARTIST')
            if song_artist:
                if ',' in song_artist:
                    sing_it()
                    report('TRUNCATING ALBUMARTIST', end='')
                    song.set('ALBUMARTIST',
                             song.get('ALBUMARTIST').split(',')[0])

                if song.get('ALBUMARTIST') not in song.get('ARTIST'):
                    song.set(
                        'ARTIST',
                        song.get('ARTIST') + ', ' + song.get('ALBUMARTIST'))
                break

            elif artist:
                sing_it()
                report('FIXING ALBUMARTIST ', end='')
                if ',' in artist:
                    song.set('ALBUMARTIST', song.get('ARTIST').split(',')[0])
                else:
                    song.set('ALBUMARTIST', song.get('ARTIST'))

            else:
                error('No ARTIST and no ALBUMARTIST?')
                error(project, '/', artist_d, '/', album_d, '/', song_f, '\n')
                break

    def finish_it():
        global errors_fixed

        debug_out('finish_it')

        artist = song.get('ALBUMARTIST')
        contributing_artists = song.get('ARTIST')
        album = song.get('ALBUM')
        title = song.get('TITLE')

        if sung_it:
            report('OK')
        if did_it():
            if silent:
                green('Retagged', project, '/', artist,
                      '(' + contributing_artists + ') /', album, '/', title)
            else:
                stdout('WAS:')
                print_it(keep)
                stdout('BECAME:')
                print_it()
            save_it()  # this is the moment where we save!
            errors_fixed += 1

    def audit_entity(entity_tag, unrooted_entity_path_root, is_file,
                     file_extension, entity_d, entity, set_entity):
        global errors_fixed, errors_unresolved

        debug_out('audit_entity:', entity_tag, unrooted_entity_path_root,
                  is_file, file_extension, entity_d, entity, set_entity)

        def retag(to):
            green('Retagging', unrooted_entity_path_root.replace('/', ' / '),
                  '/', entity, 'to', to)
            # TODO(do we need to save here?)
            song.set(entity_tag, to, save=True, dryrun=dryrun)

        def rename(to):
            rooted_entity_path_root = root + '/' + unrooted_entity_path_root
            if is_file:
                green('Renaming',
                      unrooted_entity_path_root.replace('/', ' / '), '/',
                      entity_d + file_extension, 'to', to + file_extension)
                rename_file(rooted_entity_path_root,
                            entity_d + file_extension,
                            to + file_extension,
                            safe_rename=True,
                            add_suffix_if_exists=True,
                            dryrun=dryrun,
                            verbose=verbose,
                            silent=silent,
                            debug=debug)
            elif (path_exists(rooted_entity_path_root + '/' + to)
                  and not (is_windows() and entity_d.lower() == to.lower())):
                green('Merging', unrooted_entity_path_root, '/', entity_d,
                      'into', to)
                merge_dir(rooted_entity_path_root + '/' + entity_d,
                          rooted_entity_path_root + '/' + to,
                          safe_merge=True,
                          add_suffix_if_exists=True,
                          merge_subdirs=True,
                          dryrun=dryrun,
                          verbose=verbose,
                          silent=silent,
                          debug=debug)
            else:
                green('Renaming',
                      unrooted_entity_path_root.replace('/', ' / '), '/',
                      entity_d, 'to', to)
                rename_dir(rooted_entity_path_root,
                           entity_d,
                           to,
                           safe_rename=False,
                           dryrun=dryrun,
                           verbose=verbose,
                           silent=silent,
                           debug=debug)

        if set_entity:
            debug_out('audit_entity:', entity_tag, 'set to', set_entity)
            modified = False
            if entity != set_entity:
                sing_it()
                retag(set_entity)
                errors_fixed += 1
                modified = True
            c_set_entity = tag_to_filesystem_name(set_entity, not is_file)
            if entity_d != c_set_entity:
                sing_it()
                rename(c_set_entity)
                errors_fixed += 1
                modified = True
            return c_set_entity if modified else None

        else:
            c_entity = tag_to_filesystem_name(entity, not is_file)
            if c_entity != entity_d and entity_d != JOKER_VALUE:
                if dir_structure_as_ref:
                    sing_it()
                    retag(entity_d)
                    errors_fixed += 1
                    return entity_d
                else:
                    sing_it()
                    rename(c_entity)
                    errors_fixed += 1
                    return c_entity

    def audit_artist(set_it):
        artist = song.get('ALBUMARTIST')
        return audit_entity('ALBUMARTIST', project, False, None, artist_d,
                            artist, set_it)

    def audit_album(set_it):
        album = song.get('ALBUM')
        return audit_entity('ALBUM', project + '/' + artist_d, False, None,
                            album_d, album, set_it)

    def audit_title(set_it):
        title = song.get('TITLE')
        return audit_entity('TITLE', project + '/' + artist_d + '/' + album_d,
                            True, SONG_FILE_EXT, title_f, title, set_it)

    orig_artist_d = artist_d
    orig_album_d = album_d
    orig_title_d = title_f

    if dir_structure_as_ref:
        artist_mod = fix_artist_dir()
        if artist_mod:
            set_artist = set_artist or artist_mod
            if not dryrun:
                cyan('(Resetting ARTIST)')
                reset_artist_ref[0] = set_artist

        artist_mod, album_mod, title_mod = fix_dirs_for_camel_case_and_more()

        if artist_mod:
            set_artist = set_artist or artist_mod  # mind, despite efforts to
            #                                        correct it, when was pre-
            #                                        set, we stick to what was
            #                                        set (manually or via
            #                                             fix_artist_dir)
            if not dryrun and not reset_artist_ref[0]:
                cyan('(Resetting ARTIST)')
                reset_artist_ref[0] = set_artist

        if album_mod:
            set_album = set_album or album_mod  # mind, same here, but then
            #                                     only for previously manually
            #                                     set in this case
            if not dryrun:
                cyan('(Resetting ALBUM)')
                reset_album_ref[0] = set_album

        if title_mod:
            set_song = set_song or title_mod

    else:
        keep_it()
        if force_write:
            force_it()
        fix_artist_tag()
        fix_album_tag()
        fix_tags_for_camel_case_and_more()
        fix_collection_albums()
        truncate_artists()
        finish_it()

    modified_to = audit_artist(set_artist)
    if modified_to and not dir_structure_as_ref:
        artist_d = modified_to
        if not dryrun:
            cyan('(Resetting ARTIST)')
            reset_artist_ref[0] = modified_to
    artist_d = fix_dir_name(artist_d)  # always

    modified_to = audit_album(set_album)
    if modified_to and not dir_structure_as_ref:
        album_d = modified_to
        if not dryrun:
            cyan('(Resetting ALBUM)')
            reset_album_ref[0] = modified_to
    album_d = fix_dir_name(album_d)  # always

    modified_to = audit_title(set_song)
    if modified_to and not dir_structure_as_ref:
        title_f = modified_to

    number_modified = errors_fixed > pre_errors_fixed
    if number_modified:
        fixed_songs.append(root + '/' + project + '/' +
                           # if dryrun, files aren't actually changed
                           (orig_artist_d if dryrun else artist_d) + '/' +
                           (orig_album_d if dryrun else album_d) + '/' +
                           (orig_title_d if dryrun else title_f) +
                           SONG_FILE_EXT)
    return number_modified
コード例 #16
0
ファイル: review_songs.py プロジェクト: krissterckx/win_audio
def review_songs(path, song_files, title_filter,
                 detailed=True, sort=True,
                 verbose=False, silent=False, radio_silent=False, debug=False):
    songs = []

    filtered_songs, missed_songs, _, _, _ = get_filtered_songs(
        path, song_files, title_filter=title_filter,
        sort_per_track=sort, post_process_songs=sort,
        print_header=not silent,
        verbose=verbose, silent=silent, no_warn=radio_silent, debug=debug)

    if not filtered_songs:
        return

    for track_nbr in sorted(filtered_songs):
        for song in filtered_songs[track_nbr]:
            songs.append(song)

    PAGE_SIZE = 20
    done = False
    idx = 1

    def option_title(title_idx):
        s = songs[title_idx - 1]
        # noinspection PyTypeChecker
        title = s.get('TITLE')
        if detailed:
            # noinspection PyTypeChecker
            track_nr = s.get('TRACKNUMBER')
            title += (' (' + track_nr + ')')
        option(title_idx, title)

    while not done:
        if idx > len(songs):
            break

        default = idx - 1
        stdout()
        option(default, 'None')

        for _ in range(PAGE_SIZE):
            if idx > len(songs):
                done = True
                break
            option_title(idx)
            idx += 1

        def add_options(_idx):
            _add_tags = None

            def _add_option(_s, _i):
                option(_i, _s)
                return _i, _i + 1

            if missed_songs:
                _add_tags, _idx = _add_option('-- ADD .missing TAGS --', _idx)
            _reload, _idx = _add_option('-- RELOAD --', _idx)
            _exit_the_game, _idx = _add_option('-- EXIT --', _idx)

            return _add_tags, _reload, _exit_the_game

        add_tags, reload, exit_the_game = add_options(idx)
        stdout()

        while True:
            c = numerical_input('Song to edit', default, exit_the_game)
            if missed_songs and c == add_tags:
                stdout()
                for missed in missed_songs:
                    add_missing_file(missed[0], missed[1], dryrun=False)
                stdout()
                c = None

            elif c == reload:
                stdout()
                option(default, 'None')
                for i in range(default + 2, idx):
                    option_title(i)
                add_options(idx)
                cyan('(mind, not re-sorted)')
                cyan()
                c = None

            elif c == exit_the_game:
                cyan('Bye.')
                end()

            elif c == default:
                break

            if c is not None:
                stdout()
                song_idx = c - 1
                songs[song_idx] = edit_song(songs[song_idx], debug=debug)
コード例 #17
0
ファイル: audit_songs.py プロジェクト: krissterckx/win_audio
 def force_it():
     keep['TITLE'] = ''
     sing_it()
     cyan('FORCE-WRITING TITLE ', end='')
コード例 #18
0
ファイル: test_base.py プロジェクト: krissterckx/win_audio
        dryrun=dryrun,
        verbose=verbose,
        silent=silent)
    remove_file('.',
                'test3.txt',
                safe_remove=safe_remove,
                dryrun=dryrun,
                verbose=verbose,
                silent=silent)
    remove_file('.',
                'test3 (1).txt',
                safe_remove=safe_remove,
                dryrun=dryrun,
                verbose=verbose,
                silent=silent)
    cyan('test_file_manipulation_2 OK')


if __name__ == "__main__":
    test_colours()
    test_windows()
    test_error()
    test_to_camel_case()
    test_file_extension()
    test_file_manipulation_1()
    test_file_manipulation_2()
    green('ALL TESTS PASS. Happy day :)')
    cyan('Final test is a fatal error:')
    fatal_error('The world exploded')
    error('SHOULD NOT HAVE COME HERE!')