Exemplo n.º 1
0
class ViewletSettingsStorage(Persistent):
    implements(IViewletSettingsStorage)

    def __init__(self):
        self._order = PersistentDict()
        self._hidden = PersistentDict()
        self._defaults = PersistentDict()

    def getOrder(self, name, skinname):
        skin = self._order.get(skinname, {})
        order = skin.get(name, ())
        if not order:
            skinname = self.getDefault(name)
            if skinname is not None:
                skin = self._order.get(skinname, {})
                order = skin.get(name, ())
        return order

    def setOrder(self, name, skinname, order):
        skin = self._order.setdefault(skinname, PersistentDict())
        skin[name] = tuple(order)
        if self.getDefault(name) is None:
            self.setDefault(name, skinname)

    def getHidden(self, name, skinname):
        skin = self._hidden.get(skinname, {})
        hidden = skin.get(name, ())
        if not hidden:
            skinname = self.getDefault(name)
            if skinname is not None:
                skin = self._hidden.get(skinname, {})
                hidden = skin.get(name, ())
        return hidden

    def setHidden(self, name, skinname, hidden):
        skin = self._hidden.setdefault(skinname, PersistentDict())
        skin[name] = tuple(hidden)

    def getDefault(self, name):
        try:
            return self._defaults.get(name)
        except AttributeError:  # Backward compatibility
            self._defaults = PersistentDict()
            self.setDefault(name, 'Plone Default')
            return self.getDefault(name)

    def setDefault(self, name, skinname):
        try:
            self._defaults[name] = skinname
        except AttributeError:  # Backward compatibility
            self._defaults = PersistentDict()
            self.setDefault(name, skinname)
Exemplo n.º 2
0
class DavizSettings(SimpleItem):
    """ Daviz Settings
    """
    meta_type = "EEA Daviz Settings"
    security = ClassSecurityInfo()
    implements(IDavizSettings)
    id = 'portal_daviz'

    manage_options = (
        {'label': 'Edit', 'action': 'zmi_edit_html'},
    ) + SimpleItem.manage_options

    def __init__(self, p_id, title="all daviz settings"):
        super(DavizSettings, self).__init__()
        self._setId(p_id)
        self.title = title
        self.settings = PersistentDict()

        site = getSite()
        sm = site.getSiteManager()
        ds = sm.queryUtility(IDavizSettings)
        if ds:
            sm.unregisterUtility(ds, IDavizSettings)
        sm.registerUtility(self, IDavizSettings)

    def disabled(self, view, content_type):
        """ Is view disabled for given content_type
        """
        if not isinstance(view, (str, unicode)):
            view = getattr(view, '__name__', '')
        if not isinstance(content_type, (str, unicode)):
            content_type = getattr(content_type, 'portal_type',
                           getattr(content_type, 'meta_type', None))
        portal_types = self.settings.get(u'forbidden.%s' % view, None) or []
        return content_type in portal_types
Exemplo n.º 3
0
class Base(object):
    use_interface = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('wc.pageturner', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            self._metadata['last_updated'] = DateTime('1901/01/01').ISO8601()
            annotations['wc.pageturner'] = self._metadata

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'use_interface']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in self.use_interface.names():
            default = self.use_interface[name].default

        return self._metadata.get(name, default)
Exemplo n.º 4
0
class Base(object):
    use_interface = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('wc.pageturner', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            self._metadata['last_updated'] = DateTime('1901/01/01').ISO8601()
            annotations['wc.pageturner'] = self._metadata

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'use_interface']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in self.use_interface.names():
            default = self.use_interface[name].default

        return self._metadata.get(name, default)
class Base(object):
    use_interface = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('collective.documentviewer', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            self._metadata['last_updated'] = DateTime('1901/01/01').ISO8601()
            self.storage_version = STORAGE_VERSION
            annotations['collective.documentviewer'] = self._metadata

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'use_interface']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in self.use_interface.names():
            default = self.use_interface[name].default
        elif name in _defaults:
            default = _defaults.get(name, None)

        return self._metadata.get(name, default)
class Base(object):
    use_interface = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get("collective.documentviewer", None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            self._metadata["last_updated"] = DateTime("1901/01/01").ISO8601()
            self.storage_version = STORAGE_VERSION
            annotations["collective.documentviewer"] = self._metadata

    def __setattr__(self, name, value):
        if name[0] == "_" or name in ["context", "use_interface"]:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in self.use_interface.names():
            default = self.use_interface[name].default
        elif name in _defaults:
            default = _defaults.get(name, None)

        return self._metadata.get(name, default)
Exemplo n.º 7
0
class AnnotationAdapter(object):
    """Abstract Base Class for an annotation storage.

    If the annotation wasn't set, it won't be created until the first attempt
    to set a property on this adapter.
    So, the context doesn't get polluted with annotations by accident.

    """
    ANNOTATION_KEY = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(context)
        self._data = annotations.get(self.ANNOTATION_KEY, None)

    def __setattr__(self, name, value):
        if name in ('context', '_data', 'ANNOTATION_KEY'):
            self.__dict__[name] = value
        else:
            if self._data is None:
                self._data = PersistentDict()
                annotations = IAnnotations(self.context)
                annotations[self.ANNOTATION_KEY] = self._data
            self._data[name] = value

    def __getattr__(self, name):
        return self._data.get(name, None) if self._data else None
class DavizSettings(SimpleItem):
    """ Daviz Settings
    """
    meta_type = "EEA Daviz Settings"
    security = ClassSecurityInfo()
    implements(IDavizSettings)
    id = 'portal_daviz'

    manage_options = (
        {'label': 'Edit', 'action': 'zmi_edit_html'},
    ) + SimpleItem.manage_options

    def __init__(self, p_id, title="all daviz settings"):
        super(DavizSettings, self).__init__()
        self._setId(p_id)
        self.title = title
        self.settings = PersistentDict()

        site = getSite()
        sm = site.getSiteManager()
        ds = sm.queryUtility(IDavizSettings)
        if ds:
            sm.unregisterUtility(ds, IDavizSettings)
        sm.registerUtility(self, IDavizSettings)

    def disabled(self, view, content_type):
        """ Is view disabled for given content_type
        """
        if not isinstance(view, (str, unicode)):
            view = getattr(view, '__name__', '')
        if not isinstance(content_type, (str, unicode)):
            content_type = getattr(content_type, 'portal_type',
                           getattr(content_type, 'meta_type', None))
        portal_types = self.settings.get(u'forbidden.%s' % view, None) or []
        return content_type in portal_types
Exemplo n.º 9
0
class AnnotationAdapter(object):
    """Abstract Base Class for an annotation storage.

    If the annotation wasn't set, it won't be created until the first attempt
    to set a property on this adapter.
    So, the context doesn't get polluted with annotations by accident.

    """
    ANNOTATION_KEY = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(context)
        self._data = annotations.get(self.ANNOTATION_KEY, None)

    def __setattr__(self, name, value):
        if name in ('context', '_data', 'ANNOTATION_KEY'):
            self.__dict__[name] = value
        else:
            if self._data is None:
                self._data = PersistentDict()
                annotations = IAnnotations(self.context)
                annotations[self.ANNOTATION_KEY] = self._data
            self._data[name] = value

    def __getattr__(self, name):
        return self._data and self._data.get(name, None) or None
Exemplo n.º 10
0
class Base(object):
    use_interface = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('vindula.streaming', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            self._metadata['last_updated'] = DateTime('1901/01/01').ISO8601()
            self.storage_version = STORAGE_VERSION
            annotations['vindula.streaming'] = self._metadata

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'use_interface']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in self.use_interface.names():
            default = self.use_interface[name].default
        elif name in _defaults:
            default = _defaults.get(name, None)

        return self._metadata.get(name, default)
Exemplo n.º 11
0
class Base(object):
    use_interface = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('wildcard.media', None)

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'use_interface']:
            self.__dict__[name] = value
        else:
            if self._metadata is None:
                self._metadata = PersistentDict()
                annotations = IAnnotations(self.context)
                annotations['wildcard.media'] = self._metadata
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in self.use_interface.names():
            default = self.use_interface[name].default

        if self._metadata is None:
            return default
        return self._metadata.get(name, default)
