dashboard.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. from importlib import import_module
  2. from django.core.urlresolvers import resolve, reverse
  3. from django.template.loader import render_to_string
  4. from jet.dashboard import modules
  5. from jet.dashboard.models import UserDashboardModule
  6. from django.core.context_processors import csrf
  7. from django.utils.translation import ugettext_lazy as _
  8. from jet.ordered_set import OrderedSet
  9. from jet.utils import get_admin_site_name
  10. class Dashboard(object):
  11. columns = 2
  12. children = None
  13. available_children = None
  14. app_label = None
  15. context = None
  16. modules = None
  17. class Media:
  18. css = ()
  19. js = ()
  20. def __init__(self, context, **kwargs):
  21. for key in kwargs:
  22. if hasattr(self.__class__, key):
  23. setattr(self, key, kwargs[key])
  24. self.children = self.children or []
  25. self.available_children = self.available_children or []
  26. self.set_context(context)
  27. def set_context(self, context):
  28. self.context = context
  29. self.update_app_label()
  30. self.init_with_context(context)
  31. self.load_modules()
  32. def init_with_context(self, context):
  33. pass
  34. def load_module(self, module_fullname):
  35. package, module_name = module_fullname.rsplit('.', 1)
  36. package = import_module(package)
  37. module = getattr(package, module_name)
  38. return module
  39. def update_app_label(self):
  40. pass
  41. def create_initial_module_models(self, user):
  42. module_models = []
  43. i = 0
  44. for module in self.children:
  45. column = module.column if module.column else i % self.columns
  46. order = module.order if module.order else int(i / self.columns)
  47. module_models.append(UserDashboardModule.objects.create(
  48. title=module.title,
  49. app_label=self.app_label,
  50. user=user.pk,
  51. module=module.fullname(),
  52. column=column,
  53. order=order,
  54. settings=module.dump_settings(),
  55. children=module.dump_children()
  56. ))
  57. i += 1
  58. return module_models
  59. def load_modules(self):
  60. module_models = UserDashboardModule.objects.filter(
  61. app_label=self.app_label,
  62. user=self.context['request'].user.pk
  63. ).all()
  64. if len(module_models) == 0:
  65. module_models = self.create_initial_module_models(self.context['request'].user)
  66. loaded_modules = []
  67. for module_model in module_models:
  68. module_cls = module_model.load_module()
  69. if module_cls is not None:
  70. module = module_cls(model=module_model, context=self.context)
  71. loaded_modules.append(module)
  72. self.modules = loaded_modules
  73. def render(self):
  74. context = self.context
  75. context.update({
  76. 'columns': range(self.columns),
  77. 'modules': self.modules,
  78. 'app_label': self.app_label,
  79. })
  80. context.update(csrf(context['request']))
  81. return render_to_string('jet.dashboard/dashboard.html', context)
  82. def render_tools(self):
  83. context = self.context
  84. context.update({
  85. 'children': self.children,
  86. 'app_label': self.app_label,
  87. 'available_children': self.available_children
  88. })
  89. context.update(csrf(context['request']))
  90. return render_to_string('jet.dashboard/dashboard_tools.html', context)
  91. def media(self):
  92. unique_css = OrderedSet()
  93. unique_js = OrderedSet()
  94. for js in getattr(self.Media, 'js', ()):
  95. unique_js.add(js)
  96. for css in getattr(self.Media, 'css', ()):
  97. unique_css.add(css)
  98. for module in self.modules:
  99. for js in getattr(module.Media, 'js', ()):
  100. unique_js.add(js)
  101. for css in getattr(module.Media, 'css', ()):
  102. unique_css.add(css)
  103. class Media:
  104. css = list(unique_css)
  105. js = list(unique_js)
  106. return Media
  107. class AppIndexDashboard(Dashboard):
  108. def update_app_label(self):
  109. resolver = resolve(self.context['request'].path)
  110. self.app_label = resolver.kwargs.get('app_label')
  111. def get_app_content_types(self):
  112. return self.app_label + '.*',
  113. def models(self):
  114. return self.app_label + '.*',
  115. class DefaultIndexDashboard(Dashboard):
  116. columns = 3
  117. def init_with_context(self, context):
  118. self.available_children.append(modules.LinkList)
  119. self.available_children.append(modules.Feed)
  120. site_name = get_admin_site_name(context)
  121. # append a link list module for "quick links"
  122. self.children.append(modules.LinkList(
  123. _('Quick links'),
  124. layout='inline',
  125. draggable=False,
  126. deletable=False,
  127. collapsible=False,
  128. children=[
  129. [_('Return to site'), '/'],
  130. [_('Change password'),
  131. reverse('%s:password_change' % site_name)],
  132. [_('Log out'), reverse('%s:logout' % site_name)],
  133. ],
  134. column=0,
  135. order=0
  136. ))
  137. # append an app list module for "Applications"
  138. self.children.append(modules.AppList(
  139. _('Applications'),
  140. exclude=('auth.*',),
  141. column=1,
  142. order=0
  143. ))
  144. # append an app list module for "Administration"
  145. self.children.append(modules.AppList(
  146. _('Administration'),
  147. models=('auth.*',),
  148. column=2,
  149. order=0
  150. ))
  151. # append a recent actions module
  152. self.children.append(modules.RecentActions(
  153. _('Recent Actions'),
  154. 10,
  155. column=0,
  156. order=1
  157. ))
  158. # append a feed module
  159. self.children.append(modules.Feed(
  160. _('Latest Django News'),
  161. feed_url='http://www.djangoproject.com/rss/weblog/',
  162. limit=5,
  163. column=1,
  164. order=1
  165. ))
  166. # append another link list module for "support".
  167. self.children.append(modules.LinkList(
  168. _('Support'),
  169. children=[
  170. {
  171. 'title': _('Django documentation'),
  172. 'url': 'http://docs.djangoproject.com/',
  173. 'external': True,
  174. },
  175. {
  176. 'title': _('Django "django-users" mailing list'),
  177. 'url': 'http://groups.google.com/group/django-users',
  178. 'external': True,
  179. },
  180. {
  181. 'title': _('Django irc channel'),
  182. 'url': 'irc://irc.freenode.net/django',
  183. 'external': True,
  184. },
  185. ],
  186. column=2,
  187. order=1
  188. ))
  189. class DefaultAppIndexDashboard(AppIndexDashboard):
  190. def init_with_context(self, context):
  191. self.available_children.append(modules.LinkList)
  192. self.children.append(modules.ModelList(
  193. title=_('Application models'),
  194. models=self.models(),
  195. column=0,
  196. order=0
  197. ))
  198. self.children.append(modules.RecentActions(
  199. include_list=self.get_app_content_types(),
  200. column=1,
  201. order=0
  202. ))
  203. class DashboardUrls(object):
  204. _urls = []
  205. def get_urls(self):
  206. return self._urls
  207. def register_url(self, url):
  208. self._urls.append(url)
  209. def register_urls(self, urls):
  210. self._urls.extend(urls)
  211. urls = DashboardUrls()