We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Let admins set default interface language
Right now, BookWyrm's interface language is determined by, in order of preference:
1. The language selected in the user's settings
2. The language requested by the browser, if it's available in the app
3. English

Admin should be able to set the default display language of the interface for logged out viewers and users that don't have a preference saved.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bookwyrm/settings.py`
Content:
```
1 """ bookwyrm settings and configuration """
2 import os
3 from environs import Env
4 
5 import requests
6 from django.utils.translation import gettext_lazy as _
7 
8 
9 env = Env()
10 env.read_env()
11 DOMAIN = env("DOMAIN")
12 VERSION = "0.2.0"
13 
14 PAGE_LENGTH = env("PAGE_LENGTH", 15)
15 DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English")
16 
17 JS_CACHE = "76c5ff1f"
18 
19 # email
20 EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
21 EMAIL_HOST = env("EMAIL_HOST")
22 EMAIL_PORT = env("EMAIL_PORT", 587)
23 EMAIL_HOST_USER = env("EMAIL_HOST_USER")
24 EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD")
25 EMAIL_USE_TLS = env.bool("EMAIL_USE_TLS", True)
26 EMAIL_USE_SSL = env.bool("EMAIL_USE_SSL", False)
27 EMAIL_SENDER_NAME = env("EMAIL_SENDER_NAME", "admin")
28 EMAIL_SENDER_DOMAIN = env("EMAIL_SENDER_DOMAIN", DOMAIN)
29 EMAIL_SENDER = f"{EMAIL_SENDER_NAME}@{EMAIL_SENDER_DOMAIN}"
30 
31 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
32 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
33 LOCALE_PATHS = [
34     os.path.join(BASE_DIR, "locale"),
35 ]
36 LANGUAGE_COOKIE_NAME = env.str("LANGUAGE_COOKIE_NAME", "django_language")
37 
38 DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
39 
40 # Preview image
41 ENABLE_PREVIEW_IMAGES = env.bool("ENABLE_PREVIEW_IMAGES", False)
42 PREVIEW_BG_COLOR = env.str("PREVIEW_BG_COLOR", "use_dominant_color_light")
43 PREVIEW_TEXT_COLOR = env.str("PREVIEW_TEXT_COLOR", "#363636")
44 PREVIEW_IMG_WIDTH = env.int("PREVIEW_IMG_WIDTH", 1200)
45 PREVIEW_IMG_HEIGHT = env.int("PREVIEW_IMG_HEIGHT", 630)
46 PREVIEW_DEFAULT_COVER_COLOR = env.str("PREVIEW_DEFAULT_COVER_COLOR", "#002549")
47 
48 # Quick-start development settings - unsuitable for production
49 # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
50 
51 # SECURITY WARNING: keep the secret key used in production secret!
52 SECRET_KEY = env("SECRET_KEY")
53 
54 # SECURITY WARNING: don't run with debug turned on in production!
55 DEBUG = env.bool("DEBUG", True)
56 USE_HTTPS = env.bool("USE_HTTPS", False)
57 
58 ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", ["*"])
59 
60 # Application definition
61 
62 INSTALLED_APPS = [
63     "django.contrib.admin",
64     "django.contrib.auth",
65     "django.contrib.contenttypes",
66     "django.contrib.sessions",
67     "django.contrib.messages",
68     "django.contrib.staticfiles",
69     "django.contrib.humanize",
70     "django_rename_app",
71     "bookwyrm",
72     "celery",
73     "imagekit",
74     "storages",
75 ]
76 
77 MIDDLEWARE = [
78     "django.middleware.security.SecurityMiddleware",
79     "django.contrib.sessions.middleware.SessionMiddleware",
80     "django.middleware.locale.LocaleMiddleware",
81     "django.middleware.common.CommonMiddleware",
82     "django.middleware.csrf.CsrfViewMiddleware",
83     "django.contrib.auth.middleware.AuthenticationMiddleware",
84     "bookwyrm.middleware.TimezoneMiddleware",
85     "bookwyrm.middleware.IPBlocklistMiddleware",
86     "django.contrib.messages.middleware.MessageMiddleware",
87     "django.middleware.clickjacking.XFrameOptionsMiddleware",
88 ]
89 
90 ROOT_URLCONF = "bookwyrm.urls"
91 
92 TEMPLATES = [
93     {
94         "BACKEND": "django.template.backends.django.DjangoTemplates",
95         "DIRS": ["templates"],
96         "APP_DIRS": True,
97         "OPTIONS": {
98             "context_processors": [
99                 "django.template.context_processors.debug",
100                 "django.template.context_processors.request",
101                 "django.contrib.auth.context_processors.auth",
102                 "django.contrib.messages.context_processors.messages",
103                 "bookwyrm.context_processors.site_settings",
104             ],
105         },
106     },
107 ]
108 
109 LOG_LEVEL = env("LOG_LEVEL", "INFO").upper()
110 # Override aspects of the default handler to our taste
111 # See https://docs.djangoproject.com/en/3.2/topics/logging/#default-logging-configuration
112 # for a reference to the defaults we're overriding
113 #
114 # It seems that in order to override anything you have to include its
115 # entire dependency tree (handlers and filters) which makes this a
116 # bit verbose
117 LOGGING = {
118     "version": 1,
119     "disable_existing_loggers": False,
120     "filters": {
121         # These are copied from the default configuration, required for
122         # implementing mail_admins below
123         "require_debug_false": {
124             "()": "django.utils.log.RequireDebugFalse",
125         },
126         "require_debug_true": {
127             "()": "django.utils.log.RequireDebugTrue",
128         },
129     },
130     "handlers": {
131         # Overrides the default handler to make it log to console
132         # regardless of the DEBUG setting (default is to not log to
133         # console if DEBUG=False)
134         "console": {
135             "level": LOG_LEVEL,
136             "class": "logging.StreamHandler",
137         },
138         # This is copied as-is from the default logger, and is
139         # required for the django section below
140         "mail_admins": {
141             "level": "ERROR",
142             "filters": ["require_debug_false"],
143             "class": "django.utils.log.AdminEmailHandler",
144         },
145     },
146     "loggers": {
147         # Install our new console handler for Django's logger, and
148         # override the log level while we're at it
149         "django": {
150             "handlers": ["console", "mail_admins"],
151             "level": LOG_LEVEL,
152         },
153         # Add a bookwyrm-specific logger
154         "bookwyrm": {
155             "handlers": ["console"],
156             "level": LOG_LEVEL,
157         },
158     },
159 }
160 
161 
162 WSGI_APPLICATION = "bookwyrm.wsgi.application"
163 
164 # redis/activity streams settings
165 REDIS_ACTIVITY_HOST = env("REDIS_ACTIVITY_HOST", "localhost")
166 REDIS_ACTIVITY_PORT = env("REDIS_ACTIVITY_PORT", 6379)
167 REDIS_ACTIVITY_PASSWORD = env("REDIS_ACTIVITY_PASSWORD", None)
168 REDIS_ACTIVITY_DB_INDEX = env("REDIS_ACTIVITY_DB_INDEX", 0)
169 
170 MAX_STREAM_LENGTH = int(env("MAX_STREAM_LENGTH", 200))
171 
172 STREAMS = [
173     {"key": "home", "name": _("Home Timeline"), "shortname": _("Home")},
174     {"key": "books", "name": _("Books Timeline"), "shortname": _("Books")},
175 ]
176 
177 # Search configuration
178 # total time in seconds that the instance will spend searching connectors
179 SEARCH_TIMEOUT = int(env("SEARCH_TIMEOUT", 15))
180 # timeout for a query to an individual connector
181 QUERY_TIMEOUT = int(env("QUERY_TIMEOUT", 5))
182 
183 # Redis cache backend
184 if env("USE_DUMMY_CACHE", False):
185     CACHES = {
186         "default": {
187             "BACKEND": "django.core.cache.backends.dummy.DummyCache",
188         }
189     }
190 else:
191     # pylint: disable=line-too-long
192     CACHES = {
193         "default": {
194             "BACKEND": "django_redis.cache.RedisCache",
195             "LOCATION": f"redis://:{REDIS_ACTIVITY_PASSWORD}@{REDIS_ACTIVITY_HOST}:{REDIS_ACTIVITY_PORT}/{REDIS_ACTIVITY_DB_INDEX}",
196             "OPTIONS": {
197                 "CLIENT_CLASS": "django_redis.client.DefaultClient",
198             },
199         }
200     }
201 
202     SESSION_ENGINE = "django.contrib.sessions.backends.cache"
203     SESSION_CACHE_ALIAS = "default"
204 
205 # Database
206 # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
207 
208 DATABASES = {
209     "default": {
210         "ENGINE": "django.db.backends.postgresql_psycopg2",
211         "NAME": env("POSTGRES_DB", "bookwyrm"),
212         "USER": env("POSTGRES_USER", "bookwyrm"),
213         "PASSWORD": env("POSTGRES_PASSWORD", "bookwyrm"),
214         "HOST": env("POSTGRES_HOST", ""),
215         "PORT": env("PGPORT", 5432),
216     },
217 }
218 
219 
220 LOGIN_URL = "/login/"
221 AUTH_USER_MODEL = "bookwyrm.User"
222 
223 # Password validation
224 # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
225 
226 # pylint: disable=line-too-long
227 AUTH_PASSWORD_VALIDATORS = [
228     {
229         "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
230     },
231     {
232         "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
233     },
234     {
235         "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
236     },
237     {
238         "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
239     },
240 ]
241 
242 
243 # Internationalization
244 # https://docs.djangoproject.com/en/3.2/topics/i18n/
245 
246 LANGUAGE_CODE = "en-us"
247 LANGUAGES = [
248     ("en-us", _("English")),
249     ("de-de", _("Deutsch (German)")),
250     ("es-es", _("Español (Spanish)")),
251     ("gl-es", _("Galego (Galician)")),
252     ("it-it", _("Italiano (Italian)")),
253     ("fr-fr", _("Français (French)")),
254     ("lt-lt", _("Lietuvių (Lithuanian)")),
255     ("no-no", _("Norsk (Norwegian)")),
256     ("pt-br", _("Português do Brasil (Brazilian Portuguese)")),
257     ("pt-pt", _("Português Europeu (European Portuguese)")),
258     ("zh-hans", _("简体中文 (Simplified Chinese)")),
259     ("zh-hant", _("繁體中文 (Traditional Chinese)")),
260 ]
261 
262 
263 TIME_ZONE = "UTC"
264 
265 USE_I18N = True
266 
267 USE_L10N = True
268 
269 USE_TZ = True
270 
271 
272 agent = requests.utils.default_user_agent()
273 USER_AGENT = f"{agent} (BookWyrm/{VERSION}; +https://{DOMAIN}/)"
274 
275 # Imagekit generated thumbnails
276 ENABLE_THUMBNAIL_GENERATION = env.bool("ENABLE_THUMBNAIL_GENERATION", False)
277 IMAGEKIT_CACHEFILE_DIR = "thumbnails"
278 IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = "bookwyrm.thumbnail_generation.Strategy"
279 
280 # Static files (CSS, JavaScript, Images)
281 # https://docs.djangoproject.com/en/3.2/howto/static-files/
282 
283 PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
284 
285 # Storage
286 
287 PROTOCOL = "http"
288 if USE_HTTPS:
289     PROTOCOL = "https"
290 
291 USE_S3 = env.bool("USE_S3", False)
292 
293 if USE_S3:
294     # AWS settings
295     AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID")
296     AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY")
297     AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME")
298     AWS_S3_CUSTOM_DOMAIN = env("AWS_S3_CUSTOM_DOMAIN")
299     AWS_S3_REGION_NAME = env("AWS_S3_REGION_NAME", "")
300     AWS_S3_ENDPOINT_URL = env("AWS_S3_ENDPOINT_URL")
301     AWS_DEFAULT_ACL = "public-read"
302     AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"}
303     # S3 Static settings
304     STATIC_LOCATION = "static"
305     STATIC_URL = f"{PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{STATIC_LOCATION}/"
306     STATICFILES_STORAGE = "bookwyrm.storage_backends.StaticStorage"
307     # S3 Media settings
308     MEDIA_LOCATION = "images"
309     MEDIA_URL = f"{PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{MEDIA_LOCATION}/"
310     MEDIA_FULL_URL = MEDIA_URL
311     STATIC_FULL_URL = STATIC_URL
312     DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.ImagesStorage"
313     # I don't know if it's used, but the site crashes without it
314     STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static"))
315     MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images"))
316 else:
317     STATIC_URL = "/static/"
318     STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static"))
319     MEDIA_URL = "/images/"
320     MEDIA_FULL_URL = f"{PROTOCOL}://{DOMAIN}{MEDIA_URL}"
321     STATIC_FULL_URL = f"{PROTOCOL}://{DOMAIN}{STATIC_URL}"
322     MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images"))
323
```
--- 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/bookwyrm/settings.py b/bookwyrm/settings.py
--- a/bookwyrm/settings.py
+++ b/bookwyrm/settings.py
@@ -243,7 +243,7 @@
 # Internationalization
 # https://docs.djangoproject.com/en/3.2/topics/i18n/
 
