예제 #1
0
class VersionedObject(Versioning, SilvaObject, ViewableObject):
    security = ClassSecurityInfo()
    grok.implements(IVersionedObject)
    grok.baseclass()

    # there is always at least a single version to start with,
    # created by the object's factory function
    _version_count = 1

    # Set ZMI tabs
    manage_options = ((BaseFolder.manage_options[0], ) + ({
        'label': 'Silva /edit...',
        'action': 'edit'
    }, ) + BaseFolder.manage_options[1:])

    # MANIPULATORS

    security.declareProtected(permissions.ChangeSilvaContent, 'set_title')

    def set_title(self, title):
        """Set title of version under edit.
        """
        editable = self.get_editable()
        if editable is None:
            return
        editable.set_title(title)

    # ACCESSORS
    security.declareProtected(permissions.AccessContentsInformation,
                              'get_title')

    def get_title(self):
        """Get title for public use, from published version.
        """
        version = self.get_viewable()
        if version is None:
            return ""
        return version.get_title()

    security.declareProtected(permissions.AccessContentsInformation,
                              'get_title_editable')

    def get_title_editable(self):
        """Get title for editable or previewable use
        """
        # Ask for 'previewable', which will return either the 'next version'
        # (which may be under edit, or is approved), or the public version,
        # or, as a last resort, the closed version.
        # This to be able to show at least some title in the Silva edit
        # screens.
        version = self.get_previewable()
        if version is None:
            return ""
        return version.get_title_editable()

    security.declareProtected(permissions.AccessContentsInformation,
                              'get_short_title')

    def get_short_title(self):
        """Get short_title for public use, from published version.
        """
        version = self.get_viewable()
        if version is None:
            return self.id
        return version.get_short_title()

    security.declareProtected(permissions.AccessContentsInformation,
                              'get_short_title_editable')

    def get_short_title_editable(self):
        """Get short_title for editable or previewable use
        """
        version = self.get_previewable()
        if version is None:
            return self.id
        return version.get_short_title_editable()

    security.declareProtected(permissions.ChangeSilvaContent, 'get_editable')

    def get_editable(self):
        """Get the editable version (may be object itself if no versioning).
        """
        # the editable version is the unapproved version
        version_id = self.get_unapproved_version()
        if version_id is None:
            return None  # there is no editable version
        return self._getOb(version_id, None)

    security.declareProtected(permissions.ReadSilvaContent, 'get_previewable')

    def get_previewable(self):
        """Get the previewable version (may be the object itself if no
        versioning).
        """
        version_id = self.get_next_version()
        if version_id is None:
            version_id = self.get_public_version()
            if version_id is None:
                version_id = self.get_last_closed_version()
                if version_id is None:
                    return None
        return self._getOb(version_id, None)

    security.declareProtected(permissions.AccessContentsInformation,
                              'get_viewable')

    def get_viewable(self):
        """Get the publically viewable version (may be the object itself if
        no versioning).
        """
        version_id = self.get_public_version()
        if version_id is None:
            return None  # There is no public document
        return self._getOb(version_id, None)

    security.declareProtected(permissions.AccessContentsInformation,
                              'get_last_author_info')

    def get_last_author_info(self):
        previewable = self.get_previewable()
        if previewable is not None:
            return previewable.get_last_author_info()
        return noneMember.__of__(self)

    security.declareProtected(permissions.AccessContentsInformation,
                              'is_deletable')

    def is_deletable(self):
        """is object deletable?

            a publishable object is only deletable if
                it's not published
                it's not approved

        """
        if not checkPermission('silva.ApproveSilvaContent', self):
            if self.is_published():
                raise ContentError(_(u"Content is published."), self)
            if self.is_approved():
                raise ContentError(_(u"Content is approved."), self)
예제 #2
0
class SilvaFind(Query, Content, SimpleItem):
    __doc__ = _("""Silva Find is a powerful search feature that allows easy
        creation of search forms and result pages. Users can add a Find
        anywhere and define which fields to make searchable by site visitors
        and/or which fields to limit to a preset value. Users also can
        determine which fields should be displayed in the search results. All
        metadata sets/fields are supported.""")

    security = ClassSecurityInfo()

    meta_type = "Silva Find"
    grok.implements(IFind)
    silvaconf.icon('SilvaFind.png')

    def __init__(self, id):
        Content.__init__(self, id)
        Query.__init__(self)
        self.shownFields = PersistentMapping()
        self.shownResultsFields = PersistentMapping()
        # by default we only show fulltext search
        # and a couple of resultfields
        self.shownFields['fulltext'] = True
        self.shownResultsFields['link'] = True
        self.shownResultsFields['ranking'] = True
        self.shownResultsFields['resultcount'] = True
        self.shownResultsFields['icon'] = True
        self.shownResultsFields['date'] = True
        self.shownResultsFields['textsnippet'] = True
        self.shownResultsFields['thumbnail'] = True
        self.shownResultsFields['breadcrumbs'] = True

    # ACCESSORS
    security.declareProtected(SilvaPermissions.View, 'getPublicResultFields')

    def getPublicResultFields(self):
        return filter(lambda field: self.isResultShown(field.getName()),
                      self.getResultFields())

    security.declareProtected(SilvaPermissions.View, 'getPublicSearchFields')

    def getPublicSearchFields(self):
        return filter(lambda field: self.isCriterionShown(field.getName()),
                      self.getSearchFields())

    security.declareProtected(SilvaPermissions.View, 'isCriterionShown')

    def isCriterionShown(self, fieldName):
        return self.shownFields.get(fieldName, False)

    security.declareProtected(SilvaPermissions.View, 'isResultShown')

    def isResultShown(self, fieldName):
        return self.shownResultsFields.get(fieldName, False)

    security.declareProtected(SilvaPermissions.View, 'havePublicSearchFields')

    def havePublicSearchFields(self):
        # BBB map(bool) is here for previously non-boolean stored values
        return reduce(operator.or_, map(bool, self.shownFields.values()))

    security.declareProtected(SilvaPermissions.View, 'searchResults')

    def searchResults(self, request={}, validate=True):
        options = self.getSearchCriterias(request)
        if validate:
            queryEmpty = True
            for key, value in options.items():
                if key in ['path', 'meta_type']:
                    # these fields do not count as a real search query
                    # they are always there to filter unwanted results
                    continue
                if type(value) is unicode and value.strip():
                    queryEmpty = False
                    break
                elif type(value) is list:
                    queryEmpty = False
                    break
            query = options.get('fulltext', '').strip()
            if query and query[0] in ['?', '*']:
                raise ValueError(
                    _(u'Search query can not start with wildcard character.'))
            if queryEmpty:
                raise ValueError(
                    _(u'You need to fill at least one field in the search form.'
                      ))
        options['publication_status'] = ['public']
        catalog = self.get_root().service_catalog
        try:
            results = catalog.searchResults(options)
        except ParseError:
            raise ValueError(
                _(u'Search query contains only common or reserved words.'))

        return results

    def getSearchCriterias(self, request):
        options = {}
        for field in self.getSearchFields():
            name = field.getName()
            if (self.shownFields.get(name, False) or name == 'path'):
                queryPart = getMultiAdapter((field, self, request), IQueryPart)
                value = queryPart.getIndexValue()
                if value is None:
                    value = ''
                options[queryPart.getIndexId()] = value
        return options
예제 #3
0
class Heatsetwaschmittel(Container):
    grok.implements(IHeatsetwaschmittel)
