예제 #1
0
    def setUp(self):
        self.app = self.layer['app']
        self.portal = self.layer['portal']
        self.portal_url = self.portal.absolute_url()
        self.request = self.portal.REQUEST
        self.catalog = getToolByName(self.portal, 'portal_catalog')

        self.api_session = RelativeSession(self.portal_url)
        self.api_session.headers.update({'Accept': 'application/json'})
        self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)

        # /plone/folder
        self.folder = createContentInContainer(self.portal,
                                               u'Folder',
                                               id=u'folder',
                                               title=u'Some Folder')

        # /plone/folder/doc
        self.doc = createContentInContainer(
            self.folder,
            u'DXTestDocument',
            id='doc',
            title=u'Lorem Ipsum',
            start=DateTime(1950, 1, 1, 0, 0),
            effective=DateTime(1995, 1, 1, 0, 0),
            expires=DateTime(1999, 1, 1, 0, 0),
            test_int_field=42,
            test_list_field=['Keyword1', 'Keyword2', 'Keyword3'],
            test_bool_field=True,
            test_richtext_field=RichTextValue(raw=u'<p>Some Text</p>',
                                              mimeType='text/html',
                                              outputMimeType='text/html'),
        )
        IMutableUUID(self.doc).set('77779ffa110e45afb1ba502f75f77777')
        self.doc.reindexObject()

        # /plone/folder/other-document
        self.doc2 = createContentInContainer(
            self.folder,
            u'DXTestDocument',
            id='other-document',
            title=u'Other Document',
            description=u'\xdcbersicht',
            start=DateTime(1975, 1, 1, 0, 0),
            effective=DateTime(2015, 1, 1, 0, 0),
            expires=DateTime(2020, 1, 1, 0, 0),
            test_list_field=['Keyword2', 'Keyword3'],
            test_bool_field=False,
        )

        # /plone/folder2
        self.folder2 = createContentInContainer(self.portal,
                                                u'Folder',
                                                id=u'folder2',
                                                title=u'Another Folder')

        # /plone/folder2/doc
        createContentInContainer(
            self.folder2,
            u'DXTestDocument',
            id='doc',
            title=u'Document in second folder',
            start=DateTime(1975, 1, 1, 0, 0),
            effective=DateTime(2015, 1, 1, 0, 0),
            expires=DateTime(2020, 1, 1, 0, 0),
            test_bool_field=False,
        )

        # /plone/doc-outside-folder
        createContentInContainer(
            self.portal,
            u'DXTestDocument',
            id='doc-outside-folder',
            title=u'Doc outside folder',
        )

        transaction.commit()
예제 #2
0
    def test_MailerXMLAttachments(self):
        """ Test mailer with dummy_send """
        mailer = get_actions(self.ff1)["mailer"]
        mailer.sendXML = True
        mailer.sendCSV = False
        context = get_context(mailer)
        # Test all dexterity field type listed at https://docs.plone.org/external/plone.app.dexterity/docs/reference/fields.html
        fields = dict(
            replyto="*****@*****.**",
            topic="test subject",
            richtext=RichTextValue(raw="Raw"),
            comments=u"test comments😀",
            datetime=datetime.datetime(2019, 4, 1),
            date=datetime.date(2019, 4, 2),
            delta=datetime.timedelta(1),
            bool=True,
            number=1981,
            floating=3.14,
            tuple=("elemenet1", "element2"),
            list=[1, 2, 3, 4],
            map=dict(fruit="apple"),
            choices=set(["A", "B"]),
            empty_string="",
            zero_value=0,
            none_value=None,
            empty_tuple=(),
            empty_list=[],
            empty_set=set(),
            empty_map=dict(),
        )
        request = self.LoadRequestForm(**fields)
        attachments = mailer.get_attachments(fields, request)
        self.assertEqual(1, len(attachments))
        self.assertIn(
            u"Content-Type: application/xml\nMIME-Version: 1.0\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment",
            mailer.get_mail_text(fields, request, context),
        )
        name, mime, enc, xml = attachments[0]
        output_nodes = (
            b'<field name="replyto">[email protected]</field>',
            b'<field name="topic">test subject</field>',
            b'<field name="richtext">Raw</field>',
            b'<field name="comments">test comments\xf0\x9f\x98\x80</field>',
            b'<field name="datetime">2019/04/01, 00:00:00</field>',
            b'<field name="date">2019/04/02</field>',
            b'<field name="delta">1 day, 0:00:00</field>',
            b'<field name="bool">True</field>',
            b'<field name="number">1981</field>',
            b'<field name="floating">3.14</field>',
            b'<field name="tuple">["elemenet1", "element2"]</field>',
            b'<field name="list">["1", "2", "3", "4"]</field>',
            b'<field name="map">{"fruit": "apple"}</field>',
            b'<field name="empty_string" />',
            b'<field name="zero_value">0</field>',
            b'<field name="none_value" />',
            b'<field name="empty_tuple">[]</field>',
            b'<field name="empty_list">[]</field>',
            b'<field name="empty_set">[]</field>',
            b'<field name="empty_map">{}</field>',
        )

        self.assertIn(b"<?xml version='1.0' encoding='utf-8'?>\n<form>", xml)

        # the order of the nodes can change ... check each line
        for node in output_nodes:
            self.assertIn(node, xml)

        # the order of ["A", "B"] can change ... check separately
        self.assertIn(b'"A"', xml)
        self.assertIn(b'"B"', xml)
예제 #3
0
 def testTransformNone(self):
     from plone.app.textfield.value import RichTextValue
     value = RichTextValue()
     # Mostly, these calls simply should not give an error.
     self.assertEquals(None, value.raw)
     self.assertEquals(u'', value.output)
예제 #4
0
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        utils._send_emails = False
        try:

            en_folder = self.context.restrictedTraverse('en')
            if 'organisations' in en_folder:
                org_folder = en_folder.restrictedTraverse('organisations')
            else:
                org_folder = content.create(
                    en_folder,
                    type='osha.hwccontent.organisationfolder',
                    title='Organisations')
            if 'focalpoints' in en_folder:
                fop_folder = en_folder.restrictedTraverse('focalpoints')
            else:
                fop_folder = content.create(
                    en_folder,
                    type='osha.hwccontent.organisationfolder',
                    title='Focalpoints')

            type_mapping = {
                u'Organisation': {
                    'type': 'osha.hwccontent.organisation',
                    'schema': dict(getFieldsInOrder(IOrganisation)),
                    'folder': org_folder,
                    'wf_actions': ('approve_phase_1', ),
                },
                u'Focalpoint': {
                    'type': 'osha.hwccontent.focalpoint',
                    'schema': dict(getFieldsInOrder(IFocalPoint)),
                    'folder': fop_folder,
                    'wf_actions': ('publish', ),
                }
            }

            count = 0
            for data in json.loads(data['json']):

                # Only keep the data that's in the main schema:
                type_info = type_mapping[data['_type']]
                schema = type_info['schema']
                fields = {}

                if data['title'].startswith('MC-'):
                    continue

                for name, field in schema.items():
                    if name in data:
                        value = data[name]
                        if value and INamedImageField.providedBy(field):
                            content_type = data.get('_%s_content_type' % name,
                                                    '')
                            filename = data.get('_%s_filename' % name, None)
                            value = NamedBlobImage(base64.b64decode(value),
                                                   str(content_type), filename)
                        elif value and IRichText.providedBy(field):
                            content_type = data.get('_%s_content_type', None)
                            value = RichTextValue(value, mimeType=content_type)
                        elif name.find("email") >= 0:
                            value = value.strip()

                        fields[name] = value

                new_obj = content.create(container=type_info['folder'],
                                         type=type_info['type'],
                                         id=data['id'],
                                         **fields)
                for transition in type_info['wf_actions']:
                    try:
                        content.transition(new_obj, transition)
                    except Exception:
                        logger.exception(
                            'Could not execute %s transition for %s' %
                            (transition, '/'.join(new_obj.getPhysicalPath())))

                logger.info('Imported %s' % new_obj.getId())
                count += 1

            # Set status on this form page
            self.status = "%s partners imported" % count
        except Exception:
            # Enable emails again:
            utils._send_emails = True
            raise
예제 #5
0
 def _create_page(self, _id='test-snippet', title='Test Snippet', text='<p>foobar</p>'):
     page = api.content.create(type='Document', id=_id, title=title,
                               container=self.portal,
                               text=RichTextValue(text, 'text/html', 'text/html'))
     return page
