def user_tagged_content(event): if ITagAddedEvent.providedBy(event): request = get_current_request() context = getattr(request, 'context', None) if context is None: return events = find_events(context) if not events: return site = find_site(context) catalog = find_catalog(context) path = catalog.document_map.address_for_docid(event.item) tagged = find_model(site, path) if tagged is None: return profile_id = event.user if profile_id in (None, 'None'): return profile = site['profiles'][profile_id] info = _getInfo(profile, tagged) if info is None: return if info['content_type'] == 'Community': info['flavor'] = 'tagged_community' elif info['content_type'] == 'Profile': info['flavor'] = 'tagged_profile' else: info['flavor'] = 'tagged_other' info['operation'] = 'tagged' info['tagname'] = event.name events.push(**info)
def __init__(self, context, request): self.context = context self.request = request self.username = authenticated_userid(request) self.path = model_path(context) self.catalog = find_catalog(context) self.tags = find_tags(context)
def __init__(self, context, request=None): # XXX request argument is not used, is left in for backwards # compatability. Should be phased out. self.context = context self.catalog = find_catalog(self.context) if request is not None: warnings.warn('Creating CatalogSearch with request is deprecated.', DeprecationWarning, stacklevel=2)
def reindex_content(obj, event): """ Reindex a single piece of content (non-recursive); an IObjectModifed event subscriber """ catalog = find_catalog(obj) if catalog is not None: path = model_path(obj) docid = catalog.document_map.docid_for_address(path) catalog.reindex_doc(docid, obj)
def unindex_content(obj, docids): """ Unindex given 'docids'. """ catalog = find_catalog(obj) if catalog is not None: for docid in docids: catalog.unindex_doc(docid) catalog.document_map.remove_docid(docid)
def del_tags(context, request, values): """ Delete the specified tags. """ username = authenticated_userid(request) path = model_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)
def handle_content_removed(obj, event): """ IObjectWillBeRemovedEvent subscriber. """ catalog = find_catalog(obj) if catalog is not None: path = model_path(obj) num, docids = catalog.search(path={'query': path, 'include_path': True}) unindex_content(obj, docids) cleanup_content_tags(obj, docids)
def _modify_community(obj, when): # manage content_modified on community whenever a piece of content # in a community is changed community = find_interface(obj, ICommunity) if community is not None: community.content_modified = when catalog = find_catalog(community) if catalog is not None: # may not be wired into the site yet index = catalog.get('content_modified') if index is not None: index.index_doc(community.docid, community)
def __call__(self, docid): site = self.context.site catalog = find_catalog(site) if catalog is None: raise ValueError('No catalog') path = catalog.document_map.address_for_docid(docid) if path is None: raise KeyError(docid) doc = find_model(site, path) community = find_community(doc) return community and community.__name__ or None
def set_tags(context, request, values): """ Set the specified tags, previously removing any existing tags. """ if values is None: values = () username = authenticated_userid(request) path = model_path(context) catalog = find_catalog(context) docid = getattr(context, 'docid', None) or catalog.document_map.docid_for_address(path) tags = find_tags(context) if tags is not None and docid is not None: # testing tags.update(item=docid, user=username, tags=values)
def get_container_batch(container, request, batch_start=0, batch_size=20, sort_index=None, reverse=False, permission='view', filter_func=None, interfaces=None): if 'batch_start' in request.params: batch_start = int(request.params['batch_start']) if 'batch_size' in request.params: batch_size = int(request.params['batch_size']) if sort_index: catalog = find_catalog(container) index = catalog[sort_index] # XXX this is not part of ICatalogIndex, but it happens to work # for most indexes. It might be useful to expand ICatalogIndex. sort_func = index.discriminator else: sort_func = None entries = [] # [(sort key, name, item)] for name, item in container.items(): if interfaces: # item must provide at least one of the given interfaces for iface in interfaces: if iface.providedBy(item): break else: continue if permission: if not has_permission(permission, item, request): continue if filter_func: if not filter_func(name, item): continue if sort_func is not None: sort_key = sort_func(item, None) else: sort_key = None entries.append((sort_key, name, item)) entries.sort() if reverse: entries.reverse() page_entries = entries[batch_start : batch_start + batch_size] info = { 'entries': [item for _, _, item in page_entries], 'batch_start': batch_start, 'batch_size': batch_size, 'batch_end': batch_start + len(page_entries), 'total': len(entries), } _add_link_data(info, container, request) return info
def index_content(obj, event): """ Index content (an IObjectAddedEvent subscriber) """ log.debug('index_content: obj=%s, event=%s' % (obj, event)) catalog = find_catalog(obj) if catalog is not None: for node in postorder(obj): if is_content(obj): path = model_path(node) docid = getattr(node, 'docid', None) if docid is None: docid = node.docid = catalog.document_map.add(path) else: catalog.document_map.add(path, docid) catalog.index_doc(docid, node)
def add_tags(context, request, values): """ Add the specified tags. o Existing tags remain assigned. """ if values: if isinstance(values, basestring): values = [values] path = model_path(context) catalog = find_catalog(context) docid = catalog.document_map.docid_for_address(path) username = authenticated_userid(request) tags = find_tags(context) if tags is not None: # testing new = list(tags.getTags(items=(docid,), users=(username,))) new.extend(values) tags.update(item=docid, user=username, tags=new)
def community_tag_users_view(context, request): page_title = 'Tag Users' api = request.api api.page_title = page_title tag = request.params.get('tag', None) docid = request.params.get('docid', None) # Test for some cases if tag is None: return HTTPBadRequest('Missing parameter for tag') if docid is None: return HTTPBadRequest('Missing parameter for docid') docid = int(docid) tags = find_tags(context) profiles = find_profiles(context) catalog = find_catalog(context) address = catalog.document_map.address_for_docid(docid) target = find_model(context, address) if tags is not None and profiles is not None: users = [] for userid in tags.getUsers(tags=[tag], items=[docid], community=context.__name__): profile = profiles[userid] fullname = profile.firstname + ' ' + profile.lastname also = [x for x in tags.getTags(items=[docid], users=[userid], community=context.__name__) if x != tag] users.append({'login': userid, 'fullname': fullname, 'also': also, }) else: users = () return dict( api=api, tag=tag, url=model_url(target, request), title=target.title, users=users, )
def move_content(root, src, dst, wf_state): try: context = find_model(root, src) except KeyError: print >>sys.stderr, "Source content not found: %s" % src sys.exit(-1) try: dest_folder = find_model(root, dst) except KeyError: print >>sys.stderr, "Destination folder not found: %s" % dst sys.exit(-1) src_community = find_community(context) catalog = find_catalog(root) assert catalog is not None users = find_users(root) assert users is not None if src_community is not None: move_header = ('<p><em>This was originally authored ' 'in the "%s" community.</em></p>' % src_community.title) else: move_header = '' src_folder = context.__parent__ name = context.__name__ log.info("Moving %s", model_path(context)) for obj in postorder(context): if hasattr(obj, 'docid'): docid = obj.docid catalog.document_map.remove_docid(docid) catalog.unindex_doc(docid) del src_folder[name] if (context.creator != 'admin' and users.get_by_id(context.creator) is None): # give the entry to the system admin log.warning( "User %s not found; reassigning to admin", context.creator) context.creator = 'admin' if name in dest_folder: name = make_unique_name(dest_folder, context.title) dest_folder[name] = context for obj in postorder(context): if hasattr(obj, 'docid'): docid = obj.docid catalog.document_map.add(model_path(obj), docid) catalog.index_doc(docid, obj) if wf_state is not None: wf = get_workflow(get_content_type(context), 'security', context) wf.transition_to_state(context, None, wf_state) if hasattr(context, 'text'): context.text = "%s\n%s" % (move_header, context.text)
def edit_acl_view(context, request): acl = original_acl = getattr(context, '__acl__', []) if acl and acl[-1] == NO_INHERIT: acl = acl[:-1] epilog = [NO_INHERIT] else: epilog = [] if 'form.move_up' in request.POST: index = int(request.POST['index']) if index > 0: new = acl[:] new[index-1], new[index] = new[index], new[index-1] acl = new elif 'form.move_down' in request.POST: index = int(request.POST['index']) if index < len(acl) - 1: new = acl[:] new[index+1], new[index] = new[index], new[index+1] acl = new elif 'form.remove' in request.POST: index = int(request.POST['index']) new = acl[:] del new[index] acl = new elif 'form.add' in request.POST: verb = request.POST['verb'] principal = request.POST['principal'] permissions = tuple(filter(None, COMMA_WS.split(request.POST['permissions']))) new = acl[:] new.append((verb, principal, permissions)) acl = new elif 'form.inherit' in request.POST: no_inherit = request.POST['inherit'] == 'disabled' if no_inherit: epilog = [NO_INHERIT] else: epilog = [] acl = acl + epilog if acl != original_acl: context.__acl__ = acl catalog = find_catalog(context) if catalog is not None: allowed = catalog.get('allowed') if allowed is not None: for node in postorder(context): allowed.reindex_doc(node.docid, node) catalog.invalidate() parent = context.__parent__ parent_acl = [] while parent is not None: p_acl = getattr(parent, '__acl__', ()) stop = False for ace in p_acl: if ace == NO_INHERIT: stop = True else: parent_acl.append(ace) if stop: break parent = parent.__parent__ local_acl = [] inheriting = 'enabled' l_acl = getattr(context, '__acl__', ()) for l_ace in l_acl: if l_ace == NO_INHERIT: inheriting = 'disabled' break local_acl.append(l_ace) return render_template_to_response('templates/edit_acl.pt', parent_acl=parent_acl or (), local_acl=local_acl, inheriting=inheriting, security_state=None, security_states=None, )
def rename_user(context, old_name, new_name, merge=False, out=None): """ Renames a user with the given userid to a new userid. If `merge` is `True` a user is expected to already exist with userid `new_name`. Moves all content and group memberships from old user to new user before removing the old user. """ profiles = find_profiles(context) users = find_users(context) old_user = users.get_by_id(old_name) if old_name not in profiles: raise ValueError("No such profile: %s" % old_name) if merge: if old_user is not None and users.get_by_id(new_name) is None: raise ValueError("No such user: %s" % new_name) if new_name not in profiles: raise ValueError("No such profile: %s" % new_name) if out is not None: print >> out, "Merging user from %s to %s." % (old_name, new_name) if old_user is not None: for group in old_user["groups"]: if not users.member_of_group(new_name, group): users.add_user_to_group(new_name, group) users.remove(old_name) del profiles[old_name] else: if users.get_by_id(new_name) is not None: raise ValueError("User already exists: %s" % new_name) if new_name in profiles: raise ValueError("Profile already exists: %s" % new_name) if out is not None: print >> out, "Renaming user %s to %s." % (old_name, new_name) if old_user is not None: users.add(new_name, new_name, old_user["password"], old_user["groups"], encrypted=True) users.remove(old_name) profile = profiles[old_name] del profiles[old_name] profiles[new_name] = profile catalog = find_catalog(context) search = ICatalogSearch(context) index = catalog["creator"] count, docids, resolver = search(creator=old_name) for docid in docids: doc = resolver(docid) if out is not None: print >> out, "Updating creator for %s." % model_path(doc) doc.creator = new_name index.reindex_doc(docid, doc) index = catalog["modified_by"] count, docids, resolver = search(modified_by=old_name) for docid in docids: doc = resolver(docid) if out is not None: print >> out, "Updating modified_by for %s." % model_path(doc) doc.modified_by = new_name index.reindex_doc(docid, doc)
def showtag_view(context, request, community=None, user=None, crumb_title=None): """Show a page for a particular tag, optionally refined by context.""" page_title = 'Show Tag' api = request.api api.page_title = page_title # The tag screens (cloud, listing, and this view) each have a # "jump box" that allows you to quickly jump to another tag. All # three will point here at /showtag?tag=tag1. We detect this mode # and do a redirect. jump_tag = request.params.get('jumptag', False) if jump_tag: location = model_url(context, request, request.view_name, jump_tag) return HTTPFound(location=location) # Our strategy is to support tag URLs that are like this: # /showtag/tag1 # ...instead of: # /tagpage.html?tag=tag1 # However, our tag data isn't traversable (it is site.tags and not # site['tags']. So we have a view at /showtag that picks apart # the next hop in the URL. tag = request.subpath if not tag: # The user didn't provide anything beyond /showtag in the URL tag = None entries = related = [] else: # Ahh, the good part. Let's find some tag results and unpack # data into what the ZPT needs. tag = tag[0] page_title = 'Show Tag ' + tag catalog = find_catalog(context) dm = catalog.document_map tags = find_tags(context) related = tags.getRelatedTags(tag, user=user, community=community) entries = [] if user: users = (user,) else: users = None for docid in tags.getItems(tags=(tag,), users=users, community=community, ): # XXX Need to wire in batching address = dm.address_for_docid(int(docid)) if address is None: raise KeyError(docid) resource = find_model(context, address) # Skip documents which aren't viewable by authenticated user #if not has_permission('view', resource, request): # continue # Do a secondary query for each result to find the # per-user info users = tags.getUsers(tags=(tag,), items=(docid,), community=community) if len(users) == 1: tuh = '1 person' else: tuh = '%s people' % len(users) tuhref = model_url(context, request, 'tagusers.html', query={'tag': tag, 'docid': docid}) entry = { 'title': resource.title, 'description': getattr(resource, 'description', ''), 'href': model_url(resource, request), 'type': get_content_type_name(resource), 'tagusers_href': tuhref, 'tagusers_count': tuh, } entries.append(entry) args = dict( api=api, tag=tag, entries=entries, related=related, ) if crumb_title: # XXX Would context.title be a bit nicer for displaying to user? system_name = get_setting(context, 'system_name', 'KARL') args['crumbs'] = '%s / %s / %s' % ( system_name, crumb_title, context.__name__) return dict(**args)