def generate_waveform(song, mp3_file, filename_appendix=""): suffix = '.png' png_tmp_handle = tempfile.NamedTemporaryFile(mode='r+b', suffix=suffix) p = subprocess.Popen([ 'waveform', '--width', str(design.waveform_size[0]), '--height', str(design.waveform_size[1]), '--color-bg', '00000000', '--color-center', design.waveform_center_color, '--color-outer', design.waveform_outer_color, mp3_file, png_tmp_handle.name, ]) p.communicate() # move to storage song.waveform_img = os.path.join( obfuscated_url(song.band), clean_filename(song.displayString()) + filename_appendix + suffix) import storage storage.engine.store(png_tmp_handle.name, song.waveform_img, reducedRedundancy=True) # clean up png_tmp_handle.close()
def handle_mp3_upload(file_mp3_handle, song, max_song_len=None, filename_appendix=""): data = {'success': False} # upload mp3 file to temp folder mp3_tmp_handle = tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) upload_file_h(file_mp3_handle, mp3_tmp_handle) mp3_tmp_handle.close() # read the length tag try: audio = MP3(mp3_tmp_handle.name, ID3=EasyID3) song.length = audio.info.length except: data['reason'] = design.invalid_mp3_file return data # reject if invalid if audio.info.sketchy: data['reason'] = design.sketchy_mp3_file return data # reject if too long if max_song_len != None: if audio.info.length > max_song_len: data['reason'] = design.song_too_long return data # enforce ID3 tags try: audio.add_tags(ID3=EasyID3) except MutagenID3Error: pass audio['artist'] = song.band.title if song.title != None: audio['title'] = song.title if song.album != None: audio['album'] = song.album try: audio.save() except: data['reason'] = design.unable_to_save_id3_tags return data # pick a path for the mp3 file. obscure the URL so that people can't steal songs song.mp3_file = os.path.join(obfuscated_url(song.band), clean_filename(song.displayString() + filename_appendix + '.mp3')) generate_waveform(song, mp3_tmp_handle.name, filename_appendix) # count mp3 against the band's size quota song.band.used_space += os.path.getsize(mp3_tmp_handle.name) # move mp3 file to storage move_to_storage(mp3_tmp_handle.name, song.mp3_file) song.band.save() data = {'success': True} return data
def download_zip(request): song = get_object_or_404(Song, pk=get_val(request.GET, 'song', 0)) if not song.permission_to_view_source(request.user): raise Http403 wanted_samples = request.GET.getlist('s') if len(wanted_samples) == 0: want_project = True deps = SampleDependency.objects.filter(song=song).exclude(uploaded_sample=None) else: want_project = False wanted_sample_ids = [] for wanted_sample in wanted_samples: if wanted_sample == 'project': want_project = True continue try: wanted_sample_id = int(wanted_sample) except ValueError: continue wanted_sample_ids.append(wanted_sample_id) deps = SampleDependency.objects.filter(pk__in=wanted_sample_ids, song=song).exclude(uploaded_sample=None) zip_file_h = make_timed_temp_file() z = zipfile.ZipFile(zip_file_h, mode='w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) import storage def store_file_id(file_id, title): tmp = tempfile.NamedTemporaryFile(mode='r+b') storage.engine.retrieve(file_id, tmp.name) z.write(tmp.name, title) tmp.close() if want_project: _path, title = os.path.split(song.source_file) store_file_id(song.source_file, title) for dep in deps: file_id = dep.uploaded_sample.sample_file.path store_file_id(file_id, dep.title) z.close() response = HttpResponse(FileWrapper(zip_file_h), mimetype='application/zip') response['Content-Disposition'] = 'attachment; filename="%s"' % clean_filename(song.displayString() + '.zip') response['Content-Length'] = zip_file_h.tell() zip_file_h.seek(0) return response
def generate_waveform(song, mp3_file, filename_appendix=""): suffix = '.png' png_tmp_handle = tempfile.NamedTemporaryFile(mode='r+b', suffix=suffix) p = subprocess.Popen(['waveform', '--width', str(design.waveform_size[0]), '--height', str(design.waveform_size[1]), '--color-bg', '00000000', '--color-center', design.waveform_center_color, '--color-outer', design.waveform_outer_color, mp3_file, png_tmp_handle.name, ]) p.communicate() # move to storage song.waveform_img = os.path.join(obfuscated_url(song.band), clean_filename(song.displayString()) + filename_appendix + suffix) import storage storage.engine.store(png_tmp_handle.name, song.waveform_img, reducedRedundancy=True) # clean up png_tmp_handle.close()
def handle_project_file(filename, user, song, filename_appendix=""): """ creates the database entries necessary for filename as the project for song. moves filename to storage or deletes it if there is a problem. increments the band's used space. be sure to save song and song.band after calling. """ _prefix, ext = os.path.splitext(filename) profile = user.get_profile() # handle zip files if ext.lower() == '.zip': studioExts = studio_extensions() song.studio = None def zipCallback(extracted_filename): _path, title = os.path.split(extracted_filename) _prefix, ext = os.path.splitext(extracted_filename) if ext[1:].lower() in studioExts: if song.studio is None: handle_project_file(extracted_filename, user, song, filename_appendix=filename_appendix) else: handle_sample_file(extracted_filename, title, user, song.band) zip_walk(filename, zipCallback) os.remove(filename) return # read the project file with the daw source_file_title = song.displayString() profile_save_required = False try: dawProject = daw.load(filename) dawExt = dawProject.extension() # assign the correct studio try: song.studio = Studio.objects.get(identifier=dawProject.identifier) # assume the user owns the studio profile.studios.add(song.studio) profile_save_required = True except Studio.DoesNotExist: pass stuff = ( (dawProject.generators(), PluginDepenency.GENERATOR), (dawProject.effects(), PluginDepenency.EFFECT), ) for plugins, plugin_type in stuff: for plugin in plugins: # if it's an invalid name, ignore if plugin.strip() == '': continue if plugin in IGNORED_PLUGINS: continue # see if it already exists deps = PluginDepenency.objects.filter(title=plugin) if deps.count() == 0: # create it dep = PluginDepenency() dep.title = plugin dep.plugin_type = plugin_type dep.save() else: dep = deps[0] # add it as a dependency song.plugins.add(dep) # assume that the user owns this dependency if profile.assume_uploaded_plugins_owned: profile.plugins.add(dep) profile_save_required = True samples = dawProject.samples() for sample in samples: # if it's an invalid name, ignore if sample.strip() == '': continue _path, title = os.path.split(sample) # create the dependency dep = SampleDependency() dep.title = title dep.song = song # if the title matches anthing the user or band has already uploaded, # establish a link. existing_samples = UploadedSample.objects.filter(title=title).filter(Q(user=user)|Q(band=song.band)) if existing_samples.count() > 0: # TODO: handle title ambiguity # copy the dependency to this song existing_sample = existing_samples[0] dep.uploaded_sample = existing_sample dep.save() if dawExt: source_file_title += filename_appendix + "." + dawExt usingDaw = True except daw.exceptions.LoadError: usingDaw = False # ok forget about processing it with the daw # add the extension from before source_file_title += filename_appendix + ext finally: if profile_save_required: profile.save() song.source_file = os.path.join(obfuscated_url(song.band), clean_filename(source_file_title)) if usingDaw: out_handle = tempfile.NamedTemporaryFile(mode='r+b') dawProject.save(out_handle.name) # count it against the band's size quota song.band.used_space += os.path.getsize(out_handle.name) # move to storage import storage storage.engine.store(out_handle.name, song.source_file) out_handle.close() os.remove(filename) else: # count it against the band's size quota song.band.used_space += os.path.getsize(filename) # move to storage move_to_storage(filename, song.source_file) song.save()
def download_zip(request): song = get_object_or_404(Song, pk=get_val(request.GET, 'song', 0)) if not song.permission_to_view_source(request.user): raise Http403 wanted_samples = request.GET.getlist('s') if len(wanted_samples) == 0: want_project = True deps = SampleDependency.objects.filter(song=song).exclude( uploaded_sample=None) else: want_project = False wanted_sample_ids = [] for wanted_sample in wanted_samples: if wanted_sample == 'project': want_project = True continue try: wanted_sample_id = int(wanted_sample) except ValueError: continue wanted_sample_ids.append(wanted_sample_id) deps = SampleDependency.objects.filter( pk__in=wanted_sample_ids, song=song).exclude(uploaded_sample=None) zip_file_h = make_timed_temp_file() z = zipfile.ZipFile(zip_file_h, mode='w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) import storage def store_file_id(file_id, title): tmp = tempfile.NamedTemporaryFile(mode='r+b') storage.engine.retrieve(file_id, tmp.name) z.write(tmp.name, title) tmp.close() if want_project: _path, title = os.path.split(song.source_file) store_file_id(song.source_file, title) for dep in deps: file_id = dep.uploaded_sample.sample_file.path store_file_id(file_id, dep.title) z.close() response = HttpResponse(FileWrapper(zip_file_h), mimetype='application/zip') response[ 'Content-Disposition'] = 'attachment; filename="%s"' % clean_filename( song.displayString() + '.zip') response['Content-Length'] = zip_file_h.tell() zip_file_h.seek(0) return response
def handle_mp3_upload(file_mp3_handle, song, max_song_len=None, filename_appendix=""): data = {'success': False} # upload mp3 file to temp folder mp3_tmp_handle = tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) upload_file_h(file_mp3_handle, mp3_tmp_handle) mp3_tmp_handle.close() # read the length tag try: audio = MP3(mp3_tmp_handle.name, ID3=EasyID3) song.length = audio.info.length except: data['reason'] = design.invalid_mp3_file return data # reject if invalid if audio.info.sketchy: data['reason'] = design.sketchy_mp3_file return data # reject if too long if max_song_len != None: if audio.info.length > max_song_len: data['reason'] = design.song_too_long return data # enforce ID3 tags try: audio.add_tags(ID3=EasyID3) except MutagenID3Error: pass audio['artist'] = song.band.title if song.title != None: audio['title'] = song.title if song.album != None: audio['album'] = song.album try: audio.save() except: data['reason'] = design.unable_to_save_id3_tags return data # pick a path for the mp3 file. obscure the URL so that people can't steal songs song.mp3_file = os.path.join( obfuscated_url(song.band), clean_filename(song.displayString() + filename_appendix + '.mp3')) generate_waveform(song, mp3_tmp_handle.name, filename_appendix) # count mp3 against the band's size quota song.band.used_space += os.path.getsize(mp3_tmp_handle.name) # move mp3 file to storage move_to_storage(mp3_tmp_handle.name, song.mp3_file) song.band.save() data = {'success': True} return data
def handle_project_file(filename, user, song, filename_appendix=""): """ creates the database entries necessary for filename as the project for song. moves filename to storage or deletes it if there is a problem. increments the band's used space. be sure to save song and song.band after calling. """ _prefix, ext = os.path.splitext(filename) profile = user.get_profile() # handle zip files if ext.lower() == '.zip': studioExts = studio_extensions() song.studio = None def zipCallback(extracted_filename): _path, title = os.path.split(extracted_filename) _prefix, ext = os.path.splitext(extracted_filename) if ext[1:].lower() in studioExts: if song.studio is None: handle_project_file(extracted_filename, user, song, filename_appendix=filename_appendix) else: handle_sample_file(extracted_filename, title, user, song.band) zip_walk(filename, zipCallback) os.remove(filename) return # read the project file with the daw source_file_title = song.displayString() profile_save_required = False try: dawProject = daw.load(filename) dawExt = dawProject.extension() # assign the correct studio try: song.studio = Studio.objects.get(identifier=dawProject.identifier) # assume the user owns the studio profile.studios.add(song.studio) profile_save_required = True except Studio.DoesNotExist: pass stuff = ( (dawProject.generators(), PluginDepenency.GENERATOR), (dawProject.effects(), PluginDepenency.EFFECT), ) for plugins, plugin_type in stuff: for plugin in plugins: # if it's an invalid name, ignore if plugin.strip() == '': continue if plugin in IGNORED_PLUGINS: continue # see if it already exists deps = PluginDepenency.objects.filter(title=plugin) if deps.count() == 0: # create it dep = PluginDepenency() dep.title = plugin dep.plugin_type = plugin_type dep.save() else: dep = deps[0] # add it as a dependency song.plugins.add(dep) # assume that the user owns this dependency if profile.assume_uploaded_plugins_owned: profile.plugins.add(dep) profile_save_required = True samples = dawProject.samples() for sample in samples: # if it's an invalid name, ignore if sample.strip() == '': continue _path, title = os.path.split(sample) # create the dependency dep = SampleDependency() dep.title = title dep.song = song # if the title matches anthing the user or band has already uploaded, # establish a link. existing_samples = UploadedSample.objects.filter( title=title).filter(Q(user=user) | Q(band=song.band)) if existing_samples.count() > 0: # TODO: handle title ambiguity # copy the dependency to this song existing_sample = existing_samples[0] dep.uploaded_sample = existing_sample dep.save() if dawExt: source_file_title += filename_appendix + "." + dawExt usingDaw = True except daw.exceptions.LoadError: usingDaw = False # ok forget about processing it with the daw # add the extension from before source_file_title += filename_appendix + ext finally: if profile_save_required: profile.save() song.source_file = os.path.join(obfuscated_url(song.band), clean_filename(source_file_title)) if usingDaw: out_handle = tempfile.NamedTemporaryFile(mode='r+b') dawProject.save(out_handle.name) # count it against the band's size quota song.band.used_space += os.path.getsize(out_handle.name) # move to storage import storage storage.engine.store(out_handle.name, song.source_file) out_handle.close() os.remove(filename) else: # count it against the band's size quota song.band.used_space += os.path.getsize(filename) # move to storage move_to_storage(filename, song.source_file) song.save()