예제 #6
0
def encode_after_json(value):
    """ Is the opposite of decode_for_json
    """
    # there should not be any encoded strings
    if isinstance(value, str):
        value = unicode(value)

    # unicode
    if isinstance(value, unicode):
        encoding, nval = unicode(value).split(':', 1)
        if encoding == u'unicode':
            return nval

        else:
            return nval.encode(encoding)

    # list, tuple, set
    elif isinstance(value, list):
        new_value = map(encode_after_json, value)
        if len(new_value) == 2 and new_value[0] == 'tuple':
            return tuple(new_value[1])
        elif len(new_value) == 2 and new_value[0] == 'set':
            return set(new_value[1])
        elif len(new_value) == 2 and new_value[0] == 'PersistentList':
            return PersistentList(new_value[1])
        elif len(new_value) == 2 and new_value[0] == 'PersistentMapping':
            return PersistentMapping(new_value[1])
        else:
            return new_value

    # OOBTree
    elif isinstance(value, dict) and \
            value.get('utf8:publisher-wrapper', False) \
            and value.get('utf8:type', None) == 'utf8:OOBTree':
        return OOBTree(value.get('utf8:value'))

    # PortletAssignmentSettings
    elif isinstance(value, dict) and \
            value.get('utf8:publisher-wrapper', False) \
            and value.get('utf8:type', None) == \
            'utf8:PortletAssignmentSettings':
        settings = PortletAssignmentSettings()
        for key, val in value.get('utf8:value').items():
            settings[key] = val
        return settings

    # python datetime
    elif isinstance(value, dict) and \
            value.get('publisher-wrapper', False) \
            and value.get('type', None) == 'datetime':
        if value['tzinfo']:
            tzinfo = timezone(value['tzinfo'])
        else:
            tzinfo = None
        return datetime(*value['timetuple'], tzinfo=tzinfo)

    # zope datetime
    elif isinstance(value, dict) and \
            value.get('publisher-wrapper', False) \
            and value.get('type', None) == 'DateTime':
        return DateTime(value.get('value'))

    # RichTextValue
    elif isinstance(value, dict) and value.get('utf8:publisher-wrapper', False) \
            and value.get('utf8:type', None) == 'utf8:RichTextValue':
        return RichTextValue(**encode_after_json(value['utf8:value']))

    # RelationValue
    elif isinstance(value, dict) and value.get('utf8:publisher-wrapper', False) \
            and value.get('utf8:type', None) == 'utf8:RelationValue':

        data = encode_after_json(value['utf8:data'])

        obj = get_obj_by_relative_path(data['to_path'])
        if not obj:
            # The target object does not exist on the receiver side.
            # We cannot make a relation at this point.
            return None

        rel = create_relation_for(obj)
        rel.from_attribute = data['from_attribute']

        return rel

    # dicts
    elif isinstance(value, dict):
        nval = {}
        for key, sval in value.items():
            key = encode_after_json(key)
            sval = encode_after_json(sval)
            nval[key] = sval
        return nval

    # other types
    else:
        return value
예제 #7
0
def set_text(obj):
    if IDexterityContent.providedBy(obj):
        obj.text = RichTextValue(LOREMIPSUM_HTML_10_PARAGRAPHS, 'text/html',
                                 'text/x-html-safe')
    else:
        obj.setText(LOREMIPSUM_HTML_10_PARAGRAPHS)
예제 #8
0
 def test_parseField_value_is_not_none(self):
     value = RichTextValue(u'foo')
     diff = CMFDTHtmlDiff(DummyType(value), DummyType(value), 'body')
     self.assertEqual(diff._parseField(value), [u'foo'])
예제 #9
0
    def test_anon_only(self):

        # Add folder content
        setRoles(self.portal, TEST_USER_ID, ('Manager', ))
        self.portal.invokeFactory('Folder', 'f1')
        self.portal['f1'].title = u"Folder one"
        self.portal['f1'].description = u"Folder one description"
        self.portal['f1'].reindexObject()

        # Add page content
        self.portal['f1'].invokeFactory('Document', 'd1')
        self.portal['f1']['d1'].title = u"Document one"
        self.portal['f1']['d1'].description = u"Document one description"
        testText = "Testing... body one"
        self.portal['f1']['d1'].text = RichTextValue(testText, 'text/plain',
                                                     'text/html')
        self.portal['f1']['d1'].reindexObject()

        # Publish the folder and page
        self.portal.portal_workflow.doActionFor(self.portal['f1'], 'publish')
        self.portal.portal_workflow.doActionFor(self.portal['f1']['d1'],
                                                'publish')

        # Set pages to have weak caching and test anonymous

        self.cacheSettings.operationMapping = {
            'plone.content.itemView': 'plone.app.caching.weakCaching'
        }
        transaction.commit()

        # View the page as anonymous
        browser = Browser(self.app)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView',
                         browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching',
                         browser.headers['X-Cache-Operation'])
        self.assertTrue(testText in browser.contents)
        self.assertEqual('max-age=0, must-revalidate, private',
                         browser.headers['Cache-Control'])

        # Set pages to have moderate caching so that we can see the difference
        # between logged in and anonymous

        self.cacheSettings.operationMapping = {
            'plone.content.itemView': 'plone.app.caching.moderateCaching'
        }
        self.registry['plone.app.caching.moderateCaching.smaxage'] = 60
        self.registry['plone.app.caching.moderateCaching.vary'] = 'X-Anonymous'
        self.registry['plone.app.caching.moderateCaching.anonOnly'] = True

        transaction.commit()

        # View the page as anonymous
        browser = Browser(self.app)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView',
                         browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.moderateCaching',
                         browser.headers['X-Cache-Operation'])
        self.assertTrue(testText in browser.contents)
        self.assertEqual('max-age=0, s-maxage=60, must-revalidate',
                         browser.headers['Cache-Control'])
        self.assertEqual('X-Anonymous', browser.headers['Vary'])
        self.assertFalse('Etag' in browser.headers)

        # View the page as logged-in
        browser = Browser(self.app)
        browser.addHeader(
            'Authorization', 'Basic %s:%s' % (
                TEST_USER_NAME,
                TEST_USER_PASSWORD,
            ))
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView',
                         browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.moderateCaching',
                         browser.headers['X-Cache-Operation'])
        self.assertTrue(testText in browser.contents)
        self.assertEqual('max-age=0, must-revalidate, private',
                         browser.headers['Cache-Control'])
        self.assertTrue('Etag' in browser.headers)

        # Set pages to have strong caching so that we can see the difference
        # between logged in and anonymous

        self.cacheSettings.operationMapping = {
            'plone.content.itemView': 'plone.app.caching.strongCaching'
        }
        self.registry['plone.app.caching.strongCaching.vary'] = 'X-Anonymous'
        self.registry['plone.app.caching.strongCaching.anonOnly'] = True
        transaction.commit()

        # View the page as anonymous
        browser = Browser(self.app)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView',
                         browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.strongCaching',
                         browser.headers['X-Cache-Operation'])
        self.assertTrue(testText in browser.contents)
        self.assertEqual('max-age=86400, proxy-revalidate, public',
                         browser.headers['Cache-Control'])
        self.assertEqual('X-Anonymous', browser.headers['Vary'])
        self.assertFalse('Etag' in browser.headers)

        # View the page as logged-in
        browser = Browser(self.app)
        browser.addHeader(
            'Authorization', 'Basic %s:%s' % (
                TEST_USER_NAME,
                TEST_USER_PASSWORD,
            ))
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView',
                         browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.strongCaching',
                         browser.headers['X-Cache-Operation'])
        self.assertTrue(testText in browser.contents)
        self.assertEqual('max-age=0, must-revalidate, private',
                         browser.headers['Cache-Control'])
        self.assertTrue('Etag' in browser.headers)

        # Check an edge case that has had a problem in the past:
        # setting strongCaching maxage to zero.

        self.registry['plone.app.caching.strongCaching.maxage'] = 0
        self.registry['plone.app.caching.strongCaching.smaxage'] = 60
        transaction.commit()

        # View the page as anonymous
        browser = Browser(self.app)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('max-age=0, s-maxage=60, must-revalidate',
                         browser.headers['Cache-Control'])
예제 #10
0
def add_resolveuid(context):

    story_brains = api.content.find(portal_type="story")
    count = 0
    for brain in story_brains:
        story = brain.getObject()

        # A broken text field contains an <img> tag with class="image-inline caption" \
        # and src attribute does not contain 'resolveuid'
        #example: <p><img src="200803-PH-covid-inside.jpg" class="image-inline captioned" /></p>
        if story.text is None:
            continue

        soup = BeautifulSoup(story.text.raw, "html.parser")
        images = soup.findAll('img', class_="image-inline")
        changed = False
        story_path = '/'.join(story.getPhysicalPath())
        logger.info(f"processing {story_path}")
        for image in images:
            if 'resolveuid' not in image['src']:
                #we found a broken one.
                #get uid of image:

                #handle image scale - ex: 'foo.jpeg/@@images/image/thumb'
                image_split = image['src'].split('@@images')
                image_id = image_split[0]
                if len(image_split) > 1:
                    image_scale = image_split[1]
                else:
                    image_scale = None

                try:
                    image_object = context.unrestrictedTraverse(story_path +
                                                                '/' + image_id)
                except zExceptions.NotFound:
                    logger.warning("couldn't find image: " + story_path + '/' +
                                   image_id)
                    continue
                except KeyError:
                    logger.warning(f"image doesn't exist: {image_id}")
                    continue
                except IndexError:  #string index out of range
                    logger.warning(f"Couldn't fix image at: " + story_path +
                                   '/' + image_id)
                    #Honestly don't know why this happens
                    continue

                uuid = IUUID(image_object)
                #replace <img> src with 'resolveuid/{uuid}'
                if image_scale is not None:
                    image['src'] = f'resolveuid/{uuid}/@@images/{image_scale}'
                else:
                    image['src'] = f'resolveuid/{uuid}'
                changed = True

        if changed:
            count = count + 1
            new = RichTextValue(str(soup), story.text.mimeType,
                                story.text.outputMimeType)
            story.text = new
            logger.info("fixed " + '/'.join(story.getPhysicalPath()))

        if count >= 100:
            transaction.commit()
            count = 0

    transaction.commit()
    logger.info("Done")
