utils package

Submodules

utils.admin module

class utils.admin.DoNextModelAdmin(model, admin_site)[source]

Bases: django.contrib.admin.options.ModelAdmin

This class adds processing of a next parameter in the urls of the add and change admin forms.

If it is set and safe this override will redirect the user to the provided url.

property media
response_add(request, obj, **kwargs)[source]

Determine the HttpResponse for the add_view stage.

response_change(request, obj)[source]

Determine the HttpResponse for the change_view stage.

class utils.admin.DoNextTranslatedModelAdmin(model, admin_site)[source]

Bases: utils.translation.TranslatedModelAdmin

This class adds processing of a next parameter in the urls of the add and change admin forms.

If it is set and safe this override will redirect the user to the provided url.

property media
response_add(request, obj, **kwargs)[source]

Determine the HttpResponse for the add_view stage.

response_change(request, obj)[source]

Determine the HttpResponse for the change_view stage.

utils.countries module

utils.exception_filter module

Provides an exception filter for django.

class utils.exception_filter.ThaliaSafeExceptionReporterFilter[source]

Bases: django.views.debug.SafeExceptionReporterFilter

Filter additional variables from tracebacks.

https://docs.djangoproject.com/en/2.0/howto/error-reporting/#filtering-sensitive-information

get_traceback_frame_variables(request, tb_frame)[source]

Filter traceback frame variables.

utils.google_api module

class utils.google_api.MemoryCache[source]

Bases: googleapiclient.discovery_cache.base.Cache

get(url)[source]

Gets the content from the memcache with a given key.

Args:

url: string, the key for the cache.

Returns:

object, the value in the cache for the given key, or None if the key is not in the cache.

set(url, content)[source]

Sets the given key and content in the cache.

Args:

url: string, the key for the cache. content: string, the discovery document.

utils.google_api.get_directory_api()[source]
utils.google_api.get_groups_settings_api()[source]

utils.snippets module

Provides various utilities that are useful across the project.

utils.snippets.create_google_maps_url(location, zoom, size)[source]
utils.snippets.datetime_to_lectureyear(date)[source]

Convert a date to the start of the lectureyear.

>>> from datetime import date, datetime, timezone
>>> nov_23 = date(1990, 11, 7)
>>> datetime_to_lectureyear(nov_23)
1990
>>> mar_2 = date(1993, 3, 2)
>>> datetime_to_lectureyear(mar_2)
1992

Also works on datetime, but they need to be tz-aware:

>>> new_year = datetime(2000, 1, 1, tzinfo=timezone.utc)
>>> datetime_to_lectureyear(new_year)
1999
utils.snippets.dict2obj(d, name='Object')[source]
utils.snippets.extract_date_range(request, allow_empty=False)[source]

Extract a date range from an arbitrary string.

utils.snippets.overlaps(check, others, can_equal=True)[source]

Check for overlapping date ranges.

This works by checking the maximum of the two since times, and the minimum of the two until times. Because there are no infinite dates, the value date_max is created for when the until value is None; this signifies a timespan that has not ended yet and is the maximum possible date in Python’s datetime.

The ranges overlap when the maximum start time is smaller than the minimum end time, as can be seen in this example of two integer ranges:

check: … .[4]… . 9 other: . . 2 . .[5]… .

check: … .[4]… . 9 other: . . 2 … … . [date_max]

And when non overlapping: check: … …[6] . . 9 other: . . 2 . .[5]… .

4 < 5 == True so these intervals overlap, while 6 < 5 == False so these intervals don’t overlap

The can_equal argument is used for boards, where the end date can’t be the same as the start date.

>>> overlaps(     dict2obj({         'pk': 1         , 'since': datetime.date(2018, 12, 1)         , 'until': datetime.date(2019, 1, 1)     })     , [dict2obj({     'pk': 2     , 'since': datetime.date(2019, 1, 1)     , 'until': datetime.date(2019, 1, 31)     })])
False
>>> overlaps(     dict2obj({         'pk': 1         , 'since': datetime.date(2018, 12, 1)         , 'until': datetime.date(2019, 1, 1)     })     , [dict2obj({     'pk': 2     , 'since': datetime.date(2019, 1, 1)     , 'until': datetime.date(2019, 1, 31)     })], False)
True
>>> overlaps(     dict2obj({         'pk': 1         , 'since': datetime.date(2018, 12, 1)         , 'until': datetime.date(2019, 1, 2)     })     , [dict2obj({     'pk': 2     , 'since': datetime.date(2019, 1, 1)     , 'until': datetime.date(2019, 1, 31)     })])
True

utils.threading module

utils.threading.PopenAndCall(onExit, *popenArgs, **popenKWArgs)[source]

Run a subprocess.Popen, and then call the function onExit when the subprocess completes.

Use it exactly the way you’d normally use subprocess.Popen, except include a callable to execute as the first argument. onExit is a callable object, and *popenArgs and **popenKWArgs are simply passed up to subprocess.Popen.

utils.translation module

This module makes it easy to define translatable model fields.

To use it in a models.py, make sure you;

See the following usage example;

from django.db import models
from utils.translation import MultilingualField, ModelTranslateMeta

class SomeItem(models.Model, metaclass=ModelTranslateMeta):

    name = MultilingualField(models.CharField, max_length=100)
    description = MultilingualField(models.TextField)

In order to use the fields in ModelAdmin configuration (such as in the fields, fieldsets or prepopulated_fields attributes), subclass TranslatedModelAdmin instead;

from utils.translation import TranslatedModelAdmin

class SomeItemAdmin(TranslatedModelAdmin):
    fields = (name, description)
class utils.translation.ModelTranslateMeta(name, bases, dct)[source]

Bases: django.db.models.base.ModelBase

Metaclass to handle the MultilingualField transformations.

class utils.translation.MultilingualField(cls, *args, **kwargs)[source]

Bases: object

Transformed the passed-in form field into fields appended with the active languages and generates an automatic accessor property that translates based on the currently active language.

Requires a Model metaclassed by ModelTranslateMeta.

class utils.translation.TranslatedModelAdmin(model, admin_site)[source]

Bases: django.contrib.admin.options.ModelAdmin

This class should be used when ModelAdmin is used with a translated model and one refers to such a field in the fields or fieldsets attributes, or in prepopulated_fields.

This works because ModelAdmin has an empty metaclass; we can hook in to __init__ and modify the attributes when model is known.

property media
utils.translation.localize_attr_name(attr_name, language=None)[source]

Generate the localized attribute name.