Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..388fb2b
--- /dev/null
+++ b/main.py
@@ -0,0 +1,57 @@
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Main program for Monorail.
+
+Monorail is an issue tracking tool that is based on the code.google.com
+issue tracker, but it has been ported to Google AppEngine and Google Cloud SQL.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import os
+import six
+
+import flask
+import google.appengine.api
+import google.cloud.logging
+
+# Fix imports before importing gae_ts_mon.
+import import_utils
+
+import_utils.FixImports()
+
+import gae_ts_mon
+
+import registerpages
+from framework import sorting
+from redirect import redirect
+from services import service_manager
+
+if os.getenv('GAE_ENV') == 'standard':
+  # If this isn't a local server, set up cloud logging.
+  client = google.cloud.logging.Client()
+  client.setup_logging()
+
+if six.PY3:
+  # https://github.com/GoogleCloudPlatform/appengine-python-standard/issues/70
+  import functools
+  from google.appengine.api import memcache
+  unpickler = functools.partial(six.moves.cPickle.Unpickler, encoding='bytes')
+  memcache.setup_client(memcache.Client(unpickler=unpickler))
+
+services = service_manager.set_up_services()
+sorting.InitializeArtValues(services)
+
+app = flask.Flask(__name__)
+app.wsgi_app = google.appengine.api.wrap_wsgi_app(app.wsgi_app)
+
+redirect_app = redirect.GenerateRedirectApp()
+app.wsgi_app = redirect.RedirectMiddleware(app.wsgi_app, redirect_app.wsgi_app)
+
+registerpages.ServletRegistry().Register(services, app)
+registerpages.RegisterEndpointsUrls(app)
+registerpages.RegisterTeardown(app)
+
+gae_ts_mon.initialize_prod(app)