We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Change Docker entrypoint to use gunicorn
* [x] Run WSGI server using gunicorn
* [ ] Do some basic testing with boom / siege / wrk to set reasonable defaults for concurrency


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `concordia/settings_template.py`
Content:
```
1 # TODO: use correct copyright header
2 import os
3 import sys
4 
5 from django.contrib import messages
6 from dotenv import load_dotenv
7 from machina import MACHINA_MAIN_STATIC_DIR, MACHINA_MAIN_TEMPLATE_DIR
8 from machina import get_apps as get_machina_apps
9 
10 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
11 PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
12 BASE_DIR = os.path.dirname(PROJECT_DIR)
13 
14 # Build path for and load .env file.
15 dotenv_path = os.path.join(BASE_DIR, ".env")
16 load_dotenv(dotenv_path)
17 
18 # SECURITY WARNING: keep the secret key used in production secret!
19 SECRET_KEY = "django-secret-key"
20 
21 CONCORDIA_ENVIRONMENT = os.environ.get("CONCORDIA_ENVIRONMENT", "development")
22 
23 # Optional SMTP authentication information for EMAIL_HOST.
24 EMAIL_HOST_USER = ""
25 EMAIL_HOST_PASSWORD = ""
26 EMAIL_USE_TLS = False
27 DEFAULT_FROM_EMAIL = "crowd@loc.gov"
28 
29 ALLOWED_HOSTS = ["*"]
30 
31 DEBUG = False
32 CSRF_COOKIE_SECURE = False
33 
34 sys.path.append(PROJECT_DIR)
35 AUTH_PASSWORD_VALIDATORS = []
36 EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
37 # EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'emails')
38 EMAIL_HOST = "localhost"
39 EMAIL_PORT = 25
40 LANGUAGE_CODE = "en-us"
41 LOGIN_REDIRECT_URL = "/"
42 LOGOUT_REDIRECT_URL = "/"
43 ROOT_URLCONF = "concordia.urls"
44 STATIC_ROOT = "static"
45 STATIC_URL = "/static/"
46 STATICFILES_DIRS = [
47     os.path.join(PROJECT_DIR, "static"),
48     os.path.join("/".join(PROJECT_DIR.split("/")[:-1]), "concordia/static"),
49 ]
50 STATICFILES_DIRS = [os.path.join(PROJECT_DIR, "static"), MACHINA_MAIN_STATIC_DIR]
51 TEMPLATE_DEBUG = False
52 TIME_ZONE = "UTC"
53 USE_I18N = True
54 USE_L10N = True
55 USE_TZ = True
56 WSGI_APPLICATION = "concordia.wsgi.application"
57 
58 ADMIN_SITE = {"site_header": "Concordia Admin", "site_title": "Concordia"}
59 
60 DATABASES = {
61     "default": {
62         "ENGINE": "django.db.backends.postgresql",
63         "NAME": "concordia",
64         "USER": "concordia",
65         "PASSWORD": "$(POSTGRESQL_PW)",
66         "HOST": "$(POSTGRESQL_HOST)",
67         "PORT": "5432",
68         "CONN_MAX_AGE": 15 * 60,  # Keep database connections open for 15 minutes
69     }
70 }
71 
72 
73 INSTALLED_APPS = [
74     "django.contrib.admin",
75     "django.contrib.auth",
76     "django.contrib.contenttypes",
77     "django.contrib.humanize",
78     "django.contrib.sessions",
79     "django.contrib.messages",
80     "django.contrib.staticfiles",
81     "raven.contrib.django.raven_compat",
82     "maintenance_mode",
83     "rest_framework",
84     "concordia",
85     "exporter",
86     "faq",
87     "importer",
88     "concordia.experiments.wireframes",
89     "captcha",
90     # Machina related apps:
91     "mptt",
92     "haystack",
93     "widget_tweaks",
94     "django_prometheus_metrics",
95 ] + get_machina_apps()
96 
97 
98 if DEBUG:
99     INSTALLED_APPS += ["django_extensions"]
100     INSTALLED_APPS += ["kombu.transport"]
101 
102 
103 MIDDLEWARE = [
104     "django_prometheus_metrics.middleware.PrometheusBeforeMiddleware",
105     "django.middleware.security.SecurityMiddleware",
106     "django.contrib.sessions.middleware.SessionMiddleware",
107     "django.middleware.common.CommonMiddleware",
108     "django.middleware.csrf.CsrfViewMiddleware",
109     "django.contrib.auth.middleware.AuthenticationMiddleware",
110     "django.contrib.messages.middleware.MessageMiddleware",
111     "django.middleware.clickjacking.XFrameOptionsMiddleware",
112     # Machina
113     "machina.apps.forum_permission.middleware.ForumPermissionMiddleware",
114     "maintenance_mode.middleware.MaintenanceModeMiddleware",
115 ]
116 
117 TEMPLATES = [
118     {
119         "BACKEND": "django.template.backends.django.DjangoTemplates",
120         "DIRS": [os.path.join(PROJECT_DIR, "templates"), MACHINA_MAIN_TEMPLATE_DIR],
121         #    'APP_DIRS': True,
122         "OPTIONS": {
123             "context_processors": [
124                 "django.template.context_processors.debug",
125                 "django.template.context_processors.request",
126                 "django.contrib.auth.context_processors.auth",
127                 "django.contrib.messages.context_processors.messages",
128                 "django.template.context_processors.media",
129                 # Concordia
130                 "concordia.context_processors.system_configuration",
131                 "concordia.context_processors.site_navigation",
132                 # Machina
133                 "machina.core.context_processors.metadata",
134             ],
135             "loaders": [
136                 "django.template.loaders.filesystem.Loader",
137                 "django.template.loaders.app_directories.Loader",
138             ],
139         },
140     }
141 ]
142 
143 CACHES = {
144     "default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"},
145     "machina_attachments": {
146         "BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
147         "LOCATION": "/tmp",
148     },
149 }
150 
151 HAYSTACK_CONNECTIONS = {
152     "default": {
153         "ENGINE": "haystack.backends.whoosh_backend.WhooshEngine",
154         "PATH": os.path.join(os.path.dirname(__file__), "whoosh_index"),
155     }
156 }
157 
158 # Celery settings
159 CELERY_BROKER_URL = "pyamqp://guest@rabbit"
160 CELERY_RESULT_BACKEND = "rpc://"
161 
162 CELERY_ACCEPT_CONTENT = ["json"]
163 CELERY_TASK_SERIALIZER = "json"
164 CELERY_IMPORTS = ("importer.tasks",)
165 
166 CELERY_BROKER_HEARTBEAT = 0
167 CELERY_BROKER_TRANSPORT_OPTIONS = {
168     "confirm_publish": True,
169     "max_retries": 3,
170     "interval_start": 0,
171     "interval_step": 0.2,
172     "interval_max": 0.5,
173 }
174 
175 LOGGING = {
176     "version": 1,
177     "disable_existing_loggers": False,
178     "formatters": {
179         "long": {
180             "format": "[{asctime} {levelname} {name}:{lineno}] {message}",
181             "datefmt": "%Y-%m-%dT%H:%M:%S",
182             "style": "{",
183         },
184         "short": {
185             "format": "[{levelname} {name}] {message}",
186             "datefmt": "%Y-%m-%dT%H:%M:%S",
187             "style": "{",
188         },
189     },
190     "handlers": {
191         "stream": {
192             "class": "logging.StreamHandler",
193             "level": "INFO",
194             "formatter": "long",
195         },
196         "null": {"level": "DEBUG", "class": "logging.NullHandler"},
197         "file": {
198             "class": "logging.handlers.TimedRotatingFileHandler",
199             "level": "DEBUG",
200             "formatter": "long",
201             "filename": "{}/logs/concordia.log".format(BASE_DIR),
202             "when": "H",
203             "interval": 3,
204             "backupCount": 16,
205         },
206         "celery": {
207             "level": "DEBUG",
208             "class": "logging.handlers.RotatingFileHandler",
209             "filename": "{}/logs/celery.log".format(BASE_DIR),
210             "formatter": "long",
211             "maxBytes": 1024 * 1024 * 100,  # 100 mb
212         },
213         "sentry": {
214             "level": "WARNING",
215             "class": "raven.contrib.django.raven_compat.handlers.SentryHandler",
216         },
217     },
218     "loggers": {
219         "django": {"handlers": ["file", "stream"], "level": "DEBUG", "propagate": True},
220         "celery": {"handlers": ["celery", "stream"], "level": "DEBUG"},
221         "sentry.errors": {"level": "INFO", "handlers": ["stream"], "propagate": False},
222     },
223 }
224 
225 
226 ################################################################################
227 # Django-specific settings above
228 ################################################################################
229 
230 ACCOUNT_ACTIVATION_DAYS = 7
231 
232 REST_FRAMEWORK = {
233     "PAGE_SIZE": 10,
234     "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
235     "DEFAULT_AUTHENTICATION_CLASSES": (
236         "rest_framework.authentication.BasicAuthentication",
237         "rest_framework.authentication.SessionAuthentication",
238     ),
239 }
240 
241 CONCORDIA = {"netloc": "http://0:80"}
242 MEDIA_URL = "/media/"
243 MEDIA_ROOT = os.path.join(BASE_DIR, "media")
244 
245 
246 LOGIN_URL = "/account/login/"
247 
248 PASSWORD_VALIDATOR = (
249     "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
250 )
251 
252 AUTH_PASSWORD_VALIDATORS = [
253     {"NAME": PASSWORD_VALIDATOR},
254     {
255         "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
256         "OPTIONS": {"min_length": 8},
257     },
258     {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
259     {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
260     {"NAME": "concordia.validators.complexity"},
261 ]
262 
263 AUTHENTICATION_BACKENDS = [
264     "concordia.email_username_backend.EmailOrUsernameModelBackend"
265 ]
266 
267 REGISTRATION_URLS = "registration.backends.simple.urls"
268 
269 CAPTCHA_CHALLENGE_FUNCT = "captcha.helpers.random_char_challenge"
270 CAPTCHA_FIELD_TEMPLATE = "captcha/field.html"
271 CAPTCHA_TEXT_FIELD_TEMPLATE = "captcha/text_field.html"
272 
273 AWS_S3 = {
274     "AWS_ACCESS_KEY_ID": os.getenv("AWS_ACCESS_KEY_ID"),
275     "AWS_SECRET_ACCESS_KEY": os.getenv("AWS_SECRET_ACCESS_KEY"),
276     "S3_COLLECTION_BUCKET": "chc-collections",
277     "REGION": os.getenv("AWS_REGION"),
278 }
279 
280 PASSWORD_RESET_TIMEOUT_DAYS = 1
281 ACCOUNT_ACTIVATION_DAYS = 1
282 REGISTRATION_OPEN = True  # set to false to temporarily disable registrations
283 
284 MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
285 
286 MESSAGE_TAGS = {
287     messages.ERROR: 'danger',
288 }
289 
290 SENTRY_DSN = os.environ.get("SENTRY_DSN", "")
291 SENTRY_PUBLIC_DSN = os.environ.get("SENTRY_PUBLIC_DSN", "")
292 
293 if SENTRY_DSN:
294     RAVEN_CONFIG = {"dsn": SENTRY_DSN, "environment": CONCORDIA_ENVIRONMENT}
295 
296 # When the MAINTENANCE_MODE setting is true, this template will be used to
297 # generate a 503 response:
298 MAINTENANCE_MODE_TEMPLATE = "maintenance-mode.html"
299
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/concordia/settings_template.py b/concordia/settings_template.py
--- a/concordia/settings_template.py
+++ b/concordia/settings_template.py
@@ -103,15 +103,17 @@
 MIDDLEWARE = [
     "django_prometheus_metrics.middleware.PrometheusBeforeMiddleware",
     "django.middleware.security.SecurityMiddleware",
+    # WhiteNoise serves static files efficiently:
+    "whitenoise.middleware.WhiteNoiseMiddleware",
     "django.contrib.sessions.middleware.SessionMiddleware",
     "django.middleware.common.CommonMiddleware",
     "django.middleware.csrf.CsrfViewMiddleware",
     "django.contrib.auth.middleware.AuthenticationMiddleware",
     "django.contrib.messages.middleware.MessageMiddleware",
     "django.middleware.clickjacking.XFrameOptionsMiddleware",
+    "maintenance_mode.middleware.MaintenanceModeMiddleware",
     # Machina
     "machina.apps.forum_permission.middleware.ForumPermissionMiddleware",
-    "maintenance_mode.middleware.MaintenanceModeMiddleware",
 ]
 
 TEMPLATES = [
@@ -277,15 +279,16 @@
     "REGION": os.getenv("AWS_REGION"),
 }
 
+STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
+WHITENOISE_ROOT = STATIC_ROOT
+
 PASSWORD_RESET_TIMEOUT_DAYS = 1
 ACCOUNT_ACTIVATION_DAYS = 1
 REGISTRATION_OPEN = True  # set to false to temporarily disable registrations
 
-MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
+MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage"
 
-MESSAGE_TAGS = {
-    messages.ERROR: 'danger',
-}
+MESSAGE_TAGS = {messages.ERROR: "danger"}
 
 SENTRY_DSN = os.environ.get("SENTRY_DSN", "")
 SENTRY_PUBLIC_DSN = os.environ.get("SENTRY_PUBLIC_DSN", "")

{"golden_diff": "diff --git a/concordia/settings_template.py b/concordia/settings_template.py\n--- a/concordia/settings_template.py\n+++ b/concordia/settings_template.py\n@@ -103,15 +103,17 @@\n MIDDLEWARE = [\n     \"django_prometheus_metrics.middleware.PrometheusBeforeMiddleware\",\n     \"django.middleware.security.SecurityMiddleware\",\n+    # WhiteNoise serves static files efficiently:\n+    \"whitenoise.middleware.WhiteNoiseMiddleware\",\n     \"django.contrib.sessions.middleware.SessionMiddleware\",\n     \"django.middleware.common.CommonMiddleware\",\n     \"django.middleware.csrf.CsrfViewMiddleware\",\n     \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n     \"django.contrib.messages.middleware.MessageMiddleware\",\n     \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n+    \"maintenance_mode.middleware.MaintenanceModeMiddleware\",\n     # Machina\n     \"machina.apps.forum_permission.middleware.ForumPermissionMiddleware\",\n-    \"maintenance_mode.middleware.MaintenanceModeMiddleware\",\n ]\n \n TEMPLATES = [\n@@ -277,15 +279,16 @@\n     \"REGION\": os.getenv(\"AWS_REGION\"),\n }\n \n+STATICFILES_STORAGE = \"whitenoise.storage.CompressedManifestStaticFilesStorage\"\n+WHITENOISE_ROOT = STATIC_ROOT\n+\n PASSWORD_RESET_TIMEOUT_DAYS = 1\n ACCOUNT_ACTIVATION_DAYS = 1\n REGISTRATION_OPEN = True  # set to false to temporarily disable registrations\n \n-MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'\n+MESSAGE_STORAGE = \"django.contrib.messages.storage.session.SessionStorage\"\n \n-MESSAGE_TAGS = {\n-    messages.ERROR: 'danger',\n-}\n+MESSAGE_TAGS = {messages.ERROR: \"danger\"}\n \n SENTRY_DSN = os.environ.get(\"SENTRY_DSN\", \"\")\n SENTRY_PUBLIC_DSN = os.environ.get(\"SENTRY_PUBLIC_DSN\", \"\")\n", "issue": "Change Docker entrypoint to use gunicorn\n* [x] Run WSGI server using gunicorn\r\n* [ ] Do some basic testing with boom / siege / wrk to set reasonable defaults for concurrency\r\n\n", "before_files": [{"content": "# TODO: use correct copyright header\nimport os\nimport sys\n\nfrom django.contrib import messages\nfrom dotenv import load_dotenv\nfrom machina import MACHINA_MAIN_STATIC_DIR, MACHINA_MAIN_TEMPLATE_DIR\nfrom machina import get_apps as get_machina_apps\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nPROJECT_DIR = os.path.dirname(os.path.abspath(__file__))\nBASE_DIR = os.path.dirname(PROJECT_DIR)\n\n# Build path for and load .env file.\ndotenv_path = os.path.join(BASE_DIR, \".env\")\nload_dotenv(dotenv_path)\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = \"django-secret-key\"\n\nCONCORDIA_ENVIRONMENT = os.environ.get(\"CONCORDIA_ENVIRONMENT\", \"development\")\n\n# Optional SMTP authentication information for EMAIL_HOST.\nEMAIL_HOST_USER = \"\"\nEMAIL_HOST_PASSWORD = \"\"\nEMAIL_USE_TLS = False\nDEFAULT_FROM_EMAIL = \"crowd@loc.gov\"\n\nALLOWED_HOSTS = [\"*\"]\n\nDEBUG = False\nCSRF_COOKIE_SECURE = False\n\nsys.path.append(PROJECT_DIR)\nAUTH_PASSWORD_VALIDATORS = []\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\n# EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'emails')\nEMAIL_HOST = \"localhost\"\nEMAIL_PORT = 25\nLANGUAGE_CODE = \"en-us\"\nLOGIN_REDIRECT_URL = \"/\"\nLOGOUT_REDIRECT_URL = \"/\"\nROOT_URLCONF = \"concordia.urls\"\nSTATIC_ROOT = \"static\"\nSTATIC_URL = \"/static/\"\nSTATICFILES_DIRS = [\n    os.path.join(PROJECT_DIR, \"static\"),\n    os.path.join(\"/\".join(PROJECT_DIR.split(\"/\")[:-1]), \"concordia/static\"),\n]\nSTATICFILES_DIRS = [os.path.join(PROJECT_DIR, \"static\"), MACHINA_MAIN_STATIC_DIR]\nTEMPLATE_DEBUG = False\nTIME_ZONE = \"UTC\"\nUSE_I18N = True\nUSE_L10N = True\nUSE_TZ = True\nWSGI_APPLICATION = \"concordia.wsgi.application\"\n\nADMIN_SITE = {\"site_header\": \"Concordia Admin\", \"site_title\": \"Concordia\"}\n\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"NAME\": \"concordia\",\n        \"USER\": \"concordia\",\n        \"PASSWORD\": \"$(POSTGRESQL_PW)\",\n        \"HOST\": \"$(POSTGRESQL_HOST)\",\n        \"PORT\": \"5432\",\n        \"CONN_MAX_AGE\": 15 * 60,  # Keep database connections open for 15 minutes\n    }\n}\n\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.humanize\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"raven.contrib.django.raven_compat\",\n    \"maintenance_mode\",\n    \"rest_framework\",\n    \"concordia\",\n    \"exporter\",\n    \"faq\",\n    \"importer\",\n    \"concordia.experiments.wireframes\",\n    \"captcha\",\n    # Machina related apps:\n    \"mptt\",\n    \"haystack\",\n    \"widget_tweaks\",\n    \"django_prometheus_metrics\",\n] + get_machina_apps()\n\n\nif DEBUG:\n    INSTALLED_APPS += [\"django_extensions\"]\n    INSTALLED_APPS += [\"kombu.transport\"]\n\n\nMIDDLEWARE = [\n    \"django_prometheus_metrics.middleware.PrometheusBeforeMiddleware\",\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    # Machina\n    \"machina.apps.forum_permission.middleware.ForumPermissionMiddleware\",\n    \"maintenance_mode.middleware.MaintenanceModeMiddleware\",\n]\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [os.path.join(PROJECT_DIR, \"templates\"), MACHINA_MAIN_TEMPLATE_DIR],\n        #    'APP_DIRS': True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.request\",\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.contrib.messages.context_processors.messages\",\n                \"django.template.context_processors.media\",\n                # Concordia\n                \"concordia.context_processors.system_configuration\",\n                \"concordia.context_processors.site_navigation\",\n                # Machina\n                \"machina.core.context_processors.metadata\",\n            ],\n            \"loaders\": [\n                \"django.template.loaders.filesystem.Loader\",\n                \"django.template.loaders.app_directories.Loader\",\n            ],\n        },\n    }\n]\n\nCACHES = {\n    \"default\": {\"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\"},\n    \"machina_attachments\": {\n        \"BACKEND\": \"django.core.cache.backends.filebased.FileBasedCache\",\n        \"LOCATION\": \"/tmp\",\n    },\n}\n\nHAYSTACK_CONNECTIONS = {\n    \"default\": {\n        \"ENGINE\": \"haystack.backends.whoosh_backend.WhooshEngine\",\n        \"PATH\": os.path.join(os.path.dirname(__file__), \"whoosh_index\"),\n    }\n}\n\n# Celery settings\nCELERY_BROKER_URL = \"pyamqp://guest@rabbit\"\nCELERY_RESULT_BACKEND = \"rpc://\"\n\nCELERY_ACCEPT_CONTENT = [\"json\"]\nCELERY_TASK_SERIALIZER = \"json\"\nCELERY_IMPORTS = (\"importer.tasks\",)\n\nCELERY_BROKER_HEARTBEAT = 0\nCELERY_BROKER_TRANSPORT_OPTIONS = {\n    \"confirm_publish\": True,\n    \"max_retries\": 3,\n    \"interval_start\": 0,\n    \"interval_step\": 0.2,\n    \"interval_max\": 0.5,\n}\n\nLOGGING = {\n    \"version\": 1,\n    \"disable_existing_loggers\": False,\n    \"formatters\": {\n        \"long\": {\n            \"format\": \"[{asctime} {levelname} {name}:{lineno}] {message}\",\n            \"datefmt\": \"%Y-%m-%dT%H:%M:%S\",\n            \"style\": \"{\",\n        },\n        \"short\": {\n            \"format\": \"[{levelname} {name}] {message}\",\n            \"datefmt\": \"%Y-%m-%dT%H:%M:%S\",\n            \"style\": \"{\",\n        },\n    },\n    \"handlers\": {\n        \"stream\": {\n            \"class\": \"logging.StreamHandler\",\n            \"level\": \"INFO\",\n            \"formatter\": \"long\",\n        },\n        \"null\": {\"level\": \"DEBUG\", \"class\": \"logging.NullHandler\"},\n        \"file\": {\n            \"class\": \"logging.handlers.TimedRotatingFileHandler\",\n            \"level\": \"DEBUG\",\n            \"formatter\": \"long\",\n            \"filename\": \"{}/logs/concordia.log\".format(BASE_DIR),\n            \"when\": \"H\",\n            \"interval\": 3,\n            \"backupCount\": 16,\n        },\n        \"celery\": {\n            \"level\": \"DEBUG\",\n            \"class\": \"logging.handlers.RotatingFileHandler\",\n            \"filename\": \"{}/logs/celery.log\".format(BASE_DIR),\n            \"formatter\": \"long\",\n            \"maxBytes\": 1024 * 1024 * 100,  # 100 mb\n        },\n        \"sentry\": {\n            \"level\": \"WARNING\",\n            \"class\": \"raven.contrib.django.raven_compat.handlers.SentryHandler\",\n        },\n    },\n    \"loggers\": {\n        \"django\": {\"handlers\": [\"file\", \"stream\"], \"level\": \"DEBUG\", \"propagate\": True},\n        \"celery\": {\"handlers\": [\"celery\", \"stream\"], \"level\": \"DEBUG\"},\n        \"sentry.errors\": {\"level\": \"INFO\", \"handlers\": [\"stream\"], \"propagate\": False},\n    },\n}\n\n\n################################################################################\n# Django-specific settings above\n################################################################################\n\nACCOUNT_ACTIVATION_DAYS = 7\n\nREST_FRAMEWORK = {\n    \"PAGE_SIZE\": 10,\n    \"DEFAULT_PAGINATION_CLASS\": \"rest_framework.pagination.PageNumberPagination\",\n    \"DEFAULT_AUTHENTICATION_CLASSES\": (\n        \"rest_framework.authentication.BasicAuthentication\",\n        \"rest_framework.authentication.SessionAuthentication\",\n    ),\n}\n\nCONCORDIA = {\"netloc\": \"http://0:80\"}\nMEDIA_URL = \"/media/\"\nMEDIA_ROOT = os.path.join(BASE_DIR, \"media\")\n\n\nLOGIN_URL = \"/account/login/\"\n\nPASSWORD_VALIDATOR = (\n    \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\"\n)\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\"NAME\": PASSWORD_VALIDATOR},\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n        \"OPTIONS\": {\"min_length\": 8},\n    },\n    {\"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\"},\n    {\"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\"},\n    {\"NAME\": \"concordia.validators.complexity\"},\n]\n\nAUTHENTICATION_BACKENDS = [\n    \"concordia.email_username_backend.EmailOrUsernameModelBackend\"\n]\n\nREGISTRATION_URLS = \"registration.backends.simple.urls\"\n\nCAPTCHA_CHALLENGE_FUNCT = \"captcha.helpers.random_char_challenge\"\nCAPTCHA_FIELD_TEMPLATE = \"captcha/field.html\"\nCAPTCHA_TEXT_FIELD_TEMPLATE = \"captcha/text_field.html\"\n\nAWS_S3 = {\n    \"AWS_ACCESS_KEY_ID\": os.getenv(\"AWS_ACCESS_KEY_ID\"),\n    \"AWS_SECRET_ACCESS_KEY\": os.getenv(\"AWS_SECRET_ACCESS_KEY\"),\n    \"S3_COLLECTION_BUCKET\": \"chc-collections\",\n    \"REGION\": os.getenv(\"AWS_REGION\"),\n}\n\nPASSWORD_RESET_TIMEOUT_DAYS = 1\nACCOUNT_ACTIVATION_DAYS = 1\nREGISTRATION_OPEN = True  # set to false to temporarily disable registrations\n\nMESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'\n\nMESSAGE_TAGS = {\n    messages.ERROR: 'danger',\n}\n\nSENTRY_DSN = os.environ.get(\"SENTRY_DSN\", \"\")\nSENTRY_PUBLIC_DSN = os.environ.get(\"SENTRY_PUBLIC_DSN\", \"\")\n\nif SENTRY_DSN:\n    RAVEN_CONFIG = {\"dsn\": SENTRY_DSN, \"environment\": CONCORDIA_ENVIRONMENT}\n\n# When the MAINTENANCE_MODE setting is true, this template will be used to\n# generate a 503 response:\nMAINTENANCE_MODE_TEMPLATE = \"maintenance-mode.html\"\n", "path": "concordia/settings_template.py"}], "after_files": [{"content": "# TODO: use correct copyright header\nimport os\nimport sys\n\nfrom django.contrib import messages\nfrom dotenv import load_dotenv\nfrom machina import MACHINA_MAIN_STATIC_DIR, MACHINA_MAIN_TEMPLATE_DIR\nfrom machina import get_apps as get_machina_apps\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nPROJECT_DIR = os.path.dirname(os.path.abspath(__file__))\nBASE_DIR = os.path.dirname(PROJECT_DIR)\n\n# Build path for and load .env file.\ndotenv_path = os.path.join(BASE_DIR, \".env\")\nload_dotenv(dotenv_path)\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = \"django-secret-key\"\n\nCONCORDIA_ENVIRONMENT = os.environ.get(\"CONCORDIA_ENVIRONMENT\", \"development\")\n\n# Optional SMTP authentication information for EMAIL_HOST.\nEMAIL_HOST_USER = \"\"\nEMAIL_HOST_PASSWORD = \"\"\nEMAIL_USE_TLS = False\nDEFAULT_FROM_EMAIL = \"crowd@loc.gov\"\n\nALLOWED_HOSTS = [\"*\"]\n\nDEBUG = False\nCSRF_COOKIE_SECURE = False\n\nsys.path.append(PROJECT_DIR)\nAUTH_PASSWORD_VALIDATORS = []\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\n# EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'emails')\nEMAIL_HOST = \"localhost\"\nEMAIL_PORT = 25\nLANGUAGE_CODE = \"en-us\"\nLOGIN_REDIRECT_URL = \"/\"\nLOGOUT_REDIRECT_URL = \"/\"\nROOT_URLCONF = \"concordia.urls\"\nSTATIC_ROOT = \"static\"\nSTATIC_URL = \"/static/\"\nSTATICFILES_DIRS = [\n    os.path.join(PROJECT_DIR, \"static\"),\n    os.path.join(\"/\".join(PROJECT_DIR.split(\"/\")[:-1]), \"concordia/static\"),\n]\nSTATICFILES_DIRS = [os.path.join(PROJECT_DIR, \"static\"), MACHINA_MAIN_STATIC_DIR]\nTEMPLATE_DEBUG = False\nTIME_ZONE = \"UTC\"\nUSE_I18N = True\nUSE_L10N = True\nUSE_TZ = True\nWSGI_APPLICATION = \"concordia.wsgi.application\"\n\nADMIN_SITE = {\"site_header\": \"Concordia Admin\", \"site_title\": \"Concordia\"}\n\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"NAME\": \"concordia\",\n        \"USER\": \"concordia\",\n        \"PASSWORD\": \"$(POSTGRESQL_PW)\",\n        \"HOST\": \"$(POSTGRESQL_HOST)\",\n        \"PORT\": \"5432\",\n        \"CONN_MAX_AGE\": 15 * 60,  # Keep database connections open for 15 minutes\n    }\n}\n\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.humanize\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"raven.contrib.django.raven_compat\",\n    \"maintenance_mode\",\n    \"rest_framework\",\n    \"concordia\",\n    \"exporter\",\n    \"faq\",\n    \"importer\",\n    \"concordia.experiments.wireframes\",\n    \"captcha\",\n    # Machina related apps:\n    \"mptt\",\n    \"haystack\",\n    \"widget_tweaks\",\n    \"django_prometheus_metrics\",\n] + get_machina_apps()\n\n\nif DEBUG:\n    INSTALLED_APPS += [\"django_extensions\"]\n    INSTALLED_APPS += [\"kombu.transport\"]\n\n\nMIDDLEWARE = [\n    \"django_prometheus_metrics.middleware.PrometheusBeforeMiddleware\",\n    \"django.middleware.security.SecurityMiddleware\",\n    # WhiteNoise serves static files efficiently:\n    \"whitenoise.middleware.WhiteNoiseMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"maintenance_mode.middleware.MaintenanceModeMiddleware\",\n    # Machina\n    \"machina.apps.forum_permission.middleware.ForumPermissionMiddleware\",\n]\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [os.path.join(PROJECT_DIR, \"templates\"), MACHINA_MAIN_TEMPLATE_DIR],\n        #    'APP_DIRS': True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.request\",\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.contrib.messages.context_processors.messages\",\n                \"django.template.context_processors.media\",\n                # Concordia\n                \"concordia.context_processors.system_configuration\",\n                \"concordia.context_processors.site_navigation\",\n                # Machina\n                \"machina.core.context_processors.metadata\",\n            ],\n            \"loaders\": [\n                \"django.template.loaders.filesystem.Loader\",\n                \"django.template.loaders.app_directories.Loader\",\n            ],\n        },\n    }\n]\n\nCACHES = {\n    \"default\": {\"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\"},\n    \"machina_attachments\": {\n        \"BACKEND\": \"django.core.cache.backends.filebased.FileBasedCache\",\n        \"LOCATION\": \"/tmp\",\n    },\n}\n\nHAYSTACK_CONNECTIONS = {\n    \"default\": {\n        \"ENGINE\": \"haystack.backends.whoosh_backend.WhooshEngine\",\n        \"PATH\": os.path.join(os.path.dirname(__file__), \"whoosh_index\"),\n    }\n}\n\n# Celery settings\nCELERY_BROKER_URL = \"pyamqp://guest@rabbit\"\nCELERY_RESULT_BACKEND = \"rpc://\"\n\nCELERY_ACCEPT_CONTENT = [\"json\"]\nCELERY_TASK_SERIALIZER = \"json\"\nCELERY_IMPORTS = (\"importer.tasks\",)\n\nCELERY_BROKER_HEARTBEAT = 0\nCELERY_BROKER_TRANSPORT_OPTIONS = {\n    \"confirm_publish\": True,\n    \"max_retries\": 3,\n    \"interval_start\": 0,\n    \"interval_step\": 0.2,\n    \"interval_max\": 0.5,\n}\n\nLOGGING = {\n    \"version\": 1,\n    \"disable_existing_loggers\": False,\n    \"formatters\": {\n        \"long\": {\n            \"format\": \"[{asctime} {levelname} {name}:{lineno}] {message}\",\n            \"datefmt\": \"%Y-%m-%dT%H:%M:%S\",\n            \"style\": \"{\",\n        },\n        \"short\": {\n            \"format\": \"[{levelname} {name}] {message}\",\n            \"datefmt\": \"%Y-%m-%dT%H:%M:%S\",\n            \"style\": \"{\",\n        },\n    },\n    \"handlers\": {\n        \"stream\": {\n            \"class\": \"logging.StreamHandler\",\n            \"level\": \"INFO\",\n            \"formatter\": \"long\",\n        },\n        \"null\": {\"level\": \"DEBUG\", \"class\": \"logging.NullHandler\"},\n        \"file\": {\n            \"class\": \"logging.handlers.TimedRotatingFileHandler\",\n            \"level\": \"DEBUG\",\n            \"formatter\": \"long\",\n            \"filename\": \"{}/logs/concordia.log\".format(BASE_DIR),\n            \"when\": \"H\",\n            \"interval\": 3,\n            \"backupCount\": 16,\n        },\n        \"celery\": {\n            \"level\": \"DEBUG\",\n            \"class\": \"logging.handlers.RotatingFileHandler\",\n            \"filename\": \"{}/logs/celery.log\".format(BASE_DIR),\n            \"formatter\": \"long\",\n            \"maxBytes\": 1024 * 1024 * 100,  # 100 mb\n        },\n        \"sentry\": {\n            \"level\": \"WARNING\",\n            \"class\": \"raven.contrib.django.raven_compat.handlers.SentryHandler\",\n        },\n    },\n    \"loggers\": {\n        \"django\": {\"handlers\": [\"file\", \"stream\"], \"level\": \"DEBUG\", \"propagate\": True},\n        \"celery\": {\"handlers\": [\"celery\", \"stream\"], \"level\": \"DEBUG\"},\n        \"sentry.errors\": {\"level\": \"INFO\", \"handlers\": [\"stream\"], \"propagate\": False},\n    },\n}\n\n\n################################################################################\n# Django-specific settings above\n################################################################################\n\nACCOUNT_ACTIVATION_DAYS = 7\n\nREST_FRAMEWORK = {\n    \"PAGE_SIZE\": 10,\n    \"DEFAULT_PAGINATION_CLASS\": \"rest_framework.pagination.PageNumberPagination\",\n    \"DEFAULT_AUTHENTICATION_CLASSES\": (\n        \"rest_framework.authentication.BasicAuthentication\",\n        \"rest_framework.authentication.SessionAuthentication\",\n    ),\n}\n\nCONCORDIA = {\"netloc\": \"http://0:80\"}\nMEDIA_URL = \"/media/\"\nMEDIA_ROOT = os.path.join(BASE_DIR, \"media\")\n\n\nLOGIN_URL = \"/account/login/\"\n\nPASSWORD_VALIDATOR = (\n    \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\"\n)\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\"NAME\": PASSWORD_VALIDATOR},\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n        \"OPTIONS\": {\"min_length\": 8},\n    },\n    {\"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\"},\n    {\"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\"},\n    {\"NAME\": \"concordia.validators.complexity\"},\n]\n\nAUTHENTICATION_BACKENDS = [\n    \"concordia.email_username_backend.EmailOrUsernameModelBackend\"\n]\n\nREGISTRATION_URLS = \"registration.backends.simple.urls\"\n\nCAPTCHA_CHALLENGE_FUNCT = \"captcha.helpers.random_char_challenge\"\nCAPTCHA_FIELD_TEMPLATE = \"captcha/field.html\"\nCAPTCHA_TEXT_FIELD_TEMPLATE = \"captcha/text_field.html\"\n\nAWS_S3 = {\n    \"AWS_ACCESS_KEY_ID\": os.getenv(\"AWS_ACCESS_KEY_ID\"),\n    \"AWS_SECRET_ACCESS_KEY\": os.getenv(\"AWS_SECRET_ACCESS_KEY\"),\n    \"S3_COLLECTION_BUCKET\": \"chc-collections\",\n    \"REGION\": os.getenv(\"AWS_REGION\"),\n}\n\nSTATICFILES_STORAGE = \"whitenoise.storage.CompressedManifestStaticFilesStorage\"\nWHITENOISE_ROOT = STATIC_ROOT\n\nPASSWORD_RESET_TIMEOUT_DAYS = 1\nACCOUNT_ACTIVATION_DAYS = 1\nREGISTRATION_OPEN = True  # set to false to temporarily disable registrations\n\nMESSAGE_STORAGE = \"django.contrib.messages.storage.session.SessionStorage\"\n\nMESSAGE_TAGS = {messages.ERROR: \"danger\"}\n\nSENTRY_DSN = os.environ.get(\"SENTRY_DSN\", \"\")\nSENTRY_PUBLIC_DSN = os.environ.get(\"SENTRY_PUBLIC_DSN\", \"\")\n\nif SENTRY_DSN:\n    RAVEN_CONFIG = {\"dsn\": SENTRY_DSN, \"environment\": CONCORDIA_ENVIRONMENT}\n\n# When the MAINTENANCE_MODE setting is true, this template will be used to\n# generate a 503 response:\nMAINTENANCE_MODE_TEMPLATE = \"maintenance-mode.html\"\n", "path": "concordia/settings_template.py"}]}