root/cpsskins/branches/paris-sprint-2006/thememanager.py

Revision 3581, 11.0 kB (checked in by jmorliaguet, 2 years ago)

- saving work

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 ##############################################################################
2 #
3 # Copyright (c) 2005-2006 Nuxeo and Contributors.
4 # All Rights Reserved.
5 #
6 # This software is subject to the provisions of the Zope Public License,
7 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11 # FOR A PARTICULAR PURPOSE.
12 #
13 ##############################################################################
14 """
15
16 $Id$
17 """
18 __docformat__ = "reStructuredText"
19
20 import logging
21
22 from zope.app.container.btree import BTreeContainer
23 from zope.app.container.interfaces import INameChooser
24 from zope.component import getUtility
25 from zope.component.persistentregistry import PersistentComponents
26 from zope.interface import implements, Interface
27 from zope.i18nmessageid import MessageFactory
28 from zope.traversing.api import getName, getParent
29
30 from cpsskins.caching import ImageCache, IImageCache
31 from cpsskins.elements.interfaces import IFormattable
32 from cpsskins.elements.interfaces import ITheme, IThemePage, IThemeContainer
33 from cpsskins.ontology import isDefault, hasFormat
34 from cpsskins.perspectives import Perspective
35 from cpsskins.perspectives.interfaces import IPerspective
36 from cpsskins.relations import MonadicRelation
37 from cpsskins.setup.interfaces import IResourceManager, IResource
38 from cpsskins.setup.presets import Presets, IPresets
39 from cpsskins.storage.formats import FormatStorage, IFormatStorage
40 from cpsskins.storage.locations import LocationStorage, ILocationStorage
41 from cpsskins.storage.portlets import PortletStorage, IPortletStorage
42 from cpsskins.storage.relations import RelationStorage, IRelationStorage
43 from cpsskins.storage.snapshots import ISnapshotStorage, SnapshotStorage
44 from cpsskins.uids import IUids, Uids
45
46 logger = logging.getLogger("cpsskins")
47
48 _ = MessageFactory("cpsskins")
49
50 def added(object, event):
51     object.registerUtilities()
52
53 class IThemeManagementFolder(Interface):
54     """Interface for theme management.
55
56     The methods may be moved to other classes.
57     """
58
59     def registerUtilities():
60         """Register the various components."""
61
62     def getIdRegistry():
63         """Return the unique id registry."""
64
65     def getImageCache():
66         """Return the image cache."""
67
68     def getRelationStorage():
69         """Return the relation storage."""
70
71     def getFormatStorage():
72         """Return the format storage."""
73
74     def getPortletStorage():
75         """Return the portlet storage."""
76
77     def getLocationStorage():
78         """Return the location storage."""
79
80     def getSnapshotStorage():
81         """Return the snapshot storage."""
82
83     def getPresets():
84         """Return the presets."""
85
86     def registerElement(element):
87         """Add an element to the unique id registry."""
88
89     def unregisterElement(element):
90         """Remove an element from the unique id registry."""
91
92     def getElementById(id):
93         """Return an element by its unique id. """
94
95     def addTheme(theme, name):
96         """Add a theme."""
97
98     def addPage(theme, page, name):
99         """Add a page."""
100
101     def getThemes():
102         """Return the list of available themes."""
103
104     def getPages(theme):
105         """Return the list of available pages in a theme."""
106
107     def deleteTheme(name):
108         """Delete a theme."""
109
110     def deleteAllThemes():
111         """Delete all themes."""
112
113     def getThemeByName(name):
114         """Return a theme by its name."""
115
116     def getPageByName(name):
117         """Return a page by its name."""
118
119     def isDefault(object):
120         """Return true if the object is used by default."""
121
122     def setAsDefault(object):
123         """Set the object as a default object."""
124
125     def getDefaultTheme():
126         """Return the default theme."""
127
128     def getDefaultPage(theme):
129         """Return the default page of a theme."""
130
131     def removeFormats(object):
132         """Remove the formats of an element"""
133
134     def listPerspectives():
135         """Return the list of perspectives."""
136
137     def addPerspective(perspective, id):
138         """Add a perspective to the storage"""
139
140     def getLocation(context):
141         """Return the location in a given context"""
142
143 class ThemeManagementFolder(BTreeContainer, PersistentComponents):
144     """A theme management utility that can contain multiple .
145     themes
146
147     >>> from zope.interface.verify import verifyClass
148     >>> verifyClass(IThemeManagementFolder, ThemeManagementFolder)
149     True
150
151     """
152     implements(IThemeManagementFolder, IThemeContainer)
153
154     def __init__(self):
155         BTreeContainer.__init__(self)
156         PersistentComponents.__init__(self)
157         # registries, storages, etc.
158         self[u'uids'] = Uids()
159         self[u'imagecache'] = ImageCache()
160         self[u'presets'] = Presets()
161         self[u'relations'] = RelationStorage()
162         self[u'portlets'] = PortletStorage()
163         self[u'formats'] = FormatStorage()
164         self[u'locations'] = LocationStorage()
165         # snapshots
166         self[u'snapshots'] = SnapshotStorage()
167
168     ###################################################################
169     # Local utilities
170     ###################################################################
171
172     def registerUtilities(self):
173         self.registerUtility(self[u'uids'], IUids)
174         self.registerUtility(self[u'snapshots'], ISnapshotStorage)
175         self.registerUtility(self[u'imagecache'], IImageCache)
176         self.registerUtility(self[u'presets'], IPresets)
177         self.registerUtility(self[u'relations'], IRelationStorage)
178         self.registerUtility(self[u'portlets'], IPortletStorage)
179         self.registerUtility(self[u'formats'], IFormatStorage)
180         self.registerUtility(self[u'locations'], ILocationStorage)
181
182     def getIdRegistry(self):
183         return self.getUtility(IUids)
184
185     def getImageCache(self):
186         return self.getUtility(IImageCache)
187
188     def getRelationStorage(self):
189         return self.getUtility(IRelationStorage)
190
191     def getFormatStorage(self):
192         return self.getUtility(IFormatStorage)
193
194     def getPortletStorage(self):
195         return self.getUtility(IPortletStorage)
196
197     def getLocationStorage(self):
198         return self.getUtility(ILocationStorage)
199
200     def getSnapshotStorage(self):
201         return self.getUtility(ISnapshotStorage)
202
203     def getPresets(self):
204         return self.getUtility(IPresets)
205
206     ###################################################################
207     # Unique id registry
208     ###################################################################
209
210     def registerElement(self, element):
211         intids = self.getIdRegistry()
212         id = intids.queryId(element)
213         if id is None:
214             id = intids.register(element)
215             # store the element's id in the element itself.
216             element.identifier = id
217         else:
218             logger.debug("The element %s is already registered. "
219                          "No need to register it again.", repr(element))
220         return id
221
222     def unregisterElement(self, element):
223         try:
224             self.getIdRegistry().unregister(element)
225         except KeyError:
226             logger.debug("The element %s is not registered", repr(element))
227
228     def getElementById(self, id):
229         return self.getIdRegistry().getObject(int(id))
230
231     ###################################################################
232     # Themes and pages
233     ###################################################################
234
235     def addTheme(self, theme, name=u''):
236         if not ITheme.providedBy(theme):
237             raise("Must specify a theme.")
238
239         name = INameChooser(self).chooseName(name, theme)
240         self[name] = theme
241         return name
242
243     def addPage(self, theme, page, name=u''):
244         if not IThemePage.providedBy(page):
245             raise("Must specify a theme page.")
246
247         name = INameChooser(theme).chooseName(name, page)
248         theme[name] = page
249         return name
250
251     def getThemes(self):
252         return [theme for name, theme in self.getUtilitiesFor(ITheme)]
253
254     def getPages(self, theme):
255         return [page for name, page in theme.getUtilitiesFor(IThemePage)]
256
257     def deleteTheme(self, name):
258         for k, v in self.getUtilitiesFor(ITheme):
259             if k == name:
260                 del self[getName(v)]
261                 return
262
263         raise KeyError("No such theme: %s." % name)
264
265     def deleteAllThemes(self):
266         for k, v in self.getUtilitiesFor(ITheme):
267             del self[getName(v)]
268
269     def getThemeByName(self, name):
270         for k, v in self.getUtilitiesFor(ITheme):
271             if k == name:
272                 return v
273         return None
274
275     def getPageByName(self, name):
276         theme_name, page_name = name.split(u':')
277         theme = self.getThemeByName(theme_name)
278         if theme is None:
279             return None
280         for k, v in theme.getUtilitiesFor(IThemePage):
281             if k == page_name:
282                 return v
283         return None
284
285     def isDefault(self, object):
286         relations = self.getRelationStorage()
287         res = relations.search(predicate=isDefault, first=object)
288         return bool(res)
289
290     def setAsDefault(self, object):
291         relations = self.getRelationStorage()
292         relations.add(MonadicRelation(isDefault, object))
293         defaults = []
294         for o in object.getSiblings():
295             defaults.extend(relations.search(predicate=isDefault, first=o))
296         relations.remove(defaults)
297
298     def getDefaultTheme(self):
299         for theme in self.getThemes():
300             if theme.isDefault():
301                 return theme
302         return None
303
304     def getDefaultPage(self, theme):
305         for page in theme.getPages():
306             if page.isDefault():
307                 return page
308         return None
309
310     ###################################################################
311     # Formats
312     ###################################################################
313
314     def removeFormats(self, object):
315
316         # Physically remove the formats
317         formats = self.getFormatStorage()
318         formats.remove([getName(f) for f
319                         in IFormattable(object).getFormats(resolve=False)])
320
321         # Remove the relation
322         relations = self.getRelationStorage()
323         format_relations = relations.search(first=object, predicate=hasFormat)
324         relations.remove(format_relations)
325
326     ###################################################################
327     # Perspectives
328     ###################################################################
329
330     def listPerspectives(self):
331         resources = getUtility(IResourceManager)
332         return [IResource(r).getResource() for r in
333                 resources.list(type=IPerspective, context=self)]
334
335     def addPerspective(self, name, title):
336         perspective = Perspective(name)
337         resources = getUtility(IResourceManager)
338         resources.register(name=name, resource=perspective, context=self)
339
340     ###################################################################
341     # Locations
342     ###################################################################
343
344     def getLocation(self, path, root=u''):
345         locations = self.getLocationStorage()
346         return locations.find(path, root)
347
Note: See TracBrowser for help on using the browser.