예제 #4
0
class IconResolver(grok.Adapter):
    """Resolve and return an icon.
    """
    grok.context(IBrowserRequest)
    grok.implements(IIconResolver)

    sprite = registry

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

    @Lazy
    def root_url(self):
        site = IVirtualSite(self.request)
        return site.get_root_url()

    def get_tag(self, content=None, identifier=None, default=_marker):
        if content is not None:
            icon = self.get_content(content)
            alt = getattr(content, 'meta_type', 'Missing')
        else:
            icon = self.get_identifier(identifier, default=_marker)
            alt = identifier or 'Missing'
        if icon is not None:
            return icon.template.format(url=icon.get_url(self, content),
                                        alt=alt)
        return u''

    def get_identifier(self, identifier, default=_marker):
        if not isinstance(identifier, tuple):
            identifier = ('meta_type', identifier)
        try:
            return self.sprite.get(identifier)
        except ValueError:
            if default is _marker:
                default = ('default', None)
            elif not isinstance(default, tuple):
                default = ('default', default)
            return self.sprite.get(default, default=None)

    def get_content(self, content):
        identifier = ('meta_type', None)
        default = ('default', None)
        try:
            if interfaces.IGhost.providedBy(content):
                viewable = content.get_viewable()
                if (viewable is not None
                        and viewable.get_link_status() is not None):
                    identifier = ('meta_type', 'Broken Silva Ghost')
                else:
                    identifier = ('meta_type', 'Silva Ghost')
            elif interfaces.IGhostFolder.providedBy(content):
                if content.get_link_status() is None:
                    if interfaces.IPublication.providedBy(
                            content.get_haunted()):
                        identifier = ('meta_type', 'Silva Ghost Publication')
                    else:
                        identifier = ('meta_type', 'Silva Ghost Folder')
                else:
                    identifier = ('meta_type', 'Broken Silva Ghost Folder')
            elif interfaces.IFile.providedBy(content):
                identifier = ('mime_type', content.get_mime_type())
                default = ('meta_type', 'Silva File')
            elif interfaces.ISilvaObject.providedBy(content):
                identifier = ('meta_type', content.meta_type)
            elif content is None:
                default = ('meta_type', None)
            else:
                if interfaces.IAuthorization.providedBy(content):
                    content = content.source
                meta_type = getattr(content, 'meta_type', None)
                if meta_type is None:
                    raise ValueError(u"No icon for unknown object %r" %
                                     content)
                identifier = ('meta_type', meta_type)
            return self.sprite.get(identifier)
        except ValueError:
            return self.sprite.get(default, default=None)

    def get_content_url(self, content):
        """Return a content icon URL.
        """
        icon = self.get_content(content)
        if icon is not None:
            return icon.get_url(self, content)
        return None

    def get_identifier_url(self, identifier, default=_marker):
        """Return a URL out of a identifier.
        """
        icon = self.get_identifier(identifier, default=default)
        if icon is not None:
            return icon.get_url(self, None)
        return None
예제 #5
0
class V10APIClient(object):
    grok.implements(IAPIClient)

    def __init__(self, context, endpoint):
        self.context = context
        if endpoint.endswith('/'):
            endpoint = endpoint[:-1]
        self.endpoint = endpoint

    def news(self, language=None, category=None, limit=20):
        api_url = '%s/1.0/news' % (self.endpoint)
        ss = ISignatureService(self.context)

        params = {}
        if language is not None:
            params['language'] = language.strip()

        if limit is not None:
            params['limit'] = limit
        if category:
            params['category'] = category.strip()

        params = ss.sign_params(api_url, params)
        resp = requests.get(api_url, params=params)
        out = resp.json()

        if 'error' in out:
            raise APIQueryError('%s : %s' %
                                (out['error'], out['error-message']))

        return out

    def activities(self, language=None, category=None, limit=20):
        api_url = '%s/1.0/activities' % (self.endpoint)
        ss = ISignatureService(self.context)

        params = {}

        if language is not None:
            params['language'] = language.strip()

        if limit is not None:
            params['limit'] = limit

        if category:
            params['category'] = category.strip()

        params = ss.sign_params(api_url, params)
        resp = requests.get(api_url, params=params)
        out = resp.json()

        if 'error' in out:
            raise APIQueryError('%s : %s' %
                                (out['error'], out['error-message']))

        return out

    def translation(self, content):
        api_url = '%s/1.0/translations/%s' % (self.endpoint, content)
        ss = ISignatureService(self.context)
        params = ss.sign_params(api_url, {})
        resp = requests.get(api_url, params=params)
        out = resp.json()

        if 'error' in out:
            raise APIQueryError('%s : %s' %
                                (out['error'], out['error-message']))

        return out

    def activity(self, activity):
        api_url = '%s/1.0/activities/%s' % (self.endpoint, activity)
        ss = ISignatureService(self.context)
        params = ss.sign_params(api_url, {})
        resp = requests.get(api_url, params=params)
        out = resp.json()

        if 'error' in out:
            raise APIQueryError('%s : %s' %
                                (out['error'], out['error-message']))

        return out

    def activity_news(self, activity, category=None, language=None, limit=20):
        api_url = '%s/1.0/activities/%s/news' % (self.endpoint, activity)
        ss = ISignatureService(self.context)

        params = {}
        if limit is not None:
            params['limit'] = limit

        if category is not None:
            params['category'] = category

        if language is not None:
            params['language'] = language

        params = ss.sign_params(api_url, params)
        resp = requests.get(api_url, params=params)
        out = resp.json()

        if 'error' in out:
            raise APIQueryError('%s : %s' %
                                (out['error'], out['error-message']))
        return out
예제 #6
0
class categories(grok.GlobalUtility):
    grok.name('sinar.pardocs.categories')
    grok.implements(IVocabularyFactory)

    # this should be written to automatically be generated from csv
    _terms = [
        {
            'value': 'agriculture',
            'title': 'Agriculture',
        },
        {
            'value': 'citizenship',
            'title': 'Citizenship',
        },
        {
            'value': 'civilservice',
            'title': 'Civil Service',
        },
        {
            'value': 'consumers',
            'title': 'Consumers',
        },
        {
            'value': 'constitution',
            'title': 'Constitutional',
        },
        {
            'value': 'corruption',
            'title': 'Corruption and Transparency',
        },
        {
            'value': 'defence',
            'title': 'Defence',
        },
        {
            'value': 'economy',
            'title': 'Economy',
        },
        {
            'value': 'education',
            'title': 'Education',
        },
        {
            'value': 'employment',
            'title': 'Employment',
        },
        {
            'value': 'energy',
            'title': 'Energy',
        },
        {
            'value': 'environment',
            'title': 'Environment',
        },
        {
            'value': 'finance',
            'title': 'Finance',
        },
        {
            'value': 'fishery',
            'title': 'Fishery',
        },
        {
            'value': 'foodsecurity',
            'title': 'Food Security',
        },
        {
            'value': 'foreignaffairs',
            'title': 'Foreign Affairs',
        },
        {
            'value': 'gender',
            'title': 'Women and Gender',
        },
        {
            'value': 'glc',
            'title': 'GLC',
        },
        {
            'value': 'health',
            'title': 'Health',
        },
        {
            'value': 'homeaffairs',
            'title': 'Home Affairs',
        },
        {
            'value': 'housing',
            'title': 'Housing',
        },
        {
            'value': 'humanresources',
            'title': 'Human Resources',
        },
        {
            'value': 'humanrights',
            'title': 'Human Rights',
        },
        {
            'value': 'indigenous',
            'title': 'Indigenous Affairs',
        },
        {
            'value': 'labour',
            'title': 'Labour Rights',
        },
        {
            'value': 'localgov',
            'title': 'Local Government',
        },
        {
            'value': 'migrants',
            'title': 'Migrants and Refugees',
        },
        {
            'value': 'naturaldisasters',
            'title': 'Natural Disasters',
        },
        {
            'value': 'sports',
            'title': 'Sports and Recreation',
        },
        {
            'value': 'tariffsubsidy',
            'title': 'Tariffs and Subsidies',
        },
        {
            'value': 'tax',
            'title': 'Taxation',
        },
        {
            'value': 'trade',
            'title': 'Trade',
        },
        {
            'value': 'transportation',
            'title': 'Transportation',
        },
        {
            'value': 'tourism',
            'title': 'Tourism',
        },
    ]

    def __call__(self, context):
        terms = []
        for i in self._terms:
            terms.append(SimpleTerm(**i))
        return SimpleVocabulary(terms)
