def parse(self, filename): d = [] mp3 = None try: mp3 = mutagen.mp3.MP3(filename) except mutagen.mp3.HeaderNotFoundError: pass except struct.error: pass if mp3 != None: if mp3.tags != None: self.handle_string_tags(self.mp3_string_map, mp3, d) self.handle_int_tags(self.mp3_int_map, mp3, d) self.handle_rating(mp3, d) self.handle_track(mp3, d) self.handle_disc(mp3, d) self.add_file_info(filename, d) d.extend([ do('daap.songtime', mp3.info.length * 1000), do('daap.songbitrate', mp3.info.bitrate / 1000), do('daap.songsamplerate', mp3.info.sample_rate), do('daap.songformat', 'mp3'), do('daap.songdescription', 'MPEG Audio File'), ]) name = self.set_itemname_if_unset(os.path.basename(filename), d) return (d, name) else: return (None, None)
def build_item(md): return do('dmap.listingitem', [ do('dmap.itemkind', 2), do('dmap.containeritemid', md.id), do('dmap.itemid', md.id), md.get_dmap_raw() ])
def build_item(md): return do('dmap.listingitem', [do('dmap.itemkind', 2), do('dmap.containeritemid', md.id), do('dmap.itemid', md.id), md.get_dmap_raw() ])
def add_file_info(self, filename, daap): statinfo = os.stat(filename) daap.extend([ do('daap.songsize', os.path.getsize(filename)), do('daap.songdateadded', statinfo.st_ctime), do('daap.songdatemodified', statinfo.st_ctime) ])
def parse(self, trk): try: #trk = mutagen.File(filename) d = [] if len(trk.list_tags()) > 0: if 'title' in trk.list_tags(): name = str(trk.get_tag_raw('title')[0]) else: name = str(trk) self.handle_string_tags(self._string_map, trk, d) self.handle_int_tags(self._int_map, trk, d) # self.handle_rating(trk, d) else: name = str(trk) #statinfo = os.stat(filename) _len = trk.get_tag_raw('__length') if _len is None: # don't parse songs that don't have length return (None, None) d.extend([#do('daap.songsize', trk.get_size()), #do('daap.songdateadded', statinfo.st_ctime), #do('daap.songdatemodified', statinfo.st_ctime), do('daap.songtime', _len * 1000), # do('daap.songbitrate', trk.get_tag_raw('__bitrate') / 1000), # do('daap.songsamplerate', ogg.info.sample_rate), # todo ?? do('daap.songformat', trk.get_local_path().split('.')[-1]), # todo ?? do('daap.songdescription', 'Exaile Streaming Audio'), ]) return (d, name) except Exception: logger.exception('caught exception while processing %s', trk) return (None, None)
def parse(self, filename): d = [] mp3 = None try: mp3 = mutagen.mp3.MP3(filename) except mutagen.mp3.HeaderNotFoundError: pass except struct.error: pass if mp3 != None: if mp3.tags != None: self.handle_string_tags(self.mp3_string_map, mp3, d) self.handle_int_tags(self.mp3_int_map, mp3, d) self.handle_rating(mp3, d) self.handle_track(mp3, d) self.handle_disc(mp3, d) self.add_file_info(filename, d) d.extend([do('daap.songtime', mp3.info.length * 1000), do('daap.songbitrate', mp3.info.bitrate / 1000), do('daap.songsamplerate', mp3.info.sample_rate), do('daap.songformat', 'mp3'), do('daap.songdescription', 'MPEG Audio File'), ]) name = self.set_itemname_if_unset(os.path.basename(filename), d) return (d, name) else: return (None, None)
def build_do(md, id): d = do('dmap.listingitem', [ do('dmap.itemkind', 2), do('dmap.itemid', md.id), do('dmap.itemname', md.get_name()), do('dmap.containeritemid', id) ] ) return d
def build_do(md, id): d = do('dmap.listingitem', [ do('dmap.itemkind', 2), do('dmap.itemid', md.id), do('dmap.itemname', md.get_name()), do('dmap.containeritemid', id) ]) return d
def handle_disc(self, mp3, d): discnumber = None disccount = None if mp3.tags.has_key('TPOS'): t = str(mp3.tags['TPOS']).split('/') discnumber = self.my_int(t[0]) if (len(t) == 2): disccount = self.my_int(t[1]) if discnumber: d.append(do('daap.songdiscnumber', discnumber)) if disccount: d.append(do('daap.songdisccount', disccount))
def handle_track(self, mp3, d): tracknumber = None trackcount = None if mp3.tags.has_key('TRCK'): t = str(mp3.tags['TRCK']).split('/') tracknumber = self.my_int(t[0]) if (len(t) == 2): trackcount = self.my_int(t[1]) if tracknumber: d.append(do('daap.songtracknumber', tracknumber)) if trackcount: d.append(do('daap.songtrackcount', trackcount))
def handle_disc(self, flac, d): discnumber = None disccount = None if flac.tags.has_key('discnumber'): t = unicode(flac.tags['discnumber'][0]).split('/') discnumber = self.my_int(t[0]) if (len(t) == 2): disccount = self.my_int(t[1]) if flac.tags.has_key('disctotal'): disccount = self.my_int(flac.tags['disctotal']) if discnumber: d.append(do('daap.songdiscnumber', discnumber)) if disccount: d.append(do('daap.songdisccount', disccount))
def handle_track(self, flac, d): tracknumber = None trackcount = None if flac.tags.has_key('tracknumber'): t = str(flac.tags['tracknumber']).split('/') tracknumber = self.my_int(t[0]) if (len(t) == 2): trackcount = self.my_int(t[1]) if flac.tags.has_key('tracktotal'): trackcount = self.my_int(flac.tags['tracktotal']) if tracknumber: d.append(do('daap.songtracknumber', tracknumber)) if trackcount: d.append(do('daap.songtrackcount', trackcount))
def parse(self, filename): md = mutagen.File(filename) d = [] if md.tags != None: self.handle_string_tags(self.vorbis_string_map, md, d) self.handle_int_tags(self.vorbis_int_map, md, d) self.handle_track(md, d) self.handle_disc(md, d) self.add_file_info(filename, d) d.extend([do('daap.songtime', md.info.length * 1000), do('daap.songsamplerate', md.info.sample_rate)]) name = self.set_itemname_if_unset(os.path.basename(filename), d) if hasattr(self, 'parse_extra_vorbis'): self.parse_extra_vorbis(filename, md, d) return (d, name)
def handle_int_tags(self, map, md, daap): for k in md.list_tags(): if map.has_key(k): try: tn = str(md.get_tag_raw(k)[0]) if '/' in tn: # num, tot = tn.split('/') if num == '': # empty tags num = 0 daap.append(do(map[k], int(num))) # set total? else: daap.append(do(map[k], int(tn))) except Exception: logger.exception('exception caught parsing tag: %s=%s from %s', k, tn, md)
def handle_int_tags(self, map, md, daap): for k in md.tags.keys(): if map.has_key(k): val = md.tags[k] if type(val) == list: val = val[0] intval = self.my_int(unicode(val)) if intval: daap.append(do(map[k], intval))
def handle_int_tags(self, map, md, daap): for k in md.list_tags(): if k in map: try: tn = str(md.get_tag_raw(k)[0]) if '/' in tn: num, tot = tn.split('/') if num == '': # empty tags num = 0 daap.append(do(map[k], int(num))) # set total? else: daap.append(do(map[k], int(tn))) except Exception: logger.exception( 'exception caught parsing tag: %s=%s from %s', k, tn, md )
def handle_int_tags(self, map, md, daap): for k in md.list_tags(): if map.has_key(k): try: tn = str(md.get_tag_raw(k)[0]) if '/' in tn: # num, tot = tn.split('/') if num == '': # empty tags num = 0 daap.append(do(map[k], int(num))) # set total? else: daap.append(do(map[k], int(tn))) except Exception: logger.debug('exception caught parsing tag: {0}={1} from {2}' .format(k, tn, md)) logger.debug(traceback.format_exc())
def handle_string_tags(self, map, md, daap): for k in md.list_tags(): if k in map: try: tag = [t.encode("utf-8", "replace") for t in md.get_tag_raw(k)] tag = [t for t in tag if t != ""] daap.append(do(map[k], "/".join(tag))) except Exception: logger.exception("error decoding tags")
def handle_int_tags(self, map, md, daap): for k in md.tags.keys(): if k in map: val = md.tags[k] if isinstance(val, list): val = val[0] intval = self.my_int(unicode(val)) if intval: daap.append(do(map[k], intval))
def handle_string_tags(self, map, md, daap): for k in md.list_tags(): if map.has_key(k): try: tag = [ str(t) for t in md.get_tag_raw(k)] tag = [ t for t in tag if t != ""] daap.append(do(map[k], "/".join(tag))) except Exception: logger.exception("error decoding tags")
def handle_int_tags(self, map, md, daap): for k in md.list_tags(): if map.has_key(k): try: tn = str(md.get_tag_raw(k)[0]) if '/' in tn: # num, tot = tn.split('/') if num == '': # empty tags num = 0 daap.append(do(map[k], int(num))) # set total? else: daap.append(do(map[k], int(tn))) except Exception: logger.debug( 'exception caught parsing tag: {0}={1} from {2}'. format(k, tn, md)) logger.debug(traceback.format_exc())
def handle_string_tags(self, map, md, daap): for k in md.list_tags(): if map.has_key(k): try: tag = [str(t) for t in md.get_tag_raw(k)] tag = [t for t in tag if t != ""] daap.append(do(map[k], "/".join(tag))) except Exception: logger.debug(traceback.format_exc())
def handle_string_tags(self, map, md, daap): for k in md.list_tags(): if map.has_key(k): try: tag = [str(t) for t in md.get_tag_raw(k)] tag = [t for t in tag if t != ""] daap.append(do(map[k], "/".join(tag))) except Exception: logger.exception("error decoding tags")
def handle_string_tags(self, map, md, daap): for k in md.list_tags(): if k in map: try: tag = [t.encode("utf-8", "replace") for t in md.get_tag_raw(k)] tag = [t for t in tag if t != ""] daap.append(do(map[k], b"/".join(tag))) except Exception: logger.exception("error decoding tags")
def handle_string_tags(self, map, md, daap): for k in md.list_tags(): if map.has_key(k): try: tag = [ str(t) for t in md.get_tag_raw(k)] tag = [ t for t in tag if t != ""] daap.append(do(map[k], "/".join(tag))) except Exception: logger.debug(traceback.format_exc())
def handle_string_tags(self, map, md, daap): h = {} for k in md.tags.keys(): if map.has_key(k): tag = [unicode(t) for t in md.tags[k]] tag = [t for t in tag if t != ""] if not (h.has_key(map[k])): h[map[k]] = [] h[map[k]] = h[map[k]] + tag for k in h.keys(): h[k].sort() daap.append(do(k, "/".join(h[k])))
def handle_string_tags(self, map, md, daap): h = {} for k in md.tags.keys(): if map.has_key(k): tag = [ unicode(t) for t in md.tags[k] ] tag = [ t for t in tag if t != "" ] if not(h.has_key(map[k])): h[map[k]] = [] h[map[k]] = h[map[k]] + tag for k in h.keys(): h[k].sort() daap.append(do(k, "/".join(h[k])))
def build(self, md_cache): def build_do(md, id): d = do('dmap.listingitem', [ do('dmap.itemkind', 2), do('dmap.itemid', md.id), do('dmap.itemname', md.get_name()), do('dmap.containeritemid', id) ]) return d pid_list = [] for pl in self.container_list: entries = [n for n in md_cache if pl.contains(n)] pl.sort(entries) d = do('daap.playlistsongs', [ do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', len(entries)), do('dmap.returnedcount', len(entries)), do('dmap.listing', [build_do(md, id) for (id, md) in enumerate(entries)]) ]) ContainerCacheItem.write_entry(self.dir, pl.name, d, len(entries)) pid_list.append(md5.md5(pl.name).hexdigest()) self.build_index(pid_list)
def get_md(self): if self.md is None: self.md = {} s = StringIO.StringIO(self.get_dmap_raw()) l = len(self.get_dmap_raw()) data = [] while s.tell() != l: d = do() d.processData(s) data.append(d) for d in data: self.md[d.codeName()] = d.value return self.md
def get_md(self): if self.md == None: self.md = {} s = StringIO.StringIO(self.get_dmap_raw()) l = len(self.get_dmap_raw()) data = [] while s.tell() != l: d = do() d.processData(s) data.append(d) for d in data: self.md[d.codeName()] = d.value return self.md
def parse(self, trk): try: # trk = mutagen.File(filename) d = [] if len(trk.list_tags()) > 0: if 'title' in trk.list_tags(): name = trk.get_tag_raw('title')[0].encode("utf-8", "replace") else: name = str(trk) self.handle_string_tags(self._string_map, trk, d) self.handle_int_tags(self._int_map, trk, d) # self.handle_rating(trk, d) else: name = str(trk) # statinfo = os.stat(filename) _len = trk.get_tag_raw('__length') if _len is None: # don't parse songs that don't have length return (None, None) d.extend( [ # do('daap.songsize', trk.get_size()), # do('daap.songdateadded', statinfo.st_ctime), # do('daap.songdatemodified', statinfo.st_ctime), do('daap.songtime', _len * 1000), # do('daap.songbitrate', trk.get_tag_raw('__bitrate') / 1000), # do('daap.songsamplerate', ogg.info.sample_rate), # todo ?? do( 'daap.songformat', trk.get_local_path().split('.')[-1] ), # todo ?? do('daap.songdescription', 'Exaile Streaming Audio'), ] ) return (d, name) except Exception: logger.exception('caught exception while processing %s', trk) return (None, None)
def build_do(md, id): d = do('dmap.listingitem', [do('dmap.itemkind', 2), do('dmap.itemid', md.id), do('dmap.itemname', md.get_name()), do('dmap.containeritemid', id), do('daap.songformat', md.get_md()['daap.songformat'])]) return d
def build_do(md, id): d = do('dmap.listingitem', [ do('dmap.itemkind', 2), do('dmap.itemid', md.id), do('dmap.itemname', md.get_name()), do('dmap.containeritemid', id), do('daap.songformat', md.get_md()['daap.songformat']) ]) return d
def build(f): children = [build_item(md) for md in md_cache] file_count = len(children) d = do('daap.databasesongs', [do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', file_count), do('dmap.returnedcount', file_count), do('dmap.listing', children)]) f.write(d.encode())
def build(): children = [ build_item (md) for md in md_cache ] file_count = len(children) d = do('daap.databasesongs', [ do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', file_count), do('dmap.returnedcount', file_count), do('dmap.listing', children) ]) return d.encode()
def do_GET_content_codes(self): children = [do('dmap.status', 200)] for code in spydaap.daap.dmapCodeTypes.keys(): (name, dtype) = spydaap.daap.dmapCodeTypes[code] d = do('dmap.dictionary', [ do('dmap.contentcodesnumber', code), do('dmap.contentcodesname', name), do('dmap.contentcodestype', spydaap.daap.dmapReverseDataTypes[dtype]) ]) children.append(d) mccr = do('dmap.contentcodesresponse', children) self.h(mccr.encode())
def do_GET_content_codes(self): children = [ do('dmap.status', 200) ] for code in spydaap.daap.dmapCodeTypes.keys(): (name, dtype) = spydaap.daap.dmapCodeTypes[code] d = do('dmap.dictionary', [ do('dmap.contentcodesnumber', code), do('dmap.contentcodesname', name), do('dmap.contentcodestype', spydaap.daap.dmapReverseDataTypes[dtype]) ]) children.append(d) mccr = do('dmap.contentcodesresponse', children) self.h(mccr.encode())
def build(self, md_cache): def build_do(md, id): d = do('dmap.listingitem', [do('dmap.itemkind', 2), do('dmap.itemid', md.id), do('dmap.itemname', md.get_name()), do('dmap.containeritemid', id), do('daap.songformat', md.get_md()['daap.songformat'])]) return d pid_list = [] for pl in self.container_list: entries = [n for n in md_cache if pl.contains(n)] pl.sort(entries) d = do('daap.playlistsongs', [do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', len(entries)), do('dmap.returnedcount', len(entries)), do('dmap.listing', [build_do(md, id) for (id, md) in enumerate(entries)]) ]) ContainerCacheItem.write_entry(self.dir, pl.name, d, len(entries)) pid_list.append(md5(pl.name).hexdigest()) self.build_index(pid_list)
def set_itemname_if_unset(self, name, daap): for d in daap: if d.code == 'minm': return d.value daap.extend([do('minm', name)]) return name
def do_GET_database_list(self): d = do('daap.serverdatabases', [ do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', 1), do('dmap.returnedcount', 1), do('dmap.listing', [ do('dmap.listingitem', [ do('dmap.itemid', 1), do('dmap.persistentid', 1), do('dmap.itemname', server_name), do('dmap.itemcount', len(md_cache)), do('dmap.containercount', len(container_cache))]) ]) ]) self.h(d.encode())
def do_GET_database_list(self): d = do('daap.serverdatabases', [do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', 1), do('dmap.returnedcount', 1), do('dmap.listing', [do('dmap.listingitem', [do('dmap.itemid', 1), do('dmap.persistentid', 1), do('dmap.itemname', server_name), do('dmap.itemcount', len(md_cache)), do('dmap.containercount', len(container_cache))]) ]) ]) self.h(d.encode())
def add_file_info(self, filename, daap): statinfo = os.stat(filename) daap.extend([do('daap.songsize', os.path.getsize(filename)), do('daap.songdateadded', statinfo.st_ctime), do('daap.songdatemodified', statinfo.st_ctime)])
def do_GET_container_list(self, database): container_do = [] for i, c in enumerate(container_cache): d = [ do('dmap.itemid', i + 1 ), do('dmap.itemcount', len(c)), do('dmap.containeritemid', i + 1), do('dmap.itemname', c.get_name()) ] if c.get_name() == 'Library': # this should be better d.append(do('daap.baseplaylist', 1)) else: d.append(do('com.apple.itunes.smart-playlist', 1)) container_do.append(do('dmap.listingitem', d)) d = do('daap.databaseplaylists', [ do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', len(container_do)), do('dmap.returnedcount', len(container_do)), do('dmap.listing', container_do) ]) self.h(d.encode())
def parse(self, filename): name = filename statinfo = os.stat(filename) d = [do('daap.songsize', os.path.getsize(filename)), do('daap.songdateadded', statinfo.st_mtime), do('daap.songdatemodified', statinfo.st_mtime), do('dmap.itemname', name), do('daap.songalbum', ''), do('daap.songartist', ''), do('daap.songbitrate', 0), do('daap.songcomment', ''), do('daap.songdescription', 'QuickTime movie file'), do('daap.songformat', 'mov'), do('com.apple.itunes.mediakind', 2), do('com.apple.itunes.has-video', True) ] return (d, name)
def parse_extra_vorbis(self, filename, md, daap): daap.extend([ do('daap.songformat', 'flac'), do('daap.songdescription', 'FLAC Audio File') ])
def do_GET_update(self): mupd = do('dmap.updateresponse', [ do('dmap.status', 200), do('dmap.serverrevision', self.daap_server_revision), ]) self.h(mupd.encode())
def do_GET_server_info(self): msrv = do('dmap.serverinforesponse', [do('dmap.status', 200), do('dmap.protocolversion', '2.0'), do('daap.protocolversion', '3.0'), do('dmap.timeoutinterval', 1800), do('dmap.itemname', server_name), do('dmap.loginrequired', 0), do('dmap.authenticationmethod', 0), do('dmap.supportsextensions', 0), do('dmap.supportsindex', 0), do('dmap.supportsbrowse', 0), do('dmap.supportsquery', 0), do('dmap.supportspersistentids', 0), do('dmap.databasescount', 1), #do('dmap.supportsautologout', 0), #do('dmap.supportsupdate', 0), #do('dmap.supportsresolve', 0), ]) self.h(msrv.encode())
def do_GET_update(self): mupd = do('dmap.updateresponse', [do('dmap.status', 200), do('dmap.serverrevision', self.daap_server_revision), ]) self.h(mupd.encode())
def do_GET_container_list(self, database): container_do = [] for i, c in enumerate(container_cache): d = [do('dmap.itemid', i + 1), do('dmap.itemcount', len(c)), do('dmap.containeritemid', i + 1), do('dmap.itemname', c.get_name())] if c.get_name() == 'Library': # this should be better d.append(do('daap.baseplaylist', 1)) else: d.append(do('com.apple.itunes.smart-playlist', 1)) container_do.append(do('dmap.listingitem', d)) d = do('daap.databaseplaylists', [do('dmap.status', 200), do('dmap.updatetype', 0), do('dmap.specifiedtotalcount', len(container_do)), do('dmap.returnedcount', len(container_do)), do('dmap.listing', container_do) ]) self.h(d.encode())
def do_GET_server_info(self): msrv = do('dmap.serverinforesponse', [ do('dmap.status', 200), do('dmap.protocolversion', '2.0'), do('daap.protocolversion', '3.0'), do('dmap.timeoutinterval', 1800), do('dmap.itemname', server_name), do('dmap.loginrequired', 0), do('dmap.authenticationmethod', 0), do('dmap.supportsextensions', 0), do('dmap.supportsindex', 0), do('dmap.supportsbrowse', 0), do('dmap.supportsquery', 0), do('dmap.supportspersistentids', 0), do('dmap.databasescount', 1), #do('dmap.supportsautologout', 0), #do('dmap.supportsupdate', 0), #do('dmap.supportsresolve', 0), ]) self.h(msrv.encode())
def do_GET_login(self): mlog = do('dmap.loginresponse', [ do('dmap.status', 200), do('dmap.sessionid', session_id) ]) self.h(mlog.encode())
def parse_extra_vorbis(self, filename, md, daap): daap.extend([do('daap.songbitrate', md.info.bitrate / 1000), do('daap.songformat', 'ogg'), do('daap.songdescription', 'Ogg/Vorbis Audio File')])
def do_GET_login(self): mlog = do('dmap.loginresponse', [do('dmap.status', 200), do('dmap.sessionid', session_id)]) self.h(mlog.encode())