class Site(object): """ Misago user sites controller Allows for adding custom views to User CP, Users Lists and User Profile """ def __init__(self, name): self._finalized = False self.name = name self._unsorted_list = [] self._sorted_list = [] def assert_site_is_finalized(self): if not self._finalized: self._finalized = True self._finalize_site() def _finalize_site(self): iterations = 0 while self._unsorted_list: iterations += 1 if iterations > 512: message = ("%s site hierarchy is invalid or too complex " "to resolve. pages left: %s" % self._unsorted_list) raise ValueError(message) for index, page in enumerate(self._unsorted_list): if page['after']: page_added = self._insert_page(page, after=page['after']) elif page['before']: page_added = self._insert_page(page, before=page['before']) else: page_added = self._insert_page(page) if page_added: del self._unsorted_list[index] break def _insert_page(self, inserted_page, after=None, before=None): if after: new_sorted_list = [] for index, page in enumerate(self._sorted_list): new_sorted_list.append(page) if page['link'] == after: new_sorted_list.append(inserted_page) self._sorted_list = new_sorted_list return True else: return False elif before: new_sorted_list = [] for index, page in enumerate(self._sorted_list): if page['link'] == before: new_sorted_list.append(inserted_page) new_sorted_list.append(page) self._sorted_list = new_sorted_list return True else: new_sorted_list.append(page) else: return False else: self._sorted_list.append(inserted_page) return True def add_page(self, link, name, icon=None, after=None, before=None, visibility_condition=None): if self._finalized: message = ("%s site was initialized already and no longer " "accepts new pages") raise RuntimeError(message % self.name) if after and before: raise ValueError("after and before arguments are exclusive") self._unsorted_list.append({ 'link': link, 'name': name, 'icon': icon, 'after': after, 'before': before, 'visibility_condition': visibility_condition, }) def _active_link_name(self, request): namespace = request.resolver_match.namespace url_name = request.resolver_match.url_name if namespace: active_link = '%s:%s' % (namespace, url_name) else: active_link = url_name return active_link def get_pages(self, request, profile=None): self.assert_site_is_finalized() active_link = self._active_link_name(request) visible_pages = [] if profile: test_args = (request, profile) else: test_args = (request,) for page in self._sorted_list: is_visible = True if page['visibility_condition']: is_visible = page['visibility_condition'](*test_args) if is_visible: page['is_active'] = page['link'].startswith(active_link) visible_pages.append(page) return visible_pages def get_default_link(self): self.assert_site_is_finalized() return self._sorted_list[0]['link'] usercp = Site('usercp') users_list = Site('users list') user_profile = Site('user profile')