예제 #7
0
class AutoTOCPolicy(Persistent):
    grok.implements(IContainerPolicy)

    def createDefaultDocument(self, container, title):
        factory = container.manage_addProduct['Silva']
        factory.manage_addAutoTOC('index', title)
예제 #8
0
class FilePayload(grok.Adapter):
    grok.implements(interfaces.IAssetPayload)
    grok.context(interfaces.IFile)

    def get_payload(self):
        return self.context.get_file()
예제 #9
0
class File(Asset):
    __doc__ = """Any digital file can be uploaded as Silva content.
       For instance large files such as pdf docs or mpegs can be placed in a
       site. File objects have metadata as well."""
    security = ClassSecurityInfo()

    meta_type = "Silva File"

    grok.implements(interfaces.IFile)
    silvaconf.icon('icons/file.png')
    silvaconf.factory('manage_addFile')

    # Default values
    _filename = None
    _content_encoding = None

    # ACCESSORS

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_filename')

    def get_filename(self):
        """Object's id is filename if not set.
        """
        if self._filename is not None:
            return self._filename
        return self.id

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_file_size')

    def get_file_size(self):
        """Get the size of the file as it will be downloaded.
        """
        return self._file.get_size()

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_mime_type')

    def get_mime_type(self):
        """Return the content mimetype.
        """
        # possibly strip out charset encoding
        return self.get_content_type().split(';')[0].strip()

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'fulltext')

    def fulltext(self):
        """Return the content of this object without any markup
        """
        converter = get_converter_for_mimetype(self.get_mime_type())
        fulltext = [self.get_title()]
        if converter is None:
            return fulltext

        text = None
        filename = self.get_file_system_path()
        if filename is not None:
            text = converter.convert_file(filename)
        else:
            file_data = self.get_file()
            if file_data:
                text = converter.convert_string(file_data)
        if text:
            fulltext.append(text)
        return fulltext

    security.declareProtected(SilvaPermissions.View, 'get_download_url')

    def get_download_url(self, preview=False, request=None):
        if request is None:
            request = self.REQUEST
        url = getMultiAdapter((self, request),
                              IContentURL).url(preview=preview)
        if preview:
            # In case of preview we add something that change at the
            # end of the url to prevent caching from the browser.
            url += '?' + str(int(time.time()))
        return url

    security.declareProtected(SilvaPermissions.View, 'tag')

    def tag(self, **kw):
        warnings.warn(
            'tag have been replaced with get_html_tag. '
            'It will be removed, please update your code.',
            DeprecationWarning,
            stacklevel=2)
        return self.get_html_tag(**kw)

    security.declareProtected(SilvaPermissions.View, 'get_html_tag')

    def get_html_tag(self, preview=False, request=None, **extra_attributes):
        """ return xhtml tag

        Since 'class' is a Python reserved word, it cannot be passed in
        directly in keyword arguments which is a problem if you are
        trying to use 'tag()' to include a CSS class. The tag() method
        will accept a 'css_class' argument that will be converted to
        'class' in the output tag to work around this.
        """
        src = self.get_download_url(preview, request)
        title = self.get_title_or_id()

        if 'css_class' in extra_attributes:
            extra_attributes['class'] = extra_attributes['css_class']
            del extra_attributes['css_class']

        extra_html_attributes = [
            '{name}="{value}"'.format(name=escape(name, 1),
                                      value=escape(value, 1))
            for name, value in extra_attributes.items()
        ]

        return '<a href="%s" title="Download %s" %s>%s</a>' % (
            src, self.get_filename(), extra_html_attributes, title)

    # checks where the mime type is text/* or javascript
    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'is_text')

    def is_text(self):
        mimetype = self.get_mime_type()
        if ((mimetype.startswith('text/') and mimetype != 'text/rtf')
                or mimetype in ('application/x-javascript', 'application/xml',
                                'application/xhtml+xml')):
            return self.get_content_encoding() is None
        return False

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'is_text_editable')

    def is_text_editable(self):
        #size is editable if it is less than 150 KB
        return self.is_text() and (not self.get_file_size() > 153600)

    security.declareProtected(SilvaPermissions.View, 'get_text')

    def get_text(self):
        if not self.is_text():
            raise TypeError("Content of Silva File is not text")
        return self.get_file()

    security.declareProtected(SilvaPermissions.View, 'get_file')

    def get_file(self):
        fd = self.get_file_fd()
        data = fd.read()
        fd.close()
        return data

    security.declareProtected(SilvaPermissions.View, 'get_file_fd')

    def get_file_fd(self):
        raise NotImplementedError

    security.declareProtected(SilvaPermissions.View, 'get_content_type')

    def get_content_type(self):
        return self._file.content_type

    security.declareProtected(SilvaPermissions.View, 'get_content_encoding')

    def get_content_encoding(self):
        return self._content_encoding

    # MODIFIERS

    security.declareProtected(SilvaPermissions.ChangeSilvaContent, 'set_file')

    def set_file(self, stream, content_type=None, content_encoding=None):
        """Set data in _file object
        """
        raise NotImplementedError

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_filename')

    def set_filename(self, filename):
        """Set filename
        """
        self._filename = filename

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'get_file_system_path')

    def get_file_system_path(self):
        """Return path on filesystem for containing File.
        """
        return None

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_content_type')

    def set_content_type(self, content_type):
        self._file.content_type = content_type

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_content_encoding')

    def set_content_encoding(self, content_encoding):
        self._content_encoding = content_encoding

    security.declareProtected(SilvaPermissions.ChangeSilvaContent, 'set_text')

    def set_text(self, text):
        raise NotImplementedError
예제 #10
0
class FundraisingSeal(dexterity.Item):
    grok.implements(IFundraisingSeal)
예제 #11
0
class BlobFile(File):
    """Silva File object, storage using blobs.
    """
    grok.implements(interfaces.IBlobFile)
    grok.baseclass()
    security = ClassSecurityInfo()

    def __init__(self, id):
        super(BlobFile, self).__init__(id)
        self._file = blob.Blob()
        self._content_type = DEFAULT_MIMETYPE

    # MODIFIERS

    security.declareProtected(SilvaPermissions.ChangeSilvaContent, 'set_file')

    def set_file(self, stream, content_type=None, content_encoding=None):
        with self._file.open('w') as descriptor:
            data = stream.read(CHUNK_SIZE)
            while data:
                descriptor.write(data)
                data = stream.read(CHUNK_SIZE)
        if content_type is None:
            # Detect content-type
            identifier = get_file_name(stream, default=self.id)
            blob_filename = self._file._p_blob_uncommitted or \
                self._file._p_blob_committed
            self._content_type, self._content_encoding = getUtility(
                IMimeTypeClassifier).guess_type(id=identifier,
                                                filename=blob_filename,
                                                default=DEFAULT_MIMETYPE)
        else:
            # Set provided values
            self._content_type = content_type
            self._content_encoding = content_encoding
        if self._content_type == 'text/plain':
            self._content_type = 'text/plain; charset=utf-8'
        if not interfaces.IImage.providedBy(aq_parent(self)):
            #    # If we are not a storage of an image, trigger an event.
            notify(ObjectModifiedEvent(self))

    security.declareProtected(SilvaPermissions.ChangeSilvaContent, 'set_text')

    def set_text(self, text):
        with self._file.open('w') as descriptor:
            descriptor.write(text)
        if not interfaces.IImage.providedBy(aq_parent(self)):
            #    # If we are not a storage of an image, trigger an event.
            notify(ObjectModifiedEvent(self))

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_content_type')

    def set_content_type(self, content_type):
        self._content_type = content_type

    # ACCESSORS

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_file_size')

    def get_file_size(self):
        """Get the size of the file as it will be downloaded.
        """
        with self._file.open() as descriptor:
            descriptor.seek(0, 2)
            return descriptor.tell()

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_content_type')

    def get_content_type(self):
        """Return the content type
        """
        return self._content_type

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_file_fd')

    def get_file_fd(self):
        return self._file.open()

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'get_file_system_path')

    def get_file_system_path(self):
        with self._file.open() as descriptor:
            return descriptor.name
