Document setting storage and mail sending

This commit is contained in:
Raphael Michel
2016-05-29 20:34:03 +02:00
parent ead7d8ed78
commit e4b1cf8d6f
6 changed files with 122 additions and 28 deletions

View File

@@ -83,7 +83,12 @@ class I18nInlineFormSet(BaseInlineFormSet):
class SettingsForm(forms.Form):
"""
This form is meant to be used for modifying Event- or OrganizerSettings
This form is meant to be used for modifying Event- or OrganizerSettings. It takes
care of loading the current values of the fields and saving the field inputs to the
settings storage. It also deals with setting the available languages for internationalized
fields.
:param obj: The event or organizer object which should be used for the settings storage
"""
BOOL_CHOICES = (
('False', _('disabled')),
@@ -99,6 +104,9 @@ class SettingsForm(forms.Form):
field.widget.enabled_langcodes = self.obj.settings.get('locales')
def save(self):
"""
Performs the save operation
"""
for name, field in self.fields.items():
value = self.cleaned_data[name]
if isinstance(value, UploadedFile):

View File

@@ -3,7 +3,6 @@ import logging
from django.conf import settings
from django.core.mail import EmailMessage, get_connection
from django.template.loader import get_template
from django.utils import translation
from django.utils.translation import ugettext as _
from typing import Any, Dict
@@ -22,22 +21,26 @@ class TolerantDict(dict):
def mail(email: str, subject: str, template: str,
context: Dict[str, Any]=None, event: Event=None, locale: str=None):
"""
Sends out an email to a user.
Sends out an email to a user. The mail will be sent synchronously or asynchronously depending on the installation.
:param email: The e-mail this should be sent to.
:param subject: The e-mail subject. Should be localized.
:param template: The filename of a template to be used. It will
be rendered with the recipient's locale. Alternatively, you
can pass a LazyI18nString and ``context`` will be used
for a Python .format() call.
:param context: The context for rendering the template.
:param event: The event, used for determining the sender of the e-mail
:param locale: The locale used while rendering the template
:param email: The e-mail address of the recipient.
:return: ``False`` on obvious failures, like the user having to e-mail
address, ``True`` otherwise. ``True`` does not necessarily mean that
the email has been sent, just that it has been queued by the e-mail
backend.
:param subject: The e-mail subject. Should be localized to the recipients's locale or a lazy object that will be
localized by being casted to a string.
:param template: The filename of a template to be used. It will be rendered with the locale given in the locale
argument and the context given in the next argument. Alternatively, you can pass a LazyI18nString and
``context`` will be used as the argument to a Python ``.format()`` call on the template.
:param context: The context for rendering the template (see ``template`` parameter).
:param event: The event this email is related to (optional). If set, this will be used to determine the sender,
a possible prefix for the subject and the SMTP server that should be used to send this email.
:param locale: The locale to be used while evaluating the subject and the template.
:return: ``False`` on obvious, immediate failures, ``True`` otherwise. ``True`` does not necessarily mean that
the email has been sent, just that it has been queued by the e-mail backend.
"""
with language(locale):
if isinstance(template, LazyI18nString):

View File

@@ -213,7 +213,7 @@ class SettingsProxy:
This objects allows convenient access to settings stored in the
EventSettings/OrganizerSettings database model. It exposes all settings as
properties and it will do all the nasty inheritance and defaults stuff for
you. It will return None for non-existing properties.
you.
"""
def __init__(self, obj: Model, parent: Optional[Model]=None, type=None):
@@ -232,7 +232,11 @@ class SettingsProxy:
def _flush(self) -> None:
self._cached_obj = None
def freeze(self):
def freeze(self) -> dict:
"""
Returns a dictionary of all settings set for this object, including
any default values of its parents or hardcoded in pretix.
"""
settings = {}
for key, v in DEFAULTS.items():
settings[key] = self._unserialize(v['default'], v['type'])
@@ -297,11 +301,17 @@ class SettingsProxy:
raise TypeError('Unable to serialize %s into a setting.' % str(type(value)))
def get(self, key: str, default: Any=None, as_type: type=None):
def get(self, key: str, default=None, as_type: type=None):
"""
Get a setting specified by key 'key'. Normally, settings are strings, but
Get a setting specified by key ``key``. Normally, settings are strings, but
if you put non-strings into the settings object, you can request unserialization
by specifying 'as_type'
by specifying ``as_type``. If the key does not have a harcdoded type in the pretix source,
omitting ``as_type`` always will get you a string.
If the setting with the specified name does not exist on this object, any parent object
will be queried (e.g. the organizer of an event). If still no value is found, a default
value hardcoded will be returned if one exists. If not, the value of the ``default`` argument
will be returned instead.
"""
if as_type is None and key in DEFAULTS:
as_type = DEFAULTS[key]['type']
@@ -336,6 +346,9 @@ class SettingsProxy:
self.set(key, value)
def set(self, key: str, value: Any) -> None:
"""
Stores a setting to the database of this object.
"""
if key in self._cache():
s = self._cache()[key]
else:
@@ -347,9 +360,15 @@ class SettingsProxy:
def __delattr__(self, key: str) -> None:
if key.startswith('_'):
return super().__delattr__(key)
return self.__delitem__(key)
self.delete(key)
def __delitem__(self, key: str) -> None:
self.delete(key)
def delete(self, key: str) -> None:
"""
Deletes a setting from this object's storage.
"""
if key in self._cache():
self._cache()[key].delete()
del self._cache()[key]
@@ -357,13 +376,16 @@ class SettingsProxy:
class SettingsSandbox:
"""
Transparently proxied access to event settings, handling your domain-
prefixes for you.
Transparently proxied access to event settings, handling your prefixes for you.
:param typestr: The first part of the pretix, e.g. ``plugin``
:param key: The prefix, e.g. the name of your plugin
:param obj: The event or organizer that should be queried
"""
def __init__(self, type: str, key: str, event: Model):
self._event = event
self._type = type
def __init__(self, typestr: str, key: str, obj: Model):
self._event = obj
self._type = typestr
self._key = key
def _convert_key(self, key: str) -> str: