Login

FirstRun Middleware

Author:
TheMysteriousX
Posted:
May 7, 2011
Language:
Python
Version:
1.3
Score:
2 (after 4 ratings)

Simple piece of middleware that redirects all requests to settings.FIRSTRUN_APP_PATH, until a lockfile is created.

Tested on 1.3 only, but I do not believe it requires any special functionality beyond that provided in 1.1

This is useful if you need to force a user to run an installer, or do some configuration before your project can function fully.

At first glance, such a thing would generate a lot of hits on the disk. However, once the lockfile has been created, the middleware unloads itself, so when a project is in a production environment, the lockfile is only checked once per process invocation (with passenger or mod_wsgi, that's not very often at all).

Once your user has completed your FirstRun app, simply create the lockfile and the project will function as normal.

For it to function, the following settings must be configured:

  • settings.PROJECT_PATH - absolute path to project on disk (e.g. /var/www/project/)
  • settings.FIRSTRUN_LOCKFILE - relative path of the lockfile (e.g. /.lockfile)
  • settings.FIRSTRUN_APP_ROOT - relative URL of the App you want to FirstRun (eg./firstrun/)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.shortcuts import redirect

import django.core.exceptions

import logging
import re
import os

# Check for the existance of a lockfile.  If the lockfile doesn't exist, deny access to everywhere except settings.FIRSTRUN_APP_ROOT
# If the lockfile exists, throw django.core.exceptions.MiddlewareNotUsed() so that this class is unloaded

class FirstRunMiddleware:
    def __init__(self):
        if not self.is_first_run():
            logging.debug('FirstRunMiddleware: FirstRun not required, unloading for process lifetime.')
            raise django.core.exceptions.MiddlewareNotUsed()

        self.p = re.compile(''.join(['^', settings.FIRSTRUN_APP_ROOT]))

    def process_request(self, request):
        if self.p.match(request.path) == None:
            if self.is_first_run():
                logging.debug(''.join(['FirstRunMiddleware: Denying access to ', request.path, ' FirstRun needed.']));
                return redirect(settings.FIRSTRUN_APP_ROOT)
            else:
                # Will only be executed between the time firstrun has been completed, until the process is regenerated (typically on the scale of mins).
                logging.debug('FirstRunMiddleware: FirstRun completed, resuming normal flow.')

    def is_first_run(self):
        return not os.path.exists(''.join([settings.PROJECT_PATH, settings.FIRSTRUN_LOCKFILE]))

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.