예제 #12
0
class Stream(Item):
    """A stream (audio and video)."""
    grok.implements(IStream)
class SilvaSoftwareActivity(Content, SimpleItem, ExternalSource):
    """Collect activity from an RSS feed and generate statistics about
    it.
    """
    grok.implements(ISilvaSoftwareActivity)
    meta_type = 'Silva Software Activity'
    security = ClassSecurityInfo()
    silvaconf.icon('SilvaSoftwareActivity.png')
    silvaconf.priority(9)

    _rss_url = None
    _data = None

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_rss_url')

    def get_rss_url(self):
        return self._rss_url

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_rss_url')

    def set_rss_url(self, url):
        self._rss_url = url

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_changes_since')

    def get_changes_since(self, days=31, empty=True):
        """Return the changes since the given number of days.
        """
        if self._data is not None:
            today = datetime.date.today()
            today_day = today.toordinal()
            since = (today - datetime.timedelta(days))
            since_day = since.toordinal()
            if not empty:
                return list(self._data.values(since_day))
            data = self._data.items(since_day)
            result = []
            for day, values in data:
                while day > since_day:
                    result.append([])
                    since += datetime.timedelta(1)
                    since_day = since.toordinal()
                result.append(values)
                since += datetime.timedelta(1)
                since_day = since.toordinal()
            if result:
                while today_day > since_day:
                    result.append([])
                    since += datetime.timedelta(1)
                    since_day = since.toordinal()
            return result
        return []

    security.declareProtected(SilvaPermissions.ChangeSilvaContent, 'refresh')

    def refresh(self):
        """Refresh the data stored.
        """
        rss_url = self.get_rss_url()
        if rss_url is None:
            return
        if self._data is None:
            self._data = IOBTree()
        data = feedparser.parse(rss_url)
        changed = False
        for entry in data['entries']:
            date = datetime.date(*entry['updated_parsed'][:3])
            key = date.toordinal()
            if key not in self._data:
                self._data[key] = Changes()
            change = Change(entry['id'], entry['author'], date,
                            entry['summary'])
            changed = self._data[key].add(change) or changed
        if changed:
            self._p_changed = True

    def is_previewable(self):
        return False

    def to_html(self, content, request, **parameters):
        return silvaviews.render(self, request)
class SilvaSoftwareActivityAggregator(Content, SimpleItem, ExternalSource):
    """Aggregate multiple activities together.
    """
    grok.implements(ISilvaSoftwareActivityAggregator)
    meta_type = 'Silva Software Activity Aggregator'
    security = ClassSecurityInfo()
    silvaconf.icon('SilvaSoftwareActivity.png')
    silvaconf.priority(9)

    _data = None
    _most_actives = []

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_changes_since')

    def get_changes_since(self, days=31, empty=True):
        """Return the changes since the given number of days.
        """
        if self._data is not None:
            today = datetime.date.today()
            today_day = today.toordinal()
            since = (today - datetime.timedelta(days))
            since_day = since.toordinal()
            if not empty:
                return list(self._data.values(since_day))
            data = self._data.items(since_day)
            result = []
            for day, values in data:
                while day > since_day:
                    result.append([])
                    since += datetime.timedelta(1)
                    since_day = since.toordinal()
                result.append(values)
                since += datetime.timedelta(1)
                since_day = since.toordinal()
            if result:
                while today_day > since_day:
                    result.append([])
                    since += datetime.timedelta(1)
                    since_day = since.toordinal()
            return result
        return []

    security.declareProtected(SilvaPermissions.ChangeSilvaContent, 'refresh')

    def refresh(self):
        """Refresh the data stored.
        """
        if self._data is None:
            self._data = IOBTree()

        counts = {}
        catalog = getUtility(ICatalogService)
        for brain in catalog(meta_type=['Silva Software Activity'],
                             path='/'.join(
                                 self.get_container().getPhysicalPath())):
            activity = brain.getObject()
            counts[brain.content_intid] = 0
            changes = activity.get_changes_since(empty=False)
            print activity.get_title(), len(changes)
            for change in changes:
                for commit in change:
                    key = commit.date.toordinal()
                    if key not in self._data:
                        self._data[key] = Changes()
                    self._data[key].add(commit)
                counts[brain.content_intid] += len(change)
        self._most_actives = map(
            operator.itemgetter(0),
            sorted(counts.items(), key=operator.itemgetter(1), reverse=True))

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_most_active')

    def get_most_active(self, limit=5):
        get_activity = getUtility(IIntIds).getObject
        return map(lambda i: get_activity(i).get_container(),
                   self._most_actives[:limit])

    def is_previewable(self):
        return False

    def to_html(self, content, request, **parameters):
        return silvaviews.render(self, request)
예제 #15
0
class ProductFieldset(dexterity.Container):
    grok.implements(IProductFieldset)
예제 #16
0
class Section(dexterity.Container):
    grok.implements(ISection)
예제 #17
0
class MembershipTableSource(SqlTableSource):
    grok.implements(ITableSource)
    grok.adapts(MembershipListingTab, Interface)

    searchable_columns = []
예제 #18
0
class DossierTemplateSearchableTextExtender(SearchableTextExtender):
    grok.context(IDossierTemplateMarker)
    grok.name('IDossierTemplate')
    grok.implements(dexteritytextindexer.IDynamicTextIndexExtender)
예제 #19
0
class Question(dexterity.Item):
    grok.implements(IQuestion)
