We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Pagination and filtering don't work together
**What behavior did you observe? Please describe the bug**
The filter became unset and went to all images.

**How can we reproduce the bug?**
Steps to reproduce the behavior:
1. Go to an item that has several assets in open and submitted states.
2. Use the filter to only view submitted for review assets.
3. Scroll down and click page 2.

**What is the expected behavior?**
When I click page 2, the filter should be maintained.


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

{"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@@ -78,6 +78,7 @@\n     \"raven.contrib.django.raven_compat\",\n     \"maintenance_mode\",\n     \"bootstrap4\",\n+    \"bittersweet\",\n     \"concordia.apps.ConcordiaAppConfig\",\n     \"exporter\",\n     \"importer\",\n", "issue": "Pagination and filtering don't work together\n**What behavior did you observe? Please describe the bug**\r\nThe filter became unset and went to all images.\r\n\r\n**How can we reproduce the bug?**\r\nSteps to reproduce the behavior:\r\n1. Go to an item that has several assets in open and submitted states.\r\n2. Use the filter to only view submitted for review assets.\r\n3. Scroll down and click page 2.\r\n\r\n**What is the expected behavior?**\r\nWhen I click page 2, the filter should be maintained.\r\n\n", "before_files": [{"content": "# TODO: use correct copyright header\nimport os\n\nfrom django.contrib import messages\nfrom dotenv import load_dotenv\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# Build path for and load .env file.\ndotenv_path = os.path.join(SITE_ROOT_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\nAUTH_PASSWORD_VALIDATORS = []\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\n# EMAIL_FILE_PATH = os.path.join(SITE_ROOT_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(CONCORDIA_APP_DIR, \"static\"),\n    os.path.join(\"/\".join(CONCORDIA_APP_DIR.split(\"/\")[:-1]), \"concordia/static\"),\n]\nSTATICFILES_DIRS = [os.path.join(CONCORDIA_APP_DIR, \"static\")]\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\": os.getenv(\"POSTGRESQL_PW\"),\n        \"HOST\": os.getenv(\"POSTGRESQL_HOST\", \"localhost\"),\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.sites\",\n    \"django.contrib.staticfiles\",\n    \"raven.contrib.django.raven_compat\",\n    \"maintenance_mode\",\n    \"bootstrap4\",\n    \"concordia.apps.ConcordiaAppConfig\",\n    \"exporter\",\n    \"importer\",\n    \"captcha\",\n    \"django_prometheus_metrics\",\n    \"robots\",\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]\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\nCACHES = {\"default\": {\"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\"}}\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(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\nACCOUNT_ACTIVATION_DAYS = 7\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.complexity\"},\n]\n\nAUTHENTICATION_BACKENDS = [\n    \"concordia.email_username_backend.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 = 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\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# 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", "path": "concordia/settings_template.py"}], "after_files": [{"content": "# TODO: use correct copyright header\nimport os\n\nfrom django.contrib import messages\nfrom dotenv import load_dotenv\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# Build path for and load .env file.\ndotenv_path = os.path.join(SITE_ROOT_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\nAUTH_PASSWORD_VALIDATORS = []\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\n# EMAIL_FILE_PATH = os.path.join(SITE_ROOT_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(CONCORDIA_APP_DIR, \"static\"),\n    os.path.join(\"/\".join(CONCORDIA_APP_DIR.split(\"/\")[:-1]), \"concordia/static\"),\n]\nSTATICFILES_DIRS = [os.path.join(CONCORDIA_APP_DIR, \"static\")]\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\": os.getenv(\"POSTGRESQL_PW\"),\n        \"HOST\": os.getenv(\"POSTGRESQL_HOST\", \"localhost\"),\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.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]\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]\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\nCACHES = {\"default\": {\"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\"}}\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(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\nACCOUNT_ACTIVATION_DAYS = 7\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.complexity\"},\n]\n\nAUTHENTICATION_BACKENDS = [\n    \"concordia.email_username_backend.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 = 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\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# 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", "path": "concordia/settings_template.py"}]}