def describe_sounds(request): forms = [] sounds_to_process = [] sounds = request.session.get('describe_sounds', False) if not sounds: msg = 'Please pick at least one sound.' messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(reverse('accounts-describe')) sounds_to_describe = sounds[0:settings.SOUNDS_PER_DESCRIBE_ROUND] request.session['describe_sounds_number'] = len(request.session.get('describe_sounds')) selected_license = request.session.get('describe_license', False) selected_pack = request.session.get('describe_pack', False) # If there are no files in the session redirect to the first describe page if len(sounds_to_describe) <= 0: msg = 'You have finished describing your sounds.' messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(reverse('accounts-describe')) tvars = { 'sounds_per_round': settings.SOUNDS_PER_DESCRIBE_ROUND, 'forms': forms, } if request.method == 'POST': # First get all the data n_sounds_already_part_of_freesound = 0 for i in range(len(sounds_to_describe)): prefix = str(i) forms.append({}) forms[i]['sound'] = sounds_to_describe[i] forms[i]['description'] = SoundDescriptionForm(request.POST, prefix=prefix) forms[i]['geotag'] = GeotaggingForm(request.POST, prefix=prefix) forms[i]['pack'] = PackForm(Pack.objects.filter(user=request.user), request.POST, prefix=prefix) forms[i]['license'] = NewLicenseForm(request.POST, prefix=prefix) # Validate each form for i in range(len(sounds_to_describe)): for f in ['license', 'geotag', 'pack', 'description']: if not forms[i][f].is_valid(): # If at least one form is not valid, render template with form errors return render(request, 'accounts/describe_sounds.html', tvars) # All valid, then create sounds and moderation tickets dirty_packs = [] for i in range(len(sounds_to_describe)): # Create sound object and set basic properties sound = Sound() sound.user = request.user sound.original_filename = forms[i]['description'].cleaned_data['name'] sound.original_path = forms[i]['sound'].full_path try: sound.filesize = os.path.getsize(sound.original_path) except OSError: # If for some reason audio file does not exist, skip creating this sound messages.add_message(request, messages.ERROR, 'Something went wrong with accessing the file %s.' % sound.original_path) continue sound.md5 = md5file(forms[i]['sound'].full_path) sound.type = get_sound_type(sound.original_path) sound.license = forms[i]['license'].cleaned_data['license'] try: # Check if another file with same md5 already exists, if it does, delete the sound and post a message existing_sound = Sound.objects.get(md5=sound.md5) n_sounds_already_part_of_freesound += 1 msg = 'The file %s is already part of freesound and has been discarded, see <a href="%s">here</a>' % \ (forms[i]['sound'].name, reverse('sound', args=[existing_sound.user.username, existing_sound.id])) messages.add_message(request, messages.WARNING, msg) os.remove(forms[i]['sound'].full_path) continue except Sound.DoesNotExist: # Reaching here means that no other sound already exists with the same md5 pass sound.save() # Move the original audio file orig = os.path.splitext(os.path.basename(sound.original_filename))[0] sound.base_filename_slug = "%d__%s__%s" % (sound.id, slugify(sound.user.username), slugify(orig)) new_original_path = sound.locations("path") if sound.original_path != new_original_path: try: os.makedirs(os.path.dirname(new_original_path)) except OSError: pass try: shutil.move(sound.original_path, new_original_path) except IOError, e: logger.info("Failed to move file from %s to %s" % (sound.original_path, new_original_path), e) logger.info("Moved original file from %s to %s" % (sound.original_path, new_original_path)) sound.original_path = new_original_path sound.save() # Set pack (optional) pack = forms[i]['pack'].cleaned_data.get('pack', False) new_pack = forms[i]['pack'].cleaned_data.get('new_pack', False) if not pack and new_pack: pack, created = Pack.objects.get_or_create(user=request.user, name=new_pack) if pack: sound.pack = pack dirty_packs.append(sound.pack) # Set geotag data = forms[i]['geotag'].cleaned_data if not data.get('remove_geotag') and data.get('lat'): # if 'lat' is in data, we assume other fields are too geotag = GeoTag(user=request.user, lat=data.get('lat'), lon=data.get('lon'), zoom=data.get('zoom')) geotag.save() sound.geotag = geotag # Set the tags and description data = forms[i]['description'].cleaned_data sound.description = remove_control_chars(data.get('description', '')) sound.set_tags(data.get('tags')) sound.save() # Remember to process the file and create moderation ticket if user is not whitelisted sounds_to_process.append(sound) if request.user.profile.is_whitelisted: sound.change_moderation_state('OK', do_not_update_related_stuff=True) messages.add_message(request, messages.INFO, 'File <a href="%s">%s</a> has been described and has been added to freesound.' % \ (sound.get_absolute_url(), forms[i]['sound'].name)) else: sound.create_moderation_ticket() messages.add_message(request, messages.INFO, 'File <a href="%s">%s</a> has been described and is now awaiting processing ' 'and moderation.' % (sound.get_absolute_url(), forms[i]['sound'].name)) # Invalidate affected caches in user header invalidate_template_cache("user_header", request.user.id) for moderator in Group.objects.get(name='moderators').user_set.all(): invalidate_template_cache("user_header", moderator.id) # Compute sound crc try: sound.compute_crc() except: pass # Remove the files we just described from the session and redirect to this page request.session['describe_sounds'] = request.session['describe_sounds'][len(sounds_to_describe):] # Process sounds and packs # N.B. we do this at the end to avoid conflicts between django-web and django-workers # If we're not careful django's save() functions will overwrite any processing we # do on the workers. # In the future if django-workers do not write to the db this might be changed try: for s in sounds_to_process: s.process() except Exception as e: audio_logger.error('Sound with id %s could not be scheduled. (%s)' % (s.id, str(e))) for p in dirty_packs: p.process() # Check if all sounds have been described after that round and redirect accordingly if len(request.session['describe_sounds']) <= 0: if len(sounds_to_describe) != n_sounds_already_part_of_freesound: msg = 'You have described all the selected files and are now awaiting processing and moderation. ' \ 'You can check the status of your uploaded sounds in your <a href="%s">home page</a>. ' \ 'Once your sounds have been processed, you can also get information about the moderation ' \ 'status in the <a href="%s">uploaded sounds awaiting moderation' \ '</a> page.' % (reverse('accounts-home'), reverse('accounts-pending')) messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(reverse('accounts-describe')) else: return HttpResponseRedirect(reverse('accounts-describe-sounds'))
def describe_sounds(request): sounds_to_process = [] sounds = request.session.get('describe_sounds', False) selected_license = request.session.get('describe_license', False) selected_pack = request.session.get('describe_pack', False) # This is to prevent people browsing to the /home/describe/sounds page # without going through the necessary steps. # selected_pack can be False, but license and sounds have to be picked at least if not (sounds): msg = 'Please pick at least one sound.' messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(reverse('accounts-describe')) # So SOUNDS_PER_DESCRIBE_ROUND is available in the template sounds_per_round = SOUNDS_PER_DESCRIBE_ROUND sounds_to_describe = sounds[0:sounds_per_round] forms = [] request.session['describe_sounds_number'] = len(request.session.get('describe_sounds')) # If there are no files in the session redirect to the first describe page if len(sounds_to_describe) <= 0: msg = 'You have finished describing your sounds.' messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(reverse('accounts-describe')) if request.method == 'POST': # first get all the data for i in range(len(sounds_to_describe)): prefix = str(i) forms.append({}) forms[i]['sound'] = sounds_to_describe[i] forms[i]['description'] = SoundDescriptionForm(request.POST, prefix=prefix) forms[i]['geotag'] = GeotaggingForm(request.POST, prefix=prefix) forms[i]['pack'] = PackForm(Pack.objects.filter(user=request.user), request.POST, prefix=prefix) forms[i]['license'] = NewLicenseForm(request.POST, prefix=prefix) # validate each form for i in range(len(sounds_to_describe)): for f in ['license', 'geotag', 'pack', 'description']: if not forms[i][f].is_valid(): return render_to_response('accounts/describe_sounds.html', locals(), context_instance=RequestContext(request)) # all valid, then create sounds and moderation tickets dirty_packs = [] for i in range(len(sounds_to_describe)): sound = Sound() sound.user = request.user sound.original_filename = forms[i]['description'].cleaned_data['name'] sound.original_path = forms[i]['sound'].full_path sound.filesize = os.path.getsize(sound.original_path) try: sound.md5 = md5file(forms[i]['sound'].full_path) except IOError: messages.add_message(request, messages.ERROR, 'Something went wrong with accessing the file %s.' % sound.original_path) continue sound.type = get_sound_type(sound.original_path) # check if file exists or not try: existing_sound = Sound.objects.get(md5=sound.md5) msg = 'The file %s is already part of freesound and has been discarded, see <a href="%s">here</a>' % \ (forms[i]['sound'].name, reverse('sound', args=[existing_sound.user.username, existing_sound.id])) messages.add_message(request, messages.WARNING, msg) os.remove(forms[i]['sound'].full_path) continue except Sound.DoesNotExist, e: pass # set the license sound.license = forms[i]['license'].cleaned_data['license'] sound.save() # now move the original orig = os.path.splitext(os.path.basename(sound.original_filename))[0] sound.base_filename_slug = "%d__%s__%s" % (sound.id, slugify(sound.user.username), slugify(orig)) new_original_path = sound.locations("path") if sound.original_path != new_original_path: try: os.makedirs(os.path.dirname(new_original_path)) except OSError: pass try: shutil.move(sound.original_path, new_original_path) #shutil.copy(sound.original_path, new_original_path) except IOError, e: logger.info("failed to move file from %s to %s" % (sound.original_path, new_original_path), e) logger.info("moved original file from %s to %s" % (sound.original_path, new_original_path)) sound.original_path = new_original_path sound.save() # set the pack (optional) pack = forms[i]['pack'].cleaned_data.get('pack', False) new_pack = forms[i]['pack'].cleaned_data.get('new_pack', False) if not pack and new_pack: pack, created = Pack.objects.get_or_create(user=request.user, name=new_pack) if pack: sound.pack = pack dirty_packs.append(sound.pack) # set the geotag (if 'lat' is there, all fields are) data = forms[i]['geotag'].cleaned_data if not data.get('remove_geotag') and data.get('lat'): geotag = GeoTag(user=request.user, lat=data.get('lat'), lon=data.get('lon'), zoom=data.get('zoom')) geotag.save() sound.geotag = geotag # set the tags and descriptions data = forms[i]['description'].cleaned_data sound.description = data.get('description', '') sound.set_tags(data.get('tags')) sound.save() # remember to process the file sounds_to_process.append(sound) if request.user.profile.is_whitelisted: sound.moderation_state = 'OK' sound.save() messages.add_message(request, messages.INFO, 'File <a href="%s">%s</a> has been described and has been added to freesound.' % \ (sound.get_absolute_url(), forms[i]['sound'].name)) else: # create moderation ticket! ticket = Ticket() ticket.title = 'Moderate sound %s' % sound.original_filename ticket.source = TICKET_SOURCE_NEW_SOUND ticket.status = TICKET_STATUS_NEW ticket.queue = Queue.objects.get(name='sound moderation') ticket.sender = request.user lc = LinkedContent() lc.content_object = sound lc.save() ticket.content = lc ticket.save() tc = TicketComment() tc.sender = request.user tc.text = "I've uploaded %s. Please moderate!" % sound.original_filename tc.ticket = ticket tc.save() # add notification that the file was described successfully messages.add_message(request, messages.INFO, 'File <a href="%s">%s</a> has been described and is awaiting moderation.' % \ (sound.get_absolute_url(), forms[i]['sound'].name)) # compute crc # TEMPORARY try: sound.compute_crc() except: pass
def handle(self, *args, **options): sound_list = args[0] base_dir = os.path.dirname(sound_list) delete_already_existing = False if len(args) > 1: delete_already_existing = bool(args[1]) isHeader = True for line in csv.reader(open(sound_list,'rU')): if isHeader: isHeader = False continue # 0 get data from csv pathf,namef,tagsf,geotagf,descriptionf,licensef,packnamef,usernamef = line u = User.objects.get(username=usernamef) # 1 create dir and move sound to dir directory = os.path.join(settings.UPLOADS_PATH, str(u.id)) if not os.path.exists(directory): os.mkdir(directory) src_path = base_dir + "/"+ pathf dest_path = os.path.join(directory, os.path.basename(pathf)) #print src_path,dest_path shutil.copy(src_path,dest_path) # 2 make sound object # user id (search), original_fname(name),path (new), filesize,type,slicense sound = Sound() sound.user = u sound.original_filename = namef sound.original_path = dest_path sound.filesize = os.path.getsize(sound.original_path) sound.type = get_sound_type(sound.original_path) # License format # name: 'Creative Commons 0' # name: 'Attribution' # name: 'Attribution Noncommercial' l = License.objects.get(name=licensef) sound.license = l # 3 md5, check try: sound.md5 = md5file(sound.original_path) except IOError: #messages.add_message(request, messages.ERROR, 'Something went wrong with accessing the file %s.' % sound.original_path) continue sound_already_exists = Sound.objects.filter(md5=sound.md5).exists() if sound_already_exists: if delete_already_existing: existing_sound = Sound.objects.get(md5=sound.md5) existing_sound.delete() print 'The file %s is already part of freesound, we re-add it again' % (sound.original_filename) else: os.remove(sound.original_path) print 'The file %s is already part of freesound, we re-add it again' % (sound.original_filename) continue # 4 save sound.save() # 5 move to new path orig = os.path.splitext(os.path.basename(sound.original_filename))[0] # WATCH OUT! sound.base_filename_slug = "%d__%s__%s" % (sound.id, slugify(sound.user.username), slugify(orig)) new_original_path = sound.locations("path") if sound.original_path != new_original_path: try: os.makedirs(os.path.dirname(new_original_path)) except OSError: pass try: shutil.move(sound.original_path, new_original_path) #shutil.copy(sound.original_path, new_original_path) except IOError, e: print "failed to move file from %s to %s" % (sound.original_path, new_original_path) #logger.info("failed to move file from %s to %s" % (sound.original_path, new_original_path), e) #logger.info("moved original file from %s to %s" % (sound.original_path, new_original_path)) sound.original_path = new_original_path sound.save() # 6 create pack if it does not exist if packnamef: if Pack.objects.filter(name=packnamef, user=u).exists(): p = Pack.objects.get(name=packnamef, user=u) else: p, created = Pack.objects.get_or_create(user=u, name=packnamef) sound.pack = p #dirty_packs.append(sound.pack) # 7 create geotag objects # format: lat#lon#zoom if geotagf: lat,lon,zoom = [g for g in geotagf.split(" ") if g] geotag = GeoTag(user=u, lat=float(lat), lon=float(lon), zoom=int(zoom)) geotag.save() sound.geotag = geotag # 8 set description, tags sound.description = descriptionf sound.set_tags([t for t in tagsf.split(" ") if t]) # 9 save! sound.save() # if(whitelisted): set moderation OK sound.moderation_state = 'OK' sound.save() # 10 Proces try: sound.compute_crc() except: pass try: sound.process() except Exception, e: print 'Sound with id %s could not be scheduled. (%s)' % (sound.id, str(e))
def handle(self, *args, **options): sound_list = args[0] base_dir = os.path.dirname(sound_list) delete_already_existing = False if len(args) > 1: delete_already_existing = bool(args[1]) isHeader = True for line in csv.reader(open(sound_list, 'rU')): if isHeader: isHeader = False continue # 0 get data from csv pathf, namef, tagsf, geotagf, descriptionf, licensef, packnamef, usernamef = line u = User.objects.get(username=usernamef) # 1 create dir and move sound to dir directory = os.path.join(settings.UPLOADS_PATH, str(u.id)) if not os.path.exists(directory): os.mkdir(directory) src_path = base_dir + "/" + pathf dest_path = os.path.join(directory, os.path.basename(pathf)) #print src_path,dest_path shutil.copy(src_path, dest_path) # 2 make sound object # user id (search), original_fname(name),path (new), filesize,type,slicense sound = Sound() sound.user = u sound.original_filename = namef sound.original_path = dest_path sound.filesize = os.path.getsize(sound.original_path) sound.type = get_sound_type(sound.original_path) # License format # name: 'Creative Commons 0' # name: 'Attribution' # name: 'Attribution Noncommercial' l = License.objects.get(name=licensef) sound.license = l # 3 md5, check try: sound.md5 = md5file(sound.original_path) except IOError: #messages.add_message(request, messages.ERROR, 'Something went wrong with accessing the file %s.' % sound.original_path) continue sound_already_exists = Sound.objects.filter(md5=sound.md5).exists() if sound_already_exists: if delete_already_existing: existing_sound = Sound.objects.get(md5=sound.md5) existing_sound.delete() print 'The file %s is already part of freesound, we re-add it again' % ( sound.original_filename) else: os.remove(sound.original_path) print 'The file %s is already part of freesound, not uploading it' % ( sound.original_filename) continue # 4 save sound.save() # 5 move to new path orig = os.path.splitext(os.path.basename( sound.original_filename))[0] # WATCH OUT! sound.base_filename_slug = "%d__%s__%s" % ( sound.id, slugify(sound.user.username), slugify(orig)) new_original_path = sound.locations("path") if sound.original_path != new_original_path: try: os.makedirs(os.path.dirname(new_original_path)) except OSError: pass try: shutil.move(sound.original_path, new_original_path) #shutil.copy(sound.original_path, new_original_path) except IOError, e: print "failed to move file from %s to %s" % ( sound.original_path, new_original_path) #logger.info("failed to move file from %s to %s" % (sound.original_path, new_original_path), e) #logger.info("moved original file from %s to %s" % (sound.original_path, new_original_path)) sound.original_path = new_original_path sound.save() # 6 create pack if it does not exist if packnamef: if Pack.objects.filter( name=packnamef, user=u).exclude(is_deleted=True).exists(): p = Pack.objects.get(name=packnamef, user=u) else: p, created = Pack.objects.get_or_create(user=u, name=packnamef) sound.pack = p # 7 create geotag objects # format: lat#lon#zoom if geotagf: lat, lon, zoom = [g for g in geotagf.split(" ") if g] geotag = GeoTag(user=u, lat=float(lat), lon=float(lon), zoom=int(zoom)) geotag.save() sound.geotag = geotag # 8 set description, tags sound.description = descriptionf sound.set_tags([t for t in tagsf.split(" ") if t]) # 9 save! sound.save() # if(whitelisted): set moderation OK sound.change_moderation_state('OK', do_not_update_related_stuff=True) # 10 Proces try: sound.compute_crc() except: pass try: sound.process() except Exception, e: print 'Sound with id %s could not be scheduled. (%s)' % ( sound.id, str(e))
def create_sound(user, sound_fields, apiv2_client=None, process=True, remove_exists=False): ''' This function is used by the upload handler to create a sound object with the information provided through sound_fields parameter. ''' # 1 make sound object sound = Sound() sound.user = user sound.original_filename = sound_fields['name'] sound.original_path = sound_fields['dest_path'] try: sound.filesize = os.path.getsize(sound.original_path) except OSError: raise NoAudioException() license = License.objects.get(name=sound_fields['license']) sound.type = get_sound_type(sound.original_path) sound.license = license sound.md5 = md5file(sound.original_path) sound_already_exists = Sound.objects.filter(md5=sound.md5).exists() if sound_already_exists: existing_sound = Sound.objects.get(md5=sound.md5) if remove_exists: existing_sound.delete() else: msg = 'The file %s is already part of freesound and has been discarded, see <a href="%s">here</a>' % \ (sound_fields['name'], reverse('sound', args=[existing_sound.user.username, existing_sound.id])) # Remove file (including mirror locations) os.remove(sound.original_path) remove_uploaded_file_from_mirror_locations(sound.original_path) _remove_user_uploads_folder_if_empty(sound.user) raise AlreadyExistsException(msg) # 2 save sound.save() # Create corresponding SoundLicenseHistory object (can't be done before Sound is saved for the first time) sound.set_license(license) # 3 move to new path orig = os.path.splitext(os.path.basename( sound.original_filename))[0] # WATCH OUT! sound.base_filename_slug = "%d__%s__%s" % ( sound.id, slugify(sound.user.username), slugify(orig)) new_original_path = sound.locations("path") if sound.original_path != new_original_path: try: os.makedirs(os.path.dirname(new_original_path)) except OSError: pass try: shutil.move(sound.original_path, new_original_path) # Check if user upload folder still has files and remove if empty # NOTE: we first need to remove the file from the mirror locations as we do not perform # a 'move' operation there. remove_uploaded_file_from_mirror_locations(sound.original_path) _remove_user_uploads_folder_if_empty(sound.user) except IOError as e: raise CantMoveException("Failed to move file from %s to %s" % (sound.original_path, new_original_path)) sound.original_path = new_original_path sound.save() # Copy to mirror location copy_sound_to_mirror_locations(sound) # 4 create pack if it does not exist if 'pack' in sound_fields: if sound_fields['pack']: if Pack.objects.filter( name=sound_fields['pack'], user=user).exclude(is_deleted=True).exists(): p = Pack.objects.get(name=sound_fields['pack'], user=user) else: p, created = Pack.objects.get_or_create( user=user, name=sound_fields['pack']) sound.pack = p # 5 create geotag objects # format: lat#lon#zoom if 'geotag' in sound_fields: if sound_fields['geotag']: lat, lon, zoom = sound_fields['geotag'].split(',') geotag = GeoTag(user=user, lat=float(lat), lon=float(lon), zoom=int(zoom)) geotag.save() sound.geotag = geotag # 6 set description, tags sound.description = sound_fields['description'] sound.set_tags(sound_fields['tags']) if 'is_explicit' in sound_fields: sound.is_explicit = sound_fields['is_explicit'] # 6.5 set uploaded apiv2 client sound.uploaded_with_apiv2_client = apiv2_client # 7 save! sound.save() # 8 create moderation tickets if needed if user.profile.is_whitelisted: sound.change_moderation_state('OK', do_not_update_related_stuff=True) else: # create moderation ticket! sound.create_moderation_ticket() invalidate_template_cache("user_header", user.id) moderators = Group.objects.get(name='moderators').user_set.all() for moderator in moderators: invalidate_template_cache("user_header", moderator.id) # 9 proces sound and packs try: sound.compute_crc() except: pass if process: try: sound.process() if sound.pack: sound.pack.process() except ServerUnavailable: pass return sound