def get_album_and_artist(self): """ Return Ogg tags for album and artist""" self.audio_files.sort() for file in self.audio_files: try: tags = OggVorbis(file) if tags: if "album" in tags.keys() and "artist" in tags.keys(): return (tags["album"][0], tags["artist"][0]) break # If we found ID3 tag info from a file, no reason to query the rest in a directory. except mutagen.oggvorbis.OggVorbisHeaderError: continue return (None, None)
def rm_ogg_cover(self, episode): filename = episode.local_filename(create=False) if filename is None: return basename, extension = os.path.splitext(filename) if episode.file_type() != 'audio': return if extension.lower() != '.ogg': return try: ogg = OggVorbis(filename) found = False for key in ogg.keys(): if key.startswith('cover'): found = True ogg.pop(key) if found: logger.info('Removed cover art from OGG file: %s', filename) ogg.save() except Exception, e: logger.warn('Failed to remove OGG cover: %s', e, exc_info=True)
def on_episode_downloaded(self, episode): filename = episode.local_filename(create=False, check_only=True) if filename is None: return (basename, extension) = os.path.splitext(filename) if episode.file_type() == 'audio' and extension.lower().endswith( 'ogg'): log(u'trying to remove cover from %s' % filename) found = False try: ogg = OggVorbis(filename) for key in ogg.keys(): if key.startswith('cover'): found = True ogg[key] = '' if found: log(u'removed cover from the ogg file successfully') ogg.save() else: log(u'there was no cover to remove in the ogg file') except: None
def on_episode_downloaded(self, episode): log(u'on_episode_downloaded(%s/%s)' % (episode.channel.title, episode.title)) filename = episode.local_filename(create=False, check_only=True) if filename is None: return basename, extension = os.path.splitext(filename) if episode.file_type() == 'audio' and extension.lower() == '.ogg': log(u'trying to remove cover from %s' % filename) found = False try: ogg = OggVorbis(filename) for key in ogg.keys(): if key.startswith('cover'): found = True ogg[key]='' if found: log(u'removed cover from the ogg file successfully') ogg.save() else: log(u'there was no cover to remove in the ogg file') except: None
def get_album_and_artist(self): """ Return Ogg tags for album and artist""" self.audio_files.sort() for file in self.audio_files: try: tags = OggVorbis(file) if tags: if "album" in tags.keys() and "artist" in tags.keys(): logger.debug(u'album -> {album}, artist -> {artist}'.format(album=tags["album"][0], artist=tags["artist"][0])) return (tags["album"][0], tags["artist"][0]) break # If we found ID3 tag info from a file, no reason to query the rest in a directory. except mutagen.oggvorbis.OggVorbisHeaderError: logger.error(u'No OggVorbis Header data found') continue return (None, None)
def get_album_and_artist(self): """ Return Ogg tags for album and artist""" self.audio_files.sort() for file in self.audio_files: try: tags = OggVorbis(file) if tags: if "album" in tags.keys() and "artist" in tags.keys(): logger.debug( u'album -> {album}, artist -> {artist}'.format( album=tags["album"][0], artist=tags["artist"][0])) return (tags["album"][0], tags["artist"][0]) break # If we found ID3 tag info from a file, no reason to query the rest in a directory. except mutagen.oggvorbis.OggVorbisHeaderError: logger.error(u'No OggVorbis Header data found') continue return (None, None)
def clear_tags(filename): try: if '.mp3' in filename: f = APEv2(filename) elif '.ogg' in filename: f = OggVorbis(filename) elif '.flac' in filename: f = FLAC(filename) for k in f.keys(): f[k] = u'' f.save() except: pass # again for mp3 with tags that are worse if '.mp3' in filename: try: f = EasyID3(filename) for k in f.keys(): f[k] = [u''] f.save() except mutagen.id3.ID3NoHeaderError: pass
def get(self): """ This is the no update version of musicd, so we read the FS once at load to sync the DB and then load the tracks into a template. A page refresh is necessary to reflect changes in the track listing. """ library_path = os.path.normpath(Config.absolute_library) for root, dirs, files in os.walk(library_path): for filename in fnmatch.filter(files, "*.ogg") + fnmatch.filter(files, "*.mp3"): path = os.path.join(root, filename) track = {} try: if re.search(".ogg", filename): audio = OggVorbis(path) track["length"] = audio.info.length elif re.search(".mp3", filename): audio = EasyID3(path) track["length"] = MP3(path).info.length except: print "Failed to read tags: %s" % path continue for key in audio.keys(): if key in Config.tags: track[key] = audio[key].pop() track["path"] = re.sub(library_path + "/", "", path) spec = {} for tag in ["artist", "album", "title"]: if tag in track: spec[tag] = track[tag] if not tracks.find_one(spec): print "found %s" % track["path"] tracks.save(track) # look for deleted files for track in tracks.find(): path = os.path.join(library_path, track["path"]) if not os.path.exists(path): print "deleting from db: %s" % path tracks.remove(track) self.render( "main.html", tracks=tracks.find(fields=Config.tags, sort=[("artist", pymongo.ASCENDING), ("album", pymongo.ASCENDING)]), )
def rm_ogg_cover(episode): filename = episode.local_filename(create=False, check_only=True) if filename is None: return (basename, extension) = os.path.splitext(filename) if episode.file_type() == "audio" and extension.lower().endswith("ogg"): logger.info(u"trying to remove cover from %s" % filename) found = False try: ogg = OggVorbis(filename) for key in ogg.keys(): if key.startswith("cover"): found = True ogg.pop(key) if found: logger.info(u"removed cover from the ogg file successfully") ogg.save() else: logger.info(u"there was no cover to remove in the ogg file") except: None
class VorbisFile: def __init__(self, fn): self.config = config if fn is not None: self.SetFile(fn) def SetFile(self, fn): self.fn = fn self.filename = os.path.basename(self.fn) self.af = OggVorbis(self.fn) def read_comments(self): dic = {'title' : '', 'artist' : '', 'album' : '', 'license' : '', 'label' : '', 'comment' : '' } for tag in self.af.keys(): tag = tag.lower() val = self.af.get(tag).pop(0) if val <> '': dic[tag] = val return dic def write_comments(self, metadata, userInfo, cache=1, removeSpool=0): ''' Cache the file (copy it to a tmp dir) and write the tags there. ''' logger.debug99("called VorbisFile.write_comments()") # now write the comments to file (self.af) dic = {} for tag in metadata: tag = tag.lower() val = metadata[tag] # build up metadata object together with audio file object if val != '': self.af[tag] = val else: logger.debug3("Not writing tag: %s (was left empty)" % tag) self.af.save() logger.debug3( "in VorbisFile.write_comments() Done! Wrote tags successfully to %s!" % self.fn ) # FIXME : el ImportOGG en modo 'edit' es para que re-lea tags y actualice la DB # pero no deberia ir dentro de la clase VorbisFile ''' if not cache: logger.debug2("Should re-import/update: %s" % self.fn) ImportOGG(self, self.fn, userInfo, 'edit') ''' return self.fn def getFilepath(self): return self.fn def getFilename(self): return self.filename def getTag(self, tag): if self.af.has_key(tag) and self.af[tag] is not '': return self.af.get(tag).pop(0) else: return '' def getLength(self): return self.af.info.length def getBitrate(self): return self.af.info.bitrate def getSamplerate(self): return self.af.info.sample_rate def getInfo(self): '''Available info (for OGG/Vorbis) is: channels, bitrate, serial, sample_rate, length''' return self.af.info def listTags(self): return self.af.keys() def getSize(self): return os.stat(self.fn).st_size
class VorbisFile: def __init__(self, fn): self.config = config if fn is not None: self.SetFile(fn) def SetFile(self, fn): self.fn = fn self.filename = os.path.basename(self.fn) self.af = OggVorbis(self.fn) def read_comments(self): dic = { 'title': '', 'artist': '', 'album': '', 'license': '', 'label': '', 'comment': '' } for tag in self.af.keys(): tag = tag.lower() val = self.af.get(tag).pop(0) if val <> '': dic[tag] = val return dic def write_comments(self, metadata, userInfo, cache=1, removeSpool=0): ''' Cache the file (copy it to a tmp dir) and write the tags there. ''' logger.debug99("called VorbisFile.write_comments()") # now write the comments to file (self.af) dic = {} for tag in metadata: tag = tag.lower() val = metadata[tag] # build up metadata object together with audio file object if val != '': self.af[tag] = val else: logger.debug3("Not writing tag: %s (was left empty)" % tag) self.af.save() logger.debug3( "in VorbisFile.write_comments() Done! Wrote tags successfully to %s!" % self.fn) # FIXME : el ImportOGG en modo 'edit' es para que re-lea tags y actualice la DB # pero no deberia ir dentro de la clase VorbisFile ''' if not cache: logger.debug2("Should re-import/update: %s" % self.fn) ImportOGG(self, self.fn, userInfo, 'edit') ''' return self.fn def getFilepath(self): return self.fn def getFilename(self): return self.filename def getTag(self, tag): if self.af.has_key(tag) and self.af[tag] is not '': return self.af.get(tag).pop(0) else: return '' def getLength(self): return self.af.info.length def getBitrate(self): return self.af.info.bitrate def getSamplerate(self): return self.af.info.sample_rate def getInfo(self): '''Available info (for OGG/Vorbis) is: channels, bitrate, serial, sample_rate, length''' return self.af.info def listTags(self): return self.af.keys() def getSize(self): return os.stat(self.fn).st_size
from mutagen.mp3 import MP3 from mutagen.easyid3 import EasyID3 if len(sys.argv) != 2: print "Usage: tags2json.py filename" sys.exit(1) filename = os.path.abspath( sys.argv[1] ) lower_filename = filename.lower() tags = {} try: if lower_filename.endswith('.ogg'): audio = OggVorbis(filename) tags['length'] = audio.info.length elif lower_filename.endswith('.mp3'): audio = EasyID3(filename) tags['length'] = MP3(filename).info.length else: sys.exit(2) except: sys.exit(2) tags['length'] = time.strftime('%M:%S', time.gmtime(tags['length'])) for key in audio.keys(): tags[key] = audio[key].pop() print json.dumps(tags)