src/pyams_content/features/redirect/zmi/container.py
changeset 1295 6aded60a6fe7
parent 1288 ef227fc388a6
child 1436 758f1ae21724
equal deleted inserted replaced
1294:4eebb9dfb488 1295:6aded60a6fe7
     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),