예제 #11
0
def workspaces_spec(context):
    now = localized_now()
    budget_proposal_filename = u'budget-proposal.png'
    budget_proposal_path = os.path.join('images', budget_proposal_filename)
    budget_proposal_img = NamedBlobImage(
        data=context.openDataFile(budget_proposal_path).read(),
        filename=budget_proposal_filename)
    minutes_filename = u'minutes.docx'
    minutes_path = os.path.join('files', minutes_filename)
    minutes_file = NamedBlobImage(
        data=context.openDataFile(minutes_path).read(),
        filename=minutes_filename)

    tomorrow = (now + timedelta(days=1)).replace(hour=9,
                                                 minute=0,
                                                 second=0,
                                                 microsecond=0)
    next_month = (now + timedelta(days=30)).replace(hour=9,
                                                    minute=0,
                                                    second=0,
                                                    microsecond=0)

    # Create workspaces
    workspaces = [
        {
            'title':
            'Open Market Committee',
            'description':
            'The OMC holds eight regularly scheduled meetings '
            'during the year and other meetings as needed.',
            'transition':
            'make_private',
            'participant_policy':
            'publishers',
            'members': {
                'allan_neece': [u'Members'],
                'christian_stoney': [u'Admins', u'Members'],
                'neil_wichmann': [u'Members'],
                'francois_gast': [u'Members'],
                'jamie_jacko': [u'Members'],
                'jesse_shaik': [u'Members'],
                'jorge_primavera': [u'Members'],
                'silvio_depaoli': [u'Members'],
                'lance_stockstill': [u'Members'],
                'pearlie_whitby': [u'Members'],
                'dollie_nocera': [u'Members'],
                'esmeralda_claassen': [u'Members'],
                'rosalinda_roache': [u'Members'],
                'guy_hackey': [u'Members'],
            },
            'contents': [{
                'title':
                'Manage Information',
                'type':
                'Folder',
                'contents': [
                    {
                        'title': 'Preparation of Records',
                        'description': 'How to prepare records',
                        'state': 'published',
                        'subject': 'Read carefully',
                        'type': 'File',
                    },
                    {
                        'title':
                        'Public bodies reform',
                        'description':
                        'Making arrangements for the transfer of '
                        'information, records and knowledge is a '
                        'key part of any Machinery of Government '
                        'change.',
                        'type':
                        'Document',
                        'state':
                        'published'
                    },
                    {
                        'title':
                        'Repurchase Agreements',
                        'description':
                        'A staff presentation outlined several '
                        'approaches to raising shortterm interest '
                        'rates when it becomes appropriate to do '
                        'so, and to controlling the level of '
                        'short-term interest rates ',
                        'owner':
                        'allan_neece',
                        'type':
                        'Document'
                    },
                    {
                        'title':
                        u'Budget Proposal',
                        'description':
                        (u'A diagram of the factors impacting the budget and '
                         u'results'),
                        'owner':
                        'allan_neece',
                        'image':
                        budget_proposal_img,
                        'type':
                        'Image',
                    },
                    {
                        'title': u'Minutes',
                        'owner': 'allan_neece',
                        'description': u'Meeting Minutes',
                        'file': minutes_file,
                        'type': 'File',
                    },
                    {
                        'title': u'Minutes Overview',
                        'owner': 'allan_neece',
                        'description': u'Meeting Minutes Overview',
                        'type': 'Document',
                        'modification_date': now - timedelta(days=60),
                    },
                    {
                        'title': 'Open Market Day',
                        'type': 'Event',
                        'state': 'published',
                        'start': tomorrow,
                        'end': tomorrow + timedelta(hours=8)
                    },
                    {
                        'title': 'Plone Conf',
                        'type': 'Event',
                        'state': 'published',
                        'start': next_month,
                        'end': next_month + timedelta(days=3, hours=8)
                    },
                    {
                        'title': "Yesterday's gone",
                        'type': 'Event',
                        'state': 'published',
                        'owner': 'allan_neece',
                        'start': tomorrow - timedelta(days=3),
                        'end': tomorrow - timedelta(days=2)
                    },
                ]
            }, {
                'title':
                'Projection Materials',
                'type':
                'Folder',
                'contents': [{
                    'title': 'Projection Material',
                    'type': 'File'
                }]
            }, {
                'title': 'Future Event',
                'type': 'Event',
                'start': now + timedelta(days=7),
                'end': now + timedelta(days=14)
            }, {
                'title': 'Past Event',
                'type': 'Event',
                'start': now + timedelta(days=-7),
                'end': now + timedelta(days=-14)
            }, {
                'title':
                'Files for application 2837',
                'type':
                'ploneintranet.workspace.mail',
                'mail_from':
                u'*****@*****.**',
                'mail_to': (
                    u'*****@*****.**',
                    u'*****@*****.**',
                ),
                'mail_body':
                RichTextValue(u'''
                    <p>Dear mister Kolbach,</p>
                    <p>We’ll process your application with the shortest
                     delay.</p>
                    <p>Yours sincerely, <br>
                    Alexander Pilz</p>

                    <blockquote>
                      <p>Dear Sir or Madam,</p>

                      <p>Sed ut perspiciatis unde omnis iste natus error
                      sit voluptatem accusantium doloremque laudantium,
                      totam rem aperiam, eaque ipsa quae ab illo inventore
                      veritatis et quasi architecto beatae vitae dicta sunt
                      explicabo.</p>

                      <p>Kind regards,<br>
                    Cornelis G. A. Kolbach</p>
                    </blockquote>
                   '''),
                'contents': [
                    {
                        'title': 'Budget proposal',
                        'type': 'Image',
                        'image': budget_proposal_img,
                    },
                    {
                        'title': u'Minutes',
                        'owner': 'allan_neece',
                        'description': u'Meeting Minutes',
                        'file': minutes_file,
                        'type': 'File',
                    },
                ]
            }],
        },
        {
            'title':
            'Parliamentary papers guidance',
            'description':
            '"Parliamentary paper" is a term used to describe a '
            'document which is laid before Parliament. Most '
            'government organisations will produce at least one '
            'parliamentary paper per year.',
            'transition':
            'make_private',
            'participant_policy':
            'producers',
            'members': {
                'allan_neece': [u'Members'],
                'christian_stoney': [u'Admins', u'Members'],
                'francois_gast': [u'Members'],
                'jamie_jacko': [u'Members'],
                'fernando_poulter': [u'Members'],
                'jesse_shaik': [u'Members'],
                'jorge_primavera': [u'Members'],
                'silvio_depaoli': [u'Members'],
                'kurt_weissman': [u'Members'],
                'esmeralda_claassen': [u'Members'],
                'rosalinda_roache': [u'Members'],
                'guy_hackey': [u'Members'],
            },
            'contents': [{
                'title': 'Test Document',
                'description': 'A document just for testing',
                'type': 'Document'
            }]
        },
        {
            'title':
            u'Shareholder information',
            'description':
            u'"Shareholder information" contains all documents, '
            u'papers and diagrams for keeping shareholders informed about the '
            u'current state of affairs.',
            'transition':
            'make_private',
            'participant_policy':
            'consumers',
            'members': {
                'allan_neece': [u'Members'],
                'christian_stoney': [u'Admins', u'Members'],
                'francois_gast': [u'Members'],
                'jamie_jacko': [u'Members'],
                'fernando_poulter': [u'Members'],
                'jesse_shaik': [u'Members'],
                'jorge_primavera': [u'Members'],
                'silvio_depaoli': [u'Members'],
                'kurt_weissman': [u'Members'],
                'esmeralda_claassen': [u'Members'],
                'rosalinda_roache': [u'Members'],
                'guy_hackey': [u'Members'],
            },
            'contents': [{
                'title': 'Test Document',
                'description': 'A document just for testing',
                'type': 'Document',
                'state': 'published'
            }]
        },
        {
            'title':
            u'Service announcements',
            'description':
            u'Public service announcements can be found here.',
            'transition':
            'make_open',
            'participant_policy':
            'consumers',
            'members': {
                'allan_neece': [u'Members'],
                'christian_stoney': [u'Admins', u'Members'],
                'francois_gast': [u'Members'],
                'jamie_jacko': [u'Members'],
                'fernando_poulter': [u'Members'],
                'jesse_shaik': [u'Members'],
                'jorge_primavera': [u'Members'],
                'silvio_depaoli': [u'Members'],
                'kurt_weissman': [u'Members'],
                'esmeralda_claassen': [u'Members'],
                'rosalinda_roache': [u'Members'],
                'guy_hackey': [u'Members'],
            },
            'contents': [
                {
                    'title': 'Terms and conditions',
                    'description': 'A document just for testing',
                    'type': 'Document',
                    'state': 'published'
                },
                {
                    'title': 'Customer satisfaction survey',
                    'description': 'A private document',
                    'type': 'Document'
                },
            ]
        },
    ]
    return workspaces
