src/pyams_content/features/redirect/zmi/container.py
changeset 1295 6aded60a6fe7
parent 1288 ef227fc388a6
child 1436 758f1ae21724
--- a/src/pyams_content/features/redirect/zmi/container.py	Fri Mar 22 11:03:28 2019 +0100
+++ b/src/pyams_content/features/redirect/zmi/container.py	Fri Mar 22 12:46:49 2019 +0100
@@ -9,13 +9,14 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
-from pyams_workflow.interfaces import IWorkflowPublicationInfo
-
 
 __docformat__ = 'restructuredtext'
 
 import json
 
+from hypatia.catalog import CatalogQuery
+from hypatia.interfaces import ICatalog
+from hypatia.query import Eq
 from pyramid.decorator import reify
 from pyramid.exceptions import NotFound
 from pyramid.view import view_config
@@ -25,6 +26,8 @@
 from zope.interface import Interface
 from zope.schema import Bool, TextLine
 
+from pyams_catalog.query import CatalogResultSet
+from pyams_content import _
 from pyams_content.features.redirect.interfaces import IRedirectionManager, IRedirectionManagerTarget
 from pyams_content.interfaces import MANAGE_SITE_ROOT_PERMISSION
 from pyams_content.zmi import pyams_content
@@ -40,22 +43,22 @@
 from pyams_skin.layer import IPyAMSLayer
 from pyams_skin.page import DefaultPageHeaderAdapter
 from pyams_skin.skin import apply_skin
-from pyams_skin.table import AttributeSwitcherColumn, BaseTable, I18nColumn, SorterColumn, TrashColumn, ImageColumn
+from pyams_skin.table import AttributeSwitcherColumn, BaseTable, I18nColumn, ImageColumn, SorterColumn, TrashColumn
 from pyams_skin.viewlet.menu import MenuItem
 from pyams_skin.viewlet.toolbar import ToolbarAction
 from pyams_template.template import template_config
 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
 from pyams_utils.fanstatic import get_resource_path
+from pyams_utils.registry import get_utility
 from pyams_utils.request import copy_request
 from pyams_utils.url import absolute_url
 from pyams_viewlet.viewlet import Viewlet, viewlet_config
+from pyams_workflow.interfaces import IWorkflow, IWorkflowPublicationInfo, IWorkflowVersions
 from pyams_zmi.form import AdminDialogAddForm
 from pyams_zmi.interfaces.menu import ISiteManagementMenu
 from pyams_zmi.layer import IAdminLayer
 from pyams_zmi.view import ContainerAdminView
 
-from pyams_content import _
-
 
 @viewlet_config(name='redirections.menu', context=IRedirectionManagerTarget, layer=IPyAMSLayer,
                 manager=ISiteManagementMenu, permission=MANAGE_SITE_ROOT_PERMISSION, weight=35)
@@ -210,6 +213,9 @@
     weight = 10
 
 
+MISSING_TARGET = object()
+
+
 @adapter_config(name='visible', context=(IRedirectionManagerTarget, IPyAMSLayer, RedirectionsContainerTable),
                 provides=IColumn)
 class RedirectionsContainerVisibleColumn(ImageColumn):
@@ -218,31 +224,56 @@
     cssClasses = {'th': 'action', 'td': 'action'}
     weight = 19
 
-    def get_icon_class(self, item):
-        if item.reference:
-            target = item.target
+    def __init__(self, context, request, table):
+        super(RedirectionsContainerVisibleColumn, self).__init__(context, request, table)
+        self.targets = {}
+
+    def get_status(self, reference):
+        status = self.targets.get(reference, MISSING_TARGET)
+        if status is not MISSING_TARGET:
+            return status
+        status = ''
+        hint = ''
+        catalog = get_utility(ICatalog)
+        params = Eq(catalog['oid'], reference)
+        results = list(CatalogResultSet(CatalogQuery(catalog).query(params)))
+        if results:
+            target = results[0]
+            versions = IWorkflowVersions(target, None)
+            if versions is not None:
+                workflow = IWorkflow(target, None)
+                versions = versions.get_versions(workflow.published_states)
+                if versions:
+                    target = versions.pop()
+                else:
+                    target = None
+                    status = 'fa-eye-slash text-danger'
+                    hint = _("Target has no published version")
             if target is not None:
                 info = IWorkflowPublicationInfo(target, None)
                 if info is not None:
                     if info.is_published():
-                        return 'fa-eye'
+                        status = 'fa-eye'
+                        hint = _("Target is published")
                     else:
-                        return 'fa-eye-slash text-danger'
-            return ''
+                        status = 'fa-eye-slash text-danger'
+                        hint = _("Target is not published")
+        self.targets[reference] = result = {
+            'status': status,
+            'hint': hint
+        }
+        return result
+
+    def get_icon_class(self, item):
+        if item.reference:
+            return self.get_status(item.reference).get('status', 'fa-question')
         else:
             return 'fa-external-link'
 
     def get_icon_hint(self, item):
         if item.reference:
-            target = item.target
-            if target is not None:
-                info = IWorkflowPublicationInfo(target, None)
-                if info is not None:
-                    if info.is_published():
-                        return self.request.localizer.translate(_("Target is published"))
-                    else:
-                        return self.request.localizer.translate(_("Target is not published"))
-            return ''
+            hint = self.get_status(item.reference).get('hint')
+            return self.request.localizer.translate(hint)
         else:
             return self.request.localizer.translate(_("External link"))