Esempio n. 1
0
def assign_canonical_url(obj, event):
    """Assing canonical URL to the object after it is published."""
    if event.status['review_state'] not in ('published', ):
        # don't a assign a canonical URL as this is not a public state
        return

    record = ISocialLikeSettings.__identifier__ + '.canonical_domain'
    try:
        canonical_domain = api.portal.get_registry_record(record)
    except api.exc.InvalidParameterError:
        # package is not installed or record deleted; do nothing
        return

    # we can't assign a canonical URL without a canonical domain
    if canonical_domain:
        # FIXME: we're currently ignoring the Plone site id
        #        https://github.com/collective/sc.social.like/issues/119
        path = '/'.join(obj.getPhysicalPath()[2:])
        obj.canonical_url = '{0}/{1}'.format(canonical_domain, path)
        logger.info('canonical_url set for {0}'.format(obj.canonical_url))
    else:
        logger.warn(
            'Canonical domain not set in Social Media configlet; '
            "Facebook's Open Graph canonical URL (og:orl) will not be available"
        )
Esempio n. 2
0
def facebook_prefetching(obj, event):
    """Call Facebook Graph API endpoint to keep metadata of published
    objects always updated.
    """
    record = ISocialLikeSettings.__identifier__ + '.facebook_prefetch_enabled'
    prefetch_enable = api.portal.get_registry_record(record, default=False)
    if not prefetch_enable:
        return

    try:
        review_state = api.content.get_state(obj)
    except WorkflowException:
        # images and files have no associated workflow by default
        review_state = 'published'

    if review_state not in ('published', ):
        return  # can't prefetch non-public content

    url = obj.absolute_url()
    endpoint = 'https://graph.facebook.com/?id=' + url + '&scrape=true'
    try:
        r = requests.post(endpoint, timeout=5)
    except requests.exceptions.RequestException as e:
        logger.warn('Prefetch failure: ' + str(e))
        return

    if r.status_code == '200':
        logger.info('Prefetch successful: ' + url)
    else:
        logger.warn('Prefetch error {code} ({reason}): {debug}'.format(
            code=r.status_code, reason=r.reason, debug=str(r.json())))
Esempio n. 3
0
def facebook_prefetching(obj, event):
    """Call Facebook Graph API endpoint to keep metadata of published
    objects always updated.
    """
    record = ISocialLikeSettings.__identifier__ + '.facebook_prefetch_enabled'
    prefetch_enable = api.portal.get_registry_record(record, default=False)
    if not prefetch_enable:
        return

    try:
        review_state = api.content.get_state(obj)
    except WorkflowException:
        # images and files have no associated workflow by default
        review_state = 'published'

    if review_state not in ('published', ):
        return  # can't prefetch non-public content

    url = obj.absolute_url()
    endpoint = 'https://graph.facebook.com/?id=' + url + '&scrape=true'
    try:
        r = requests.post(endpoint, timeout=5)
    except requests.exceptions.RequestException as e:
        logger.warn('Prefetch failure: ' + str(e))
        return

    if r.status_code == '200':
        logger.info('Prefetch successful: ' + url)
    else:
        logger.warn(
            'Prefetch error {code} ({reason}): {debug}'.format(
                code=r.status_code, reason=r.reason, debug=str(r.json())))
Esempio n. 4
0
def get_valid_objects(brains):
    """Generate a list of objects associated with valid brains."""
    for b in brains:
        try:
            obj = b.getObject()
        except KeyError:
            obj = None

        if obj is None:  # warn on broken entries in the catalog
            msg = u'Skipping invalid reference in the catalog: {0}'
            logger.warn(msg.format(b.getPath()))
            continue
        yield obj
Esempio n. 5
0
def get_valid_objects(brains):
    """Generate a list of objects associated with valid brains."""
    for b in brains:
        try:
            obj = b.getObject()
        except KeyError:
            obj = None

        if obj is None:  # warn on broken entries in the catalog
            msg = u'Skipping invalid reference in the catalog: {0}'
            logger.warn(msg.format(b.getPath()))
            continue
        yield obj
Esempio n. 6
0
def assign_canonical_url(obj, event):
    """Assing canonical URL to the object after it is published."""
    if event.status['review_state'] not in ('published', ):
        # don't a assign a canonical URL as this is not a public state
        return

    record = ISocialLikeSettings.__identifier__ + '.canonical_domain'
    try:
        canonical_domain = api.portal.get_registry_record(record)
    except api.exc.InvalidParameterError:
        # package is not installed or record deleted; do nothing
        return

    # we can't assign a canonical URL without a canonical domain
    if canonical_domain:
        # FIXME: we're currently ignoring the Plone site id
        #        https://github.com/collective/sc.social.like/issues/119
        path = '/'.join(obj.getPhysicalPath()[2:])
        obj.canonical_url = '{0}/{1}'.format(canonical_domain, path)
        logger.info('canonical_url set for {0}'.format(obj.canonical_url))
    else:
        logger.warn(
            'Canonical domain not set in Social Media configlet; '
            "Facebook's Open Graph canonical URL (og:orl) will not be available")
Esempio n. 7
0
def migrate_settings_to_registry(setup_tool):  # noqa: C901
    """Migrate settings to registry."""
    def filter_types(portal_types):
        """Return ReallyUserFriendlyTypes only. Old field values were
        not restricted in any way; new field values must be terms of
        this vocabulary.
        """
        from zope.component import getUtility
        from zope.schema.interfaces import IVocabularyFactory
        name = 'plone.app.vocabularies.ReallyUserFriendlyTypes'
        friendly_types = getUtility(IVocabularyFactory, name)(None)
        return tuple([i for i in portal_types if i in friendly_types])

    def safe_migrate(old_attr, new_attr=None, to_string=False):
        """Copy value for property sheet to registry record avoiding
        AttributeError; rename record if needed. In case of error
        the record must already have loaded its default value.
        """
        try:
            value = getattr(old_props, old_attr)
        except AttributeError:
            pass

        if to_string:  # convert unicode to string?
            # avoid 'None' on None values (missing value)
            value = str(value) if value else ''

        if new_attr is None:
            new_attr = old_attr
        setattr(settings, new_attr, value)

    profile = 'profile-{0}:default'.format(PROJECTNAME)
    setup_tool.runImportStepFromProfile(profile, 'plone.app.registry')
    portal_properties = api.portal.get_tool(name='portal_properties')
    if 'sc_social_likes_properties' not in portal_properties:
        logger.warn('Property sheet not found; using defaults')
        return

    old_props = portal_properties.sc_social_likes_properties
    registry = getUtility(IRegistry)
    settings = registry.forInterface(ISocialLikeSettings)

    # ignore types not allowed
    try:
        portal_types = old_props.enabled_portal_types
    except AttributeError:
        pass
    else:
        portal_types = filter_types(portal_types)
        settings.enabled_portal_types = portal_types

    safe_migrate('plugins_enabled')
    safe_migrate('typebutton')
    safe_migrate('do_not_track')

    try:
        safe_migrate('fbaction')
    except ConstraintNotSatisfied:
        pass  # skip on empty string

    safe_migrate('fbbuttons')

    # these fields are no longer TextLine but ASCIILine
    # and have a different name
    safe_migrate('fbadmins', 'facebook_username', to_string=True)
    safe_migrate('fbapp_id', 'facebook_app_id', to_string=True)
    safe_migrate('twittvia', 'twitter_username', to_string=True)

    logger.info('Settings migrated')

    del portal_properties['sc_social_likes_properties']
    logger.info('Property sheet removed')
Esempio n. 8
0
def migrate_settings_to_registry(setup_tool):  # noqa: C901
    """Migrate settings to registry."""

    def filter_types(portal_types):
        """Return ReallyUserFriendlyTypes only. Old field values were
        not restricted in any way; new field values must be terms of
        this vocabulary.
        """
        from zope.component import getUtility
        from zope.schema.interfaces import IVocabularyFactory
        name = 'plone.app.vocabularies.ReallyUserFriendlyTypes'
        friendly_types = getUtility(IVocabularyFactory, name)(None)
        return tuple([i for i in portal_types if i in friendly_types])

    def safe_migrate(old_attr, new_attr=None, to_string=False):
        """Copy value for property sheet to registry record avoiding
        AttributeError; rename record if needed. In case of error
        the record must already have loaded its default value.
        """
        try:
            value = getattr(old_props, old_attr)
        except AttributeError:
            pass

        if to_string:  # convert unicode to string?
            # avoid 'None' on None values (missing value)
            value = str(value) if value else ''

        if new_attr is None:
            new_attr = old_attr
        setattr(settings, new_attr, value)

    profile = 'profile-{0}:default'.format(PROJECTNAME)
    setup_tool.runImportStepFromProfile(profile, 'plone.app.registry')
    portal_properties = api.portal.get_tool(name='portal_properties')
    if 'sc_social_likes_properties' not in portal_properties:
        logger.warn('Property sheet not found; using defaults')
        return

    old_props = portal_properties.sc_social_likes_properties
    registry = getUtility(IRegistry)
    settings = registry.forInterface(ISocialLikeSettings)

    # ignore types not allowed
    try:
        portal_types = old_props.enabled_portal_types
    except AttributeError:
        pass
    else:
        portal_types = filter_types(portal_types)
        settings.enabled_portal_types = portal_types

    safe_migrate('plugins_enabled')
    safe_migrate('typebutton')
    safe_migrate('do_not_track')

    try:
        safe_migrate('fbaction')
    except ConstraintNotSatisfied:
        pass  # skip on empty string

    safe_migrate('fbbuttons')

    # these fields are no longer TextLine but ASCIILine
    # and have a different name
    safe_migrate('fbadmins', 'facebook_username', to_string=True)
    safe_migrate('fbapp_id', 'facebook_app_id', to_string=True)
    safe_migrate('twittvia', 'twitter_username', to_string=True)

    logger.info('Settings migrated')

    del portal_properties['sc_social_likes_properties']
    logger.info('Property sheet removed')