diff --git a/CHANGES.rst b/CHANGES.rst index 0ea47fc9..cb9955db 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,8 @@ There's a frood who really knows where his towel is. 2.4.2 (unreleased) ^^^^^^^^^^^^^^^^^^ -- Nothing changed yet. +- Use Plone's registry instead of the ``portal_properties`` tool to store package configuration (closes `#1`_). + [hvelarde] 2.4.1 (2015-12-10) @@ -276,6 +277,7 @@ There's a frood who really knows where his towel is. * Initial release [cleberjsantos] +.. _`#1`: https://github.com/collective/sc.social.like/issues/1 .. _`#15`: https://github.com/collective/sc.social.like/pull/15 .. _`#36`: https://github.com/collective/sc.social.like/issues/36 .. _`#38`: https://github.com/collective/sc.social.like/issues/38 diff --git a/sc/social/like/Extensions/Install.py b/sc/social/like/Extensions/Install.py index 45523398..cd1db2b4 100644 --- a/sc/social/like/Extensions/Install.py +++ b/sc/social/like/Extensions/Install.py @@ -3,17 +3,8 @@ from plone import api -def remove_properties(portal): - portal_properties = api.portal.get_tool(name='portal_properties') - try: - portal_properties.manage_delObjects(ids='sc_social_likes_properties') - except KeyError: - pass - - def uninstall(portal, reinstall=False): if not reinstall: - remove_properties(portal) profile = 'profile-%s:uninstall' % PROJECTNAME setup_tool = api.portal.get_tool(name='portal_setup') setup_tool.runAllImportStepsFromProfile(profile) diff --git a/sc/social/like/browser/configure.zcml b/sc/social/like/browser/configure.zcml index 36bc5760..9e5d9d4b 100644 --- a/sc/social/like/browser/configure.zcml +++ b/sc/social/like/browser/configure.zcml @@ -61,4 +61,11 @@ permission="zope.Public" /> + + diff --git a/sc/social/like/browser/helper.py b/sc/social/like/browser/helper.py index cc3feaf4..5dd69bd7 100644 --- a/sc/social/like/browser/helper.py +++ b/sc/social/like/browser/helper.py @@ -1,15 +1,16 @@ # -*- coding: utf-8 -*- - from Acquisition import aq_inner -from Products.Five import BrowserView from plone.app.layout.globals.interfaces import IViewView from plone.memoize.view import memoize from plone.memoize.view import memoize_contextless -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter +from plone.registry.interfaces import IRegistry +from Products.Five import BrowserView +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.interfaces import IHelperView from sc.social.like.plugins import IPlugin from zope.component import getMultiAdapter from zope.component import getUtilitiesFor +from zope.component import getUtility from zope.interface import implements @@ -30,8 +31,9 @@ def __init__(self, context, request, *args, **kwargs): @memoize_contextless def configs(self): - adapter = LikeControlPanelAdapter(self.portal) - return adapter + registry = getUtility(IRegistry) + settings = registry.forInterface(ISocialLikeSettings) + return settings @memoize_contextless def enabled_portal_types(self): diff --git a/sc/social/like/browser/socialikes.py b/sc/social/like/browser/socialikes.py index 1cea0023..93518652 100644 --- a/sc/social/like/browser/socialikes.py +++ b/sc/social/like/browser/socialikes.py @@ -1,38 +1,27 @@ # -*- coding: utf-8 -*- -from Acquisition import aq_inner +from plone import api +from plone.api.exc import InvalidParameterError from Products.Five import BrowserView -from Products.CMFCore.utils import getToolByName - -from zope.interface import implements -from zope.i18nmessageid import MessageFactory - +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.interfaces import ISocialLikes - -_ = MessageFactory('sc.social.like') +from zope.interface import implements class SocialLikes(BrowserView): - """ - """ - implements(ISocialLikes) - enabled_portal_types = [] + implements(ISocialLikes) - def __init__(self, context, request, *args, **kwargs): - super(SocialLikes, self).__init__(context, request, *args, **kwargs) - context = aq_inner(context) + def __init__(self, context, request): self.context = context - pp = getToolByName(context, 'portal_properties') - self.sheet = getattr(pp, 'sc_social_likes_properties', None) - if self.sheet: - self.enabled_portal_types = self.sheet.getProperty( - 'enabled_portal_types' - ) + self.request = request @property def enabled(self): - """Validates if social bookmarks should be enabled - for this context""" - context = self.context - enabled_portal_types = self.enabled_portal_types - return context.portal_type in enabled_portal_types + """Validates if social bookmarks should be enabled in this context.""" + record = ISocialLikeSettings.__identifier__ + '.enabled_portal_types' + try: + enabled_portal_types = api.portal.get_registry_record(record) + except InvalidParameterError: + enabled_portal_types = [] + + return self.context.portal_type in enabled_portal_types diff --git a/sc/social/like/browser/viewlets.py b/sc/social/like/browser/viewlets.py index bfc1e346..19f21a34 100644 --- a/sc/social/like/browser/viewlets.py +++ b/sc/social/like/browser/viewlets.py @@ -1,8 +1,11 @@ # -*- coding:utf-8 -*- +from plone import api +from plone.api.exc import InvalidParameterError from plone.app.layout.viewlets import ViewletBase +from plone.memoize.view import memoize from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile +from sc.social.like.interfaces import ISocialLikeSettings from zope.component import getMultiAdapter -from plone.memoize.view import memoize class BaseLikeViewlet(ViewletBase): @@ -74,17 +77,19 @@ class SocialLikesViewlet(BaseLikeViewlet): @property def render_method(self): - tools = getMultiAdapter((self.context, self.request), - name=u'plone_tools') - site_properties = tools.properties() # global cookie settings for privacy level if self.request.cookies.get('social-optout', None) == 'true' or \ self.request.get_header('HTTP_DNT') == '1': return 'link' + # site specific privacy level check - if getattr(site_properties, 'sc_social_likes_properties', None) \ - and getattr(site_properties.sc_social_likes_properties, - 'do_not_track', None) and \ - site_properties.sc_social_likes_properties.do_not_track: + record = ISocialLikeSettings.__identifier__ + '.do_not_track' + try: + do_not_track = api.portal.get_registry_record(record) + except InvalidParameterError: + do_not_track = False + + if do_not_track: return 'link' + return 'plugin' diff --git a/sc/social/like/config.py b/sc/social/like/config.py index e22edcf4..c5465115 100644 --- a/sc/social/like/config.py +++ b/sc/social/like/config.py @@ -5,3 +5,6 @@ __docformat__ = 'plaintext' PROJECTNAME = 'sc.social.like' + +DEFAULT_ENABLED_CONTENT_TYPES = ('Document', 'Event', 'News Item') +DEFAULT_PLUGINS_ENABLED = ('Facebook', 'Twitter') diff --git a/sc/social/like/configure.zcml b/sc/social/like/configure.zcml index c7c8ee1c..9620fc5e 100644 --- a/sc/social/like/configure.zcml +++ b/sc/social/like/configure.zcml @@ -7,11 +7,10 @@ - + - diff --git a/sc/social/like/controlpanel.py b/sc/social/like/controlpanel.py new file mode 100644 index 00000000..82c77fd5 --- /dev/null +++ b/sc/social/like/controlpanel.py @@ -0,0 +1,20 @@ +# -*- coding:utf-8 -*- +from plone.app.registry.browser import controlpanel +from sc.social.like import LikeMessageFactory as _ +from sc.social.like.interfaces import ISocialLikeSettings + + +class SocialLikeSettingsEditForm(controlpanel.RegistryEditForm): + + """Control panel edit form.""" + + schema = ISocialLikeSettings + label = _(u'Social Like') + description = _(u'Settings for the sc.social.like package') + + +class SocialLikeSettingsControlPanel(controlpanel.ControlPanelFormWrapper): + + """Control panel form wrapper.""" + + form = SocialLikeSettingsEditForm diff --git a/sc/social/like/controlpanel/__init__.py b/sc/social/like/controlpanel/__init__.py deleted file mode 100644 index 40a96afc..00000000 --- a/sc/social/like/controlpanel/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# -*- coding: utf-8 -*- diff --git a/sc/social/like/controlpanel/configure.zcml b/sc/social/like/controlpanel/configure.zcml deleted file mode 100644 index 2630d71f..00000000 --- a/sc/social/like/controlpanel/configure.zcml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/sc/social/like/controlpanel/likes.pt b/sc/social/like/controlpanel/likes.pt deleted file mode 100644 index 426e7657..00000000 --- a/sc/social/like/controlpanel/likes.pt +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - -
-
- Info -
-
-
-
- - - Site Setup - - -

- Do something -