예제 #20
0
class ExtensionService(SilvaService, Folder):
    meta_type = 'Silva Extension Service'
    grok.implements(IExtensionService, ISilvaConfigurableService)
    grok.name('service_extensions')
    silvaconf.default_service()
    silvaconf.icon('icons/service_extension.png')

    security = ClassSecurityInfo()
    manage_options = (
        {
            'label': 'Extensions',
            'action': 'manage_extensions'
        },
        {
            'label': 'Partial upgrades',
            'action': 'manage_partialUpgrade'
        },
        {
            'label': 'Partial reindex',
            'action': 'manage_partialReindex'
        },
        {
            'label': 'Logs',
            'action': 'manage_main'
        },
    ) + SilvaService.manage_options

    _site_quota = 0
    _quota_enabled = False
    _quota_verify = False

    # MANIPULATORS

    security.declareProtected('View management screens', 'install')

    def install(self, name):
        """Install extension
        """
        root = self.get_root()
        extensionRegistry.install(name, root)

    security.declareProtected('View management screens', 'uninstall')

    def uninstall(self, name):
        """Uninstall extension
        """
        root = self.get_root()
        extensionRegistry.uninstall(name, root)

    security.declareProtected('View management screens', 'refresh')

    def refresh(self, name):
        """Refresh  extension.
        """
        root = self.get_root()
        extensionRegistry.refresh(name, root)

    security.declareProtected('View management screens', 'refresh_all')

    def refresh_all(self):
        """Refreshes all extensions
        """
        for name in extensionRegistry.get_names():
            if self.is_installed(name):
                self.refresh(name)

    security.declareProtected('View management screens', 'reindex_all')

    def reindex_all(self):
        """Refresh the silva catalog.
        """
        root = self.get_root()
        root.service_catalog.manage_catalogClear()
        logger.info('Catalog cleared.')
        index_content(root)

    security.declareProtected('View management screens', 'reindex_subtree')

    def reindex_subtree(self, path):
        """reindexes a subtree.
        """
        root = self.get_root()
        index_content(root.unrestrictedTraverse(str(path)), reindex=True)

    security.declareProtected('View management screens',
                              'disable_quota_subsystem')

    def disable_quota_subsystem(self):
        """Disable quota sub-system.
        """
        if not self._quota_enabled:
            return False
        if self._site_quota:
            # You cannot disable the quota system if there is a site quota.
            return False
        root = self.get_root()

        # Disable metadata for quota
        collection = root.service_metadata.getCollection()
        if 'silva-quota' in collection.objectIds():
            collection.manage_delObjects(['silva-quota'])
        setids = ('silva-quota', )
        types = (
            'Silva Root',
            'Silva Publication',
        )
        root.service_metadata.removeTypesMapping(types, setids)

        self._quota_enabled = False
        self._quota_verify = False
        return True

    security.declareProtected('View management screens',
                              'enable_quota_subsystem')

    def enable_quota_subsystem(self):
        """Enable quota sub-system.
        """
        if self._quota_enabled:
            return False
        root = self.get_root()

        # Setup metadata for quota
        schema = os.path.join(os.path.dirname(__file__), 'schema')

        collection = root.service_metadata.getCollection()
        if 'silva-quota' in collection.objectIds():
            collection.manage_delObjects(['silva-quota'])

        xml_file = os.path.join(schema, 'silva-quota.xml')
        with open(xml_file, 'r') as fh:
            collection.importSet(fh)

        setids = ('silva-quota', )
        types = [
            c['name']
            for c in extensionRegistry.get_contents(requires=[IPublication])
        ]
        root.service_metadata.addTypesMapping(types, setids)
        root.service_metadata.initializeMetadata()

        root.used_space = compute_used_space(root)
        self._quota_enabled = True
        self._quota_verify = True
        return True

    security.declareProtected('View management screens', 'upgrade_content')

    def upgrade_content(self, content, from_version, to_version):
        """Upgrade the given content
        """
        now = datetime.now().strftime('%Y-%b-%dT%H%M%S')
        log_filename = 'upgrade-log-%s-to-%s-on-%s.log' % (from_version,
                                                           to_version, now)
        log = upgrade.registry.upgrade(content, from_version, to_version)
        factory = self.manage_addProduct['OFS']
        factory = factory.manage_addFile(log_filename,
                                         log.read(),
                                         content_type='text/plain')
        if interfaces.IRoot.providedBy(content):
            content._content_version = to_version

    # ACCESSORS

    security.declareProtected('Access contents information',
                              'get_quota_subsystem_status')

    def get_quota_subsystem_status(self):
        if not self._quota_enabled:
            return None
        return self._quota_verify

    security.declareProtected('Access contents information', 'get_site_quota')

    def get_site_quota(self):
        return self._site_quota

    security.declareProtected('Access contents information', 'is_installed')

    def is_installed(self, name):
        """Is extension installed?
        """
        root = self.get_root()
        return extensionRegistry.is_installed(name, root)
예제 #21
0
class AutoTOC(Content, SimpleItem):
    __doc__ = _("""This is a special document type that automatically generates
    a Table of Contents. Usually it's used as the 'index' document of a folder.
    Then the parent folder displays a TOC when accessed (e.g.
    http://www.x.yz/silva/myFolder). The AutoTOC is configurable: it can display
    any selection of Silva content including assets, include descriptions or
    icons, be set to stop at a specific depth, and use various sorting
    methods.
    """)
    security = ClassSecurityInfo()

    meta_type = "Silva AutoTOC"

    grok.implements(IAutoTOC)
    silvaconf.icon('icons/autotoc.png')
    silvaconf.priority(0.2)

    _local_types = ['Silva Document', 'Silva Publication', 'Silva Folder']
    _toc_depth = -1
    _display_desc_flag = False
    # values: 'silva', 'alpha', 'reversealpha', 'chronmod', 'rchronmod'
    _sort_order = 'silva'
    _show_icon = False
    _show_container_link = False

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_toc_depth')

    def set_toc_depth(self, depth):
        self._toc_depth = depth

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_toc_depth')

    def get_toc_depth(self):
        """get the depth to which the toc will be rendered"""
        return self._toc_depth

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_show_container_link')

    def set_show_container_link(self, flag):
        self._show_container_link = flag

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_show_container_link')

    def get_show_container_link(self):
        """get the depth to which the toc will be rendered"""
        return self._show_container_link

    security.declareProtected(SilvaPermissions.View, 'get_local_types')

    def get_local_types(self):
        return self._local_types

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_local_types')

    def set_local_types(self, types):
        self._local_types = types

    security.declareProtected(SilvaPermissions.View, 'get_display_desc_flag')

    def get_display_desc_flag(self):
        return self._display_desc_flag

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_display_desc_flag')

    def set_display_desc_flag(self, flag):
        self._display_desc_flag = flag

    security.declareProtected(SilvaPermissions.View, 'get_show_icon')

    def get_show_icon(self):
        return self._show_icon

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_show_icon')

    def set_show_icon(self, flag):
        self._show_icon = flag

    security.declareProtected(SilvaPermissions.View, 'get_sort_order')

    def get_sort_order(self):
        return self._sort_order

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_sort_order')

    def set_sort_order(self, order):
        self._sort_order = order
예제 #22
0
class AddLocalRoles(grok.Adapter):

    grok.implements(ILocalRoleProvider)
    grok.context(IlocalrolesMarker)

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

    def getreaders(self, start, end):
        #         if self.readers != set(): return self.readers
        localrole = Ilocalroles(self.context, None)
        if localrole == None: return set()
        tp = set()
        for i in xrange(start, end):
            attrname = 'reader%s' % i

            item = getattr(localrole, attrname, ())
            if type(item) == type(''):
                tp.add(item)
            else:
                # set join set
                tp = set(getattr(localrole, attrname, ())) | tp

        return tp

    def getRoles(self, principal_id):
        """If the user is in the list of Reviewers for this item, grant
        the reader, Editor and Contributor local roles.
        """
        #        import pdb
        #        pdb.set_trace()
        localrole = Ilocalroles(self.context, None)

        roles = set()
        # the EMC designer will be assigned Manager role
        if principal_id in localrole.emc_designer:
            api.user.grant_roles(username=principal_id, roles=['Reader'])
            roles.add('Site Administrator')
            roles.add('Reader')

# the product designer will be assigned Contributor and Editor roles
        if principal_id in localrole.designer:
            api.user.grant_roles(username=principal_id, roles=['Reader'])
            roles.add('Contributor')
            roles.add('Editor')
            roles.add('ProjectReader')
            roles.add('Reader')
#             if IProject.providedBy(self.context):
#                 roles.add('Contributor')
#                 roles.add('Editor')
#             else:
#                 roles.add('Site Administrator')

# the first group members will be assigned Reader role
        if principal_id in self.getreaders(1, 8):
            api.user.grant_roles(username=principal_id, roles=['Reader'])
            roles.add('ProjectReader')
# the third group members will be assigned EMCExpert role

        if principal_id in self.getreaders(8, 12):
            api.user.grant_roles(username=principal_id, roles=['Reader'])
            roles.add('ProjectReader')
        return roles

    def getAllRoles(self):
        """Return a list of tuples (principal_id, roles), where roles is a
        list of roles for the given user id.
        """

        localrole = Ilocalroles(self.context, None)

        if localrole is None  or (not localrole.emc_designer  \
                                   and not localrole.designer and not self.getreaders(1,12)):
            return

        for principal_id in localrole.emc_designer:
            yield (
                principal_id,
                ('Site Administrator', ),
            )

        for principal_id in localrole.designer:
            yield (
                principal_id,
                ('Contributor', 'Editor', 'ProjectReader'),
            )
#             if IProject.providedBy(self.context):
#                 yield (principal_id, ('Contributor','Editor'),)
#             else:
#                 yield (principal_id, ('Site Administrator',),)

        for principal_id in self.getreaders(1, 8):
            yield (
                principal_id,
                ('ProjectReader', ),
            )
        for principal_id in self.getreaders(8, 12):
            yield (
                principal_id,
                ('ProjectReader', ),
            )


