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): | ||||
|     "Starts a lightweight Web server for development." | ||||
|     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(): | ||||
|         sys.stderr.write("Error: %r is not a valid port number.\n" % port) | ||||
|         sys.exit(1) | ||||
|     print "Starting server on port %s. Go to http://127.0.0.1:%s/ for Django." % (port, port) | ||||
|     try: | ||||
|         run(int(port), WSGIHandler()) | ||||
|         run(int(port), AdminMediaHandler(WSGIHandler())) | ||||
|     except WSGIServerException, e: | ||||
|         # Use helpful error messages instead of ugly tracebacks. | ||||
|         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" | ||||
|         import sys, traceback | ||||
|         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', | ||||
|     packages = find_packages(), | ||||
|     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'], | ||||
| ) | ||||
|   | ||||