def convert_to_solr_document(sound): document = {} # Basic sound fields keep_fields = ['username', 'created', 'is_explicit', 'avg_rating', 'is_remix', 'num_ratings', 'channels', 'md5', 'was_remixed', 'original_filename', 'duration', 'type', 'id', 'num_downloads', 'filesize'] for key in keep_fields: document[key] = getattr(sound, key) document["original_filename"] = remove_control_chars(getattr(sound, "original_filename")) document["description"] = remove_control_chars(getattr(sound, "description")) document["tag"] = getattr(sound, "tag_array") document["license"] = getattr(sound, "license_name") if getattr(sound, "pack_id"): document["pack"] = remove_control_chars(getattr(sound, "pack_name")) document["grouping_pack"] = str(getattr(sound, "pack_id")) + "_" + remove_control_chars(getattr(sound, "pack_name")) else: document["grouping_pack"] = str(getattr(sound, "id")) document["is_geotagged"] = False if getattr(sound, "geotag_id"): document["is_geotagged"] = True if not math.isnan(getattr(sound, "geotag_lon")) and not math.isnan(getattr(sound, "geotag_lat")): document["geotag"] = str(getattr(sound, "geotag_lon")) + " " + str(getattr(sound, "geotag_lat")) document["bitdepth"] = getattr(sound, "bitdepth") if getattr(sound, "bitdepth") else 0 document["bitrate"] = getattr(sound, "bitrate") if getattr(sound, "bitrate") else 0 document["samplerate"] = int(getattr(sound, "samplerate")) if getattr(sound, "samplerate") else 0 document["comment"] = [remove_control_chars(comment_text) for comment_text in getattr(sound, "comments_array")] document["comments"] = getattr(sound, "num_comments") locations = sound.locations() document["waveform_path_m"] = locations["display"]["wave"]["M"]["path"] document["waveform_path_l"] = locations["display"]["wave"]["L"]["path"] document["spectral_path_m"] = locations["display"]["spectral"]["M"]["path"] document["spectral_path_l"] = locations["display"]["spectral"]["L"]["path"] document["preview_path"] = locations["preview"]["LQ"]["mp3"]["path"] # Audio Commons analysis # NOTE: as the sound object here is the one returned by SoundManager.bulk_query_solr, it will have the Audio Commons # descriptor fields under a property called 'ac_analysis'. ac_analysis = getattr(sound, "ac_analysis") if ac_analysis is not None: # If analysis is present, index all existing analysis fields under SOLR's dynamic fields "*_i", "*_d", "*_s" # and "*_b" depending on the value's type. Also add Audio Commons prefix. for key, value in ac_analysis.items(): suffix = settings.SOLR_DYNAMIC_FIELDS_SUFFIX_MAP.get(type(value), None) if suffix: document['{0}{1}{2}'.format(settings.AUDIOCOMMONS_DESCRIPTOR_PREFIX, key, suffix)] = value return document
def convert_to_solr_document(sound): document = {} keep_fields = [ 'username', 'created', 'is_explicit', 'avg_rating', 'is_remix', 'num_ratings', 'channels', 'md5', 'was_remixed', 'original_filename', 'duration', 'type', 'id', 'num_downloads', 'filesize' ] for key in keep_fields: document[key] = getattr(sound, key) document["original_filename"] = remove_control_chars( getattr(sound, "original_filename")) document["description"] = remove_control_chars( getattr(sound, "description")) document["tag"] = getattr(sound, "tag_array") document["license"] = getattr(sound, "license_name") if getattr(sound, "pack_id"): document["pack"] = remove_control_chars(getattr(sound, "pack_name")) document["grouping_pack"] = str(getattr( sound, "pack_id")) + "_" + remove_control_chars( getattr(sound, "pack_name")) else: document["grouping_pack"] = str(getattr(sound, "id")) document["is_geotagged"] = False if getattr(sound, "geotag_id"): document["is_geotagged"] = True if not math.isnan(getattr(sound, "geotag_lon")) and not math.isnan( getattr(sound, "geotag_lat")): document["geotag"] = str(getattr(sound, "geotag_lon")) + " " + str( getattr(sound, "geotag_lat")) document["bitdepth"] = getattr(sound, "bitdepth") if getattr( sound, "bitdepth") else 0 document["bitrate"] = getattr(sound, "bitrate") if getattr( sound, "bitrate") else 0 document["samplerate"] = int(getattr(sound, "samplerate")) if getattr( sound, "samplerate") else 0 document["comment"] = [ remove_control_chars(comment_text) for comment_text in getattr(sound, "comments_array") ] document["comments"] = getattr(sound, "num_comments") locations = sound.locations() document["waveform_path_m"] = locations["display"]["wave"]["M"]["path"] document["waveform_path_l"] = locations["display"]["wave"]["L"]["path"] document["spectral_path_m"] = locations["display"]["spectral"]["M"]["path"] document["spectral_path_l"] = locations["display"]["spectral"]["L"]["path"] document["preview_path"] = locations["preview"]["LQ"]["mp3"]["path"] return document
def convert_to_solr_document(post): document = { "id": post.id, "thread_id": post.thread.id, "thread_title": remove_control_chars(post.thread.title), "thread_author": post.thread.author, "thread_created": post.thread.created, "forum_name": post.thread.forum.name, "forum_name_slug": post.thread.forum.name_slug, "post_author": post.author, "post_created": post.created, "post_body": remove_control_chars(post.body), "num_posts": post.thread.num_posts, "has_posts": False if post.thread.num_posts == 0 else True } return document
def convert_to_solr_document(sound): #logger.info("creating solr XML from sound %d" % sound.id) document = dict() document["id"] = sound.id document["username"] = sound.user.username document["created"] = sound.created document["original_filename"] = remove_control_chars(sound.original_filename) document["description"] = remove_control_chars(sound.description) document["tag"] = list(sound.tags.select_related("tag").values_list('tag__name', flat=True)) document["license"] = sound.license.name document["is_remix"] = bool(sound.sources.count()) document["was_remixed"] = bool(sound.remixes.count()) if sound.pack: document["pack"] = remove_control_chars(sound.pack.name) document["grouping_pack"] = str(sound.pack.id) + "_" + remove_control_chars(sound.pack.name) else: document["grouping_pack"] = str(sound.id) document["is_geotagged"] = sound.geotag_id is not None if sound.geotag_id is not None: if not math.isnan(sound.geotag.lon) and not math.isnan(sound.geotag.lat): document["geotag"] = str(sound.geotag.lon) + " " + str(sound.geotag.lat) document["type"] = sound.type document["duration"] = sound.duration document["bitdepth"] = sound.bitdepth if sound.bitdepth != None else 0 document["bitrate"] = sound.bitrate if sound.bitrate != None else 0 document["samplerate"] = int(sound.samplerate) document["filesize"] = sound.filesize document["channels"] = sound.channels document["md5"] = sound.md5 document["num_downloads"] = sound.num_downloads document["avg_rating"] = sound.avg_rating document["num_ratings"] = sound.num_ratings document["comment"] = [remove_control_chars(comment_text) for comment_text in sound.comments.values_list('comment', flat=True)] document["comments"] = sound.num_comments document["waveform_path_m"] = sound.locations()["display"]["wave"]["M"]["path"] document["waveform_path_l"] = sound.locations()["display"]["wave"]["L"]["path"] document["spectral_path_m"] = sound.locations()["display"]["spectral"]["M"]["path"] document["spectral_path_l"] = sound.locations()["display"]["spectral"]["L"]["path"] document["preview_path"] = sound.locations()["preview"]["LQ"]["mp3"]["path"] return document
def post_edit(request, post_id): post = get_object_or_404(Post, id=post_id) if post.author == request.user or request.user.has_perm( 'forum.change_post'): if request.method == 'POST': form = PostReplyForm(request, '', request.POST) if form.is_valid(): post.body = remove_control_chars(form.cleaned_data['body']) post.save() add_post_to_solr(post.id) # Update post in solr return HttpResponseRedirect( reverse('forums-post', args=[ post.thread.forum.name_slug, post.thread.id, post.id ])) else: form = PostReplyForm(request, '', {'body': post.body}) tvars = {'form': form} return render(request, 'forum/post_edit.html', tvars) else: raise Http404
def sound_edit(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, processing_state='OK') if sound.user.username.lower() != username.lower(): raise Http404 if not (request.user.has_perm('sound.can_change') or sound.user == request.user): raise PermissionDenied def is_selected(prefix): if request.method == "POST": for name in request.POST.keys(): if name.startswith(prefix + '-'): return True return False def update_sound_tickets(sound, text): tickets = Ticket.objects.filter(sound_id=sound.id)\ .exclude(status=TICKET_STATUS_CLOSED) for ticket in tickets: tc = TicketComment(sender=request.user, ticket=ticket, moderator_only=False, text=text) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, ticket.MODERATOR_ONLY) if is_selected("description"): description_form = SoundDescriptionForm( request.POST, prefix="description", explicit_disable=sound.is_explicit) if description_form.is_valid(): data = description_form.cleaned_data sound.is_explicit = data["is_explicit"] sound.set_tags(data["tags"]) sound.description = remove_control_chars(data["description"]) sound.original_filename = data["name"] sound.mark_index_dirty() sound.invalidate_template_caches() update_sound_tickets( sound, '%s updated the sound description and/or tags.' % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: tags = " ".join([ tagged_item.tag.name for tagged_item in sound.tags.all().order_by('tag__name') ]) description_form = SoundDescriptionForm( prefix="description", explicit_disable=sound.is_explicit, initial=dict(tags=tags, description=sound.description, name=sound.original_filename)) packs = Pack.objects.filter(user=request.user).exclude(is_deleted=True) if is_selected("pack"): pack_form = PackForm(packs, request.POST, prefix="pack") if pack_form.is_valid(): data = pack_form.cleaned_data affected_packs = [] if data['new_pack']: (pack, created) = Pack.objects.get_or_create(user=sound.user, name=data['new_pack']) if sound.pack: affected_packs.append( sound.pack) # Append previous sound pack if exists sound.pack = pack affected_packs.append(pack) else: new_pack = data["pack"] old_pack = sound.pack if new_pack != old_pack: sound.pack = new_pack if new_pack: affected_packs.append(new_pack) if old_pack: affected_packs.append(old_pack) sound.mark_index_dirty() # Marks as dirty and saves sound.invalidate_template_caches() update_sound_tickets( sound, '%s updated the sound pack.' % request.user.username) for affected_pack in affected_packs: # Process affected packs affected_pack.process() return HttpResponseRedirect(sound.get_absolute_url()) else: pack_form = PackForm( packs, prefix="pack", initial=dict(pack=sound.pack.id) if sound.pack else None) if is_selected("geotag"): geotag_form = GeotaggingForm(request.POST, prefix="geotag") if geotag_form.is_valid(): data = geotag_form.cleaned_data if data["remove_geotag"]: if sound.geotag: sound.geotag.delete() sound.geotag = None sound.mark_index_dirty() else: if sound.geotag: sound.geotag.lat = data["lat"] sound.geotag.lon = data["lon"] sound.geotag.zoom = data["zoom"] sound.geotag.save() else: sound.geotag = GeoTag.objects.create(lat=data["lat"], lon=data["lon"], zoom=data["zoom"], user=request.user) sound.mark_index_dirty() sound.mark_index_dirty() sound.invalidate_template_caches() update_sound_tickets( sound, '%s updated the sound geotag.' % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: if sound.geotag: geotag_form = GeotaggingForm(prefix="geotag", initial=dict(lat=sound.geotag.lat, lon=sound.geotag.lon, zoom=sound.geotag.zoom)) else: geotag_form = GeotaggingForm(prefix="geotag") license_form = NewLicenseForm(request.POST) if request.POST and license_form.is_valid(): new_license = license_form.cleaned_data["license"] if new_license != sound.license: sound.set_license(new_license) sound.mark_index_dirty() # Sound is saved here if sound.pack: sound.pack.process( ) # Sound license changed, process pack (if sound has pack) sound.invalidate_template_caches() update_sound_tickets( sound, '%s updated the sound license.' % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: license_form = NewLicenseForm(initial={'license': sound.license}) tvars = { 'sound': sound, 'description_form': description_form, 'pack_form': pack_form, 'geotag_form': geotag_form, 'license_form': license_form } return render(request, 'sounds/sound_edit.html', tvars)
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 sound_edit(request, username, sound_id): ONLY_RECOMMEND_TAGS_TO_HALF_OF_UPLOADS = settings.ONLY_RECOMMEND_TAGS_TO_HALF_OF_UPLOADS sound = get_object_or_404(Sound, id=sound_id, processing_state='OK') if sound.user.username.lower() != username.lower(): raise Http404 if not (request.user.has_perm('sound.can_change') or sound.user == request.user): raise PermissionDenied def invalidate_sound_cache(sound): invalidate_template_cache("sound_header", sound.id, True) invalidate_template_cache("sound_header", sound.id, False) invalidate_template_cache("sound_footer_top", sound.id) invalidate_template_cache("sound_footer_bottom", sound.id) invalidate_template_cache("display_sound", sound.id, True, sound.processing_state, sound.moderation_state) invalidate_template_cache("display_sound", sound.id, False, sound.processing_state, sound.moderation_state) def is_selected(prefix): if request.method == "POST": for name in request.POST.keys(): if name.startswith(prefix + '-'): return True return False if is_selected("description"): description_form = SoundDescriptionForm(request.POST, prefix="description") if description_form.is_valid(): data = description_form.cleaned_data sound.set_tags(data["tags"]) sound.description = remove_control_chars(data["description"]) sound.original_filename = data["name"] sound.mark_index_dirty() invalidate_sound_cache(sound) # also update any possible related sound ticket tickets = Ticket.objects.filter(content__object_id=sound.id, source=TICKET_SOURCE_NEW_SOUND) \ .exclude(status=TICKET_STATUS_CLOSED) for ticket in tickets: tc = TicketComment(sender=request.user, ticket=ticket, moderator_only=False, text='%s updated the sound description and/or tags.' % request.user.username) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, ticket.MODERATOR_ONLY) return HttpResponseRedirect(sound.get_absolute_url()) else: tags = " ".join([tagged_item.tag.name for tagged_item in sound.tags.all().order_by('tag__name')]) description_form = SoundDescriptionForm(prefix="description", initial=dict(tags=tags, description=sound.description, name=sound.original_filename)) packs = Pack.objects.filter(user=request.user) if is_selected("pack"): pack_form = PackForm(packs, request.POST, prefix="pack") if pack_form.is_valid(): data = pack_form.cleaned_data dirty_packs = [] if data['new_pack']: (pack, created) = Pack.objects.get_or_create(user=sound.user, name=data['new_pack']) sound.pack = pack else: new_pack = data["pack"] old_pack = sound.pack if new_pack != old_pack: sound.pack = new_pack if new_pack: dirty_packs.append(new_pack) if old_pack: dirty_packs.append(old_pack) for p in dirty_packs: p.process() sound.mark_index_dirty() invalidate_sound_cache(sound) return HttpResponseRedirect(sound.get_absolute_url()) else: pack_form = PackForm(packs, prefix="pack", initial=dict(pack=sound.pack.id) if sound.pack else None) if is_selected("geotag"): geotag_form = GeotaggingForm(request.POST, prefix="geotag") if geotag_form.is_valid(): data = geotag_form.cleaned_data if data["remove_geotag"]: if sound.geotag: geotag = sound.geotag.delete() sound.geotag = None sound.mark_index_dirty() else: if sound.geotag: sound.geotag.lat = data["lat"] sound.geotag.lon = data["lon"] sound.geotag.zoom = data["zoom"] sound.geotag.save() else: sound.geotag = GeoTag.objects.create(lat=data["lat"], lon=data["lon"], zoom=data["zoom"], user=request.user) sound.mark_index_dirty() invalidate_sound_cache(sound) return HttpResponseRedirect(sound.get_absolute_url()) else: if sound.geotag: geotag_form = GeotaggingForm(prefix="geotag", initial=dict(lat=sound.geotag.lat, lon=sound.geotag.lon, zoom=sound.geotag.zoom)) else: geotag_form = GeotaggingForm(prefix="geotag") license_form = NewLicenseForm(request.POST) if request.POST and license_form.is_valid(): sound.license = license_form.cleaned_data["license"] sound.mark_index_dirty() invalidate_sound_cache(sound) return HttpResponseRedirect(sound.get_absolute_url()) else: license_form = NewLicenseForm(initial={'license': sound.license}) google_api_key = settings.GOOGLE_API_KEY return render_to_response('sounds/sound_edit.html', locals(), context_instance=RequestContext(request))
def new_thread(request, forum_name_slug): forum = get_object_or_404(Forum, name_slug=forum_name_slug) user_can_post_in_forum, user_can_post_message = request.user.profile.can_post_in_forum( ) user_is_blocked_for_spam_reports = request.user.profile.is_blocked_for_spam_reports( ) if request.method == 'POST': form = NewThreadForm(request.POST) if user_can_post_in_forum and not user_is_blocked_for_spam_reports: if form.is_valid(): post_title = form.cleaned_data["title"] post_body = form.cleaned_data["body"] thread = Thread.objects.create(forum=forum, author=request.user, title=post_title) may_be_spam = text_may_be_spam(post_body) or \ text_may_be_spam(post_title) post_body = remove_control_chars(post_body) if not request.user.posts.filter( moderation_state="OK").count() and may_be_spam: post = Post.objects.create(author=request.user, body=post_body, thread=thread, moderation_state="NM") # DO NOT add the post to solr, only do it when it is moderated set_to_moderation = True else: post = Post.objects.create(author=request.user, body=post_body, thread=thread) add_post_to_solr(post.id) set_to_moderation = False # Add first post to thread (first post will always be the same) # We need to reload thread object from DB, not so overwrite the object we created before when saving # TODO: Ideally we would have a specific function to create a Post and add it to a thread immediately # so that we can use this functionality in tests too updated_thread = Thread.objects.get(id=thread.id) updated_thread.first_post = post updated_thread.save() if form.cleaned_data["subscribe"]: Subscription.objects.create(subscriber=request.user, thread=thread, is_active=True) if not set_to_moderation: return HttpResponseRedirect(post.get_absolute_url()) else: messages.add_message( request, messages.INFO, "Your post won't be shown until it is manually " "approved by moderators") return HttpResponseRedirect( post.thread.forum.get_absolute_url()) else: form = NewThreadForm() if not user_can_post_in_forum: messages.add_message(request, messages.INFO, user_can_post_message) if user_is_blocked_for_spam_reports: messages.add_message( request, messages.INFO, "You're not allowed to post in the forums because your account " "has been temporaly blocked after multiple spam reports") tvars = {'forum': forum, 'form': form} return render(request, 'forum/new_thread.html', tvars)
def sound_edit(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, processing_state="OK") if sound.user.username.lower() != username.lower(): raise Http404 if not (request.user.has_perm("sound.can_change") or sound.user == request.user): raise PermissionDenied def is_selected(prefix): if request.method == "POST": for name in request.POST.keys(): if name.startswith(prefix + "-"): return True return False def update_sound_tickets(sound, text): tickets = Ticket.objects.filter(content__object_id=sound.id, source=TICKET_SOURCE_NEW_SOUND).exclude( status=TICKET_STATUS_CLOSED ) for ticket in tickets: tc = TicketComment(sender=request.user, ticket=ticket, moderator_only=False, text=text) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, ticket.MODERATOR_ONLY) if is_selected("description"): description_form = SoundDescriptionForm(request.POST, prefix="description") if description_form.is_valid(): data = description_form.cleaned_data sound.set_tags(data["tags"]) sound.description = remove_control_chars(data["description"]) sound.original_filename = data["name"] sound.mark_index_dirty() sound.invalidate_template_caches() update_sound_tickets(sound, "%s updated the sound description and/or tags." % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: tags = " ".join([tagged_item.tag.name for tagged_item in sound.tags.all().order_by("tag__name")]) description_form = SoundDescriptionForm( prefix="description", initial=dict(tags=tags, description=sound.description, name=sound.original_filename) ) packs = Pack.objects.filter(user=request.user) if is_selected("pack"): pack_form = PackForm(packs, request.POST, prefix="pack") if pack_form.is_valid(): data = pack_form.cleaned_data affected_packs = [] if data["new_pack"]: (pack, created) = Pack.objects.get_or_create(user=sound.user, name=data["new_pack"]) if sound.pack: affected_packs.append(sound.pack) # Append previous sound pack if exists sound.pack = pack affected_packs.append(pack) else: new_pack = data["pack"] old_pack = sound.pack if new_pack != old_pack: sound.pack = new_pack if new_pack: affected_packs.append(new_pack) if old_pack: affected_packs.append(old_pack) sound.mark_index_dirty() # Marks as dirty and saves sound.invalidate_template_caches() update_sound_tickets(sound, "%s updated the sound pack." % request.user.username) for affected_pack in affected_packs: # Process affected packs affected_pack.process() return HttpResponseRedirect(sound.get_absolute_url()) else: pack_form = PackForm(packs, prefix="pack", initial=dict(pack=sound.pack.id) if sound.pack else None) if is_selected("geotag"): geotag_form = GeotaggingForm(request.POST, prefix="geotag") if geotag_form.is_valid(): data = geotag_form.cleaned_data if data["remove_geotag"]: if sound.geotag: sound.geotag.delete() sound.geotag = None sound.mark_index_dirty() else: if sound.geotag: sound.geotag.lat = data["lat"] sound.geotag.lon = data["lon"] sound.geotag.zoom = data["zoom"] sound.geotag.save() else: sound.geotag = GeoTag.objects.create( lat=data["lat"], lon=data["lon"], zoom=data["zoom"], user=request.user ) sound.mark_index_dirty() sound.mark_index_dirty() sound.invalidate_template_caches() update_sound_tickets(sound, "%s updated the sound geotag." % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: if sound.geotag: geotag_form = GeotaggingForm( prefix="geotag", initial=dict(lat=sound.geotag.lat, lon=sound.geotag.lon, zoom=sound.geotag.zoom) ) else: geotag_form = GeotaggingForm(prefix="geotag") license_form = NewLicenseForm(request.POST) if request.POST and license_form.is_valid(): sound.license = license_form.cleaned_data["license"] sound.mark_index_dirty() if sound.pack: sound.pack.process() # Sound license changed, process pack (is sound has pack) sound.invalidate_template_caches() update_sound_tickets(sound, "%s updated the sound license." % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: license_form = NewLicenseForm(initial={"license": sound.license}) tvars = { "sound": sound, "description_form": description_form, "pack_form": pack_form, "geotag_form": geotag_form, "license_form": license_form, } return render(request, "sounds/sound_edit.html", tvars)
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 = remove_control_chars(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 convert_to_solr_document(sound): document = {} # Basic sound fields keep_fields = [ 'username', 'created', 'is_explicit', 'avg_rating', 'is_remix', 'num_ratings', 'channels', 'md5', 'was_remixed', 'original_filename', 'duration', 'type', 'id', 'num_downloads', 'filesize' ] for key in keep_fields: document[key] = getattr(sound, key) document["original_filename"] = remove_control_chars( getattr(sound, "original_filename")) document["description"] = remove_control_chars( getattr(sound, "description")) document["tag"] = getattr(sound, "tag_array") document["license"] = getattr(sound, "license_name") if getattr(sound, "pack_id"): document["pack"] = remove_control_chars(getattr(sound, "pack_name")) document["grouping_pack"] = str(getattr( sound, "pack_id")) + "_" + remove_control_chars( getattr(sound, "pack_name")) else: document["grouping_pack"] = str(getattr(sound, "id")) document["is_geotagged"] = False if getattr(sound, "geotag_id"): document["is_geotagged"] = True if not math.isnan(getattr(sound, "geotag_lon")) and not math.isnan( getattr(sound, "geotag_lat")): document["geotag"] = str(getattr(sound, "geotag_lon")) + " " + str( getattr(sound, "geotag_lat")) document["bitdepth"] = getattr(sound, "bitdepth") if getattr( sound, "bitdepth") else 0 document["bitrate"] = getattr(sound, "bitrate") if getattr( sound, "bitrate") else 0 document["samplerate"] = int(getattr(sound, "samplerate")) if getattr( sound, "samplerate") else 0 document["comment"] = [ remove_control_chars(comment_text) for comment_text in getattr(sound, "comments_array") ] document["comments"] = getattr(sound, "num_comments") locations = sound.locations() document["waveform_path_m"] = locations["display"]["wave"]["M"]["path"] document["waveform_path_l"] = locations["display"]["wave"]["L"]["path"] document["spectral_path_m"] = locations["display"]["spectral"]["M"]["path"] document["spectral_path_l"] = locations["display"]["spectral"]["L"]["path"] document["preview_path"] = locations["preview"]["LQ"]["mp3"]["path"] # Audio Commons analysis # NOTE: as the sound object here is the one returned by SoundManager.bulk_query_solr, it will have the Audio Commons # descriptor fields under a property called 'ac_analysis'. ac_analysis = getattr(sound, "ac_analysis") if ac_analysis is not None: # If analysis is present, index all existing analysis fields under SOLR's dynamic fields "*_i", "*_d", "*_s" # and "*_b" depending on the value's type. Also add Audio Commons prefix. for key, value in ac_analysis.items(): suffix = settings.SOLR_DYNAMIC_FIELDS_SUFFIX_MAP.get( type(value), None) if suffix: document['{0}{1}{2}'.format( settings.AUDIOCOMMONS_DESCRIPTOR_PREFIX, key, suffix)] = value return document
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. """ # Import models using apps.get_model (to avoid circular dependencies) Sound = apps.get_model('sounds', 'Sound') License = apps.get_model('sounds', 'License') Pack = apps.get_model('sounds', 'Pack') # 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 if 'geotag' in sound_fields: # Create geotag from lat,lon,zoom text format 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 else: # Create geotag from lat, lon, zoom separated fields (if available) lat = sound_fields.get('lat', None) lon = sound_fields.get('lon', None) zoom = sound_fields.get('zoom', None) if lat is not None and lon is not None and zoom is not None: geotag = GeoTag(user=user, lat=float(lat), lon=float(lon), zoom=int(zoom)) geotag.save() sound.geotag = geotag # 6 set description, tags sound.description = remove_control_chars(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') 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 process sound and packs sound.compute_crc() if process: try: sound.process_and_analyze(high_priority=True) if sound.pack: sound.pack.process() except ServerUnavailable: pass return sound
def create_sound(user, sound_fields, apiv2_client=None, bulk_upload_progress=None, process=True, remove_exists=False): """ This function is used to create sound objects uploaded via the sound describe form, the API or the bulk describe feature. Args: user (User): user that will appear as the uploader of the sound (author) sound_fields (dict): dictionary with data to populate the different fields of the sound object. Check example usages of create_sound for more information about what are these fields and their expected format apiv2_client (ApiV2Client): ApiV2Client object corresponding to the API account that triggered the creation of that sound object (if not provided, will be set to None) bulk_upload_progress (BulkUploadProgress): BulkUploadProgress object corresponding to the bulk upload progress that triggered the creation of this sound object (if not provided, will be set to None) process (bool): whether to trigger processing and analysis of the sound object after being created (defaults to True) remove_exists (bool): if the sound we're trying to create an object for already exists (according to md5 check), delete it (defaults to False) Returns: Sound: returns the created Sound object """ # Import models using apps.get_model (to avoid circular dependencies) Sound = apps.get_model('sounds', 'Sound') License = apps.get_model('sounds', 'License') Pack = apps.get_model('sounds', 'Pack') # 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: create_directories(os.path.dirname(new_original_path), exist_ok=True) 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 if 'geotag' in sound_fields: # Create geotag from lat,lon,zoom text format 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 else: # Create geotag from lat, lon, zoom separated fields (if available) lat = sound_fields.get('lat', None) lon = sound_fields.get('lon', None) zoom = sound_fields.get('zoom', None) if lat is not None and lon is not None and zoom is not None: geotag = GeoTag(user=user, lat=float(lat), lon=float(lon), zoom=int(zoom)) geotag.save() sound.geotag = geotag # 6 set description, tags sound.description = remove_control_chars(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 or bulk progress object (if any) sound.uploaded_with_apiv2_client = apiv2_client sound.uploaded_with_bulk_upload_progress = bulk_upload_progress # 7 save! sound.save() # 8 create moderation tickets if needed if user.profile.is_whitelisted: sound.change_moderation_state('OK') 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 process sound and packs sound.compute_crc() if process: try: sound.process_and_analyze(high_priority=True) if sound.pack: sound.pack.process() except ServerUnavailable: pass # Log if sound.uploaded_with_apiv2_client is not None: upload_source = 'api' elif sound.uploaded_with_bulk_upload_progress is not None: upload_source = 'bulk' else: upload_source = 'web' sounds_logger.info('Created Sound object (%s)' % json.dumps({ 'sound_id': sound.id, 'username': sound.user.username, 'upload_source': upload_source, })) return sound
def sound_edit(request, username, sound_id): ONLY_RECOMMEND_TAGS_TO_HALF_OF_UPLOADS = settings.ONLY_RECOMMEND_TAGS_TO_HALF_OF_UPLOADS sound = get_object_or_404(Sound, id=sound_id, processing_state='OK') if sound.user.username.lower() != username.lower(): raise Http404 if not (request.user.has_perm('sound.can_change') or sound.user == request.user): raise PermissionDenied def invalidate_sound_cache(sound): invalidate_template_cache("sound_header", sound.id, True) invalidate_template_cache("sound_header", sound.id, False) invalidate_template_cache("sound_footer_top", sound.id) invalidate_template_cache("sound_footer_bottom", sound.id) invalidate_template_cache("display_sound", sound.id, True, sound.processing_state, sound.moderation_state) invalidate_template_cache("display_sound", sound.id, False, sound.processing_state, sound.moderation_state) def is_selected(prefix): if request.method == "POST": for name in request.POST.keys(): if name.startswith(prefix + '-'): return True return False def update_sound_tickets(sound, text): tickets = Ticket.objects.filter(content__object_id=sound.id, source=TICKET_SOURCE_NEW_SOUND) \ .exclude(status=TICKET_STATUS_CLOSED) for ticket in tickets: tc = TicketComment(sender=request.user, ticket=ticket, moderator_only=False, text=text) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, ticket.MODERATOR_ONLY) if is_selected("description"): description_form = SoundDescriptionForm(request.POST, prefix="description") if description_form.is_valid(): data = description_form.cleaned_data sound.set_tags(data["tags"]) sound.description = remove_control_chars(data["description"]) sound.original_filename = data["name"] sound.mark_index_dirty() invalidate_sound_cache(sound) update_sound_tickets( sound, '%s updated the sound description and/or tags.' % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: tags = " ".join([ tagged_item.tag.name for tagged_item in sound.tags.all().order_by('tag__name') ]) description_form = SoundDescriptionForm( prefix="description", initial=dict(tags=tags, description=sound.description, name=sound.original_filename)) packs = Pack.objects.filter(user=request.user) if is_selected("pack"): pack_form = PackForm(packs, request.POST, prefix="pack") if pack_form.is_valid(): data = pack_form.cleaned_data affected_packs = [] if data['new_pack']: (pack, created) = Pack.objects.get_or_create(user=sound.user, name=data['new_pack']) sound.pack = pack affected_packs.append(pack) else: new_pack = data["pack"] old_pack = sound.pack if new_pack != old_pack: sound.pack = new_pack if new_pack: affected_packs.append(new_pack) if old_pack: affected_packs.append(old_pack) sound.mark_index_dirty() # Marks as dirty and saves invalidate_sound_cache(sound) update_sound_tickets( sound, '%s updated the sound pack.' % request.user.username) for affected_pack in affected_packs: # Process affected packs affected_pack.process() return HttpResponseRedirect(sound.get_absolute_url()) else: pack_form = PackForm( packs, prefix="pack", initial=dict(pack=sound.pack.id) if sound.pack else None) if is_selected("geotag"): geotag_form = GeotaggingForm(request.POST, prefix="geotag") if geotag_form.is_valid(): data = geotag_form.cleaned_data if data["remove_geotag"]: if sound.geotag: geotag = sound.geotag.delete() sound.geotag = None sound.mark_index_dirty() else: if sound.geotag: sound.geotag.lat = data["lat"] sound.geotag.lon = data["lon"] sound.geotag.zoom = data["zoom"] sound.geotag.save() else: sound.geotag = GeoTag.objects.create(lat=data["lat"], lon=data["lon"], zoom=data["zoom"], user=request.user) sound.mark_index_dirty() sound.mark_index_dirty() invalidate_sound_cache(sound) update_sound_tickets( sound, '%s updated the sound geotag.' % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: if sound.geotag: geotag_form = GeotaggingForm(prefix="geotag", initial=dict(lat=sound.geotag.lat, lon=sound.geotag.lon, zoom=sound.geotag.zoom)) else: geotag_form = GeotaggingForm(prefix="geotag") license_form = NewLicenseForm(request.POST) if request.POST and license_form.is_valid(): sound.license = license_form.cleaned_data["license"] sound.mark_index_dirty() invalidate_sound_cache(sound) update_sound_tickets( sound, '%s updated the sound license.' % request.user.username) return HttpResponseRedirect(sound.get_absolute_url()) else: license_form = NewLicenseForm(initial={'license': sound.license}) google_api_key = settings.GOOGLE_API_KEY return render_to_response('sounds/sound_edit.html', locals(), context_instance=RequestContext(request))