def evolve(root): former_id = None # Create lazily, in case we don't need it profiles = find_profiles(root) search = ICatalogSearch(root) catalog = find_catalog(root) creators = catalog['creator']._fwd_index.keys() modifiers = catalog['modified_by']._fwd_index.keys() userids = set(creators) | set(modifiers) for userid in userids: if userid not in profiles: if former_id is None: former_id = make_unique_name(profiles, 'formeruser') print "Creating profile for former user content:", former_id former_profile = create_content( IProfile, firstname='Former', lastname='User' ) profiles[former_id] = former_profile count, docids, resolver = search(creator=userid) for docid in docids: doc = resolver(docid) print "Updating 'creator' for", resource_path(doc) doc.creator = former_id count, docids, resolver = search(modified_by=userid) for docid in docids: doc = resolver(docid) print "Updating 'modified_by' for", resource_path(doc) doc.modified_by = former_id
def reload_data_json(context, request): """ A json list of things interesting for an eventual update of agenda items view or poll menu. See reload_meeting_data in voteit_common.js Note: This is not a smart way of doing this, so MAKE SURE this executes fast! This will be replaced when proper websockets are in place. """ root = context.__parent__ response = {'polls': {}, 'proposals': {}, 'discussionposts': ()} #Get poll reload information query = Eq('content_type', 'Poll' ) & Eq('path', resource_path(context)) #ISn't there a smarter way to load wfs? for wf_state in ('upcoming', 'ongoing', 'canceled', 'closed'): response['polls'][wf_state] = tuple(root.catalog.query(query & Eq('workflow_state', wf_state), sort_index = 'created')[1]) #Fetch proposals and discussions? We'll focus on unread here, polls should catch wf changes on most proposals ai_name = request.GET.get('ai_name', None) if ai_name and ai_name in context: query = Eq('path', resource_path(context, ai_name)) #Proposal #This seems silly too... for wf_state in ('published', 'retracted', 'voting', 'approved', 'denied', 'unhandled'): response['proposals'][wf_state] = tuple(root.catalog.query(query & Eq('content_type', 'Proposal') \ & Eq('workflow_state', wf_state), sort_index = 'created')[1]) #DiscussionPost response['discussionposts'] = tuple(root.catalog.query(query & Eq('content_type', 'DiscussionPost'), sort_index = 'created')[1]) return response
def evolve(context): """ Upgrades required for new Image Drawer functionality. """ # Add IImage marker to instances of ICommunityFile which are images. catalog = find_catalog(context) search = ICatalogSearch(context) cnt, docids, resolver = search(interfaces=[ICommunityFile]) for docid in docids: obj = resolver(docid) if obj is None: continue # Work around catalog bug obj._init_image() if obj.is_image: print "Image: %s" % resource_path(obj) catalog.reindex_doc(obj.docid, obj) # Convert WikiPages to Folders so they can contain attachments cnt, docids, resolver = search(interfaces=[IWikiPage]) for docid in docids: obj = resolver(docid) if obj is None: continue # Work around catalog bug print "Convert wiki page to folder: %s" % resource_path(obj) Folder.__init__(obj) catalog.reindex_doc(obj.docid, obj)
def evolve(root): former_id = 'formeruser' profiles = find_profiles(root) search = ICatalogSearch(root) catalog = find_catalog(root) creators = catalog['creator']._fwd_index.keys() modifiers = catalog['modified_by']._fwd_index.keys() userids = set(creators) | set(modifiers) for userid in userids: if userid not in profiles: if former_id not in profiles: workflow = get_workflow(IProfile, 'security') former_id = make_unique_name(profiles, 'formeruser') print "Creating profile for former user content:", former_id former_profile = create_content( IProfile, firstname='Former', lastname='User' ) profiles[former_id] = former_profile workflow.initialize(former_profile) workflow.transition_to_state(former_profile, None, 'inactive') count, docids, resolver = search(creator=userid) for docid in docids: doc = resolver(docid) print "Updating 'creator' for", resource_path(doc) doc.creator = former_id count, docids, resolver = search(modified_by=userid) for docid in docids: doc = resolver(docid) print "Updating 'modified_by' for", resource_path(doc) doc.modified_by = former_id
def mothball_community(community): catalog = find_catalog(community) tags = find_tags(community) def get_docid(doc): return catalog.document_map.docid_for_address(resource_path(doc)) # Unindex all documents, remove top level tools # Make copy of items so we're not mutating a BTree while traversing it for name, tool in list(community.items()): if name == 'members': # We probably want to hang on to historical membership data continue for doc in postorder(tool): # includes tool in traversal log.info("Removing %s", resource_path(doc)) docid = get_docid(doc) tags.delete(docid) catalog.unindex_doc(docid) del community[name] log.info("Removing tags") docid = get_docid(community) tags.delete(docid) catalog.unindex_doc(docid) community.description = 'This community has been archived.' community.text = render('templates/archived_community_text.pt', { 'settings': get_current_registry().settings}) community.archive_status = 'archived' community.default_tool = None log.info("Finished removing content: %s", resource_path(community))
def test_create(self, context, registry, log): from adhocracy_core.interfaces import DEFAULT_USER_GROUP_NAME from pyramid.traversal import resource_path from adhocracy_core.interfaces import DEFAULT_USER_GROUP_NAME self._tempfd, filename = mkstemp() with open(filename, 'w') as f: f.write(json.dumps([ {'name': 'Alice', 'email': '*****@*****.**', 'initial-password': '******', 'roles': ['contributor'], 'groups': ['gods']}, {'name': 'Bob', 'email': '*****@*****.**', 'initial-password': '******', 'roles': [], 'groups': []} ])) locator = self._get_user_locator(context, registry) self.call_fut(context, registry, filename) god_group = context['principals']['groups']['gods'] alice = locator.get_user_by_login('Alice') assert alice.active alice = locator.get_user_by_login('Alice') alice_user_id = resource_path(alice) groups = locator.get_groups(alice_user_id) assert groups == [god_group] bob = locator.get_user_by_login('Bob') default_group = context['principals']['groups'][DEFAULT_USER_GROUP_NAME] bob_user_id = resource_path(bob) groups = locator.get_groups(bob_user_id) assert groups == [default_group]
def test_create(self, context, registry, log): from pyramid.traversal import resource_path self._tempfd, filename = mkstemp() with open(filename, 'w') as f: f.write(json.dumps([ {'name': 'Alice', 'email': '*****@*****.**', 'initial-password': '******', 'roles': ['contributor'], 'groups': ['gods']}, {'name': 'Bob', 'email': '*****@*****.**', 'initial-password': '******', 'roles': [], 'groups': ['moderators-xyz']} ])) locator = self._get_user_locator(context, registry) moderators_xyz_group = testing.DummyResource(roles=['moderator'], name='moderators-xyz') context['principals']['groups']['moderators-xyz'] = moderators_xyz_group self.call_fut(context, registry, filename) god_group = context['principals']['groups']['gods'] alice = locator.get_user_by_login('Alice') assert alice.active alice = locator.get_user_by_login('Alice') alice_user_id = resource_path(alice) default_group = context['principals']['groups']['authenticated'] groups = locator.get_groups(alice_user_id) assert groups == [default_group, god_group] bob = locator.get_user_by_login('Bob') bob_user_id = resource_path(bob) bob.group_ids = ['/principals/groups/authenticated', '/principals/groups/moderators-xyz']
def item_index_data(context, request): uuid = str(context.uuid) properties = context.upgrade_properties() links = context.links(properties) unique_keys = context.unique_keys(properties) principals_allowed = {} for permission in ('view', 'edit', 'audit'): p = principals_allowed_by_permission(context, permission) if p is Everyone: p = [Everyone] principals_allowed[permission] = sorted(p) path = resource_path(context) paths = {path} collection = context.collection if collection.unique_key in unique_keys: paths.update( resource_path(collection, key) for key in unique_keys[collection.unique_key]) for base in (collection, request.root): for key_name in ('accession', 'alias'): if key_name not in unique_keys: continue paths.add(resource_path(base, uuid)) paths.update( resource_path(base, key) for key in unique_keys[key_name]) path = path + '/' embedded = request.embed(path, '@@embedded') object = request.embed(path, '@@object') audit = request.embed(path, '@@audit')['audit'] document = { 'audit': audit, 'embedded': embedded, 'embedded_uuids': sorted(request._embedded_uuids), 'item_type': context.item_type, 'linked_uuids': sorted(request._linked_uuids), 'links': links, 'object': object, 'paths': sorted(paths), 'principals_allowed': principals_allowed, 'properties': properties, 'propsheets': { name: context.propsheets[name] for name in context.propsheets.keys() if name != '' }, 'tid': context.tid, 'unique_keys': unique_keys, 'uuid': uuid, } return document
def objectReplaced(event): """Tell the redirection storage that an object replaced """ old_object = event.old_object new_object = event.new_object if old_object is not None and new_object is not None: storage = get_storage(new_object) if storage is not None: old_path = resource_path(old_object) new_path = resource_path(new_object) storage.add(old_path, new_path)
def _set_local_role_creator(self, resource: IResource, creator: IResource, anonymized_creator: IResource, registry: Registry ): if creator and not anonymized_creator: userid = resource_path(creator) add_local_roles(resource, {userid: {'role:creator'}}, registry) elif creator and anonymized_creator: userid = resource_path(anonymized_creator) set_anonymized_creator(resource, userid)
def delete_user(request): schema = formutils.CSRFSchema().bind(request=request) is_self = request.context == request.user form = deform.Form( schema, buttons=[ deform.Button( name='yes', css_class='btn-danger', ), deform.Button( name='no', )], formid='deleteuser', ) try: if 'no' in request.POST: return HTTPFound(location = resource_path(request.context)) elif 'yes' in request.POST: controls = request.POST.items() form.validate(controls) db.delete(request.context) db.commit() request.session.flash('User deleted successfully!', queue='success') if is_self: return HTTPFound(location = resource_path(userregister)) else: return HTTPFound(location = resource_path(userlist)) except ValueError as e: if e.message == "Bad CSRF token": request.session.flash('Warning: Bad CSRF token, another site may be trying to control your session!', queue='error') formutils.error(form) else: raise e except deform.ValidationFailure: if form['csrf'].error is not None: request.session.flash('Warning: Bad CSRF token, another site may be trying to control your session!', queue='error') css_resources, js_resources = formutils.resources(form) return {'form': form, 'css_resources': css_resources, 'js_resources': js_resources, }
def index_object(catalog, obj): """ Index an object and add metadata. """ #Check if object already exists if catalog.document_map.docid_for_address(resource_path(obj)) is not None: reindex_object(catalog, obj) return obj_id = catalog.document_map.add(resource_path(obj)) catalog.index_doc(obj_id, obj) #Add metadata if ICatalogMetadataEnabled.providedBy(obj): metadata = getAdapter(obj, ICatalogMetadata)() metadata['docid'] = obj_id catalog.document_map.add_metadata(obj_id, metadata)
def add(self, activity: Activity) -> None: """Serialize `activity` and store in audit log.""" kwargs = {'object_path': resource_path(activity.object), 'type': activity.type, } if activity.subject: kwargs['subject_path'] = resource_path(activity.subject) if activity.target: kwargs['target_path'] = resource_path(activity.target) if activity.sheet_data: kwargs['sheet_data'] = activity.sheet_data entry = SerializedActivity()._replace(**kwargs) self[activity.published] = entry
def objectMoved(event): """Tell the redirection storage that an object moved """ moved_object = event.obj if event.old_parent is not None and \ event.new_parent is not None and event.old_name is not None: storage = get_storage(moved_object) if storage is not None: old_path = "%s/%s" % (resource_path(event.old_parent), event.old_name) new_path = resource_path(moved_object) storage.add(old_path, new_path)
def item_index_data(context, request): uuid = str(context.uuid) properties = context.upgrade_properties() links = context.links(properties) unique_keys = context.unique_keys(properties) principals_allowed = {} for permission in ("view", "edit", "audit"): p = principals_allowed_by_permission(context, permission) if p is Everyone: p = [Everyone] principals_allowed[permission] = sorted(p) path = resource_path(context) paths = {path} collection = context.collection if collection.unique_key in unique_keys: paths.update(resource_path(collection, key) for key in unique_keys[collection.unique_key]) for base in (collection, request.root): for key_name in ("accession", "alias"): if key_name not in unique_keys: continue paths.add(resource_path(base, uuid)) paths.update(resource_path(base, key) for key in unique_keys[key_name]) path = path + "/" embedded = request.embed(path, "@@embedded") object = request.embed(path, "@@object") audit = request.embed(path, "@@audit")["audit"] document = { "audit": audit, "embedded": embedded, "embedded_uuids": sorted(request._embedded_uuids), "item_type": context.type_info.item_type, "linked_uuids": sorted(request._linked_uuids), "links": links, "object": object, "paths": sorted(paths), "principals_allowed": principals_allowed, "properties": properties, "propsheets": {name: context.propsheets[name] for name in context.propsheets.keys() if name != ""}, "tid": context.tid, "unique_keys": unique_keys, "uuid": uuid, } return document
def finish_recording(song, request): tmpdir = '/tmp/' + request.params['id'] recording = request.registry.content.create('Recording', tmpdir) recordings = request.root['recordings'] name = generate_recording_id(recordings) recordings[name] = recording print request.user.performer recording.performer = request.user.performer recording.song = song redis = get_redis(request) print "finished", tmpdir, resource_path(recording) redis.rpush("yss.new-recordings", resource_path(recording)) return request.resource_url(recording)
def _reindex_es(): is_blacklisted = get_is_blacklisted() print "Start reindex" request = get_current_request() es_client = get_client(request) for obj in Content.query.all(): if not is_blacklisted(obj): print "OK. Type: %s. Path: %s" % (obj.type_info.name, resource_path(obj)) es_client.index_object(obj, immediate=True) else: print "BLACKLISTED. Type: %s. Path: %s" % (obj.type_info.name, resource_path(obj)) print "End reindex"
def index_creator(resource, default) -> str: """Return creator userid value for the creator index.""" creator = get_sheet_field(resource, IMetadata, 'creator') if creator == '': # FIXME the default value should be None return creator userid = resource_path(creator) return userid
def _assert_follows_last_version(node: SchemaNode, value: list, last: object): follows = value[0] if follows is not last: last_path = resource_path(last) msg = 'No fork allowed - valid follows resources are: {0}' msg = msg.format(str(last_path)) raise Invalid(node, msg, value=value)
def __init__(self, context, request): self.context = context self.request = request self.username = authenticated_userid(request) self.path = resource_path(context) self.catalog = find_catalog(context) self.tags = find_tags(context)
def evolve(root): logger.info( 'Running substanced evolve step 7: reset all blob mimetypes ' 'to nominal USE_MAGIC value' ) if magic: objectmap = find_objectmap(root) if objectmap is not None: oids = objectmap.get_extent(get_dotted_name(File)) if oids is not None: for oid in oids: f = objectmap.object_for(oid) try: if f.get_size(): blob = f.blob fp = blob.open('r') for chunk in chunks(fp): m = magic.Magic(mime=True) mimetype = m.from_buffer(chunk) f.mimetype = mimetype break except POSKeyError: logger.error( 'Missing blob for file %s, overwriting with ' 'empty blob' % resource_path(f) ) f.blob = Blob() f.mimetype = 'application/octet-stream'
def __repr__(self): return "<{0} {1} => {2} at {3}>".format( self.__class__.__name__, self.principal_name, self.group_name, resource_path(self.node), )
def purge_varnish_after_commit_hook(success: bool, registry: Registry, request: IRequest): """Send PURGE requests for all changed resources to Varnish.""" varnish_url = registry.settings.get('adhocracy.varnish_url') if not (success and varnish_url): return changelog_metadata = registry.changelog.values() errcount = 0 for meta in changelog_metadata: events = extract_events_from_changelog_metadata(meta) if events == []: continue path = resource_path(meta.resource) url = varnish_url + request.script_name + path for event in events: headers = {'X-Purge-Host': request.host} headers['X-Purge-Regex'] = '/?\??[^/]*' try: resp = requests.request('PURGE', url, headers=headers) if resp.status_code != 200: logger.warning( 'Varnish responded %s to purge request for %s', resp.status_code, path) except RequestException as err: logger.error( 'Couldn\'t send purge request for %s to Varnish: %s', path, exception_to_str(err)) errcount += 1 if errcount >= 3: # pragma: no cover logger.error('Giving up on purge requests') return
def evolve(context): # add default category and layer to all calendars # Prevent 'set_created' event handler from being called since it will, # in turn, set the content_modified attribute of community which is used # as the "Last Activity" in the user interface. We don't want this tweak # to impact a community's last activity. This means we need to set created # and modified on the new layers and categories ourselves. registry = getSiteManager() registry.adapters.unsubscribe( (IContent, IObjectWillBeAddedEvent), None, set_created) try: search = ICatalogSearch(context) default_category_name = ICalendarCategory.getTaggedValue('default_name') default_layer_name = ICalendarLayer.getTaggedValue('default_name') now = datetime.now() cnt, docids, resolver = search(interfaces=[ICalendar]) for docid in docids: calendar = resolver(docid) default_category = create_content(ICalendarCategory, 'Default') default_category.created = default_category.modified = now if not default_category_name in calendar: calendar[default_category_name] = default_category local_layer = create_content(ICalendarLayer, "This Calendar's Events Only", 'blue', [resource_path(default_category)]) local_layer.created = local_layer.modified = now if not default_layer_name in calendar: calendar[default_layer_name] = local_layer finally: registry.adapters.subscribe( (IContent, IObjectWillBeAddedEvent), None, set_created)
def copy_community_to_box(community): log.info("Connecting to Box.") box = BoxClient(find_box(community), get_current_registry().settings) def realize_archive(archive, folder, path, copied): for name, item in archive.items(): subpath = path + (name,) copied.append(subpath) log.info("Copying (%d) %s", len(copied), '/' + '/'.join(subpath)) if isinstance(item, ArchiveFolder): if name in folder: subfolder = folder[name] else: subfolder = folder.mkdir(name) realize_archive(item, subfolder, subpath, copied) else: folder.upload(name, item.open()) path = reversed([o.__name__ for o in lineage(community) if o.__name__]) folder = box.root().get_or_make('Karl Archive', *path) if folder: raise ValueError( 'Cannot archive community, folder already exists: %s' % ( '/' + '/'.join(path))) copied = [] realize_archive(archive(community), folder, tuple(path), copied) community.archive_status = 'reviewing' log.info("Finished copying to box: %s", resource_path(community))
def _login_user(request: IRequest) -> dict: """Set cookies and return a data for token header authentication.""" user = request.validated['user'] userid = resource_path(user) headers = remember(request, userid) cstruct = _get_api_auth_data(headers, request, user) return cstruct
def content_added_or_removed(event): """ Generates ContentAdded and ContentRemoved audit events """ if IObjectWillBeRemoved.providedBy(event): event_name = 'ContentRemoved' elif IObjectAdded.providedBy(event): event_name = 'ContentAdded' else: return False # for testing userinfo = get_userinfo() eventscribe = AuditScribe(event.object) parent = event.parent # this is an event related to the *container*, not to the object. folder_oid = get_oid(parent, None) object_oid = get_oid(event.object, None) folder_path = resource_path(parent) object_name = event.name moving = bool(event.moving) loading = bool(event.loading) content_type = str(event.registry.content.typeof(event.object)) eventscribe.add( event_name, folder_oid, object_oid=object_oid, folder_oid=folder_oid, folder_path=folder_path, object_name=object_name, content_type=content_type, userinfo=userinfo, moving=moving, loading=loading, )
def get_columns(self, subobject): columns = self.get_default_columns(subobject) owner = getattr(subobject, 'owner', None) if owner is not None: owner = owner.__name__ resource = getattr(subobject, 'resource', None) if resource is not None: resource = resource_path(resource) expires = getattr(subobject, 'expires', None) if expires is not None: expires = expires() if expires is not None: tz = self.request.user.timezone expires = expires.replace(tzinfo=None) # in case it's not naive expires = tz.localize(expires).strftime('%Y-%m-%d %H:%M:%S %Z') columns.extend(( {'name':_('Owner'), 'value':owner, }, {'name':_('Resource'), 'value':resource, }, {'name':_('Expires'), 'value':expires, }, )) return columns
def _show_communities_view_helper(context, request, prefix='', **kw ): # Grab the data for the two listings, main communities and portlet communities_path = resource_path(context) query = dict( sort_index='title', interfaces=[ICommunity], path={'query': communities_path, 'depth': 1}, allowed={'query': effective_principals(request), 'operator': 'or'}, **kw ) qualifiers = [] titlestartswith = request.params.get('titlestartswith') if titlestartswith: query['titlestartswith'] = (titlestartswith, titlestartswith) qualifiers.append( _(u"Communities that begin with '${titlestartswith}'", mapping={'titlestartswith': titlestartswith})) body = request.params.get('body') if body: query['texts'] = body qualifiers.append('Search for "%s"' % body) error = None try: batch_info = get_catalog_batch_grid(context, request, **query) except ParseError, e: batch_info = {'entries': [], 'batching_required': False} error = _(u'Error: ${message}', mapping={'message': e})
def validate_root_versions(node: SchemaNode, value: list): """Validate root versions.""" for root_version in value: if not IItemVersion.providedBy(root_version): msg = 'This resource is not a valid ' \ 'root version: {}'.format(resource_path(root_version)) raise Invalid(node, msg=msg)
def unindex_object(catalog, obj): """ Remove an index and its metadata if it exists in the catalog. """ obj_id = catalog.document_map.docid_for_address(resource_path(obj)) if obj_id is None: return catalog.unindex_doc(obj_id) #Remove metadata if ICatalogMetadataEnabled.providedBy(obj): catalog.document_map.remove_metadata(obj_id)
def _get_user_info(request: Request) -> (str, str): if not hasattr(request, 'authenticated_userid'): return ('', '') # ease scripting without user and testing user = get_user(request) if user is None: return ('', '') else: user_name = get_sheet_field(user, IUserBasic, 'name') user_path = resource_path(user) return (user_name, user_path)
def count_tags(self, context, request, base_tag, num): results = {} query = Eq('path', resource_path(context)) & Eq('type_name', 'Proposal') query &= NotAny('workflow_state', ['retracted', 'unhandled']) cquery = request.root.catalog.query for i in range(1, num+1): tag = "%s-%s" % (base_tag, i) res = cquery(query & Any('tags', [tag]))[0] results[tag] = res.total return results
def log_content_removed(obj, event): #Which context to use? context = _get_logger_context(obj) request = get_current_request() log_handler = request.registry.getAdapter(context, ILogHandler) userid = authenticated_userid(request) msg = _(u"${ctype} removed from ${path}", mapping={'ctype': obj.content_type, 'path':resource_path(obj)}) log_handler.add(obj.uid, msg, tags=('removed',), userid=userid)
def get_tag_count(self, tag): """ Returns total count for a tag withing the context this view was registered on. """ try: return self.tag_count[tag] except KeyError: query = Eq('path', resource_path(self.context)) &\ Any('allowed_to_view', self.cached_effective_principals) &\ Any('tags', tag) self.tag_count[tag] = self.root.catalog.query(query)[0] return self.tag_count[tag]
def evolve(context): root = find_root(context) searcher = ICatalogSearch(root) total, docids, resolver = searcher(interfaces=[IForumTopic]) count = 0 workflow = get_workflow(IForumTopic, 'security') for docid in docids: topic = resolver(docid) if has_custom_acl(topic): continue # don't mess with objects customized via edit_acl try: state, msg = workflow.reset(topic) except: print "ERROR while resetting topic workflow: %s" % resource_path( topic) else: print "Reset topic workflow: %s" % resource_path(topic) count += 1 print "Updated %d forum topic workflows" % count
def get_asset_choices(context, request) -> []: """Return asset choices based on the available `assets` service.""" assets = find_service(context, 'assets') if assets is None: return [] target_isheet = ImageReference.getTaggedValue('target_isheet') choices = [(request.resource_url(asset, route_name=API_ROUTE_NAME), resource_path(asset)) for asset in assets.values() if target_isheet.providedBy(asset)] return choices
def evolve(root): profiles = root['profiles'] for name in profiles.keys(): profile = profiles[name] if 'photo' not in profile: continue photo = profile['photo'] if photo.creator != name: print "Updating creator for %s" % resource_path(photo) photo.creator = name
def forum_to_inherits(ob, info): acl = [(Allow, 'group.KarlStaff', (CREATE, ))] # Note: don't add NO_INHERIT, ergo fall back to __parent__ msg = None added, removed = acl_diff(ob, acl) if added or removed: ob.__acl__ = acl msg = ts('forum-inherited', resource_path(ob), added, removed) _reindex(ob) return msg
def handle_content_removed(obj, event): """ IObjectWillBeRemovedEvent subscriber. """ catalog = find_catalog(obj) if catalog is not None: path = resource_path(obj) num, docids = catalog.search(path={'query': path, 'include_path': True}) unindex_content(obj, docids) cleanup_content_tags(obj, docids)
def context_tools(context, request): community = find_community(context) if community is None: return None community_info = getMultiAdapter((community, request), ICommunityInfo) tools = community_info.tabs members = community['members'] members_path = resource_path(community['members']) context_path = resource_path(context) in_members = context_path.startswith(members_path) tools.append({ 'url': request.resource_url(members), 'selected': in_members, 'title': 'Members', 'name': 'members' }) return tools
def _resolve_user(s): if not isinstance(s, str) or not s.startswith('user_by_login:'******'user_by_login:'******'No such user: {}.'.format(user_name)) return resource_path(user)
class ManageAgendaItemsView(BaseEdit): @view_config(context=IMeeting, name="manage_agenda_items", renderer="templates/manage_agenda_items.pt", permission=security.EDIT) def manage_agenda_items(self): post = self.request.POST if 'cancel' in self.request.POST: url = self.request.resource_url(self.context, 'manage_agenda_items') return HTTPFound(location=url) if 'change' in post: state_id = self.request.POST['state_id'] controls = self.request.POST.items() for (k, v) in controls: if k == 'ais': ai = self.context[v] try: ai.set_workflow_state(self.request, state_id) except WorkflowError, e: self.api.flash_messages.add(_( 'Unable to change state on ${title}: ${error}', mapping={ 'title': ai.title, 'error': e }), type='error') self.api.flash_messages.add(_('States updated')) state_info = _dummy_agenda_item.workflow.state_info(None, self.request) def _translated_state_title(state): for info in state_info: if info['name'] == state: return self.api.tstring(info['title']) return state self.response['translated_state_title'] = _translated_state_title self.response['find_resource'] = find_resource self.response['states'] = states = ('ongoing', 'upcoming', 'closed', 'private') self.response['ais'] = {} context_path = resource_path(self.context) for state in states: query = dict( path=context_path, content_type='AgendaItem', sort_index='order', workflow_state=state, ) self.response['ais'][state] = self.api.get_metadata_for_query( **query) return self.response
def test_content_object(self): model = testing.DummyModel() model['people'] = testing.DummyModel() from pyramid.traversal import resource_path path = resource_path(model) from karl.testing import DummyCatalog catalog = DummyCatalog({1: path}) model['people'].catalog = catalog self._callFUT(model, None) self.assertEqual(catalog.unindexed, [1]) self.assertEqual(catalog.indexed, [model])
def change_usertags(root, userid, userid_lower): catalog = root.catalog result = catalog.search(path=resource_path(root), like_userids=(userid,))[1] for docid in result: obj = resolve_catalog_docid(catalog, root, docid) # get unread adapter usertags = UserTags(obj) for tag in usertags.tags_storage: if userid in usertags.tags_storage[tag]: usertags.tags_storage[tag].remove(userid) # remove old userid usertags.tags_storage[tag].add(userid_lower) # add new userid
def polls_menu(context, request, va, **kw): api = kw['api'] if api.meeting is None: return '' query = Eq('content_type', 'Poll' ) & Eq('path', resource_path(api.meeting)) & Eq('workflow_state', 'ongoing') response = {} response['api'] = api response['menu_title'] = va.title response['open_polls'] = bool(api.root.catalog.query(query)[0]) response['url'] = request.resource_url(api.meeting, 'meeting_poll_menu') return render('templates/polls/polls_menu.pt', response, request = request)
def test_resource_and_descentdants_reindexed(self, context, catalog, mock_path_query): from pyramid.traversal import resource_path child = testing.DummyResource() mock_path_query.execute.return_value = [context, child] self.call_fut(context) assert catalog['system']['path'].eq.call_args == \ call(resource_path(context), include_origin=True) mock_reindex = catalog.reindex_index assert call(child, 'private_visibility') in mock_reindex.call_args_list assert mock_reindex.call_count == 2
def admin_docker_massaction_view(context, request): """Mass action view.""" items_list = request.POST.getall('selected_item') for item in items_list: try: context.cli.remove_image(item) request.session.flash(["deleted {}".format(item), "success"]) except docker.errors.APIError as e: request.session.flash([e.explanation, "error"]) url = "/" + request.sacrud_prefix + "/" + resource_path(context.__parent__) return HTTPFound(location=url)
def add_mailinglist(obj, event): # When this handler is called while loading a peopleconf configuration, # this will get called before the maillist has been added to the site, # so we won't actually have a path to the site. In this case we'll get # back a report object that doesn't have a 'list_aliases' attribute. We # safely do nothing here, since the peopleconf loader will go back and # add the aliases when it has finished loading. site = find_site(obj) aliases = getattr(site, 'list_aliases', None) if aliases is not None: aliases[obj.short_address] = resource_path(obj.__parent__)
def log_auditevent(context: IResource, name: AuditlogAction, user_name: str, user_path: str) -> None: """Add an auditlog entry for `context` to the audit database. The audit database is created if missing. If the `zodbconn.uri.audit` value is not specified in the config, auditing does not happen. """ auditlog = get_auditlog(context) path = resource_path(context) if auditlog is not None: auditlog.add(name, path, user_name, user_path)
def process_embed_code_config_adapter(context: IResource, request: IRequest) -> {}: """Return config to render `adhocracy_core:templates/embed_code.html`.""" mapping = embed_code_config_adapter(context, request) initial_url = '/r' + resource_path(context) + '/' mapping.update({ 'widget': 'plain', 'autourl': 'true', 'initial_url': initial_url, }) return mapping
def del_tags(context, request, values): """ Delete the specified tags. """ username = authenticated_userid(request) path = resource_path(context) catalog = find_catalog(context) docid = catalog.document_map.docid_for_address(path) tags = find_tags(context) for tag in values: tags.delete(item=docid, user=username, tag=tag) catalog.reindex_doc(docid, context)
def previous_ai(self): """ Return previous agenda item within this workflow category, if there is one. """ query = u"path == '%s' and content_type == 'AgendaItem'" % resource_path(self.context.__parent__) query += u" and order < %s" % self.context.get_field_value('order') query += u" and workflow_state == '%s'" % self.context.get_workflow_state() #Note that docids might be a generator here count, docids = self.api.query_catalog(query , limit = 1, sort_index='order', reverse = True) if not count: return return self.api.resolve_catalog_docid(tuple(docids)[0])
def search_catalog(self, context=None, **kwargs): """ Same as catalog.search, but also extracts path from context if it's specified. returns the same tuple with (itemcount, docid_set) as result. Note: search is deprecated in catalog so this will removed. Use query instead! """ if context is not None: if 'path' in kwargs: ValueError("Can't specify both context and path") kwargs['path'] = resource_path(context) return self.root.catalog.search(**kwargs)
def number_of_comments(forum, request): searcher = ICatalogSearch(forum) total, docids, resolver = searcher( interfaces=[IComment], path={'query': resource_path(forum)}, allowed={ 'query': effective_principals(request), 'operator': 'or' }, ) return total
def _common(self, obj): res = { 'created': self._timestamp(obj.created), 'path': resource_path(obj), 'uid': obj.uid, 'type_name': obj.type_name, } for ts_attr in ('start_time', 'end_time'): if hasattr(obj, ts_attr): res[ts_attr] = self._timestamp(getattr(obj, ts_attr, None)) return res
def test_add_and_get_metadata(self): obj = self._make_obj() dm = self.root.catalog.document_map doc_id = dm.add(resource_path(obj.context)) dm.add_metadata(doc_id, obj()) metadata = dm.get_metadata(doc_id) self.assertEqual(metadata['title'], obj.context.title) self.assertEqual(metadata['created'], obj.context.created)
def evolve(root): search = ICatalogSearch(root) catalog = find_catalog(root) index = catalog['mimetype'] for old_type, new_type in ie_types.items(): cnt, docids, resolver = search(mimetype=old_type) for docid in docids: doc = resolver(docid) print "Adjusting mimetype for %s" % resource_path(doc) doc.mimetype = new_type index.reindex_doc(docid, doc)
def _entry_models(self): search = getAdapter(self.context, ICatalogSearch) count, docids, resolver = search(limit=N_ENTRIES, path=resource_path(self.context), sort_index="modified_date", reverse=True, interfaces=[ ICalendarEvent, ]) return [resolver(docid) for docid in docids]
def subscribe(self, client: Hashable, resource: IResource) -> bool: """Subscribe a client to a resource, if necessary. :return: True if the subscription was successful, False if it was unnecessary (the client was already subscribed). """ if self.is_subscribed(client, resource): return False path = resource_path(resource) self._clients2resource_paths[client].add(path) self._resource_paths2clients[path].add(client) return True