# class localrolesIndexer(grok.MultiAdapter):
#     """Catalog indexer for the 'localroles' index.
#     """
#     grok.implements(IIndexer)
#     grok.adapts(IlocalrolesMarker, IZCatalog)
#     grok.name('localManager')
#
#     def __init__(self, context, catalog):
#         self.localroles = Ilocalroles(context)
#
#     def __call__(self):
#         Manager = self.localroles.Manager or ()
#         return tuple(set(Manager))
예제 #23
0
class BlogPage(Container):
    grok.implements(IBlogPage)
예제 #24
0
class Author(Container):
    grok.implements(IAuthor)
예제 #25
0
class FindEditView(FormWithTemplateREST):
    """Edit a Silva Find
    """
    grok.adapts(Screen, IFind)
    grok.name('content')
    grok.require('silva.ChangeSilvaContent')
    grok.implements(IEditScreen)

    def send_message(self, message, type=u""):
        service = component.getUtility(IMessageService)
        service.send(message, self.request, namespace=type)

    def save(self):
        """Store fields values
        """

        # Validate values
        def validate(prefix, schema):
            atLeastOneShown = False
            for field in schema:
                shown = self.request.get(prefix + field.getName(), False)
                atLeastOneShown = atLeastOneShown or shown
            return atLeastOneShown

        if not validate('show_', self.context.getSearchFields()):
            self.send_message(
                _(u'You need to activate at least one search criterion.'),
                type=u'error')
            return
        if not validate('show_result_', self.context.getResultFields()):
            self.send_message(
                _(u'You need to display at least one field in the results.'),
                type=u'error')
            return

        for widget in self.widgets:
            widget.saveWidgetValue()

        for field in self.context.getSearchFields():
            fieldName = field.getName()
            self.context.shownFields[fieldName] = bool(
                self.request.form.get('show_' + fieldName, False))

        for field in self.context.getResultFields():
            fieldName = field.getName()
            self.context.shownResultsFields[fieldName] = bool(
                self.request.form.get('show_result_' + fieldName, False))

        notify(ObjectModifiedEvent(self.context))
        return self.send_message(_(u'Changes saved.'), type=u'feedback')

    def update(self):
        self.widgets = []
        for field in self.context.getSearchFields():
            widget = getMultiAdapter((field, self.context, self.request),
                                     ICriterionView)
            self.widgets.append(widget)

        self.title = self.context.get_title_or_id()

        if 'silvafind_save' in self.request.form:
            self.save()