- -
- Description -
- -
- -
- - - -
-
- -
- Form name - - -
- - - -
- The Error -
- -
- -
-
- -
- -
- - -
- -
- - - -
- -
- - - -
- - - - - - -
- -
- -
- - -
- diff --git a/sc/social/like/controlpanel/likes.py b/sc/social/like/controlpanel/likes.py deleted file mode 100644 index 9581ee0c..00000000 --- a/sc/social/like/controlpanel/likes.py +++ /dev/null @@ -1,134 +0,0 @@ -# -*- coding:utf-8 -*- - -from Acquisition import aq_inner -from Products.CMFDefault.formlib.schema import ProxyFieldProperty as PFP -from Products.CMFDefault.formlib.schema import SchemaAdapterBase -from Products.CMFPlone.interfaces import IPloneSiteRoot -from Products.CMFPlone.utils import getToolByName -from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile -from plone.app.controlpanel.form import ControlPanelForm -from sc.social.like import LikeMessageFactory as _ -from sc.social.like.plugins import IPlugin -from zope import schema -from zope.app.form.browser import itemswidgets -from zope.component import adapts -from zope.component import getUtilitiesFor -from zope.formlib.form import FormFields -from zope.interface import Interface -from zope.interface import implements -from zope.schema.vocabulary import SimpleTerm -from zope.schema.vocabulary import SimpleVocabulary - -CONTENT_TYPES = 'plone.app.vocabularies.ReallyUserFriendlyTypes' - - -class MultiSelectWidget(itemswidgets.MultiSelectWidget): - """ """ - def __init__(self, field, request): - """Initialize the widget.""" - super(MultiSelectWidget, self).__init__(field, - field.value_type.vocabulary, - request) - - -styles = SimpleVocabulary([ - SimpleTerm(value=u'horizontal', title=_(u'horizontal')), - SimpleTerm(value=u'vertical', title=_(u'vertical')), -]) - - -class IProvidersSchema(Interface): - """ General Configurations """ - - enabled_portal_types = schema.Tuple( - title=_(u'Content types'), - description=_( - u'help_portal_types', - default=u'Please select content types in which the ' - u'viewlet will be applied.', - ), - required=True, - value_type=schema.Choice(vocabulary=CONTENT_TYPES) - ) - - plugins_enabled = schema.Tuple( - title=_(u'Plugins'), - description=_( - u'help_enabled_plugins', - default=u'Please select which plugins will be used', - ), - required=False, - value_type=schema.Choice(vocabulary='sc.social.likes.plugins') - ) - - typebutton = schema.Choice( - title=_(u'Button style'), - description=_( - u'help_selected_buttons', - default=u'Choose your button style.', - ), - required=True, - default=_(u'horizontal'), - vocabulary=styles, - ) - - do_not_track = schema.Bool( - title=_(u'Do not track users'), - description=_( - u'help_do_not_track', - default=u'If enabled, the site will not provide advanced sharing ' - u'widgets , instead simple links will be used.\n' - u'This will limits user experience and features ' - u'(like the share count) but will enhance users privacy: ' - u'no 3rd party cookies will be sent to users.' - ), - default=False, - ) - - -class BaseControlPanelAdapter(SchemaAdapterBase): - """ Base control panel adapter """ - - def __init__(self, context): - super(BaseControlPanelAdapter, self).__init__(context) - portal_properties = getToolByName(context, 'portal_properties') - self.context = portal_properties.get('sc_social_likes_properties', None) - - -class LikeControlPanelAdapter(BaseControlPanelAdapter): - """ Like control panel adapter """ - adapts(IPloneSiteRoot) - implements(IProvidersSchema) - - enabled_portal_types = PFP(IProvidersSchema['enabled_portal_types']) - typebutton = PFP(IProvidersSchema['typebutton']) - plugins_enabled = PFP(IProvidersSchema['plugins_enabled']) - do_not_track = PFP(IProvidersSchema['do_not_track']) - - -class ProvidersControlPanel(ControlPanelForm): - """ """ - template = ViewPageTemplateFile('likes.pt') - form_fields = FormFields(IProvidersSchema) - - form_fields['enabled_portal_types'].custom_widget = MultiSelectWidget - form_fields['plugins_enabled'].custom_widget = MultiSelectWidget - - label = _('Social: Like Actions settings') - description = _('Configure settings for social like actions.') - form_name = _('Social: Like Actions') - - def plugins_configs(self): - """ Return Plugins and their configuration pages """ - context = aq_inner(self.context) - portal_url = getToolByName(context, 'portal_url')() - registered = dict(getUtilitiesFor(IPlugin)) - plugins = [] - for name in registered: - plugin = registered[name] - config_view = plugin.config_view() - if config_view: - url = '%s/%s' % (portal_url, config_view) - plugins.append({'name': name, - 'url': url}) - return plugins diff --git a/sc/social/like/docs/__init__.py b/sc/social/like/docs/__init__.py deleted file mode 100644 index 792d6005..00000000 --- a/sc/social/like/docs/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/sc/social/like/docs/browser.txt b/sc/social/like/docs/browser.txt deleted file mode 100644 index bd12ee63..00000000 --- a/sc/social/like/docs/browser.txt +++ /dev/null @@ -1,8 +0,0 @@ -Accessing as portal owner -------------------------- - - >>> from Products.Five.testbrowser import Browser - >>> from Testing.ZopeTestCase import user_password - >>> browser = Browser() - >>> browser.addHeader('Authorization', - ... 'Basic %s:%s' % ('portal_owner', user_password)) diff --git a/sc/social/like/interfaces.py b/sc/social/like/interfaces.py new file mode 100644 index 00000000..0ba8b84c --- /dev/null +++ b/sc/social/like/interfaces.py @@ -0,0 +1,169 @@ +# -*- coding:utf-8 -*- +from plone.supermodel import model +from sc.social.like import LikeMessageFactory as _ +from sc.social.like.config import DEFAULT_ENABLED_CONTENT_TYPES +from sc.social.like.config import DEFAULT_PLUGINS_ENABLED +from sc.social.like.vocabularies import FacebookButtonsVocabulary +from sc.social.like.vocabularies import FacebookVerbsVocabulary +from sc.social.like.vocabularies import TypeButtonVocabulary +from zope import schema +from zope.interface import Interface + + +class ISocialLikeLayer(Interface): + """ + """ + + +class ISocialLikes(Interface): + """ + """ + + +class IHelperView(Interface): + """ + """ + def configs(): + """ Social Like configuration """ + + def enabled_portal_types(): + """ Portal Types that will display our viewlet """ + + def plugins_enabled(): + """ List of plugins enabled """ + + def typebutton(): + """ Button to be used """ + + def enabled(view): + """ + Social Like is enabled for this context and provided view + (when provided) + """ + + def available_plugins(): + """ Return available plugins """ + + def plugins(): + """ Return enabled plugins """ + + def view_template_id(): + """ View or template id for this context """ + + +class ISocialLikeSettings(model.Schema): + + """Schema for the control panel form.""" + + enabled_portal_types = schema.Tuple( + title=_(u'Content types'), + description=_( + u'help_portal_types', + default=u'Please select content types in which the ' + u'viewlet will be applied.', + ), + required=True, + default=DEFAULT_ENABLED_CONTENT_TYPES, + value_type=schema.Choice( + vocabulary='plone.app.vocabularies.ReallyUserFriendlyTypes') + ) + + plugins_enabled = schema.Tuple( + title=_(u'Plugins'), + description=_( + u'help_enabled_plugins', + default=u'Please select which plugins will be used', + ), + required=False, + default=DEFAULT_PLUGINS_ENABLED, + value_type=schema.Choice(vocabulary='sc.social.likes.plugins') + ) + + typebutton = schema.Choice( + title=_(u'Button style'), + description=_( + u'help_selected_buttons', + default=u'Choose your button style.', + ), + required=True, + default=u'horizontal', + vocabulary=TypeButtonVocabulary, + ) + + do_not_track = schema.Bool( + title=_(u'Do not track users'), + description=_( + u'help_do_not_track', + default=u'If enabled, the site will not provide advanced sharing ' + u'widgets , instead simple links will be used.\n' + u'This will limits user experience and features ' + u'(like the share count) but will enhance users privacy: ' + u'no 3rd party cookies will be sent to users.' + ), + default=False, + ) + + model.fieldset( + 'facebook', + label=u'Facebook', + fields=['fbaction', 'facebook_username', 'facebook_app_id', 'fbbuttons'], + ) + + fbaction = schema.Choice( + title=_(u'Verb to display'), + description=_( + u'help_verb_display', + default=u'The verb to display in the facebook button. ' + u'Currently only "like" and "recommend" are ' + u'supported.', + ), + required=True, + default=u'like', + vocabulary=FacebookVerbsVocabulary, + ) + + facebook_username = schema.ASCIILine( + title=_(u'Admins'), + description=_( + u'help_admins', + default=u'A comma-separated list of either the ' + u'Facebook IDs of page administrators.', + ), + required=False, + default='', + ) + + facebook_app_id = schema.ASCIILine( + title=_(u'Application ID'), + description=_( + u'help_appid', + default=u'A Facebook Platform application ID.\n' + u'This is required when \"Do not track users\" option is enabled.', + ), + required=False, + default='', + ) + + fbbuttons = schema.Tuple( + title=_(u'Facebook buttons'), + description=_( + u'help_fbbuttons', + default=u'Select buttons to be shown', + ), + value_type=schema.Choice(vocabulary=FacebookButtonsVocabulary), + required=True, + default=(u'Like', ), + ) + + model.fieldset( + 'twitter', label=u'Twitter', fields=['twitter_username']) + + twitter_username = schema.ASCIILine( + title=_(u'Twitter nick'), + description=_( + u'help_your_twitter_nick', + default=u'Enter your twitter nick. eg. simplesconsultoria', + ), + required=False, + default='', + ) diff --git a/sc/social/like/interfaces/__init__.py b/sc/social/like/interfaces/__init__.py deleted file mode 100644 index 02662a9a..00000000 --- a/sc/social/like/interfaces/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# flake8: noqa - -from socialikes import IHelperView -from socialikes import ISocialLikeLayer -from socialikes import ISocialLikes diff --git a/sc/social/like/interfaces/socialikes.py b/sc/social/like/interfaces/socialikes.py deleted file mode 100644 index 207ac79b..00000000 --- a/sc/social/like/interfaces/socialikes.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding:utf-8 -*- -from zope.interface import Interface -from zope.i18nmessageid import MessageFactory -_ = MessageFactory('sc.social.like') - - -class ISocialLikeLayer(Interface): - """ - """ - - -class ISocialLikes(Interface): - """ - """ - - -class IHelperView(Interface): - """ - """ - def configs(): - """ Social Like configuration """ - - def enabled_portal_types(): - """ Portal Types that will display our viewlet """ - - def plugins_enabled(): - """ List of plugins enabled """ - - def typebutton(): - """ Button to be used """ - - def enabled(view): - """ - Social Like is enabled for this context and provided view - (when provided) - """ - - def available_plugins(): - """ Return available plugins """ - - def plugins(): - """ Return enabled plugins """ - - def view_template_id(): - """ View or template id for this context """ diff --git a/sc/social/like/logger.py b/sc/social/like/logger.py new file mode 100644 index 00000000..8d4c9a3c --- /dev/null +++ b/sc/social/like/logger.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from sc.social.like.config import PROJECTNAME + +import logging + +logger = logging.getLogger(PROJECTNAME) diff --git a/sc/social/like/plugins/facebook/browser.py b/sc/social/like/plugins/facebook/browser.py index 74ebefe1..90b9fead 100644 --- a/sc/social/like/plugins/facebook/browser.py +++ b/sc/social/like/plugins/facebook/browser.py @@ -1,9 +1,12 @@ # -*- coding:utf-8 -*- from Acquisition import aq_parent, aq_inner +from plone import api +from plone.api.exc import InvalidParameterError from Products.CMFCore.interfaces import ISiteRoot from Products.CMFCore.utils import getToolByName from Products.Five import BrowserView from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.plugins.facebook.utils import facebook_language from sc.social.like.utils import get_content_image from sc.social.like.utils import get_language @@ -16,27 +19,21 @@ class PluginView(BrowserView): - enabled_portal_types = [] - typebutton = '' fb_enabled = False - fbaction = '' - fbadmins = '' language = 'en_US' - fbshow_like = True - fbshow_share = False metadata = ViewPageTemplateFile('templates/metadata.pt') plugin = ViewPageTemplateFile('templates/plugin.pt') link = ViewPageTemplateFile('templates/link.pt') def __init__(self, context, request): - super(PluginView, self).__init__(context, request) - pp = getToolByName(context, 'portal_properties') - self.context = context + self.request = request + # FIXME: the following could rise unexpected exceptions + # move it to a new setup() method + # see: http://docs.plone.org/develop/plone/views/browserviews.html#creating-a-view self.title = context.title self.description = context.Description() - self.request = request self.portal_state = getMultiAdapter((self.context, self.request), name=u'plone_portal_state') self.portal = self.portal_state.portal() @@ -44,15 +41,8 @@ def __init__(self, context, request): self.portal_title = self.portal_state.portal_title() self.url = context.absolute_url() self.language = facebook_language(get_language(context), self.language) - self.sheet = getattr(pp, 'sc_social_likes_properties', None) self.image = get_content_image(context, width=1200, height=630) - if self.sheet: - self.fbaction = self.sheet.getProperty('fbaction', '') - self.fbapp_id = self.sheet.getProperty('fbapp_id', '') - self.fbadmins = self.sheet.getProperty('fbadmins', '') - self.fbshow_like = 'Like' in self.sheet.getProperty('fbbuttons', []) - self.fbshow_share = 'Share' in self.sheet.getProperty('fbbuttons', []) - self.button = self.typebutton + self.typebutton # XXX: needed to initialize self.width def fbjs(self): js_source = """ @@ -99,7 +89,12 @@ def image_url(self): @property def typebutton(self): - typebutton = self.sheet.getProperty('typebutton', '') + record = ISocialLikeSettings.__identifier__ + '.typebutton' + try: + typebutton = api.portal.get_registry_record(record) + except InvalidParameterError: + typebutton = '' + if typebutton == 'horizontal': typebutton = 'button_count' self.width = '90px' @@ -108,6 +103,46 @@ def typebutton(self): self.width = '55px' return typebutton + @property + def fbaction(self): + record = ISocialLikeSettings.__identifier__ + '.fbaction' + try: + return api.portal.get_registry_record(record) + except InvalidParameterError: + return '' + + @property + def app_id(self): + record = ISocialLikeSettings.__identifier__ + '.facebook_app_id' + try: + return api.portal.get_registry_record(record) + except InvalidParameterError: + return '' + + @property + def admins(self): + record = ISocialLikeSettings.__identifier__ + '.facebook_username' + try: + return api.portal.get_registry_record(record) + except InvalidParameterError: + return '' + + @property + def fbshow_like(self): + record = ISocialLikeSettings.__identifier__ + '.fbbuttons' + try: + return 'Like' in api.portal.get_registry_record(record) + except InvalidParameterError: + return False + + @property + def fbshow_share(self): + record = ISocialLikeSettings.__identifier__ + '.fbbuttons' + try: + return 'Share' in api.portal.get_registry_record(record) + except InvalidParameterError: + return False + def _isPortalDefaultView(self): context = self.context if ISiteRoot.providedBy(aq_parent(aq_inner(context))): @@ -129,7 +164,7 @@ def type(self): def share_link(self): absolute_url = self.context.absolute_url() params = dict( - app_id=self.fbapp_id, + app_id=self.app_id, display='popup', href=absolute_url, redirect_uri=absolute_url, diff --git a/sc/social/like/plugins/facebook/configure.zcml b/sc/social/like/plugins/facebook/configure.zcml index 50e3923c..b8ed70c7 100644 --- a/sc/social/like/plugins/facebook/configure.zcml +++ b/sc/social/like/plugins/facebook/configure.zcml @@ -8,17 +8,6 @@ factory="sc.social.like.plugins.facebook.Facebook" name="Facebook" /> - - - - - Simple link sharing will not work is no FB APPID is configured - + - - + + - \ No newline at end of file + diff --git a/sc/social/like/plugins/gplus/browser.py b/sc/social/like/plugins/gplus/browser.py index f79bceb3..853144b8 100644 --- a/sc/social/like/plugins/gplus/browser.py +++ b/sc/social/like/plugins/gplus/browser.py @@ -1,7 +1,9 @@ # -*- coding:utf-8 -*- -from Products.CMFCore.utils import getToolByName +from plone import api +from plone.api.exc import InvalidParameterError from Products.Five import BrowserView from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.utils import get_language from urllib import urlencode from zope.component import getMultiAdapter @@ -9,7 +11,6 @@ class PluginView(BrowserView): - typebutton = '' gp_enabled = True language = 'en' @@ -18,11 +19,11 @@ class PluginView(BrowserView): link = ViewPageTemplateFile('templates/link.pt') def __init__(self, context, request): - super(PluginView, self).__init__(context, request) - pp = getToolByName(context, 'portal_properties') - self.context = context self.request = request + # FIXME: the following could rise unexpected exceptions + # move it to a new setup() method + # see: http://docs.plone.org/develop/plone/views/browserviews.html#creating-a-view self.portal_state = getMultiAdapter((self.context, self.request), name=u'plone_portal_state') self.portal = self.portal_state.portal() @@ -30,11 +31,15 @@ def __init__(self, context, request): self.portal_title = self.portal_state.portal_title() self.url = context.absolute_url() self.language = get_language(context) - self.sheet = getattr(pp, 'sc_social_likes_properties', None) @property def typebutton(self): - typebutton = self.sheet.getProperty('typebutton', '') + record = ISocialLikeSettings.__identifier__ + '.typebutton' + try: + typebutton = api.portal.get_registry_record(record) + except InvalidParameterError: + typebutton = '' + if typebutton == 'horizontal': typebutton = 'medium' else: diff --git a/sc/social/like/plugins/linkedin/browser.py b/sc/social/like/plugins/linkedin/browser.py index c1138c15..e7a3fb8a 100644 --- a/sc/social/like/plugins/linkedin/browser.py +++ b/sc/social/like/plugins/linkedin/browser.py @@ -1,7 +1,9 @@ # -*- coding:utf-8 -*- -from Products.CMFCore.utils import getToolByName +from plone import api +from plone.api.exc import InvalidParameterError from Products.Five import BrowserView from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.utils import get_language from urllib import urlencode from zope.component import getMultiAdapter @@ -9,7 +11,6 @@ class PluginView(BrowserView): - typebutton = '' linkedin_enabled = True language = 'en' @@ -18,11 +19,11 @@ class PluginView(BrowserView): link = ViewPageTemplateFile('templates/link.pt') def __init__(self, context, request): - super(PluginView, self).__init__(context, request) - pp = getToolByName(context, 'portal_properties') - self.context = context self.request = request + # FIXME: the following could rise unexpected exceptions + # move it to a new setup() method + # see: http://docs.plone.org/develop/plone/views/browserviews.html#creating-a-view self.portal_state = getMultiAdapter((self.context, self.request), name=u'plone_portal_state') self.portal = self.portal_state.portal() @@ -30,11 +31,15 @@ def __init__(self, context, request): self.portal_title = self.portal_state.portal_title() self.url = context.absolute_url() self.language = get_language(context) - self.sheet = getattr(pp, 'sc_social_likes_properties', None) @property def typebutton(self): - typebutton = self.sheet.getProperty('typebutton', '') + record = ISocialLikeSettings.__identifier__ + '.typebutton' + try: + typebutton = api.portal.get_registry_record(record) + except InvalidParameterError: + typebutton = '' + if typebutton == 'horizontal': typebutton = 'right' else: diff --git a/sc/social/like/plugins/pinterest/browser.py b/sc/social/like/plugins/pinterest/browser.py index 43131fd4..c34973fc 100644 --- a/sc/social/like/plugins/pinterest/browser.py +++ b/sc/social/like/plugins/pinterest/browser.py @@ -1,7 +1,9 @@ # -*- coding:utf-8 -*- -from Products.CMFCore.utils import getToolByName +from plone import api +from plone.api.exc import InvalidParameterError from Products.Five import BrowserView from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.utils import get_content_image from sc.social.like.utils import get_language from urllib import urlencode @@ -13,7 +15,6 @@ class PluginView(BrowserView): - typebutton = '' pinterest_enabled = False language = 'en' @@ -22,11 +23,11 @@ class PluginView(BrowserView): link = ViewPageTemplateFile('templates/link.pt') def __init__(self, context, request): - super(PluginView, self).__init__(context, request) - pp = getToolByName(context, 'portal_properties') - self.context = context self.request = request + # FIXME: the following could rise unexpected exceptions + # move it to a new setup() method + # see: http://docs.plone.org/develop/plone/views/browserviews.html#creating-a-view self.portal_state = getMultiAdapter((self.context, self.request), name=u'plone_portal_state') self.portal = self.portal_state.portal() @@ -35,7 +36,6 @@ def __init__(self, context, request): self.url = context.absolute_url() self.image = get_content_image(context, scale='large') self.language = get_language(context) - self.sheet = getattr(pp, 'sc_social_likes_properties', None) def share_url(self): template = BASE_URL + PARAMS @@ -56,7 +56,12 @@ def image_url(self): @property def typebutton(self): - typebutton = self.sheet.getProperty('typebutton', '') + record = ISocialLikeSettings.__identifier__ + '.typebutton' + try: + typebutton = api.portal.get_registry_record(record) + except InvalidParameterError: + typebutton = '' + if typebutton == 'horizontal': typebutton = 'beside' else: diff --git a/sc/social/like/plugins/twitter/browser.py b/sc/social/like/plugins/twitter/browser.py index 2c31f476..65b24fab 100644 --- a/sc/social/like/plugins/twitter/browser.py +++ b/sc/social/like/plugins/twitter/browser.py @@ -1,9 +1,11 @@ # -*- coding:utf-8 -*- -from Products.CMFCore.utils import getToolByName +from plone import api +from plone.api.exc import InvalidParameterError from Products.CMFPlone.utils import safe_unicode from Products.Five import BrowserView from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from Products.PythonScripts.standard import url_quote +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.utils import get_language from urllib import urlencode from zope.component import getMultiAdapter @@ -11,10 +13,7 @@ class PluginView(BrowserView): - enabled_portal_types = [] - typebutton = '' - twitter_enabled = '' - twittvia = '' + twitter_enabled = False language = 'en' metadata = ViewPageTemplateFile('templates/metadata.pt') @@ -22,11 +21,11 @@ class PluginView(BrowserView): link = ViewPageTemplateFile('templates/link.pt') def __init__(self, context, request): - super(PluginView, self).__init__(context, request) - pp = getToolByName(context, 'portal_properties') - self.context = context self.request = request + # FIXME: the following could rise unexpected exceptions + # move it to a new setup() method + # see: http://docs.plone.org/develop/plone/views/browserviews.html#creating-a-view self.portal_state = getMultiAdapter((self.context, self.request), name=u'plone_portal_state') self.portal = self.portal_state.portal() @@ -34,26 +33,38 @@ def __init__(self, context, request): self.portal_title = self.portal_state.portal_title() self.url = context.absolute_url() self.language = get_language(context) - self.sheet = getattr(pp, 'sc_social_likes_properties', None) - if self.sheet: - self.typebutton = self.sheet.getProperty('typebutton', '') - self.twittvia = self.sheet.getProperty('twittvia', '') self.urlnoscript = ( u'http://twitter.com/home?status=' + url_quote(u'{0} - {1} via {2}'.format( safe_unicode(self.context.title), self.context.absolute_url(), - self.twittvia) + self.via) ) ) + @property + def typebutton(self): + record = ISocialLikeSettings.__identifier__ + '.typebutton' + try: + return api.portal.get_registry_record(record) + except InvalidParameterError: + return '' + + @property + def via(self): + record = ISocialLikeSettings.__identifier__ + '.twitter_username' + try: + return api.portal.get_registry_record(record) + except InvalidParameterError: + return '' + def share_link(self): params = dict( text=self.context.Title(), url=self.context.absolute_url(), ) - if self.twittvia: - params['via'] = self.twittvia + if self.via: + params['via'] = self.via url = 'https://twitter.com/intent/tweet?' + urlencode(params) return url diff --git a/sc/social/like/plugins/twitter/configure.zcml b/sc/social/like/plugins/twitter/configure.zcml index 654c60fd..b209e973 100644 --- a/sc/social/like/plugins/twitter/configure.zcml +++ b/sc/social/like/plugins/twitter/configure.zcml @@ -8,17 +8,6 @@ factory="sc.social.like.plugins.twitter.Twitter" name="Twitter" /> - - - - - diff --git a/sc/social/like/plugins/whatsapp/browser.py b/sc/social/like/plugins/whatsapp/browser.py index e73a9490..8a3e95bd 100644 --- a/sc/social/like/plugins/whatsapp/browser.py +++ b/sc/social/like/plugins/whatsapp/browser.py @@ -1,5 +1,4 @@ # -*- coding:utf-8 -*- -from Products.CMFCore.utils import getToolByName from Products.CMFPlone.utils import safe_unicode from Products.Five import BrowserView from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile @@ -11,18 +10,18 @@ class PluginView(BrowserView): typebutton = '' - gp_enabled = True + whatsapp_enabled = False language = 'en' metadata = ViewPageTemplateFile('templates/metadata.pt') plugin = link = ViewPageTemplateFile('templates/plugin.pt') def __init__(self, context, request): - super(PluginView, self).__init__(context, request) - pp = getToolByName(context, 'portal_properties') - self.context = context self.request = request + # FIXME: the following could rise unexpected exceptions + # move it to a new setup() method + # see: http://docs.plone.org/develop/plone/views/browserviews.html#creating-a-view self.portal_state = getMultiAdapter( (self.context, self.request), name=u'plone_portal_state') self.portal = self.portal_state.portal() @@ -30,7 +29,6 @@ def __init__(self, context, request): self.portal_title = self.portal_state.portal_title() self.url = context.absolute_url() self.language = get_language(context) - self.sheet = getattr(pp, 'sc_social_likes_properties', None) self.whatsappurl = ( u'whatsapp://send?text=' + url_quote( diff --git a/sc/social/like/profiles/default/controlpanel.xml b/sc/social/like/profiles/default/controlpanel.xml index 2857e234..90ae077c 100644 --- a/sc/social/like/profiles/default/controlpanel.xml +++ b/sc/social/like/profiles/default/controlpanel.xml @@ -4,7 +4,7 @@ i18n:domain="sc.social.like"> Manage portal diff --git a/sc/social/like/profiles/default/metadata.xml b/sc/social/like/profiles/default/metadata.xml index bcf8b36c..e3fc2887 100644 --- a/sc/social/like/profiles/default/metadata.xml +++ b/sc/social/like/profiles/default/metadata.xml @@ -1,4 +1,4 @@ - 3030 + 3040 diff --git a/sc/social/like/profiles/default/propertiestool.xml b/sc/social/like/profiles/default/propertiestool.xml deleted file mode 100644 index af216efd..00000000 --- a/sc/social/like/profiles/default/propertiestool.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - horizontal - - - - - - - - - - - - - - - - - diff --git a/sc/social/like/profiles/default/registry.xml b/sc/social/like/profiles/default/registry.xml new file mode 100644 index 00000000..fa32528a --- /dev/null +++ b/sc/social/like/profiles/default/registry.xml @@ -0,0 +1,4 @@ + + + + diff --git a/sc/social/like/profiles/uninstall/registry.xml b/sc/social/like/profiles/uninstall/registry.xml new file mode 100644 index 00000000..a88aeaa8 --- /dev/null +++ b/sc/social/like/profiles/uninstall/registry.xml @@ -0,0 +1,4 @@ + + + + diff --git a/sc/social/like/testing.py b/sc/social/like/testing.py index 35fa3a89..fb60710f 100644 --- a/sc/social/like/testing.py +++ b/sc/social/like/testing.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from plone import api from plone.app.robotframework.testing import AUTOLOGIN_LIBRARY_FIXTURE from plone.app.testing import FunctionalTesting from plone.app.testing import IntegrationTesting @@ -8,6 +9,8 @@ import os.path +IS_PLONE_5 = api.env.plone_version().startswith('5') + def load_image(width, height, format='PNG'): filename = os.path.join( diff --git a/sc/social/like/tests/functional.txt b/sc/social/like/tests/functional.txt deleted file mode 100644 index 9b87f00d..00000000 --- a/sc/social/like/tests/functional.txt +++ /dev/null @@ -1,23 +0,0 @@ -Functional test: - - >>> app = layer['app'] - >>> portal = layer['portal'] - >>> request = layer['request'] - - >>> from plone.testing.z2 import Browser - >>> browser = Browser(app) - >>> portalURL = portal.absolute_url() - - >>> from plone.app.testing import SITE_OWNER_NAME, SITE_OWNER_PASSWORD - >>> browser.open(portalURL + '/login_form') - >>> browser.getControl(name='__ac_name').value = SITE_OWNER_NAME - >>> browser.getControl(name='__ac_password').value = SITE_OWNER_PASSWORD - >>> browser.getControl(name='submit').click() - - >>> 'You are now logged in' in browser.contents - True - - >>> browser.open(portalURL + '/@@likes-providers') - >>> 'Configure settings for social like actions' in browser.contents - True - diff --git a/sc/social/like/tests/test_controlpanel.py b/sc/social/like/tests/test_controlpanel.py index 05fc7132..36c03893 100644 --- a/sc/social/like/tests/test_controlpanel.py +++ b/sc/social/like/tests/test_controlpanel.py @@ -1,83 +1,120 @@ # -*- coding: utf-8 -*- from plone import api from plone.app.testing import logout +from plone.registry.interfaces import IRegistry from sc.social.like.config import PROJECTNAME -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter -from sc.social.like.controlpanel.likes import ProvidersControlPanel +from sc.social.like.interfaces import ISocialLikeSettings +from sc.social.like.interfaces import ISocialLikeLayer from sc.social.like.testing import INTEGRATION_TESTING -from zope.component import getMultiAdapter +from zope.component import getUtility +from zope.interface import alsoProvides import unittest -class ControlPanelTest(unittest.TestCase): +class ControlPanelTestCase(unittest.TestCase): layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer['portal'] + self.request = self.layer['request'] + alsoProvides(self.request, ISocialLikeLayer) self.controlpanel = self.portal['portal_controlpanel'] - self.adapter = LikeControlPanelAdapter(self.portal) - self.sheet = self.portal.portal_properties.sc_social_likes_properties - def test_controlpanel_view(self): - view = getMultiAdapter( - (self.portal, self.portal.REQUEST), name='likes-providers') + def test_controlpanel_has_view(self): + view = api.content.get_view(u'sociallike-settings', self.portal, self.request) view = view.__of__(self.portal) self.assertTrue(view()) - self.assertTrue(isinstance(view, ProvidersControlPanel)) - def test_controlpanel_plugins_configs(self): - view = getMultiAdapter( - (self.portal, self.portal.REQUEST), name='likes-providers') - configs = view.plugins_configs() - self.assertEqual(len(configs), 2) - - def test_controlpanel_view_protected(self): - # control panel view can not be accessed by anonymous users + def test_controlpanel_view_is_protected(self): from AccessControl import Unauthorized logout() with self.assertRaises(Unauthorized): - self.portal.restrictedTraverse('@@likes-providers') + self.portal.restrictedTraverse('@@sociallike-settings') - def test_configlet_installed(self): - actions = [a.getAction(self)['id'] - for a in self.controlpanel.listActions()] + def test_controlpanel_installed(self): + actions = [ + a.getAction(self)['id'] for a in self.controlpanel.listActions()] self.assertIn('sociallikes', actions) - def test_configlet_removed_on_uninstall(self): + def test_controlpanel_removed_on_uninstall(self): qi = self.portal['portal_quickinstaller'] with api.env.adopt_roles(['Manager']): qi.uninstallProducts(products=[PROJECTNAME]) - actions = [a.getAction(self)['id'] - for a in self.controlpanel.listActions()] + actions = [ + a.getAction(self)['id'] for a in self.controlpanel.listActions()] self.assertNotIn('sociallikes', actions) - def test_enabled_portal_types(self): - adapter = self.adapter - adapter.enabled_portal_types = () - self.assertEqual(len(adapter.enabled_portal_types), 0) - adapter.enabled_portal_types = ('Document', 'Event') - self.assertEqual(len(adapter.enabled_portal_types), 2) +class RegistryTestCase(unittest.TestCase): + + layer = INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer['portal'] + self.registry = getUtility(IRegistry) + self.settings = self.registry.forInterface(ISocialLikeSettings) + + def test_enabled_portal_types_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'enabled_portal_types')) + self.assertEqual( + self.settings.enabled_portal_types, + ('Document', 'Event', 'News Item'), + ) + + def test_plugins_enabled_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'plugins_enabled')) self.assertEqual( - adapter.enabled_portal_types, self.sheet.enabled_portal_types) + self.settings.plugins_enabled, ('Facebook', 'Twitter')) - def test_plugins_enabled(self): - adapter = self.adapter - adapter.plugins_enabled = () - self.assertEqual(len(adapter.plugins_enabled), 0) - adapter.plugins_enabled = ('Facebook', 'Twitter') + def test_typebutton_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'typebutton')) + self.assertEqual(self.settings.typebutton, u'horizontal') - self.assertEqual(len(adapter.plugins_enabled), 2) - self.assertEqual(adapter.plugins_enabled, self.sheet.plugins_enabled) + def test_do_not_track_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'do_not_track')) + self.assertFalse(self.settings.do_not_track) - def test_typebutton(self): - adapter = self.adapter - adapter.typebutton = 'horizontal' - self.assertEqual(adapter.typebutton, self.sheet.typebutton) + def test_fbaction_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'fbaction')) + self.assertEqual(self.settings.fbaction, u'like') + + def test_facebook_username_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'facebook_username')) + self.assertEqual(self.settings.facebook_username, '') + + def test_facebook_app_id_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'facebook_app_id')) + self.assertEqual(self.settings.facebook_app_id, '') + + def test_fbbuttons_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'fbbuttons')) + self.assertEqual(self.settings.fbbuttons, (u'Like',)) + + def test_twitter_username_record_in_registry(self): + self.assertTrue(hasattr(self.settings, 'twitter_username')) + self.assertEqual(self.settings.twitter_username, '') + + def test_records_removed_on_uninstall(self): + qi = self.portal['portal_quickinstaller'] + + with api.env.adopt_roles(['Manager']): + qi.uninstallProducts(products=[PROJECTNAME]) - adapter.typebutton = 'vertical' - self.assertEqual(adapter.typebutton, self.sheet.typebutton) + records = [ + ISocialLikeSettings.__identifier__ + '.enabled_portal_types', + ISocialLikeSettings.__identifier__ + '.plugins_enabled', + ISocialLikeSettings.__identifier__ + '.typebutton', + ISocialLikeSettings.__identifier__ + '.do_not_track', + ISocialLikeSettings.__identifier__ + '.fbaction', + ISocialLikeSettings.__identifier__ + '.facebook_username', + ISocialLikeSettings.__identifier__ + '.facebook_app_id', + ISocialLikeSettings.__identifier__ + '.fbbuttons', + ISocialLikeSettings.__identifier__ + '.twitter_username', + ] + + for r in records: + self.assertNotIn(r, self.registry) diff --git a/sc/social/like/tests/test_doctest.py b/sc/social/like/tests/test_doctest.py deleted file mode 100644 index a1418445..00000000 --- a/sc/social/like/tests/test_doctest.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- - -import unittest -import doctest - -from plone.testing import layered - -from sc.social.like.testing import FUNCTIONAL_TESTING - -optionflags = doctest.REPORT_ONLY_FIRST_FAILURE - - -def test_suite(): - suite = unittest.TestSuite() - suite.addTests([ - layered(doctest.DocFileSuite('functional.txt', - optionflags=optionflags), - layer=FUNCTIONAL_TESTING), - doctest.DocTestSuite(module='sc.social.like'), - ]) - return suite diff --git a/sc/social/like/tests/test_plugin_facebook.py b/sc/social/like/tests/test_plugin_facebook.py index 09d0d213..40ca585c 100644 --- a/sc/social/like/tests/test_plugin_facebook.py +++ b/sc/social/like/tests/test_plugin_facebook.py @@ -1,19 +1,21 @@ # -*- coding: utf-8 -*- from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter -from sc.social.like.interfaces import ISocialLikeLayer +from plone.registry.interfaces import IRegistry from sc.social.like import utils +from sc.social.like.interfaces import ISocialLikeLayer +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.plugins.facebook import browser -from sc.social.like.plugins.facebook import controlpanel from sc.social.like.plugins.facebook.utils import facebook_language from sc.social.like.plugins.facebook.utils import fix_iso from sc.social.like.plugins.interfaces import IPlugin -from sc.social.like.testing import load_image from sc.social.like.testing import INTEGRATION_TESTING +from sc.social.like.testing import load_image from zope.component import getUtilitiesFor +from zope.component import getUtility from zope.interface import alsoProvides + import unittest name = 'Facebook' @@ -36,10 +38,6 @@ def test_plugin_config(self): self.assertEqual(plugin.name, name) self.assertEqual(plugin.id, 'facebook') - def test_plugin_config_view(self): - plugin = self.plugins[name] - self.assertEqual(plugin.config_view(), '@@facebook-config') - def test_plugin_view(self): plugin = self.plugins[name] self.assertEqual(plugin.view(), '@@facebook-plugin') @@ -59,9 +57,13 @@ class PluginViewsTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] - self.adapter = LikeControlPanelAdapter(self.portal) + self.request = self.layer['request'] setRoles(self.portal, TEST_USER_ID, ['Manager']) self.setup_content(self.portal) + + self.registry = getUtility(IRegistry) + self.settings = self.registry.forInterface(ISocialLikeSettings) + alsoProvides(self.portal.REQUEST, ISocialLikeLayer) self.plugins = dict(getUtilitiesFor(IPlugin)) self.plugin = self.plugins[name] @@ -82,13 +84,6 @@ def setup_content(self, portal): self.image_bmp = portal['my-image-bmp'] self.image_bmp.setImage(load_image(640, 480, format='BMP')) - def test_config_view(self): - plugin = self.plugin - portal = self.portal - config_view = plugin.config_view() - view = portal.restrictedTraverse(config_view) - self.assertTrue(isinstance(view, controlpanel.ProviderControlPanel)) - def test_plugin_view(self): plugin = self.plugin portal = self.portal @@ -99,8 +94,8 @@ def test_plugin_view(self): def test_plugin_view_html_likeonly(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.fbbuttons = ('Like',) + self.settings.fbbuttons = ('Like',) + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.plugin() @@ -110,8 +105,8 @@ def test_plugin_view_html_likeonly(self): def test_plugin_view_html_shareonly(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.fbbuttons = ('Share',) + self.settings.fbbuttons = ('Share',) + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.plugin() @@ -121,8 +116,8 @@ def test_plugin_view_html_shareonly(self): def test_plugin_view_html_both(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.fbbuttons = ('Like', 'Share') + self.settings.fbbuttons = ('Like', 'Share') + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.plugin() @@ -133,14 +128,14 @@ def test_plugin_view_html_both(self): def test_privacy_plugin_view_html(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.do_not_track = True + self.settings.do_not_track = True + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.link() - # Check that an appid is required + # Check that an app_id is required self.assertEqual('', html.strip()) - properties.fbapp_id = '12345' + self.settings.facebook_app_id = '12345' view = portal.restrictedTraverse(plugin_view) html = view.link() self.assertIn('Share on Facebook', html) @@ -304,13 +299,11 @@ def test_plugin_view_typebutton(self): plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) - self.assertEqual(view.button, 'button_count') self.assertEqual(view.typebutton, 'button_count') self.assertEqual(view.width, '90px') # Change to vertical - adapter = self.adapter - adapter.typebutton = 'vertical' + self.settings.typebutton = 'vertical' view = portal.restrictedTraverse(plugin_view) self.assertEqual(view.typebutton, 'box_count') self.assertEqual(view.width, '55px') diff --git a/sc/social/like/tests/test_plugin_gplus.py b/sc/social/like/tests/test_plugin_gplus.py index 06ff1894..3fc094ef 100644 --- a/sc/social/like/tests/test_plugin_gplus.py +++ b/sc/social/like/tests/test_plugin_gplus.py @@ -1,12 +1,14 @@ # -*- coding: utf-8 -*- from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter +from plone.registry.interfaces import IRegistry +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.interfaces import ISocialLikeLayer from sc.social.like.plugins.gplus import browser from sc.social.like.plugins.interfaces import IPlugin from sc.social.like.testing import INTEGRATION_TESTING from zope.component import getUtilitiesFor +from zope.component import getUtility from zope.interface import alsoProvides import unittest @@ -54,9 +56,12 @@ class PluginViewsTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] - self.adapter = LikeControlPanelAdapter(self.portal) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.setup_content(self.portal) + + self.registry = getUtility(IRegistry) + self.settings = self.registry.forInterface(ISocialLikeSettings) + alsoProvides(self.portal.REQUEST, ISocialLikeLayer) self.plugins = dict(getUtilitiesFor(IPlugin)) self.plugin = self.plugins[name] @@ -83,8 +88,8 @@ def test_plugin_view_html(self): def test_privacy_plugin_view_html(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.do_not_track = True + self.settings.do_not_track = True + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.link() @@ -107,7 +112,6 @@ def test_plugin_view_typebutton(self): self.assertEqual(view.typebutton, 'medium') # Change to vertical - adapter = self.adapter - adapter.typebutton = 'vertical' + self.settings.typebutton = 'vertical' view = portal.restrictedTraverse(plugin_view) self.assertEqual(view.typebutton, 'tall') diff --git a/sc/social/like/tests/test_plugin_linkedin.py b/sc/social/like/tests/test_plugin_linkedin.py index 4cf0b176..d7b5e45f 100644 --- a/sc/social/like/tests/test_plugin_linkedin.py +++ b/sc/social/like/tests/test_plugin_linkedin.py @@ -1,12 +1,14 @@ # -*- coding: utf-8 -*- from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter +from plone.registry.interfaces import IRegistry +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.interfaces import ISocialLikeLayer -from sc.social.like.plugins.linkedin import browser from sc.social.like.plugins.interfaces import IPlugin +from sc.social.like.plugins.linkedin import browser from sc.social.like.testing import INTEGRATION_TESTING from zope.component import getUtilitiesFor +from zope.component import getUtility from zope.interface import alsoProvides import unittest @@ -54,9 +56,12 @@ class PluginViewsTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] - self.adapter = LikeControlPanelAdapter(self.portal) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.setup_content(self.portal) + + self.registry = getUtility(IRegistry) + self.settings = self.registry.forInterface(ISocialLikeSettings) + alsoProvides(self.portal.REQUEST, ISocialLikeLayer) self.plugins = dict(getUtilitiesFor(IPlugin)) self.plugin = self.plugins[name] @@ -83,8 +88,8 @@ def test_plugin_view_html(self): def test_privacy_plugin_view_html(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.do_not_track = True + self.settings.do_not_track = True + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.link() @@ -107,7 +112,6 @@ def test_plugin_view_typebutton(self): self.assertEqual(view.typebutton, 'right') # Change to vertical - adapter = self.adapter - adapter.typebutton = 'vertical' + self.settings.typebutton = 'vertical' view = portal.restrictedTraverse(plugin_view) self.assertEqual(view.typebutton, 'top') diff --git a/sc/social/like/tests/test_plugin_pinterest.py b/sc/social/like/tests/test_plugin_pinterest.py index 9b53ed88..c40b21fd 100644 --- a/sc/social/like/tests/test_plugin_pinterest.py +++ b/sc/social/like/tests/test_plugin_pinterest.py @@ -1,13 +1,15 @@ # -*- coding: utf-8 -*- from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter +from plone.registry.interfaces import IRegistry +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.interfaces import ISocialLikeLayer -from sc.social.like.plugins.pinterest import browser from sc.social.like.plugins.interfaces import IPlugin +from sc.social.like.plugins.pinterest import browser from sc.social.like.testing import INTEGRATION_TESTING from sc.social.like.testing import load_image from zope.component import getUtilitiesFor +from zope.component import getUtility from zope.interface import alsoProvides import unittest @@ -55,9 +57,12 @@ class PluginViewsTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] - self.adapter = LikeControlPanelAdapter(self.portal) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.setup_content(self.portal) + + self.registry = getUtility(IRegistry) + self.settings = self.registry.forInterface(ISocialLikeSettings) + alsoProvides(self.portal.REQUEST, ISocialLikeLayer) self.plugins = dict(getUtilitiesFor(IPlugin)) self.plugin = self.plugins[name] @@ -95,8 +100,8 @@ def test_plugin_view_html(self): def test_privacy_plugin_view_html(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.do_not_track = True + self.settings.do_not_track = True + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.link() @@ -148,7 +153,6 @@ def test_plugin_view_typebutton(self): self.assertEqual(view.typebutton, 'beside') # Change to vertical - adapter = self.adapter - adapter.typebutton = 'vertical' + self.settings.typebutton = 'vertical' view = portal.restrictedTraverse(plugin_view) self.assertEqual(view.typebutton, 'above') diff --git a/sc/social/like/tests/test_plugin_twitter.py b/sc/social/like/tests/test_plugin_twitter.py index fb72fcbc..1a463fb0 100644 --- a/sc/social/like/tests/test_plugin_twitter.py +++ b/sc/social/like/tests/test_plugin_twitter.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter +from plone.registry.interfaces import IRegistry from sc.social.like.interfaces import ISocialLikeLayer -from sc.social.like.plugins.twitter import browser -from sc.social.like.plugins.twitter import controlpanel +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.plugins.interfaces import IPlugin from sc.social.like.testing import INTEGRATION_TESTING from zope.component import getUtilitiesFor +from zope.component import getUtility from zope.interface import alsoProvides import unittest @@ -21,6 +21,7 @@ class PluginTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] + self.request = self.layer['request'] alsoProvides(self.portal.REQUEST, ISocialLikeLayer) self.plugins = dict(getUtilitiesFor(IPlugin)) @@ -32,10 +33,6 @@ def test_plugin_config(self): self.assertEqual(plugin.name, name) self.assertEqual(plugin.id, 'twitter') - def test_plugin_config_view(self): - plugin = self.plugins[name] - self.assertEqual(plugin.config_view(), '@@twitter-config') - def test_plugin_view(self): plugin = self.plugins[name] self.assertEqual(plugin.view(), '@@twitter-plugin') @@ -55,9 +52,12 @@ class PluginViewsTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] - self.adapter = LikeControlPanelAdapter(self.portal) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.setup_content(self.portal) + + self.registry = getUtility(IRegistry) + self.settings = self.registry.forInterface(ISocialLikeSettings) + alsoProvides(self.portal.REQUEST, ISocialLikeLayer) self.plugins = dict(getUtilitiesFor(IPlugin)) self.plugin = self.plugins[name] @@ -66,20 +66,6 @@ def setup_content(self, portal): portal.invokeFactory('Document', 'my-document') self.document = portal['my-document'] - def test_config_view(self): - plugin = self.plugin - portal = self.portal - config_view = plugin.config_view() - view = portal.restrictedTraverse(config_view) - self.assertTrue(isinstance(view, controlpanel.ProviderControlPanel)) - - def test_plugin_view(self): - plugin = self.plugin - portal = self.portal - plugin_view = plugin.view() - view = portal.restrictedTraverse(plugin_view) - self.assertTrue(isinstance(view, browser.PluginView)) - def test_plugin_view_html(self): plugin = self.plugin document = self.document @@ -91,18 +77,17 @@ def test_plugin_view_html(self): def test_privacy_plugin_view_html(self): plugin = self.plugin portal = self.portal - properties = portal.portal_properties.sc_social_likes_properties - properties.do_not_track = True + self.settings.do_not_track = True + plugin_view = plugin.view() view = portal.restrictedTraverse(plugin_view) html = view.link() self.assertIn('Tweet it!', html) - def test_plugin_twittvia(self): + def test_plugin_twitter_username(self): plugin = self.plugin document = self.document - adapter = controlpanel.ControlPanelAdapter(self.portal) - adapter.twittvia = u'@simplesconsult' + self.settings.twitter_username = '@simplesconsult' plugin_view = plugin.view() view = document.restrictedTraverse(plugin_view) @@ -113,8 +98,7 @@ def test_plugin_urlnoscript_encoding(self): plugin = self.plugin document = self.document document.setTitle(u'Notícia') - adapter = controlpanel.ControlPanelAdapter(self.portal) - adapter.twittvia = u'@simplesconsult' + self.settings.twitter_username = '@simplesconsult' plugin_view = plugin.view() view = document.restrictedTraverse(plugin_view) diff --git a/sc/social/like/tests/test_plugin_whatsapp.py b/sc/social/like/tests/test_plugin_whatsapp.py index 70702fea..ee017356 100644 --- a/sc/social/like/tests/test_plugin_whatsapp.py +++ b/sc/social/like/tests/test_plugin_whatsapp.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID -from sc.social.like.controlpanel.likes import LikeControlPanelAdapter from sc.social.like.interfaces import ISocialLikeLayer from sc.social.like.plugins.interfaces import IPlugin from sc.social.like.plugins.whatsapp import browser @@ -55,7 +54,6 @@ class PluginViewsTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] self.request = self.layer['request'] - self.adapter = LikeControlPanelAdapter(self.portal) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.setup_content(self.portal) alsoProvides(self.request, ISocialLikeLayer) diff --git a/sc/social/like/tests/test_setup.py b/sc/social/like/tests/test_setup.py index d6e596de..e659670f 100644 --- a/sc/social/like/tests/test_setup.py +++ b/sc/social/like/tests/test_setup.py @@ -2,15 +2,12 @@ from plone.browserlayer.utils import registered_layers from sc.social.like.config import PROJECTNAME from sc.social.like.testing import INTEGRATION_TESTING +from sc.social.like.testing import IS_PLONE_5 import unittest -JAVASCRIPTS = [ -] - -CSS = [ - '++resource++sl_stylesheets/social_like.css', -] +JAVASCRIPT = '++resource++sl_scripts/social_like.js' +CSS = '++resource++sl_stylesheets/social_like.css' class InstallTestCase(unittest.TestCase): @@ -24,23 +21,19 @@ def test_installed(self): qi = getattr(self.portal, 'portal_quickinstaller') self.assertTrue(qi.isProductInstalled(PROJECTNAME)) - def test_portal_properties(self): - portal_properties = self.portal['portal_properties'] - self.assertIn('sc_social_likes_properties', portal_properties) - def test_addon_layer(self): layers = [l.getName() for l in registered_layers()] self.assertIn('ISocialLikeLayer', layers) + @unittest.skipIf(IS_PLONE_5, 'No easy way to test this under Plone 5') def test_jsregistry(self): resource_ids = self.portal.portal_javascripts.getResourceIds() - for id in JAVASCRIPTS: - self.assertIn(id, resource_ids, '%s not installed' % id) + self.assertIn(JAVASCRIPT, resource_ids) + @unittest.skipIf(IS_PLONE_5, 'No easy way to test this under Plone 5') def test_cssregistry(self): resource_ids = self.portal.portal_css.getResourceIds() - for id in CSS: - self.assertIn(id, resource_ids, '%s not installed' % id) + self.assertIn(CSS, resource_ids) class UninstallTest(unittest.TestCase): @@ -59,16 +52,12 @@ def test_addon_layer_removed(self): layers = [l.getName() for l in registered_layers()] self.assertNotIn('ISocialLikeLayer', layers) - def test_portal_properties_removed(self): - portal_properties = self.portal['portal_properties'] - self.assertNotIn('sc_social_likes_properties', portal_properties) - + @unittest.skipIf(IS_PLONE_5, 'No easy way to test this under Plone 5') def test_jsregistry_removed(self): resource_ids = self.portal.portal_javascripts.getResourceIds() - for id in JAVASCRIPTS: - self.assertNotIn(id, resource_ids, '%s not removed' % id) + self.assertNotIn(JAVASCRIPT, resource_ids) + @unittest.skipIf(IS_PLONE_5, 'No easy way to test this under Plone 5') def test_cssregistry_removed(self): resource_ids = self.portal.portal_css.getResourceIds() - for id in CSS: - self.assertNotIn(id, resource_ids, '%s not removed' % id) + self.assertNotIn(CSS, resource_ids) diff --git a/sc/social/like/tests/test_upgrades.py b/sc/social/like/tests/test_upgrades.py index 42ce0570..61b155cd 100644 --- a/sc/social/like/tests/test_upgrades.py +++ b/sc/social/like/tests/test_upgrades.py @@ -66,3 +66,87 @@ def test_move_mobile_detection_client_side(self): # Check self.assertIn(JS_ID, js_tool.getResourceIds()) + + +class To3040TestCase(UpgradeTestCaseBase): + + def setUp(self): + UpgradeTestCaseBase.setUp(self, u'3030', u'3040') + + def test_upgrade_to_3040_registrations(self): + version = self.setup.getLastVersionForProfile(self.profile_id)[0] + self.assertGreaterEqual(int(version), int(self.to_version)) + self.assertEqual(self.total_steps, 2) + + def test_update_configlet_information(self): + # check if the upgrade step is registered + title = u'Update configlet information' + step = self.get_upgrade_step(title) + assert step is not None + + # simulate state on previous version + controlpanel = api.portal.get_tool(name='portal_controlpanel') + configlet = controlpanel.getActionObject('Products/sociallikes') + configlet.setActionExpression('string:${portal_url}/@@likes-providers') + assert configlet.getActionExpression().endswith('@@likes-providers') + + # run the upgrade step to validate the update + self.execute_upgrade_step(step) + + configlet = controlpanel.getActionObject('Products/sociallikes') + self.assertTrue( + configlet.getActionExpression().endswith('@@sociallike-settings')) + + def test_migrate_settings_to_registry(self): + # check if the upgrade step is registered + title = u'Migrate package settings to registry' + step = self.get_upgrade_step(title) + assert step is not None + + # simulate state on previous version + from plone.registry.interfaces import IRegistry + from sc.social.like.config import PROJECTNAME + from sc.social.like.interfaces import ISocialLikeSettings + from zope.component import getUtility + + # restore old property sheet + portal_properties = api.portal.get_tool(name='portal_properties') + portal_properties.manage_addPropertySheet('sc_social_likes_properties') + old_props = portal_properties['sc_social_likes_properties'] + enabled_portal_types = ('Event', 'Document', 'News Item', 'File') + old_props.manage_addProperty( + 'enabled_portal_types', enabled_portal_types, 'lines') + old_props.manage_addProperty('typebutton', 'horizontal', 'string') + old_props.manage_addProperty('twittvia', '', 'string') + old_props.manage_addProperty('fbaction', '', 'string') + old_props.manage_addProperty('fbadmins', '', 'string') + old_props.manage_addProperty('fbapp_id', '', 'string') + old_props.manage_addProperty('fbbuttons', ('Like',), 'lines') + plugins_enabled = ('Facebook', 'Twitter', 'Google+') + old_props.manage_addProperty( + 'plugins_enabled', plugins_enabled, 'lines') + old_props.manage_addProperty('do_not_track', False, 'boolean') + + # remove registry settings + profile = 'profile-{0}:uninstall'.format(PROJECTNAME) + setup_tool = api.portal.get_tool(name='portal_setup') + setup_tool.runImportStepFromProfile(profile, 'plone.app.registry') + registry = getUtility(IRegistry) + with self.assertRaises(KeyError): + registry.forInterface(ISocialLikeSettings) + + # run the upgrade step to validate the update + self.execute_upgrade_step(step) + + self.assertNotIn('sc_social_likes_properties', portal_properties) + + settings = registry.forInterface(ISocialLikeSettings) + self.assertEqual(settings.enabled_portal_types, enabled_portal_types) + self.assertEqual(settings.plugins_enabled, plugins_enabled) + self.assertEqual(settings.typebutton, u'horizontal') + self.assertFalse(settings.do_not_track) + self.assertEqual(settings.fbaction, u'like') + self.assertEqual(settings.facebook_username, '') + self.assertEqual(settings.facebook_app_id, '') + self.assertEqual(settings.fbbuttons, (u'Like',)) + self.assertEqual(settings.twitter_username, '') diff --git a/sc/social/like/tests/test_viewlets.py b/sc/social/like/tests/test_viewlets.py index 7b5cbed7..27d07824 100644 --- a/sc/social/like/tests/test_viewlets.py +++ b/sc/social/like/tests/test_viewlets.py @@ -1,14 +1,18 @@ # -*- coding: utf-8 -*- -from sc.social.like.testing import INTEGRATION_TESTING +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID from sc.social.like.browser.viewlets import SocialLikesViewlet from sc.social.like.browser.viewlets import SocialMetadataViewlet +from sc.social.like.interfaces import ISocialLikeSettings from sc.social.like.interfaces import ISocialLikeLayer -from plone.app.testing import setRoles -from plone.app.testing import TEST_USER_ID +from sc.social.like.testing import INTEGRATION_TESTING from zope.interface import alsoProvides import unittest +do_not_track = ISocialLikeSettings.__identifier__ + '.do_not_track' + class MetadataViewletTestCase(unittest.TestCase): @@ -97,18 +101,18 @@ def test_rendermethod_default(self): self.assertEqual(viewlet.render_method, 'plugin') def test_rendermethod_privacy(self): - self.portal.portal_properties.sc_social_likes_properties.do_not_track = True + api.portal.set_registry_record(do_not_track, True) viewlet = self.viewlet(self.document) self.assertEqual(viewlet.render_method, 'link') def test_rendermethod_privacy_opt_cookie(self): - self.portal.portal_properties.sc_social_likes_properties.do_not_track = False + api.portal.set_registry_record(do_not_track, False) self.request.cookies['social-optout'] = 'true' viewlet = self.viewlet(self.document) self.assertEqual(viewlet.render_method, 'link') def test_rendermethod_privacy_donottrack(self): - self.portal.portal_properties.sc_social_likes_properties.do_not_track = False + api.portal.set_registry_record(do_not_track, False) self.request.environ['HTTP_DNT'] = '1' viewlet = self.viewlet(self.document) self.assertEqual(viewlet.render_method, 'link') diff --git a/sc/social/like/upgrades/configure.zcml b/sc/social/like/upgrades/configure.zcml index 3b6950ff..5daf6c14 100644 --- a/sc/social/like/upgrades/configure.zcml +++ b/sc/social/like/upgrades/configure.zcml @@ -9,5 +9,6 @@ + diff --git a/sc/social/like/upgrades/v3040/__init__.py b/sc/social/like/upgrades/v3040/__init__.py new file mode 100644 index 00000000..d7b0e77f --- /dev/null +++ b/sc/social/like/upgrades/v3040/__init__.py @@ -0,0 +1,45 @@ +# -*- coding:utf-8 -*- +from plone import api +from plone.registry.interfaces import IRegistry +from sc.social.like.config import PROJECTNAME +from sc.social.like.interfaces import ISocialLikeSettings +from sc.social.like.logger import logger +from zope.component import getUtility +from zope.schema.interfaces import ConstraintNotSatisfied + + +def update_configlet_information(setup_tool): + """Update configlet information.""" + controlpanel = api.portal.get_tool(name='portal_controlpanel') + configlet = controlpanel.getActionObject('Products/sociallikes') + if configlet is not None: + configlet.setActionExpression('string:${portal_url}/@@sociallike-settings') + logger.info('Configlet information updated') + + +def migrate_settings_to_registry(setup_tool): + """Migrate settings to registry.""" + 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' in portal_properties: + old_props = portal_properties.sc_social_likes_properties + registry = getUtility(IRegistry) + settings = registry.forInterface(ISocialLikeSettings) + settings.enabled_portal_types = old_props.enabled_portal_types + settings.plugins_enabled = old_props.plugins_enabled + settings.typebutton = old_props.typebutton + settings.do_not_track = old_props.do_not_track + # this property may have an invalid value under certain circunstances + try: + settings.fbaction = old_props.fbaction + except ConstraintNotSatisfied: # empty string + settings.fbaction = u'like' # use default + settings.facebook_username = old_props.fbadmins + settings.facebook_app_id = old_props.fbapp_id + settings.fbbuttons = old_props.fbbuttons + settings.twitter_username = old_props.twittvia + logger.info('Settings migrated') + + del portal_properties['sc_social_likes_properties'] + logger.info('sc_social_likes_properties removed') diff --git a/sc/social/like/upgrades/v3040/configure.zcml b/sc/social/like/upgrades/v3040/configure.zcml new file mode 100644 index 00000000..c4844814 --- /dev/null +++ b/sc/social/like/upgrades/v3040/configure.zcml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/sc/social/like/vocabularies.py b/sc/social/like/vocabularies.py index 9ee36edb..a7d40290 100644 --- a/sc/social/like/vocabularies.py +++ b/sc/social/like/vocabularies.py @@ -1,5 +1,6 @@ # -*- coding:utf-8 -*- from plone.memoize import forever +from sc.social.like import LikeMessageFactory as _ from sc.social.like.plugins import IPlugin from zope.component import getUtilitiesFor from zope.interface import implements @@ -29,3 +30,20 @@ def __call__(self, context): return self.plugins() PluginsVocabularyFactory = PluginsVocabulary() + + +TypeButtonVocabulary = SimpleVocabulary([ + SimpleTerm(value=u'horizontal', title=_(u'horizontal')), + SimpleTerm(value=u'vertical', title=_(u'vertical')), +]) + + +FacebookVerbsVocabulary = SimpleVocabulary([ + SimpleTerm(value=u'like', title=_(u'Like')), + SimpleTerm(value=u'recommend', title=_(u'Recommend')), +]) + +FacebookButtonsVocabulary = SimpleVocabulary([ + SimpleTerm(value=u'Like', title=_(u'Like')), + SimpleTerm(value=u'Share', title=_(u'Share')), +]) diff --git a/setup.py b/setup.py index a45b1626..4418691f 100644 --- a/setup.py +++ b/setup.py @@ -43,17 +43,19 @@ zip_safe=False, install_requires=[ 'Acquisition', - 'plone.app.controlpanel', + 'plone.api', 'plone.app.layout', + 'plone.app.registry', 'plone.app.upgrade', 'plone.memoize', + 'plone.registry', + 'plone.supermodel', 'Products.Archetypes', 'Products.CMFCore', 'Products.CMFDefault', 'Products.CMFPlone >=4.2', 'Products.CMFQuickInstallerTool', 'Products.GenericSetup', - 'plone.api', 'setuptools', 'zope.component', 'zope.i18nmessageid',