src/pyams_content/component/paragraph/association.py
changeset 1398 fc32ec8a8f53
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/association.py	Fri Jul 03 18:43:46 2020 +0200
@@ -0,0 +1,104 @@
+#
+# Copyright (c) 2015-2020 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+"""PyAMS_*** module
+
+"""
+
+__docformat__ = 'restructuredtext'
+
+import re
+
+from pyquery import PyQuery
+from pyramid.threadlocal import get_current_registry
+from zope.lifecycleevent import ObjectCreatedEvent
+
+from pyams_content.component.association import IAssociationContainer
+from pyams_content.component.extfile import IBaseExtFile
+from pyams_content.component.links import ExternalLink, IExternalLink, IInternalLink, IMailtoLink, \
+    InternalLink, MailtoLink
+from pyams_i18n.interfaces import II18n
+from pyams_sequence.interfaces import ISequentialIntIds
+from pyams_utils.registry import get_utility
+from pyams_utils.request import check_request
+from pyams_utils.url import absolute_url
+
+
+FULL_EMAIL = re.compile('(.*) \<(.*)\>')
+
+
+def check_associations(context, body, lang, notify=True):
+    """Check for link associations from HTML content"""
+    associations = IAssociationContainer(context, None)
+    if associations is None:
+        return
+    registry = get_current_registry()
+    html = PyQuery('<html>{0}</html>'.format(body))
+    for link in html('a[href]'):
+        link_info = None
+        has_link = False
+        href = link.attrib['href']
+        if href.startswith('oid://'):
+            sequence = get_utility(ISequentialIntIds)
+            oid = sequence.get_full_oid(href.split('//', 1)[1])
+            for association in associations.values():
+                internal_info = IInternalLink(association, None)
+                if (internal_info is not None) and (internal_info.reference == oid):
+                    has_link = True
+                    break
+            if not has_link:
+                link_info = InternalLink()
+                link_info.visible = False
+                link_info.reference = oid
+                link_info.title = {lang: link.attrib.get('title') or link.text}
+        elif href.startswith('mailto:'):
+            name = None
+            email = href[7:]
+            if '<' in email:
+                groups = FULL_EMAIL.findall(email)
+                if groups:
+                    name, email = groups[0]
+            for association in associations.values():
+                mailto_info = IMailtoLink(association, None)
+                if (mailto_info is not None) and (mailto_info.address == email):
+                    has_link = True
+                    break
+            if not has_link:
+                link_info = MailtoLink()
+                link_info.visible = False
+                link_info.address = email
+                link_info.address_name = name or email
+                link_info.title = {lang: link.attrib.get('title') or link.text}
+        elif href.startswith('http://') or href.startswith('https://'):
+            for association in associations.values():
+                external_info = IExternalLink(association, None)
+                if (external_info is not None) and (external_info.url == href):
+                    has_link = True
+                    break
+                else:
+                    extfile_info = IBaseExtFile(association, None)
+                    if extfile_info is not None:
+                        request = check_request()
+                        extfile_url = absolute_url(
+                            II18n(extfile_info).query_attribute('data', request=request),
+                            request=request)
+                        if extfile_url.endswith(href):
+                            has_link = True
+                            break
+            if not has_link:
+                link_info = ExternalLink()
+                link_info.visible = False
+                link_info.url = href
+                link_info.title = {lang: link.attrib.get('title') or link.text}
+        if link_info is not None:
+            registry.notify(ObjectCreatedEvent(link_info))
+            associations.append(link_info, notify=notify)
\ No newline at end of file