예제 #26
0
class Versioning(object):
    """Mixin baseclass to make object contents versioned.
    """
    grok.implements(IVersioning)
    security = ClassSecurityInfo()

    # TODO: Silva 3.1: The datetime expiration and publication are
    # currently stored inside the VersionedContent. Moving it to the
    # Version would simplify a lot the management of the versions.
    _unapproved_version = empty_version
    _approved_version = empty_version
    _public_version = empty_version
    _previous_versions = None
    _first_publication_date = None

    # MANIPULATORS
    security.declarePrivate('create_version')
    def create_version(self, version_id,
                       publication_datetime,
                       expiration_datetime):
        """Add unapproved version
        """

        assert self._approved_version == empty_version, \
            u'There is an approved version'

        assert self._unapproved_version == empty_version, \
            u'There is an unapproved version'

        # if a version with this name already exists, complain
        if self._public_version is not None:
            assert version_id != self._public_version[0], \
                u'There is already a public version with the same id'

        previous_versions = self._previous_versions or []
        for previous_version in previous_versions:
            assert version_id != previous_version[0], \
                u'There is already a previous version with the same id'

        self._unapproved_version = (version_id,
                                    publication_datetime,
                                    expiration_datetime)

    security.declareProtected(SilvaPermissions.ApproveSilvaContent,
                              'approve_version')
    def approve_version(self):
        """Aprove the current unapproved version.
        """
        # self._update_publication_status()
        if self._unapproved_version == empty_version:
            raise VersioningError(
                _('There is no unapproved version to approve.'),
                self)

        if self._approved_version != empty_version:
            raise VersioningError(
                _('There already is an approved version.'),
                self)

        if self._unapproved_version[1] is None:
            raise VersioningError(
                _('Cannot approve version without publication datetime.'),
                self)

        self._approved_version = self._unapproved_version
        self._unapproved_version = empty_version

        version = self._getOb(self._approved_version[0])
        status = IRequestForApprovalStatus(version)
        status.validate()

        notify(events.ContentApprovedEvent(version, status))

        # We may be published now
        self._update_publication_status()

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'unapprove_version')
    def unapprove_version(self):
        """Unapprove an approved but not yet public version.
        """
        # self._update_publication_status()
        if self._approved_version == empty_version:
            raise VersioningError(
                  _("This content is not approved."),
                  self)

        if self._unapproved_version != empty_version:
            raise VersioningError(
                _(('Should never happen: unapproved version ${unapproved} found while '
                   'approved version ${approved} exists at the same time.'),
                  mapping={'unapproved': self._unapproved_version[0],
                           'approved': self._approved_version[0]}),
                self)

        self._unapproved_version = self._approved_version
        self._approved_version = empty_version

        version = self._getOb(self._unapproved_version[0])
        notify(events.ContentUnApprovedEvent(version))


    security.declareProtected(SilvaPermissions.ApproveSilvaContent,
                              'close_version')
    def close_version(self):
        """Close public version.
        """
        if self._public_version == empty_version:
            raise VersioningError(
                _(u"There is no public version to close."),
                self)

        previous_versions = self._previous_versions or []
        previous_versions.append(self._public_version)
        self._public_version = empty_version
        self._previous_versions = previous_versions

        version = self._getOb(self._previous_versions[-1][0])
        notify(events.ContentClosedEvent(version))

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'create_copy')
    def create_copy(self, version_id=None):
        """Create new version of public version.
        """
        if self.get_approved_version() is not None:
            raise VersioningError(
                _('An approved version is already available.'),
                self)
        if self.get_unapproved_version() is not None:
            raise VersioningError(
                _('An new version is already available.'),
                self)

        expiration_time = None
        if version_id is None:
            # get id of public version to copy
            version_id, ignored_time, expiration_time = self._public_version
            # if there is no public version, get id of last closed version
            # (which should always be there)
            if version_id is None:
                if self._previous_versions:
                    version_id, ignored_time, expiration_time = \
                        self._previous_versions[-1]
                if version_id is None:
                    raise VersioningError(
                        _(u"There is no version to create a version form."),
                        self)
        if expiration_time is not None and not expiration_time.isFuture():
            # Reset expiration time if it is in the past.
            expiration_time = None

        # Copy given version
        new_version_id = self.get_new_version_id()
        self.manage_clone(self._getOb(version_id), new_version_id)

        # The version might have been copied. Clear its data.
        version = self._getOb(new_version_id)
        IRequestForApprovalStatus(version).reset()

        # Register it
        self.create_version(new_version_id, None, expiration_time)

    security.declarePrivate('get_new_version_id')
    def get_new_version_id(self):
        """get_new_version_id is used when a new version will be created,
        to get a new unique id.  This may or may not change internal
        variables"""
        new_version_id = str(self._version_count)
        self._version_count = self._version_count + 1
        return str(new_version_id)

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'request_version_approval')
    def request_version_approval(self, message):
        """Request approval for the current unapproved version
        Raises VersioningError, if there is no such version,
        or it is already approved.
        Returns None otherwise
        """
        version_id = self.get_unapproved_version()
        if version_id is None:
            raise VersioningError(
                _("This content doesn't require approval."),
                self)

        version = self._getOb(version_id)
        status = IRequestForApprovalStatus(version)
        if status.pending:
            raise VersioningError(
                _('The version is already requested for approval.'),
                self)

        status.comment('request', message)
        notify(events.ContentRequestApprovalEvent(version, status))

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'withdraw_version_approval')
    def withdraw_version_approval(self, message):
        """Withdraw a previous request for approval
        Implementation should raise VersioningError, if the
        currently unapproved version has no request for approval yet,
        or if there is no unapproved version.
        """
        version_id = self.get_unapproved_version()
        if version_id is None:
            raise VersioningError(
                _("This content doesn't require approval."),
                self)

        version = self._getOb(version_id)
        status = IRequestForApprovalStatus(version)
        if not status.pending:
            raise VersioningError(
                _("No request for approval is pending for this content."),
                self)

        status.comment('withdraw', message)
        notify(events.ContentApprovalRequestWithdrawnEvent(version, status))

    security.declareProtected(SilvaPermissions.ApproveSilvaContent,
                              'reject_version_approval')
    def reject_version_approval(self, message):
        """Reject a previous request for approval
        Implementation should raise VersioningError, if the
        currently unapproved version has no request for approval yet,
        or if there is no unapproved version.
        """
        version_id = self.get_unapproved_version()
        if version_id is None:
            raise VersioningError(
                _("This content doesn't require approval."),
                self)

        version = self._getOb(version_id)
        status = IRequestForApprovalStatus(version)
        if not status.pending:
            raise VersioningError(
                _("No request for approval is pending for this content."),
                self)

        status.comment('reject', message)
        notify(events.ContentApprovalRequestRefusedEvent(version, status))

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_unapproved_version_publication_datetime')
    def set_unapproved_version_publication_datetime(self, dt):
        """Set publication datetime for unapproved, or None for no
        publication at all yet.
        """
        if self._unapproved_version == empty_version:
            raise VersioningError(_('No unapproved version.'), self)

        version_id, publication_datetime, expiration_datetime = \
                    self._unapproved_version
        self._unapproved_version = version_id, dt, expiration_datetime

    security.declareProtected(SilvaPermissions.ChangeSilvaContent,
                              'set_unapproved_version_expiration_datetime')
    def set_unapproved_version_expiration_datetime(self, dt):
        """Set expiration datetime, or None for no expiration.
        """
        if self._unapproved_version == empty_version:
            raise VersioningError(_('No unapproved version.'), self)

        version_id, publication_datetime, expiration_datetime = \
                    self._unapproved_version
        self._unapproved_version = version_id, publication_datetime, dt

    security.declareProtected(SilvaPermissions.ApproveSilvaContent,
                              'set_approved_version_publication_datetime')
    def set_approved_version_publication_datetime(self, dt):
        """Set publication datetime for approved.
        """
        if self._approved_version == empty_version:
            raise VersioningError(_('No approved version.'), self)

        if dt is None:
            raise VersioningError(_('Must specify publication datetime.'), self)

        version_id, publication_datetime, expiration_datetime = \
                    self._approved_version
        self._approved_version = version_id, dt, expiration_datetime
        # may become published, update publication status
        self._update_publication_status()

    security.declareProtected(SilvaPermissions.ApproveSilvaContent,
                              'set_approved_version_expiration_datetime')
    def set_approved_version_expiration_datetime(self, dt):
        """Set expiration datetime, or None for no expiration.
        """
        if self._approved_version == empty_version:
            raise VersioningError(_('No approved version.'), self)

        version_id, publication_datetime, expiration_datetime = \
                    self._approved_version
        self._approved_version = version_id, publication_datetime, dt
        # may become closed, update publication status
        self._update_publication_status()

    security.declareProtected(
        SilvaPermissions.ApproveSilvaContent, 'set_public_version_expiration_datetime')
    def set_public_version_expiration_datetime(self, dt):
        """Set expiration datetime, or None for no expiration.
        """
        if self._public_version == empty_version:
            raise VersioningError(_('No public version.'), self)

        version_id, publication_datetime, expiration_datetime = \
            self._public_version
        self._public_version = version_id, publication_datetime, dt
        # may become expired, update publication status
        self._update_publication_status()

    security.declareProtected(SilvaPermissions.ApproveSilvaContent,
                              'set_next_version_publication_datetime')
    def set_next_version_publication_datetime(self, dt):
        """Set publication datetime of next version.
        """
        if self._approved_version[0]:
            version_id, publication_datetime, expiration_datetime = \
                        self._approved_version
            self._approved_version = version_id, dt, expiration_datetime
            self._update_publication_status()
        elif self._unapproved_version[0]:
            version_id, publication_datetime, expiration_datetime = \
                        self._unapproved_version
            self._unapproved_version = version_id, dt, expiration_datetime
        else:
            raise VersioningError(_('No next version.'), self)

    security.declareProtected(SilvaPermissions.ApproveSilvaContent,
                              'set_next_version_expiration_datetime')
    def set_next_version_expiration_datetime(self, dt):
        """Set expiration datetime of next version.
        """
        if self._approved_version[0]:
            version_id, publication_datetime, expiration_datetime = \
                        self._approved_version
            self._approved_version = version_id, publication_datetime, dt
        elif self._unapproved_version[0]:
            version_id, publication_datetime, expiration_datetime = \
                        self._unapproved_version
            self._unapproved_version = version_id, publication_datetime, dt
        else:
            raise VersioningError(_('No next version.'), self)

    def _update_publication_status(self):
        # Publish what need to be publish, expire what need to be expired
        now = DateTime()
        # get publication datetime of approved version
        publication_datetime = self._approved_version[1]
        # if it is time make approved version public
        if publication_datetime and now >= publication_datetime:
            if self._public_version != empty_version:
                if not self._previous_versions:
                    self._previous_versions = []
                self._previous_versions.append(self._public_version)
                notify(events.ContentClosedEvent(
                        self._getOb(self._public_version[0], None)))
            self._public_version = self._approved_version
            if self._first_publication_date is None:
                self._first_publication_date = publication_datetime
            self._approved_version = empty_version
            notify(events.ContentPublishedEvent(
                    self._getOb(self._public_version[0], None)))
        # get expiration datetime of public version
        expiration_datetime = self._public_version[2]
        # expire public version if expiration datetime reached
        if expiration_datetime and now >= expiration_datetime:
            # make sure to add it to the previous versions
            previous_versions = self._previous_versions or []
            previous_versions.append(self._public_version)
            self._public_version = empty_version
            self._previous_versions = previous_versions
            notify(events.ContentExpiredEvent(
                    self._getOb(self._previous_versions[-1][0], None)))

    # ACCESSORS

    security.declareProtected(
        SilvaPermissions.ReadSilvaContent, 'is_approved')
    def is_approved(self):
        """Check whether version is approved.
        """
        return self._approved_version != empty_version

    security.declareProtected(
        SilvaPermissions.AccessContentsInformation, 'is_published')
    def is_published(self):
        """Check whether version is published.
        """
        return self._public_version != empty_version

    security.declareProtected(
        SilvaPermissions.ReadSilvaContent, 'is_approval_requested')
    def is_approval_requested(self):
        """Check if there exists an unapproved version
        which has a request for approval.
        """
        version_id = self.get_unapproved_version()
        if version_id is None:
            return False

        version = self._getOb(version_id)
        status = IRequestForApprovalStatus(version)
        return status.pending

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_unapproved_version')
    def get_unapproved_version(self):
        """Get the unapproved version.
        """
        return self._unapproved_version[0]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_unapproved_version_data')
    def get_unapproved_version_data(self):
        """Get all the workflow data of the unapproved version.
        """
        return self._unapproved_version

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_unapproved_version_publication_datetime')
    def get_unapproved_version_publication_datetime(self):
        """Get publication datetime."""
        return self._unapproved_version[1]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_unapproved_version_expiration_datetime')
    def get_unapproved_version_expiration_datetime(self):
        """Get version datetime."""
        return self._unapproved_version[2]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_approved_version')
    def get_approved_version(self):
        """Get the approved version.
        """
        return self._approved_version[0]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_approved_version_data')
    def get_approved_version_data(self):
        """Get all the workflow data of the approved version.
        """
        return self._approved_version

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_approved_version_publication_datetime')
    def get_approved_version_publication_datetime(self):
        """Get publication datetime."""
        return self._approved_version[1]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_approved_version_expiration_datetime')
    def get_approved_version_expiration_datetime(self):
        """Get version datetime."""
        return self._approved_version[2]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_next_version')
    def get_next_version(self):
        """Get either approved version if available, or unapproved
        version if not, or None if no next version.
        """
        return self._approved_version[0] or self._unapproved_version[0]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_next_version_publication_datetime')
    def get_next_version_publication_datetime(self):
        """Get publication datetime."""
        return self._approved_version[1] or self._unapproved_version[1]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_next_version_expiration_datetime')
    def get_next_version_expiration_datetime(self):
        """Get version datetime."""
        return self._approved_version[2] or self._unapproved_version[2]

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_public_version')
    def get_public_version(self):
        """Get the public version.
        """
        return self._public_version[0]

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_public_version_data')
    def get_public_version_data(self):
        """Get all workflow data of the public version.
        """
        return self._public_version

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_first_publication_date')
    def get_first_publication_date(self):
        """Get the earliest publication date of any version of this Content.
        Needed for rss/atom feeds.
        """
        if not self._first_publication_date is None:
            return self._first_publication_date
        return self.get_public_version_publication_datetime()

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_public_version_publication_datetime')
    def get_public_version_publication_datetime(self):
        """Get publication datetime."""
        return self._public_version[1]

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'get_public_version_expiration_datetime')
    def get_public_version_expiration_datetime(self):
        """Get version datetime."""
        return self._public_version[2]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_previous_versions')
    def get_previous_versions(self):
        """Get list of previous versions, index 0 most recent.
        """
        if self._previous_versions is None:
            return []
        return [version[0] for version in self._previous_versions]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_previous_versions_data')
    def get_previous_versions_data(self):
        """Get list of workflow data of the previous versions, index 0 most
        recent.
        """
        if self._previous_versions is None:
            return []
        return [version for version in self._previous_versions]

    security.declareProtected(SilvaPermissions.ReadSilvaContent,
                              'get_last_closed_version')
    def get_last_closed_version(self):
        """Get the last closed version or None if no such thing.
        """
        versions = self.get_previous_versions()
        if len(versions) < 1:
            return None
        return versions[-1]
