7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
10 # FOR A PARTICULAR PURPOSE. |
10 # FOR A PARTICULAR PURPOSE. |
11 # |
11 # |
12 from pyams_workflow.interfaces import IWorkflowPublicationInfo |
|
13 |
|
14 |
12 |
15 __docformat__ = 'restructuredtext' |
13 __docformat__ = 'restructuredtext' |
16 |
14 |
17 import json |
15 import json |
18 |
16 |
|
17 from hypatia.catalog import CatalogQuery |
|
18 from hypatia.interfaces import ICatalog |
|
19 from hypatia.query import Eq |
19 from pyramid.decorator import reify |
20 from pyramid.decorator import reify |
20 from pyramid.exceptions import NotFound |
21 from pyramid.exceptions import NotFound |
21 from pyramid.view import view_config |
22 from pyramid.view import view_config |
22 from z3c.form import button, field |
23 from z3c.form import button, field |
23 from z3c.table.column import GetAttrColumn |
24 from z3c.table.column import GetAttrColumn |
24 from z3c.table.interfaces import IColumn, IValues |
25 from z3c.table.interfaces import IColumn, IValues |
25 from zope.interface import Interface |
26 from zope.interface import Interface |
26 from zope.schema import Bool, TextLine |
27 from zope.schema import Bool, TextLine |
27 |
28 |
|
29 from pyams_catalog.query import CatalogResultSet |
|
30 from pyams_content import _ |
28 from pyams_content.features.redirect.interfaces import IRedirectionManager, IRedirectionManagerTarget |
31 from pyams_content.features.redirect.interfaces import IRedirectionManager, IRedirectionManagerTarget |
29 from pyams_content.interfaces import MANAGE_SITE_ROOT_PERMISSION |
32 from pyams_content.interfaces import MANAGE_SITE_ROOT_PERMISSION |
30 from pyams_content.zmi import pyams_content |
33 from pyams_content.zmi import pyams_content |
31 from pyams_form.form import AJAXAddForm |
34 from pyams_form.form import AJAXAddForm |
32 from pyams_form.interfaces.form import IWidgetsSuffixViewletsManager |
35 from pyams_form.interfaces.form import IWidgetsSuffixViewletsManager |
38 from pyams_skin.interfaces import IContentHelp, IPageHeader, IUserSkinnable |
41 from pyams_skin.interfaces import IContentHelp, IPageHeader, IUserSkinnable |
39 from pyams_skin.interfaces.viewlet import IToolbarViewletManager |
42 from pyams_skin.interfaces.viewlet import IToolbarViewletManager |
40 from pyams_skin.layer import IPyAMSLayer |
43 from pyams_skin.layer import IPyAMSLayer |
41 from pyams_skin.page import DefaultPageHeaderAdapter |
44 from pyams_skin.page import DefaultPageHeaderAdapter |
42 from pyams_skin.skin import apply_skin |
45 from pyams_skin.skin import apply_skin |
43 from pyams_skin.table import AttributeSwitcherColumn, BaseTable, I18nColumn, SorterColumn, TrashColumn, ImageColumn |
46 from pyams_skin.table import AttributeSwitcherColumn, BaseTable, I18nColumn, ImageColumn, SorterColumn, TrashColumn |
44 from pyams_skin.viewlet.menu import MenuItem |
47 from pyams_skin.viewlet.menu import MenuItem |
45 from pyams_skin.viewlet.toolbar import ToolbarAction |
48 from pyams_skin.viewlet.toolbar import ToolbarAction |
46 from pyams_template.template import template_config |
49 from pyams_template.template import template_config |
47 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config |
50 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config |
48 from pyams_utils.fanstatic import get_resource_path |
51 from pyams_utils.fanstatic import get_resource_path |
|
52 from pyams_utils.registry import get_utility |
49 from pyams_utils.request import copy_request |
53 from pyams_utils.request import copy_request |
50 from pyams_utils.url import absolute_url |
54 from pyams_utils.url import absolute_url |
51 from pyams_viewlet.viewlet import Viewlet, viewlet_config |
55 from pyams_viewlet.viewlet import Viewlet, viewlet_config |
|
56 from pyams_workflow.interfaces import IWorkflow, IWorkflowPublicationInfo, IWorkflowVersions |
52 from pyams_zmi.form import AdminDialogAddForm |
57 from pyams_zmi.form import AdminDialogAddForm |
53 from pyams_zmi.interfaces.menu import ISiteManagementMenu |
58 from pyams_zmi.interfaces.menu import ISiteManagementMenu |
54 from pyams_zmi.layer import IAdminLayer |
59 from pyams_zmi.layer import IAdminLayer |
55 from pyams_zmi.view import ContainerAdminView |
60 from pyams_zmi.view import ContainerAdminView |
56 |
|
57 from pyams_content import _ |
|
58 |
61 |
59 |
62 |
60 @viewlet_config(name='redirections.menu', context=IRedirectionManagerTarget, layer=IPyAMSLayer, |
63 @viewlet_config(name='redirections.menu', context=IRedirectionManagerTarget, layer=IPyAMSLayer, |
61 manager=ISiteManagementMenu, permission=MANAGE_SITE_ROOT_PERMISSION, weight=35) |
64 manager=ISiteManagementMenu, permission=MANAGE_SITE_ROOT_PERMISSION, weight=35) |
62 class RedirectionMenu(MenuItem): |
65 class RedirectionMenu(MenuItem): |
208 _header = _("URL pattern") |
211 _header = _("URL pattern") |
209 attrName = 'url_pattern' |
212 attrName = 'url_pattern' |
210 weight = 10 |
213 weight = 10 |
211 |
214 |
212 |
215 |
|
216 MISSING_TARGET = object() |
|
217 |
|
218 |
213 @adapter_config(name='visible', context=(IRedirectionManagerTarget, IPyAMSLayer, RedirectionsContainerTable), |
219 @adapter_config(name='visible', context=(IRedirectionManagerTarget, IPyAMSLayer, RedirectionsContainerTable), |
214 provides=IColumn) |
220 provides=IColumn) |
215 class RedirectionsContainerVisibleColumn(ImageColumn): |
221 class RedirectionsContainerVisibleColumn(ImageColumn): |
216 """Redirections container visible column""" |
222 """Redirections container visible column""" |
217 |
223 |
218 cssClasses = {'th': 'action', 'td': 'action'} |
224 cssClasses = {'th': 'action', 'td': 'action'} |
219 weight = 19 |
225 weight = 19 |
220 |
226 |
221 def get_icon_class(self, item): |
227 def __init__(self, context, request, table): |
222 if item.reference: |
228 super(RedirectionsContainerVisibleColumn, self).__init__(context, request, table) |
223 target = item.target |
229 self.targets = {} |
|
230 |
|
231 def get_status(self, reference): |
|
232 status = self.targets.get(reference, MISSING_TARGET) |
|
233 if status is not MISSING_TARGET: |
|
234 return status |
|
235 status = '' |
|
236 hint = '' |
|
237 catalog = get_utility(ICatalog) |
|
238 params = Eq(catalog['oid'], reference) |
|
239 results = list(CatalogResultSet(CatalogQuery(catalog).query(params))) |
|
240 if results: |
|
241 target = results[0] |
|
242 versions = IWorkflowVersions(target, None) |
|
243 if versions is not None: |
|
244 workflow = IWorkflow(target, None) |
|
245 versions = versions.get_versions(workflow.published_states) |
|
246 if versions: |
|
247 target = versions.pop() |
|
248 else: |
|
249 target = None |
|
250 status = 'fa-eye-slash text-danger' |
|
251 hint = _("Target has no published version") |
224 if target is not None: |
252 if target is not None: |
225 info = IWorkflowPublicationInfo(target, None) |
253 info = IWorkflowPublicationInfo(target, None) |
226 if info is not None: |
254 if info is not None: |
227 if info.is_published(): |
255 if info.is_published(): |
228 return 'fa-eye' |
256 status = 'fa-eye' |
|
257 hint = _("Target is published") |
229 else: |
258 else: |
230 return 'fa-eye-slash text-danger' |
259 status = 'fa-eye-slash text-danger' |
231 return '' |
260 hint = _("Target is not published") |
|
261 self.targets[reference] = result = { |
|
262 'status': status, |
|
263 'hint': hint |
|
264 } |
|
265 return result |
|
266 |
|
267 def get_icon_class(self, item): |
|
268 if item.reference: |
|
269 return self.get_status(item.reference).get('status', 'fa-question') |
232 else: |
270 else: |
233 return 'fa-external-link' |
271 return 'fa-external-link' |
234 |
272 |
235 def get_icon_hint(self, item): |
273 def get_icon_hint(self, item): |
236 if item.reference: |
274 if item.reference: |
237 target = item.target |
275 hint = self.get_status(item.reference).get('hint') |
238 if target is not None: |
276 return self.request.localizer.translate(hint) |
239 info = IWorkflowPublicationInfo(target, None) |
|
240 if info is not None: |
|
241 if info.is_published(): |
|
242 return self.request.localizer.translate(_("Target is published")) |
|
243 else: |
|
244 return self.request.localizer.translate(_("Target is not published")) |
|
245 return '' |
|
246 else: |
277 else: |
247 return self.request.localizer.translate(_("External link")) |
278 return self.request.localizer.translate(_("External link")) |
248 |
279 |
249 |
280 |
250 @adapter_config(name='target', context=(IRedirectionManagerTarget, IPyAMSLayer, RedirectionsContainerTable), |
281 @adapter_config(name='target', context=(IRedirectionManagerTarget, IPyAMSLayer, RedirectionsContainerTable), |