aircox-radiocampus/aircox/conf.py
Thomas Kairos 0e183099ed #88 #89 : use pytest + reorganise settings (#92)
- !88 pytest on existing tests
- !89 reorganise settings (! see notes for deployment)

Co-authored-by: bkfox <thomas bkfox net>
Reviewed-on: rc/aircox#92
2023-03-28 14:40:49 +02:00

181 lines
5.2 KiB
Python
Executable File

import os
import inspect
from django.conf import settings as d_settings
__all__ = ("Settings", "settings")
# code from django-fox
class BaseSettings:
"""Utility class used to load and save settings, can be used as model.
Some members are excluded from being configuration:
- Protected/private members;
- On django model, "objects" and "Meta";
- Class declaration and callables
Example:
```
class MySettings(Settings):
a = 13
b = 12
my_settings = MySettings().load('MY_SETTINGS_KEY')
print(my_settings.a, my_settings.get('b'))
```
This will load values from django project settings.
"""
def __init__(self, key, module=None):
self.load(key, module)
def load(self, key, module=None):
"""Load settings from module's item specified by its member name. When
no module is provided, uses ``django.conf.settings``.
:param str key: module member name.
:param module: configuration object.
:returns self
"""
if module is None:
module = d_settings
settings = getattr(module, key, None)
if settings:
self.update(settings)
return self
def update(self, settings):
"""Update self's values from provided settings. ``settings`` can be an
iterable of ``(key, value)``.
:param dict|Settings|iterable settings: value to update from.
"""
if isinstance(settings, (dict, Settings)):
settings = settings.items()
for key, value in settings:
if self.is_config_item(key, value):
setattr(self, key, value)
def get(self, key, default=None):
"""Return settings' value for provided key."""
return getattr(self, key, default)
def items(self):
"""Iterate over items members, as tupple of ``key, value``."""
for key in dir(self):
value = getattr(self, key)
if self.is_config_item(key, value):
yield key, value
def is_config_item(self, key, value):
"""Return True if key/value item is a configuration setting."""
if key.startswith("_") or callable(value) or inspect.isclass(value):
return False
return True
class Settings(BaseSettings):
# --- Global & misc
DEFAULT_USER_GROUPS = {
"radio hosts": (
# TODO include content_type in order to avoid clash with potential
# extra applications
# aircox
"change_program",
"change_episode",
"change_diffusion",
"add_comment",
"change_comment",
"delete_comment",
"add_article",
"change_article",
"delete_article",
"change_sound",
"add_track",
"change_track",
"delete_track",
# taggit
"add_tag",
"change_tag",
"delete_tag",
# filer
"add_folder",
"change_folder",
"delete_folder",
"can_use_directory_listing",
"add_image",
"change_image",
"delete_image",
),
}
"""Groups to assign to users at their creation, along with the permissions
to add to each group."""
PROGRAMS_DIR = "programs"
"""Directory for the programs data."""
@property
def PROGRAMS_DIR_ABS(self):
return os.path.join(d_settings.MEDIA_ROOT, self.PROGRAMS_DIR)
# --- Programs & episodes
EPISODE_TITLE = "{program.title} - {date}"
"""Default title for episodes."""
EPISODE_TITLE_DATE_FORMAT = "%-d %B %Y"
"""Date format in episode title (python's strftime)"""
# --- Logs & archives
LOGS_ARCHIVES_DIR = "logs/archives"
"""Directory where to save logs' archives."""
@property
def LOGS_ARCHIVES_DIR_ABS(self):
return os.path.join(d_settings.PROJECT_ROOT, self.LOGS_ARCHIVES_DIR)
LOGS_ARCHIVES_AGE = 60
"""In days, minimal age of a log before it is archived."""
# --- Sounds
SOUND_ARCHIVES_SUBDIR = "archives"
"""Sub directory used for the complete episode sounds."""
SOUND_EXCERPTS_SUBDIR = "excerpts"
"""Sub directory used for the excerpts of the episode."""
SOUND_QUALITY = {
"attribute": "RMS lev dB",
"range": (-18.0, -8.0),
"sample_length": 120,
}
"""Quality attributes passed to sound_quality_check from sounds_monitor
(Soxi parameters)."""
SOUND_FILE_EXT = (".ogg", ".flac", ".wav", ".mp3", ".opus")
"""Extension of sound files."""
SOUND_KEEP_DELETED = False
"""Tag sounds as deleted instead of deleting them when file has been
removed from filesystem (sound monitoring)."""
# --- Streamer & Controllers
CONTROLLERS_WORKING_DIR = "/tmp/aircox"
"""Controllers working directory."""
# --- Playlist import from CSV
IMPORT_PLAYLIST_CSV_COLS = (
"artist",
"title",
"minutes",
"seconds",
"tags",
"info",
)
"""Columns for CSV file."""
IMPORT_PLAYLIST_CSV_DELIMITER = ";"
"""Column delimiter of csv text files."""
IMPORT_PLAYLIST_CSV_TEXT_QUOTE = '"'
"""Text delimiter of csv text files."""
settings = Settings("AIRCOX")