def pack(request, username, pack_id): try: pack = Pack.objects.select_related().get(id=pack_id) if pack.user.username.lower() != username.lower(): raise Http404 except Pack.DoesNotExist: raise Http404 if pack.is_deleted: return render(request, 'sounds/deleted_pack.html') qs = Sound.objects.only('id').filter(pack=pack, moderation_state='OK', processing_state='OK') paginator = paginate(request, qs, settings.SOUNDS_PER_PAGE) sound_ids = [sound_obj.id for sound_obj in paginator['page']] pack_sounds = Sound.objects.ordered_ids(sound_ids) num_sounds_ok = len(qs) if num_sounds_ok == 0 and pack.num_sounds != 0: messages.add_message(request, messages.INFO, 'The sounds of this pack have <b>not been moderated</b> yet.') else: if num_sounds_ok < pack.num_sounds: messages.add_message(request, messages.INFO, 'This pack contains more sounds that have <b>not been moderated</b> yet.') tvars = {'pack': pack, 'num_sounds_ok': num_sounds_ok, 'pack_sounds': pack_sounds } tvars.update(paginator) return render(request, 'sounds/pack.html', tvars)
def pack_delete(request, username, pack_id): pack = get_object_or_404(Pack, id=pack_id) if pack.user.username.lower() != username.lower(): raise Http404 if not (request.user.has_perm('pack.can_change') or pack.user == request.user): raise PermissionDenied encrypted_string = request.GET.get("pack", None) waited_too_long = False if encrypted_string is not None: pack_id, now = decrypt(encrypted_string).split("\t") pack_id = int(pack_id) link_generated_time = float(now) if pack_id != pack.id: raise PermissionDenied if abs(time.time() - link_generated_time) < 10: logger.info("User %s requested to delete pack %s" % (request.user.username, pack_id)) pack.delete_pack(remove_sounds=False) return HttpResponseRedirect(reverse("accounts-home")) else: waited_too_long = True encrypted_link = encrypt(u"%d\t%f" % (pack.id, time.time())) tvars = { 'pack': pack, 'encrypted_link': encrypted_link, 'waited_too_long': waited_too_long } return render(request, 'sounds/pack_delete.html', tvars)
def front_page(request): rss_cache = cache.get("rss_cache", None) donations_cache = cache.get("donations_cache", None) current_forum_threads = Thread.objects.filter(pk__in=get_current_thread_ids(), first_post__moderation_state="OK", last_post__moderation_state="OK") \ .order_by('-last_post__created') \ .select_related('author', 'forum', 'last_post', 'last_post__author', 'last_post__thread', 'last_post__thread__forum') latest_additions = Sound.objects.latest_additions(5, '2 days') random_sound_id = get_sound_of_the_day_id() if random_sound_id: random_sound = Sound.objects.bulk_query_id([random_sound_id])[0] else: random_sound = None tvars = { 'rss_cache': rss_cache, 'donations_cache': donations_cache, 'current_forum_threads': current_forum_threads, 'latest_additions': latest_additions, 'random_sound': random_sound } return render(request, 'index.html', tvars)
def downloaders(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id) # Retrieve all users that downloaded a sound qs = Download.objects.filter(sound=sound_id) pagination = paginate(request, qs, 32, object_count=sound.num_downloads) page = pagination["page"] # Get all users+profiles for the user ids sounds = list(page) userids = [s.user_id for s in sounds] users = User.objects.filter(pk__in=userids).select_related("profile") user_map = {} for u in users: user_map[u.id] = u download_list = [] for s in page: download_list.append({"created": s.created, "user": user_map[s.user_id]}) download_list = sorted(download_list, key=itemgetter("created"), reverse=True) tvars = {"sound": sound, "username": username, "download_list": download_list} tvars.update(pagination) return render(request, 'sounds/downloaders.html', tvars)
def pack_edit(request, username, pack_id): pack = get_object_or_404(Pack, id=pack_id) if pack.user.username.lower() != username.lower(): raise Http404 pack_sounds = ",".join([str(s.id) for s in pack.sounds.all()]) if not (request.user.has_perm('pack.can_change') or pack.user == request.user): raise PermissionDenied current_sounds = list() if request.method == "POST": form = PackEditForm(request.POST, instance=pack) if form.is_valid(): form.save() pack.sounds.all().update(is_index_dirty=True) return HttpResponseRedirect(pack.get_absolute_url()) else: form = PackEditForm(instance=pack, initial=dict(pack_sounds=pack_sounds)) current_sounds = Sound.objects.bulk_sounds_for_pack(pack_id=pack.id) tvars = { 'pack': pack, 'form': form, 'current_sounds': current_sounds, } return render(request, 'sounds/pack_edit.html', tvars)
def for_user(request, username): sound_user = get_object_or_404(User, username__iexact=username) paginator = paginate(request, Sound.public.only('id').filter(user=sound_user), settings.SOUNDS_PER_PAGE) sound_ids = [sound_obj.id for sound_obj in paginator['page']] user_sounds = Sound.objects.ordered_ids(sound_ids) tvars = {'sound_user': sound_user, 'user_sounds': user_sounds} tvars.update(paginator) return render(request, 'sounds/for_user.html', tvars)
def packs(request): order = request.GET.get("order", "name") if order not in ["name", "-last_updated", "-created", "-num_sounds", "-num_downloads"]: order = "name" qs = Pack.objects.select_related() \ .filter(num_sounds__gt=0) \ .exclude(is_deleted=True) \ .order_by(order) tvars = {'order': order} tvars.update(paginate(request, qs, settings.PACKS_PER_PAGE, cache_count=True)) return render(request, 'sounds/browse_packs.html', tvars)
def pack_downloaders(request, username, pack_id): pack = get_object_or_404(Pack, id=pack_id) # Retrieve all users that downloaded a sound qs = PackDownload.objects.filter(pack_id=pack_id) paginator = paginate(request, qs, 32, object_count=pack.num_downloads) tvars = {'username': username, 'pack': pack} tvars.update(paginator) return render(request, 'sounds/pack_downloaders.html', tvars)
def remix_group(request, group_id): group = get_object_or_404(RemixGroup, id=group_id) data = group.protovis_data sounds = Sound.objects.ordered_ids( [element['id'] for element in group.sounds.all().order_by('created').values('id')]) tvars = { 'sounds': sounds, 'last_sound': sounds[len(sounds)-1], 'group_sound': sounds[0], 'data': data, } return render(request, 'sounds/remixes.html', tvars)
def packs_for_user(request, username): user = get_object_or_404(User, username__iexact=username) order = request.GET.get("order", "name") if order not in ["name", "-last_updated", "-created", "-num_sounds", "-num_downloads"]: order = "name" qs = Pack.objects.select_related().filter(user=user, num_sounds__gt=0).exclude(is_deleted=True).order_by(order) paginator = paginate(request, qs, settings.PACKS_PER_PAGE) tvars = {'user': user, 'order': order} tvars.update(paginator) return render(request, 'sounds/packs.html', tvars)
def pack(request, username, pack_id): try: pack = Pack.objects.select_related().get(id=pack_id) if pack.user.username.lower() != username.lower(): raise Http404 except Pack.DoesNotExist: raise Http404 if pack.is_deleted: return render(request, 'sounds/deleted_pack.html') qs = Sound.objects.only('id').filter(pack=pack, moderation_state='OK', processing_state='OK') paginator = paginate(request, qs, settings.SOUNDS_PER_PAGE) sound_ids = [sound_obj.id for sound_obj in paginator['page']] pack_sounds = Sound.objects.ordered_ids(sound_ids) num_sounds_ok = len(qs) if num_sounds_ok == 0 and pack.num_sounds != 0: messages.add_message( request, messages.INFO, 'The sounds of this pack have <b>not been moderated</b> yet.') else: if num_sounds_ok < pack.num_sounds: messages.add_message( request, messages.INFO, 'This pack contains more sounds that have <b>not been moderated</b> yet.' ) tvars = { 'pack': pack, 'num_sounds_ok': num_sounds_ok, 'pack_sounds': pack_sounds } tvars.update(paginator) return render(request, 'sounds/pack.html', tvars)
def remix_group(request, group_id): group = get_object_or_404(RemixGroup, id=group_id) data = group.protovis_data sounds = Sound.objects.ordered_ids([ element['id'] for element in group.sounds.all().order_by('created').values('id') ]) tvars = { 'sounds': sounds, 'last_sound': sounds[len(sounds) - 1], 'group_sound': sounds[0], 'data': data, } return render(request, 'sounds/remixes.html', tvars)
def packs(request): order = request.GET.get("order", "name") if order not in [ "name", "-last_updated", "-created", "-num_sounds", "-num_downloads" ]: order = "name" qs = Pack.objects.select_related() \ .filter(num_sounds__gt=0) \ .exclude(is_deleted=True) \ .order_by(order) tvars = {'order': order} tvars.update(paginate(request, qs, settings.PACKS_PER_PAGE)) return render(request, 'sounds/browse_packs.html', tvars)
def front_page(request): rss_cache = cache.get( "rss_cache_bw" if using_beastwhoosh(request) else "rss_cache", None) trending_sound_ids = cache.get("trending_sound_ids", None) popular_searches = cache.get("popular_searches", None) current_forum_threads = Thread.objects.filter(pk__in=get_current_thread_ids(), first_post__moderation_state="OK", last_post__moderation_state="OK") \ .order_by('-last_post__created') \ .select_related('author', 'forum', 'last_post', 'last_post__author', 'last_post__thread', 'last_post__thread__forum') latest_additions = Sound.objects.latest_additions(5, '2 days') random_sound_id = get_sound_of_the_day_id() if random_sound_id: random_sound = Sound.objects.bulk_query_id([random_sound_id])[0] else: random_sound = None top_donor = None if using_beastwhoosh(request): # TODO: simplify the calclation of the top donor using annotate in the query # TODO: add pertinent caching strategy here last_week = get_n_weeks_back_datetime(n_weeks=1) top_donor_data = defaultdict(int) for username, amount in \ Donation.objects.filter(created__gt=last_week)\ .exclude(user=None, is_anonymous=True)\ .values_list('user__username', 'amount'): top_donor_data[username] += amount if top_donor_data: top_donor_username = sorted(top_donor_data.items(), key=lambda x: x[1], reverse=True)[0][0] top_donor = User.objects.get(username=top_donor_username) tvars = { 'rss_cache': rss_cache, 'popular_searches': popular_searches, 'trending_sound_ids': trending_sound_ids, 'current_forum_threads': current_forum_threads, 'latest_additions': latest_additions, 'random_sound': random_sound, 'top_donor': top_donor, } return render(request, 'front.html', tvars)
def packs_for_user(request, username): user = get_object_or_404(User, username__iexact=username) order = request.GET.get("order", "name") if order not in [ "name", "-last_updated", "-created", "-num_sounds", "-num_downloads" ]: order = "name" qs = Pack.objects.select_related().filter( user=user, num_sounds__gt=0).exclude(is_deleted=True).order_by(order) return render( request, 'sounds/packs.html', combine_dicts(paginate(request, qs, settings.PACKS_PER_PAGE), locals()))
def embed_iframe(request, sound_id, player_size): """ This view returns an HTML player of `sound_id` which can be embeded in external sites. The player can take different "sizes" including: - 'mini': shows just a play button and a loop button. No background image. Eg: /embed/sound/iframe/1234/simple/mini/. - 'small': shows a play button, a loop button and the name of the user and sound. No background image. Eg: /embed/sound/iframe/1234/simple/small/. - 'medium': shows the waveform image with playing controls plus the sound name, username, license and some tags. Eg: /embed/sound/iframe/1234/simple/medium/. - 'medium_no_info': shows the waveform and with playing controls. Eg: /embed/sound/iframe/1234/simple/medium_no_info/. - 'large': shows the waveform image in large size with playing controls plus the sound name, username and license. Eg: /embed/sound/iframe/1234/simple/large/. - 'large_no_info': shows the waveform image in large size with playing controls. Eg: /embed/sound/iframe/1234/simple/large_no_info/. - 'full_size': like 'large' but taking the full width (used in twitter embeds). Eg: /embed/sound/iframe/1234/simple/full_size/. The sizes 'medium', 'medium_no_info', 'large', 'large_no_info' and 'full_size' can optionally show the spectrogram image instead of the waveform if being passed a request parameter 'spec=1' in the URL. Eg: /embed/sound/iframe/1234/simple/large/?spec=1. The sizes 'medium' and 'medium_no_info' can optionally show a button to toggle the background image between the waveform and the spectrogram by passing the request parameter 'td=1'. Bigger sizes always show that button. """ if player_size not in [ 'mini', 'small', 'medium', 'large', 'large_no_info', 'medium_no_info', 'full_size' ]: raise Http404 sound = get_object_or_404(Sound, id=sound_id, moderation_state='OK', processing_state='OK') tvars = { 'sound': sound, 'username_and_filename': '%s - %s' % (sound.user.username, sound.original_filename), 'size': player_size, 'use_spectrogram': request.GET.get('spec', None) == '1', 'show_toggle_display_button': request.GET.get('td', None) == '1', } return render(request, 'sounds/sound_iframe.html', tvars)
def similar(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, moderation_state="OK", processing_state="OK", analysis_state="OK", similarity_state="OK") if sound.user.username.lower() != username.lower(): raise Http404 similarity_results, count = get_similar_sounds(sound, request.GET.get('preset', None), int(settings.SOUNDS_PER_PAGE)) similar_sounds = Sound.objects.ordered_ids([sound_id for sound_id, distance in similarity_results]) tvars = {'similar_sounds': similar_sounds} return render(request, 'sounds/similar.html', tvars)
def packs_for_user(request, username): user = request.parameter_user order = request.GET.get("order", "name") if order not in [ "name", "-last_updated", "-created", "-num_sounds", "-num_downloads" ]: order = "name" qs = Pack.objects.select_related().filter( user=user, num_sounds__gt=0).exclude(is_deleted=True).order_by(order) paginator = paginate(request, qs, settings.PACKS_PER_PAGE) tvars = {'user': user, 'order': order} tvars.update(paginator) return render(request, 'sounds/packs.html', tvars)
def front_page(request): rss_cache = cache.get("rss_cache_bw" if using_beastwhoosh(request) else "rss_cache", None) trending_sound_ids = cache.get("trending_sound_ids", None) popular_searches = cache.get("popular_searches", None) current_forum_threads = Thread.objects.filter(pk__in=get_current_thread_ids(), first_post__moderation_state="OK", last_post__moderation_state="OK") \ .order_by('-last_post__created') \ .select_related('author', 'forum', 'last_post', 'last_post__author', 'last_post__thread', 'last_post__thread__forum') latest_additions = Sound.objects.latest_additions(5 if not using_beastwhoosh(request) else 9, '2 days') random_sound_id = get_sound_of_the_day_id() if random_sound_id: random_sound = Sound.objects.bulk_query_id([random_sound_id])[0] else: random_sound = None top_donor = None if using_beastwhoosh(request): # TODO: simplify the calclation of the top donor using annotate in the query # TODO: add pertinent caching strategy here last_week = get_n_weeks_back_datetime(n_weeks=1) top_donor_data = defaultdict(int) for username, amount in \ Donation.objects.filter(created__gt=last_week)\ .exclude(user=None, is_anonymous=True)\ .values_list('user__username', 'amount'): top_donor_data[username] += amount if top_donor_data: top_donor_username = sorted(top_donor_data.items(), key=lambda x: x[1], reverse=True)[0][0] top_donor = User.objects.get(username=top_donor_username) tvars = { 'rss_cache': rss_cache, 'popular_searches': popular_searches, 'trending_sound_ids': trending_sound_ids, 'current_forum_threads': current_forum_threads, 'latest_additions': latest_additions, 'random_sound': random_sound, 'top_donor': top_donor, 'donation_amount_request_param': settings.DONATION_AMOUNT_REQUEST_PARAM, # Not needed for NG } return render(request, 'front.html', tvars)
def similar(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, moderation_state="OK", processing_state="OK", analysis_state="OK", similarity_state="OK") if sound.user.username.lower() != username.lower(): raise Http404 similarity_results, count = get_similar_sounds( sound, request.GET.get('preset', None), int(settings.SOUNDS_PER_PAGE)) logger.debug('Got similar_sounds for %s: %s' % (sound_id, similarity_results)) similar_sounds = Sound.objects.ordered_ids( [sound_id for sound_id, distance in similarity_results]) return render(request, 'sounds/similar.html', locals())
def delete(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id) if sound.user.username.lower() != username.lower(): raise Http404 if not (request.user.has_perm('sound.delete_sound') or sound.user == request.user): raise PermissionDenied error_message = None if request.method == "POST": form = DeleteSoundForm(request.POST, sound_id=sound_id) if not form.is_valid(): error_message = "Sorry, you waited too long, ... try again?" form = DeleteSoundForm(sound_id=sound_id) else: logger.debug("User %s requested to delete sound %s" % (request.user.username, sound_id)) try: ticket = sound.ticket tc = TicketComment(sender=request.user, text="User %s deleted the sound" % request.user, ticket=ticket, moderator_only=False) tc.save() except Ticket.DoesNotExist: # No ticket assigned, not adding any message (should not happen) pass sound.delete() return HttpResponseRedirect(reverse("accounts-home")) else: form = DeleteSoundForm(sound_id=sound_id) tvars = { 'error_message': error_message, 'delete_form': form, 'sound': sound } return render(request, 'sounds/delete.html', tvars)
def oembed(request): url = request.GET.get('url', '') view, args, kwargs = resolve(urlparse(url)[2]) if not 'sound_id' in kwargs: raise Http404 sound_id = kwargs['sound_id'] sound = get_object_or_404(Sound, id=sound_id, moderation_state='OK', processing_state='OK') player_size = request.GET.get('size', 'medium') if player_size == 'large': sizes = settings.IFRAME_PLAYER_SIZE['large'] if player_size == 'medium': sizes = settings.IFRAME_PLAYER_SIZE['medium'] if player_size == 'small': sizes = settings.IFRAME_PLAYER_SIZE['small'] tvars = { 'sound': sound, 'sizes': sizes, 'player_size': player_size, } return render(request, 'sounds/sound_oembed.xml', tvars, content_type='text/xml')
def flag(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, moderation_state="OK", processing_state="OK") if sound.user.username.lower() != username.lower(): raise Http404 user = None if request.user.is_authenticated: user = request.user if request.method == "POST": flag_form = FlagForm(request.POST) if flag_form.is_valid(): flag = flag_form.save() flag.reporting_user = user flag.sound = sound flag.save() if user: user_email = user.profile.get_email_for_delivery() else: user_email = flag_form.cleaned_data["email"] send_mail_template_to_support( u"Sound flag: %s - %s" % (sound.user.username, sound.original_filename), "sounds/email_flag.txt", {"flag": flag}, reply_to=user_email) return redirect(sound) else: initial = {} if user: initial["email"] = user.email flag_form = FlagForm(initial=initial) tvars = {"sound": sound, "flag_form": flag_form} return render(request, 'sounds/sound_flag.html', tvars)
def flag(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, moderation_state="OK", processing_state="OK") if sound.user.username.lower() != username.lower(): raise Http404 user = None if request.user.is_authenticated: user = request.user if request.method == "POST": flag_form = FlagForm(request.POST) if flag_form.is_valid(): flag = flag_form.save() flag.reporting_user = user flag.sound = sound flag.save() if user: user_email = user.email else: user_email = flag_form.cleaned_data["email"] from_email = settings.DEFAULT_FROM_EMAIL send_mail_template(u"[flag] flagged file", "sounds/email_flag.txt", {"flag": flag}, from_email, reply_to=user_email) return redirect(sound) else: initial = {} if user: initial["email"] = user.email flag_form = FlagForm(initial=initial) tvars = {"sound": sound, "flag_form": flag_form} return render(request, 'sounds/sound_flag.html', tvars)
def sound_edit_sources(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id) 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 current_sources = Sound.objects.ordered_ids( [element['id'] for element in sound.sources.all().values('id')]) sources_string = ",".join( map(str, [source.id for source in current_sources])) if request.method == 'POST': form = RemixForm(sound, request.POST) if form.is_valid(): form.save() else: form = RemixForm(sound, initial=dict(sources=sources_string)) tvars = {'sound': sound, 'form': form, 'current_sources': current_sources} return render(request, 'sounds/sound_edit_sources.html', tvars)
def display_sound_wrapper(request, username, sound_id): sound_obj = get_object_or_404(Sound, id=sound_id, user__username__iexact=username) # The following code is duplicated in sounds.tempaltetags.display_sound. This could be optimized. is_explicit = False if sound_obj is not None: is_explicit = sound_obj.is_explicit and \ (not request.user.is_authenticated or \ not request.user.profile.is_adult) tvars = { 'sound_id': sound_id, 'sound': sound_obj, 'sound_tags': sound_obj.get_sound_tags(12), 'sound_user': sound_obj.user.username, 'license_name': sound_obj.license.name, 'media_url': settings.MEDIA_URL, 'request': request, 'is_explicit': is_explicit } return render(request, 'sounds/display_sound.html', tvars)
def delete(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id) if sound.user.username.lower() != username.lower(): raise Http404 if not (request.user.has_perm('sound.delete_sound') or sound.user == request.user): raise PermissionDenied error_message = None if request.method == "POST" : form = DeleteSoundForm(request.POST, sound_id=sound_id) if not form.is_valid(): error_message = "Sorry, you waited too long, ... try again?" form = DeleteSoundForm(sound_id=sound_id) else: logger.info("User %s requested to delete sound %s" % (request.user.username,sound_id)) try: ticket = sound.ticket tc = TicketComment(sender=request.user, text="User %s deleted the sound" % request.user, ticket=ticket, moderator_only=False) tc.save() except Ticket.DoesNotExist: # No ticket assigned, not adding any message (should not happen) pass sound.delete() return HttpResponseRedirect(reverse("accounts-home")) else: form = DeleteSoundForm(sound_id=sound_id) tvars = { 'error_message': error_message, 'delete_form': form, 'sound': sound } return render(request, 'sounds/delete.html', tvars)
def embed_iframe(request, sound_id, player_size): """ This view returns an HTML player of `sound_id` which can be embeded in external sites. The player can take different "sizes" including: - 'mini': shows just a play button and a loop button. No background image. Eg: /embed/sound/iframe/1234/simple/mini/. - 'small': shows a play button, a loop button and the name of the user and sound. No background image. Eg: /embed/sound/iframe/1234/simple/small/. - 'medium': shows the waveform image with playing controls plus the sound name, username, license and some tags. Eg: /embed/sound/iframe/1234/simple/medium/. - 'medium_no_info': shows the waveform and with playing controls. Eg: /embed/sound/iframe/1234/simple/medium_no_info/. - 'large': shows the waveform image in large size with playing controls plus the sound name, username and license. Eg: /embed/sound/iframe/1234/simple/large/. - 'large_no_info': shows the waveform image in large size with playing controls. Eg: /embed/sound/iframe/1234/simple/large_no_info/. - 'full_size': like 'large' but taking the full width (used in twitter embeds). Eg: /embed/sound/iframe/1234/simple/full_size/. The sizes 'medium', 'medium_no_info', 'large', 'large_no_info' and 'full_size' can optionally show the spectrogram image instead of the waveform if being passed a request parameter 'spec=1' in the URL. Eg: /embed/sound/iframe/1234/simple/large/?spec=1. The sizes 'medium' and 'medium_no_info' can optionally show a button to toggle the background image between the waveform and the spectrogram by passing the request parameter 'td=1'. Bigger sizes always show that button. """ if player_size not in ['mini', 'small', 'medium', 'large', 'large_no_info', 'medium_no_info', 'full_size']: raise Http404 sound = get_object_or_404(Sound, id=sound_id, moderation_state='OK', processing_state='OK') tvars = { 'sound': sound, 'username_and_filename': '%s - %s' % (sound.user.username, sound.original_filename), 'size': player_size, 'use_spectrogram': request.GET.get('spec', None) == '1', 'show_toggle_display_button': request.GET.get('td', None) == '1', } return render(request, 'sounds/sound_iframe.html', tvars)
def sound_edit_sources(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id) if sound.user.username.lower() != username.lower(): raise Http404 if not (request.user.is_superuser or sound.user == request.user): raise PermissionDenied current_sources = Sound.objects.ordered_ids([element['id'] for element in sound.sources.all().values('id')]) sources_string = ",".join(map(str, [source.id for source in current_sources])) if request.method == 'POST': form = RemixForm(sound, request.POST) if form.is_valid(): form.save() sound.invalidate_template_caches() else: form = RemixForm(sound, initial=dict(sources=sources_string)) tvars = { 'sound': sound, 'form': form, 'current_sources': current_sources } return render(request, 'sounds/sound_edit_sources.html', tvars)
def display_sound_wrapper(request, username, sound_id): sound_obj = get_object_or_404(Sound, id=sound_id) if sound_obj.user.username.lower() != username.lower(): raise Http404 # The following code is duplicated in sounds.tempaltetags.display_sound. This could be optimized. is_explicit = False if sound_obj is not None: is_explicit = sound_obj.is_explicit and \ (not request.user.is_authenticated or \ not request.user.profile.is_adult) tvars = { 'sound_id': sound_id, 'sound': sound_obj, 'sound_tags': sound_obj.get_sound_tags(12), 'sound_user': sound_obj.user.username, 'license_name': sound_obj.license.name, 'media_url': settings.MEDIA_URL, 'request': request, 'is_explicit': is_explicit, 'is_authenticated': request.user.is_authenticated() # cache computation is weird with CallableBool } return render(request, 'sounds/display_sound.html', tvars)
def sounds(request): latest_sounds = Sound.objects.latest_additions(5, '2 days') latest_sound_objects = Sound.objects.ordered_ids([latest_sound['sound_id'] for latest_sound in latest_sounds]) latest_sounds = [(latest_sound, latest_sound_objects[index],) for index, latest_sound in enumerate(latest_sounds)] latest_packs = Pack.objects.select_related().filter(num_sounds__gt=0).exclude(is_deleted=True).order_by("-last_updated")[0:20] last_week = get_n_weeks_back_datetime(n_weeks=1) popular_sound_ids = [snd.id for snd in Sound.objects.filter( Q(moderation_date__gte=last_week) | Q(created__gte=last_week)).order_by("-num_downloads")[0:5]] popular_sounds = Sound.objects.ordered_ids(popular_sound_ids) popular_packs = Pack.objects.filter(created__gte=last_week).exclude(is_deleted=True).order_by("-num_downloads")[0:5] random_sound_id = get_sound_of_the_day_id() if random_sound_id: random_sound = Sound.objects.bulk_query_id([random_sound_id])[0] else: random_sound = None tvars = { 'latest_sounds': latest_sounds, 'latest_packs': latest_packs, 'popular_sounds': popular_sounds, 'popular_packs': popular_packs, 'random_sound': random_sound } return render(request, 'sounds/sounds.html', tvars)
def display_sound_wrapper(request, username, sound_id): sound_obj = get_object_or_404(Sound, id=sound_id) if sound_obj.user.username.lower() != username.lower(): raise Http404 # The following code is duplicated in sounds.tempaltetags.display_sound. This could be optimized. is_explicit = False if sound_obj is not None: is_explicit = sound_obj.is_explicit and \ (not request.user.is_authenticated or \ not request.user.profile.is_adult) tvars = { 'sound_id': sound_id, 'sound': sound_obj, 'sound_tags': sound_obj.get_sound_tags(12), 'sound_user': sound_obj.user.username, 'license_name': sound_obj.license.name, 'media_url': settings.MEDIA_URL, 'request': request, 'is_explicit': is_explicit, 'is_authenticated': request.user.is_authenticated( ) # cache computation is weird with CallableBool } return render(request, 'sounds/display_sound.html', tvars)
def flag(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, moderation_state="OK", processing_state="OK") if sound.user.username.lower() != username.lower(): raise Http404 user = None if request.user.is_authenticated: user = request.user if request.method == "POST": flag_form = FlagForm(request.POST) if flag_form.is_valid(): flag = flag_form.save() flag.reporting_user = user flag.sound = sound flag.save() if user: user_email = user.profile.get_email_for_delivery() else: user_email = flag_form.cleaned_data["email"] send_mail_template_to_support(u"Sound flag: %s - %s" % (sound.user.username, sound.original_filename), "sounds/email_flag.txt", {"flag": flag}, reply_to=user_email) return redirect(sound) else: initial = {} if user: initial["email"] = user.email flag_form = FlagForm(initial=initial) tvars = {"sound": sound, "flag_form": flag_form} return render(request, 'sounds/sound_flag.html', tvars)
def remixed(request): qs = RemixGroup.objects.all().order_by('-group_size') tvars = dict() tvars.update(paginate(request, qs, settings.SOUND_COMMENTS_PER_PAGE)) return render(request, 'sounds/remixed.html', tvars)
def front_page(request): rss_cache = cache.get( "rss_cache_bw" if using_beastwhoosh(request) else "rss_cache", None) trending_sound_ids = cache.get("trending_sound_ids", None) trending_pack_ids = cache.get("trending_pack_ids", None) total_num_sounds = cache.get("total_num_sounds", 0) popular_searches = cache.get("popular_searches", None) if popular_searches is not None: popular_searches = [(query_terms, '{0}?q={1}'.format(reverse('sounds-search'), query_terms)) for query_terms in popular_searches] current_forum_threads = Thread.objects.filter(first_post__moderation_state="OK", last_post__moderation_state="OK") \ .order_by('-last_post__created') \ .select_related('author', 'forum', 'last_post', 'last_post__author', 'last_post__thread', 'last_post__thread__forum')[:10] num_latest_sounds = 5 if not using_beastwhoosh(request) else 9 latest_sounds = Sound.objects.latest_additions( num_sounds=num_latest_sounds, period_days=2) random_sound_id = get_sound_of_the_day_id() if random_sound_id: random_sound = Sound.objects.bulk_query_id([random_sound_id])[0] else: random_sound = None top_donor = None if using_beastwhoosh(request): # TODO: simplify the calculation of the top donor using annotate in the query # TODO: add pertinent caching strategy here last_week = get_n_weeks_back_datetime(n_weeks=1) top_donor_data = defaultdict(int) for username, amount in \ Donation.objects.filter(created__gt=last_week)\ .exclude(user=None, is_anonymous=True)\ .values_list('user__username', 'amount'): top_donor_data[username] += amount if top_donor_data: top_donor_username = sorted(top_donor_data.items(), key=lambda x: x[1], reverse=True)[0][0] top_donor = User.objects.get(username=top_donor_username) tvars = { 'rss_cache': rss_cache, 'popular_searches': popular_searches, 'trending_sound_ids': trending_sound_ids, 'trending_pack_ids': trending_pack_ids, 'current_forum_threads': current_forum_threads, 'latest_sounds': latest_sounds, 'random_sound': random_sound, 'top_donor': top_donor, 'total_num_sounds': total_num_sounds, 'donation_amount_request_param': settings.DONATION_AMOUNT_REQUEST_PARAM, 'enable_query_suggestions': settings.ENABLE_QUERY_SUGGESTIONS, # Used for beash whoosh only } return render(request, 'front.html', tvars)
def sound(request, username, sound_id): try: sound = Sound.objects.prefetch_related("tags__tag")\ .select_related("license", "user", "user__profile", "pack")\ .get(id=sound_id, user__username=username) user_is_owner = request.user.is_authenticated and \ (sound.user == request.user or request.user.is_superuser or request.user.is_staff or Group.objects.get(name='moderators') in request.user.groups.all()) # If the user is authenticated and this file is his, don't worry about moderation_state and processing_state if user_is_owner: if sound.moderation_state != "OK": messages.add_message( request, messages.INFO, 'Be advised, this file has <b>not been moderated</b> yet.') if sound.processing_state != "OK": messages.add_message( request, messages.INFO, 'Be advised, this file has <b>not been processed</b> yet.') else: if sound.moderation_state != 'OK' or sound.processing_state != 'OK': raise Http404 except Sound.DoesNotExist: if DeletedSound.objects.filter(sound_id=sound_id).exists(): return render(request, 'sounds/deleted_sound.html') else: raise Http404 if request.method == "POST": form = CommentForm(request, request.POST) if request.user.is_authenticated: if request.user.profile.is_blocked_for_spam_reports(): messages.add_message( request, messages.INFO, "You're not allowed to post the comment because your " "account has been temporaly blocked after multiple spam " "reports") else: if form.is_valid(): comment_text = form.cleaned_data["comment"] sound.add_comment(request.user, comment_text) sound.invalidate_template_caches() send_mail_template( u'You have a new comment.', 'sounds/email_new_comment.txt', { 'sound': sound, 'user': request.user, 'comment': comment_text }, user_to=sound.user, email_type_preference_check="new_comment") return HttpResponseRedirect(sound.get_absolute_url()) else: form = CommentForm(request) qs = Comment.objects.select_related("user", "user__profile")\ .filter(sound_id=sound_id) display_random_link = request.GET.get('random_browsing', False) is_following = False if request.user.is_authenticated: users_following = follow_utils.get_users_following(request.user) if sound.user in users_following: is_following = True is_explicit = sound.is_explicit and (not request.user.is_authenticated or not request.user.profile.is_adult) tvars = { 'sound': sound, 'username': username, 'form': form, 'display_random_link': display_random_link, 'is_following': is_following, 'is_explicit': is_explicit, # if the sound should be shown blurred, already checks for adult profile 'sizes': settings.IFRAME_PLAYER_SIZE, } tvars.update(paginate(request, qs, settings.SOUND_COMMENTS_PER_PAGE)) return render(request, 'sounds/sound.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(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 sound(request, username, sound_id): try: sound = Sound.objects.select_related("license", "user", "user__profile", "pack").get(id=sound_id) if sound.user.username.lower() != username.lower(): raise Http404 user_is_owner = request.user.is_authenticated and \ (sound.user == request.user or request.user.is_superuser or request.user.is_staff or Group.objects.get(name='moderators') in request.user.groups.all()) # If the user is authenticated and this file is his, don't worry about moderation_state and processing_state if user_is_owner: if sound.moderation_state != "OK": messages.add_message( request, messages.INFO, 'Be advised, this file has <b>not been moderated</b> yet.') if sound.processing_state != "OK": messages.add_message( request, messages.INFO, 'Be advised, this file has <b>not been processed</b> yet.') else: if sound.moderation_state != 'OK' or sound.processing_state != 'OK': raise Http404 except Sound.DoesNotExist: if DeletedSound.objects.filter(sound_id=sound_id).exists(): return render(request, 'sounds/deleted_sound.html') else: raise Http404 if request.method == "POST": form = CommentForm(request, request.POST) if request.user.is_authenticated: if request.user.profile.is_blocked_for_spam_reports(): messages.add_message( request, messages.INFO, "You're not allowed to post the comment because your account " "has been temporaly blocked after multiple spam reports") else: if form.is_valid(): comment_text = form.cleaned_data["comment"] sound.add_comment(request.user, comment_text) try: if request.user.profile.email_not_disabled( "new_comment"): # Send the user an email to notify him of the new comment! logger.debug( "Notifying user %s of a new comment by %s" % (sound.user.username, request.user.username)) send_mail_template( u'You have a new comment.', 'sounds/email_new_comment.txt', { 'sound': sound, 'user': request.user, 'comment': comment_text }, None, sound.user.email) except Exception as e: # If the email sending fails, ignore... logger.error( "Problem sending email to '%s' about new comment: %s" % (request.user.email, e)) return HttpResponseRedirect(sound.get_absolute_url()) else: form = CommentForm(request) qs = Comment.objects.select_related("user", "user__profile")\ .filter(sound_id=sound_id) display_random_link = request.GET.get('random_browsing') is_following = False if request.user.is_authenticated: users_following = follow_utils.get_users_following(request.user) if sound.user in users_following: is_following = True is_explicit = sound.is_explicit and (not request.user.is_authenticated \ or not request.user.profile.is_adult) tvars = { 'sound': sound, 'username': username, 'form': form, 'display_random_link': display_random_link, 'is_following': is_following, 'is_explicit': is_explicit, 'sizes': settings.IFRAME_PLAYER_SIZE, } tvars.update(paginate(request, qs, settings.SOUND_COMMENTS_PER_PAGE)) return render(request, 'sounds/sound.html', tvars)
def remixed(request): qs = RemixGroup.objects.all().order_by('-group_size') tvars = dict() tvars.update(paginate(request, qs, settings.SOUND_COMMENTS_PER_PAGE)) return render(request, 'sounds/remixed.html', tvars)
def sound_edit_download(request, username, sound_id): sound = Sound.objects.prefetch_related("tags__tag") \ .select_related("license", "user", "user__profile", "pack") \ .get(id=sound_id, user__username=username) tvars = {'sound': sound, 'username': username, 'sound_id': sound_id} return render(request, 'sounds/editor.html', tvars)
def search_forum(request): search_query = request.GET.get("q", "") filter_query = request.GET.get("f", "") try: current_page = int(request.GET.get("page", 1)) except ValueError: current_page = 1 current_forum_name_slug = request.GET.get( "forum", "").strip() # for context sensitive search if current_forum_name_slug: current_forum = get_object_or_404(forum.models.Forum.objects, name_slug=current_forum_name_slug) else: current_forum = None sort = ["thread_created desc"] # Parse advanced search options advanced_search = request.GET.get("advanced_search", "") date_from = request.GET.get("dt_from", "") try: df_parsed = datetime.datetime.strptime(date_from, "%Y-%m-%d") date_from_display = df_parsed.strftime("%d-%m-%Y") except ValueError: date_from = "" date_from_display = "Choose a Date" date_to = request.GET.get("dt_to", "") try: dt_parsed = datetime.datetime.strptime(date_to, "%Y-%m-%d") date_to_display = dt_parsed.strftime("%d-%m-%Y") except ValueError: date_to = "" date_to_display = "Choose a Date" if search_query.startswith("search in"): search_query = "" error = False error_text = "" paginator = None num_results = None page = None results = [] if search_query.strip() != "" or filter_query: # add current forum if current_forum: filter_query += "forum_name_slug:" + current_forum.name_slug # add date range if advanced_search == "1" and date_from != "" or date_to != "": filter_query = __add_date_range(filter_query, date_from, date_to) query = SolrQuery() query.set_dismax_query(search_query, query_fields=[("thread_title", 4), ("post_body", 3), ("thread_author", 3), ("post_author", 3), ("forum_name", 2)]) query.set_highlighting_options_default( field_list=["post_body"], fragment_size=200, alternate_field="post_body", # TODO: revise this param require_field_match=False, pre="<strong>", post="</strong>") query.set_query_options( start=(current_page - 1) * settings.SOUNDS_PER_PAGE, rows=settings.SOUNDS_PER_PAGE, field_list=[ "id", "forum_name", "forum_name_slug", "thread_id", "thread_title", "thread_author", "thread_created", "post_body", "post_author", "post_created", "num_posts" ], filter_query=filter_query, sort=sort) query.set_group_field("thread_title_grouped") query.set_group_options(group_limit=30) solr = Solr(settings.SOLR_FORUM_URL) try: results = SolrResponseInterpreter(solr.select(unicode(query))) paginator = SolrResponseInterpreterPaginator( results, settings.SOUNDS_PER_PAGE) num_results = paginator.count page = paginator.page(current_page) error = False except SolrException as e: search_logger.warning("search error: query: %s error %s" % (query, e)) error = True error_text = 'There was an error while searching, is your query correct?' except Exception as e: search_logger.error("Could probably not connect to Solr - %s" % e) error = True error_text = 'The search server could not be reached, please try again later.' tvars = { 'advanced_search': advanced_search, 'current_forum': current_forum, 'current_page': current_page, 'date_from': date_from, 'date_from_display': date_from_display, 'date_to': date_to, 'date_to_display': date_to_display, 'error': error, 'error_text': error_text, 'filter_query': filter_query, 'num_results': num_results, 'page': page, 'paginator': paginator, 'search_query': search_query, 'sort': sort, 'results': results, } return render(request, 'search/search_forum.html', tvars)
def search(request): search_query = request.GET.get("q", "") filter_query = request.GET.get("f", "") filter_query_link_more_when_grouping_packs = filter_query.replace(' ', '+') # Generate array with information of filters filter_query_split = [] if filter_query != "": for filter_str in re.findall(r'[\w-]+:\"[^\"]+', filter_query): valid_filter = True filter_str = filter_str + '"' filter_display = filter_str.replace('"', '') filter_name = filter_str.split(":")[0] if filter_name != "duration" and filter_name != "is_geotagged": if filter_name == "grouping_pack": val = filter_display.split(":")[1] # If pack does not contain "_" then it's not a valid pack filter if "_" in val: filter_display = "pack:" + val.split("_")[1] else: valid_filter = False if valid_filter: filter = { 'name': filter_display, 'remove_url': filter_query.replace(filter_str, ''), } filter_query_split.append(filter) try: current_page = int(request.GET.get("page", 1)) except ValueError: current_page = 1 sort = request.GET.get("s", None) sort_options = forms.SEARCH_SORT_OPTIONS_WEB grouping = request.GET.get("g", "1") # Group by default # If the query is filtered by pack, do not collapse sounds of the same pack (makes no sense) # If the query is through AJAX (for sources remix editing), do not collapse if "pack" in filter_query or request.GET.get("ajax", "") == "1": grouping = "" # Set default values id_weight = settings.DEFAULT_SEARCH_WEIGHTS['id'] tag_weight = settings.DEFAULT_SEARCH_WEIGHTS['tag'] description_weight = settings.DEFAULT_SEARCH_WEIGHTS['description'] username_weight = settings.DEFAULT_SEARCH_WEIGHTS['username'] pack_tokenized_weight = settings.DEFAULT_SEARCH_WEIGHTS['pack_tokenized'] original_filename_weight = settings.DEFAULT_SEARCH_WEIGHTS[ 'original_filename'] # Parse advanced search options advanced = request.GET.get("advanced", "") advanced_search_params_dict = {} # if advanced search if advanced == "1": a_tag = request.GET.get("a_tag", "") a_filename = request.GET.get("a_filename", "") a_description = request.GET.get("a_description", "") a_packname = request.GET.get("a_packname", "") a_soundid = request.GET.get("a_soundid", "") a_username = request.GET.get("a_username", "") advanced_search_params_dict.update({ # These are stored in a dict to facilitate logging and passing to template 'a_tag': a_tag, 'a_filename': a_filename, 'a_description': a_description, 'a_packname': a_packname, 'a_soundid': a_soundid, 'a_username': a_username, }) # If none is selected use all (so other filter can be appleid) if a_tag or a_filename or a_description or a_packname or a_soundid or a_username != "": # Initialize all weights to 0 id_weight = 0 tag_weight = 0 description_weight = 0 username_weight = 0 pack_tokenized_weight = 0 original_filename_weight = 0 # Set the weights of selected checkboxes if a_soundid != "": id_weight = settings.DEFAULT_SEARCH_WEIGHTS['id'] if a_tag != "": tag_weight = settings.DEFAULT_SEARCH_WEIGHTS['tag'] if a_description != "": description_weight = settings.DEFAULT_SEARCH_WEIGHTS[ 'description'] if a_username != "": username_weight = settings.DEFAULT_SEARCH_WEIGHTS['username'] if a_packname != "": pack_tokenized_weight = settings.DEFAULT_SEARCH_WEIGHTS[ 'pack_tokenized'] if a_filename != "": original_filename_weight = settings.DEFAULT_SEARCH_WEIGHTS[ 'original_filename'] sort = search_prepare_sort(sort, forms.SEARCH_SORT_OPTIONS_WEB) search_logger.info(u'Search (%s)' % json.dumps({ 'ip': get_client_ip(request), 'query': search_query, 'filter': filter_query, 'username': request.user.username, 'page': current_page, 'sort': sort[0], 'group_by_pack': grouping, 'advanced': json.dumps(advanced_search_params_dict) if advanced == "1" else "" })) query = search_prepare_query(search_query, filter_query, sort, current_page, settings.SOUNDS_PER_PAGE, id_weight, tag_weight, description_weight, username_weight, pack_tokenized_weight, original_filename_weight, grouping=grouping) tvars = { 'error_text': None, 'filter_query': filter_query, 'filter_query_split': filter_query_split, 'search_query': search_query, 'grouping': grouping, 'advanced': advanced, 'sort': sort, 'sort_options': sort_options, 'filter_query_link_more_when_grouping_packs': filter_query_link_more_when_grouping_packs, 'current_page': current_page, } if advanced == "1": tvars.update(advanced_search_params_dict) try: non_grouped_number_of_results, facets, paginator, page, docs = perform_solr_query( query, current_page) resultids = [d.get("id") for d in docs] resultsounds = sounds.models.Sound.objects.bulk_query_id(resultids) allsounds = {} for s in resultsounds: allsounds[s.id] = s # allsounds will contain info from all the sounds returned by bulk_query_id. This should # be all sounds in docs, but if solr and db are not synchronised, it might happen that there # are ids in docs which are not found in bulk_query_id. To avoid problems we remove elements # in docs that have not been loaded in allsounds. docs = [doc for doc in docs if doc["id"] in allsounds] for d in docs: d["sound"] = allsounds[d["id"]] tvars.update({ 'paginator': paginator, 'page': page, 'docs': docs, 'facets': facets, 'non_grouped_number_of_results': non_grouped_number_of_results, }) except SolrException as e: search_logger.warning('Search error: query: %s error %s' % (query, e)) tvars.update({ 'error_text': 'There was an error while searching, is your query correct?' }) except Exception as e: search_logger.error('Could probably not connect to Solr - %s' % e) tvars.update({ 'error_text': 'The search server could not be reached, please try again later.' }) if request.GET.get("ajax", "") != "1": return render(request, 'search/search.html', tvars) else: return render(request, 'search/search_ajax.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.is_superuser 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 geotag(request, username, sound_id): sound = get_object_or_404(Sound, id=sound_id, moderation_state="OK", processing_state="OK") if sound.user.username.lower() != username.lower(): raise Http404 tvars = {'sound': sound} return render(request, 'sounds/geotag.html', tvars)
def sound(request, username, sound_id): try: sound = Sound.objects.select_related("license", "user", "user__profile", "pack").get(id=sound_id, user__username=username) user_is_owner = request.user.is_authenticated and \ (sound.user == request.user or request.user.is_superuser or request.user.is_staff or Group.objects.get(name='moderators') in request.user.groups.all()) # If the user is authenticated and this file is his, don't worry about moderation_state and processing_state if user_is_owner: if sound.moderation_state != "OK": messages.add_message(request, messages.INFO, 'Be advised, this file has <b>not been moderated</b> yet.') if sound.processing_state != "OK": messages.add_message(request, messages.INFO, 'Be advised, this file has <b>not been processed</b> yet.') else: if sound.moderation_state != 'OK' or sound.processing_state != 'OK': raise Http404 except Sound.DoesNotExist: if DeletedSound.objects.filter(sound_id=sound_id).exists(): return render(request, 'sounds/deleted_sound.html') else: raise Http404 if request.method == "POST": form = CommentForm(request, request.POST) if request.user.is_authenticated: if request.user.profile.is_blocked_for_spam_reports(): messages.add_message(request, messages.INFO, "You're not allowed to post the comment because your account " "has been temporaly blocked after multiple spam reports") else: if form.is_valid(): comment_text = form.cleaned_data["comment"] sound.add_comment(request.user, comment_text) sound.invalidate_template_caches() try: if sound.user.profile.email_not_disabled("new_comment"): # Send the user an email to notify him of the new comment! logger.info("Notifying user %s of a new comment by %s" % (sound.user.username, request.user.username)) send_mail_template(u'You have a new comment.', 'sounds/email_new_comment.txt', {'sound': sound, 'user': request.user, 'comment': comment_text}, user_to=sound.user) except Exception as e: # If the email sending fails, ignore... logger.error("Problem sending email to '%s' about new comment: %s" % (request.user.username, e)) return HttpResponseRedirect(sound.get_absolute_url()) else: form = CommentForm(request) qs = Comment.objects.select_related("user", "user__profile")\ .filter(sound_id=sound_id) display_random_link = request.GET.get('random_browsing', False) is_following = False if request.user.is_authenticated: users_following = follow_utils.get_users_following(request.user) if sound.user in users_following: is_following = True is_explicit = sound.is_explicit and (not request.user.is_authenticated or not request.user.profile.is_adult) tvars = { 'sound': sound, 'username': username, 'form': form, 'display_random_link': display_random_link, 'is_following': is_following, 'is_explicit': is_explicit, # if the sound should be shown blurred, already checks for adult profile 'sizes': settings.IFRAME_PLAYER_SIZE, } tvars.update(paginate(request, qs, settings.SOUND_COMMENTS_PER_PAGE)) return render(request, 'sounds/sound.html', tvars)