예제 #12
0
    def addMail(self, mailString):
        """ Store mail as news item
            Returns created item
        """

        pw = self.context.portal_workflow

        (header, body) = splitMail(mailString)

        # if 'keepdate' is set, get date from mail,
        # XXX 'time' is unused
        if self.getValueFor('keepdate'):
            timetuple = rfc822.parsedate_tz(header.get('date'))
            time = DateTime(rfc822.mktime_tz(timetuple))
        # ... take our own date, clients are always lying!
        else:
            time = DateTime()

        (TextBody, ContentType, HtmlBody, Attachments) = unpackMail(mailString)

        # Test Zeitangabe hinter Subject
        today = date.today()
        mydate = today.strftime("%d.%m.%Y")

        # let's create the news item

        subject = mime_decode_header(header.get('subject', 'No Subject'))
        sender = mime_decode_header(header.get('from', 'No From'))
        title = "%s" % (subject)

        new_id = IUserPreferredURLNormalizer(self.request).normalize(title)
        id = self._findUniqueId(new_id)
        # ContentType is only set for the TextBody
        if ContentType:
            body = TextBody
        else:
            body = self.HtmlToText(HtmlBody)

        # XXX als vorlaeufige Loesung
        from zope.component import getMultiAdapter
        plone_view = getMultiAdapter((self.context, self.request),
                                     name='plone')
        desc = plone_view.cropText(body, 60)
        body = '\n'.join([wrap_line(line) for line in body.splitlines()])
        uni_aktuell_body = ("<p><strong>%s: %s</strong></p> "
                            "<p>&nbsp;</p><pre>%s</pre>" %
                            (mydate, sender, body))

        objid = self.context.invokeFactory(
            'News Item',
            id=id,
            title=title,
            text=RichTextValue(uni_aktuell_body),
            description=desc,
        )

        mailObject = getattr(self.context, objid)
        images = [
            att for att in Attachments
            if att['maintype'] == 'image' and att['filename']
        ]
        if images and hasattr(mailObject, 'image'):
            image = Attachments[0]
            mailObject.image = NamedBlobImage(
                filename=safe_unicode(image['filename']),
                data=image['filebody'],
            )
        try:
            pw.doActionFor(mailObject, 'publish')
        except Exception as e:
            log.exception(e)
        return mailObject
예제 #13
0
 def test_GetSpecificAssemblyFor(self):
     """
         This method aimed to ease printings should return formated assembly
     """
     self.changeUser('pmManager')
     m1 = self._createMeetingWithItems()
     m1.assembly = RichTextValue(
         'Pierre Dupont - Bourgmestre,\n'
         'Charles Exemple - 1er Echevin,\n'
         'Echevin Un, Echevin Deux, Echevin Trois - Echevins,\n'
         'Jacqueline Exemple, Responsable du CPAS')
     attendee = '<p class="mltAssembly">Pierre Dupont - Bourgmestre,<br />' \
                'Charles Exemple - 1er Echevin,<br />Echevin Un, Echevin Deux, ' \
                'Echevin Trois - Echevins,<br />Jacqueline Exemple, Responsable du CPAS</p>'
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='')[0],
         attendee)
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Absent'), '')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Excus'), '')
     m1.assembly = RichTextValue(
         'Pierre Dupont - Bourgmestre,\n'
         'Charles Exemple - 1er Echevin,\n'
         'Echevin Un, Echevin Deux, Echevin Trois - Echevins,\n'
         'Jacqueline Exemple, Responsable du CPAS \n'
         'Excusés: \n '
         'Monsieur x, Mesdames Y et Z')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='')[0],
         attendee)
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Absent'), '')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Excus')[0],
         'Excusés:')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Excus')[1],
         '<p class="mltAssembly">Monsieur x, Mesdames Y et Z</p>')
     m1.assembly = RichTextValue(
         'Pierre Dupont - Bourgmestre,\n'
         'Charles Exemple - 1er Echevin,\n'
         'Echevin Un, Echevin Deux, Echevin Trois - Echevins,\n'
         'Jacqueline Exemple, Responsable du CPAS \n'
         'Absent: \n '
         'Monsieur tartenpion \n'
         'Excusés: \n '
         'Monsieur x, Mesdames Y et Z')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='')[0],
         attendee)
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Absent')[0],
         'Absent:')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Absent')[1],
         '<p class="mltAssembly">Monsieur tartenpion</p>')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Excus')[0],
         'Excusés:')
     self.assertEqual(
         self.tool.adapted().getSpecificAssemblyFor(m1.get_assembly(),
                                                    startTxt='Excus')[1],
         '<p class="mltAssembly">Monsieur x, Mesdames Y et Z</p>')
예제 #14
0
 def set(self, instance, value, **kw):
     from plone.app.textfield.value import RichTextValue
     value = RichTextValue(raw=value,
                           outputMimeType=self.field.output_mime_type)
     return self._set(instance, value, **kw)
예제 #15
0
    def setUp(self):
        """Construct sample contents.

        These are all events:

        'Long Event: 2013-04-25T10:00:00+02:00 - 2013-06-04T10:00:00+02:00'

        'Past Event: 2013-04-25T00:00:00+02:00 - 2013-04-25T23:59:59+02:00'
        'Past Event: 2013-04-26T00:00:00+02:00 - 2013-04-26T23:59:59+02:00'
        'Past Event: 2013-04-27T00:00:00+02:00 - 2013-04-27T23:59:59+02:00'

        'Now Event: 2013-05-05T10:00:00+02:00 - 2013-05-05T11:00:00+02:00'
        'Now Event: 2013-05-07T10:00:00+02:00 - 2013-05-07T11:00:00+02:00'
        'Now Event: 2013-05-09T10:00:00+02:00 - 2013-05-09T11:00:00+02:00'

        'Future Event: 2013-05-15T10:00:00+02:00 - 2013-05-15T11:00:00+02:00'

        """
        self.portal = self.layer['portal']
        self.app = self.layer['app']
        self.request = self.layer['request']
        set_browserlayer(self.request)
        set_timezone(TEST_TIMEZONE)

        now, past, future, far, duration = self.make_dates()
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        workflow = getToolByName(self.portal, 'portal_workflow')
        workflow.setDefaultChain("simple_publication_workflow")

        factory = self.event_factory
        self.past_event = factory(container=self.portal,
                                  id='past',
                                  title=u'Past Event',
                                  start=past,
                                  end=past + duration,
                                  location=u"Vienna",
                                  whole_day=True,
                                  recurrence='RRULE:FREQ=DAILY;COUNT=3')
        workflow.doActionFor(self.past_event, 'publish')
        # adjust start and end according to whole_day and open_end
        self.past_event.reindexObject()

        self.now_event = factory(
            container=self.portal,
            id='now',
            title=u'Now Event',
            start=now,
            end=now + duration,
            location=u"Vienna",
            recurrence="""RRULE:FREQ=DAILY;COUNT=3;INTERVAL=1
RDATE:20130509T000000
EXDATE:20130506T000000,20140404T000000""",
            contact_name='Auto Testdriver',
            contact_email='*****@*****.**',
            contact_phone='+123456789',
            event_url='http://plone.org',
            subject=('plone', 'testing'))  # change to subjects, once this is
        # fixed:
        # https://github.com/plone/plone.dexterity/pull/18
        # https://github.com/plone/plone.app.dexterity/issues/118
        workflow.doActionFor(self.now_event, 'publish')
        self.now_event.reindexObject()

        self.future_event = factory(
            container=self.portal,
            id='future',
            title=u'Future Event',
            text=RichTextValue(
                u'Überraschung! Du kannst nach mir suchen',
                'text/plain',
                'text/html',
            ),
            start=future,
            end=future + duration,
            location=u'Graz')
        workflow.doActionFor(self.future_event, 'publish')
        self.future_event.reindexObject()

        self.portal.invokeFactory('Folder', 'sub', title=u'sub')
        self.long_event = factory(container=self.portal.sub,
                                  id='long',
                                  title=u'Long Event',
                                  start=past,
                                  end=far,
                                  location=u'Schaftal')
        workflow.doActionFor(self.long_event, 'publish')
        self.long_event.reindexObject()

        # plone.app.contenttypes ICollection type
        self.portal.invokeFactory('Collection', 'collection', title=u'Col')
        collection = self.portal.collection
        collection.sort_on = u'start'
        collection.reverse_sort = True
        collection.query = [
            {
                'i': 'portal_type',
                'o': 'plone.app.querystring.operation.selection.any',
                'v': ['Event', 'plone.app.event.dx.event']
            },
        ]
        collection.reindexObject()
