Allow users to play mp3 files but dont expose them directly on the web

I want to store some mp3s in a folder wich is no public, cant be directly accessed trough the web and allow users to hear/download the songs with a browser only if they are logged in.

How can I do that ?

I do my web development with django, but If I know how it works is enough.

Answers


I assume you use django. Then you can try something like this:

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse


@login_required
def listen(request, file_name):
    # note that MP3_STORAGE should not be in MEDIA_ROOT
    file = open("%smp3/%s" % (settings.MP3_STORAGE, file_name))
    response = HttpResponse(file.read(), mimetype="audio/mpeg")
    return response

Note that you will get dramatic speed decrease. Using generator to read file in blocks may help to save memory.

Lazy Method for Reading Big File in Python?


You first need to setup authentication. The django tutorials thoroughly explore this.

You don't' link the mp3's directly, You link to a django script that checks the auth, then reads the mp3 and serves it to the client with a mp3 content type header.

http://yourserver.com/listen?file=Fat+Boys+Greatest+Hits


  • File outside of public access (not in MEDIA_URL folders)
  • Check if user logged in
  • Serve files only via a view, with unique links for every user

Pseudocode:

class Mp3(models.Model):
    file = models.FileField(upload_to=path_outside_of_public_access)
    hash = models.CharField(unique=True)


def generate_link_hash(request, file):
    return hashlib.md5("%s_%i_%s_%s" % (request.session.session_key, file.id, str(file.date_added), file.hash)) # or however u like


def files_list(request)
    """ view to show files list """
    for file in files:
        file.link_hash = generate_link_hash(request, file)


@login_required
def download_file(request, file_hash, link_hash):
    """ view to download file """
    file = Mp3.objects.get(hash=file_hash)
    if link_hash == generate_link_hash(request, file):
        file = open(file.file)
        return HttpResponse(file.read(), mimetype="audio/mpeg")
    else:
        raise Http404

Should do the job enough, but remember - what is once accessed, you have no control where it goes from now on. And that every file download needs reading the file through the app (it's not given statically), which will affect the performance of your app.


Need Your Help

click event on list view in fragments

android xml android-layout listview android-fragments

I have a list view in fragment and I want to sense the click on list view , so that I can change my layout but my code isn't working.

MouseDrag Triangle Logic

c# winforms graphics

I'm trying to create a triangle with a simple mousedown, drag, and mouseup. I have a sketch of the logic, that I drew with lines, for further clarification and some snippet that I've been trying bu...