forked from rc/aircox

- !88 pytest on existing tests - !89 reorganise settings (! see notes for deployment) Co-authored-by: bkfox <thomas bkfox net> Reviewed-on: rc/aircox#92
181 lines
5.2 KiB
Python
Executable File
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")
|