diff options
Diffstat (limited to 'webapp/main.py')
-rw-r--r-- | webapp/main.py | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/webapp/main.py b/webapp/main.py new file mode 100644 index 0000000000..a6cfa93245 --- /dev/null +++ b/webapp/main.py @@ -0,0 +1,128 @@ +# Copyright 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Main program for Gerrit. + +This is also a template for running a Django app under Google App +Engine, especially when using a newer version of Django than provided +in the App Engine standard library. + +The site-specific code is all in other files: urls.py, models.py, +views.py, settings.py. +""" + +# Standard Python imports. +import os +import sys +import logging + +# Log a message each time this module get loaded. +logging.info('Loading %s, app version = %s', + __name__, os.getenv('CURRENT_VERSION_ID')) + +# Delete the preloaded copy of Django. +for key in [key for key in sys.modules if key.startswith('django')]: + del sys.modules[key] + +# Force sys.path to have our own directory first, so we can import from it. +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) +sys.path.insert(0, os.path.abspath('django.zip')) +sys.path.insert(0, os.path.abspath('froofle.zip')) +sys.path.insert(0, os.path.abspath('codereview.zip')) + +# Fail early if we can't import Django. Log identifying information. +import django +logging.info('django.__file__ = %r, django.VERSION = %r', + django.__file__, django.VERSION) +assert django.VERSION[0] >= 1,"This Django version is too old" + +# AppEngine imports. +from google.appengine.ext.webapp import util + +# Helper to enter the debugger. This passes in __stdin__ and +# __stdout__, because stdin and stdout are connected to the request +# and response streams. You must import this from __main__ to use it. +# (I tried to make it universally available via __builtin__, but that +# doesn't seem to work for some reason.) +def BREAKPOINT(): + import pdb + p = pdb.Pdb(None, sys.__stdin__, sys.__stdout__) + p.set_trace() + +# Custom Django configuration. +from django.conf import settings +settings._target = None +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' + +# Import various parts of Django. +import django.core.handlers.wsgi +import django.core.signals +import django.db +import django.dispatch.dispatcher +import django.forms + +# Work-around to avoid warning about django.newforms in djangoforms. +django.newforms = django.forms + +def log_exception(*args, **kwds): + """Django signal handler to log an exception.""" + cls, err = sys.exc_info()[:2] + logging.exception('Exception in request: %s: %s', cls.__name__, err) + +# Log all exceptions detected by Django. +django.core.signals.got_request_exception.connect(log_exception) + +# Unregister Django's default rollback event handler. +django.core.signals.got_request_exception.disconnect( + django.db._rollback_on_exception) + +correct_path = None +def real_main(): + """Main program. + """ + global correct_path + + if correct_path is None: + correct_path = list(sys.path) + else: + sys.path[:] = correct_path + + application = django.core.handlers.wsgi.WSGIHandler() + util.run_wsgi_app(application) + +def profile_main(): + """Main program for profiling. + """ + import cProfile, pstats, StringIO + prof = cProfile.Profile() + prof = prof.runctx('real_main()', globals(), locals()) + stream = StringIO.StringIO() + stats = pstats.Stats(prof, stream=stream) + # stats.strip_dirs() # Don't; too many modules are named __init__.py. + stats.sort_stats('time') # 'time', 'cumulative' or 'calls' + stats.print_stats() # Optional arg: how many to print + # The rest is optional. + # stats.print_callees() + # stats.print_callers() + print '\n<hr>' + print '<h1>Profile</h1>' + print '<pre>' + print stream.getvalue()[:1000000] + print '</pre>' + +# Set this to profile_main to enable profiling. +main = real_main + +if __name__ == '__main__': + main() |