def setUp(self): self.portal = self.layer['portal'] self.request = self.layer['request'] alsoProvides(self.request, IDefaultBrowserLayer) alsoProvides(self.request, IPloneAppMultilingualInstalled) fti = DexterityFTI('Feedback') fti.behaviors = ( 'plone.app.dexterity.behaviors.metadata.IBasic', 'plone.app.content.interfaces.INameFromTitle', 'plone.app.multilingual.dx.interfaces.IDexterityTranslatable', ) fti.model_source = u"""\ <model xmlns="http://namespaces.plone.org/supermodel/schema" xmlns:lingua="http://namespaces.plone.org/supermodel/lingua"> <schema> <field name="mandatory_feedback" type="zope.schema.Text" lingua:independent="true"> <description /> <required>True</required> <title>Mandatory feedback</title> </field> </schema> </model>""" portal_types = getToolByName(self.portal, 'portal_types') portal_types._setObject('Feedback', fti) self.document = createContentInContainer( self.portal['en'], 'Feedback', checkConstraints=False, title=u'Test feedback', mandatory_feedback=u'This is a test') # Call 'create_translation' to annotate request self.request.form['language'] = 'ca' self.redirect = getMultiAdapter((self.document, self.request), name="create_translation") self.redirect() # Look up the ++addtranslation++ with annotated request in place self.view = self.portal['ca'].restrictedTraverse('++addtranslation++' + IUUID(self.document)) self.view.update() self.field = self.view.form_instance.fields['mandatory_feedback'].field self.widget = self.view.form_instance.widgets['mandatory_feedback']
def default_template_is_in_allowed_templates(data): """ Validate ad-hoc agenda item templates """ default_template = data.ad_hoc_template allowed_templates = data.allowed_ad_hoc_agenda_item_templates if default_template is None: return if not allowed_templates: return if IUUID(default_template) not in allowed_templates: raise Invalid( _(u'error_default_template_is_in_allowed_templates', default=u'The default ad-hoc agenda item template has to be ' u'amongst the allowed ones for this committee.'))
def _remove_grouping_values(self, grouping, values, obj): """ Remove $uid from the list of uids stored under the grouping values (provided by $values) in the groupings datastructure. If $uid is the only one in the list, then remove the list (and its key) entirely. """ uid = IUUID(obj) groupings = self.get_groupings() if grouping not in groupings: return for value in groupings[grouping].keys(): if value not in values and uid in groupings[grouping][value]: if len(groupings[grouping][value]) == 1: del groupings[grouping][value] else: groupings[grouping][value].remove(uid)
def get_options(self): site = get_top_site_from_url(self.context, self.request) base_url = site.absolute_url() base_vocabulary = '%s/@@getVocabulary?name=' % base_url site_path = site.getPhysicalPath() context_path = self.context.getPhysicalPath() columns = self.get_columns() options = { 'vocabularyUrl': '%splone.app.vocabularies.Catalog' % (base_vocabulary), 'urlStructure': { 'base': base_url, 'appended': '/folder_contents' }, 'moveUrl': '%s{path}/fc-itemOrder' % base_url, 'indexOptionsUrl': '%s/@@qsOptions' % base_url, 'contextInfoUrl': '%s{path}/@@fc-contextInfo' % base_url, 'setDefaultPageUrl': '%s{path}/@@fc-setDefaultPage' % base_url, 'availableColumns': columns, 'attributes': [ 'Title', 'path', 'getURL', 'getIcon', 'getMimeIcon', 'portal_type' ] + list(columns.keys()), # noqa 'buttons': self.get_actions(), 'rearrange': { 'properties': self.get_indexes(), 'url': '%s{path}/@@fc-rearrange' % base_url }, 'basePath': '/' + '/'.join(context_path[len(site_path):]), 'upload': { 'relativePath': 'fileUpload', 'baseUrl': base_url, 'initialFolder': IUUID(self.context, None), 'useTus': TUS_ENABLED }, 'thumb_scale': self.get_thumb_scale(), } return options
def populate_with_object(self, obj): super(ListTile, self).populate_with_object(obj) uuid = IUUID(obj, None) data_mgr = ITileDataManager(self) old_data = data_mgr.get() if data_mgr.get()['uuids']: uuids = data_mgr.get()['uuids'] if type(uuids) != list: uuids = [uuid] elif uuid not in uuids: uuids.append(uuid) old_data['uuids'] = uuids[:self.limit] else: old_data['uuids'] = [uuid] data_mgr.set(old_data)
def createItem(message, event): """Consume item creation message""" uuid = message.header_frame.correlation_id container = uuidToObject(uuid) obj = createContentInContainer(container, "collective.zamqpdemo.item", checkConstraints=True, **message.body) kwargs = {"uuid": IUUID(obj)} producer = getUtility(IProducer, name="amqpdemo.delete") producer._register() producer.publish(kwargs) message.ack()
def short_uuid(obj): uuid = IUUID(obj, None) if uuid is not None: portal_catalog = getToolByName(obj, 'portal_catalog') short_uuids = portal_catalog.uniqueValuesFor('short_uuid') uuid = uuid.replace('-', '') for i in xrange(0, 32): short_uuid_ = uuid[:i] if short_uuid_ in short_uuids: same_short = portal_catalog.searchResults( short_uuid=short_uuid_ ) if same_short[0]['UID'] == uuid: return short_uuid_ else: return short_uuid_ return uuid
def item_ordered(self, state=[]): """Return total count buyable item was ordered. """ context = self.context bookings_soup = get_bookings_soup(context) order_bookings = dict() for booking in bookings_soup.query(Eq('buyable_uid', IUUID(context))): bookings = order_bookings.setdefault(booking.attrs['order_uid'], list()) bookings.append(booking) count = Decimal('0') for order_uid, bookings in order_bookings.items(): for booking in bookings: if state and booking.attrs['state'] not in state: continue count += booking.attrs['buyable_count'] return count
def remove(self): request = self.request user = request.AUTHENTICATED_USER view = request.get('view', '') portal = getToolByName(self.context, 'portal_url').getPortalObject() site = getNavigationRootObject(self.context, portal) IFavoriteStorage(site).remove_favorite(user.getId(), id=IUUID(self.context)) statusmsg = IStatusMessage(request) if IFolderish.providedBy(self.context): statusmsg.add(_("The folder has been removed from your favorites")) else: statusmsg.add( _("The document has been removed from your favorites")) request.response.redirect(self.context.absolute_url() + '/' + view)
def _get_markers(self, brain): """Return dict of marker details. Handle Info objects in special way. """ markers = [] if brain.portal_type == 'tbfac.Info': # get related Venues obj = brain.getObject() if obj is None: return [] refs = obj.venue if not refs: return [] for ref in refs: venue = ref.to_object geo = IGeoManager(venue, None) if geo and geo.isGeoreferenceable(): geometry, coordinates = geo.getCoordinates() if not coordinates or len(coordinates) != 2: continue else: longitude, latitude = coordinates if geometry == 'Point' and longitude and latitude: markers.append({ 'uid': IUUID(venue), 'search_uid': brain.UID, 'url': brain.getURL(), 'title': brain.Title, 'tags': brain.Subject or [], 'start': brain.start or '', 'end': brain.end or '', 'geometry': { 'style': None, 'type': 'Point', 'coordinates': (longitude, latitude) }, 'latitude': latitude, 'longitude': longitude, }) else: markers = super(UshahidiMapView, self)._get_markers(brain) return markers
def get_venue_url(venue): """Get URL to venue. We explicitly support here venues defined in other subsites. If so, URL is specially constructed, so that we can show the venue in our own site. """ # construct url to location site = getSite() venue_url = venue.absolute_url() site_path = u'/'.join(site.getPhysicalPath()) venue_path = u'/'.join(venue.getPhysicalPath()) if site_path not in venue_path: # venue in different site - cannot directly open it venue_url = u'{0}/@@venue_view?uid={1}'.format( site.absolute_url(), IUUID(venue) ) return venue_url
def num_more_occurrences(self): """Return the number of extra occurrences, which are not listed by next_occurrences. """ uid = IUUID(self.event_context, None) if not uid: # Might be an occurrence return 0 catalog = getToolByName(self.event_context, 'portal_catalog') brains = catalog(UID=uid) if len(brains) == 0: return 0 brain = brains[0] # assuming, that current context is in the catalog idx = catalog.getIndexDataForRID(brain.getRID()) num = len(idx['start']) - self.max_occurrences return num if num > 0 else 0
def getUID(context): uid = IUUID(context, None) if uid is not None: return uid if hasattr(context, 'UID'): return context.UID() try: return '/'.join(context.getPhysicalPath()) except AttributeError: pass try: return context.id except AttributeError: return 'unknown'
def test_scanin_to_new_private_dossier(self, browser): self.login(self.manager, browser) private_folder = self.create_private_folder() body, headers = self.prepare_request(destination='private') browser.open(self.portal.absolute_url() + '/@scan-in', method='POST', headers=headers, data=body) self.assertEqual(201, browser.status_code) dossier = private_folder.objectValues()[0] self.assertEqual('Scaneingang', dossier.Title()) self.assertIsNotNone(IUUID(dossier)) self.assertIsNotNone(obj2brain(dossier).UID) doc = dossier.objectValues()[0] self.assertEqual('mydocument', doc.Title())
def test_maintenance_error(self): portal = self.layer['portal'] request = self.layer['request'] folder = self.layer['folder'] request.form['uid'] = IUUID(folder) _portlet, portlet_hash = self._get_portlet_and_hash() self._expect_request().throw(MaintenanceError()) self.replay() request.form['hash'] = portlet_hash view = queryMultiAdapter((portal, request), name='watcher-load-data') self.assertNotEqual(view, None) self.assertEqual(view(), '"MAINTENANCE"')
def _move_selected_content(self, origin_tile, target_tile, obj): """Move selected content from one tile to another tile""" target_tile.populate_with_object(obj) if IListTile.providedBy(origin_tile): uuid = IUUID(obj) origin_tile.remove_item(uuid) else: origin_dmgr = ITileDataManager(origin_tile) origin_data = origin_dmgr.get() target_dmgr = ITileDataManager(target_tile) target_data = target_dmgr.get() for k, v in origin_data.iteritems(): if k in target_data and not k.startswith( 'uuid') and v is not None: target_data[k] = v target_dmgr.set(target_data) origin_dmgr.delete()
def test_UIDIndexer(self): uc = getattr(self.portal, config.UID_CATALOG) dext = DexterityLike() dext.path = list(self.folder.getPhysicalPath()) self.folder[dext.id] = dext notify(ObjectCreatedEvent(dext)) # it supposed to add uuid attribute # catalog dext instance uc.catalog_object(dext, '/'.join(dext.getPhysicalPath())) # check lookup uuid = IUUID(dext, None) results = uc(UID=uuid) self.assertTrue(len(results) == 1) self.assertTrue(results[0].UID == uuid) self.assertTrue(results[0].Title == str(dext.Title()))
def test_create_document_with_image_block_stores_uuid(self): self.portal.invokeFactory("Image", id="image", title="Image") image_file = os.path.join(os.path.dirname(__file__), "image.png") with open(image_file, "rb") as f: image_data = f.read() self.portal.image.image = NamedBlobImage(data=image_data, contentType="image/png", filename="image.png") self.portal.image.image_caption = "This is an image caption." transaction.commit() target_uuid = IUUID(self.portal.image) response = requests.post( self.portal.folder1.absolute_url(), headers={"Accept": "application/json"}, auth=(SITE_OWNER_NAME, SITE_OWNER_PASSWORD), json={ "@type": "Document", "id": "mydocument", "title": "My Document", "blocks": { "09e39ddf-a945-49f2-b609-ea427ac3430b": { "@type": "image", "url": f"{self.portal_url}/image", }, "21270e22-3a61-4780-b164-d6be56d942f4": { "@type": "title" }, }, "blocks_layout": { "items": [ "21270e22-3a61-4780-b164-d6be56d942f4", "09e39ddf-a945-49f2-b609-ea427ac3430b", ] }, }, ) self.assertEqual(201, response.status_code) transaction.begin() self.assertEqual( f"../../resolveuid/{target_uuid}", self.portal.folder1.mydocument.blocks.get( "09e39ddf-a945-49f2-b609-ea427ac3430b").get("url"), )
def move_file(obj): _, bucket = get_bucket() if bucket is None: return uid = IUUID(obj) if not uid: logger.info('Could not get uid of object') return key = KEY_PREFIX + uid filename = obj.file.filename if not isinstance(filename, unicode): filename = unicode(filename, 'utf-8', errors="ignore") filename = urllib.quote(filename.encode("utf8")) disposition = "attachment; filename*=UTF-8''%s" % filename size = obj.file.getSize() chunk_count = int(math.ceil(size / float(CHUNK_SIZE))) content_type = obj.file.contentType mp = bucket.initiate_multipart_upload(key, metadata={ 'Content-Type': content_type, 'Content-Disposition': disposition }) blob_fi = obj.file._blob.open('r') for i in range(chunk_count): chunk = blob_fi.read(CHUNK_SIZE) fp = io.BytesIO(chunk) mp.upload_part_from_file(fp, part_num=i + 1) mp.complete_upload() blob_fi.close() obj._p_jar.sync() obj.file = NamedBlobFile(data='', contentType=obj.file.contentType, filename=FILENAME) obj.file.original_filename = filename obj.file.original_content_type = content_type obj.file.original_size = size set_permission(obj)
def setUp(self): self.portal = self.layer['portal'] login(self.portal, TEST_USER_NAME) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal.invokeFactory('Document', id="page", title="page") self.portal.page.reindexObject() self.env = {'HTTP_ACCEPT_LANGUAGE': 'en', 'REQUEST_METHOD': 'POST'} self.request = makerequest(self.layer['app']).REQUEST self.request.environ.update(self.env) self.request.form = { 'selection': '["' + IUUID(self.portal.page) + '"]', '_authenticator': createToken(), 'folder': '/' } self.request.REQUEST_METHOD = 'POST'
def serialize(self, use_json=True, include_uid=False, encDefault=json.JSONEncoder.default): """ Serialze queries of context to JSON, or if use_json is False, to an equivalent dict of data. """ enc = lambda v: encDefault(v) if not isinstance(v, set) else list(v) data = {} if include_uid: data['uid'] = IUUID(self.context) data['operator'] = self.context.operator data['rows'] = [self._mkrow(q) for q in self.context.values()] if use_json: return json.dumps(data, indent=4, default=enc) return data
def test_existing_content_tile(self): page = api.content.create(type='Document', id='page1', container=self.portal, subject=('foobar', ), title='Foobar', description='Some foobar stuff') api.content.transition(obj=page, to_state='published') data = {'content': [IUUID(page)]} name = self.prefix + 'existing' html = render_tile(self.request, page, name, data) self.assertTrue('existing-content-basic' in html) data['display_type'] = 'backgroundimage' html = render_tile(self.request, page, name, data) self.assertTrue('existing-content-backgroundimage' in html)
def _add_grouping_values(self, grouping, values, obj): """ Add $uid to the list of uids stored under the grouping values (provided by $values) in the groupings datastructure. If the list doesn't exist yet, add it. """ uid = IUUID(obj) groupings = self.get_groupings() if grouping not in groupings: logger.info('Adding grouping %s to object %r', grouping, obj) groupings[grouping] = OrderedBTreeFolderBase() for value in values: if value in groupings[grouping]: groupings[grouping][value].add(uid) else: groupings[grouping][value] = GroupingStorageValues([uid])
def filters(self): if not hasattr(self, '_filters'): self._filters = [] included = self.include_queries() for name in included: title = name.title() composed = self.composed_query(name) found = self.find_filters(composed) if found: rfilter = found[0] self._filters.append({ 'groupname': name, 'uid': IUUID(rfilter), 'title': title, 'filter': rfilter, }) return self._filters
class RenameForm(plone_actions.RenameForm): @button.buttonAndHandler(_(u"Rename"), name="Rename") def handle_rename(self, action): request = self.request data, errors = self.extractData() if errors: return context = self.context parent = aq_parent(aq_inner(context)) sm = getSecurityManager() if not sm.checkPermission("Copy or Move", parent): raise Unauthorized( _( u"Permission denied to rename ${title}.", mapping={u"title": context.title}, )) newid = data["new_id"] newtitle = data["new_title"] try: notify(events.AsyncBeforeRename(context, newid, newtitle)) except Unauthorized: IStatusMessage(self.request).add( _( u"Permission denied to rename ${title}.", mapping={u"title": context.title}, )) return self.request.response.redirect(context.absolute_url()) except interfaces.AsyncValidationFailed, e: IStatusMessage(request).add(unicode(e)) return request.response.redirect(context.absolute_url()) uuid = IUUID(context, 0) task_id = utils.register_task( action=constants.RENAME, context=uuid, old_title=context.title, old_id=context.id, new_id=newid, new_title=newtitle, ) tasks.rename.apply_async( [context, data["new_id"], data["new_title"], task_id], dict()) return self.request.response.redirect(parent.absolute_url())
def test_add_to_folder(self): browser = Browser(self.layer['app']) browser.handleErrors = False uuid = IUUID(self.folder) # Login browser.open(self.portal.absolute_url() + '/login') browser.getControl(name='__ac_name').value = TEST_USER_NAME browser.getControl(name='__ac_password').value = TEST_USER_PASSWORD browser.getControl('Log in').click() # Enter the add screen for a temporary # portal_factory-managed object browser.open( '{}/portal_factory/Document/document.2010-02-04.2866363923/edit?_authenticator={}' .format( # noqa self.folder.absolute_url(), createToken())) # We should now have cookies with the drafts information cookies = browser.cookies.forURL(browser.url) path = '"{0}/portal_factory/Document/document.2010-02-04.2866363923"' # noqa self.assertEqual( path.format(self.folder.absolute_url_path()), cookies['plone.app.drafts.path'], ) self.assertEqual( '"{0}%3ADocument"'.format(uuid), cookies['plone.app.drafts.targetKey'], ) self.assertNotIn( 'plone.app.drafts.draftName', browser.cookies.forURL(browser.url), ) # We can now cancel the edit. The cookies should expire. browser.getControl(name='form.button.cancel').click() self.assertNotIn( 'plone.app.drafts.targetKey', browser.cookies.forURL(browser.url), ) self.assertNotIn( 'plone.app.drafts.path', browser.cookies.forURL(browser.url), )
def create_file_from_request(self, name): context = self.context filedata = self.request.form.get(name, None) if not filedata: return filename = filedata.filename content_type = mimetypes.guess_type(filename)[0] or "" # Determine if the default file/image types are DX or AT based ctr = api.portal.get_tool('content_type_registry') type_ = ctr.findTypeName(filename.lower(), content_type, '') if not type_ == 'Image': type_ = 'File' pt = api.portal.get_tool('portal_types') if IDexterityFTI.providedBy(getattr(pt, type_)): obj = self.create_dx_file(filename, content_type, filedata, type_) self.post_factory(obj) notify(ObjectCreatedEvent(obj)) if hasattr(obj, 'file'): size = obj.file.getSize() content_type = obj.file.contentType elif hasattr(obj, 'image'): size = obj.image.getSize() content_type = obj.image.contentType else: return result = {"type": content_type, "size": size} else: from Products.ATContentTypes.interfaces import IATCTFileFactory obj = IATCTFileFactory(context)(filename, content_type, filedata) self.post_factory(obj) try: size = obj.getSize() except AttributeError: size = obj.getObjSize() result = {"type": obj.getContentType(), "size": size} result.update({ 'url': obj.absolute_url(), 'name': obj.getId(), 'UID': IUUID(obj), 'filename': filename }) return result
def delete(self, obj, fieldNames=[], force=False): '''Pass an xmlrpc call to the daemon when a video is deleted''' UID = IUUID(obj) log = logging.getLogger('collective.transcode.star') tt = getUtility(ITranscodeTool) fields = self._getFields(obj, fieldNames) if not self._hasFiles(obj, fields): return address = self._getDaemonAddress() if address is None: return (transcodeServer, daemonProfiles) = self._getDaemon(address) if transcodeServer is None or daemonProfiles is None: return secret = self.secret() for field in fields: info = self._getFieldInfo(obj, field) if info is None: continue fieldName = info['fieldName'] md5sum = info['md5sum'] fileType = info['fileType'] fileName = info['fileName'] filePath = obj.absolute_url() portal_url = getToolByName(obj, 'portal_url')() fileUrl = portal_url + '/@@serve_daemon' norm = queryUtility(IIDNormalizer) fileName = norm.normalize(fileName.decode('utf-8')) options = dict() payload = { 'path': filePath, 'url': fileUrl, 'type': fileType, # don't send fieldName if it's the primary field 'fieldName': fieldNames and fieldName or '', 'fileName': fileName, 'uid': UID, } # Encrypt and send the transcode request payload = {'key': b64encode(encrypt(str(payload), secret))} transcodeServer.delete(payload, options, portal_url) tt.__delitem__(UID) return
def set_related_items(self, value): """ Set related items """ instance = self field = self.getField('relatedItems') tool = getToolByName(instance, REFERENCE_CATALOG) targetUIDs = [ ref.targetUID for ref in tool.getReferences(instance, field.relationship) ] if value is None: value = () if not isinstance(value, (list, tuple)): value = value, elif not field.multiValued and len(value) > 1: raise ValueError( "Multiple values given for single valued field %r" % self) # convert objects to uids if necessary uids = [] for v in value: if isinstance(v, basestring): uids.append(v) else: uids.append(IUUID(v, None)) add = [x for x in uids if x and x not in targetUIDs] sub = [t for t in targetUIDs if t not in uids] for uid in add: # __traceback_info__ = (instance, uid, value, targetUIDs) # throws IndexError if uid is invalid tool.addReference(instance, uid, field.relationship) for uid in sub: tool.deleteReference(instance, uid, field.relationship) if not hasattr(aq_base(instance), 'at_ordered_refs'): instance.at_ordered_refs = {} tpl_uids = tuple([u for u in uids if u is not None]) instance.at_ordered_refs[field.relationship] = tpl_uids
def test_search(self): from plone.uuid.interfaces import IUUID portal = self.layer['portal'] setRoles(portal, TEST_USER_ID, ['Manager']) portal.invokeFactory('Document', 'd1') portal.invokeFactory('Document', 'd2') d1 = portal['d1'] uuid = IUUID(d1) catalog = portal['portal_catalog'] results = catalog(UID=uuid) self.assertEqual(1, len(results)) self.assertEqual(uuid, results[0].UID) self.assertEqual('/'.join(d1.getPhysicalPath()), results[0].getPath())