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" )
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())))
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())))
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
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
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")
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')
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')