def close(self): if self._fh is None: return self._fh.close() self._fh = None # Now re-open the MP3 file with mutagen and fix up the tags. mp3 = mutagen.mp3.MP3(self.path) # Put in the correct length. mp3.tags.add( mutagen.id3.TLEN(text=u"%d" % self.duration_ms, encoding=constants.DEFAULT_ID3_TEXT_ENCODING)) # Store a version of the title w/ both start and end times. mp3["TIT1"].text = [self._get_title()] # Add the frame count header. frame_count_tag = mutagen.id3.TXXX( desc=constants.TXXX_FRAME_COUNT_DESCRIPTION, text=[unicode(self.frame_count)], encoding=constants.DEFAULT_ID3_TEXT_ENCODING) mp3.tags.add(frame_count_tag) # Add the frame size header. frame_size_tag = mutagen.id3.TXXX( desc=constants.TXXX_FRAME_SIZE_DESCRIPTION, text=[unicode(self.frame_size)], encoding=constants.DEFAULT_ID3_TEXT_ENCODING) mp3.tags.add(frame_size_tag) # Add a UFID tag. We use the start_ms timestamp as an import # time. mp3.tags.add(ufid.ufid_tag(_ARCHIVE_VOLUME, int(self._start_ms/1000), self._sha1_calc.hexdigest())) mp3.save()
def close(self): if self._fh is None: return self._fh.close() self._fh = None # Now re-open the MP3 file with mutagen and fix up the tags. mp3 = mutagen.mp3.MP3(self.path) # Put in the correct length. mp3.tags.add( mutagen.id3.TLEN(text=u"%d" % self.duration_ms, encoding=constants.DEFAULT_ID3_TEXT_ENCODING)) # Store a version of the title w/ both start and end times. mp3["TIT1"].text = [self._get_title()] # Add the frame count header. frame_count_tag = mutagen.id3.TXXX( desc=constants.TXXX_FRAME_COUNT_DESCRIPTION, text=[unicode(self.frame_count)], encoding=constants.DEFAULT_ID3_TEXT_ENCODING) mp3.tags.add(frame_count_tag) # Add the frame size header. frame_size_tag = mutagen.id3.TXXX( desc=constants.TXXX_FRAME_SIZE_DESCRIPTION, text=[unicode(self.frame_size)], encoding=constants.DEFAULT_ID3_TEXT_ENCODING) mp3.tags.add(frame_size_tag) # Add a UFID tag. We use the start_ms timestamp as an import # time. mp3.tags.add( ufid.ufid_tag(_ARCHIVE_VOLUME, int(self._start_ms / 1000), self._sha1_calc.hexdigest())) mp3.save()
def write_mp3(args): mp3 = mutagen.mp3.MP3(args.file) write_id3(mp3.tags, args) mp3.save(v2_version=args.id3v2_version) # Generic comment format in an APEv2 tag attached to the mp3 is used by a # few legacy tools, e.g. the command-line "mp3gain" if args.mp3_apev2: apev2 = mutagen.apev2.APEv2File(args.file) write_generic(apev2, args) apev2.save()
def add_metadata(track_file, track_data): """ Adds artist and title from the track data, and downloads the cover and embeds it in the MP3 tags. """ # This needs some exception handling! # We don't always know what type the cover is! mp3 = mutagen.mp3.MP3(track_file) mp3['TPE1'] = mutagen.id3.TPE1(encoding=3, text=track_data.user['username']) mp3['TIT2'] = mutagen.id3.TIT2(encoding=3, text=track_data.title) cover_bytes = requests.get(track_data.artwork_url, stream=True).raw.read() mp3.tags.add(mutagen.id3.APIC(encoding=3, mime='image/jpeg', type=3, desc='Front cover', data=cover_bytes)) mp3.save()
def run(self): print self._label # Switch into target directory, creating it if necessary. dir = os.path.join(self._directory, self._slugify(self._label)) if not os.path.isdir(dir): os.makedirs(dir) os.chdir(dir) # Get mp3s. print "scraping %s" % self._page.url mp3s = self._page.get_mp3s() track = 0 new_files = False for mp3 in mp3s[: self._max_files]: track += 1 target = mp3.get_filename() if os.path.exists(target): # Don't replace pre-existing files. print "skipping %s" % target mp3_file = MP3File(target) else: sys.stdout.write("downloading %s... " % target) sys.stdout.flush() mp3_file = mp3.save(reporthook=self._report_progress) print new_files = True if self._apply_id3_tags and new_files: mp3_file.write_tags( artist="Podcast", album=self._label, title=target[:-4], tracknumber=str(track), date=str(datetime.date.today().year), genre="Podcast", ) if self._delete_old_files and len(mp3s) > 0: downloaded_files = set([mp3.get_filename() for mp3 in mp3s]) existing_files = set(os.listdir(os.curdir)) for filename in existing_files.difference(downloaded_files): if not filename.startswith("("): print "removing %s" % filename os.remove(filename) if new_files: if self._show_alerts: self._trigger_alert("Podcast updated", self._label) # Change back to the initial directory. os.chdir(self._original_dir)
def edit_id3(self, sound_file_path, album, artist, title, tracknumber, thumbnail): mp3 = mutagen.mp3.MP3(sound_file_path) try: mp3.add_tags(ID3=mutagen.id3.ID3) except mutagen.id3.error: pass mp3['TALB'] = mutagen.id3.TALB(encoding=3, text=album) mp3['TPE1'] = mutagen.id3.TPE1(encoding=3, text=artist) mp3['TIT2'] = mutagen.id3.TIT2(encoding=3, text=title) mp3['TRCK'] = mutagen.id3.TRCK(encoding=3, text=[str(tracknumber)]) mp3.tags.add( mutagen.id3.APIC( encoding=3, mime='image/jpeg', type=3, desc='Cover', data=thumbnail ) ) mp3.save()
def run(self): print self._label # Switch into target directory, creating it if necessary. dir = os.path.join(self._directory, self._slugify(self._label)) if not os.path.isdir(dir): os.makedirs(dir) os.chdir(dir) # Get mp3s. print "scraping %s" % self._page.url mp3s = self._page.get_mp3s() track = 0 new_files = False for mp3 in mp3s[:self._max_files]: track += 1 target = mp3.get_filename() if os.path.exists(target): # Don't replace pre-existing files. print 'skipping %s' % target mp3_file = MP3File(target) else: sys.stdout.write('downloading %s... ' % target) sys.stdout.flush() mp3_file = mp3.save(reporthook=self._report_progress) print new_files = True if self._apply_id3_tags and new_files: mp3_file.write_tags(artist='Podcast', album=self._label, title=target[:-4], tracknumber=str(track), date=str(datetime.date.today().year), genre='Podcast') if self._delete_old_files and len(mp3s) > 0: downloaded_files = set([mp3.get_filename() for mp3 in mp3s]) existing_files = set(os.listdir(os.curdir)) for filename in existing_files.difference(downloaded_files): if not filename.startswith('('): print 'removing %s' % filename os.remove(filename) if new_files: if self._show_alerts: self._trigger_alert("Podcast updated", self._label) # Change back to the initial directory. os.chdir(self._original_dir)
def upload_media(request): """ HTTP POST with the following fields: media_file, type: file client_id, type: text media_type, type: text where valid mediatypes are: 'text', 'audio', 'video', 'image' optional fields: media_text, type: text media_caption, type: text """ result = {'success': False} #error_text = '' #try: if True: if True: #try: client_id = request.POST['client_id'] media_type = request.POST['media_type'] #except: # result['error_text'] = 'Missing or invalid field' # raise Exception('missing fields') file_name = '' file_path = '' if media_type == 'image' or media_type == 'video' \ or media_type == 'audio': #if True: try: #print "FILE TYPE: {0}".format(type(request.POST['media_file'])) #print "FILE CONTENTS: {0}".format(request.POST['media_file']) #print "LIST OF FORM OBJECTS:" #print request.POST media_file_name = request.POST['media_file'].filename input_file = request.POST['media_file'].file except: result['error_text'] = 'Missing or invalid file field' raise Exception('Invalid media_file field.') media_extention="processing" # generate a unique file name to store the file to file_name = '{0}.{1}'.format(uuid.uuid4(),media_extention) file_path = os.path.join(system_config['upload_dir'], file_name) # write file to temp location, and then to disk temp_file_path = file_path + '~' output_file = open(temp_file_path, 'wb') # Finally write the data to disk input_file.seek(0) while True: data = input_file.read(2<<16) if not data: break output_file.write(data) #decode media type of written file #more file types can be added, but these should cover most for now #TODO: client side validation so they don't lose content when they upload incorrect files? #TODO: better error messages #TODO: delete / handle (in some way) files that do not validate? mimetype = magic.from_file(temp_file_path, mime=True) #process image files if media_type == 'image': #jpeg if mimetype == "image/jpeg": media_extention = 'jpg' #print "media_Extension is: " + media_extention #png elif mimetype == "image/png": media_extention = 'png' #print "media_Extension is: " + media_extention #not jpeg or png else: error_text = 'invalid image file' raise Exception('') #strip metadata from images with ImageMagick's mogrify #TODO: dynamically find mogrify (but I think it's usually /usr/bin) if True: #try: subprocess.call(['mogrify', '-strip', temp_file_path]) # subprocess.call(['/usr/bin/mogrify', '-strip', temp_file_path]) # subprocess.call(['/usr/local/bin/mogrify', '-strip', temp_file_path]) #except: # error_text = "Mogrify is missing, or in an unexpected place." # raise Exception('') #process video files elif media_type == 'video': #I can't seem to find any evidence of PII in mpg metadata if mimetype == "video/mpeg": media_extention = 'mpg' elif mimetype == "video/mp4": media_extension = "mp4" #strip metadata try: mp4 = mutagen.mp4.MP4(temp_file_path) mp4.delete() mp4.save() except: error_text = "Something went wrong while stripping metadata from mp4" raise Exception('') else: error_text = 'invalid video file' raise Exception('') #process audio files elif media_type == 'audio': #mp3 file if mimetype == "audio/mpeg": media_extention = 'mp3' #strip metadata try: mp3 = mutagen.mp3.MP3(temp_file_path) mp3.delete() mp3.save() except: error_text = "Something went wrong while stripping metadata from mp3" raise Exception('') #ogg vorbis file elif mimetype == "audio/ogg" or mimetype == "application/ogg": media_extention = 'ogg' try: ogg = mutagen.oggvorbis.Open(temp_file_path) ogg.delete() ogg.save() except: error_text = "Something went wrong while stripping metadata from ogg vorbis" raise Exception('') #not mp3 or ogg vorbis else: error_text = 'invalid audio file' raise Exception('') #I don't think the user has a way to upload files of this type besides typing in the box #so it doesn't need as robust detection. elif media_type == 'text': media_extention = 'txt' else: error_text = 'invalid media type' raise Exception('') #the file has been validated and processed, so we adjust the file path #to the mimetype-dictated file extension file_path = file_path.replace("processing", media_extention) # rename once we are valid os.rename(temp_file_path, file_path) result['file_name'] = os.path.basename(file_path) #except: #result['error_text'] = 'Missing or invalid media_file contents.' #raise Exception('missing/invalid media_file contents') media_caption = '' #if True: try: media_caption = request.POST['media_caption'] except: pass media_text = '' if media_type == 'text': try: media_text = request.POST['media_text'] except: raise Exception('Invalid/missing field') # register file with database, and get file id back media_object, created = MediaObjects.create_new_media_object( DBSession, client_id, media_type, os.path.basename(file_path), media_caption, media_text, ) result['media_id'] = media_object.media_id result['success'] = True result['new_user'] = created #result['media_text'] = media_text result['error_text'] = '' # Debug/Logging #datetime = str(strftime("%Y-%m-%d %H:%M:%S")) event_type = 'http_request' event_details = { 'url':'upload_media.json', 'event_datetime': str(datetime.datetime.now()), 'client_id': client_id, 'media_type': media_type, 'file_name': os.path.basename(file_path), 'media_caption': media_caption, 'media_text': media_text, 'success': result['success'], 'media_id': result['media_id'], 'new_user': result['new_user'], 'error_text': result['error_text'], } client_log = EventLogs.log(DBSession,client_id,event_type,json.dumps(event_details)) if created: #datetime = str(strftime("%Y-%m-%d %H:%M:%S")) event_type = 'new_user_created' event_details = { 'client_id': client_id, 'method': 'upload_media.json', } client_log = EventLogs.log(DBSession,client_id,event_type,json.dumps(event_details)) #except: # pass #resp = json.dumps(result) #return Response(resp,content_type='application/json') return make_response(result)
filename = filename.strip("_") filename += ".mp3" stdout("%s " % filename) if os.path.exists(filename): stdout("exists, skipped.\n") else: stdout("does not exist.\n") stdout(" * Fetching streams URL... ") streams_url = "/i1/tracks/%d/streams" % track.obj['id'] streams = client.get(streams_url) mp3_url = streams.obj['http_mp3_128_url'] stdout("done\n") stdout(" * Fetching MP3... ") response = requests.get(mp3_url) if response.status_code == 200: stdout("done, got %d bytes\n" % len(response.content)) open(filename, "w").write(response.content) stdout(" * Setting ID3 tags... ") mp3 = mutagen.mp3.EasyMP3(filename) mp3.tags = mutagen.easyid3.EasyID3() mp3.tags['artist'] = [track.obj['user']['username']] mp3.tags['title'] = [track.obj['title']] mp3.tags['album'] = ['soundcloud'] mp3.save() stdout("done!\n") else: stdout("failed, got HTTP %d\n" % response.status_code) stdout("All tracks processed.\n")
def entag(json_path, idx_album_p1, stderr): # cwd = os.getcwd() idx_album = idx_album_p1 - 1 target_dir = os.path.dirname(json_path) # idx_album = 0 with open(json_path, "r", encoding='utf-8') as f_json: album_ary = json.load(f_json) #(sys.stdin) album_i = check_none(album_ary[idx_album].get("ALBUM")) album_title = check_none(album_i.get("TITLE_OFFICIAL").get("DISPLAY")) stderr.write("[info] album_title=%s\n" % album_title) album_artist = check_none( album_i.get("ARTIST").get("NAME_OFFICIAL").get("DISPLAY")) stderr.write("[info] album_artist=%s\n" % album_artist) # print(album_artist) dir_mp3_prev = os.path.join(target_dir, "mp3") dir_mp3 = os.path.join(target_dir, valid_fn("%s - %s" % (album_title, album_artist))) # os.mkdir(target_dir) # shutil.move(dir_mp3_prev, dir_mp3) os.mkdir(dir_mp3) # shutil.copy(dir_mp3_prev, dir_mp3) # os.chdir(dir_mp3) # os.mkdir(dir_mp3) # os.chdir(dir_mp3) track_count = check_none(int(album_i.get("TRACK_COUNT"))) stderr.write("[info] track_count=%s\n" % track_count) track_ary = check_none(album_i.get("TRACK")) if len(track_ary) != track_count: raise Exception("number of tracks is inconsistent!") for idx_track in range(track_count): track = track_ary[idx_track] # ord_track = int(check_none(track.get("ORD"))) # if (idx_track+1)!=ord_track: # raise Exception("ORD is inconsistent") track_num = int(check_none(track.get("TRACK_NUM"))) stderr.write("[info] track num=%s\n" % track_num) if (idx_track + 1) != track_num: raise Exception("TRACK_NUM is inconsistent") track_title = check_none(track.get("TITLE_OFFICIAL").get("DISPLAY")) stderr.write("[info] track title=%s\n" % track_title) track_artist_json = track.get("ARTIST") if track_artist_json: track_artist = check_none( track_artist_json.get("NAME_OFFICIAL").get("DISPLAY")) stderr.write("[info] track artist=%s\n" % track_artist) stderr.write("[info] copying...") prev_fn = os.path.join(dir_mp3_prev, "track%02d.mp3" % track_num) mp3_fn = os.path.join( dir_mp3, "%02d - %s.mp3" % (track_num, valid_fn(track_title))) shutil.copyfile(prev_fn, mp3_fn) stderr.write("done\n") stderr.write("[info] entagging...") mp3 = mutagen.mp3.MP3(mp3_fn, ID3=mutagen.id3.ID3) mp3.add_tags(ID3=mutagen.id3.ID3) mp3["TIT2"] = mutagen.id3.TIT2(encoding=3, text=track_title) #if track_artist is not None: if track_artist_json: mp3["TPE1"] = mutagen.id3.TPE1(encoding=3, text=track_artist) else: mp3["TPE1"] = mutagen.id3.TPE1(encoding=3, text=album_artist) #if album_title is not None: mp3["TALB"] = mutagen.id3.TALB(encoding=3, text=album_title) #if album_artist is not None: mp3["TPE2"] = mutagen.id3.TPE2(encoding=3, text=album_artist) mp3["TRCK"] = mutagen.id3.TRCK(encoding=3, text="%s/%s" % (track_num, track_count)) mp3["TPOS"] = mutagen.id3.TPOS( encoding=3, text="%s/%s" % (album_i.get("DISC_IN_SET"), album_i.get("TOTAL_IN_SET"))) mp3.save() stderr.write("done\n")
continue filename = gpod.itdb_filename_on_ipod(track) try: mp3 = mutagen.mp3.MP3(filename) if not mp3.tags: print '' print '%s has no id3 tags' % (filename) print 'iTDB says: AR = %s, TI = %s, AL = %s' % ( track.artist, track.title, track.album) mp3.add_tags() # create header mp3.tags.add(mutagen.id3.TPE1(3, track.artist)) mp3.tags.add(mutagen.id3.TALB(3, track.album)) mp3.tags.add(mutagen.id3.TIT2(3, track.title)) mp3.tags.add( mutagen.id3.TXXX(3, "Taggger", "tagged from itdb with libgpod")) mp3.save() counter_upd += 1 print 'wrote tags to: %s' % (filename) else: counter_left += 1 except Exception, e: print 'informative debug output: something went wrong.. : %s' % e counter_left = counter_left + 1 print '' print ' ++ results ++' print "updated: %d\nleft as-is: %d" % (counter_upd, counter_left) print ''