class SourceAsset(VersionedNonPublishable):
    """A source asset stores a external source and a set of its parameters.x
    """
    meta_type = "Silva Source Asset"
    grok.implements(ISourceAsset)
    silvaconf.icon('www/code_source_asset.png')
    silvaconf.version_class(SourceAssetVersion)
    security = ClassSecurityInfo()

    security.declareProtected(permissions.AccessContentsInformation,
                              'get_parameters_form')

    def get_parameters_form(self):
        return None

    security.declarePrivate('get_source')

    def get_viewable_source(self):
        viewable = self.get_viewable()
        if viewable is not None:
            try:
                return viewable.get_source()
            except SourceError:
                pass
        return None

    security.declareProtected(permissions.AccessContentsInformation, 'to_html')

    def to_html(self, content, request, **parameters):
        viewable = self.get_viewable()
        if viewable is not None:
            return viewable.get_controller(request).render()
        # Should we put an error message instead ?
        return ''

    def get_description(self):
        source = self.get_viewable_source()
        if source is not None:
            return source.get_description()
        return _('Broken or missing source.')

    security.declareProtected(permissions.AccessContentsInformation,
                              'get_icon')

    def get_icon(self):
        source = self.get_viewable_source()
        if source is not None:
            return source.get_icon()
        return None

    security.declareProtected(permissions.AccessContentsInformation,
                              'is_usable')

    def is_usable(self):
        source = self.get_viewable_source()
        if source is not None:
            return True
        return False

    security.declareProtected(permissions.AccessContentsInformation,
                              'is_previewable')

    def is_previewable(self, **parameters):
        source = self.get_viewable_source()
        if source is not None:
            return source.is_previewable()
        return False

    security.declareProtected(permissions.AccessContentsInformation,
                              'is_cacheable')

    def is_cacheable(self, **parameters):
        source = self.get_viewable_source()
        if source is not None:
            return source.is_cacheable()
        return False
class NominationFolder(dexterity.Container):
    grok.implements(INominationFolder)
예제 #29
0
class ResponseTransporter(grok.Adapter):
    """Adadpter for sending responses of the adapted task to
    a remote task on a remote client.
    """

    grok.context(ITask)
    grok.implements(IResponseTransporter)
    grok.require('zope2.View')

    def send_responses(self, target_cid, remote_task_url, intids_mapping=None):
        """ Sends all responses of task self.context to task on
        a remote client.
        `target_cid`: client_id of a target client
        `remote_task_url`: url to a task on `target_cid` relative
        to its site root.
        `intids_mapping`: replace intids of RelationValues according
        to this mapping. This fixes the intids on remote clients.
        RelationValues not listed in this mapping will not be sent.
        """

        jsondata = self.extract_responses(intids_mapping)

        return remote_request(target_cid,
                              '@@task-responses-receive',
                              path=remote_task_url,
                              data=dict(responses=jsondata))

    def get_responses(self, target_cid, remote_task_path, intids_mapping):
        """Retrieves all responses from the task with path `remote_task_path`
        on the client `client` and adds them to the current context (target
        task).

        Provide a an `intids_mapping` (dict), mapping the original intids of
        related objects to the new intids of the copies on this client. This
        is necessary for fixing the relations.
        """

        req_data = {'intids_mapping': json.dumps(intids_mapping)}
        response = remote_request(target_cid,
                                  '@@task-responses-extract',
                                  path=remote_task_path,
                                  data=req_data)
        try:
            data = json.loads(response.read())
        except ValueError:
            #is a internal request
            data = response.read()

        self.create_responses(data)

    def extract_responses(self, intids_mapping=None):
        if intids_mapping is None:
            intids_mapping = {}

        self.intids_mapping = intids_mapping

        data = []
        for resp in IResponseContainer(self.context):
            resp_data = {}

            for key in IPersistentResponse.names():
                attr = IPersistentResponse[key]
                if type(attr) == Attribute:
                    val = getattr(resp, key, None)
                    try:
                        val = self._encode(val)
                    except ValueError:
                        # the intid in the relation value is not listed
                        # in the mapping - so we skip it.
                        pass
                    else:
                        resp_data[key] = val
            data.append(resp_data)

        return json.dumps(data)

    def create_responses(self, data):
        container = IResponseContainer(self.context)

        for resp_data in data:
            response = Response('')

            for key, value in resp_data.items():
                if value:
                    value = self._decode(value)
                setattr(response, key, value)

            container.add(response)

        modified(self.context)

    def _encode(self, value):
        """Lazy encoding function.
        """

        if isinstance(value, str):
            return [u'string:utf8', value.decode('utf-8')]

        if isinstance(value, unicode):
            return [u'unicode', value]

        if isinstance(value, datetime):
            return [u'datetime', str(value)]

        if isinstance(value, DateTime):
            return [u'DateTime', str(value)]

        if isinstance(value, (PersistentList, list)):
            return [u'list', [self._encode(item) for item in value]]

        if isinstance(value, RelationValue):
            if value.to_id in self.intids_mapping:
                return [u'RelationValue', self.intids_mapping[value.to_id]]
            else:
                raise ValueError('intids of relation value not in ' 'mapping')

        return value

    def _decode(self, value):
        """Decode the previously encoded value.
        """

        if not isinstance(value, list):
            return value

        if not value or not isinstance(value[0], unicode):
            return value

        type_, val = value

        if type_.startswith('string:'):
            return val.encode(type_.split(':', 1)[1])

        if type_ == 'unicode':
            return unicode(val)

        if type_ == 'datetime':
            return DateTime(val).asdatetime()

        if type_ == 'DateTime':
            return DateTime(val)

        if type_ == 'RelationValue':
            return RelationValue(val)

        if type_ == 'list':
            return [self._decode(item) for item in val]

        return val
예제 #30
0
class VersionedNonPublishable(VersionedObject, NonPublishable, BaseFolder):
    grok.implements(IVersionedNonPublishable)
    grok.baseclass()