def sound_download(request, username, sound_id): if not request.user.is_authenticated(): return HttpResponseRedirect('%s?next=%s' % (reverse("accounts-login"), reverse("sound", args=[username, sound_id]))) sound = get_object_or_404(Sound, user__username__iexact=username, id=sound_id, moderation_state="OK", processing_state="OK") Download.objects.get_or_create(user=request.user, sound=sound) return sendfile(sound.locations("path"), sound.friendly_filename(), sound.locations("sendfile_url"))
def sound_download(request, username, sound_id): if not request.user.is_authenticated: return HttpResponseRedirect( '%s?next=%s' % (reverse("accounts-login"), reverse("sound", args=[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 sentry_logger.info('Download sound', exc_info=True, extra={ 'request': request, 'sound_id': sound_id, }) if not Download.objects.filter(user=request.user, sound=sound).exists(): Download.objects.create(user=request.user, sound=sound, license=sound.license) return sendfile(sound.locations("path"), sound.friendly_filename(), sound.locations("sendfile_url"))
def sound_download(request, username, sound_id): if not request.user.is_authenticated: return HttpResponseRedirect( '%s?next=%s' % (reverse("accounts-login"), reverse("sound", args=[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 if 'HTTP_RANGE' not in request.META: ''' Download managers and some browsers use the range header to download files in multiple parts. We have observed that all clients first make a GET with no range header (to get the file length) and then make multiple other requests. We ignore all requests that have range header because we assume that a first query has already been made. We additionally guard against users clicking on download multiple times by storing a sentinel in the cache for 5 minutes. ''' cache_key = 'sdwn_%s_%d' % (sound_id, request.user.id) if cache.get(cache_key, None) is None: Download.objects.create(user=request.user, sound=sound, license=sound.license) sound.invalidate_template_caches() cache.set( cache_key, True, 60 * 5) # Don't save downloads for the same user/sound in 5 minutes return sendfile(sound.locations("path"), sound.friendly_filename(), sound.locations("sendfile_url"))
def read(self, request, pack_id): try: pack = Pack.objects.get(id=pack_id) except Pack.DoesNotExist: raise ReturnError(404, "NotFound", {"explanation": "Pack with id %s does not exist." % pack_id}) logger.info("Serving pack,id=" + pack_id + ",api_key=" + request.GET.get("api_key", False) + ",api_key_username="******"path"), pack.friendly_filename(), pack.locations("sendfile_url"))
def sound_download(request, username, sound_id): if not request.user.is_authenticated(): return HttpResponseRedirect('%s?next=%s' % (reverse("accounts-login"), reverse("sound", args=[username, sound_id]))) if settings.LOG_CLICKTHROUGH_DATA: click_log(request,click_type='sounddownload',sound_id=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 Download.objects.get_or_create(user=request.user, sound=sound) return sendfile(sound.locations("path"), sound.friendly_filename(), sound.locations("sendfile_url"))
def read(self, request, sound_id, filename): ip = get_client_ip(request) sound_id = int(sound_id) id_folder = str(sound_id/1000) path = os.path.join(settings.PREVIEWS_PATH, id_folder, filename) preview_url = os.path.join(settings.PREVIEWS_URL, id_folder, filename) try: response = sendfile(path, filename, preview_url) except Http404: raise ReturnError(404, "NotFound", {"explanation": "Requested preview for sound %i does not exist." % sound_id}) logger.info("Preview sound,id=" + str(sound_id) + ",api_key=" + request.GET.get("api_key", False) + ",api_key_username="******",ip=" + ip) return response
def read(self, request, sound_id): ip = get_client_ip(request) try: sound = Sound.objects.get(id=sound_id, moderation_state="OK", processing_state="OK") except Sound.DoesNotExist: #@UndefinedVariable raise ReturnError(404, "NotFound", {"explanation": "Sound with id %s does not exist." % sound_id}) # Check if file actually exists in the hard drive if not os.path.exists(sound.locations('path')) : raise ReturnError(404, "NotFound", {"explanation": "Sound with id %s is not available for download." % sound_id}) # DISABLED (FOR THE MOMENT WE DON'T UPDATE DOWNLOADS TABLE THROUGH API) #Download.objects.get_or_create(user=request.user, sound=sound, interface='A') logger.info("Serving sound,id=" + sound_id + ",api_key=" + request.GET.get("api_key", False) + ",api_key_username="******",ip=" + ip) return sendfile(sound.locations("path"), sound.friendly_filename(), sound.locations("sendfile_url"))
def sound_download(request, username, sound_id): if not request.user.is_authenticated: return HttpResponseRedirect('%s?next=%s' % (reverse("accounts-login"), reverse("sound", args=[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 if 'HTTP_RANGE' not in request.META: ''' Download managers and some browsers use the range header to download files in multiple parts. We have observed that all clients first make a GET with no range header (to get the file length) and then make multiple other requests. We ignore all requests that have range header because we assume that a first query has already been made. We additionally guard against users clicking on download multiple times by storing a sentinel in the cache for 5 minutes. ''' cache_key = 'sdwn_%s_%d' % (sound_id, request.user.id) if cache.get(cache_key, None) is None: Download.objects.create(user=request.user, sound=sound, license=sound.license) sound.invalidate_template_caches() cache.set(cache_key, True, 60 * 5) # Don't save downloads for the same user/sound in 5 minutes return sendfile(sound.locations("path"), sound.friendly_filename(), sound.locations("sendfile_url"))