class DateRegistry(object): """Maintains a collection of important changeable date fields. """ def __init__(self): self._registry = OrderedRegistry() class DateItem(object): def __init__(self, date_field, name_generator, model): self.date_field = date_field self.name_generator = name_generator self.model = model def register(self, date_field, name_generator=None, model=None, order=sys.maxint): """Registers a new date item. :param date_field: the date's field in the model :param name_generator: function taking model's object and returning the name to be displayed with the date. :param model: the date's model. If the model is not provided the method returns a decorator for a model. :param order: the date's order. The lower the order, the higher the priority of the date. """ def decorator(original_class): self.register(date_field, name_generator, original_class, order) return original_class if model is None: return decorator if name_generator is None: name_generator = lambda obj: \ unicode(model._meta.verbose_name) + " " + unicode(model._meta. get_field_by_name(date_field)[0].verbose_name) date_item = self.DateItem(date_field, name_generator, model) self._registry.register(date_item, order) def tolist(self, contest_id): """Returns a list of items to pass to a template for rendering.""" context_items = [] for idx, item in enumerate(self._registry): model = item.model data = model.objects.filter(contest=contest_id).values() for record in data: context_items.append( dict(text=item.name_generator(record), date=record[item.date_field], date_field=item.date_field, model=model, id=record['id'], order=self._registry.keys[idx])) return context_items
class AttachmentRegistry(object): """Maintains a collection of functions that return attachments for 'Downloads' view. """ def __init__(self): self._registry = OrderedRegistry() def register(self, attachment_generator=None, order=sys.maxsize): """Register function generating attachments. :Parameters: Function that takes elements from `**kwargs` as arguments and returns dictionary containing following keys: `category`, `name`, `description`, `link`, `pub_date`. """ if attachment_generator is not None: self._registry.register(attachment_generator, order) def to_list(self, **kwargs): attachments = [] for idx, gen in enumerate(self._registry): attachments.extend(gen(**kwargs)) return attachments
from oioioi.base.menu import OrderedRegistry from oioioi.base.utils.archive import Archive from oioioi.contests.controllers import submission_template_context from oioioi.contests.forms import SubmissionFormForProblemInstance from oioioi.contests.models import (ProblemInstance, Submission) from oioioi.contests.utils import administered_contests from oioioi.problems.forms import PackageFileReuploadForm from oioioi.problems.models import (Problem, ProblemAttachment, ProblemPackage, AlgorithmTagProposal, ProblemStatement) from oioioi.problems.problem_sources import UploadedPackageSource from oioioi.problems.utils import (query_statement, query_zip, generate_add_to_contest_metadata, generate_model_solutions_context, can_admin_problem, can_admin_problem_instance) from oioioi.contests.attachment_registration import attachment_registry_problemset from oioioi.sinolpack.models import OriginalPackage problem_site_tab_registry = OrderedRegistry() logger = logging.getLogger(__name__) def problem_site_tab(title, key, order=sys.maxsize, condition=None): """A decorator that for each decorated function adds a corresponding tab to the global problem site that uses the function to generate its contents. The decorated function should be somewhat similar to a view. It should take as its arguments a request and a problem, and return either a HttpResponseRedirect, a TemplateResponse or rendered html. :param title: the tab's title, will be shown on the site :param key: will be used as a GET parameter to indicate the active tab :param order: value determining the order of tabs
class DateRegistry(object): """Maintains a collection of important changeable date fields.""" def __init__(self): self._registry = OrderedRegistry() class DateItem(object): def __init__(self, date_field, name_generator, round_chooser, qs_filter, model): self.date_field = date_field self.name_generator = name_generator self.round_chooser = round_chooser self.qs_filter = qs_filter self.model = model def register( self, date_field, name_generator=None, round_chooser=None, qs_filter=None, model=None, order=sys.maxsize, ): """Registers a new date item. :param date_field: the date's field in the model :param name_generator: function taking model's object and returning the name to be displayed with the date. :param round_chooser: function taking model's object and returning the round it belongs to. :param qs_filter: function taking a (queryset, contest id) pair and returning a queryset limited to instances related to the contest. :param model: the date's model. If the model is not provided the method returns a decorator for a model. :param order: the date's order. The lower the order, the higher the priority of the date. """ def decorator(original_class): self.register( date_field, name_generator, round_chooser, qs_filter, original_class, order, ) return original_class if model is None: return decorator if name_generator is None: name_generator = ( lambda obj: six.text_type(model._meta.verbose_name) + " " + six .text_type(model._meta.get_field(date_field).verbose_name)) if round_chooser is None: round_chooser = lambda obj: None if qs_filter is None: qs_filter = lambda qs, contest_id: qs.filter(contest=contest_id) date_item = self.DateItem(date_field, name_generator, round_chooser, qs_filter, model) self._registry.register(date_item, order) def tolist(self, contest_id): """Returns a list of items to pass to a template for rendering.""" context_items = [] for idx, item in enumerate(self._registry): model = item.model instances = item.qs_filter(model.objects.all(), contest_id) for instance in instances: context_items.append( dict( text=item.name_generator(instance), date=getattr(instance, item.date_field), date_field=item.date_field, model=model, id=instance.id, round=item.round_chooser(instance), order=self._registry.keys[idx], )) return context_items
def test_ordered_registry(self): reg = OrderedRegistry() reg.register(1, 12) reg.register(3) reg.register(2, 3) reg.register(4) self.assertListEqual([2, 1, 3, 4], list(reg)) reg.unregister(3) self.assertListEqual([2, 1, 4], list(reg)) self.assertEqual(len(reg), 3)
from django.db.models import F from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ from oioioi.base.menu import OrderedRegistry from oioioi.gamification.friends import UserFriends from oioioi.contests.models import UserResultForProblem from oioioi.gamification.controllers import TaskSuggestionController MAX_SUGGESTIONS_FROM_FRIENDS = 10 miniprofile_row_registry = OrderedRegistry() miniprofile_tab_registry = OrderedRegistry() """Adds a row to the miniprofile given a view function. The view should return a string. Warning: Miniprofile is added to the site through a context processor, so the use of RequestContext in miniprofile tabs is impossible. """ miniprofile_row = miniprofile_row_registry.register_decorator def miniprofile_tab(title, order): """Adds a tab to the miniprofile given heading and view function. The view should return a string. Warning: Miniprofile is added to the site through a context processor, so the use of RequestContext in miniprofile tabs is impossible. """ def decorator(func): miniprofile_tab_registry.register((title, func), order) return func
from oioioi.base.menu import OrderedRegistry #: A registry containing fragments of the dashboard. Each fragment is a #: callable which expects a single parameter --- the request --- and returns an #: HTML string to render on the dashboard. It should return ``None`` if there #: is no content to display. dashboard_registry = OrderedRegistry() #: A registry containing headers of the dashboard. They are just like regular #: fragments above, except that a placeholder text "this is dashboard, #: something will be shown here once you submit..." is shown only when there is #: nothing rendered by functions registered in ``dashboard_registry``, even if #: some headers are present. dashboard_headers_registry = OrderedRegistry()
import sys from django.core.exceptions import ImproperlyConfigured from oioioi.base.menu import OrderedRegistry from oioioi.base.permissions import Condition class _MainPageEntry(object): def __init__(self, view, condition): self.view = view self.condition = condition _main_page_registry = OrderedRegistry() def register_main_page_view(order=sys.maxsize, condition=None): """Decorator for a view, which registers it as a main page. A view registered this way can be shown as the main page of the website (at URL /). If multiple views are registered, one with the lowest ``order`` for which the ``condition`` holds true is selected. :param order: value determining the order in which the main page is selected :type order: int :param condition: decides if a main page can be selected :type condition: :class:`oioioi.base.permissions.Condition` """
def __init__(self): self._registry = OrderedRegistry()
class DateRegistry(object): """Maintains a collection of important changeable date fields. """ def __init__(self): self._registry = OrderedRegistry() class DateItem(object): def __init__(self, date_field, name_generator, round_chooser, qs_filter, model): self.date_field = date_field self.name_generator = name_generator self.round_chooser = round_chooser self.qs_filter = qs_filter self.model = model def register(self, date_field, name_generator=None, round_chooser=None, qs_filter=None, model=None, order=sys.maxint): """Registers a new date item. :param date_field: the date's field in the model :param name_generator: function taking model's object and returning the name to be displayed with the date. :param round_chooser: function taking model's object and returning the round it belongs to. :param qs_filter: function taking a (queryset, contest id) pair and returning a queryset limited to instances related to the contest. :param model: the date's model. If the model is not provided the method returns a decorator for a model. :param order: the date's order. The lower the order, the higher the priority of the date. """ def decorator(original_class): self.register(date_field, name_generator, round_chooser, qs_filter, original_class, order) return original_class if model is None: return decorator if name_generator is None: name_generator = lambda obj: \ unicode(model._meta.verbose_name) + " " + unicode(model._meta. get_field_by_name(date_field)[0].verbose_name) if round_chooser is None: round_chooser = lambda obj: None if qs_filter is None: qs_filter = lambda qs, contest_id: qs.filter(contest=contest_id) date_item = self.DateItem(date_field, name_generator, round_chooser, qs_filter, model) self._registry.register(date_item, order) def tolist(self, contest_id): """Returns a list of items to pass to a template for rendering.""" context_items = [] for idx, item in enumerate(self._registry): model = item.model instances = item.qs_filter(model.objects.all(), contest_id) for instance in instances: context_items.append(dict( text=item.name_generator(instance), date=getattr(instance, item.date_field), date_field=item.date_field, model=model, id=instance.id, round=item.round_chooser(instance), order=self._registry.keys[idx])) return context_items
import sys from django.core.exceptions import ImproperlyConfigured from oioioi.base.menu import OrderedRegistry from oioioi.base.permissions import Condition class _ContestDashboardEntry(object): def __init__(self, view, condition): self.view = view self.condition = condition _contest_dashboard_registry = OrderedRegistry() def register_contest_dashboard_view(order=sys.maxsize, condition=None): """Decorator for a view, which registers it as a contest dashboard. A view registered this way can be shown as the main page of the contest. If multiple views are registered, one with the lowest ``order`` for which the ``condition`` holds true is selected. :param order: value determining the order in which the dashboard is selected :type order: int :param condition: decides if a dashboard can be selected :type condition: :class:`oioioi.base.permissions.Condition` """
def setUp(self): self.saved_menu = menu_registry._registry menu_registry._registry = OrderedRegistry()
def setUp(self): # pylint: disable=global-statement global profile_registry self.profile_backup = profile_registry profile_registry = OrderedRegistry()
from oioioi.base.menu import OrderedRegistry status_registry = OrderedRegistry()
from django.template.loader import render_to_string from oioioi.base.menu import OrderedRegistry from oioioi.gamification.friends import UserFriends profile_registry = OrderedRegistry() def profile_section(order): """ Decorator for registering profile view sections. The decorated function is passed the request and shown user. It may return a string, a TemplateResponse or HttpResponseRedirect. """ return profile_registry.register_decorator(order) @profile_section(order=80) def friend_finder_section(request, user): if user != request.user: return '' return render_to_string('gamification/profile/invite-friends.html') @profile_section(order=90) def invite_list_section(request, user): if user != request.user: return '' requests = UserFriends(user).requests_for_me\ .select_related('sender__user')