src/pyams_content/component/paragraph/association.py
changeset 1398 fc32ec8a8f53
equal deleted inserted replaced
1397:d05fc6aa4217 1398:fc32ec8a8f53
       
     1 #
       
     2 # Copyright (c) 2015-2020 Thierry Florac <tflorac AT ulthar.net>
       
     3 # All Rights Reserved.
       
     4 #
       
     5 # This software is subject to the provisions of the Zope Public License,
       
     6 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     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
       
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    10 # FOR A PARTICULAR PURPOSE.
       
    11 #
       
    12 
       
    13 """PyAMS_*** module
       
    14 
       
    15 """
       
    16 
       
    17 __docformat__ = 'restructuredtext'
       
    18 
       
    19 import re
       
    20 
       
    21 from pyquery import PyQuery
       
    22 from pyramid.threadlocal import get_current_registry
       
    23 from zope.lifecycleevent import ObjectCreatedEvent
       
    24 
       
    25 from pyams_content.component.association import IAssociationContainer
       
    26 from pyams_content.component.extfile import IBaseExtFile
       
    27 from pyams_content.component.links import ExternalLink, IExternalLink, IInternalLink, IMailtoLink, \
       
    28     InternalLink, MailtoLink
       
    29 from pyams_i18n.interfaces import II18n
       
    30 from pyams_sequence.interfaces import ISequentialIntIds
       
    31 from pyams_utils.registry import get_utility
       
    32 from pyams_utils.request import check_request
       
    33 from pyams_utils.url import absolute_url
       
    34 
       
    35 
       
    36 FULL_EMAIL = re.compile('(.*) \<(.*)\>')
       
    37 
       
    38 
       
    39 def check_associations(context, body, lang, notify=True):
       
    40     """Check for link associations from HTML content"""
       
    41     associations = IAssociationContainer(context, None)
       
    42     if associations is None:
       
    43         return
       
    44     registry = get_current_registry()
       
    45     html = PyQuery('<html>{0}</html>'.format(body))
       
    46     for link in html('a[href]'):
       
    47         link_info = None
       
    48         has_link = False
       
    49         href = link.attrib['href']
       
    50         if href.startswith('oid://'):
       
    51             sequence = get_utility(ISequentialIntIds)
       
    52             oid = sequence.get_full_oid(href.split('//', 1)[1])
       
    53             for association in associations.values():
       
    54                 internal_info = IInternalLink(association, None)
       
    55                 if (internal_info is not None) and (internal_info.reference == oid):
       
    56                     has_link = True
       
    57                     break
       
    58             if not has_link:
       
    59                 link_info = InternalLink()
       
    60                 link_info.visible = False
       
    61                 link_info.reference = oid
       
    62                 link_info.title = {lang: link.attrib.get('title') or link.text}
       
    63         elif href.startswith('mailto:'):
       
    64             name = None
       
    65             email = href[7:]
       
    66             if '<' in email:
       
    67                 groups = FULL_EMAIL.findall(email)
       
    68                 if groups:
       
    69                     name, email = groups[0]
       
    70             for association in associations.values():
       
    71                 mailto_info = IMailtoLink(association, None)
       
    72                 if (mailto_info is not None) and (mailto_info.address == email):
       
    73                     has_link = True
       
    74                     break
       
    75             if not has_link:
       
    76                 link_info = MailtoLink()
       
    77                 link_info.visible = False
       
    78                 link_info.address = email
       
    79                 link_info.address_name = name or email
       
    80                 link_info.title = {lang: link.attrib.get('title') or link.text}
       
    81         elif href.startswith('http://') or href.startswith('https://'):
       
    82             for association in associations.values():
       
    83                 external_info = IExternalLink(association, None)
       
    84                 if (external_info is not None) and (external_info.url == href):
       
    85                     has_link = True
       
    86                     break
       
    87                 else:
       
    88                     extfile_info = IBaseExtFile(association, None)
       
    89                     if extfile_info is not None:
       
    90                         request = check_request()
       
    91                         extfile_url = absolute_url(
       
    92                             II18n(extfile_info).query_attribute('data', request=request),
       
    93                             request=request)
       
    94                         if extfile_url.endswith(href):
       
    95                             has_link = True
       
    96                             break
       
    97             if not has_link:
       
    98                 link_info = ExternalLink()
       
    99                 link_info.visible = False
       
   100                 link_info.url = href
       
   101                 link_info.title = {lang: link.attrib.get('title') or link.text}
       
   102         if link_info is not None:
       
   103             registry.notify(ObjectCreatedEvent(link_info))
       
   104             associations.append(link_info, notify=notify)