We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add carousel image for new campaign
Acceptance criteria: 

- [x] Choose image 
- [x] Edit photo
- [x] Add as first slide?
- [x] Add link to let's go button


--- 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/context_processors.py`
Content:
```
1 from django.conf import settings
2 
3 from concordia.version import get_concordia_version
4 
5 
6 def system_configuration(request):
7     """
8     Expose some system configuration to the default template context
9     """
10 
11     return {
12         "SENTRY_FRONTEND_DSN": getattr(settings, "SENTRY_FRONTEND_DSN", None),
13         "CONCORDIA_ENVIRONMENT": settings.CONCORDIA_ENVIRONMENT,
14         "S3_BUCKET_NAME": getattr(settings, "S3_BUCKET_NAME", None),
15         "APPLICATION_VERSION": get_concordia_version(),
16         "RAVEN_CONFIG": settings.RAVEN_CONFIG,
17     }
18 
19 
20 def site_navigation(request):
21     data = {}
22 
23     if request.resolver_match:
24         data["VIEW_NAME"] = request.resolver_match.view_name
25         data["VIEW_NAME_FOR_CSS"] = data["VIEW_NAME"].replace(":", "--")
26 
27     path_components = request.path.strip("/").split("/")
28     for i, component in enumerate(path_components, start=1):
29         data["PATH_LEVEL_%d" % i] = component
30 
31     return data
32
```

Path: `concordia/settings_template.py`
Content:
```
1 # TODO: use correct copyright header
2 import os
3 
4 import raven
5 from django.contrib import messages
6 
7 # Build paths inside the project like this: os.path.join(SITE_ROOT_DIR, ...)
8 CONCORDIA_APP_DIR = os.path.abspath(os.path.dirname(__file__))
9 SITE_ROOT_DIR = os.path.dirname(CONCORDIA_APP_DIR)
10 
11 # SECURITY WARNING: keep the secret key used in production secret!
12 SECRET_KEY = "django-secret-key"
13 
14 CONCORDIA_ENVIRONMENT = os.environ.get("CONCORDIA_ENVIRONMENT", "development")
15 
16 # Optional SMTP authentication information for EMAIL_HOST.
17 EMAIL_HOST_USER = ""
18 EMAIL_HOST_PASSWORD = ""
19 EMAIL_USE_TLS = False
20 DEFAULT_FROM_EMAIL = "crowd@loc.gov"
21 
22 ALLOWED_HOSTS = ["*"]
23 
24 DEBUG = False
25 CSRF_COOKIE_SECURE = False
26 
27 AUTH_PASSWORD_VALIDATORS = []
28 EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
29 EMAIL_HOST = "localhost"
30 EMAIL_PORT = 25
31 LANGUAGE_CODE = "en-us"
32 LOGIN_REDIRECT_URL = "/"
33 LOGOUT_REDIRECT_URL = "/"
34 ROOT_URLCONF = "concordia.urls"
35 STATIC_ROOT = "static-files"
36 STATIC_URL = "/static/"
37 STATICFILES_DIRS = [
38     os.path.join(CONCORDIA_APP_DIR, "static"),
39     os.path.join(SITE_ROOT_DIR, "static"),
40 ]
41 TEMPLATE_DEBUG = False
42 TIME_ZONE = "America/New_York"
43 USE_I18N = True
44 USE_L10N = True
45 USE_TZ = True
46 WSGI_APPLICATION = "concordia.wsgi.application"
47 
48 DATABASES = {
49     "default": {
50         "ENGINE": "django.db.backends.postgresql",
51         "NAME": "concordia",
52         "USER": "concordia",
53         "PASSWORD": os.getenv("POSTGRESQL_PW"),
54         "HOST": os.getenv("POSTGRESQL_HOST", "localhost"),
55         "PORT": os.getenv("POSTGRESQL_PORT", "5432"),
56         # Change this back to 15 minutes (15*60) once celery regression
57         # is fixed  see https://github.com/celery/celery/issues/4878
58         "CONN_MAX_AGE": 0,  # 15 minutes
59     }
60 }
61 
62 INSTALLED_APPS = [
63     "concordia.apps.ConcordiaAdminConfig",  # Replaces 'django.contrib.admin'
64     "django.contrib.auth",
65     "django.contrib.contenttypes",
66     "django.contrib.humanize",
67     "django.contrib.sessions",
68     "django.contrib.messages",
69     "django.contrib.sites",
70     "django.contrib.staticfiles",
71     "raven.contrib.django.raven_compat",
72     "maintenance_mode",
73     "bootstrap4",
74     "bittersweet",
75     "concordia.apps.ConcordiaAppConfig",
76     "exporter",
77     "importer",
78     "captcha",
79     "django_prometheus_metrics",
80     "robots",
81     "django_celery_beat",
82     "flags",
83 ]
84 
85 MIDDLEWARE = [
86     "django_prometheus_metrics.middleware.PrometheusBeforeMiddleware",
87     "django.middleware.security.SecurityMiddleware",
88     # WhiteNoise serves static files efficiently:
89     "whitenoise.middleware.WhiteNoiseMiddleware",
90     "django.contrib.sessions.middleware.SessionMiddleware",
91     "django.middleware.common.CommonMiddleware",
92     "django.middleware.csrf.CsrfViewMiddleware",
93     "django.contrib.auth.middleware.AuthenticationMiddleware",
94     "django.contrib.messages.middleware.MessageMiddleware",
95     "django.middleware.clickjacking.XFrameOptionsMiddleware",
96     "maintenance_mode.middleware.MaintenanceModeMiddleware",
97     "ratelimit.middleware.RatelimitMiddleware",
98     "flags.middleware.FlagConditionsMiddleware",
99 ]
100 
101 RATELIMIT_VIEW = "concordia.views.ratelimit_view"
102 RATELIMIT_BLOCK = False
103 
104 TEMPLATES = [
105     {
106         "BACKEND": "django.template.backends.django.DjangoTemplates",
107         "DIRS": [
108             os.path.join(SITE_ROOT_DIR, "templates"),
109             os.path.join(CONCORDIA_APP_DIR, "templates"),
110         ],
111         "OPTIONS": {
112             "context_processors": [
113                 "django.template.context_processors.debug",
114                 "django.template.context_processors.request",
115                 "django.contrib.auth.context_processors.auth",
116                 "django.contrib.messages.context_processors.messages",
117                 "django.template.context_processors.media",
118                 # Concordia
119                 "concordia.context_processors.system_configuration",
120                 "concordia.context_processors.site_navigation",
121             ],
122             "loaders": [
123                 "django.template.loaders.filesystem.Loader",
124                 "django.template.loaders.app_directories.Loader",
125             ],
126         },
127     }
128 ]
129 
130 MEMCACHED_ADDRESS = os.getenv("MEMCACHED_ADDRESS", "")
131 MEMCACHED_PORT = os.getenv("MEMCACHED_PORT", "")
132 
133 if MEMCACHED_ADDRESS and MEMCACHED_PORT:
134 
135     CACHES = {
136         "default": {
137             "BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
138             "LOCATION": "{}:{}".format(MEMCACHED_ADDRESS, MEMCACHED_PORT),
139         }
140     }
141 
142     SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
143 
144 else:
145 
146     CACHES = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"}}
147 
148     SESSION_ENGINE = "django.contrib.sessions.backends.db"
149 
150 HAYSTACK_CONNECTIONS = {
151     "default": {
152         "ENGINE": "haystack.backends.whoosh_backend.WhooshEngine",
153         "PATH": os.path.join(os.path.dirname(__file__), "whoosh_index"),
154     }
155 }
156 
157 # Celery settings
158 CELERY_BROKER_URL = "redis://redis:6379/0"
159 CELERY_RESULT_BACKEND = "redis://redis:6379/0"
160 
161 CELERY_ACCEPT_CONTENT = ["json"]
162 CELERY_TASK_SERIALIZER = "json"
163 CELERY_IMPORTS = ("importer.tasks",)
164 
165 CELERY_BROKER_HEARTBEAT = 0
166 CELERY_BROKER_TRANSPORT_OPTIONS = {
167     "confirm_publish": True,
168     "max_retries": 3,
169     "interval_start": 0,
170     "interval_step": 0.2,
171     "interval_max": 0.5,
172 }
173 
174 LOGGING = {
175     "version": 1,
176     "disable_existing_loggers": False,
177     "formatters": {
178         "long": {
179             "format": "[{asctime} {levelname} {name}:{lineno}] {message}",
180             "datefmt": "%Y-%m-%dT%H:%M:%S",
181             "style": "{",
182         },
183         "short": {
184             "format": "[{levelname} {name}] {message}",
185             "datefmt": "%Y-%m-%dT%H:%M:%S",
186             "style": "{",
187         },
188     },
189     "handlers": {
190         "stream": {
191             "class": "logging.StreamHandler",
192             "level": "INFO",
193             "formatter": "long",
194         },
195         "null": {"level": "DEBUG", "class": "logging.NullHandler"},
196         "file": {
197             "class": "logging.handlers.TimedRotatingFileHandler",
198             "level": "DEBUG",
199             "formatter": "long",
200             "filename": "{}/logs/concordia.log".format(SITE_ROOT_DIR),
201             "when": "H",
202             "interval": 3,
203             "backupCount": 16,
204         },
205         "celery": {
206             "level": "DEBUG",
207             "class": "logging.handlers.RotatingFileHandler",
208             "filename": "{}/logs/celery.log".format(SITE_ROOT_DIR),
209             "formatter": "long",
210             "maxBytes": 1024 * 1024 * 100,  # 100 mb
211         },
212         "sentry": {
213             "level": "WARNING",
214             "class": "raven.contrib.django.raven_compat.handlers.SentryHandler",
215         },
216     },
217     "loggers": {
218         "django": {"handlers": ["file", "stream"], "level": "DEBUG", "propagate": True},
219         "celery": {"handlers": ["celery", "stream"], "level": "DEBUG"},
220         "sentry.errors": {"level": "INFO", "handlers": ["stream"], "propagate": False},
221     },
222 }
223 
224 
225 ################################################################################
226 # Django-specific settings above
227 ################################################################################
228 
229 MEDIA_URL = "/media/"
230 MEDIA_ROOT = os.path.join(SITE_ROOT_DIR, "media")
231 
232 LOGIN_URL = "login"
233 
234 PASSWORD_VALIDATOR = (
235     "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
236 )
237 
238 AUTH_PASSWORD_VALIDATORS = [
239     {"NAME": PASSWORD_VALIDATOR},
240     {
241         "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
242         "OPTIONS": {"min_length": 8},
243     },
244     {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
245     {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
246     {"NAME": "concordia.validators.DjangoPasswordsValidator"},
247 ]
248 
249 # See https://github.com/dstufft/django-passwords#settings
250 PASSWORD_COMPLEXITY = {
251     "UPPER": 1,
252     "LOWER": 1,
253     "LETTERS": 1,
254     "DIGITS": 1,
255     "SPECIAL": 1,
256     "WORDS": 1,
257 }
258 
259 AUTHENTICATION_BACKENDS = [
260     "concordia.authentication_backends.EmailOrUsernameModelBackend"
261 ]
262 
263 CAPTCHA_CHALLENGE_FUNCT = "captcha.helpers.random_char_challenge"
264 #: Anonymous sessions require captcha validation every day by default:
265 ANONYMOUS_CAPTCHA_VALIDATION_INTERVAL = 86400
266 
267 STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
268 WHITENOISE_ROOT = os.path.join(SITE_ROOT_DIR, "static")
269 
270 PASSWORD_RESET_TIMEOUT_DAYS = 2
271 ACCOUNT_ACTIVATION_DAYS = 2
272 REGISTRATION_OPEN = True  # set to false to temporarily disable registrations
273 
274 MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage"
275 
276 MESSAGE_TAGS = {messages.ERROR: "danger"}
277 
278 SENTRY_BACKEND_DSN = os.environ.get("SENTRY_BACKEND_DSN", "")
279 SENTRY_FRONTEND_DSN = os.environ.get("SENTRY_FRONTEND_DSN", "")
280 
281 RAVEN_CONFIG = {
282     "dsn": SENTRY_BACKEND_DSN,
283     "environment": CONCORDIA_ENVIRONMENT,
284     "release": raven.fetch_git_sha(SITE_ROOT_DIR),
285 }
286 
287 # When the MAINTENANCE_MODE setting is true, this template will be used to
288 # generate a 503 response:
289 MAINTENANCE_MODE_TEMPLATE = "maintenance-mode.html"
290 
291 # Names of special django.auth Groups
292 COMMUNITY_MANAGER_GROUP_NAME = "Community Managers"
293 NEWSLETTER_GROUP_NAME = "Newsletter"
294 
295 # Django sites framework setting
296 SITE_ID = 1
297 ROBOTS_USE_SITEMAP = False
298 ROBOTS_USE_HOST = False
299 
300 # django-bootstrap4 customization:
301 BOOTSTRAP4 = {"required_css_class": "form-group-required"}
302 
303 # Transcription-related settings
304 
305 #: Number of seconds an asset reservation is valid for
306 TRANSCRIPTION_RESERVATION_SECONDS = 5 * 60
307 
308 #: Web cache policy settings
309 DEFAULT_PAGE_TTL = 5 * 60
310 
311 # Feature flag for social share
312 FLAGS = {"SOCIAL_SHARE": []}
313
```
--- 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/context_processors.py b/concordia/context_processors.py
--- a/concordia/context_processors.py
+++ b/concordia/context_processors.py
@@ -1,4 +1,5 @@
 from django.conf import settings
+from flags.state import flag_enabled
 
 from concordia.version import get_concordia_version
 
@@ -14,6 +15,7 @@
         "S3_BUCKET_NAME": getattr(settings, "S3_BUCKET_NAME", None),
         "APPLICATION_VERSION": get_concordia_version(),
         "RAVEN_CONFIG": settings.RAVEN_CONFIG,
+        "NEW_CAROUSEL_SLIDE": flag_enabled("NEW_CAROUSEL_SLIDE", request=request),
     }
 
 
diff --git a/concordia/settings_template.py b/concordia/settings_template.py
--- a/concordia/settings_template.py
+++ b/concordia/settings_template.py
@@ -309,4 +309,4 @@
 DEFAULT_PAGE_TTL = 5 * 60
 
 # Feature flag for social share
-FLAGS = {"SOCIAL_SHARE": []}
+FLAGS = {"SOCIAL_SHARE": [], "NEW_CAROUSEL_SLIDE": []}

{"golden_diff": "diff --git a/concordia/context_processors.py b/concordia/context_processors.py\n--- a/concordia/context_processors.py\n+++ b/concordia/context_processors.py\n@@ -1,4 +1,5 @@\n from django.conf import settings\n+from flags.state import flag_enabled\n \n from concordia.version import get_concordia_version\n \n@@ -14,6 +15,7 @@\n         \"S3_BUCKET_NAME\": getattr(settings, \"S3_BUCKET_NAME\", None),\n         \"APPLICATION_VERSION\": get_concordia_version(),\n         \"RAVEN_CONFIG\": settings.RAVEN_CONFIG,\n+        \"NEW_CAROUSEL_SLIDE\": flag_enabled(\"NEW_CAROUSEL_SLIDE\", request=request),\n     }\n \n \ndiff --git a/concordia/settings_template.py b/concordia/settings_template.py\n--- a/concordia/settings_template.py\n+++ b/concordia/settings_template.py\n@@ -309,4 +309,4 @@\n DEFAULT_PAGE_TTL = 5 * 60\n \n # Feature flag for social share\n-FLAGS = {\"SOCIAL_SHARE\": []}\n+FLAGS = {\"SOCIAL_SHARE\": [], \"NEW_CAROUSEL_SLIDE\": []}\n", "issue": "Add carousel image for new campaign\nAcceptance criteria: \r\n\r\n- [x] Choose image \r\n- [x] Edit photo\r\n- [x] Add as first slide?\r\n- [x] Add link to let's go button\r\n\n", "before_files": [{"content": "from django.conf import settings\n\nfrom concordia.version import get_concordia_version\n\n\ndef system_configuration(request):\n    \"\"\"\n    Expose some system configuration to the default template context\n    \"\"\"\n\n    return {\n        \"SENTRY_FRONTEND_DSN\": getattr(settings, \"SENTRY_FRONTEND_DSN\", None),\n        \"CONCORDIA_ENVIRONMENT\": settings.CONCORDIA_ENVIRONMENT,\n        \"S3_BUCKET_NAME\": getattr(settings, \"S3_BUCKET_NAME\", None),\n        \"APPLICATION_VERSION\": get_concordia_version(),\n        \"RAVEN_CONFIG\": settings.RAVEN_CONFIG,\n    }\n\n\ndef site_navigation(request):\n    data = {}\n\n    if request.resolver_match:\n        data[\"VIEW_NAME\"] = request.resolver_match.view_name\n        data[\"VIEW_NAME_FOR_CSS\"] = data[\"VIEW_NAME\"].replace(\":\", \"--\")\n\n    path_components = request.path.strip(\"/\").split(\"/\")\n    for i, component in enumerate(path_components, start=1):\n        data[\"PATH_LEVEL_%d\" % i] = component\n\n    return data\n", "path": "concordia/context_processors.py"}, {"content": "# TODO: use correct copyright header\nimport os\n\nimport raven\nfrom django.contrib import messages\n\n# Build paths inside the project like this: os.path.join(SITE_ROOT_DIR, ...)\nCONCORDIA_APP_DIR = os.path.abspath(os.path.dirname(__file__))\nSITE_ROOT_DIR = os.path.dirname(CONCORDIA_APP_DIR)\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\nAUTH_PASSWORD_VALIDATORS = []\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\nEMAIL_HOST = \"localhost\"\nEMAIL_PORT = 25\nLANGUAGE_CODE = \"en-us\"\nLOGIN_REDIRECT_URL = \"/\"\nLOGOUT_REDIRECT_URL = \"/\"\nROOT_URLCONF = \"concordia.urls\"\nSTATIC_ROOT = \"static-files\"\nSTATIC_URL = \"/static/\"\nSTATICFILES_DIRS = [\n    os.path.join(CONCORDIA_APP_DIR, \"static\"),\n    os.path.join(SITE_ROOT_DIR, \"static\"),\n]\nTEMPLATE_DEBUG = False\nTIME_ZONE = \"America/New_York\"\nUSE_I18N = True\nUSE_L10N = True\nUSE_TZ = True\nWSGI_APPLICATION = \"concordia.wsgi.application\"\n\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"NAME\": \"concordia\",\n        \"USER\": \"concordia\",\n        \"PASSWORD\": os.getenv(\"POSTGRESQL_PW\"),\n        \"HOST\": os.getenv(\"POSTGRESQL_HOST\", \"localhost\"),\n        \"PORT\": os.getenv(\"POSTGRESQL_PORT\", \"5432\"),\n        # Change this back to 15 minutes (15*60) once celery regression\n        # is fixed  see https://github.com/celery/celery/issues/4878\n        \"CONN_MAX_AGE\": 0,  # 15 minutes\n    }\n}\n\nINSTALLED_APPS = [\n    \"concordia.apps.ConcordiaAdminConfig\",  # Replaces '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.sites\",\n    \"django.contrib.staticfiles\",\n    \"raven.contrib.django.raven_compat\",\n    \"maintenance_mode\",\n    \"bootstrap4\",\n    \"bittersweet\",\n    \"concordia.apps.ConcordiaAppConfig\",\n    \"exporter\",\n    \"importer\",\n    \"captcha\",\n    \"django_prometheus_metrics\",\n    \"robots\",\n    \"django_celery_beat\",\n    \"flags\",\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    \"ratelimit.middleware.RatelimitMiddleware\",\n    \"flags.middleware.FlagConditionsMiddleware\",\n]\n\nRATELIMIT_VIEW = \"concordia.views.ratelimit_view\"\nRATELIMIT_BLOCK = False\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [\n            os.path.join(SITE_ROOT_DIR, \"templates\"),\n            os.path.join(CONCORDIA_APP_DIR, \"templates\"),\n        ],\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            ],\n            \"loaders\": [\n                \"django.template.loaders.filesystem.Loader\",\n                \"django.template.loaders.app_directories.Loader\",\n            ],\n        },\n    }\n]\n\nMEMCACHED_ADDRESS = os.getenv(\"MEMCACHED_ADDRESS\", \"\")\nMEMCACHED_PORT = os.getenv(\"MEMCACHED_PORT\", \"\")\n\nif MEMCACHED_ADDRESS and MEMCACHED_PORT:\n\n    CACHES = {\n        \"default\": {\n            \"BACKEND\": \"django.core.cache.backends.memcached.MemcachedCache\",\n            \"LOCATION\": \"{}:{}\".format(MEMCACHED_ADDRESS, MEMCACHED_PORT),\n        }\n    }\n\n    SESSION_ENGINE = \"django.contrib.sessions.backends.cached_db\"\n\nelse:\n\n    CACHES = {\"default\": {\"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\"}}\n\n    SESSION_ENGINE = \"django.contrib.sessions.backends.db\"\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 = \"redis://redis:6379/0\"\nCELERY_RESULT_BACKEND = \"redis://redis:6379/0\"\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(SITE_ROOT_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(SITE_ROOT_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\nMEDIA_URL = \"/media/\"\nMEDIA_ROOT = os.path.join(SITE_ROOT_DIR, \"media\")\n\nLOGIN_URL = \"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.DjangoPasswordsValidator\"},\n]\n\n# See https://github.com/dstufft/django-passwords#settings\nPASSWORD_COMPLEXITY = {\n    \"UPPER\": 1,\n    \"LOWER\": 1,\n    \"LETTERS\": 1,\n    \"DIGITS\": 1,\n    \"SPECIAL\": 1,\n    \"WORDS\": 1,\n}\n\nAUTHENTICATION_BACKENDS = [\n    \"concordia.authentication_backends.EmailOrUsernameModelBackend\"\n]\n\nCAPTCHA_CHALLENGE_FUNCT = \"captcha.helpers.random_char_challenge\"\n#: Anonymous sessions require captcha validation every day by default:\nANONYMOUS_CAPTCHA_VALIDATION_INTERVAL = 86400\n\nSTATICFILES_STORAGE = \"whitenoise.storage.CompressedManifestStaticFilesStorage\"\nWHITENOISE_ROOT = os.path.join(SITE_ROOT_DIR, \"static\")\n\nPASSWORD_RESET_TIMEOUT_DAYS = 2\nACCOUNT_ACTIVATION_DAYS = 2\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_BACKEND_DSN = os.environ.get(\"SENTRY_BACKEND_DSN\", \"\")\nSENTRY_FRONTEND_DSN = os.environ.get(\"SENTRY_FRONTEND_DSN\", \"\")\n\nRAVEN_CONFIG = {\n    \"dsn\": SENTRY_BACKEND_DSN,\n    \"environment\": CONCORDIA_ENVIRONMENT,\n    \"release\": raven.fetch_git_sha(SITE_ROOT_DIR),\n}\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\n# Names of special django.auth Groups\nCOMMUNITY_MANAGER_GROUP_NAME = \"Community Managers\"\nNEWSLETTER_GROUP_NAME = \"Newsletter\"\n\n# Django sites framework setting\nSITE_ID = 1\nROBOTS_USE_SITEMAP = False\nROBOTS_USE_HOST = False\n\n# django-bootstrap4 customization:\nBOOTSTRAP4 = {\"required_css_class\": \"form-group-required\"}\n\n# Transcription-related settings\n\n#: Number of seconds an asset reservation is valid for\nTRANSCRIPTION_RESERVATION_SECONDS = 5 * 60\n\n#: Web cache policy settings\nDEFAULT_PAGE_TTL = 5 * 60\n\n# Feature flag for social share\nFLAGS = {\"SOCIAL_SHARE\": []}\n", "path": "concordia/settings_template.py"}], "after_files": [{"content": "from django.conf import settings\nfrom flags.state import flag_enabled\n\nfrom concordia.version import get_concordia_version\n\n\ndef system_configuration(request):\n    \"\"\"\n    Expose some system configuration to the default template context\n    \"\"\"\n\n    return {\n        \"SENTRY_FRONTEND_DSN\": getattr(settings, \"SENTRY_FRONTEND_DSN\", None),\n        \"CONCORDIA_ENVIRONMENT\": settings.CONCORDIA_ENVIRONMENT,\n        \"S3_BUCKET_NAME\": getattr(settings, \"S3_BUCKET_NAME\", None),\n        \"APPLICATION_VERSION\": get_concordia_version(),\n        \"RAVEN_CONFIG\": settings.RAVEN_CONFIG,\n        \"NEW_CAROUSEL_SLIDE\": flag_enabled(\"NEW_CAROUSEL_SLIDE\", request=request),\n    }\n\n\ndef site_navigation(request):\n    data = {}\n\n    if request.resolver_match:\n        data[\"VIEW_NAME\"] = request.resolver_match.view_name\n        data[\"VIEW_NAME_FOR_CSS\"] = data[\"VIEW_NAME\"].replace(\":\", \"--\")\n\n    path_components = request.path.strip(\"/\").split(\"/\")\n    for i, component in enumerate(path_components, start=1):\n        data[\"PATH_LEVEL_%d\" % i] = component\n\n    return data\n", "path": "concordia/context_processors.py"}, {"content": "# TODO: use correct copyright header\nimport os\n\nimport raven\nfrom django.contrib import messages\n\n# Build paths inside the project like this: os.path.join(SITE_ROOT_DIR, ...)\nCONCORDIA_APP_DIR = os.path.abspath(os.path.dirname(__file__))\nSITE_ROOT_DIR = os.path.dirname(CONCORDIA_APP_DIR)\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\nAUTH_PASSWORD_VALIDATORS = []\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\nEMAIL_HOST = \"localhost\"\nEMAIL_PORT = 25\nLANGUAGE_CODE = \"en-us\"\nLOGIN_REDIRECT_URL = \"/\"\nLOGOUT_REDIRECT_URL = \"/\"\nROOT_URLCONF = \"concordia.urls\"\nSTATIC_ROOT = \"static-files\"\nSTATIC_URL = \"/static/\"\nSTATICFILES_DIRS = [\n    os.path.join(CONCORDIA_APP_DIR, \"static\"),\n    os.path.join(SITE_ROOT_DIR, \"static\"),\n]\nTEMPLATE_DEBUG = False\nTIME_ZONE = \"America/New_York\"\nUSE_I18N = True\nUSE_L10N = True\nUSE_TZ = True\nWSGI_APPLICATION = \"concordia.wsgi.application\"\n\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"NAME\": \"concordia\",\n        \"USER\": \"concordia\",\n        \"PASSWORD\": os.getenv(\"POSTGRESQL_PW\"),\n        \"HOST\": os.getenv(\"POSTGRESQL_HOST\", \"localhost\"),\n        \"PORT\": os.getenv(\"POSTGRESQL_PORT\", \"5432\"),\n        # Change this back to 15 minutes (15*60) once celery regression\n        # is fixed  see https://github.com/celery/celery/issues/4878\n        \"CONN_MAX_AGE\": 0,  # 15 minutes\n    }\n}\n\nINSTALLED_APPS = [\n    \"concordia.apps.ConcordiaAdminConfig\",  # Replaces '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.sites\",\n    \"django.contrib.staticfiles\",\n    \"raven.contrib.django.raven_compat\",\n    \"maintenance_mode\",\n    \"bootstrap4\",\n    \"bittersweet\",\n    \"concordia.apps.ConcordiaAppConfig\",\n    \"exporter\",\n    \"importer\",\n    \"captcha\",\n    \"django_prometheus_metrics\",\n    \"robots\",\n    \"django_celery_beat\",\n    \"flags\",\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    \"ratelimit.middleware.RatelimitMiddleware\",\n    \"flags.middleware.FlagConditionsMiddleware\",\n]\n\nRATELIMIT_VIEW = \"concordia.views.ratelimit_view\"\nRATELIMIT_BLOCK = False\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [\n            os.path.join(SITE_ROOT_DIR, \"templates\"),\n            os.path.join(CONCORDIA_APP_DIR, \"templates\"),\n        ],\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            ],\n            \"loaders\": [\n                \"django.template.loaders.filesystem.Loader\",\n                \"django.template.loaders.app_directories.Loader\",\n            ],\n        },\n    }\n]\n\nMEMCACHED_ADDRESS = os.getenv(\"MEMCACHED_ADDRESS\", \"\")\nMEMCACHED_PORT = os.getenv(\"MEMCACHED_PORT\", \"\")\n\nif MEMCACHED_ADDRESS and MEMCACHED_PORT:\n\n    CACHES = {\n        \"default\": {\n            \"BACKEND\": \"django.core.cache.backends.memcached.MemcachedCache\",\n            \"LOCATION\": \"{}:{}\".format(MEMCACHED_ADDRESS, MEMCACHED_PORT),\n        }\n    }\n\n    SESSION_ENGINE = \"django.contrib.sessions.backends.cached_db\"\n\nelse:\n\n    CACHES = {\"default\": {\"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\"}}\n\n    SESSION_ENGINE = \"django.contrib.sessions.backends.db\"\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 = \"redis://redis:6379/0\"\nCELERY_RESULT_BACKEND = \"redis://redis:6379/0\"\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(SITE_ROOT_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(SITE_ROOT_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\nMEDIA_URL = \"/media/\"\nMEDIA_ROOT = os.path.join(SITE_ROOT_DIR, \"media\")\n\nLOGIN_URL = \"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.DjangoPasswordsValidator\"},\n]\n\n# See https://github.com/dstufft/django-passwords#settings\nPASSWORD_COMPLEXITY = {\n    \"UPPER\": 1,\n    \"LOWER\": 1,\n    \"LETTERS\": 1,\n    \"DIGITS\": 1,\n    \"SPECIAL\": 1,\n    \"WORDS\": 1,\n}\n\nAUTHENTICATION_BACKENDS = [\n    \"concordia.authentication_backends.EmailOrUsernameModelBackend\"\n]\n\nCAPTCHA_CHALLENGE_FUNCT = \"captcha.helpers.random_char_challenge\"\n#: Anonymous sessions require captcha validation every day by default:\nANONYMOUS_CAPTCHA_VALIDATION_INTERVAL = 86400\n\nSTATICFILES_STORAGE = \"whitenoise.storage.CompressedManifestStaticFilesStorage\"\nWHITENOISE_ROOT = os.path.join(SITE_ROOT_DIR, \"static\")\n\nPASSWORD_RESET_TIMEOUT_DAYS = 2\nACCOUNT_ACTIVATION_DAYS = 2\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_BACKEND_DSN = os.environ.get(\"SENTRY_BACKEND_DSN\", \"\")\nSENTRY_FRONTEND_DSN = os.environ.get(\"SENTRY_FRONTEND_DSN\", \"\")\n\nRAVEN_CONFIG = {\n    \"dsn\": SENTRY_BACKEND_DSN,\n    \"environment\": CONCORDIA_ENVIRONMENT,\n    \"release\": raven.fetch_git_sha(SITE_ROOT_DIR),\n}\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\n# Names of special django.auth Groups\nCOMMUNITY_MANAGER_GROUP_NAME = \"Community Managers\"\nNEWSLETTER_GROUP_NAME = \"Newsletter\"\n\n# Django sites framework setting\nSITE_ID = 1\nROBOTS_USE_SITEMAP = False\nROBOTS_USE_HOST = False\n\n# django-bootstrap4 customization:\nBOOTSTRAP4 = {\"required_css_class\": \"form-group-required\"}\n\n# Transcription-related settings\n\n#: Number of seconds an asset reservation is valid for\nTRANSCRIPTION_RESERVATION_SECONDS = 5 * 60\n\n#: Web cache policy settings\nDEFAULT_PAGE_TTL = 5 * 60\n\n# Feature flag for social share\nFLAGS = {\"SOCIAL_SHARE\": [], \"NEW_CAROUSEL_SLIDE\": []}\n", "path": "concordia/settings_template.py"}]}