def main(argv): """main function for standalone usage""" usage = "usage: %prog [options] dir" parser = OptionParser(usage=usage) parser.add_option('-f', '--full', default=False, action='store_true', help='Dump ALL groups') (options, args) = parser.parse_args(argv) if len(args) != 1: parser.print_help() return 2 # do stuff mp3s = rwalk(args[0], '*.mp3') bpms = defaultdict(list) for mp3 in mp3s: try: tags = ID3(mp3) easytags = EasyID3(mp3) except ID3NoHeaderError: continue if 'TXXX:mashupid' in tags: for pitchedbpm in allbpms(int(float(tags.get('TBPM').text[0]))): bpms[pitchedbpm].append((mp3, gettag(easytags, 'artist'), gettag(easytags, 'title'), gettag(easytags, 'genre'))) bpmgroups = sorted(bpms.keys()) if options.full: for bpm in bpmgroups: print('BPM: %d\n' % bpm) for path, artist, title, genre in bpms[bpm]: print('File: %s' % path) print('Artist: %s' % artist) print('Title: %s' % title) print('Genre: %s' % genre) else: interact()
def main(argv): """main function for standalone usage""" usage = "usage: %prog [options] dir dbfile" parser = OptionParser(usage=usage) parser.add_option('-r', '--replace', help='Replace existing BPM/key ID3 tags', default=False, action='store_true') (options, args) = parser.parse_args(argv) if len(args) != 2: parser.print_help() return 2 # do stuff mp3s = rwalk(args[0], '*.mp3') # Initialize shelve db. Check for existing 'maxkey'. db = shelve.open(args[1]) try: idx = db['maxkey'] print('%sAppending to existing database at index %s%s' % (GREEN, idx, ENDC)) except KeyError: print('%sStarting new database%s' % (GREEN, ENDC)) idx = u'0' try: for mp3 in mp3s: tags = ID3(mp3) # Skip already analyzed files if not options.replace and 'TXXX:mashupid' in tags: continue # Skip big files if os.path.getsize(mp3) > MAXSIZE: continue try: echosong = retry(audio.LocalAnalysis, [mp3], (socket.error,), sleep=30) except Exception: # This is to handle the LocalAnalysis call in the event it fails for # reasons out of my control. Print an error message and move on. When # you have time you should change the library's source to use something # smarter, say a specialized exception: AnalysisPendingException, etc. sys.stderr.write('%sSong analysis failed, skipping %s%s\n' % (RED, mp3, ENDC)) continue moreinfo = track_from_id(echosong.analysis.identifier) # Add main tags tags.add(TBPM(encoding=1, text=unicode(round(echosong.analysis.tempo['value'])))) try: tags.add(TKEY(encoding=1, text=key(echosong))) except KeyError: sys.stderr.write('%sIncorrect key info; key: %d, mode: %d%s\n' % (RED, echosong.analysis.key['value'], echosong.analysis.mode['value'], ENDC)) tags.add(TXXX(encoding=3, desc=u'danceability', text=unicode(moreinfo.danceability))) tags.add(TXXX(encoding=3, desc=u'energy', text=unicode(moreinfo.energy))) tags.add(TXXX(encoding=3, desc=u'loudness', text=unicode(moreinfo.loudness))) # Update entry in DB if it exists, or... if 'TXXX:mashupid' in tags: db[tags.get('TXXX:mashupid').text[0]] = echosong else: # create a new entry tags.add(TXXX(encoding=3, desc=u'mashupid', text=idx)) db[idx] = echosong idx = unicode(int(idx) + 1) tags.save() # So we don't hammer their servers print('%sFinished analyzing %s, sleeping...%s' % (GREEN, mp3, ENDC)) sleep(randint(0, 3)) except KeyboardInterrupt: sys.stderr.write('User termination, exiting...\n') finally: # Update 'maxkey'. db['maxkey'] = idx db.close() print('Done!')