sites.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. class Site(object):
  2. """
  3. Misago user sites controller
  4. Allows for adding custom views to User CP, Users Lists and User Profile
  5. """
  6. def __init__(self, name):
  7. self._finalized = False
  8. self.name = name
  9. self._unsorted_list = []
  10. self._sorted_list = []
  11. def assert_site_is_finalized(self):
  12. if not self._finalized:
  13. self._finalized = True
  14. self._finalize_site()
  15. def _finalize_site(self):
  16. iterations = 0
  17. while self._unsorted_list:
  18. iterations += 1
  19. if iterations > 512:
  20. message = ("%s site hierarchy is invalid or too complex "
  21. "to resolve. pages left: %s" % self._unsorted_list)
  22. raise ValueError(message)
  23. for index, page in enumerate(self._unsorted_list):
  24. if page['after']:
  25. page_added = self._insert_page(page, after=page['after'])
  26. elif page['before']:
  27. page_added = self._insert_page(page, before=page['before'])
  28. else:
  29. page_added = self._insert_page(page)
  30. if page_added:
  31. del self._unsorted_list[index]
  32. break
  33. def _insert_page(self, inserted_page, after=None, before=None):
  34. if after:
  35. new_sorted_list = []
  36. for index, page in enumerate(self._sorted_list):
  37. new_sorted_list.append(page)
  38. if page['link'] == after:
  39. new_sorted_list.append(inserted_page)
  40. self._sorted_list = new_sorted_list
  41. return True
  42. else:
  43. return False
  44. elif before:
  45. new_sorted_list = []
  46. for index, page in enumerate(self._sorted_list):
  47. if page['link'] == before:
  48. new_sorted_list.append(inserted_page)
  49. new_sorted_list.append(page)
  50. self._sorted_list = new_sorted_list
  51. return True
  52. else:
  53. new_sorted_list.append(page)
  54. else:
  55. return False
  56. else:
  57. self._sorted_list.append(inserted_page)
  58. return True
  59. def add_page(self, link, name, icon=None, after=None, before=None,
  60. visibility_condition=None, badge=None):
  61. if self._finalized:
  62. message = ("%s site was initialized already and no longer "
  63. "accepts new pages")
  64. raise RuntimeError(message % self.name)
  65. if after and before:
  66. raise ValueError("after and before arguments are exclusive")
  67. self._unsorted_list.append({
  68. 'link': link,
  69. 'name': name,
  70. 'icon': icon,
  71. 'after': after,
  72. 'before': before,
  73. 'badge': badge,
  74. 'visibility_condition': visibility_condition,
  75. })
  76. def _active_link_name(self, request):
  77. namespace = request.resolver_match.namespace
  78. url_name = request.resolver_match.url_name
  79. if namespace:
  80. active_link = '%s:%s' % (namespace, url_name)
  81. else:
  82. active_link = url_name
  83. return active_link
  84. def get_pages(self, request, profile=None):
  85. self.assert_site_is_finalized()
  86. active_link = self._active_link_name(request)
  87. visible_pages = []
  88. if profile:
  89. test_args = (request, profile)
  90. else:
  91. test_args = (request,)
  92. for _page in self._sorted_list:
  93. page = _page.copy()
  94. is_visible = True
  95. if page['visibility_condition']:
  96. is_visible = page['visibility_condition'](*test_args)
  97. if is_visible:
  98. if page['badge']:
  99. page['badge'] = page['badge'](*test_args)
  100. page['is_active'] = active_link.startswith(page['link'])
  101. visible_pages.append(page)
  102. return visible_pages
  103. def get_default_link(self):
  104. self.assert_site_is_finalized()
  105. return self._sorted_list[0]['link']
  106. usercp = Site('usercp')
  107. users_list = Site('users list')
  108. user_profile = Site('user profile')