コード例 #1
0
ファイル: models.py プロジェクト: lamby/musicdb
    def tag(self):
        data = self.get_parent_instance().metadata()

        with tempfile.NamedTemporaryFile(suffix='-musicdb.mp3') as f:
            # Download
            with default_storage.open(self.file.location) as g:
                contents = g.read()

            f.write(contents)
            f.flush()
            f.seek(0)

            audio = MutagenFile(f.name)
            audio.delete()

            if isinstance(audio, mp3.MP3):
                audio.tags = easyid3.EasyID3()

            audio.update(data)
            audio.save()

            self.length = int(audio.info.length)

            # Copy it back
            default_storage.delete(self.file.location)
            dst = default_storage.save(self.file.location, DjangoFile(f))

            assert dst == self.file.location
コード例 #2
0
ファイル: tagging.py プロジェクト: MechanisM/musicdb
def tag(filename, data):
    audio = File(filename)
    audio.delete()
    if isinstance(audio, mp3.MP3):
        audio.tags = easyid3.EasyID3()
    audio.update(data)
    audio.save()
コード例 #3
0
    def tag(self):
        data = self.get_parent_instance().metadata()

        with tempfile.NamedTemporaryFile(suffix='-musicdb.mp3') as f:
            # Download
            with default_storage.open(self.file.location) as g:
                contents = g.read()

            f.write(contents)
            f.flush()
            f.seek(0)

            audio = MutagenFile(f.name)
            audio.delete()

            if isinstance(audio, mp3.MP3):
                audio.tags = easyid3.EasyID3()

            audio.update(data)
            audio.save()

            self.length = int(audio.info.length)

            # Copy it back
            default_storage.delete(self.file.location)
            dst = default_storage.save(self.file.location, DjangoFile(f))

            assert dst == self.file.location
コード例 #4
0
def apply_tags(file_path, tag_list):
    """
    Using mutagen, apply the tags to the file.
    """

    if file_path.endswith(".mp3"):
        muta = EasyID3(file_path)
    elif file_path.endswith(".m4a"):
        muta = EasyMP4(file_path)
    else:
        muta = File(file_path)

    for key in tag_list:
        muta.update({key: tag_list[key]})

    muta.save()
コード例 #5
0
ファイル: models.py プロジェクト: MechanisM/musicdb
 def tag(self):
     try:
         data = self.get_parent_instance().metadata()
         filename = os.path.join(settings.MEDIA_LOCATION, self.file.location)
         audio = MutagenFile(filename)
         audio.delete()
         if isinstance(audio, mp3.MP3):
             audio.tags = easyid3.EasyID3()
         audio.update(data)
         audio.save()
     except:
         self.tags_dirty = None
         self.save()
         raise
     finally:
         self.tags_dirty = False
         self.save()
コード例 #6
0
 def tag(self):
     try:
         data = self.get_parent_instance().metadata()
         filename = os.path.join(settings.MEDIA_LOCATION,
                                 self.file.location)
         audio = MutagenFile(filename)
         audio.delete()
         if isinstance(audio, mp3.MP3):
             audio.tags = easyid3.EasyID3()
         audio.update(data)
         audio.save()
     except:
         self.tags_dirty = None
         self.save()
         raise
     finally:
         self.tags_dirty = False
         self.save()
コード例 #7
0
ファイル: flac2wavpack.py プロジェクト: mineo/bin
def transfer_tags(flacfile, wavpackfile):
    """docstring for transfer_tags"""
    fl = File(flacfile)
    wv = File(wavpackfile)
    wv.update(fl)

    try:
        wv["track"] = wv["tracknumber"]
        del wv["tracknumber"]
        if wv["totaltracks"]:
           wv["track"] = wv["track"][0] + "/" + wv["totaltracks"][0]
           del wv["totaltracks"]
        wv["disc"] = wv["discnumber"]
        del wv["discnumber"]
        if wv["totaldiscs"]:
           wv["disc"] = wv["disc"][0] + "/" + wv["totaldiscs"][0]
           del wv["totaldiscs"]
    except KeyError:
        pass

    wv.save()
