:py:mod:`oioioi.base.utils` =========================== .. py:module:: oioioi.base.utils Submodules ---------- .. toctree:: :titlesonly: :maxdepth: 1 api/index.rst archive/index.rst color/index.rst confirmation/index.rst db/index.rst deps/index.rst execute/index.rst filters/index.rst finders/index.rst input_with_generate/index.rst inputs/index.rst loaders/index.rst middleware/index.rst pdf/index.rst query_helpers/index.rst redirect/index.rst tags/index.rst user/index.rst user_selection/index.rst validators/index.rst Package Contents ---------------- Classes ~~~~~~~ .. autoapisummary:: oioioi.base.utils.ClassInitMeta oioioi.base.utils.ClassInitBase oioioi.base.utils.RegisteredSubclassesBase oioioi.base.utils._RemoveMixinsFromInitMixin oioioi.base.utils.ObjectWithMixins oioioi.base.utils.memoized_property oioioi.base.utils.ProgressBar Functions ~~~~~~~~~ .. autoapisummary:: oioioi.base.utils.memoized oioioi.base.utils.reset_memoized oioioi.base.utils.request_cached oioioi.base.utils.make_html_link oioioi.base.utils.make_html_links oioioi.base.utils.make_navbar_badge oioioi.base.utils.tabbed_view oioioi.base.utils.uploaded_file_name oioioi.base.utils.split_extension oioioi.base.utils.strip_num_or_hash oioioi.base.utils.naturalsort_key oioioi.base.utils.jsonify oioioi.base.utils.add_header oioioi.base.utils.allow_cross_origin oioioi.base.utils.is_ajax oioioi.base.utils.generate_key oioioi.base.utils.get_user_display_name oioioi.base.utils.find_closure Attributes ~~~~~~~~~~ .. autoapisummary:: oioioi.base.utils._STRIP_NUM_RE oioioi.base.utils._STRIP_HASH_RE .. py:class:: ClassInitMeta(class_name, bases, new_attrs) Bases: :py:obj:`type` Meta class triggering __classinit__ on class intialization. .. py:class:: ClassInitBase Bases: :py:obj:`object` Abstract base class injecting ClassInitMeta meta class. .. py:method:: __classinit__() :classmethod: Empty __classinit__ implementation. This must be a no-op as subclasses can't reliably call base class's __classinit__ from their __classinit__s. Subclasses of __classinit__ should look like: .. python:: class MyClass(ClassInitBase): @classmethod def __classinit__(cls): # Need globals().get as MyClass may be still undefined. super(globals().get('MyClass', cls), cls).__classinit__() ... class Derived(MyClass): @classmethod def __classinit__(cls): super(globals().get('Derived', cls), cls).__classinit__() ... .. py:class:: RegisteredSubclassesBase Bases: :py:obj:`ClassInitBase` A base class for classes which should have a list of subclasses available. The list of subclasses is available in their :attr:`subclasses` class attributes. Classes which have *explicitly* set :attr:`abstract` class attribute to ``True`` are not added to :attr:`subclasses`. If a class has ``modules_with_subclasses`` attribute (list or string), then specified modules for all installed applications can be loaded by calling :meth:`~RegisteredSubclassesBase.load_subclasses`. .. py:attribute:: _subclasses_loaded :annotation: = False .. py:method:: __classinit__() :classmethod: Empty __classinit__ implementation. This must be a no-op as subclasses can't reliably call base class's __classinit__ from their __classinit__s. Subclasses of __classinit__ should look like: .. python:: class MyClass(ClassInitBase): @classmethod def __classinit__(cls): # Need globals().get as MyClass may be still undefined. super(globals().get('MyClass', cls), cls).__classinit__() ... class Derived(MyClass): @classmethod def __classinit__(cls): super(globals().get('Derived', cls), cls).__classinit__() ... .. py:method:: load_subclasses() :classmethod: .. py:class:: _RemoveMixinsFromInitMixin(*args, **kwargs) Bases: :py:obj:`object` .. py:class:: ObjectWithMixins Bases: :py:obj:`ClassInitBase` Base class for objects which support mixins. Mixins are `nice tools in Python `_. But they have one drawback -- you have to specify new class' mixins at the point where you declare it. This class solves this problem. Mixins can be now be added on the fly by :meth:`~ObjectWithMixins.mix_in` method. This allows for a more flexible modular design. For example:: # base.py class UserController(ObjectWithMixins): def render_user_info(self, user): return "Login: " + user.username # some_external_module.py class UserControllerBeautifier(object): def render_user_info(self, user): super_info = super(UserControllerBeautifier, self) .render_user_info(user) return '' + super_info + '' UserController.mix_in(UserControllerBeautifier) Mixins can also be specified by providing a :attr:`mixins` class attribute or by passing an additional keyword argument ``mixins`` to the constructor. A class with a mixin behave as if it was replaced with a subclass which bases are the mixin and the original class. The actual class with the mixins is created when the constructor is called or a subclass defined. Mixing in a new mixin to a class which have instances has an undefined effect on them. .. py:attribute:: mixins :annotation: = [] .. py:attribute:: allow_too_late_mixins :annotation: = False .. py:method:: __classinit__() :classmethod: Empty __classinit__ implementation. This must be a no-op as subclasses can't reliably call base class's __classinit__ from their __classinit__s. Subclasses of __classinit__ should look like: .. python:: class MyClass(ClassInitBase): @classmethod def __classinit__(cls): # Need globals().get as MyClass may be still undefined. super(globals().get('MyClass', cls), cls).__classinit__() ... class Derived(MyClass): @classmethod def __classinit__(cls): super(globals().get('Derived', cls), cls).__classinit__() ... .. py:method:: _make_mx_class(mixins) :classmethod: .. py:method:: _get_mx_class() :classmethod: .. py:method:: _fixup_subclasses() :classmethod: .. py:method:: _fixup_subclass(subclass) :classmethod: .. py:method:: mix_in(mixin) :classmethod: Appends the given mixin to the list of class mixins. .. py:class:: memoized_property(fget, doc=None) Bases: :py:obj:`object` A read-only @property that is only evaluated once. .. py:method:: __get__(obj, cls) .. py:function:: memoized(fn) Simple wrapper that adds result caching for functions with positional arguments only. The arguments must be hashable so that they can be stored as keys in a dict. .. py:function:: reset_memoized(memoized_fn) Clear the memoization cache of a function decorated by :fun:`memoized`. .. py:function:: request_cached(fn) Adds per-request caching for functions which operate on sole request. .. py:function:: make_html_link(href, name, method='GET', extra_attrs=None) .. py:function:: make_html_links(links, extra_attrs=None) .. py:function:: make_navbar_badge(link, text, id=None) .. py:function:: tabbed_view(request, template, context, tabs, tab_kwargs, link_builder) A framework for building pages that are split into tabs. The current tab is picked using the 'key' GET parameter. The given template is rendered using the given context, which is extended by 'current_tab', representing the opened tab, 'tabs', a set of 'obj' and 'link' pairs for each existing tab, where 'obj' represents the tab and 'link' is a link to the tab's page, and 'content', the tab's rendered content. :param request: a HttpRequest object given to the view :param template: the rendered template :param context: additional context to be passed to the template :param tabs: an iterable of tabs. Each tab must have a unique 'key' attribute that will be used to create an URL to the tab, a 'view' attribute returning either HttpResponseRedirect, TemplateResponse or rendered html, and an optional 'condition' attribute: a function taking a request and returning if the tab should be accessible for this request. If there is no condition then it is assumed to be always returning True. :param tab_kwargs: a dict to be passed as kwargs to each tab's view :param link_builder: a function which receives a tab and returns a link to the tab. It should contain a proper path and the appropriate 'key' parameter. .. py:function:: uploaded_file_name(uploaded_file) .. py:function:: split_extension(filename) .. py:data:: _STRIP_NUM_RE .. py:data:: _STRIP_HASH_RE .. py:function:: strip_num_or_hash(filename) .. py:function:: naturalsort_key(key) .. py:class:: ProgressBar(max_value, length=20) Bases: :py:obj:`object` Displays simple textual progress bar. .. py:method:: _show(preserve=False) .. py:method:: _clear() .. py:method:: update(value=None, preserve=False) Set new value (if given) and redraw the bar. :param preserve: controls if bar will end with a new line and stay after next update. .. py:function:: jsonify(view) A decorator to serialize view result with JSON. The object returned by ``view`` will be converted to JSON and returned as an appropriate :class:`django.http.HttpResponse`. .. py:function:: add_header(header, value) .. py:function:: allow_cross_origin(arg='*') Add Access-Control-Allow-Origin header with given value, or '*' if none given. May be used as any of: @allow_cross_origin @allow_cross_origin() @allow_cross_origin('http://example.com') .. py:function:: is_ajax(request) Check if 'request' is an jQuery AJAX call. .. py:function:: generate_key() Generate an random key, encoded in url-safe way. .. py:function:: get_user_display_name(user) This method returns the full user name if available and the username otherwise. .. py:function:: find_closure(groups) Finds closure of sets. If any two elements were within same input set,they will be in one unique set in the output. >>> find_closure([[1, 2], [2, 3], [4]]) [[1, 2, 3], [4],]