Exemple #1
0
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)
Exemple #2
0
 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)
Exemple #3
0
 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)
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
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)
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
 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
Exemple #10
0
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)
Exemple #11
0
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
Exemple #12
0
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)
Exemple #13
0
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)
Exemple #14
0
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,
        )
Exemple #15
0
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)
Exemple #16
0
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,
                                      )
Exemple #17
0
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)
Exemple #18
0
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)