コード例 #8
0
ファイル: main.py プロジェクト: NuarkNoir/YaMusicDownloader
def download_playlist(playlist: Playlist, force_redownload=False):
    for short_track in playlist.tracks:
        track = short_track.track
        print(f"Downloading `{track.artists[0]['name']} - {track.title}`",
              end="... ")
        if not track.available:
            print("not available")
            continue

        track_path = os.path.normpath(
            os.path.join(strip_bad_symbols(track.artists[0]['name']),
                         strip_bad_symbols(track.albums[0]['title'])))

        os.makedirs(track_path, exist_ok=True)
        os.chdir(track_path)

        file_name = strip_bad_symbols(f'{track.title}')
        used_codec = None
        for info in sorted(track.get_download_info(),
                           key=lambda x: x['bitrate_in_kbps'],
                           reverse=True):
            codec = info['codec']
            bitrate = info['bitrate_in_kbps']
            full_file_name = f'{file_name}.{codec}'
            # file is not created 'til all bytes of it recieved,
            # so we can check if track was already downloaded
            # by just checking its existence on disk
            if os.path.exists(full_file_name) and not force_redownload:
                used_codec = codec  # to prevent wrong `unknown downloading error` message
                break
            try:
                track.download(full_file_name,
                               codec=codec,
                               bitrate_in_kbps=bitrate)
                used_codec = codec
                break
            except (YandexMusicError, TimeoutError):
                continue

        if not used_codec:
            print("unknown downloading error")
            continue

        cover_filename = file_name + ".jpg"
        track.download_cover(cover_filename, size="300x300")
        file = File(f'{file_name}.{used_codec}')
        file.update({
            # Title
            'TIT2':
            TIT2(encoding=3, text=track.title),
            # Artist
            'TPE1':
            TPE1(encoding=3,
                 text=DELIMITER.join(i['name'] for i in track.artists)),
            # Album
            'TALB':
            TALB(encoding=3,
                 text=DELIMITER.join(i['title'] for i in track.albums)),
            # Year
            'TDRC':
            TDRC(encoding=3, text=str(track.albums[0]['year'])),
            # Picture
            'APIC':
            APIC(encoding=3,
                 text=cover_filename,
                 data=open(cover_filename, 'rb').read())
        })
        lyrics = client.track_supplement(track.track_id).lyrics
        if lyrics:
            # Song lyrics
            file.tags.add(USLT(encoding=3, text=lyrics.full_lyrics))

        file.save()
        os.chdir(pwd)
        print("done")
