1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2010-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# See the file COPYING for details.
"""
Menus
"""
import datetime
from django.conf import settings
from django.core.cache import cache
from django.core.urlresolvers import reverse
_extra_menus = []
# collect menu from INSTALLED_APPS
for app in settings.INSTALLED_APPS:
mod = __import__(app, fromlist=['ishtar_menu'])
if hasattr(mod, 'ishtar_menu'):
menu = getattr(mod, 'ishtar_menu')
_extra_menus += menu.MENU_SECTIONS
# sort
__section_items = [mnu for order, mnu in sorted(_extra_menus,
key=lambda x:x[0])]
# regroup menus
_section_items, __keys = [], []
for section_item in __section_items:
if section_item.idx not in __keys:
__keys.append(section_item.idx)
_section_items.append(section_item)
continue
section_childs = _section_items[__keys.index(section_item.idx)].childs
childs_idx = [child.idx for child in section_childs]
for child in section_item.childs:
if child.idx not in childs_idx:
section_childs.append(child)
class Menu:
childs = _section_items
def __init__(self, user, current_action=None, session=None):
self.user = user
self.initialized = False
self.items = {}
self.current_action = current_action
self.current_section = None
self.current_url = None
self.current_section = ""
self.current_sections = []
self.current_subsection = ""
self.current_subsections = []
self.current_subsubsection = ""
self.current_subsubsections = []
self.selected_idx = None
self.session = session
self.items_by_idx = {}
def set_menu_updated_key(self):
cache_key = u"{}-{}".format(
settings.PROJECT_SLUG, 'menu_updated')
time = unicode(datetime.datetime.now().isoformat())
cache.set(cache_key, time, settings.CACHE_TIMEOUT)
self.initialized = time
def init(self, force=False):
cache_key = u"{}-{}".format(
settings.PROJECT_SLUG, 'menu_updated')
menu_updated = cache.get(cache_key)
if not force and menu_updated and self.initialized \
and self.initialized == menu_updated:
return
menu_updated = cache.get(cache_key)
self.set_menu_updated_key()
self.items = {}
self.items_by_idx = {}
for idx, main_menu in enumerate(self.childs):
self.items_by_idx[main_menu.idx] = main_menu
for child in main_menu.childs:
self.items_by_idx[child.idx] = child
if hasattr(child, 'childs'):
for subchild in child.childs:
self.items_by_idx[subchild.idx] = subchild
selected = main_menu.set_items(
self.user, self.items,
self.current_action, session=self.session)
if selected:
self.selected_idx = idx
self.initialized = True
def get_current_selection(self, current_path):
# current_section, current_subsection, etc. are current labels
# current_sections, current_subsections, etc. are list of:
# (label, url, has_children)
self.current_section = ''
self.current_sections = []
self.current_subsection = ""
self.current_subsections = []
self.current_subsubsection = ""
self.current_subsubsections = []
self.current_url = None
for section in self.childs:
if not section.available:
continue
section_url = None
subsections = []
if not self.current_section:
# initialize by default with the first section
self.current_section = section.label
selected_section = None
for menu_item in section.childs:
if not menu_item.available:
continue
if not hasattr(menu_item, 'childs') or not menu_item.childs:
item_url = reverse('action', args=[menu_item.idx])
if not section_url:
section_url = item_url
subsections.append([menu_item.label, item_url, False])
if item_url in current_path:
self.current_url = item_url
self.current_section = section.label
self.current_subsection = menu_item.label
selected_section = True
continue
subsection_url = None
selected_subsection = None
subsubsections = []
for menu_subitem in menu_item.childs:
if not menu_subitem.available:
continue
item_url = reverse('action', args=[menu_subitem.idx])
if not section_url:
section_url = item_url
if not subsection_url:
subsection_url = item_url
subsections.append([menu_item.label, item_url, True])
subsubsections.append([menu_subitem.label, item_url, False])
if item_url in current_path:
self.current_url = item_url
self.current_section = section.label
self.current_subsection = menu_item.label
self.current_subsubsection = menu_subitem.label
selected_section = True
selected_subsection = True
if selected_subsection:
self.current_subsubsections = subsubsections
if selected_section:
self.current_subsections = subsections
if not section_url:
section_url = "/"
self.current_sections.append([section.label, section_url,
bool(subsections)])
menu = Menu(None)
menu.init()
|