Exemplo n.º 12
0
class FeedSettings(object):
    implements(IFeedSettings)
    adapts(ISyndicatable)

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(context)

        self._metadata = annotations.get(FEED_SETTINGS_KEY, None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations[FEED_SETTINGS_KEY] = self._metadata

        registry = getUtility(IRegistry)
        self.site_settings = registry.forInterface(ISiteSyndicationSettings)

    def __setattr__(self, name, value):
        if name in ('context', '_metadata', 'site_settings'):
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in ISiteSyndicationSettings.names():
            default = getattr(self.site_settings, name)
        elif name == 'enabled' and self.site_settings.default_enabled:
            default = True
        elif name in IFeedSettings.names():
            default = IFeedSettings[name].default

        return self._metadata.get(name, default)
class RosterSettings(object):
    use_interface = None

    def __init__(self, context, interface):
        self.use_interface = interface
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('collective.eventmanager', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations['collective.eventmanager'] = self._metadata

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'use_interface']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        default = None
        if name in self.use_interface.names():
            default = self.use_interface[name].default

        return self._metadata.get(name, default)
Exemplo n.º 14
0
    def copy_meta(self):
        # XXX disable working copy support
        return json.dumps({
            'newId': self.request.get('metaId'),
            'success': True,
            'locked': False
        })
        _id = self.request.get('metaId')
        copy_id = self.get_working_copy_meta_id()
        annotations = IAnnotations(self.context)
        data = annotations.get(TILE_ANNOTATIONS_KEY_PREFIX + '.' + _id)
        if not data:
            data = PersistentDict()

        if ('locked' in data and self.request.get(
                'override', '').lower() not in ('y', 'yes', '1', 'true', 't')
                and api.user.get_current().getId() != data['locked']['user']):
            return json.dumps({
                'locked': True,
                'success': False,
                'lock_data': data['locked']
            })

        if TILE_ANNOTATIONS_KEY_PREFIX + '.' + copy_id in annotations:
            # cut out, we're good, resume existing
            return json.dumps({
                'newId': copy_id,
                'success': True,
                'locked': False
            })

        version_key = self.get_working_copy_key()
        tile_mapping = {}
        new_tiles = []
        for tile in data.get('tiles', []):
            # make copies of all the tiles
            tile_id = tile['id']
            copy_tile_id = '{}-{}'.format(tile_id, version_key)
            tile_data = annotations.get(TILE_ANNOTATIONS_KEY_PREFIX + '.' +
                                        tile_id)
            if tile_data:
                annotations[TILE_ANNOTATIONS_KEY_PREFIX + '.' +
                            copy_tile_id] = deepcopy(tile_data)
            new_tile_info = deepcopy(tile)
            new_tile_info['id'] = copy_tile_id
            new_tiles.append(new_tile_info)
            tile_mapping[tile_id] = copy_tile_id

        new_data = PersistentDict(dict(data))
        new_data.update({'tiles': new_tiles, 'mapping': tile_mapping})
        data.update({
            'locked': {
                'when': DateTime().ISO8601(),
                'user': api.user.get_current().getId()
            }
        })
        annotations[TILE_ANNOTATIONS_KEY_PREFIX + '.' + copy_id] = new_data

        return json.dumps({'newId': copy_id, 'success': True, 'locked': False})
Exemplo n.º 15
0
class TilesSettings(object):
    """
    """
    implements(IPageTilesSettings, IPageTilesSettings)

    interfaces = []

    def __init__(self, context):
        self.context = context

        try:
            annotations = IAnnotations(self.context)
        except TypeError:
            # XXX for things like plone.app.event, traversers
            # are not adaptable so we need to look at the parent here
            self.context = aq_parent(context)
            annotations = IAnnotations(self.context)

        self._metadata = annotations.get('tx.tiles', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations['tx.tiles'] = self._metadata

        ctx = aq_inner(context)
        rootctx = getToolByName(ctx, 'portal_url').getPortalObject()
        rootannotations = IAnnotations(rootctx)
        self._rootmetadata = rootannotations.get('tx.tiles', None)
        if self._rootmetadata is None:
            self._rootmetadata = PersistentDict()
            rootannotations['tx.tiles'] = self._rootmetadata

    @property
    def __parent__(self):
        return self.context

    @property
    def __roles__(self):
        return self.context.__roles__

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'interfaces']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        value = self._metadata.get(name)
        if value is None:
            # first check to see if there are global settings
            if name in self._rootmetadata:
                return self._rootmetadata[name]
            else:
                # no global settings, check to see if there are defaults
                for interface in self.interfaces:
                    v = interface.get(name)
                    if v:
                        return v.default
        return value
class UserIdentities(Persistent):

    def __init__(self, userid):
        self.userid = userid
        self._identities = PersistentDict()
        self._sheet = None
        self._secret = str(uuid.uuid4())

    @property
    def secret(self):
        return self._secret

    def check_password(self, password):
        return password == self._secret

    def handle_result(self, result):
        """add a authomatic result to this user
        """
        self._sheet = None  # invalidate property sheet
        self._identities[result.provider.name] = UserIdentity(result)

    def identity(self, provider):
        """users identity at a distinct provider
        """
        return self._identities.get(provider, None)

    def update_userdata(self, result):
        self._sheet = None  # invalidate property sheet
        identity = self._identities[result.provider.name]
        identity.update(result.user.to_dict())

    @property
    def propertysheet(self):
        if self._sheet is not None:
            return self._sheet
        # build sheet from identities
        pdata = dict(id=self.userid)
        cfgs_providers = authomatic_cfg()
        for provider_name in cfgs_providers:
            identity = self.identity(provider_name)
            if identity is None:
                continue
            logger.debug(identity)
            cfg = cfgs_providers[provider_name]
            for akey, pkey in cfg.get('propertymap', {}).items():
                # Always search first on the user attributes, then on the raw
                # data this guaratees we do not break existing configurations
                ainfo = identity.get(akey, identity['data'].get(akey, None))
                if ainfo is None:
                    continue
                if isinstance(pkey, dict):
                    for k, v in pkey.items():
                        pdata[k] = ainfo.get(v)
                else:
                    pdata[pkey] = ainfo
        self._sheet = UserPropertySheet(**pdata)
        return self._sheet
Exemplo n.º 17
0
class GallerySettings(object):
    """
    Just uses Annotation storage to save and retrieve the data...
    """
    implements(IGallerySettings)

    # these are settings for defaults that are not listed
    # in the interface because I don't want them to show up
    # in the schema
    defaults = {
        'last_cooked_time_in_seconds': 0,
        'cooked_images': []
    }

    def __init__(self, context, interfaces=[IGallerySettings]):
        """
        The interfaces argument allows you to customize which
        interface these settings implemenet.
        """
        self.context = context

        self._interfaces = interfaces
        if type(self._interfaces) not in (list, tuple):
            self._interfaces = [self._interfaces]
        self._interfaces = list(self._interfaces)
        if IGallerySettings not in self._interfaces:
            self._interfaces.append(IGallerySettings)

        annotations = IAnnotations(context)

        self._metadata = annotations.get('collective.plonetruegallery', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations['collective.plonetruegallery'] = self._metadata

    def __setattr__(self, name, value):
        if name in ('context', '_metadata', '_interfaces', 'defaults'):
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        """
        since we have multiple settings that are possible to be used
        here, we have to interate over those interfaces to find the
        default values here.
        """
        default = None

        if name in self.defaults:
            default = self.defaults[name]

        for iface in self._interfaces:
            if name in iface.names():
                default = iface[name].default

        return self._metadata.get(name, default)
Exemplo n.º 18
0
class UserIdentities(Persistent):
    def __init__(self, userid):
        self.userid = userid
        self._identities = PersistentDict()
        self._sheet = None
        self._secret = str(uuid.uuid4())

    @property
    def secret(self):
        return self._secret

    def check_password(self, password):
        return password == self._secret

    def handle_result(self, result):
        """add a authomatic result to this user
        """
        self._sheet = None  # invalidate property sheet
        self._identities[result.provider.name] = UserIdentity(result)

    def identity(self, provider):
        """users identity at a distinct provider
        """
        return self._identities.get(provider, None)

    def update_userdata(self, result):
        self._sheet = None  # invalidate property sheet
        identity = self._identities[result.provider.name]
        identity.update(result.user.to_dict())

    @property
    def propertysheet(self):
        if self._sheet is not None:
            return self._sheet
        # build sheet from identities
        pdata = dict(id=self.userid)
        cfgs_providers = authomatic_cfg()
        for provider_name in cfgs_providers:
            identity = self.identity(provider_name)
            if identity is None:
                continue
            logger.debug(identity)
            cfg = cfgs_providers[provider_name]
            for akey, pkey in cfg.get('propertymap', {}).items():
                # Always search first on the user attributes, then on the raw
                # data this guaratees we do not break existing configurations
                ainfo = identity.get(akey, identity['data'].get(akey, None))
                if ainfo is None:
                    continue
                if isinstance(pkey, dict):
                    for k, v in pkey.items():
                        pdata[k] = ainfo.get(v)
                else:
                    pdata[pkey] = ainfo
        self._sheet = UserPropertySheet(**pdata)
        return self._sheet
Exemplo n.º 19
0
class SliderSettings(object):
    """
    Pretty much copied how it is done in Slideshow Folder
    hopefully no one is foolish enough to want a custom slider
    and a view slider.  If they are then the settings will
    overlap.
    """
    implements(IPageSliderSettings)

    interfaces = []

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('collective.easyslider', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations['collective.easyslider'] = self._metadata

        ctx = aq_inner(context)
        rootctx = getToolByName(ctx, 'portal_url').getPortalObject()
        rootannotations = IAnnotations(rootctx)
        self._rootmetadata = rootannotations.get('collective.easyslider', None)
        if self._rootmetadata is None:
            self._rootmetadata = PersistentDict()
            rootannotations['collective.easyslider'] = self._rootmetadata

    @property
    def __parent__(self):
        return self.context

    @property
    def __roles__(self):
        return self.context.__roles__

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'interfaces']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        value = self._metadata.get(name)
        if value is None:
            # first check to see if there are global settings
            if name in self._rootmetadata:
                return self._rootmetadata[name]
            else:
                # no global settings, check to see if there are defaults
                for interface in self.interfaces:
                    v = interface.get(name)
                    if v:
                        return v.default
        return value
Exemplo n.º 20
0
class CatalogBlacklist(UniqueObject, SimpleItem):

    implements(ICatalogBlacklist)

    id = 'portal_catalogblacklist'
    meta_type = 'Catalog Blacklist Tool'

    security = ClassSecurityInfo()

    def __init__(self, id=None):
        self._blacklisted_types = PersistentDict()
        self._blacklisted_interfaces = PersistentDict()

    security.declarePrivate('extend')
    def extend(self, blacklisted_types=None, blacklisted_interfaces=None):
        """ extend the blacklisted indexes for the given types or
            interfaces
        """
        if blacklisted_types is not None:
            for pt, indexnames in blacklisted_types.items():
                self._blacklisted_types.setdefault(pt, [])
                for name in indexnames:
                    if name not in self._blacklisted_types[pt]:
                        self._blacklisted_types[pt].append(name)
            self._blacklisted_types._p_changed = 1

        if blacklisted_interfaces is not None:
            for iface, indexnames in blacklisted_interfaces.items():
                if isinstance(iface, StringTypes):
                    iface = resolve(iface)
                self._blacklisted_interfaces.setdefault(iface, [])
                for name in indexnames:
                    if name not in self._blacklisted_interfaces[iface]:
                        self._blacklisted_interfaces[iface].append(name)
            self._blacklisted_interfaces._p_changed = 1

    security.declarePrivate('getBlackListedIndexesForObject')
    def getBlackListedIndexesForObject(self, object):
        """ return blacklisted indexes for object
        """
        portal_type = getattr(object, 'portal_type', None)
        blacklisted = []
        for indexname in self._blacklisted_types.get(portal_type, []):
            blacklisted.append(indexname)

        # Inspect the interfaces
        for iface, indexes in \
                self._blacklisted_interfaces.items():                
            if iface.providedBy(object):
                for indexname in indexes:
                    if indexname not in blacklisted:
                        blacklisted.append(indexname)

        return blacklisted
Exemplo n.º 21
0
    def add_view(self, name, **kwargs):
        """ Add view

            >>> _ = visualization.add_view(name='daviz.map',
            ...                     lat='latitude', long='longitude')
            >>> view = visualization.view('daviz.map')
            >>> sorted(view.items())
            [('lat', 'latitude'), ('long', 'longitude'), ('name', 'daviz.map')]

        """
        config = self._views()
        kwargs.update({'name': name})
        view = PersistentDict(kwargs)
        config.append(view)
        return view.get('name', '')
Exemplo n.º 22
0
    def add_facet(self, name, **kwargs):
        """ Add facet

            >>> _ = visualization.add_facet('country', a=1, b=2)
            >>> facet = visualization.facet('country')
            >>> sorted(facet.items())
            [('a', 1), ('b', 2), ('label', 'country'), ('name', ...]

        """
        config = self._facets()
        kwargs.update({'name': name})
        kwargs.setdefault('type', u'daviz.list.facet')
        facet = PersistentDict(kwargs)
        config.append(facet)
        return facet.get('name', '')
Exemplo n.º 23
0
    def add_facet(self, name, **kwargs):
        """ Add facet

            >>> _ = visualization.add_facet('country', a=1, b=2)
            >>> facet = visualization.facet('country')
            >>> sorted(facet.items())
            [('a', 1), ('b', 2), ('label', 'country'), ('name', ...]

        """
        config = self._facets()
        kwargs.update({'name': name})
        kwargs.setdefault('type', u'daviz.list.facet')
        facet = PersistentDict(kwargs)
        config.append(facet)
        return facet.get('name', '')
Exemplo n.º 24
0
class PortletAssignmentSettings(Contained):
    def __init__(self):
        self.data = PersistentDict()

    def __setitem__(self, name, value):
        self.data[name] = value

    def __delitem__(self, name):
        del self.data[name]

    def __getitem__(self, name):
        return self.data.__getitem__(name)

    def get(self, name, default=None):
        return self.data.get(name, default)
Exemplo n.º 25
0
    def add_source(self, name, **kwargs):
        """ Add source

            >>> _ = visualization.add_source('http://bit.ly/rdf', type='rdf')
            >>> source = visualization.source('http://bit.ly/rdf')
            >>> sorted(source.items())
            [('name', 'http://bit.ly/rdf'), ('type', 'rdf')]

        """
        config = self._sources()
        kwargs.update({'name': name})
        kwargs.setdefault('type', u'json')
        source = PersistentDict(kwargs)
        config.append(source)
        return source.get('name', '')
Exemplo n.º 26
0
    def add_source(self, name, **kwargs):
        """ Add source

            >>> _ = visualization.add_source('http://bit.ly/rdf', type='rdf')
            >>> source = visualization.source('http://bit.ly/rdf')
            >>> sorted(source.items())
            [('name', 'http://bit.ly/rdf'), ('type', 'rdf')]

        """
        config = self._sources()
        kwargs.update({'name': name})
        kwargs.setdefault('type', u'json')
        source = PersistentDict(kwargs)
        config.append(source)
        return source.get('name', '')
class Tool(UniqueObject, SimpleItem):
    """
    Contentrules subscription tool
    """
    id = SUBSCRIPTION_TOOL
    meta_type = 'Contentrules Subscription Tool'
    plone_tool = 1

    def __init__(self):
        self.subscriptions = PersistentDict()

    def registerUser(self, rule_id, email):
        """
        Insert the given email address in the given rule_id
        """
        if not rule_id in self.subscriptions:
            self.subscriptions[rule_id] = [email]
        else:
            if email in self.subscriptions[rule_id]:
                factory = getUtility(IVocabularyFactory,
                                     "contentrules.subscription.vocabularies.SubscriptionRulesVocabulary")
                vocabulary = factory(self)
                rule_term = vocabulary.getTerm(rule_id)
                msg = _('already_subscribed_error',
                        default='The given email is already present for "${title}"',
                        mapping=dict(title=rule_term.title))
                return False, msg
            else:
                self.subscriptions[rule_id].append(email)
        return True, ""

    def getSubscriptions(self):
        """
        Return the list of subscriptions
        """
        return self.subscriptions

    def getActionUIDS(self):
        """
        return a list of email addresses for the given rule_id
        """
        return self.subscriptions.keys()

    def getRegisteredList(self, rule_id):
        """
        return a list of email addresses for the given rule_id
        """
        return self.subscriptions.get(rule_id, [])
Exemplo n.º 28
0
class PortletAssignmentSettings(Contained):

    def __init__(self):
        self.data = PersistentDict()

    def __setitem__(self, name, value):
        self.data[name] = value

    def __delitem__(self, name):
        del self.data[name]

    def __getitem__(self, name):
        return self.data.__getitem__(name)

    def get(self, name, default=None):
        return self.data.get(name, default)
Exemplo n.º 29
0
class UserAnnotation(object):
    """Stores annotations."""
    def __init__(self, principalId, store=None):
        self.principalId = principalId
        # _v_store is used to remember a mapping object that we should
        # be saved in if we ever change
        self._v_store = store
        self._data = PersistentDict() if store is None else store.get(
            principalId, PersistentDict())

    def __bool__(self):
        return bool(self._data)

    __nonzero__ = __bool__

    def __getitem__(self, key):
        return self._data[key]

    def get(self, key, default=None):
        return self._data.get(key, default)

    def keys(self):
        return self._data.keys()

    def __iter__(self):
        return iter(self._data)

    def __len__(self):
        return len(self._data)

    def __setitem__(self, key, value):
        if getattr(self, '_v_store', None) is not None:
            # _v_store is used to remember a mapping object that we should
            # be saved in if we ever change
            self._v_store[self.principalId] = self._data
            del self._v_store

        self._data[key] = value

    def __delitem__(self, key):
        del self._data[key]

    def __contains__(self, key):
        return key in self._data

    def items(self):
        return self._data.items()
Exemplo n.º 30
0
class UserAnnotation(object):
    """Stores annotations."""

    def __init__(self, principalId, store=None):
        self.principalId = principalId
        # _v_store is used to remember a mapping object that we should
        # be saved in if we ever change
        self._v_store = store
        self._data = PersistentDict() if store is None else store.get(principalId, PersistentDict())

    def __bool__(self):
        return bool(self._data)

    __nonzero__ = __bool__

    def __getitem__(self, key):
        return self._data[key]

    def get(self, key, default=None):
        return self._data.get(key, default)

    def keys(self):
        return self._data.keys()

    def __iter__(self):
        return iter(self._data)

    def __len__(self):
        return len(self._data)

    def __setitem__(self, key, value):
        if getattr(self, '_v_store', None) is not None:
            # _v_store is used to remember a mapping object that we should
            # be saved in if we ever change
            self._v_store[self.principalId] = self._data
            del self._v_store

        self._data[key] = value

    def __delitem__(self, key):
        del self._data[key]

    def __contains__(self, key):
        return key in self._data

    def items(self):
        return self._data.items()
Exemplo n.º 31
0
class ExtendedMenuSettings(object):
    """
    Pretty much copied how it is done in Slideshow Folder
    hopefully no one is foolish enough to want a custom slider
    and a view slider.  If they are then the settings will
    overlap.
    """

    implements(IExtendedMenuSettings)

    settings_key = "collective.qextendedmenu"

    def __init__(self, context, req=None):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get(self.settings_key, None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations[self.settings_key] = self._metadata

    def __setattr__(self, name, value):
        if name[0] == "_" or name in ["context", "settings_key"]:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def getValue(self, name):
        value = getattr(self, name, None)
        if name == "html" and IRichTextValue.providedBy(value):
            if value.mimeType == value.outputMimeType:
                return self.raw_encoded
            else:
                transformer = ITransformer(self.context, None)
                if transformer is None:
                    return None
                return transformer(value, value.outputMimeType)
        return value

    def __getattr__(self, name):
        value = self._metadata.get(name)
        if value is None:
            v = IExtendedMenuSettings.get(name)
            if v:
                return v.default
        return value
Exemplo n.º 32
0
class FeedSettings(object):
    implements(IFeedSettings)
    adapts(ISyndicatable)

    def __init__(self, context):
        self.context = context
        self.annotations = IAnnotations(context)
        self.needs_saving = False

        self._metadata = self.annotations.get(FEED_SETTINGS_KEY, None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            self.needs_saving = True

        registry = getUtility(IRegistry)
        self.site_settings = registry.forInterface(ISiteSyndicationSettings,
                                                   check=False)

    def _set(self):
        """
        what are we doing here you might ask?
        well, this causes us to write on read so only set on annotation
        if we need to
        """
        if self.needs_saving:
            self.annotations[FEED_SETTINGS_KEY] = self._metadata

    def __setattr__(self, name, value):
        if name in ('context', '_metadata', 'site_settings', 'annotations',
                    'needs_saving'):
            self.__dict__[name] = value
        else:
            self._metadata[name] = value
            self._set()

    def __getattr__(self, name):
        default = None
        if name in ISiteSyndicationSettings.names():
            default = getattr(self.site_settings, name)
        elif name == 'enabled' and self.site_settings.default_enabled:
            default = True
        elif name in IFeedSettings.names():
            default = IFeedSettings[name].default

        return self._metadata.get(name, default)
Exemplo n.º 33
0
    def add_view(self, name, order=None, **kwargs):
        """ Add view

            >>> _ = visualization.add_view(name='daviz.map',
            ...                     lat='latitude', long='longitude')
            >>> view = visualization.view('daviz.map')
            >>> sorted(view.items())
            [('lat', 'latitude'), ('long', 'longitude'), ('name', 'daviz.map')]

        """
        config = self._views()
        kwargs.update({"name": name})
        view = PersistentDict(kwargs)
        if isinstance(order, int):
            config.insert(order, view)
        else:
            config.append(view)
        return view.get("name", "")
Exemplo n.º 34
0
    def add_view(self, name, order=None, **kwargs):
        """ Add view

            >>> _ = visualization.add_view(name='daviz.map',
            ...                     lat='latitude', long='longitude')
            >>> view = visualization.view('daviz.map')
            >>> sorted(view.items())
            [('lat', 'latitude'), ('long', 'longitude'), ('name', 'daviz.map')]

        """
        config = self._views()
        kwargs.update({'name': name})
        view = PersistentDict(kwargs)
        if isinstance(order, int):
            config.insert(order, view)
        else:
            config.append(view)
        return view.get('name', '')
Exemplo n.º 35
0
class AnnotationStorage(object):
    def __init__(self, context):
        self.context = context

        try:
            annotations = IAnnotations(context)
            self._metadata = annotations.get(ANNOTATION_KEY, None)
            if self._metadata is None:
                self._metadata = PersistentDict()
                annotations[ANNOTATION_KEY] = self._metadata
        except TypeError:
            self._metadata = {}

    def put(self, name, value):
        self._metadata[name] = value

    def get(self, name, default=None):
        return self._metadata.get(name, default)
class AnnotationStorage(object):
    def __init__(self, context):
        self.context = context

        try:
            annotations = IAnnotations(context)
            self._metadata = annotations.get(ANNOTATION_KEY, None)
            if self._metadata is None:
                self._metadata = PersistentDict()
                annotations[ANNOTATION_KEY] = self._metadata
        except TypeError:
            self._metadata = {}

    def put(self, name, value):
        self._metadata[name] = value

    def get(self, name, default=None):
        return self._metadata.get(name, default)
Exemplo n.º 37
0
class FlowViewSettings(object):
    """
    Just uses Annotation storage to save and retrieve the data...
    """
    implements(IFlowViewSettings)
    
    defaults = {}
    
    def __init__(self, context, interfaces=[IFlowViewSettings]):

        self.context = context
        
        self._interfaces = interfaces
        if type(self._interfaces) not in (list, tuple):
            self._interfaces = [self._interfaces]
        self._interfaces = list(self._interfaces)
        if IFlowViewSettings not in self._interfaces:
            self._interfaces.append(IFlowViewSettings)
        
        annotations = IAnnotations(context)

        self._metadata = annotations.get('Solgema.FlowView', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations['Solgema.FlowView'] = self._metadata
            
    def __setattr__(self, name, value):
        if name in ('context', '_metadata', '_interfaces', 'defaults'):
            self.__dict__[name] = value
        else:
            self._metadata[name] = value
            
    def __getattr__(self, name):
        default = None
        
        if self.defaults.has_key(name):
            default = self.defaults[name]
        
        for iface in self._interfaces:
            if name in iface.names():
                default = iface[name].default
                        
        return self._metadata.get(name, default)
Exemplo n.º 38
0
class MarscatsSettingsStorage(Persistent):

    implements(IMarscatsSettingsStorage)

    def __init__(self):
        self._fields = PersistentDict()

    def setStartupDir(self, fieldname, startup_dir, portal_type=None):
        field = self._fields.setdefault(fieldname, PersistentDict())
        if portal_type is not None:
            portal_types = field.setdefault('portal_types', PersistentDict())
            portal_types[portal_type] = startup_dir
        else:
            self._fields[fieldname]['startup_directory'] = startup_dir

    def getStartupDir(self, fieldname, portal_type=None,
                            fallback=True, ispath=False):
        sd = ''
        if fallback:
            sd = CAT_CONTAINER
        if fieldname in self._fields.keys():
            field = self._fields.get(fieldname)
            sd = field.get('startup_directory', sd)
            if portal_type is not None:
                pts = field.get('portal_types')
                if pts is not None:
                    sd = pts.get(portal_type, sd)
        if ispath:
            if not sd.startswith(CAT_CONTAINER):
                sd = CAT_CONTAINER + '/' + sd
#            sd = '/' + sd
        return sd

    def getFieldNames(self):
        return list(self._fields)

    def getTypesForField(self, fieldname):
        if fieldname in self._fields:
            field = self._fields[fieldname]
            if 'portal_types' in field and len(field['portal_types']):
                return list(field['portal_types'])
        return list()
Exemplo n.º 39
0
class AnnotationAdapter(object):
    """Abstract Base Class for an annotation storage.
    """
    ANNOTATION_KEY = None

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(context)
        self._data = annotations.get(self.ANNOTATION_KEY, None)
        if self._data is None:
            self._data = PersistentDict()
            annotations[self.ANNOTATION_KEY] = self._data

    def __setattr__(self, name, value):
        if name in ('context', '_data'):
            self.__dict__[name] = value
        else:
            self._data[name] = value

    def __getattr__(self, name):
        return self._data.get(name, None)
class ContextKeys(Persistent):
    grok.implements(IContextKeys)

    def __init__(self):
        self._items = PersistentDict()

    def link(self, key, context):
        id = hash(IKeyReference(context))
        ids = self._items.setdefault(key, PersistentSet())
        ids.add(id)

    def unlink(self, key, context):
        id = hash(IKeyReference(context))
        ids = self._items.setdefault(key, PersistentSet())
        ids.discard(id)
        if not ids:
            del self._items[key]

    def unlinkKey(self, key):
        if key in self._items:
            del self._items[key]

    def unlinkContext(self, context):
        id = hash(IKeyReference(context))
        keys_removed = set()
        for key, ids in self._items.items():
            ids.discard(id)
            if not ids:
                keys_removed.add(key)
        for key in keys_removed:
            del self._items[key]
        return keys_removed

    def isLinked(self, key, context):
        id = hash(IKeyReference(context))
        return id in self._items.get(key, set())

    def __contains__(self, key):
        return key in self._items
Exemplo n.º 41
0
class Annotations(Persistent, Location):
    """Stores annotations."""

    interface.implements(IAnnotations)

    def __init__(self, principalId, store=None):
        self.principalId = principalId
        self.data = PersistentDict() # We don't really expect that many

        # _v_store is used to remember a mapping object that we should
        # be saved in if we ever change
        self._v_store = store

    def __getitem__(self, key):
        try:
            return self.data[key]
        except KeyError:
            # We failed locally: delegate to a higher-level utility.
            utility = queryNextUtility(self, IPrincipalAnnotationUtility)
            if utility is not None:
                annotations = utility.getAnnotationsById(self.principalId)
                return annotations[key]
            raise

    def __setitem__(self, key, value):
        if getattr(self, '_v_store', None) is not None:
            # _v_store is used to remember a mapping object that we should
            # be saved in if we ever change
            self._v_store[self.principalId] = self
            del self._v_store

        self.data[key] = value

    def __delitem__(self, key):
        del self.data[key]

    def get(self, key, default=None):
        return self.data.get(key, default)
Exemplo n.º 42
0
class EasysliderviewletSettings(object):
    """
    Copied from Nathan, let's see if it works.  
    """
    implements(IEasysliderviewletSettings)
    
    interfaces = []

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)

        self._metadata = annotations.get('medialog.easysliderviewlet', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations['medialog.easysliderviewlet'] = self._metadata
    
    @property
    def __parent__(self):
        return self.context

    @property
    def __roles__(self):
        return self.context.__roles__

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'interfaces']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
       value = self._metadata.get(name)
       if value is None:
           v = IEasysliderviewletSettings.get(name)
           if v:
               return v.default
       return value
Exemplo n.º 43
0
class AccessControlCustomisations(Persistent):
    implements(IAccessControlCustomisations)

    def __init__(self):
        self._settings = PersistentDict()

    def getSetting(self, key):
        for setting in self:
            if setting.key == key:
                return setting
        else:
            raise KeyError("there is no AccessControlSetting"
                           " associated with this key.")

    def get(self, key):
        return self._settings.get(key, self.getSetting(key).default)

    def set(self, key, value):
        if self.getSetting(key):
            self._settings[key] = value

    def __iter__(self):
        settings = subscribers([None], IAccessControlSetting)
        return iter(settings)
Exemplo n.º 44
0
class MockContainer(PortalContent):
    """ """
    implements(IUIDKeyedContainer, IAttributeUUID)

    def __init__(self, id, items=None):
        super(MockContainer, self).__init__()
        self.id = id
        self._items = PersistentDict(items)

    def get(self, uid, default=None):
        v = self._items.get(str(uid), None)
        if v and getattr(v, '_v_parent', None) is None:
            v._v_parent = self  # container marks obtained item with context
        return v

    # just here for test use:
    def register(self, uid, item):
        self._items[uid] = item

    def unregister(self, uid):
        del (self._items[uid])

    def __contains__(self, uid):
        return uid in self._items

    # here for indexing purposes, even though these indexes may
    # be handled differently in real life (e.g. indexer adapter):

    def UID(self):
        return IUUID(self)

    def contains(self):
        return self._items.keys()  # UUIDs of contained items

    def items(self):
        return self._items.items()
Exemplo n.º 45
0
class MockContainer(PortalContent):
    """ """
    implements(IUIDKeyedContainer, IAttributeUUID)

    def __init__(self, id, items=None):
        super(MockContainer, self).__init__()
        self.id = id
        self._items = PersistentDict(items)

    def get(self, uid, default=None):
        v = self._items.get(str(uid), None)
        if v and getattr(v, '_v_parent', None) is None:
            v._v_parent = self  # container marks obtained item with context
        return v

    # just here for test use:
    def register(self, uid, item):
        self._items[uid] = item

    def unregister(self, uid):
        del(self._items[uid])

    def __contains__(self, uid):
        return uid in self._items

    # here for indexing purposes, even though these indexes may
    # be handled differently in real life (e.g. indexer adapter):

    def UID(self):
        return IUUID(self)

    def contains(self):
        return self._items.keys()  # UUIDs of contained items

    def items(self):
        return self._items.items()
Exemplo n.º 46
0
class RoleProtectedObject(Persistent, Contained):
    """Base class for object protected by roles"""

    inherit_parent_security = FieldProperty(
        IRoleProtectedObject['inherit_parent_security'])
    everyone_denied = FieldProperty(IRoleProtectedObject['everyone_denied'])
    everyone_granted = FieldProperty(IRoleProtectedObject['everyone_granted'])
    authenticated_denied = FieldProperty(
        IRoleProtectedObject['authenticated_denied'])
    authenticated_granted = FieldProperty(
        IRoleProtectedObject['authenticated_granted'])
    inherit_parent_roles = FieldProperty(
        IRoleProtectedObject['inherit_parent_roles'])

    def __init__(self):
        self._principals_by_role = PersistentDict()
        self._roles_by_principal = PersistentDict()

    def get_everyone_denied(self):
        """Get permissions denied to everyone"""
        permissions = self.everyone_denied or set()
        if self.inherit_parent_security:
            for parent in lineage(self):
                if parent in (self, self.__parent__):
                    continue
                protection = IProtectedObject(parent, None)
                if protection is not None:
                    permissions = permissions | (protection.everyone_denied
                                                 or set())
        return permissions

    def get_everyone_granted(self):
        """Get permissions granted to everyone"""
        permissions = self.everyone_granted or set()
        if self.inherit_parent_security:
            for parent in lineage(self):
                if parent in (self, self.__parent__):
                    continue
                protection = IProtectedObject(parent, None)
                if protection is not None:
                    permissions = permissions | (protection.everyone_granted
                                                 or set())
        return permissions

    def get_authenticated_denied(self):
        """Get permissions denied to authenticated users"""
        permissions = self.authenticated_denied or set()
        if self.inherit_parent_security:
            for parent in lineage(self):
                if parent in (self, self.__parent__):
                    continue
                protection = IProtectedObject(parent, None)
                if protection is not None:
                    permissions = permissions | (
                        protection.authenticated_denied or set())
        return permissions

    def get_authenticated_granted(self):
        """Get permissions granted to authenticated users"""
        permissions = self.authenticated_granted or set()
        if self.inherit_parent_security:
            for parent in lineage(self):
                if parent in (self, self.__parent__):
                    continue
                protection = IProtectedObject(parent, None)
                if protection is not None:
                    permissions = permissions | (
                        protection.authenticated_granted or set())
        return permissions

    def grant_role(self, role_id, principal_ids):
        """Grant role to selected principals"""
        registry = get_pyramid_registry()
        if IRole.providedBy(role_id):
            role_id = role_id.id
        if isinstance(principal_ids, str):
            principal_ids = {principal_ids}
        role_principals = self._principals_by_role.get(role_id) or set()
        for principal_id in principal_ids:
            if IPrincipalInfo.providedBy(principal_id):
                principal_id = principal_id.id
            if principal_id not in role_principals:
                principal_roles = self._roles_by_principal.get(
                    principal_id) or set()
                role_principals.add(principal_id)
                principal_roles.add(role_id)
                self._roles_by_principal[principal_id] = principal_roles
                self._principals_by_role[role_id] = role_principals
                registry.notify(GrantedRoleEvent(self, role_id, principal_id))

    def revoke_role(self, role_id, principal_ids):
        """Revoke role to selected principals"""
        registry = get_pyramid_registry()
        if IRole.providedBy(role_id):
            role_id = role_id.id
        if isinstance(principal_ids, str):
            principal_ids = {principal_ids}
        role_principals = self._principals_by_role.get(role_id) or set()
        for principal_id in principal_ids.copy():
            if IPrincipalInfo.providedBy(principal_id):
                principal_id = principal_id.id
            if principal_id in role_principals:
                principal_roles = self._roles_by_principal.get(
                    principal_id) or set()
                if principal_id in role_principals:
                    role_principals.remove(principal_id)
                if role_id in principal_roles:
                    principal_roles.remove(role_id)
                if principal_roles:
                    self._roles_by_principal[principal_id] = principal_roles
                elif principal_id in self._roles_by_principal:
                    del self._roles_by_principal[principal_id]
                if role_principals:
                    self._principals_by_role[role_id] = role_principals
                elif role_id in self._principals_by_role:
                    del self._principals_by_role[role_id]
                registry.notify(RevokedRoleEvent(self, role_id, principal_id))

    def get_principals(self, role_id):
        """Get principals which have selected role granted"""
        if IRole.providedBy(role_id):
            role_id = role_id.id
        return self._principals_by_role.get(role_id) or set()

    def get_roles(self, principal_id):
        """Get roles for given principal"""
        if IPrincipalInfo.providedBy(principal_id):
            principal_id = principal_id.id
        return self._roles_by_principal.get(principal_id) or set()

    def get_permissions(self, principal_id):
        """Get permissions for given principal"""
        registry = get_pyramid_registry()
        result = set()
        for role_id in self.get_roles(principal_id):
            role = registry.queryUtility(IRole, role_id)
            result |= role.permissions or set()
        return result

    def get_granted_roles(self):
        """Get granted roles on current context or parents"""
        roles = set(self._principals_by_role.keys())
        if self.inherit_parent_roles:
            for parent in lineage(self):
                if parent in (self, self.__parent__):
                    continue
                protection = IProtectedObject(parent, None)
                if protection is not None:
                    roles = roles | protection.get_granted_roles()
        return roles

    @request_property(key=None)
    def __acl__(self):
        """Get ACL for current context

        The result is stored into current request annotations, so it's not supposed to change
        during request lifetime.
        """
        # always grant all permissions to system manager
        # and 'public' permission to everyone
        result = [(Allow, ADMIN_USER_ID, ALL_PERMISSIONS),
                  (Allow, Everyone, {PUBLIC_PERMISSION})]
        # grant access to all roles permissions
        for role_id in self.get_granted_roles():
            role = query_utility(IRole, role_id)
            if role is not None:
                result.append(
                    (Allow, ROLE_ID.format(role_id), role.permissions))
        # add denied permissions to everyone and authenticated
        permissions = self.get_everyone_denied()
        if permissions:
            result.append((Deny, Everyone, permissions))
        permissions = self.get_authenticated_denied()
        if permissions:
            result.append((Deny, Authenticated, permissions))
        # add allowed permissions to everyone and authenticated
        permissions = self.get_authenticated_granted()
        if permissions:
            result.append((Allow, Authenticated, permissions))
        permissions = self.get_everyone_granted()
        if permissions:
            result.append((Allow, Everyone, permissions))
        # deny all parent permissions if inheritance is disabled
        if not self.inherit_parent_security:
            result.append(DENY_ALL)
        LOGGER.debug('ACL({0!r}) = {1}'.format(self.__parent__, str(result)))
        return result
Exemplo n.º 47
0
class SliderSettings(object):
    """
    Pretty much copied how it is done in Slideshow Folder
    hopefully no one is foolish enough to want a custom slider
    and a view slider.  If they are then the settings will
    overlap.
    """
    implements(IPageSliderSettings)

    interfaces = []

    def __init__(self, context):
        self.context = context

        try:
            annotations = IAnnotations(self.context)
        except TypeError:
            # XXX for things like plone.app.event, traversers
            # are not adaptable so we need to look at the parent here
            self.context = aq_parent(context)
            annotations = IAnnotations(self.context)

        self._metadata = annotations.get('collective.easyslider', None)
        if self._metadata is None:
            self._metadata = PersistentDict()
            annotations['collective.easyslider'] = self._metadata

        ctx = aq_inner(context)
        rootctx = getToolByName(ctx, 'portal_url').getPortalObject()
        rootannotations = IAnnotations(rootctx)
        self._rootmetadata = rootannotations.get('collective.easyslider', None)
        if self._rootmetadata is None:
            self._rootmetadata = PersistentDict()
            rootannotations['collective.easyslider'] = self._rootmetadata

    @property
    def __parent__(self):
        return self.context

    @property
    def __roles__(self):
        return self.context.__roles__

    def __setattr__(self, name, value):
        if name[0] == '_' or name in ['context', 'interfaces']:
            self.__dict__[name] = value
        else:
            self._metadata[name] = value

    def __getattr__(self, name):
        value = self._metadata.get(name)
        if value is None:
            # first check to see if there are global settings
            if name in self._rootmetadata:
                return self._rootmetadata[name]
            else:
                # no global settings, check to see if there are defaults
                for interface in self.interfaces:
                    v = interface.get(name)
                    if v:
                        return v.default
        return value
Exemplo n.º 48
0
class Person(User, SearchableEntity, CorrelableEntity, Debatable):
    """Person class"""

    type_title = _('Person')
    icon = 'icon glyphicon glyphicon-user'  #'icon novaideo-icon icon-user'
    templates = {
        'default': 'novaideo:views/templates/person_result.pt',
        'bloc': 'novaideo:views/templates/person_bloc.pt',
        'small': 'novaideo:views/templates/small_person_result.pt',
        'popover': 'novaideo:views/templates/person_popover.pt',
        'card': 'novaideo:views/templates/person_card.pt',
        'header': 'novaideo:views/templates/person_header.pt',
    }
    default_picture = 'novaideo:static/images/user100.png'
    name = renamer()
    tokens = CompositeMultipleProperty('tokens')
    tokens_ref = SharedMultipleProperty('tokens_ref')
    organization = SharedUniqueProperty('organization', 'members')
    events = SharedMultipleProperty('events', 'author')
    picture = CompositeUniqueProperty('picture')
    cover_picture = CompositeUniqueProperty('cover_picture')
    ideas = SharedMultipleProperty('ideas', 'author')
    selections = SharedMultipleProperty('selections')
    working_groups = SharedMultipleProperty('working_groups', 'members')
    wg_participations = SharedMultipleProperty('wg_participations',
                                               'wating_list_participation')
    old_alerts = SharedMultipleProperty('old_alerts')
    following_channels = SharedMultipleProperty('following_channels',
                                                'members')
    folders = SharedMultipleProperty('folders', 'author')
    questions = SharedMultipleProperty('questions', 'author')
    challenges = SharedMultipleProperty('challenges', 'author')
    ballots = CompositeMultipleProperty('ballots')
    mask = SharedUniqueProperty('mask', 'member')

    def __init__(self, **kwargs):
        self.branches = PersistentList()
        self.keywords = PersistentList()
        super(Person, self).__init__(**kwargs)
        kwargs.pop('password', None)
        self.set_data(kwargs)
        self.set_title()
        self.last_connection = datetime.datetime.now(tz=pytz.UTC)
        self._read_at = OOBTree()
        self.guide_tour_data = PersistentDict({})
        self.confidence_index = 0
        self._notes = OOBTree()
        self.allocated_tokens = OOBTree()
        self.len_allocated_tokens = PersistentDict({})
        self.reserved_tokens = PersistentList([])
        self._submited_at = OOBTree()
        self._reported_at = OOBTree()

    def __setattr__(self, name, value):
        super(Person, self).__setattr__(name, value)
        if name == 'organization' and value:
            self.init_contents_organizations()

    def get_len_tokens(self, root=None, exclude_reserved_tokens=False):
        root = root or getSite()
        return root.tokens_mini if exclude_reserved_tokens \
            else root.tokens_mini + len(self.reserved_tokens)

    def get_len_evaluations(self, exclude_reserved_tokens=False):
        total = self.len_allocated_tokens.get(Evaluations.support, 0) + \
            self.len_allocated_tokens.get(Evaluations.oppose, 0)
        if exclude_reserved_tokens:
            return total - len([
                o for o in self.reserved_tokens if o in self.allocated_tokens
            ])
        return total

    def get_len_free_tokens(self, root=None, exclude_reserved_tokens=False):
        root = root or getSite()
        return self.get_len_tokens(root, exclude_reserved_tokens) - \
            self.get_len_evaluations(exclude_reserved_tokens)

    def has_token(self, obj=None, root=None):
        root = root or getSite()
        obj_oid = get_oid(obj, None)
        if obj_oid and obj_oid in self.reserved_tokens:
            return obj_oid not in self.allocated_tokens

        return self.get_len_free_tokens(root, True) > 0

    def add_token(self, obj, evaluation_type, root=None):
        if self.has_token(obj, root):
            self.allocated_tokens[get_oid(obj)] = evaluation_type
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] += 1

    def remove_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid in self.allocated_tokens:
            evaluation_type = self.allocated_tokens.pop(obj_oid)
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] -= 1

    def add_reserved_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid not in self.reserved_tokens:
            self.reserved_tokens.append(obj_oid)

    def remove_reserved_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid in self.reserved_tokens:
            self.reserved_tokens.remove(obj_oid)

    def evaluated_objs(self, evaluation_type=None):
        if evaluation_type:
            return [
                get_obj(key) for value, key in self.allocated_tokens.byValue(
                    evaluation_type)
            ]

        return [get_obj(key) for key in self.allocated_tokens.keys()]

    def evaluated_objs_ids(self, evaluation_type=None):
        if evaluation_type:
            return [
                key for value, key in self.allocated_tokens.byValue(
                    evaluation_type)
            ]

        return list(self.allocated_tokens.keys())

    def init_contents_organizations(self):
        novaideo_catalog = find_catalog('novaideo')
        dace_catalog = find_catalog('dace')
        organizations_index = novaideo_catalog['organizations']
        object_authors_index = novaideo_catalog['object_authors']
        object_provides_index = dace_catalog['object_provides']
        query = object_authors_index.any([get_oid(self)]) & \
            object_provides_index.any(
                [Iidea.__identifier__, IProposal.__identifier__]) & \
            organizations_index.any([0])

        for entity in query.execute().all():
            entity.init_organization()
            entity.reindex()

    def set_read_date(self, channel, date):
        self._read_at[get_oid(channel)] = date

    def get_read_date(self, channel):
        return self._read_at.get(get_oid(channel),
                                 datetime.datetime.now(tz=pytz.UTC))

    def get_channel(self, user):
        all_channels = list(self.channels)
        all_channels.extend(list(getattr(user, 'channels', [])))
        for channel in all_channels:
            if user in channel.members and self in channel.members:
                return channel

        return None

    def addtoproperty(self, name, value, moving=None):
        super(Person, self).addtoproperty(name, value, moving)
        if name == 'selections':
            value.len_selections = getattr(value, 'len_selections', 0)
            value.len_selections += 1

    def delfromproperty(self, name, value, moving=None):
        super(Person, self).delfromproperty(name, value, moving)
        if name == 'selections':
            value.len_selections = getattr(value, 'len_selections', 0)
            if value.len_selections > 0:
                value.len_selections -= 1

    def set_title(self):
        if getattr(self, 'pseudonym', ''):
            self.title = self.pseudonym
        else:
            self.title = getattr(self, 'first_name', '') + ' ' + \
                getattr(self, 'last_name', '')

    def add_note(self, user, context, note, date, time_constant):
        self._notes[date] = (get_oid(user), get_oid(context), note)
        self.calculate_confidence_index(time_constant)

    def get_questions(self, user):
        if user is self:
            return self.questions + getattr(self.mask, 'questions', [])

        return self.questions

    def get_ideas(self, user):
        if user is self:
            return self.ideas + getattr(self.mask, 'ideas', [])

        return self.ideas

    def get_working_groups(self, user):
        if user is self:
            return self.working_groups + getattr(self.mask, 'working_groups',
                                                 [])

        return self.working_groups

    @property
    def proposals(self):
        return [wg.proposal for wg in self.working_groups]

    def get_proposals(self, user):
        if user is self:
            return self.proposals + getattr(self.mask, 'proposals', [])

        return self.proposals

    @property
    def contacts(self):
        return [s for s in self.selections if isinstance(s, Person)]

    @property
    def participations(self):
        result = [
            p for p in list(self.proposals) if any(s in p.state for s in [
                'amendable', 'open to a working group', 'votes for publishing',
                'votes for amendments'
            ])
        ]
        return result

    def get_participations(self, user):
        if user is self:
            return self.participations + getattr(self.mask, 'participations',
                                                 [])

        return self.participations

    @property
    def contents(self):
        result = [i for i in list(self.ideas) if i is i.current_version]
        result.extend(self.proposals)
        result.extend(self.questions)
        result.extend(self.challenges)
        result.extend(self.events)
        return result

    def get_contents(self, user):
        if user is self:
            return self.contents + getattr(self.mask, 'contents', [])

        return self.contents

    @property
    def active_working_groups(self):
        return [p.working_group for p in self.participations]

    def get_active_working_groups(self, user):
        if user is self:
            return self.active_working_groups + getattr(
                self.mask, 'active_working_groups', [])

        return self.active_working_groups

    def get_wg_participations(self, user):
        if user is self:
            return self.wg_participations + getattr(self.mask,
                                                    'wg_participations', [])

        return self.wg_participations

    @property
    def is_published(self):
        return 'active' in self.state

    @property
    def managed_organization(self):
        return get_objects_with_role(user=self, role='OrganizationResponsible')

    def get_confidence_index(self):
        return getattr(self, 'confidence_index', 0)

    def reindex(self):
        super(Person, self).reindex()
        root = getSite()
        self.__access_keys__ = PersistentList(generate_access_keys(self, root))

    def get_picture_url(self, kind, default):
        if self.picture:
            img = getattr(self.picture, kind, None)
            if img:
                return img.url

        return default

    def get_more_contents_criteria(self):
        "return specific query, filter values"
        return None, None

    def set_organization(self, organization):
        current_organization = self.organization
        if organization:
            if current_organization is not organization:
                is_manager = current_organization and has_role(
                    ('OrganizationResponsible', current_organization),
                    self,
                    ignore_superiors=True)
                if current_organization and is_manager:
                    revoke_roles(
                        self,
                        (('OrganizationResponsible', current_organization), ))

                self.setproperty('organization', organization)
        elif current_organization:
            is_manager = has_role(
                ('OrganizationResponsible', current_organization),
                self,
                ignore_superiors=True)
            if is_manager:
                revoke_roles(
                    self,
                    (('OrganizationResponsible', current_organization), ))

            self.delfromproperty('organization', current_organization)

    @property
    def all_alerts(self):
        novaideo_catalog = find_catalog('novaideo')
        dace_catalog = find_catalog('dace')
        alert_keys_index = novaideo_catalog['alert_keys']
        alert_exclude_keys_index = novaideo_catalog['alert_exclude_keys']
        object_provides_index = dace_catalog['object_provides']
        exclude = [str(get_oid(self))]
        if self.mask:
            exclude.append(str(get_oid(self.mask)))

        query = object_provides_index.any([IAlert.__identifier__]) & \
            alert_keys_index.any(self.get_alerts_keys()) & \
            alert_exclude_keys_index.notany(exclude)
        return query.execute()

    @property
    def alerts(self):
        old_alerts = [get_oid(a) for a in self.old_alerts]
        result = self.all_alerts

        def exclude(result_set, docids):
            filtered_ids = list(result_set.ids)
            for _id in docids:
                if _id in docids and _id in filtered_ids:
                    filtered_ids.remove(_id)

            return result_set.__class__(filtered_ids, len(filtered_ids),
                                        result_set.resolver)

        return exclude(result, old_alerts)

    def get_alerts_keys(self):
        result = ['all', str(get_oid(self))]
        if self.mask:
            result.append(str(get_oid(self.mask)))

        return result

    def get_alerts(self, alerts=None, kind=None, subject=None, **kwargs):
        if alerts is None:
            alerts = self.alerts

        if kind:
            alerts = [a for a in alerts if a.is_kind_of(kind)]

        if subject:
            alerts = [a for a in alerts if subject in a.subjects]

        if kwargs:
            alerts = [a for a in alerts if a.has_args(**kwargs)]

        return alerts

    def calculate_confidence_index(self, time_constant):
        now = datetime.datetime.utcnow().timestamp()
        notes = np.array([v[2] for v in self._notes.values()])
        dates = np.array([int(t.timestamp()) for t in self._notes.keys()])
        time_c = time_constant * 86400
        confidence_index = np.sum(
            np.dot(notes, np.exp(-np.log(2) * (now - dates) / time_c)))
        self.confidence_index = round(confidence_index, 1)

    @property
    def user_groups(self):
        groups = list(self.groups)
        if self.organization:
            groups.append(self.organization)

        if self.mask:
            groups.append(self.mask)

        return groups

    @property
    def user_locale(self):
        locale = getattr(self, 'locale', None)
        if not locale:
            locale = getSite(self).locale

        return locale

    def _init_mask(self, root):
        if not self.mask:
            mask = Mask()
            root.addtoproperty('masks', mask)
            self.setproperty('mask', mask)

    def get_mask(self, root=None):
        root = root if root else getSite()
        if not getattr(root, 'anonymisation', False):
            return self

        self._init_mask(root)
        return self.mask

    def add_submission(self, obj):
        now = datetime.datetime.now(tz=pytz.UTC)
        self._submited_at[now] = get_oid(obj)

    def add_report(self, obj):
        now = datetime.datetime.now(tz=pytz.UTC)
        self._reported_at[now] = get_oid(obj)

    def can_submit_idea(self, root=None):
        root = root if root else getSite()
        now = datetime.datetime.now(tz=pytz.UTC)
        monday = datetime.datetime.combine((now - datetime.timedelta(days=7)),
                                           datetime.time(0,
                                                         0,
                                                         0,
                                                         tzinfo=pytz.UTC))
        return len(self._submited_at.values(min=monday, max=now)) < getattr(
            root, 'nb_submission_maxi', 3)

    def can_report(self, root=None):
        root = root if root else getSite()
        now = datetime.datetime.now(tz=pytz.UTC)
        monday = datetime.datetime.combine((now - datetime.timedelta(days=7)),
                                           datetime.time(0,
                                                         0,
                                                         0,
                                                         tzinfo=pytz.UTC))
        return len(self._reported_at.values(min=monday, max=now)) < getattr(
            root, 'nb_reports_maxi', 3)
Exemplo n.º 49
0
class OrderedContainer(Persistent, Contained):
    """ `OrderedContainer` maintains entries' order as added and moved.

    >>> oc = OrderedContainer()
    >>> int(IOrderedContainer.providedBy(oc))
    1
    >>> len(oc)
    0
    """

    implements(IOrderedContainer)

    def __init__(self):

        self._data = PersistentDict()
        self._order = PersistentList()

    def keys(self):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc.keys()
        []
        >>> oc['foo'] = 'bar'
        >>> oc.keys()
        ['foo']
        >>> oc['baz'] = 'quux'
        >>> oc.keys()
        ['foo', 'baz']
        >>> int(len(oc._order) == len(oc._data))
        1
        """

        return self._order[:]

    def __iter__(self):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc.keys()
        []
        >>> oc['foo'] = 'bar'
        >>> oc['baz'] = 'quux'
        >>> [i for i in oc]
        ['foo', 'baz']
        >>> int(len(oc._order) == len(oc._data))
        1
        """

        return iter(self.keys())

    def __getitem__(self, key):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc['foo'] = 'bar'
        >>> oc['foo']
        'bar'
        """

        return self._data[key]

    def get(self, key, default=None):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc['foo'] = 'bar'
        >>> oc.get('foo')
        'bar'
        >>> oc.get('funky', 'No chance, dude.')
        'No chance, dude.'
        """

        return self._data.get(key, default)

    def values(self):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc.keys()
        []
        >>> oc['foo'] = 'bar'
        >>> oc.values()
        ['bar']
        >>> oc['baz'] = 'quux'
        >>> oc.values()
        ['bar', 'quux']
        >>> int(len(oc._order) == len(oc._data))
        1
        """

        return [self._data[i] for i in self._order]

    def __len__(self):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> int(len(oc) == 0)
        1
        >>> oc['foo'] = 'bar'
        >>> int(len(oc) == 1)
        1
        """

        return len(self._data)

    def items(self):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc.keys()
        []
        >>> oc['foo'] = 'bar'
        >>> oc.items()
        [('foo', 'bar')]
        >>> oc['baz'] = 'quux'
        >>> oc.items()
        [('foo', 'bar'), ('baz', 'quux')]
        >>> int(len(oc._order) == len(oc._data))
        1
        """

        return [(i, self._data[i]) for i in self._order]

    def __contains__(self, key):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc['foo'] = 'bar'
        >>> int('foo' in oc)
        1
        >>> int('quux' in oc)
        0
        """

        return self._data.has_key(key)

    has_key = __contains__

    def __setitem__(self, key, object):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc.keys()
        []
        >>> oc['foo'] = 'bar'
        >>> oc._order
        ['foo']
        >>> oc['baz'] = 'quux'
        >>> oc._order
        ['foo', 'baz']
        >>> int(len(oc._order) == len(oc._data))
        1

        >>> oc['foo'] = 'baz'
        Traceback (most recent call last):
        ...
        KeyError: u'foo'
        >>> oc._order
        ['foo', 'baz']
        """

        existed = self._data.has_key(key)

        bad = False
        if isinstance(key, StringTypes):
            try:
                unicode(key)
            except UnicodeError:
                bad = True
        else:
            bad = True
        if bad:
            raise TypeError("'%s' is invalid, the key must be an "
                            "ascii or unicode string" % key)
        if len(key) == 0:
            raise ValueError("The key cannot be an empty string")

        # We have to first update the order, so that the item is available,
        # otherwise most API functions will lie about their available values
        # when an event subscriber tries to do something with the container.
        if not existed:
            self._order.append(key)

        # This function creates a lot of events that other code listens to.
        try:
            setitem(self, self._data.__setitem__, key, object)
        except Exception, e:
            if not existed:
                self._order.remove(key)
            raise e

        return key
Exemplo n.º 50
0
class NotificationTool(Folder):
    """ """

    meta_type = core_constants.METATYPE_NOTIFICATIONTOOL
    icon = 'misc_/NaayaCore/NotificationTool.gif'

    meta_types = ()
    all_meta_types = meta_types

    security = ClassSecurityInfo()

    # default configuration settings
    default_config = {
        'admin_on_error': True,
        'admin_on_edit': True,
        'enable_instant': True,
        'enable_daily': True,
        'enable_anonymous': False,  # Enable anonymous notifications
        'daily_hour': 0,
        'enable_weekly': True,
        'weekly_day': 1,  # 1 = monday, 7 = sunday
        'weekly_hour': 0,
        'enable_monthly': True,
        'monthly_day': 1,  # 1 = first day of the month
        'monthly_hour': 0,
        'notif_content_types': [],
    }

    def __init__(self, id, title):
        """ """
        self.id = id
        self.title = title
        self.config = PersistentDict(self.default_config)
        self.timestamps = PersistentDict()
        # Confirmations list
        self.pending_anonymous_subscriptions = PersistentList()

    def get_config(self, key):
        return self.config.get(key)

    def get_location_link(self, location):
        if location:
            return self.restrictedTraverse(location,
                                           self.getSite()).absolute_url()
        else:
            return self.getSite().absolute_url()

    def _validate_subscription(self, **kw):
        """ Validate add/edit subscription for authorized and anonymous users

        """
        if (kw['notif_type'] not in self.available_notif_types(kw['location'])
                and not (kw['notif_type'] == 'administrative'
                         and self.checkPermissionPublishObjects())):
            raise i18n_exception(ValueError, 'Subscribing to ${notif_type} '
                                 'notifications in "${location}" not allowed',
                                 location=kw['location']
                                 or self.getSite().title,
                                 notif_type=kw['notif_type'])
        try:
            obj = self.getSite().restrictedTraverse(kw['location'])
        except:
            raise i18n_exception(ValueError,
                                 'This path is invalid or protected')
        try:
            subscription_container = ISubscriptionContainer(obj)
        except:
            raise i18n_exception(ValueError, 'Cannot subscribe to this folder')

        if kw.get('anonymous', False):
            # Check if subscription exists for this anonymous subscriber
            if not is_valid_email(kw.get('email', '')):
                raise i18n_exception(
                    ValueError, 'Your e-mail address does not appear '
                    'to be valid.')
            for id, subscription in subscription_container.list_with_keys():
                # Normal subscriptions don't have e-mail
                if isinstance(subscription, AnonymousSubscription):
                    if (subscription.email == kw['email']
                            and subscription.notif_type == kw['notif_type']
                            and subscription.lang == kw['lang']):
                        raise i18n_exception(ValueError,
                                             'Subscription already exists')

    def _sitemap_dict(self, form):
        """ Compose a sitemap dict """

        node = form.get('node', '')
        if not node or node == '/':
            node = ''

        def traverse(objects, level=0, stop_level=2, exclude_root=False):
            """ Create a dict with node properties and children.
            This is a fixed level recursion. On some sites there are a lot of
            objects so we don't need to get the whole tree.

            """

            res = []
            for ob in objects:
                if ISubscriptionTarget.providedBy(ob) is False:
                    continue
                children_objects = []
                if level != stop_level:  # Stop if the level is reached
                    # Create a list of object's children
                    if hasattr(ob, 'objectValues'):
                        # Get only naaya container objects
                        for child in ob.objectValues(
                                self.get_naaya_containers_metatypes()):
                            # Skip unsubmited/unapproved
                            if not getattr(child, 'approved', False):
                                continue
                            elif not getattr(child, 'submitted', False):
                                continue
                            else:
                                children_objects.append(child)

                if hasattr(ob, 'approved'):
                    icon = ob.approved and ob.icon or ob.icon_marked
                else:
                    icon = ob.icon

                children = traverse(children_objects, level + 1, stop_level)

                if exclude_root:  # Return only the children if this is set
                    return children

                res.append({
                    'data': {
                        'title':
                        self.utStrEscapeHTMLTags(
                            self.utToUtf8(ob.title_or_id())),
                        'icon':
                        icon
                    },
                    'attributes': {
                        'title': path_in_site(ob)
                    },
                    'children': children
                })
            return res

        if node == '':
            tree_dict = traverse([self.getSite()])
        else:
            tree_dict = traverse([self.restrictedTraverse(node)],
                                 exclude_root=True)
        return tree_dict

    security.declarePublic('sitemap')

    def sitemap(self, REQUEST=None, **kw):
        """ Return a json (for Ajax tree) representation of published objects
        marked with `ISubscriptionTarget` including the portal organized in a
        tree (sitemap)

        """

        form = {}
        if REQUEST is not None:
            form = REQUEST.form
            REQUEST.RESPONSE.setHeader('content-type', 'application/json')
        else:
            form.update(kw)
        return json.dumps(self._sitemap_dict(form))

    security.declarePrivate('add_account_subscription')

    def add_account_subscription(self,
                                 user_id,
                                 location,
                                 notif_type,
                                 lang,
                                 content_types=[]):
        """ Subscribe the user `user_id` """
        self._validate_subscription(user_id=user_id,
                                    location=location,
                                    notif_type=notif_type,
                                    lang=lang,
                                    content_types=content_types)

        try:
            self.remove_account_subscription(user_id, location, notif_type,
                                             lang)
        except ValueError:
            pass

        obj = self.getSite().restrictedTraverse(location)
        subscription_container = ISubscriptionContainer(obj)
        subscription = AccountSubscription(user_id, notif_type, lang,
                                           content_types)
        subscription_container.add(subscription)

    security.declarePrivate('add_anonymous_subscription')

    def add_anonymous_subscription(self, **kw):
        """ Handle anonymous users """
        self._validate_subscription(anonymous=True, **kw)
        subscription = AnonymousSubscription(**kw)
        # Add to temporary container
        self.pending_anonymous_subscriptions.append(subscription)

        # Send email
        email_tool = self.getSite().getEmailTool()
        email_from = email_tool.get_addr_from()
        email_template = EmailPageTemplateFile('emailpt/confirm.zpt',
                                               globals())
        email_data = email_template.render_email(**{
            'key': subscription.key,
            'here': self
        })
        email_to = subscription.email
        email_tool.sendEmail(email_data['body_text'], email_to, email_from,
                             email_data['subject'])

    security.declarePrivate('remove_account_subscription')

    def remove_account_subscription(self,
                                    user_id,
                                    location,
                                    notif_type,
                                    lang,
                                    content_types=None):
        obj = self.getSite().restrictedTraverse(location)
        subscription_container = ISubscriptionContainer(obj)
        n = utils.match_account_subscription(subscription_container, user_id,
                                             notif_type, lang, content_types)
        if n is None:
            raise ValueError('Subscription not found')
        subscription_container.remove(n)

    security.declarePrivate('unsubscribe_links_html')
    unsubscribe_links_html = PageTemplateFile("emailpt/unsubscribe_links.zpt",
                                              globals())
    security.declarePrivate('remove_anonymous_subscription')

    def remove_anonymous_subscription(self, email, location, notif_type, lang):
        try:
            obj = self.getSite().restrictedTraverse(location)
        except:
            raise i18n_exception(ValueError, 'Invalid location')

        try:
            subscription_container = ISubscriptionContainer(obj)
        except:
            raise i18n_exception(ValueError, 'Invalid container')
        anonymous_subscriptions = [
            (n, s) for n, s in subscription_container.list_with_keys()
            if hasattr(s, 'email')
        ]
        subscriptions = filter(
            lambda s: (s[1].email == email and s[1].location == location and s[
                1].notif_type == notif_type), anonymous_subscriptions)
        if len(subscriptions) == 1:
            subscription_container.remove(subscriptions[0][0])
        else:
            raise i18n_exception(ValueError, 'Subscription not found')

    security.declareProtected(view, 'available_notif_types')

    def available_notif_types(self, location=''):
        if self.config['enable_instant']:
            yield 'instant'
        if self.config['enable_daily']:
            yield 'daily'
        if self.config['enable_weekly']:
            yield 'weekly'
        if self.config['enable_monthly']:
            yield 'monthly'

    security.declarePrivate('notify_maintainer')

    def notify_maintainer(self, ob, folder, **kwargs):
        """
        Process and notify by email that B{p_object} has been
        uploaded into the B{p_folder}.
        """

        auth_tool = self.getSite().getAuthenticationTool()
        emails = self.getMaintainersEmails(ob)
        person = self.REQUEST.AUTHENTICATED_USER.getUserName()
        if len(emails) > 0:
            maintainers_data = {}
            for email in emails:
                maintainers_data[email] = {
                    'ob':
                    ob,
                    'here':
                    self,
                    'person':
                    auth_tool.name_from_userid(person),
                    'ob_edited':
                    kwargs.get('ob_edited'),
                    'approved':
                    ob.approved,
                    'container_basket':
                    '%s/basketofapprovals_html' % folder.absolute_url(),
                }
            notif_logger.info('Maintainer notifications on %r', ofs_path(ob))
            template = self._get_template('maintainer')
            self._send_notifications(maintainers_data, template)

    security.declarePrivate('notify_comment_maintainer')

    def notify_comment_maintainer(self, comment, parent, **kwargs):
        """
        Process and notify by email that a comment B{comemnt} has been added
        to the object B{parent}.
        """

        auth_tool = self.getSite().getAuthenticationTool()
        emails = self.getMaintainersEmails(parent)
        if len(emails) > 0:
            maintainers_data = {}
            for email in emails:
                maintainers_data[email] = {
                    'parent':
                    parent,
                    'here':
                    self,
                    'comment':
                    comment,
                    'person':
                    auth_tool.name_from_userid(comment.author),
                    'container_basket':
                    '%s/basketofapprovals_html' % parent.absolute_url(),
                }
            notif_logger.info('Maintainer comment notifications on %r',
                              ofs_path(parent))
            template = self._get_template('maintainer')
            self._send_notifications(maintainers_data, template)

    security.declarePrivate('notify_administrative')

    def notify_administrative(self, ob, user_id, ob_edited=False):
        """
        send administrative notifications because object `ob` was added or
        edited by the user `user_id`
        """

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self,
            ob,
            notif_type='administrative',
            **{
                'person':
                auth_tool.name_from_userid(user_id),
                'ob_edited':
                ob_edited,
                'approved':
                ob.approved,
                'container_basket':
                '%s/basketofapprovals_html' % ob.aq_parent.absolute_url(),
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Administrative notifications on %r',
                              ofs_path(ob))
            template = self._get_template('administrative')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_comment_administrative')

    def notify_comment_administrative(self, comment, parent, user_id):
        """
        send administrative notifications because a comment was added to
        object `ob` by the user `user_id`
        """

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self,
            parent,
            notif_type='administrative',
            **{
                'comment': comment,
                'parent': parent,
                'here': self,
                'person': auth_tool.name_from_userid(user_id),
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Administrative comment notifications on %r',
                              ofs_path(parent))
            template = self._get_template('administrative')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_instant')

    def notify_instant(self, ob, user_id, ob_edited=False):
        """
        send instant notifications because object `ob` was changed by
        the user `user_id`
        """
        if not self.config['enable_instant']:
            return

        # Don't send notifications if the object is unapproved, but store them
        # into a queue to send them later when it becomes approved
        if not ob.approved:
            return

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self, ob, **{
                'person': auth_tool.name_from_userid(user_id),
                'ob_edited': ob_edited,
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Instant notifications on %r', ofs_path(ob))
            template = self._get_template('instant')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_comment_instant')

    def notify_comment_instant(self, comment, parent, user_id):
        """
        send instant notifications because a comment was added to
        object `ob` by the user `user_id`
        """
        if not self.config['enable_instant']:
            return

        # Don't send notifications if the object is unapproved, but store them
        # into a queue to send them later when it becomes approved
        if not parent.approved:
            return

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self, parent, **{
                'comment': comment,
                'parent': parent,
                'person': auth_tool.name_from_userid(user_id),
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Comment instant notifications on %r',
                              ofs_path(parent))
            template = self._get_template('instant')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_account_modification')

    def notify_account_modification(self,
                                    email,
                                    obj,
                                    username=None,
                                    new_roles=[],
                                    removed_roles=[]):
        """
        Send notification that the user received or lost one or more roles
        in the specified location
        """
        email_data = {
            email: {
                'new_roles': new_roles,
                'removed_roles': removed_roles,
                'username': username,
                'obj': obj,
            }
        }

        notif_logger.info('Account modification notification on %s' %
                          self.getSite().getId())
        template = self._get_template('account_modified')
        self._send_notifications(email_data, template)

    def _get_template(self, name):

        template = self._getOb('emailpt_%s' % name, None)
        if template is not None:
            return template.render_email

        template = self._getOb(name, None)
        if template is not None:
            return template.render_email

        template = email_templates.get(name, None)
        if template is not None:
            return template.render_email

        raise ValueError('template for %r not found' % name)

    def _send_notifications(self, messages_by_email, template):
        """
        Send the notifications described in the `messages_by_email` data
        structure, using the specified EmailTemplate.

        `messages_by_email` should be a dictionary, keyed by email
        address. The values should be dictionaries suitable to be passed
        as kwargs (options) to the template.
        """
        portal = self.getSite()
        email_tool = portal.getEmailTool()
        addr_from = email_tool.get_addr_from()
        for addr_to, kwargs in messages_by_email.iteritems():
            translate = self.portal_i18n.get_translation
            kwargs.update({'portal': portal, '_translate': translate})
            mail_data = template(**kwargs)
            notif_logger.info('.. sending notification to %r', addr_to)
            utils.send_notification(email_tool, addr_from, addr_to,
                                    mail_data['subject'],
                                    mail_data['body_text'])

    def _send_newsletter(self, notif_type, when_start, when_end):
        """
        We'll look in the ``Products.Naaya.NySite.getActionLogger`` for object
        creation/modification log entries. Then we'll send notifications for
        the period between `when_start` and `when_end` using the
        `notif_type` template.

        """
        notif_logger.info(
            'Notifications newsletter on site %r, type %r, '
            'from %s to %s', ofs_path(self.getSite()), notif_type, when_start,
            when_end)
        objects_by_email = {}
        langs_by_email = {}
        subscriptions_by_email = {}
        anonymous_users = {}
        for log_type, ob in utils.get_modified_objects(self.getSite(),
                                                       when_start, when_end):
            notif_logger.info('.. modified object: %r', ofs_path(ob))
            for subscription in utils.fetch_subscriptions(ob, inherit=True):
                if subscription.notif_type != notif_type:
                    continue
                if not subscription.check_permission(ob):
                    continue
                email = subscription.get_email(ob)
                if email is None:
                    continue
                content_types = getattr(subscription, 'content_types', [])
                if content_types and ob.meta_type not in content_types:
                    continue
                notif_logger.info('.. .. sending newsletter to %r', email)
                objects_by_email.setdefault(email, []).append({
                    'ob': ob,
                    'type': log_type,
                })
                langs_by_email[email] = subscription.lang

                subscriptions_by_email[email] = subscription
                anonymous_users[email] = isinstance(subscription,
                                                    AnonymousSubscription)

        messages_by_email = {}
        for email in objects_by_email:
            messages_by_email[email] = {
                'objs': objects_by_email[email],
                '_lang': langs_by_email[email],
                'subscription': subscriptions_by_email[email],
                'here': self,
                'anonymous': anonymous_users[email]
            }

        template = self._get_template(notif_type)
        self._send_notifications(messages_by_email, template)

    def _cron_heartbeat(self, when):
        transaction.commit()  # commit earlier stuff; fresh transaction
        transaction.get().note('notifications cron at %s' % ofs_path(self))

        # Clean temporary subscriptions after a week:
        if self.config.get('enable_anonymous', False):
            a_week_ago = when - timedelta(weeks=1)
            for tmp_subscription in self.pending_anonymous_subscriptions[:]:
                if tmp_subscription.datetime <= a_week_ago:
                    self.pending_anonymous_subscriptions.remove(
                        tmp_subscription)

        #  daily newsletter ###
        if self.config['enable_daily']:
            # calculate the most recent daily newsletter time
            daily_time = time(hour=self.config['daily_hour'])
            latest_daily = datetime.combine(when.date(), daily_time)
            if latest_daily > when:
                latest_daily -= timedelta(days=1)

            # check if we should send a daily newsletter
            prev_daily = self.timestamps.get('daily', when - timedelta(days=1))
            if prev_daily < latest_daily < when:
                self._send_newsletter('daily', prev_daily, when)
                self.timestamps['daily'] = when

        #  weekly newsletter ###
        if self.config['enable_weekly']:
            # calculate the most recent weekly newsletter time
            weekly_time = time(hour=self.config['daily_hour'])
            t = datetime.combine(when.date(), weekly_time)
            days_delta = self.config['weekly_day'] - t.isoweekday()
            latest_weekly = t + timedelta(days=days_delta)
            if latest_weekly > when:
                latest_weekly -= timedelta(weeks=1)

            # check if we should send a weekly newsletter
            prev_weekly = self.timestamps.get('weekly',
                                              when - timedelta(weeks=1))
            if prev_weekly < latest_weekly < when:
                self._send_newsletter('weekly', prev_weekly, when)
                self.timestamps['weekly'] = when

        #  monthly newsletter ###
        if self.config['enable_monthly']:
            # calculate the most recent monthly newsletter time
            monthly_time = time(hour=self.config['monthly_hour'])
            the_day = utils.set_day_of_month(when.date(),
                                             self.config['monthly_day'])
            latest_monthly = datetime.combine(the_day, monthly_time)
            if latest_monthly > when:
                latest_monthly = utils.minus_one_month(latest_monthly)

            # check if we should send a monthly newsletter
            prev_monthly = self.timestamps.get('monthly',
                                               utils.minus_one_month(when))
            if prev_monthly < latest_monthly < when:
                self._send_newsletter('monthly', prev_monthly, when)
                self.timestamps['monthly'] = when

        transaction.commit()  # make sure our timestamp updates are saved

    def index_html(self, RESPONSE):
        """ redirect to admin page """
        RESPONSE.redirect(self.absolute_url() + '/my_subscriptions_html')

    security.declareProtected(view, 'my_subscriptions_html')
    my_subscriptions_html = NaayaPageTemplateFile(
        'zpt/index', globals(), 'naaya.core.notifications.my_subscriptions')

    security.declarePrivate('list_user_subscriptions')

    def user_subscriptions(self, user, cutoff_level=None):
        """
        Returns all user subscriptions in the portal.
        Use with caution as this iterates almost all the objects in site.
        You can use `cutoff_level` to limit the depth.

        """
        out = []
        user_id = user.getId()
        for obj, n, subscription in utils.walk_subscriptions(
                self.getSite(), cutoff_level):
            if not isinstance(subscription, AccountSubscription):
                continue
            if subscription.user_id != user_id:
                continue
            out.append({
                'object':
                obj,
                'notif_type':
                subscription.notif_type,
                'content_types':
                getattr(subscription, 'content_types', []),
                'lang':
                subscription.lang
            })

        return out

    security.declareProtected(view, 'user_not_found')

    def user_not_found(self, REQUEST):
        """
        Returns True if the user is not Anonymous, but is still not found by
        the AuthenticationTool (i.e. is maybe defined in the Zope root)

        """
        user = REQUEST.AUTHENTICATED_USER
        if not isinstance(user, basestring):
            # with LDAP authentication, user is LDAP user instance
            user = user.id
        acl_tool = self.getAuthenticationTool()
        if acl_tool.get_user_with_userid(user) is None:
            return True

    security.declareProtected(view, 'list_my_subscriptions')

    def list_my_subscriptions(self, REQUEST):
        """
        Returns a list of mappings (location, notif_type, lang)
        for all subscriptions of logged-in user

        """
        user = REQUEST.AUTHENTICATED_USER
        if user.getId() is None and not self.config.get(
                'enable_anonymous', False):
            raise Unauthorized  # to force login

        subscriptions = self.user_subscriptions(user)
        for subscription in subscriptions:
            subscription['location'] = path_in_site(subscription['object'])
            del subscription['object']

        return subscriptions

    security.declareProtected(view, 'my_first_subscription')

    def get_location_subscription(self, location, notif_type=None):
        """
        Returns the first of the authenticated user's subscriptions in location

        """
        for subscription in self.list_my_subscriptions(self.REQUEST):
            if subscription['location'] == location:
                if notif_type:
                    if subscription['notif_type'] == notif_type:
                        return subscription
                else:
                    return subscription

    security.declareProtected(view, 'subscribe_me')

    def subscribe_me(self,
                     REQUEST,
                     location,
                     notif_type,
                     lang=None,
                     content_types=[]):
        """ add subscription for currently-logged-in user """
        # Even if some content types were selected (by turning off javascript)
        # they should be ignored, no filtering in administrative notifications
        if notif_type == 'administrative':
            content_types = []
        if isinstance(content_types, basestring):
            content_types = [content_types]
        if lang is None:
            lang = self.gl_get_selected_language()
            REQUEST.form['lang'] = lang
        user_id = REQUEST.AUTHENTICATED_USER.getId()
        if location == '/':
            location = ''
        if user_id is None and not self.config.get('enable_anonymous', False):
            raise Unauthorized  # to force login
        try:
            if user_id:
                self.add_account_subscription(user_id, location, notif_type,
                                              lang, content_types)
                if content_types:
                    self.setSessionInfoTrans(
                        'You will receive ${notif_type} notifications'
                        ' for any changes in "${location}" for objects of '
                        'types ${content_types}.',
                        notif_type=notif_type,
                        location=location or self.getSite().title,
                        content_types=', '.join(content_types))
                else:
                    self.setSessionInfoTrans(
                        'You will receive ${notif_type} notifications'
                        ' for any changes in "${location}".',
                        notif_type=notif_type,
                        location=location)
            else:
                self.add_anonymous_subscription(**dict(REQUEST.form))
                self.setSessionInfoTrans(
                    'An activation e-mail has been sent to ${email}. '
                    'Follow the instructions to subscribe to ${notif_type} '
                    'notifications for any changes in "${location}".',
                    notif_type=notif_type,
                    location=location,
                    content_types=content_types,
                    email=REQUEST.form.get('email'))
        except ValueError, msg:
            self.setSessionErrors([unicode(msg)])
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/my_subscriptions_html')
Exemplo n.º 51
0
class Tokenable(Entity):
    """Question class"""

    tokens_opposition = CompositeMultipleProperty('tokens_opposition')
    tokens_support = CompositeMultipleProperty('tokens_support')

    def __init__(self, **kwargs):
        super(Tokenable, self).__init__(**kwargs)
        self.set_data(kwargs)
        self.allocated_tokens = OOBTree()
        self.len_allocated_tokens = PersistentDict({})

    def add_token(self, user, evaluation_type):
        user_oid = get_oid(user)
        if user_oid in self.allocated_tokens:
            self.remove_token(user)

        self.allocated_tokens[user_oid] = evaluation_type
        self.len_allocated_tokens.setdefault(evaluation_type, 0)
        self.len_allocated_tokens[evaluation_type] += 1

    def remove_token(self, user):
        user_oid = get_oid(user)
        if user_oid in self.allocated_tokens:
            evaluation_type = self.allocated_tokens.pop(user_oid)
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] -= 1

    def evaluators(self, evaluation_type=None):
        if evaluation_type:
            return [
                get_obj(key) for value, key in self.allocated_tokens.byValue(
                    evaluation_type)
            ]

        return [get_obj(key) for key in self.allocated_tokens.keys()]

    def evaluation(self, user):
        user_oid = get_oid(user, None)
        return self.allocated_tokens.get(user_oid, None)

    def remove_tokens(self, force=False):
        evaluators = self.evaluators()
        for user in evaluators:
            user.remove_token(self)
            if force:
                self.remove_token(user)

    def user_has_token(self, user, root=None):
        if hasattr(user, 'has_token'):
            return user.has_token(self, root)

        return False

    def init_support_history(self):
        # [(user_oid, date, support_type), ...], support_type = {1:support, 0:oppose, -1:withdraw}
        if not hasattr(self, '_support_history'):
            setattr(self, '_support_history', PersistentList())

    @property
    def len_support(self):
        return self.len_allocated_tokens.get(Evaluations.support, 0)

    @property
    def len_opposition(self):
        return self.len_allocated_tokens.get(Evaluations.oppose, 0)
Exemplo n.º 52
0
class SearchableEntity(VisualisableElement, Entity):
    """ A Searchable entity is an entity that can be searched"""

    templates = {
        'default': 'novaideo:templates/views/default_result.pt',
        'bloc': 'novaideo:templates/views/default_result.pt'
    }

    def __init__(self, **kwargs):
        super(SearchableEntity, self).__init__(**kwargs)
        self.keywords = PersistentList()

    @property
    def is_published(self):
        return 'published' in self.state

    @property
    def is_workable(self):
        return self.is_published

    @property
    def relevant_data(self):
        return [
            getattr(self, 'title', ''),
            getattr(self, 'description', ''),
            ', '.join(getattr(self, 'keywords', []))
        ]

    def set_source_data(self, source_data):
        if not hasattr(self, 'source_data'):
            self.source_data = PersistentDict({})

        app_name = source_data.get('app_name')
        self.source_data.setdefault(app_name, {})
        self.source_data[app_name] = source_data

    def get_source_data(self, app_id):
        if not hasattr(self, 'source_data'):
            return {}

        return self.source_data.get(app_id, {})

    def is_managed(self, root):
        return True

    def get_title(self, user=None):
        return getattr(self, 'title', '')

    def _init_presentation_text(self):
        pass

    def get_release_date(self):
        return getattr(self, 'release_date', self.modified_at)

    def presentation_text(self, nb_characters=400):
        return getattr(self, 'description', "")[:nb_characters] + '...'

    def get_more_contents_criteria(self):
        "return specific query, filter values"
        return None, {
            'metadata_filter': {
                'states': ['published'],
                'keywords': list(self.keywords)
            }
        }
Exemplo n.º 53
0
class WatcherList(object):
    """Adapter for lists of watchers.

    The lists are stored on the content objects that are being
    watched.

    A not yet implemented idea for Watchers: perhaps for each watcher
    keep some configuration like this:

    - wants plain/html

    - list of mails they are interested in; for xm that could be:
      task-started (for assignees) and task-completed (for creator);
      an empty list means: give me everything.

    """

    implements(IWatcherList)
    ANNO_KEY = 'collective.watcherlist'

    def __init__(self, context):
        self.context = context
        annotations = IAnnotations(self.context)
        self.__mapping = annotations.get(self.ANNO_KEY, None)
        if self.__mapping is None:
            info = dict(
                watchers=PersistentList(),
                extra_addresses=PersistentList())
            self.__mapping = PersistentDict(info)
            annotations[self.ANNO_KEY] = self.__mapping

    def __get_watchers(self):
        return self.__mapping.get('watchers')

    def __set_watchers(self, v):
        if not isinstance(v, PersistentList):
            v = PersistentList(v)
        self.__mapping['watchers'] = v

    watchers = property(__get_watchers, __set_watchers)

    def __get_extra_addresses(self):
        """Extra email addresses
        """
        return self.__mapping.get('extra_addresses')

    def __set_extra_addresses(self, v):
        if not isinstance(v, PersistentList):
            v = PersistentList(v)
        self.__mapping['extra_addresses'] = v

    extra_addresses = property(__get_extra_addresses, __set_extra_addresses)

    def __get_send_emails(self):
        """Should emails be sent?

        The parent of the context may have a setting for this.  In the
        context we may or may not wish to override this.  For example,
        in the case of Poi we only set this on the tracker, not on
        individual issues.
        """
        setting = self.__mapping.get('send_emails', _marker)
        if setting is not _marker:
            # We have an explicit setting.
            return setting
        # The context has no explicit setting, so we ask the parent.
        context = aq_inner(self.context)
        parent_list = IWatcherList(aq_parent(context), None)
        if parent_list is not None:
            return parent_list.send_emails

        # No explicit setting, so we fall back to the default: yes, we
        # send emails.
        return True

    def __set_send_emails(self, v):
        if not isinstance(v, bool):
            v = bool(v)
        self.__mapping['send_emails'] = v

    send_emails = property(__get_send_emails, __set_send_emails)

    def __get_allow_recursive(self):
        return self.__mapping.get('allow_recursive', True)

    def __set_allow_recursive(self, v):
        if not isinstance(v, bool):
            v = bool(v)
        self.__mapping['allow_recursive'] = v

    allow_recursive = property(__get_allow_recursive, __set_allow_recursive)

    def append(self, item):
        notify(event.ToggleWatchingEvent(self.context))
        notify(event.AddedToWatchingEvent(self.context))
        self.watchers.append(item)

    def remove(self, item):
        notify(event.ToggleWatchingEvent(self.context))
        notify(event.RemovedFromWatchingEvent(self.context))
        self.watchers.remove(item)

    def toggle_watching(self):
        """Add or remove the current authenticated member from the watchers.

        Taken from PoiIssue.

        If the current value is a tuple, we keep it that way.
        """
        memship = getToolByName(self.context, 'portal_membership', None)
        if memship is None:
            return
        if memship.isAnonymousUser():
            return
        member = memship.getAuthenticatedMember()
        member_id = member.getId()
        watchers = self.watchers
        if isinstance(watchers, tuple):
            watchers = list(watchers)
            as_tuple = True
        else:
            as_tuple = False
        if member_id in self.watchers:
            notify(event.ToggleWatchingEvent(self.context))
            notify(event.RemovedFromWatchingEvent(self.context))
            watchers.remove(member_id)
        else:
            notify(event.ToggleWatchingEvent(self.context))
            notify(event.AddedToWatchingEvent(self.context))
            watchers.append(member_id)
        if as_tuple:
            self.watchers = tuple(watchers)
        else:
            self.watchers = watchers

    def isWatching(self):
        """
        Determine if the current user is watching this issue or not.

        Taken from PoiIssue.
        """
        memship = getToolByName(self.context, 'portal_membership', None)
        if memship is None:
            return False
        member = memship.getAuthenticatedMember()
        if member is None:
            return False
        return member.getId() in self.watchers

    @property
    def addresses(self):
        """
        Upon activity for the given issue, get the list of email
        addresses to which notifications should be sent. May return an
        empty list if notification is turned off. If issue is given, the
        issue poster and any watchers will also be included.

        Taken from PoiTracker.

        Note that we currently return only email addresses, without
        any full names.  That is what Poi has been doing, and it makes
        a few things simpler.
        """
        if not self.send_emails:
            return ()

        # make sure no duplicates are added
        addresses = sets.Set()

        context = aq_inner(self.context)
        memship = getToolByName(context, 'portal_membership', None)
        if memship is None:
            # Okay, either we are in a simple unit test, or someone is
            # using this package outside of CMF/Plone.  We should
            # assume the watchers are simple email addresses.
            addresses.union_update(self.watchers)
        else:
            addresses.union_update([get_member_email(w, memship)
                                    for w in self.watchers])
        addresses.union_update(self.extra_addresses)

        # Discard invalid addresses:
        addresses.discard(None)
        # Discard current user:
        email = get_member_email()
        addresses.discard(email)

        if self.allow_recursive:
            # Get addresses from parent (might be recursive).
            parent_list = IWatcherList(aq_parent(context), None)
            if parent_list is not None:
                addresses.union_update(parent_list.addresses)

        return tuple(addresses)

    def send(self, view_name, only_these_addresses=None, **kw):
        """Send mail to our addresses using browser view 'view_name'.

        view_name is the name of a browser view for the context.  We
        use that to get the contents and subject of the email.

        only_these_addresses is a list of addresses; this forces
        sending only to those addresses and ignoring all others.

        Any keyword arguments will be passed along to the update
        method of that view.
        """
        context = aq_inner(self.context)
        if only_these_addresses is None:
            addresses = self.addresses
        else:
            addresses = only_these_addresses
        if not addresses:
            logger.info("No addresses found.")
            return
        if isinstance(addresses, basestring):
            addresses = [addresses]
        immediate = kw.pop('immediate', False)

        request = context.REQUEST
        mail_content = getMultiAdapter((context, request), name=view_name)
        mail_content.update(**kw)
        message = mail_content.prepare_email_message()
        if not message:
            logger.warn("Not sending empty email.")
            return
        subject = mail_content.subject
        simple_send_mail(message, addresses, subject, immediate=immediate)
Exemplo n.º 54
0
class Taxonomy(SimpleItem):
    order = None
    count = None
    version = None

    def __init__(self, name, title, default_language):
        self.data = PersistentDict()
        self.order = PersistentDict()
        self.count = PersistentDict()
        self.version = PersistentDict()

        self.name = name
        self.title = title
        self.default_language = default_language

    @property
    def sm(self):
        return api.portal.get().getSiteManager()

    def __call__(self, context):
        if not self.data:
            return Vocabulary(self.name, {}, {}, {}, 2)

        request = getattr(context, "REQUEST", None)
        language = self.getCurrentLanguage(request)
        return self.makeVocabulary(language)

    @property
    @ram.cache(lambda method, self: (self.name, self.data._p_mtime))
    def inverted_data(self):
        inv_data = {}
        for (language, elements) in self.data.items():
            inv_data[language] = {}
            for (path, identifier) in elements.items():
                inv_data[language][identifier] = path
        return inv_data

    def getShortName(self):
        return self.name.split('.')[-1]

    def getGeneratedName(self):
        return 'collective.taxonomy.generated.' + self.getShortName()

    def getVocabularyName(self):
        return 'collective.taxonomy.' + self.getShortName()

    def makeVocabulary(self, language):
        self._fixup()
        data = self.data.get(language, {})
        order = self.order.get(language)
        version = self.version.get(language, 1)
        inverted_data = self.inverted_data.get(language, {})
        return Vocabulary(self.name, data, inverted_data, order, version)

    def getCurrentLanguage(self, request):
        language = get_lang_code()
        if language in self.data:
            return language
        elif self.default_language in self.data:
            return self.default_language
        else:
            # our best guess!
            return self.data.keys()[0]

    def getLanguages(self):
        return tuple(self.data)

    def iterLanguage(self, language=None):
        if language is None:
            language = self.default_language

        vocabulary = self.makeVocabulary(language)

        for path, identifier in vocabulary.iterEntries():
            parent_path = path.rsplit(PATH_SEPARATOR, 1)[0]
            if parent_path:
                parent = vocabulary.getTermByValue(parent_path)
            else:
                parent = None
            yield path, identifier, parent

    def registerBehavior(self, **kwargs):
        new_args = copy(kwargs)

        new_args['name'] = self.getGeneratedName()
        new_args['title'] = self.title
        new_args['description'] = kwargs.get('field_description', u'')
        new_args['field_description'] = new_args['description']

        behavior = TaxonomyBehavior(**new_args)
        self.sm.registerUtility(behavior, IBehavior,
                                name=self.getGeneratedName())

        behavior.addIndex()
        behavior.activateSearchable()

    def cleanupFTI(self):
        """Cleanup the FTIs"""
        generated_name = self.getGeneratedName()
        for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI):
            if generated_name in fti.behaviors:
                fti.behaviors = [behavior for behavior in
                                 fti.behaviors
                                 if behavior != generated_name]
            modified(fti, DexterityFTIModificationDescription("behaviors", ''))

    def updateBehavior(self, **kwargs):
        behavior_name = self.getGeneratedName()
        short_name = self.getShortName()

        utility = self.sm.queryUtility(IBehavior, name=behavior_name)
        if utility:
            utility.deactivateSearchable()
            utility.activateSearchable()
            if 'field_title' in kwargs:
                utility.title = kwargs.pop('field_title')

            for k, v in kwargs.items():
                setattr(utility, k, v)

        delattr(generated, short_name)

        for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI):
            if behavior_name in fti.behaviors:
                modified(fti, DexterityFTIModificationDescription("behaviors", ''))

    def unregisterBehavior(self):
        behavior_name = self.getGeneratedName()
        utility = self.sm.queryUtility(IBehavior, name=behavior_name)

        if utility is None:
            return

        self.cleanupFTI()

        utility.removeIndex()
        utility.deactivateSearchable()
        utility.unregisterInterface()

        self.sm.unregisterUtility(utility, IBehavior, name=behavior_name)

    def clean(self):
        self.data.clear()

    def add(self, language, value, key):
        self._fixup()
        tree = self.data.get(language)
        if tree is None:
            tree = self.data[language] = OOBTree()
        else:
            # Make sure we update the modification time.
            self.data[language] = tree

        update = key in tree
        tree[key] = value

        order = self.order.get(language)
        if order is None:
            order = self.order[language] = IOBTree()
            count = self.count[language] = 0
        else:
            if update:
                pop_value(tree, key)

            count = self.count[language] + 1

        self.count[language] = count
        order[count] = key

    def update(self, language, items, clear=False):
        self._fixup()

        tree = self.data.setdefault(language, OOBTree())
        if clear:
            tree.clear()

        # A new tree always uses the newest version.
        if not tree:
            version = self.version[language] = 2
        else:
            version = self.version.get(language, 1)

        order = self.order.setdefault(language, IOBTree())
        count = self.count.get(language, 0)

        if clear:
            order.clear()
            count = 0

        # Always migrate to newest version.
        if version == 1:
            def fix(path):
                return path.replace(LEGACY_PATH_SEPARATOR, PATH_SEPARATOR)

            for i in list(order):
                path = order[i]
                order[i] = fix(path)

            for path in list(tree):
                value = tree.pop(path)
                tree[fix(path)] = value

            version = self.version[language] = 2
            logger.info(
                "Taxonomy '%s' upgraded to version %d for language '%s'." % (
                    self.name, version, language
                )
            )

        # Make sure we update the modification time.
        self.data[language] = tree

        # The following structure is used to expunge updated entries.
        inv = {}
        if not clear:
            for i, key in order.items():
                inv[key] = i

        seen = set()
        for key, value in items:
            if key in seen:
                logger.warning("Duplicate key entry: %r" % (key, ))
                continue

            seen.add(key)
            update = key in tree
            tree[key] = value
            order[count] = key
            count += 1

            # If we're updating, then we have to pop out the old ordering
            # information in order to maintain relative ordering of new items.
            if update:
                i = inv.get(key)
                if i is not None:
                    del order[i]

        self.count[language] = count

    def translate(self, msgid, mapping=None, context=None,
                  target_language=None, default=None, msgid_plural=None,
                  default_plural=None, number=None):

        if target_language is None or \
                target_language not in self.inverted_data:
            target_language = str(api.portal.get_current_language())

        if msgid not in self.inverted_data[target_language]:
            return ''

        if self.version is not None and self.version.get(target_language) != 2:
            path_sep = LEGACY_PATH_SEPARATOR
        else:
            path_sep = PATH_SEPARATOR

        path = self.inverted_data[target_language][msgid]
        pretty_path = path[1:].replace(path_sep, PRETTY_PATH_SEPARATOR)

        if mapping is not None and mapping.get(NODE):
            pretty_path = pretty_path.rsplit(PRETTY_PATH_SEPARATOR, 1)[-1]

        return pretty_path

    def _fixup(self):
        # due to compatibility reasons this method fixes data structure
        # for old Taxonomy instances.
        # XXX: remove this in version 2.0 to prevent write on read
        if self.order is None:
            safeWrite(self, getRequest())
            self.order = PersistentDict()
            self.count = PersistentDict()

        if self.version is None:
            safeWrite(self, getRequest())
            self.version = PersistentDict()