コード例 #9
0
    def process_a_file(self, input_path, output_dir):
        au_id = input_path.name

        if not au_id.isdigit():
            print(f'unexpected file: {input_path}')
            return

        au_id = int(au_id)

        file_kind = File(input_path)

        if isinstance(file_kind, MP4):
            suffix = '.m4a'
        elif isinstance(file_kind, FLAC):
            suffix = '.flac'
        elif file_kind is None:
            raise TypeError('unknown file kind')
        else:
            raise TypeError(
                f'unsupport file kind {file_kind.__class__.__name__}')

        audio_info = self.audio_cache.get(au_id)
        filename = f'{spilt_artist_str(audio_info["author"])[0]} - {audio_info["title"]}{suffix}'

        output_path = output_dir / filename

        if not self.overwrite and output_path.is_file():
            print(f'{filename} exists, skipped')
            return

        print(f'processing: {filename}')

        shutil.copyfile(input_path, output_path)

        album_id = audio_info['pgc_info']['pgc_menu']['menuId']
        album_info = self.album_cache.get(album_id)
        album_cover_url = album_info['menusRespones']['coverUrl']

        album_au_ids = list(map(lambda x: x['id'], album_info['songsList']))
        track_id = album_au_ids.index(au_id)
        assert album_cover_url == album_info['songsList'][track_id][
            'cover_url']

        album_cover_path = self.cover_cache.get(album_cover_url)
        if album_cover_path.suffix == '.jpg':
            image_format = AtomDataType.JPEG
        elif album_cover_path.suffix == '.png':
            image_format = AtomDataType.PNG
        else:
            raise TypeError(
                f'Unsupport format: {album_cover_path.suffix}, Only support jpg and png.'
            )

        with album_cover_path.open('rb') as fp:
            cover_image = fp.read()

        audio_file = File(output_path)

        if isinstance(audio_file, MP4):
            tags = {
                '\xa9nam':
                audio_info['title'],
                '\xa9alb':
                album_info['menusRespones']['title'],
                '\xa9ART':
                format_artist_list(spilt_artist_str(audio_info['author'])),
                '\xa9day':
                str(
                    get_year_from_timestamp(
                        album_info['menusRespones']['pbtime'])),
                'aART':
                format_artist_list(
                    spilt_artist_str(album_info['menusRespones']['mbnames'])),
                'trkn':
                [(track_id + 1, album_info['menusRespones']['songNum'])],
                'disk': [(1, 1)],
                'covr': [MP4Cover(cover_image, imageformat=image_format)],
            }
        elif isinstance(audio_file, FLAC):
            tags = {
                'ALBUM':
                album_info['menusRespones']['title'],
                'ARTIST':
                format_artist_list(spilt_artist_str(audio_info['author'])),
                'ALBUMARTIST':
                format_artist_list(
                    spilt_artist_str(album_info['menusRespones']['mbnames'])),
                'DATE':
                str(
                    get_year_from_timestamp(
                        album_info['menusRespones']['pbtime'])),
                'TITLE':
                audio_info['title'],
                'DISCNUMBER':
                '1',
                'DISCTOTAL':
                '1',
                'TRACKTOTAL':
                str(album_info['menusRespones']['songNum']),
                'TRACKNUMBER':
                str(track_id + 1),
            }

            picture = Picture()
            picture.data = cover_image
            picture.type = PictureType.COVER_FRONT

            audio_file.add_picture(picture)

        audio_file.update(tags)
        audio_file.save()
