Moved default admin from media to django/conf/admin_media, so Django is able to introspect their location, in preparation for #76
git-svn-id: http://code.djangoproject.com/svn/django/trunk@185 bcc190cf-cafb-0310-a4f2-bffc1f526a37
|
@ -365,13 +365,13 @@ startapp.args = "[appname]"
|
||||||
def runserver(port):
|
def runserver(port):
|
||||||
"Starts a lightweight Web server for development."
|
"Starts a lightweight Web server for development."
|
||||||
from django.core.servers.basehttp import run, WSGIServerException
|
from django.core.servers.basehttp import run, WSGIServerException
|
||||||
from django.core.handlers.wsgi import WSGIHandler
|
from django.core.handlers.wsgi import AdminMediaHandler, WSGIHandler
|
||||||
if not port.isdigit():
|
if not port.isdigit():
|
||||||
sys.stderr.write("Error: %r is not a valid port number.\n" % port)
|
sys.stderr.write("Error: %r is not a valid port number.\n" % port)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
print "Starting server on port %s. Go to http://127.0.0.1:%s/ for Django." % (port, port)
|
print "Starting server on port %s. Go to http://127.0.0.1:%s/ for Django." % (port, port)
|
||||||
try:
|
try:
|
||||||
run(int(port), WSGIHandler())
|
run(int(port), AdminMediaHandler(WSGIHandler()))
|
||||||
except WSGIServerException, e:
|
except WSGIServerException, e:
|
||||||
# Use helpful error messages instead of ugly tracebacks.
|
# Use helpful error messages instead of ugly tracebacks.
|
||||||
ERRORS = {
|
ERRORS = {
|
||||||
|
|
Before Width: | Height: | Size: 80 B After Width: | Height: | Size: 80 B |
Before Width: | Height: | Size: 838 B After Width: | Height: | Size: 838 B |
Before Width: | Height: | Size: 58 B After Width: | Height: | Size: 58 B |
Before Width: | Height: | Size: 199 B After Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 212 B After Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 843 B After Width: | Height: | Size: 843 B |
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 844 B |
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 145 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 181 B After Width: | Height: | Size: 181 B |
Before Width: | Height: | Size: 319 B After Width: | Height: | Size: 319 B |
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 667 B |
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
Before Width: | Height: | Size: 116 B After Width: | Height: | Size: 116 B |
Before Width: | Height: | Size: 186 B After Width: | Height: | Size: 186 B |
Before Width: | Height: | Size: 273 B After Width: | Height: | Size: 273 B |
Before Width: | Height: | Size: 606 B After Width: | Height: | Size: 606 B |
Before Width: | Height: | Size: 358 B After Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 355 B |
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 552 B |
Before Width: | Height: | Size: 612 B After Width: | Height: | Size: 612 B |
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 401 B |
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 197 B |
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 198 B |
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 200 B |
Before Width: | Height: | Size: 932 B After Width: | Height: | Size: 932 B |
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 351 B |
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 354 B |
|
@ -240,3 +240,45 @@ class WSGIHandler:
|
||||||
"Helper function to return the traceback as a string"
|
"Helper function to return the traceback as a string"
|
||||||
import sys, traceback
|
import sys, traceback
|
||||||
return '\n'.join(traceback.format_exception(*sys.exc_info()))
|
return '\n'.join(traceback.format_exception(*sys.exc_info()))
|
||||||
|
|
||||||
|
class AdminMediaHandler:
|
||||||
|
"""
|
||||||
|
WSGI middleware that intercepts calls to the admin media directory, as
|
||||||
|
defined by the ADMIN_MEDIA_PREFIX setting, and serves those images.
|
||||||
|
Use this ONLY LOCALLY, for development! This hasn't been tested for
|
||||||
|
security and is not super efficient.
|
||||||
|
"""
|
||||||
|
def __init__(self, application):
|
||||||
|
from django.conf import settings
|
||||||
|
import django
|
||||||
|
self.application = application
|
||||||
|
self.media_dir = django.__path__[0] + '/conf/admin_templates'
|
||||||
|
self.media_url = settings.ADMIN_MEDIA_PREFIX
|
||||||
|
|
||||||
|
def __call__(self, environ, start_response):
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
# Ignore requests that aren't under ADMIN_MEDIA_PREFIX.
|
||||||
|
if not environ['PATH_INFO'].startswith(self.media_url):
|
||||||
|
return self.application(environ, start_response)
|
||||||
|
|
||||||
|
# Find the admin file and serve it up, if it exists and is readable.
|
||||||
|
file_path = os.path.join(self.media_dir, environ['PATH_INFO'][1:])
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
status = '404 NOT FOUND'
|
||||||
|
headers = {'Content-type': 'text/plain'}
|
||||||
|
output = ['Page not found: %s' % file_path]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
fp = open(file_path, 'r')
|
||||||
|
except IOError:
|
||||||
|
status = '401 UNAUTHORIZED'
|
||||||
|
headers = {'Content-type': 'text/plain'}
|
||||||
|
output = ['Permission denied: %s' % file_path]
|
||||||
|
else:
|
||||||
|
status = '200 OK'
|
||||||
|
headers = {}
|
||||||
|
output = [fp.read()]
|
||||||
|
fp.close()
|
||||||
|
start_response(status, headers.items())
|
||||||
|
return output
|
||||||
|
|
5
setup.py
|
@ -13,7 +13,10 @@ setup(
|
||||||
license = 'BSD',
|
license = 'BSD',
|
||||||
packages = find_packages(),
|
packages = find_packages(),
|
||||||
package_data = {
|
package_data = {
|
||||||
'django.conf': ['admin_templates/*.html', 'admin_templates/doc/*.html'],
|
'django.conf': ['admin_templates/*.html', 'admin_templates/doc/*.html',
|
||||||
|
'admin_media/css/*.css', 'admin_media/img/admin/*.gif',
|
||||||
|
'admin_media/img/admin/*.png', 'admin_media/js/*.js',
|
||||||
|
'admin_media/js/admin/*js'],
|
||||||
},
|
},
|
||||||
scripts = ['django/bin/django-admin.py'],
|
scripts = ['django/bin/django-admin.py'],
|
||||||
)
|
)
|
||||||
|
|