-LANGUAGE_CODE = "en-us"
+LANGUAGE_CODE = env("LANGUAGE_CODE", "en-us")
 LANGUAGES = [
     ("en-us", _("English")),
     ("de-de", _("Deutsch (German)")),

{"golden_diff": "diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py\n--- a/bookwyrm/settings.py\n+++ b/bookwyrm/settings.py\n@@ -243,7 +243,7 @@\n # Internationalization\n # https://docs.djangoproject.com/en/3.2/topics/i18n/\n \n-LANGUAGE_CODE = \"en-us\"\n+LANGUAGE_CODE = env(\"LANGUAGE_CODE\", \"en-us\")\n LANGUAGES = [\n     (\"en-us\", _(\"English\")),\n     (\"de-de\", _(\"Deutsch (German)\")),\n", "issue": "Let admins set default interface language\nRight now, BookWyrm's interface language is determined by, in order of preference:\r\n1. The language selected in the user's settings\r\n2. The language requested by the browser, if it's available in the app\r\n3. English\r\n\r\nAdmin should be able to set the default display language of the interface for logged out viewers and users that don't have a preference saved.\n", "before_files": [{"content": "\"\"\" bookwyrm settings and configuration \"\"\"\nimport os\nfrom environs import Env\n\nimport requests\nfrom django.utils.translation import gettext_lazy as _\n\n\nenv = Env()\nenv.read_env()\nDOMAIN = env(\"DOMAIN\")\nVERSION = \"0.2.0\"\n\nPAGE_LENGTH = env(\"PAGE_LENGTH\", 15)\nDEFAULT_LANGUAGE = env(\"DEFAULT_LANGUAGE\", \"English\")\n\nJS_CACHE = \"76c5ff1f\"\n\n# email\nEMAIL_BACKEND = env(\"EMAIL_BACKEND\", \"django.core.mail.backends.smtp.EmailBackend\")\nEMAIL_HOST = env(\"EMAIL_HOST\")\nEMAIL_PORT = env(\"EMAIL_PORT\", 587)\nEMAIL_HOST_USER = env(\"EMAIL_HOST_USER\")\nEMAIL_HOST_PASSWORD = env(\"EMAIL_HOST_PASSWORD\")\nEMAIL_USE_TLS = env.bool(\"EMAIL_USE_TLS\", True)\nEMAIL_USE_SSL = env.bool(\"EMAIL_USE_SSL\", False)\nEMAIL_SENDER_NAME = env(\"EMAIL_SENDER_NAME\", \"admin\")\nEMAIL_SENDER_DOMAIN = env(\"EMAIL_SENDER_DOMAIN\", DOMAIN)\nEMAIL_SENDER = f\"{EMAIL_SENDER_NAME}@{EMAIL_SENDER_DOMAIN}\"\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\nLOCALE_PATHS = [\n    os.path.join(BASE_DIR, \"locale\"),\n]\nLANGUAGE_COOKIE_NAME = env.str(\"LANGUAGE_COOKIE_NAME\", \"django_language\")\n\nDEFAULT_AUTO_FIELD = \"django.db.models.AutoField\"\n\n# Preview image\nENABLE_PREVIEW_IMAGES = env.bool(\"ENABLE_PREVIEW_IMAGES\", False)\nPREVIEW_BG_COLOR = env.str(\"PREVIEW_BG_COLOR\", \"use_dominant_color_light\")\nPREVIEW_TEXT_COLOR = env.str(\"PREVIEW_TEXT_COLOR\", \"#363636\")\nPREVIEW_IMG_WIDTH = env.int(\"PREVIEW_IMG_WIDTH\", 1200)\nPREVIEW_IMG_HEIGHT = env.int(\"PREVIEW_IMG_HEIGHT\", 630)\nPREVIEW_DEFAULT_COVER_COLOR = env.str(\"PREVIEW_DEFAULT_COVER_COLOR\", \"#002549\")\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = env(\"SECRET_KEY\")\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = env.bool(\"DEBUG\", True)\nUSE_HTTPS = env.bool(\"USE_HTTPS\", False)\n\nALLOWED_HOSTS = env.list(\"ALLOWED_HOSTS\", [\"*\"])\n\n# Application definition\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"django.contrib.humanize\",\n    \"django_rename_app\",\n    \"bookwyrm\",\n    \"celery\",\n    \"imagekit\",\n    \"storages\",\n]\n\nMIDDLEWARE = [\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"django.middleware.locale.LocaleMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"bookwyrm.middleware.TimezoneMiddleware\",\n    \"bookwyrm.middleware.IPBlocklistMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n]\n\nROOT_URLCONF = \"bookwyrm.urls\"\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [\"templates\"],\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                \"bookwyrm.context_processors.site_settings\",\n            ],\n        },\n    },\n]\n\nLOG_LEVEL = env(\"LOG_LEVEL\", \"INFO\").upper()\n# Override aspects of the default handler to our taste\n# See https://docs.djangoproject.com/en/3.2/topics/logging/#default-logging-configuration\n# for a reference to the defaults we're overriding\n#\n# It seems that in order to override anything you have to include its\n# entire dependency tree (handlers and filters) which makes this a\n# bit verbose\nLOGGING = {\n    \"version\": 1,\n    \"disable_existing_loggers\": False,\n    \"filters\": {\n        # These are copied from the default configuration, required for\n        # implementing mail_admins below\n        \"require_debug_false\": {\n            \"()\": \"django.utils.log.RequireDebugFalse\",\n        },\n        \"require_debug_true\": {\n            \"()\": \"django.utils.log.RequireDebugTrue\",\n        },\n    },\n    \"handlers\": {\n        # Overrides the default handler to make it log to console\n        # regardless of the DEBUG setting (default is to not log to\n        # console if DEBUG=False)\n        \"console\": {\n            \"level\": LOG_LEVEL,\n            \"class\": \"logging.StreamHandler\",\n        },\n        # This is copied as-is from the default logger, and is\n        # required for the django section below\n        \"mail_admins\": {\n            \"level\": \"ERROR\",\n            \"filters\": [\"require_debug_false\"],\n            \"class\": \"django.utils.log.AdminEmailHandler\",\n        },\n    },\n    \"loggers\": {\n        # Install our new console handler for Django's logger, and\n        # override the log level while we're at it\n        \"django\": {\n            \"handlers\": [\"console\", \"mail_admins\"],\n            \"level\": LOG_LEVEL,\n        },\n        # Add a bookwyrm-specific logger\n        \"bookwyrm\": {\n            \"handlers\": [\"console\"],\n            \"level\": LOG_LEVEL,\n        },\n    },\n}\n\n\nWSGI_APPLICATION = \"bookwyrm.wsgi.application\"\n\n# redis/activity streams settings\nREDIS_ACTIVITY_HOST = env(\"REDIS_ACTIVITY_HOST\", \"localhost\")\nREDIS_ACTIVITY_PORT = env(\"REDIS_ACTIVITY_PORT\", 6379)\nREDIS_ACTIVITY_PASSWORD = env(\"REDIS_ACTIVITY_PASSWORD\", None)\nREDIS_ACTIVITY_DB_INDEX = env(\"REDIS_ACTIVITY_DB_INDEX\", 0)\n\nMAX_STREAM_LENGTH = int(env(\"MAX_STREAM_LENGTH\", 200))\n\nSTREAMS = [\n    {\"key\": \"home\", \"name\": _(\"Home Timeline\"), \"shortname\": _(\"Home\")},\n    {\"key\": \"books\", \"name\": _(\"Books Timeline\"), \"shortname\": _(\"Books\")},\n]\n\n# Search configuration\n# total time in seconds that the instance will spend searching connectors\nSEARCH_TIMEOUT = int(env(\"SEARCH_TIMEOUT\", 15))\n# timeout for a query to an individual connector\nQUERY_TIMEOUT = int(env(\"QUERY_TIMEOUT\", 5))\n\n# Redis cache backend\nif env(\"USE_DUMMY_CACHE\", False):\n    CACHES = {\n        \"default\": {\n            \"BACKEND\": \"django.core.cache.backends.dummy.DummyCache\",\n        }\n    }\nelse:\n    # pylint: disable=line-too-long\n    CACHES = {\n        \"default\": {\n            \"BACKEND\": \"django_redis.cache.RedisCache\",\n            \"LOCATION\": f\"redis://:{REDIS_ACTIVITY_PASSWORD}@{REDIS_ACTIVITY_HOST}:{REDIS_ACTIVITY_PORT}/{REDIS_ACTIVITY_DB_INDEX}\",\n            \"OPTIONS\": {\n                \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n            },\n        }\n    }\n\n    SESSION_ENGINE = \"django.contrib.sessions.backends.cache\"\n    SESSION_CACHE_ALIAS = \"default\"\n\n# Database\n# https://docs.djangoproject.com/en/3.2/ref/settings/#databases\n\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql_psycopg2\",\n        \"NAME\": env(\"POSTGRES_DB\", \"bookwyrm\"),\n        \"USER\": env(\"POSTGRES_USER\", \"bookwyrm\"),\n        \"PASSWORD\": env(\"POSTGRES_PASSWORD\", \"bookwyrm\"),\n        \"HOST\": env(\"POSTGRES_HOST\", \"\"),\n        \"PORT\": env(\"PGPORT\", 5432),\n    },\n}\n\n\nLOGIN_URL = \"/login/\"\nAUTH_USER_MODEL = \"bookwyrm.User\"\n\n# Password validation\n# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators\n\n# pylint: disable=line-too-long\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\",\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/3.2/topics/i18n/\n\nLANGUAGE_CODE = \"en-us\"\nLANGUAGES = [\n    (\"en-us\", _(\"English\")),\n    (\"de-de\", _(\"Deutsch (German)\")),\n    (\"es-es\", _(\"Espa\u00f1ol (Spanish)\")),\n    (\"gl-es\", _(\"Galego (Galician)\")),\n    (\"it-it\", _(\"Italiano (Italian)\")),\n    (\"fr-fr\", _(\"Fran\u00e7ais (French)\")),\n    (\"lt-lt\", _(\"Lietuvi\u0173 (Lithuanian)\")),\n    (\"no-no\", _(\"Norsk (Norwegian)\")),\n    (\"pt-br\", _(\"Portugu\u00eas do Brasil (Brazilian Portuguese)\")),\n    (\"pt-pt\", _(\"Portugu\u00eas Europeu (European Portuguese)\")),\n    (\"zh-hans\", _(\"\u7b80\u4f53\u4e2d\u6587 (Simplified Chinese)\")),\n    (\"zh-hant\", _(\"\u7e41\u9ad4\u4e2d\u6587 (Traditional Chinese)\")),\n]\n\n\nTIME_ZONE = \"UTC\"\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\nagent = requests.utils.default_user_agent()\nUSER_AGENT = f\"{agent} (BookWyrm/{VERSION}; +https://{DOMAIN}/)\"\n\n# Imagekit generated thumbnails\nENABLE_THUMBNAIL_GENERATION = env.bool(\"ENABLE_THUMBNAIL_GENERATION\", False)\nIMAGEKIT_CACHEFILE_DIR = \"thumbnails\"\nIMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = \"bookwyrm.thumbnail_generation.Strategy\"\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/3.2/howto/static-files/\n\nPROJECT_DIR = os.path.dirname(os.path.abspath(__file__))\n\n# Storage\n\nPROTOCOL = \"http\"\nif USE_HTTPS:\n    PROTOCOL = \"https\"\n\nUSE_S3 = env.bool(\"USE_S3\", False)\n\nif USE_S3:\n    # AWS settings\n    AWS_ACCESS_KEY_ID = env(\"AWS_ACCESS_KEY_ID\")\n    AWS_SECRET_ACCESS_KEY = env(\"AWS_SECRET_ACCESS_KEY\")\n    AWS_STORAGE_BUCKET_NAME = env(\"AWS_STORAGE_BUCKET_NAME\")\n    AWS_S3_CUSTOM_DOMAIN = env(\"AWS_S3_CUSTOM_DOMAIN\")\n    AWS_S3_REGION_NAME = env(\"AWS_S3_REGION_NAME\", \"\")\n    AWS_S3_ENDPOINT_URL = env(\"AWS_S3_ENDPOINT_URL\")\n    AWS_DEFAULT_ACL = \"public-read\"\n    AWS_S3_OBJECT_PARAMETERS = {\"CacheControl\": \"max-age=86400\"}\n    # S3 Static settings\n    STATIC_LOCATION = \"static\"\n    STATIC_URL = f\"{PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{STATIC_LOCATION}/\"\n    STATICFILES_STORAGE = \"bookwyrm.storage_backends.StaticStorage\"\n    # S3 Media settings\n    MEDIA_LOCATION = \"images\"\n    MEDIA_URL = f\"{PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{MEDIA_LOCATION}/\"\n    MEDIA_FULL_URL = MEDIA_URL\n    STATIC_FULL_URL = STATIC_URL\n    DEFAULT_FILE_STORAGE = \"bookwyrm.storage_backends.ImagesStorage\"\n    # I don't know if it's used, but the site crashes without it\n    STATIC_ROOT = os.path.join(BASE_DIR, env(\"STATIC_ROOT\", \"static\"))\n    MEDIA_ROOT = os.path.join(BASE_DIR, env(\"MEDIA_ROOT\", \"images\"))\nelse:\n    STATIC_URL = \"/static/\"\n    STATIC_ROOT = os.path.join(BASE_DIR, env(\"STATIC_ROOT\", \"static\"))\n    MEDIA_URL = \"/images/\"\n    MEDIA_FULL_URL = f\"{PROTOCOL}://{DOMAIN}{MEDIA_URL}\"\n    STATIC_FULL_URL = f\"{PROTOCOL}://{DOMAIN}{STATIC_URL}\"\n    MEDIA_ROOT = os.path.join(BASE_DIR, env(\"MEDIA_ROOT\", \"images\"))\n", "path": "bookwyrm/settings.py"}], "after_files": [{"content": "\"\"\" bookwyrm settings and configuration \"\"\"\nimport os\nfrom environs import Env\n\nimport requests\nfrom django.utils.translation import gettext_lazy as _\n\n\nenv = Env()\nenv.read_env()\nDOMAIN = env(\"DOMAIN\")\nVERSION = \"0.2.0\"\n\nPAGE_LENGTH = env(\"PAGE_LENGTH\", 15)\nDEFAULT_LANGUAGE = env(\"DEFAULT_LANGUAGE\", \"English\")\n\nJS_CACHE = \"76c5ff1f\"\n\n# email\nEMAIL_BACKEND = env(\"EMAIL_BACKEND\", \"django.core.mail.backends.smtp.EmailBackend\")\nEMAIL_HOST = env(\"EMAIL_HOST\")\nEMAIL_PORT = env(\"EMAIL_PORT\", 587)\nEMAIL_HOST_USER = env(\"EMAIL_HOST_USER\")\nEMAIL_HOST_PASSWORD = env(\"EMAIL_HOST_PASSWORD\")\nEMAIL_USE_TLS = env.bool(\"EMAIL_USE_TLS\", True)\nEMAIL_USE_SSL = env.bool(\"EMAIL_USE_SSL\", False)\nEMAIL_SENDER_NAME = env(\"EMAIL_SENDER_NAME\", \"admin\")\nEMAIL_SENDER_DOMAIN = env(\"EMAIL_SENDER_DOMAIN\", DOMAIN)\nEMAIL_SENDER = f\"{EMAIL_SENDER_NAME}@{EMAIL_SENDER_DOMAIN}\"\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\nLOCALE_PATHS = [\n    os.path.join(BASE_DIR, \"locale\"),\n]\nLANGUAGE_COOKIE_NAME = env.str(\"LANGUAGE_COOKIE_NAME\", \"django_language\")\n\nDEFAULT_AUTO_FIELD = \"django.db.models.AutoField\"\n\n# Preview image\nENABLE_PREVIEW_IMAGES = env.bool(\"ENABLE_PREVIEW_IMAGES\", False)\nPREVIEW_BG_COLOR = env.str(\"PREVIEW_BG_COLOR\", \"use_dominant_color_light\")\nPREVIEW_TEXT_COLOR = env.str(\"PREVIEW_TEXT_COLOR\", \"#363636\")\nPREVIEW_IMG_WIDTH = env.int(\"PREVIEW_IMG_WIDTH\", 1200)\nPREVIEW_IMG_HEIGHT = env.int(\"PREVIEW_IMG_HEIGHT\", 630)\nPREVIEW_DEFAULT_COVER_COLOR = env.str(\"PREVIEW_DEFAULT_COVER_COLOR\", \"#002549\")\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = env(\"SECRET_KEY\")\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = env.bool(\"DEBUG\", True)\nUSE_HTTPS = env.bool(\"USE_HTTPS\", False)\n\nALLOWED_HOSTS = env.list(\"ALLOWED_HOSTS\", [\"*\"])\n\n# Application definition\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"django.contrib.humanize\",\n    \"django_rename_app\",\n    \"bookwyrm\",\n    \"celery\",\n    \"imagekit\",\n    \"storages\",\n]\n\nMIDDLEWARE = [\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"django.middleware.locale.LocaleMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"bookwyrm.middleware.TimezoneMiddleware\",\n    \"bookwyrm.middleware.IPBlocklistMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n]\n\nROOT_URLCONF = \"bookwyrm.urls\"\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [\"templates\"],\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                \"bookwyrm.context_processors.site_settings\",\n            ],\n        },\n    },\n]\n\nLOG_LEVEL = env(\"LOG_LEVEL\", \"INFO\").upper()\n# Override aspects of the default handler to our taste\n# See https://docs.djangoproject.com/en/3.2/topics/logging/#default-logging-configuration\n# for a reference to the defaults we're overriding\n#\n# It seems that in order to override anything you have to include its\n# entire dependency tree (handlers and filters) which makes this a\n# bit verbose\nLOGGING = {\n    \"version\": 1,\n    \"disable_existing_loggers\": False,\n    \"filters\": {\n        # These are copied from the default configuration, required for\n        # implementing mail_admins below\n        \"require_debug_false\": {\n            \"()\": \"django.utils.log.RequireDebugFalse\",\n        },\n        \"require_debug_true\": {\n            \"()\": \"django.utils.log.RequireDebugTrue\",\n        },\n    },\n    \"handlers\": {\n        # Overrides the default handler to make it log to console\n        # regardless of the DEBUG setting (default is to not log to\n        # console if DEBUG=False)\n        \"console\": {\n            \"level\": LOG_LEVEL,\n            \"class\": \"logging.StreamHandler\",\n        },\n        # This is copied as-is from the default logger, and is\n        # required for the django section below\n        \"mail_admins\": {\n            \"level\": \"ERROR\",\n            \"filters\": [\"require_debug_false\"],\n            \"class\": \"django.utils.log.AdminEmailHandler\",\n        },\n    },\n    \"loggers\": {\n        # Install our new console handler for Django's logger, and\n        # override the log level while we're at it\n        \"django\": {\n            \"handlers\": [\"console\", \"mail_admins\"],\n            \"level\": LOG_LEVEL,\n        },\n        # Add a bookwyrm-specific logger\n        \"bookwyrm\": {\n            \"handlers\": [\"console\"],\n            \"level\": LOG_LEVEL,\n        },\n    },\n}\n\n\nWSGI_APPLICATION = \"bookwyrm.wsgi.application\"\n\n# redis/activity streams settings\nREDIS_ACTIVITY_HOST = env(\"REDIS_ACTIVITY_HOST\", \"localhost\")\nREDIS_ACTIVITY_PORT = env(\"REDIS_ACTIVITY_PORT\", 6379)\nREDIS_ACTIVITY_PASSWORD = env(\"REDIS_ACTIVITY_PASSWORD\", None)\nREDIS_ACTIVITY_DB_INDEX = env(\"REDIS_ACTIVITY_DB_INDEX\", 0)\n\nMAX_STREAM_LENGTH = int(env(\"MAX_STREAM_LENGTH\", 200))\n\nSTREAMS = [\n    {\"key\": \"home\", \"name\": _(\"Home Timeline\"), \"shortname\": _(\"Home\")},\n    {\"key\": \"books\", \"name\": _(\"Books Timeline\"), \"shortname\": _(\"Books\")},\n]\n\n# Search configuration\n# total time in seconds that the instance will spend searching connectors\nSEARCH_TIMEOUT = int(env(\"SEARCH_TIMEOUT\", 15))\n# timeout for a query to an individual connector\nQUERY_TIMEOUT = int(env(\"QUERY_TIMEOUT\", 5))\n\n# Redis cache backend\nif env(\"USE_DUMMY_CACHE\", False):\n    CACHES = {\n        \"default\": {\n            \"BACKEND\": \"django.core.cache.backends.dummy.DummyCache\",\n        }\n    }\nelse:\n    # pylint: disable=line-too-long\n    CACHES = {\n        \"default\": {\n            \"BACKEND\": \"django_redis.cache.RedisCache\",\n            \"LOCATION\": f\"redis://:{REDIS_ACTIVITY_PASSWORD}@{REDIS_ACTIVITY_HOST}:{REDIS_ACTIVITY_PORT}/{REDIS_ACTIVITY_DB_INDEX}\",\n            \"OPTIONS\": {\n                \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n            },\n        }\n    }\n\n    SESSION_ENGINE = \"django.contrib.sessions.backends.cache\"\n    SESSION_CACHE_ALIAS = \"default\"\n\n# Database\n# https://docs.djangoproject.com/en/3.2/ref/settings/#databases\n\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql_psycopg2\",\n        \"NAME\": env(\"POSTGRES_DB\", \"bookwyrm\"),\n        \"USER\": env(\"POSTGRES_USER\", \"bookwyrm\"),\n        \"PASSWORD\": env(\"POSTGRES_PASSWORD\", \"bookwyrm\"),\n        \"HOST\": env(\"POSTGRES_HOST\", \"\"),\n        \"PORT\": env(\"PGPORT\", 5432),\n    },\n}\n\n\nLOGIN_URL = \"/login/\"\nAUTH_USER_MODEL = \"bookwyrm.User\"\n\n# Password validation\n# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators\n\n# pylint: disable=line-too-long\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\",\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/3.2/topics/i18n/\n\nLANGUAGE_CODE = env(\"LANGUAGE_CODE\", \"en-us\")\nLANGUAGES = [\n    (\"en-us\", _(\"English\")),\n    (\"de-de\", _(\"Deutsch (German)\")),\n    (\"es-es\", _(\"Espa\u00f1ol (Spanish)\")),\n    (\"gl-es\", _(\"Galego (Galician)\")),\n    (\"it-it\", _(\"Italiano (Italian)\")),\n    (\"fr-fr\", _(\"Fran\u00e7ais (French)\")),\n    (\"lt-lt\", _(\"Lietuvi\u0173 (Lithuanian)\")),\n    (\"no-no\", _(\"Norsk (Norwegian)\")),\n    (\"pt-br\", _(\"Portugu\u00eas do Brasil (Brazilian Portuguese)\")),\n    (\"pt-pt\", _(\"Portugu\u00eas Europeu (European Portuguese)\")),\n    (\"zh-hans\", _(\"\u7b80\u4f53\u4e2d\u6587 (Simplified Chinese)\")),\n    (\"zh-hant\", _(\"\u7e41\u9ad4\u4e2d\u6587 (Traditional Chinese)\")),\n]\n\n\nTIME_ZONE = \"UTC\"\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\nagent = requests.utils.default_user_agent()\nUSER_AGENT = f\"{agent} (BookWyrm/{VERSION}; +https://{DOMAIN}/)\"\n\n# Imagekit generated thumbnails\nENABLE_THUMBNAIL_GENERATION = env.bool(\"ENABLE_THUMBNAIL_GENERATION\", False)\nIMAGEKIT_CACHEFILE_DIR = \"thumbnails\"\nIMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = \"bookwyrm.thumbnail_generation.Strategy\"\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/3.2/howto/static-files/\n\nPROJECT_DIR = os.path.dirname(os.path.abspath(__file__))\n\n# Storage\n\nPROTOCOL = \"http\"\nif USE_HTTPS:\n    PROTOCOL = \"https\"\n\nUSE_S3 = env.bool(\"USE_S3\", False)\n\nif USE_S3:\n    # AWS settings\n    AWS_ACCESS_KEY_ID = env(\"AWS_ACCESS_KEY_ID\")\n    AWS_SECRET_ACCESS_KEY = env(\"AWS_SECRET_ACCESS_KEY\")\n    AWS_STORAGE_BUCKET_NAME = env(\"AWS_STORAGE_BUCKET_NAME\")\n    AWS_S3_CUSTOM_DOMAIN = env(\"AWS_S3_CUSTOM_DOMAIN\")\n    AWS_S3_REGION_NAME = env(\"AWS_S3_REGION_NAME\", \"\")\n    AWS_S3_ENDPOINT_URL = env(\"AWS_S3_ENDPOINT_URL\")\n    AWS_DEFAULT_ACL = \"public-read\"\n    AWS_S3_OBJECT_PARAMETERS = {\"CacheControl\": \"max-age=86400\"}\n    # S3 Static settings\n    STATIC_LOCATION = \"static\"\n    STATIC_URL = f\"{PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{STATIC_LOCATION}/\"\n    STATICFILES_STORAGE = \"bookwyrm.storage_backends.StaticStorage\"\n    # S3 Media settings\n    MEDIA_LOCATION = \"images\"\n    MEDIA_URL = f\"{PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{MEDIA_LOCATION}/\"\n    MEDIA_FULL_URL = MEDIA_URL\n    STATIC_FULL_URL = STATIC_URL\n    DEFAULT_FILE_STORAGE = \"bookwyrm.storage_backends.ImagesStorage\"\n    # I don't know if it's used, but the site crashes without it\n    STATIC_ROOT = os.path.join(BASE_DIR, env(\"STATIC_ROOT\", \"static\"))\n    MEDIA_ROOT = os.path.join(BASE_DIR, env(\"MEDIA_ROOT\", \"images\"))\nelse:\n    STATIC_URL = \"/static/\"\n    STATIC_ROOT = os.path.join(BASE_DIR, env(\"STATIC_ROOT\", \"static\"))\n    MEDIA_URL = \"/images/\"\n    MEDIA_FULL_URL = f\"{PROTOCOL}://{DOMAIN}{MEDIA_URL}\"\n    STATIC_FULL_URL = f\"{PROTOCOL}://{DOMAIN}{STATIC_URL}\"\n    MEDIA_ROOT = os.path.join(BASE_DIR, env(\"MEDIA_ROOT\", \"images\"))\n", "path": "bookwyrm/settings.py"}]}