コード例 #10
0
ファイル: spatter.py プロジェクト: balinbob/spatter
def main():
    args = sys.argv
    err = 0
    if 'id3help' in args:
        from mutagen.easyid3 import EasyID3
        for key in EasyID3.valid_keys.keys():
            print(key, )

    from optparse import OptionParser as OP

    OP = OP()
    OP.usage = ("%prog [options] filenames")
    OP.epilog = '%s id3help: for help with id3 tags' % os.path.basename(
        args[0])
    OP.add_option('-t',
                  '--tag',
                  dest='tag',
                  action='append',
                  help="set a tag",
                  metavar='tag=value')
    OP.add_option(
        '-a',
        '--add',
        dest='add',
        action='append',
        help='set/add values to a tag, without removing any existing values',
        metavar='tag=value')
    OP.add_option('-p',
                  '--pattern',
                  dest='pattern',
                  action='store',
                  help='substitution pattern from filename',
                  metavar="'%n %t.flac'")
    OP.add_option('--fn2tag',
                  dest='pattern',
                  action='store',
                  help='same as -p | --pattern')
    OP.add_option('-r',
                  '--remove',
                  dest='remove',
                  action='append',
                  help='remove a tag value or entire tag',
                  metavar="'tag' or 'tag=value'")
    OP.add_option('-j',
                  '--justify',
                  dest='justify',
                  action='store_true',
                  help='zero-justify tracknumbers')
    OP.add_option('--clear',
                  dest='clear',
                  action='store_true',
                  help='clear all tags')
    OP.add_option('-n',
                  '--noact',
                  dest='noact',
                  action='store_true',
                  help="just show what changes would be made")
    OP.add_option('-c',
                  '--confirm',
                  dest='confirm',
                  action='store_true',
                  help='show changes and prompt for confirmation to save')
    OP.add_option('-f',
                  '--files',
                  dest='filenames',
                  action='append',
                  help='one or more filenames/globs')
    OP.add_option('-q',
                  '--quiet',
                  dest='quiet',
                  action='store_true',
                  help='no output to stdout')
    OP.add_option('--tag2fn',
                  dest='tag2fn',
                  action='store',
                  help='substitution pattern from tags',
                  metavar="'%n %t.flac'")
    OP.add_option(
        '-s',
        '--filter',
        dest='symbols',
        action='store',
        help=
        'one or more characters to filter from tags used to build filenames',
        metavar="'!@$&*/\?'")
    OP.add_option(
        '-m',
        '--map',
        dest='map',
        action='store',
        help=
        'replace all instances of a char with another char\nin conjunction with --tag2fn',
        metavar="/ -")
    OP.add_option('-i',
                  '--index',
                  dest='idx',
                  action='store_true',
                  help='index files by filename order (persistent file order)')
    OP.add_option('-v',
                  '--version',
                  dest='vers',
                  action='store_true',
                  help='show version')

    argstr = ' '.join(args)

    if len(args) < 2:
        OP.print_usage()
        #        print("version %s" % __version__)
        print('-h|--help for help')
        sys.exit(1)

    p = '(-t|--tag|-a|--add|-p|--pattern|-r|--remove|-f|--files)\ +?\-[^\ ]*'
    mo = re.search(p, argstr)
    if mo:
        print('illegal option combination: ', mo.group())
        sys.exit(1)

    (opt, fnames) = OP.parse_args()
    if opt.vers:
        print('%s %s' % (OP.get_prog_name(), __version__))
    if opt.filenames:
        fnames += opt.filenames

    for fname in fnames:
        if not os.path.exists(fname):
            print('%s: no such file' % fname)
            err += 1
    if err:
        sys.exit(err)

    cfmr = Confirmer(opt)
    fnum = 0
    idx = 0
    if opt.pattern:
        subster = Subster(opt.pattern)
    elif opt.tag2fn:
        subster = Subster(opt.tag2fn, 'tag2fn')
    else:
        subster = Subster('', '')

    modded = any(
        [opt.clear, opt.remove, opt.add, opt.tag, opt.pattern, opt.justify])
    spkr = Speaker(opt.quiet)
    top_length = 0
    for fname in fnames:
        bfname = os.path.basename(fname)
        top_length = len(bfname) if len(bfname) > top_length else top_length

    for fname in fnames:
        fnum += 1
        vals = {}
        keys = []
        origfn = fname

        if os.path.splitext(fname)[1] == '.mp3':
            try:
                mf = MP3(fname)
            except IOError:
                spkr.speak("\ncan't open %s" % fname)
                continue
            spkr.speak("processing %s" % fname)
            if opt.clear:
                mf.clear()
            for action in opt.remove or []:
                k, v = (action.split('=', 1) + [''])[:2]
                vals[k] = mf.pop(k, [])
                if k and not v:
                    vals[k] = []

                elif v and v in vals[k]:
                    vals[k].remove(v)
            for action in opt.tag or []:
                k, v = (action.split('=', 1) + [''])[:2]
                vals[k] = [v]
            for action in opt.add or []:
                k, v = (action.split('=', 1) + [''])[:2]
                if vals.get(k, []):
                    vals[k] += mf.pop(k, [])
                else:
                    vals[k] = mf.pop(k, [])
                vals[k].extend([v])
            if subster.pattern:
                d = subster.getdict(fname)
                for k in d:
                    values = d.get(k, [])
                    if not isinstance(values, list):
                        values = [values]
                    try:
                        vals[k].extend(values)
                    except KeyError:
                        vals[k] = values
            if opt.justify:
                if not vals.get('tracknumber'):
                    vals['tracknumber'] = fnum
                width = len(str(len(fnames)))
                n = width - len(str(vals['tracknumber']))
                vals['tracknumber'] = [n * '0' + str(vals['tracknumber'])]

            if not modded:
                if not opt.quiet:
                    print(mf.pprint())
                    continue

            if opt.noact or opt.confirm:
                for k in vals:
                    print(k + '=' + str(vals[k]))
            if opt.noact:
                continue
            if opt.confirm and not cfmr.confirm():
                continue
            for k in vals:
                try:
                    mf.update({k: vals[k]})
