Merge pull request 'Upgrade to 3.12' (#630) from python-3.12 into main
[inboxen.git] / inboxen / config.py
blob2cda2233d8c99c8507e7850dc80c04240fcfdaef
1 ##
2 # Copyright (C) 2015, 2020 Jessica Tallon & Matt Molyneaux
4 # This file is part of Inboxen.
6 # Inboxen is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # Inboxen is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Affero General Public License for more details.
16 # You should have received a copy of the GNU Affero General Public License
17 # along with Inboxen If not, see <http://www.gnu.org/licenses/>.
20 import os
21 import warnings
23 from django.core import exceptions
24 from ruamel.yaml import YAML
26 from inboxen.utils.misc import setdefault_deep
29 # Most configuration can be done via inboxen.config
31 # The file is searched for in the follow way:
32 # 1. The environment variable "INBOXEN_CONFIG", which contains an absolute path
33 # 2. ~/.config/inboxen/inboxen.config
34 # 3. inboxen.config in the current working directory
35 # 4. inboxen.config in the root of the git repo (i.e. the same directory as "manage.py")
38 is_testing = int(os.getenv("INBOXEN_TESTING", "0")) > 0
40 BASE_DIR = os.path.dirname(os.path.dirname(__file__))
42 if is_testing:
43 CONFIG_PATH = ""
44 elif os.path.exists(os.getenv("INBOX_CONFIG", "")):
45 CONFIG_PATH = os.getenv("INBOX_CONFIG")
46 elif os.path.exists(os.path.expanduser("~/.config/inboxen/inboxen.config")):
47 CONFIG_PATH = os.path.expanduser("~/.config/inboxen/inboxen.config")
48 elif os.path.exists(os.path.join(os.getcwd(), "inboxen.config")):
49 CONFIG_PATH = os.path.join(os.getcwd(), "inboxen.config")
50 elif os.path.exists(os.path.join(BASE_DIR, "inboxen.config")):
51 CONFIG_PATH = os.path.join(BASE_DIR, "inboxen.config")
52 else:
53 raise exceptions.ImproperlyConfigured("You must provide a inboxen.config file")
55 yaml_parser = YAML(typ="safe")
56 with open(os.path.join(BASE_DIR, "inboxen", "config_defaults.yaml")) as defaults_file:
57 default_values = yaml_parser.load(defaults_file)
59 if CONFIG_PATH:
60 with open(CONFIG_PATH) as config_file:
61 config_obj = yaml_parser.load(config_file)
62 else:
63 config_obj = None
65 config = setdefault_deep(config_obj, default_values)
67 try:
68 SECRET_KEY = config["secret_key"]
69 except KeyError:
70 if is_testing:
71 warnings.warn("You haven't set 'secret_key' in your inboxen.config", ImportWarning)
72 else:
73 raise exceptions.ImproperlyConfigured("You must set 'secret_key' in your inboxen.config")
75 # Admins (and managers)
76 ADMINS = config["admins"]
78 # List of hosts allowed
79 ALLOWED_HOSTS = config["allowed_hosts"]
81 # Enable debugging - DO NOT USE IN PRODUCTION
82 DEBUG = config["debug"]
84 # Allow new users to register
85 ENABLE_REGISTRATION = config["enable_registration"]
87 # Language code, e.g. en-gb
88 LANGUAGE_CODE = config["language_code"]
90 # Where `manage.py collectstatic` puts static files
91 STATIC_ROOT = os.path.join(os.getcwd(), config["static_root"])
93 # Media files get uploaded to this dir
94 MEDIA_ROOT = os.path.join(os.getcwd(), config["media_root"])
96 # Email the server uses when sending emails
97 SERVER_EMAIL = config["server_email"]
99 # Site name used in page titles
100 SITE_NAME = config["site_name"]
102 # Site URL for use in admin emails
103 SITE_URL = config["site_url"]
105 # Link to source code
106 SOURCE_LINK = config["source_link"]
108 # Link to issue tracker
109 SOURCE_LINK = config["issue_link"]
111 # Time zone
112 TIME_ZONE = config["time_zone"]
114 # Per user email quota
115 PER_USER_EMAIL_QUOTA = config["per_user_email_quota"]
117 # Length of the local part (bit before the @) of autogenerated inbox addresses
118 INBOX_LENGTH = config["inbox_length"]
120 # Ratelimit #
122 # Cooloff time, in minutes, for failed logins
123 LOGIN_LIMIT_WINDOW = config["ratelimits"]["login"]["window"]
125 # Maximum number of unsuccessful login attempts
126 LOGIN_LIMIT_COUNT = config["ratelimits"]["login"]["count"]
128 # Cooloff time, in minutes, for registrations
129 REGISTER_LIMIT_WINDOW = config["ratelimits"]["register"]["window"]
131 # Maximum number of registrations
132 REGISTER_LIMIT_COUNT = config["ratelimits"]["register"]["count"]
134 # Cooloff time, in minutes, for downloading a single email
135 SINGLE_EMAIL_LIMIT_WINDOW = config["ratelimits"]["single_email"]["window"]
137 # Maximum number of downloads of single emails
138 SINGLE_EMAIL_LIMIT_COUNT = config["ratelimits"]["single_email"]["count"]
140 # Cooloff time, in minutes, for inbox creation
141 INBOX_LIMIT_WINDOW = config["ratelimits"]["inbox"]["window"]
143 # Maximum number of inboxes creations within limit window
144 INBOX_LIMIT_COUNT = config["ratelimits"]["inbox"]["count"]
146 # Tasks #
148 # Where Celery looks for new tasks and stores results
149 CELERY_BROKER_URL = config["tasks"]["broker_url"]
151 # Number of Celery processes to start
152 CELERY_WORKER_CONCURRENCY = config["tasks"]["concurrency"]
154 # Runs tasks synchronously
155 CELERY_TASK_ALWAYS_EAGER = config["tasks"]["always_eager"]
157 # Path where liberation data is stored
158 SENDFILE_ROOT = os.path.join(os.getcwd(), config["tasks"]["liberation"]["path"])
159 SENDFILE_ROOT = SENDFILE_ROOT.rstrip("/")
161 # Which backend should be used to accelerate liberation data downloads
162 SENDFILE_BACKEND = config["tasks"]["liberation"]["sendfile_backend"]
164 # Databases!
165 DATABASES = {
166 'default': {
167 'ENGINE': "django.db.backends.postgresql_psycopg2",
168 'USER': config["database"]["user"],
169 'PASSWORD': config["database"]["password"],
170 'NAME': config["database"]["name"],
171 'HOST': config["database"]["host"],
172 'PORT': config["database"]["port"],
176 # Caches!
177 CACHES = {
178 'default': {
179 'BACKEND': config["cache"]["backend"],
180 'TIMEOUT': config["cache"]["timeout"],
184 CACHES["default"]["LOCATION"] = config["cache"]["location"]
186 # populate __all__
187 __all__ = [item for item in dir() if item.isupper()]