예제 #16
0
    def test_composite_views(self):

        catalog = self.portal['portal_catalog']
        default_skin = self.portal['portal_skins'].default_skin

        # Add folder content
        setRoles(self.portal, TEST_USER_ID, ('Manager',))
        self.portal.invokeFactory('Folder', 'f1')
        self.portal['f1'].title = u"Folder one"
        self.portal['f1'].description = u"Folder one description"
        self.portal['f1'].reindexObject()

        # Add page content
        self.portal['f1'].invokeFactory('Document', 'd1')
        self.portal['f1']['d1'].title = u"Document one"
        self.portal['f1']['d1'].description = u"Document one description"
        testText = "Testing... body one"
        self.portal['f1']['d1'].text = RichTextValue(
            testText,
            'text/plain',
            'text/html'
        )
        self.portal['f1']['d1'].reindexObject()

        # Publish the folder and page
        self.portal.portal_workflow.doActionFor(self.portal['f1'], 'publish')
        self.portal.portal_workflow.doActionFor(self.portal['f1']['d1'], 'publish')

        # Should we set up the etag components?
        # - set member?  No
        # - reset catalog counter?  Maybe
        # - set server language?
        # - turn on gzip?
        # - set skin?  Maybe
        # - leave status unlocked
        # - set the mod date on the resource registries?  Probably.

        import transaction; transaction.commit()

        # Request the quthenticated folder
        now = stable_now()
        browser = Browser(self.app)
        browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
        browser.open(self.portal['f1'].absolute_url())
        self.assertEqual('plone.content.folderView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        # This should use cacheInBrowser
        self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control'])
        self.assertEqual('"|test_user_1_|%d|en|0|%s|0|0' % (catalog.getCounter(), default_skin), _normalize_etag(browser.headers['ETag']))
        self.assertTrue(now > dateutil.parser.parse(browser.headers['Expires']))

        # Set the copy/cut cookie and then request the folder view again
        browser.cookies.create('__cp', 'xxx')
        browser.open(self.portal['f1'].absolute_url())
        # The response should be the same as before except for the etag
        self.assertEqual('plone.content.folderView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control'])
        self.assertEqual('"|test_user_1_|%d|en|0|%s|0|1' % (catalog.getCounter(), default_skin), _normalize_etag(browser.headers['ETag']))

        # Request the authenticated page
        now = stable_now()
        browser = Browser(self.app)
        browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertTrue(testText in browser.contents)
        self.assertEqual('plone.content.itemView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        # This should use cacheInBrowser
        self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control'])
        self.assertEqual('"|test_user_1_|%d|en|0|%s|0' % (catalog.getCounter(), default_skin), _normalize_etag(browser.headers['ETag']))
        self.assertTrue(now > dateutil.parser.parse(browser.headers['Expires']))

        # Request the authenticated page again -- to test RAM cache.
        browser = Browser(self.app)
        browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        # Authenticated should NOT be RAM cached
        self.assertEqual(None, browser.headers.get('X-RAMCache'))

        # Request the authenticated page again -- with an INM header to test 304
        etag = browser.headers['ETag']
        browser = Browser(self.app)
        browser.raiseHttpErrors = False  # we really do want to see the 304
        browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
        browser.addHeader('If-None-Match', etag)
        browser.open(self.portal['f1']['d1'].absolute_url())
        # This should be a 304 response
        self.assertEqual('304 Not Modified', browser.headers['Status'])
        self.assertEqual('', browser.contents)

        # Request the anonymous folder
        now = stable_now()
        browser = Browser(self.app)
        browser.open(self.portal['f1'].absolute_url())
        self.assertEqual('plone.content.folderView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        # This should use cacheInBrowser
        self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control'])
        self.assertEqual('"||%d|en|0|%s|0|0'  % (catalog.getCounter(), default_skin), _normalize_etag(browser.headers['ETag']))
        self.assertTrue(now > dateutil.parser.parse(browser.headers['Expires']))

        # Request the anonymous page
        now = stable_now()
        browser = Browser(self.app)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        self.assertTrue(testText in browser.contents)
        # This should use cacheInBrowser
        self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control'])
        self.assertEqual('"||%d|en|0|%s|0' % (catalog.getCounter(), default_skin), _normalize_etag(browser.headers['ETag']))
        self.assertTrue(now > dateutil.parser.parse(browser.headers['Expires']))

        # Request the anonymous page again -- to test RAM cache.
        # Anonymous should be RAM cached
        now = stable_now()
        browser = Browser(self.app)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        # This should come from RAM cache
        self.assertEqual('plone.app.caching.operations.ramcache', browser.headers['X-RAMCache'])
        self.assertTrue(testText in browser.contents)
        self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control'])
        self.assertEqual('"||%d|en|0|%s|0'% (catalog.getCounter(), default_skin), _normalize_etag(browser.headers['ETag']))
        self.assertTrue(now > dateutil.parser.parse(browser.headers['Expires']))

        # Request the anonymous page again -- with an INM header to test 304.
        etag = browser.headers['ETag']
        browser = Browser(self.app)
        browser.raiseHttpErrors = False
        browser.addHeader('If-None-Match', etag)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        # This should be a 304 response
        self.assertEqual('304 Not Modified', browser.headers['Status'])
        self.assertEqual('', browser.contents)

        # Edit the page to update the etag
        testText2 = "Testing... body two"
        self.portal['f1']['d1'].text = RichTextValue(
            testText2,
            'text/plain',
            'text/html'
        )
        self.portal['f1']['d1'].reindexObject()

        transaction.commit()

        # Request the anonymous page again -- to test expiration of 304 and RAM.
        etag = browser.headers['ETag']
        browser = Browser(self.app)
        browser.addHeader('If-None-Match', etag)
        browser.open(self.portal['f1']['d1'].absolute_url())
        self.assertEqual('plone.content.itemView', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.weakCaching', browser.headers['X-Cache-Operation'])
        # The etag has changed so we should get a fresh page.
        self.assertEqual(None, browser.headers.get('X-RAMCache'))
        self.assertEqual('200 Ok', browser.headers['Status'])
예제 #17
0
    def __call__(self):
        request = self.request
        courseUID = request.form.get('id', '')
        course = api.content.find(portal_type='Course',
                                  UID=courseUID,
                                  sort_on='getObjPositionInParent')
        if len(course) == 1:
            teacher_uid = self.request.cookies.get("teacher_login", "")
            teacher = api.content.get(UID=teacher_uid)
            if not teacher:
                return self.request.response.redirect(
                    '{}/teacher-area/teacher-login'.format(
                        self.context.portal_url()))
            self.teacher = teacher

            self.course = course[0]
            if self.course.course_teacher != self.teacher.UID():
                return self.request.response.redirect(
                    '{}/teacher-area/teacher-area'.format(
                        self.context.portal_url()))

            prepareUIDList = [item.UID for item in self.getPrepare()]
            if request.form.has_key('file-upload-widget'):
                course_outline = request.get('course_outline', '')
                if course_outline:
                    alsoProvides(self.request, IDisableCSRFProtection)
                    self.course.getObject().course_outline = RichTextValue(
                        course_outline)
                for uid in prepareUIDList:
                    item = api.content.get(UID=uid)
                    url = item.absolute_url()
                    upload_file = request.form['file-' + uid]
                    upload_text = request.form['text-' + uid]
                    headers = {
                        'Accept': "application/json",
                        'Content-Type': "application/json",
                        'Authorization': "Basic YWRtaW46MTIzNDU2",
                    }
                    data = {"description": upload_text}

                    file_data = upload_file.read()
                    if file_data:
                        data.update(
                            { \
                                "file": { \
                                "content-type": upload_file.headers['content-type'], \
                                "filename": upload_file.filename, \
                                "encoding": "base64", \
                                "data": file_data.encode('base64') \
                                } \
                            } \
                        )
                    response = requests.request("PATCH",
                                                url,
                                                headers=headers,
                                                json=data)
                self.request.response.redirect(self.request.URL)
            return self.template()
        else:
            return self.request.response.redirect(
                '{}/teacher-area/teacher-area'.format(
                    self.context.portal_url()))
예제 #18
0
    def setUp(self):
        self.app = self.layer["app"]
        self.portal = self.layer["portal"]
        self.portal_url = self.portal.absolute_url()
        self.request = self.portal.REQUEST
        self.catalog = getToolByName(self.portal, "portal_catalog")

        self.api_session = RelativeSession(self.portal_url)
        self.api_session.headers.update({"Accept": "application/json"})
        self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)

        # /plone/folder
        self.folder = createContentInContainer(self.portal,
                                               u"Folder",
                                               id=u"folder",
                                               title=u"Some Folder")

        # /plone/folder/doc
        self.doc = createContentInContainer(
            self.folder,
            u"DXTestDocument",
            id="doc",
            title=u"Lorem Ipsum",
            start=DateTime(1950, 1, 1, 0, 0),
            effective=DateTime(1995, 1, 1, 0, 0),
            expires=DateTime(1999, 1, 1, 0, 0),
            test_int_field=42,
            test_list_field=["Keyword1", "Keyword2", "Keyword3"],
            test_bool_field=True,
            test_richtext_field=RichTextValue(
                raw=u"<p>Some Text</p>",
                mimeType="text/html",
                outputMimeType="text/html",
            ),
        )
        IMutableUUID(self.doc).set("77779ffa110e45afb1ba502f75f77777")
        self.doc.reindexObject()

        # /plone/folder/other-document
        self.doc2 = createContentInContainer(
            self.folder,
            u"DXTestDocument",
            id="other-document",
            title=u"Other Document",
            description=u"\xdcbersicht",
            start=DateTime(1975, 1, 1, 0, 0),
            effective=DateTime(2015, 1, 1, 0, 0),
            expires=DateTime(2020, 1, 1, 0, 0),
            test_list_field=["Keyword2", "Keyword3"],
            test_bool_field=False,
        )

        # /plone/folder2
        self.folder2 = createContentInContainer(self.portal,
                                                u"Folder",
                                                id=u"folder2",
                                                title=u"Another Folder")

        # /plone/folder2/doc
        createContentInContainer(
            self.folder2,
            u"DXTestDocument",
            id="doc",
            title=u"Document in second folder",
            start=DateTime(1975, 1, 1, 0, 0),
            effective=DateTime(2015, 1, 1, 0, 0),
            expires=DateTime(2020, 1, 1, 0, 0),
            test_bool_field=False,
        )

        # /plone/doc-outside-folder
        createContentInContainer(
            self.portal,
            u"DXTestDocument",
            id="doc-outside-folder",
            title=u"Doc outside folder",
        )

        transaction.commit()
예제 #19
0
 def dexterity_save(self, fieldname, text):
     from plone.app.textfield.value import RichTextValue
     value = RichTextValue(text)
     setattr(self.context, fieldname, value)
     return "saved"
예제 #20
0
 def text(self, value):
     self.context.text = RichTextValue(raw=safe_unicode(value))
예제 #21
0
 def text(self, value):
     behavior = IEventSummary(self.context)
     behavior.text = RichTextValue(raw=safe_unicode(value))
예제 #22
0
def creatItem(folder, row, zipFolderName):
    portal = api.portal.get()

    logger.info('Begin Create Content, %s' % safe_unicode(row['title']))
    if row['listPrice'] and row['salePrice'] and row['standardShippingCost']:
        pass
    else:
        logger.error('Lost data, title:%s, please check "listPirce, saleprice, standardShippingCost"' % row['title'])
        message = _(u"Lost data, title:%s, please check 'listPirce, saleprice, standardShippingCost'")
        api.portal.show_message(message=message, request=folder.REQUEST, type='error')
    item = api.content.create(
        type='Product',
        title=row['title'],
        productId=row['productId'],
        description=row['description'],
        productUrl=row['productUrl'],
        inStock=True if row['inStock'].strip().lower() == 'y' else False,
        brand=row['brand'],
        listPrice=int(row['listPrice']),
        salePrice=int(row['salePrice']),
        standardShippingCost=int(row['standardShippingCost']),
        container=portal['products'][folder.id],
    )
    logger.info('Content Created, %s' % safe_unicode(row['title']))

    item.setSubject(tuple(row['subjects'].split(',')))
    if row['image_1'].strip():
        with open('%s/%s' % (zipFolderName, safe_unicode(row['image_1'].strip()))) as file:
            item.image_1 = namedfile.NamedBlobImage(data=file, filename=safe_unicode('%s' % file.name.split('/')[-1]))
    try:
        if row['image_2'].strip():
            with open('%s/%s' % (zipFolderName, safe_unicode(row['image_2'].strip()))) as file:
                item.image_2 = namedfile.NamedBlobImage(data=file, filename=safe_unicode('%s' % file.name.split('/')[-1]))
    except:
        logger.error('creatItem position 1, title:%s' % title)
        pass
    try:
        if row['image_3'].strip():
            with open('%s/%s' % (zipFolderName, safe_unicode(row['image_3'].strip()))) as file:
                item.image_3 = namedfile.NamedBlobImage(data=file, filename=safe_unicode('%s' % file.name.split('/')[-1]))
    except:
        logger.error('creatItem position 2, title:%s' % title)
        pass
    try:
        if row['image_4'].strip():
            with open('%s/%s' % (zipFolderName, safe_unicode(row['image_4'].strip()))) as file:
                item.image_4 = namedfile.NamedBlobImage(data=file, filename=safe_unicode('%s' % file.name.split('/')[-1]))
    except:
        logger.error('creatItem position 3, title:%s' % title)
        pass
    try:
        if row['image_5'].strip():
            with open('%s/%s' % (zipFolderName, safe_unicode(row['image_5'].strip()))) as file:
                item.image_5 = namedfile.NamedBlobImage(data=file, filename=safe_unicode('%s' % file.name.split('/')[-1]))
    except:
        logger.error('creatItem position 4, title:%s' % title)
        pass

    item.promotionalText = RichTextValue(safe_unicode(row['promotionalText']))
    item.reindexObject()
    transaction.commit()
    logger.info('Commit OK, %s' % safe_unicode(row['title']))
예제 #23
0
    'normal',
    'min_allowable_score':
    0,
    'max_allowable_score':
    10,
    'general_help':
    RichTextValue(u"""
<ol>
    <li>First think, then write. It can be helpful to scribble some rough
        ideas on a piece of paper and quietly reflect on whether they make
        sense before starting to type into a screen that is much more formal.
    </li>
    <li>Revise. Do not try to write the perfect text in the first round.
        Rather, plan to go back and revise. Really good texts are rewritten
        several times before they become that good. You are no exception,
        especially if you are just getting started. Revisiting your text after
        some time or having it read by others can work miracles to improve
        your text.
    </li>
    <li>Practical tips for writing in Plone. In the sections of the ResearchVee
        in addition to text you can add a broad range of different types of
        content like tables, images, links, just like on any Plone page you
        write.
    </li>
</ul>"""),
    'assessment_schema':
    RichTextValue(u"""
<p>How well does the solution fulfill the tasks laid out for that section? This
   is a scale that reviewers and instructors and authors use to assess the
   quality of an entry:</p>
<table class="listing">
예제 #24
0
def addDemoData(context):
    ''' '''
    if isNotMeetingCommunesDemoProfile(context):
        return

    site = context.getSite()
    tool = api.portal.get_tool('portal_plonemeeting')
    cfg = tool.objectValues('MeetingConfig')[0]
    wfTool = api.portal.get_tool('portal_workflow')
    pTool = api.portal.get_tool('plone_utils')
    mTool = api.portal.get_tool('portal_membership')
    # first we need to be sure that our IPoneMeetingLayer is set correctly
    # https://dev.plone.org/ticket/11673
    from zope.event import notify
    from zope.traversing.interfaces import BeforeTraverseEvent
    notify(BeforeTraverseEvent(site, site.REQUEST))
    # we will create elements for some users, make sure their personal
    # area is correctly configured
    # first make sure the 'Members' folder exists
    members = mTool.getMembersFolder()
    if members is None:
        _createObjectByType('Folder', site, id='Members')
    mTool.createMemberArea('agentPers')
    mTool.createMemberArea('agentInfo')
    mTool.createMemberArea('agentCompta')
    # create 5 meetings : 2 passed, 1 current and 2 future
    today = datetime.now()
    dates = [
        today - timedelta(days=13), today - timedelta(days=6),
        today + timedelta(days=1), today + timedelta(days=8),
        today + timedelta(days=15)
    ]

    # items dict here : the key is the user we will create the item for
    # we use item templates so content is created for the demo
    items = {
        'agentPers': (
            {
                'templateId': 'template3',
                'title': u'Engagement temporaire d\'un informaticien',
                'budgetRelated': True,
                'review_state': 'validated',
            },
            {
                'templateId': 'template2',
                'title': u'Contrôle médical de Mr Antonio',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
            {
                'templateId': 'template2',
                'title': u'Contrôle médical de Mlle Debbeus',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
            {
                'templateId': 'template2',
                'title': u'Contrôle médical de Mme Hanck',
                'budgetRelated': False,
                'review_state': 'validated',
            },
            {
                'templateId': 'template4',
                'title':
                u'Prestation réduite Mme Untelle, instritutrice maternelle',
                'budgetRelated': False,
                'review_state': 'validated',
            },
        ),
        'agentInfo': (
            {
                'templateId': 'template5',
                'title': u'Achat nouveaux serveurs',
                'budgetRelated': True,
                'review_state': 'validated',
            },
            {
                'templateId': 'template5',
                'title': u'Marché public, contestation entreprise Untelle SA',
                'budgetRelated': False,
                'review_state': 'validated',
            },
        ),
        'agentCompta': (
            {
                'templateId': 'template5',
                'title': u'Présentation budget 2014',
                'budgetRelated': True,
                'review_state': 'validated',
            },
            {
                'templateId': 'template5',
                'title': u'Plainte de Mme Daise, taxe immondice',
                'budgetRelated': False,
                'review_state': 'validated',
            },
            {
                'templateId': 'template5',
                'title': u'Plainte de Mme Uneautre, taxe piscine',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
        ),
        'dgen': (
            {
                'templateId': 'template1',
                'title': u'Tutelle CPAS : point 1 BP du 15 juin',
                'budgetRelated': False,
                'review_state': 'created',
            },
            {
                'templateId': 'template5',
                'title': u'Tutelle CPAS : point 2 BP du 15 juin',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
            {
                'templateId': 'template5',
                'title': u'Tutelle CPAS : point 16 BP du 15 juin',
                'budgetRelated': True,
                'review_state': 'validated',
            },
        ),
    }
    # login as 'dgen'
    mTool.createMemberArea('dgen')

    for cfg in tool.objectValues('MeetingConfig'):
        # cleanMemoize so ToolPloneMeeting.getMeetingConfig returns the correct MeetingConfig
        cleanMemoize(site)
        secrFolder = tool.getPloneMeetingFolder(cfg.getId(), 'dgen')
        # build attendees and signatories passed to Meeting._doUpdateContacts
        # attendees OrderedDict([('uid1', 'attendee'), ('uid2', 'attendee'), ('uid3', 'absent')])
        # signatories {'uid1': '1'}
        attendees = OrderedDict()
        signatories = {}
        for hp_uid in cfg.getOrderedContacts():
            attendees[hp_uid] = 'attendee'
        signatories = {attendees.keys()[1]: '1', attendees.keys()[0]: '2'}
        # create meetings
        for date in dates:
            meetingId = secrFolder.invokeFactory(cfg.getMeetingTypeName(),
                                                 id=date.strftime('%Y%m%d'),
                                                 date=date)
            meeting = getattr(secrFolder, meetingId)
            pTool.changeOwnershipOf(meeting, 'dgen')
            meeting._do_update_contacts(attendees=attendees,
                                        signatories=signatories)
            # -13 meeting is closed
            if date == today - timedelta(days=13):
                wfTool.doActionFor(meeting, 'freeze')
                wfTool.doActionFor(meeting, 'decide')
                wfTool.doActionFor(meeting, 'close')
            # -6 meeting is frozen
            if date == today - timedelta(days=6):
                wfTool.doActionFor(meeting, 'freeze')
                wfTool.doActionFor(meeting, 'decide')
            meeting.reindexObject()

            for item in meeting.get_items():
                pTool.changeOwnershipOf(item, 'dgen')

        # create items
        for userId in items:
            userFolder = tool.getPloneMeetingFolder(cfg.getId(), userId)
            for item in items[userId]:
                # get the template then clone it
                template = getattr(
                    tool.getMeetingConfig(userFolder).itemtemplates,
                    item['templateId'])
                with api.env.adopt_user(username=userId):
                    tool.invalidateAllCache()
                    newItem = template.clone(
                        newOwnerId=userId,
                        destFolder=userFolder,
                        newPortalType=cfg.getItemTypeName())
                    newItem.setTitle(item['title'])
                    newItem.setBudgetRelated(item['budgetRelated'])
                    if item['review_state'] == 'proposed':
                        wfTool.doActionFor(newItem, 'propose')

                if item['review_state'] == 'validated':
                    wfTool.doActionFor(newItem, 'validate')
                # add annexe and advice for one item in College
                if item['templateId'] == 'template3' and cfg.id == 'meeting-config-college':
                    cpt = 1
                    annexes_config_root = get_config_root(newItem)
                    for annexType in ('annexe', 'annexe', 'annexeBudget',
                                      'annexeCahier'):
                        annex_title = u'CV Informaticien N°2016-%s' % (cpt)
                        annex_file = namedfile.NamedBlobFile(
                            'Je suis le contenu du fichier',
                            filename=u'CV-0%s.txt' % (cpt))
                        annexTypeId = calculate_category_id(
                            annexes_config_root.get(annexType))
                        annex_id = normalize_name(site.REQUEST, annex_title)
                        api.content.create(container=newItem,
                                           id=annex_id,
                                           type='annex',
                                           title=annex_title,
                                           file=annex_file,
                                           content_category=annexTypeId,
                                           to_print=False,
                                           confidential=False)
                        cpt += 1
                    newItem.setOptionalAdvisers(
                        ('{0}__rowid__unique_id_003'.format(
                            org_id_to_uid('dirfin')),
                         org_id_to_uid('informatique')))
                    newItem.at_post_create_script()
                    createContentInContainer(
                        newItem, 'meetingadvice', **{
                            'advice_group': org_id_to_uid('informatique'),
                            'advice_type': u'positive',
                            'advice_comment': RichTextValue(SAMPLE_TEXT),
                            'advice_observations': RichTextValue()
                        })
                if item['templateId'] == 'template5' and cfg.id == 'meeting-config-college':
                    newItem.setOptionalAdvisers((org_id_to_uid('dirgen'), ))
                    newItem.at_post_create_script()
                    createContentInContainer(
                        newItem, 'meetingadvice', **{
                            'advice_group': org_id_to_uid('dirgen'),
                            'advice_type': u'negative',
                            'advice_comment': RichTextValue(SAMPLE_TEXT),
                            'advice_observations': RichTextValue(SAMPLE_TEXT)
                        })

                newItem.reindexObject()

        # adapt some parameters for config
        cfg.setAnnexToPrintMode('enabled_for_info')
예제 #25
0
 def test_getSize(self):
     from plone.app.textfield.value import RichTextValue
     value = RichTextValue(u'\u2603')
     self.assertEqual(3, value.getSize())
예제 #26
0
        def set_field_value(self, uid, field, value, field_type):
            """Set field value with a specific type

            XXX: Only dexterity fields are supported
            """
            pc = getToolByName(self, 'portal_catalog')
            results = pc.unrestrictedSearchResults(UID=uid)
            obj = results[0]._unrestrictedGetObject()
            if field_type == 'float':
                value = float(value)
            if field_type == 'int':
                value = int(value)
            if field_type == 'list':
                value = eval(value)
            if field_type.startswith('datetime'):
                # field_type must begin with 'datetime'
                # followed by optional format 'datetime%Y%m%d%H%M'
                # without format: %Y%m%d%H%M is used
                field_type = field_type[8:]
                fmt = field_type and field_type or '%Y%m%d%H%M'
                value = datetime.strptime(value, fmt)
            if field_type.startswith('date'):
                # field_type must begin with 'date'
                # followed by optional format 'date%Y%m%d'
                # without format: %Y%m%d is used
                field_type = field_type[4:]
                fmt = field_type and field_type or '%Y%m%d'
                value = datetime.strptime(value, fmt).date()
            if field_type == 'reference' and HAS_DEXTERITY_RELATIONS:
                results_referenced = pc.unrestrictedSearchResults(UID=value)
                referenced_obj = results_referenced[0]._unrestrictedGetObject()
                intids = getUtility(IIntIds)
                referenced_obj_intid = intids.getId(referenced_obj)
                value = RelationValue(referenced_obj_intid)
            if field_type == 'references' and HAS_DEXTERITY_RELATIONS:
                values = eval(value)
                intids = getUtility(IIntIds)
                value = []
                for uid in values:
                    results_referenced = pc.unrestrictedSearchResults(UID=uid)
                    referenced_obj = results_referenced[
                        0]._unrestrictedGetObject()
                    referenced_obj_intid = intids.getId(referenced_obj)
                    value.append(RelationValue(referenced_obj_intid))
            if field_type == 'text/html':
                value = RichTextValue(value, 'text/html', 'text/html')
                obj.text = value
            if field_type == 'file':
                pdf_file = os.path.join(os.path.dirname(__file__), 'content',
                                        u'file.pdf')
                value = NamedBlobFile(data=open(pdf_file, 'r').read(),
                                      contentType='application/pdf',
                                      filename=u'file.pdf')
            if field_type == 'image':
                image_file = os.path.join(os.path.dirname(__file__),
                                          u'image.jpg')
                value = NamedBlobImage(data=open(image_file, 'r').read(),
                                       contentType='image/jpg',
                                       filename=u'image.jpg')

            setattr(obj, field, value)
            obj.reindexObject()
            notify(ObjectModifiedEvent(obj))
예제 #27
0
    def test_MailerCSVAttachments(self):
        """ Test mailer with dummy_send """
        mailer = get_actions(self.ff1)["mailer"]
        mailer.sendXML = False
        mailer.sendCSV = True
        context = get_context(mailer)
        # Test all dexterity field type listed at https://docs.plone.org/external/plone.app.dexterity/docs/reference/fields.html
        fields = dict(
            topic="test subject",
            replyto="*****@*****.**",
            richtext=RichTextValue(raw="Raw"),
            comments=u"test comments😀",
            datetime=datetime.datetime(2019, 4, 1),
            date=datetime.date(2019, 4, 2),
            delta=datetime.timedelta(1),
            bool=True,
            number=1981,
            floating=3.14,
            tuple=("elemenet1", "element2"),
            list=[1, 2, 3, 4],
            map=dict(fruit="apple"),
            choices=set(["A", "B"]),
            empty_string="",
            zero_value=0,
            none_value=None,
            empty_tuple=(),
            empty_list=[],
            empty_set=set(),
            empty_map=dict(),
        )
        request = self.LoadRequestForm(**fields)
        attachments = mailer.get_attachments(fields, request)
        self.assertEqual(1, len(attachments))
        self.assertIn(
            u"Content-Type: application/csv\nMIME-Version: 1.0\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment",
            mailer.get_mail_text(fields, request, context),
        )
        name, mime, enc, csv = attachments[0]
        output = (
            b"*****@*****.**",
            b"test subject",
            b"Raw",
            b"test comments\xf0\x9f\x98\x80",
            b"2019/04/01, 00:00:00",
            b"2019/04/02",
            b"1 day, 0:00:00",
            b"True",
            b"1981",
            b"3.14",
            b'[""elemenet1"", ""element2""]',
            b'[""1"", ""2"", ""3"", ""4""]',
            b'{""fruit"": ""apple""}',
            b"",
            b"0",
            b"",
            b"[]",
            b"[]",
            b"[]",
            b"{}",
        )

        # the order of the columns can change ... check each
        # TODO should really have a header row
        for value in output:
            self.assertIn(value, csv)

        # the order of [""A"", ""B""] can change ... check separately
        self.assertIn(b'""A""', csv)
        self.assertIn(b'""B""', csv)
예제 #28
0
    def __getattribute__(self, name):
        if name.startswith('_') or name.startswith(
                'portal_') or name.startswith('@@') or name == 'sql_id':
            return super(SQLDexterityItem, self).__getattribute__(name)
        connection = queryUtility(ISQLConnectionsUtility,
                                  name=self.portal_type,
                                  default=None)
        if connection == None and self.portal_type:
            fti = queryUtility(IDexterityFTI,
                               name=self.portal_type,
                               default=None)
            if not fti:
                return None
            updateConnectionsForFti(fti)
            connection = queryUtility(ISQLConnectionsUtility,
                                      name=self.portal_type,
                                      default=None)
        if name == 'view':
            #be sure session and sqlitem are up to date
            self._v_sql_item = None
            connection.session.close()
        if not connection:
            return super(SQLDexterityItem, self).__getattribute__(name)
        if name == 'UID' and self.sql_virtual:
            return self.portal_type + '-' + connection.sql_table + '-' + str(
                self.sql_id)
        if name == 'id' and 'id' not in connection.fieldnames.keys():
            if not self.sql_virtual:
                return super(SQLDexterityItem, self).__getattribute__(name)
            fti = ISQLTypeSettings(
                getUtility(IDexterityFTI, name=self.portal_type))
            nameFromTitle = INameFromTitle(self, None)
            if nameFromTitle is not None and nameFromTitle.title:
                sql_folder_id = getattr(fti, 'sql_folder_id',
                                        'data-' + self.portal_type)
                title = nameFromTitle.title
                folder = None
                if IRelationValue.providedBy(sql_folder_id):
                    folder = sql_folder_id.to_object
                elif sql_folder_id and sql_folder_id.startswith('/'):
                    portal = getToolByName(getSite(),
                                           'portal_url').getPortalObject()
                    folder = portal.restrictedTraverse(sql_folder_id)
                if folder:
                    name = INameChooser(folder).chooseName(title, self)
                    return name
#                return INameChooser(getSite()).chooseName(title, self)
#                return getUtility(IURLNormalizer).normalize(title)
                return self.sql_id
        if name in connection.fieldnames.keys():
            sql_column = connection.fieldnames[name]
            sql_item = self.getSQLItem()
            try:
                sql_id = getattr(sql_item, connection.sql_id_column, None)
            except orm_exc.DetachedInstanceError:
                self._v_sql_item = None
                sql_item = self.getSQLItem()
                sql_id = getattr(sql_item, connection.sql_id_column, None)
            fieldname = 'name'
            if sql_item and sql_column:
                while '.' in sql_column:
                    sql_key = sql_column.split('.')[0]
                    sql_item = getattr(sql_item, sql_key, None)
                    if isinstance(sql_item, list):
                        value = sql_item
                        fieldname = sql_column.split('.')[-1]
                        break
                    sql_column = '.'.join(sql_column.split('.')[1:])
                else:
                    if not isinstance(sql_item, list):
                        value = getattr(sql_item, sql_column, None)
                if not value and (isinstance(value, list)
                                  or hasattr(value, '_sa_instance_state')):
                    value = ''
                elif (isinstance(value, list)
                      or hasattr(value, '_sa_instance_state')):
                    sqlftis = [
                        a for a in getAllUtilitiesRegisteredFor(IDexterityFTI)
                        if
                        'collective.behavior.sql.behavior.behaviors.ISQLContent'
                        in a.behaviors and getattr(a, 'sql_table', None)
                    ]
                    if name == 'subject':
                        return tuple(
                            [getattr(a, fieldname, '') for a in value])
                    tableftis = []
                    for iface in iterSchemataForType(self.portal_type):
                        if name in iface.names():
                            field = iface[name]
                            if IRelationChoice.providedBy(
                                    field) or IRelationList.providedBy(field):
                                if IRelationChoice.providedBy(field):
                                    allowed_types = field.source.query.get(
                                        'portal_type', [])
                                else:
                                    allowed_types = field.value_type.source.query.get(
                                        'portal_type', [])
                                tableftis = []
                                for sqlfti in sqlftis:
                                    adapted = ISQLTypeSettings(sqlfti, None)
                                    if isinstance(value, list):
                                        classname = value[0].__class__.__name__
                                    else:
                                        classname = value.__class__.__name__
                                    if adapted and getattr(
                                            adapted, 'sql_table',
                                            None) == classname:
                                        if not allowed_types or sqlfti.id in allowed_types:
                                            tableftis.append(adapted)
                                catalog = getToolByName(
                                    getSite(), 'portal_catalog')
                                relations = []
                                for tablefti in tableftis:
                                    sql_id_column = getattr(
                                        tablefti, 'sql_id_column', 'id')
                                    valueids = []
                                    if isinstance(value, list):
                                        valueids = [
                                            getattr(a, sql_id_column, None)
                                            for a in value
                                            if getattr(a, sql_id_column, None)
                                        ]
                                    else:
                                        valueids = getattr(
                                            value, sql_id_column, None)
                                    valueids = [str(a) for a in valueids]
                                    brains = catalog.unrestrictedSearchResults(
                                        portal_type=tablefti.id,
                                        sql_id=valueids)
                                    for brain in brains:
                                        relations.append(
                                            SQLRelationValue(
                                                brain.portal_type, brain.UID,
                                                self))
                                if IRelationChoice.providedBy(
                                        field) and relations:
                                    return relations[0]
                                elif IRelationList.providedBy(
                                        field) and relations:
                                    return relations
                            elif ITuple.providedBy(field):
                                return tuple(
                                    [getattr(a, fieldname, '') for a in value])
                            elif IList.providedBy(field):
                                return [
                                    getattr(a, fieldname, '') for a in value
                                ]
                            elif value and isinstance(value, list):
                                value = getattr(value[0], fieldname, '')
                for iface in iterSchemataForType(self.portal_type):
                    if name == 'subject':
                        try:
                            return tuple([
                                a.decode('utf-8') for a in literal_eval(value)
                            ])
                        except:
                            return tuple([a.strip() for a in value.split(',')])
                    if name in iface.names():
                        field = iface[name]
                        if IRichText.providedBy(field):
                            if not value:
                                return ''
                            if not '<p' in value or not '<br' in value:
                                value = '<p>' + '</p><p>'.join([
                                    a for a in value.split('\n') if a.strip()
                                ]) + '</p>'


#                            try:
#                                value = str(value)
#                            except:
#                                try:
#                                    value = value.decode('utf-8')
#                                except:
#                                    try:
#                                        value = value.encode('utf-8')
#                                    except:
#                                        pass
                            return RichTextValue(unidecode(value))
                        elif INamedBlobImage.providedBy(field):
                            return NamedBlobImage(
                                base64.b64decode(value),
                                filename=unicode(self.portal_type + self.id +
                                                 ".jpg"))
                        elif ITuple.providedBy(field):
                            if not value:
                                return tuple([])
                            try:
                                return tuple([
                                    a.decode('utf-8')
                                    for a in literal_eval(value)
                                ])
                            except:
                                return tuple(
                                    [a.strip() for a in value.split(',')])
                        elif IList.providedBy(field):
                            if not value:
                                return []
                            try:
                                return [
                                    a.decode('utf-8')
                                    for a in literal_eval(value)
                                ]
                            except:
                                return [a.strip() for a in value.split(',')]
                        elif IDatetime.providedBy(field) and hasattr(
                                value, 'day') and not hasattr(value, 'hour'):
                            value = datetime.datetime.combine(
                                value, datetime.datetime.min.time())
                if name in [
                        'expiration_date', 'effective_date', 'effective',
                        'expires'
                ] and hasattr(value, 'day') and not hasattr(value, 'hour'):
                    value = datetime.datetime.combine(
                        value, datetime.datetime.min.time())
                if isinstance(value, unicode) or name == 'id':
                    try:
                        value = str(value)
                    except:
                        pass
                return value
        return super(SQLDexterityItem, self).__getattribute__(name)
예제 #29
0
    def import_content(self):

        username = getattr(self.context, 'username', None)

        if username:
            try:
                data = self.get_publications_json(username)
            except:
                pass
            else:
                if data and isinstance(data, (list, tuple)):
                    publications = []

                    for __ in data:

                        _ = __.get('attributes', {})

                        contributors = [
                            "%s, %s" % (
                                x.get('last_name', ''),
                                x.get('first_name', ''),
                            ) for x in _.get('contributors', [])
                            if x.get('last_name', '')
                        ]

                        try:
                            published_on = localize(
                                DateTime("%s 00:00:00 US/Eastern" %
                                         _['published_on']))
                        except:
                            published_on = None

                        abstract = _.get('abstract', None)

                        if abstract:
                            abstract = RichTextValue(
                                raw=abstract,
                                mimeType=u'text/html',
                                outputMimeType='text/x-html-safe')

                        publications.append({
                            'ai_id':
                            __.get('id', None),
                            'title':
                            _.get('title', None),
                            'doi':
                            _.get('doi', None),
                            'journal_title':
                            _.get('journal_title', None),
                            'published_on':
                            published_on,
                            'abstract':
                            abstract,
                            'contributors':
                            contributors,
                        })

                    self.context.publications = self.sort_filter(publications)
                    self.context.reindexObject()
                    transaction.commit()

                    self.log(u"Imported %d publications for %s" %
                             (len(publications), username))
예제 #30
0
 def _deserialize(cls, data):
     return RichTextValue(raw=data['raw'],
                          mimeType=data['mimeType'],
                          outputMimeType=data['outputMimeType'],
                          encoding=data['encoding'])