#                mf.save( )
                except ValueError:
                    pass
            mf.save()
        else:
            try:
                #            print(fname)
                mf = File(fname)
            except IOError:
                spkr.speak("can't open %s" % fname)
                continue
            spkr.speak(os.path.basename(fname))

            if opt.idx:
                trn = mf.get('tracknumber', None)
                mf['idx'] = unicode(fnum)
                if trn:
                    mf['idx'] += trn
                mf.save()
                print(' indexed')

            if opt.clear:
                mf.clear()
                spkr.speak('\n\ttags cleared..')
            for action in opt.remove or []:
                k, v = (action.split('=', 1) + [''])[:2]
                t = mf.pop(k, [])
                if v and v in t:
                    t.remove(v)
                    spkr.speak(str(k) + ' removes ' + str(v))
                if v and t:
                    mf.update({k: t})
            for action in opt.tag or []:
                if '=' in action:
                    k, v = action.split('=', 1)
                    if k and v:
                        mf.update({k: [v]})
                        spkr.speak('\t\ttag set: ' + k + '=' + v)
            for action in opt.add or []:
                if '=' in action:
                    k, v = action.split('=', 1)
                    mf.update({k: mf.get(k, []) + [v]})
                    spkr.speak('\n\ttag appended: ' + k + '=' + v)
            if subster.mode == 'fn2tag':
                d = subster.getdict(fname)
                for k in d:
                    mf.update({k: d[k]})
                    spkr.speak('\n\tfrom filename: ' + k + '=' + d[k])

            if subster.mode == 'tag2fn':
                fname = ''
                fnlist = subster.getfnlist()
                if 'tracknumber' in fnlist:
                    tn = 1
                else:
                    tn = 0
                lit = True
                for item in fnlist:
                    lit = not lit
                    if lit:
                        if not tn and item == 'tracknumber':
                            item = 'track'
                        if tn and item == 'track':
                            item = 'tracknumber'
                        if item.startswith('track') and opt.justify:
                            subst = mf[item][0].rjust(2, '0')
                        else:
                            subst = mf[item][0]

                        if opt.symbols:
                            pat = '[' + opt.symbols + ']'
                            subst = re.sub(pat, '', subst)
                            subst = subst.strip()

                        fname += subst
                    else:
                        fname += item

                    if '/' in fname:
                        fname = re.sub('/', '-', fname)

#            if opt.map:
#                fname = map(fname,opt.map)

                if opt.noact or opt.confirm:
                    pass

            if not any([modded, opt.tag2fn, opt.quiet]):
                print(mf.pprint(), )

            if cfmr.confirm():
                if opt.tag2fn:
                    if opt.map:
                        a, b = opt.map.split()
                        fname = re.sub(a, b, fname)

                    pth = os.path.join(os.path.dirname(origfn), fname)
                    second_column = top_length + 2
                    tab = (second_column - len(os.path.basename(origfn))) * ' '
                    try:
                        os.rename(origfn, pth)
                        print(tab + '--> ' + fname),
#                    spkr.speak( 'renamed...   ' + fname )
                    except IOError:
                        raise IOError
                else:
                    mf.save()
                    spkr.speak('\tsaved!')
コード例 #11
0
        os.makedirs(dirName, exist_ok=True)

        trackFileName = f'{dirName}\\{i+1:02d}-{trackName}.mp3'

        if not os.path.isfile(trackFileName) :
            print("%3d  %s" % (i+1, trackFileName))
            try:
                track.download(filename=trackFileName)
            except:
                print("Error!!")

        file = File(f'{trackFileName}')
        file.update({
            # Title
            'TIT2': TIT2(encoding=3, text=track.title),
            # Artist
            'TPE1': TPE1(encoding=3, text=DELIMITER.join(i['name'] for i in track.artists)),
            # Album
            'TALB': TALB(encoding=3, text=DELIMITER.join(i['title'] for i in track.albums)),
            # Year
            'TDRC': TDRC(encoding=3, text=str(track.albums[0]['year'])),
            # Picture
            #'APIC': APIC(encoding=3, text=cover_filename, data=open(cover_filename, 'rb').read())
        })

        file.save()

#        else:
#            # print("%3d  %s file exist!" % (i+1, trackFileName))
#    client.users_playlists_change(pl.kind, diff.to_json(), pl.revision)