I'd like to have a site that gives away and sells PDFs, and tracks downloads
of those PDFs. For example, I'd like to know the IP address/useragent of who
downloaded the free files, and I'd like to record the same plus the logged in
user for the pay ones (after authenticating the user is allowed to download
that file).
I've done this in Java by returning binary content (the PDF) from a servlet,
and having the servlet write to the database to say what was downloaded and
who downloaded it. I'd like to migrate this app to django (less
heavyweight!) can anyone point me towards a mechanism for doing this? I'm
fairly new at python but loving it...
Thanks,
Tim.
You could try something like that:
from django.http import HttpResponse
from testing.models import DownloadCounter
class MyFile(file):
def __init__(self, filename, *args, **kwargs):
self.filename = filename
super(MyFile, self).__init__(filename, *args, **kwargs)
def close(self):
super(MyFile, self).close()
cnt, created = DownloadCounter.objects.get_or_create(
filename=self.filename, defaults={'count':0})
cnt.count += 1
cnt.save()
def blah(request):
return HttpResponse(MyFile('views.py'),
mimetype='application/octet-stream')
(I am not running this code in production, and I don't know if I ever
will, but it was an interesting hack.)
This way, you can track file downloads when the download is completely
read from disk. If someone aborts a download, it wont be counted.
Am 05.04.2008 um 21:19 schrieb Tim Sawyer:
>
> I'd like to have a site that gives away and sells PDFs, and tracks
> downloads
> of those PDFs.
I hope I got your question right. I have a little bit different
aproach since django never serves the file directly.
If you are using nginx as a frontend-proxy and static file serving
just configure a protected-download-dir:
location /protected-downloads/ {
alias /var/protected/;
internal;
}
The "internal" is to disallow regular gets so your file is not
downloadable without the "OK" from your view.
Now you can send a X-Accel-Redirect Header from your view to let the
nginx send a file:
@login_required
def download(request, file=None):
response = HttpResponse()
response['Content-Type'] = 'application/octet-stream'
response['X-Accel-Redirect'] = '/protected-downloads/' + file
return response
Of course you can do additional processing in download as storing the
IP and download count to your database.
This soulution has the advantage that your files can be served very
quickly from your proxy instead of a relatively slow mod_python-apache.
If you are using Apache or lighttpd as a frontend-proxy you can use a
similar aproach with: X-Sendfile.
Or you use Amazon s3 etc...
Greets,
Thomas Kerpe
I'd like to do something along these lines as well – keep files in a
protected directory and only allow them to be served if Django says
so. I'm serving static media from a different domain name (but the
same physical server) from my django application, which is running on
apache/mod_wsgi. From what I can tell X-Sendfile is a lighttpd-only
thing; is that true, and is there some other option using Apache?
Thanks
Eric
Cheers everyone for your ideas, I'm going with the approach at the moment.
Thanks again,
Tim.
Am 06.04.2008 um 06:49 schrieb Eric Abrahamsen:
>
> Guess I'll have to serve the files from django's apache, not my other
> media server, but it seems like this will do it.
That depends on your setup.
You can also use a X-Sendfile or X-Accel-Redirect capable Server as
your frontend-Proxy. So your request goes this way:
1. Frontend-Proxy and static file server (i.e. Nginx od lighttpd)
if URL matches local file or rule: serve it
else: request file from Backend-Server (i.e. Apache)
2. Backend Server
handle urls as in urls.py or your resolving strategy and serve
dynamic Data accordingly.
In this way your Hostname is always the same. All Static files can be
served from your frontend-proxy with X-Accel-Redirect even private
data. You also can serve cached dynamic content directly from your
proxy without hitting the apache.
In larger setups the frontend-proxy also can handle the load-balancing
stuff.
//Thomas
Well that's about a foot and a half past my current server
configuration abilities, but I appreciate the direction, and I'll
start doing some reading! If you or anyone has any more resources you
can point me towards, I'd be grateful.
Thanks,
Eric