def cleanup_content_tags(obj, docids): """ Remove any tags associated with 'docids'. """ tags = find_tags(obj) if tags is not None: for docid in docids: tags.delete(item=docid)
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 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 visit(self, context): if IProfile.providedBy(context): users = find_users(context) person = self._get_person(context.__name__) person['first_last'] = ' '.join( (context.firstname, context.lastname)) person['create_date'] = context.created person['is_staff'] = users.member_of_group( context.__name__, 'group.KarlStaff') person['location'] = context.location person['department'] = context.department tags = find_tags(context) person['tags'] = len(tags.getTags(users=[context.__name__])) elif ICommunity.providedBy(context): for id in context.member_names: self._get_person(id)['membership'] += 1 for id in context.moderator_names: self._get_person(id)['communities_moderator'] += 1 else: creator = getattr(context, 'creator', None) if creator is not None: person = self._get_person(creator) person['content_created'] += 1 if context.created > self.one_month_ago: person['created_this_month'] += 1
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 manage_tags_view(context, request): page_title = 'Manage Tags' api = TemplateAPI(context, request, page_title) tagger = find_tags(context) userid = context.__name__ error = '' old = '' new = '' catalog = find_catalog(context) address_for_docid = catalog.document_map.address_for_docid def get_doc(docid): path = address_for_docid(docid) return find_resource(context, path) if 'form.rename' in request.POST and 'old_tag' in request.POST: old_tag = request.POST['old_tag'] new_tag = request.POST['new_tag'] # check that tag contains only valid characters if re_tag.match(new_tag) is None: error = u'Value contains characters that are not allowed in a tag.' old = old_tag new = new_tag else: docids = tagger.getItems(tags=[old_tag], users=[userid]) to_update = {} for tagob in tagger.getTagObjects(items=docids, users=[userid]): if tagob.name == old_tag: name = new_tag else: name = tagob.name to_update.setdefault(tagob.item, []).append(name) for docid in docids: tagger.update(item=docid, user=userid, tags=to_update.get(docid, [])) catalog.reindex_doc(docid, get_doc(docid)) if 'form.delete' in request.POST and 'todelete' in request.POST: old_tag = request.POST['todelete'] for docid in tagger.getItems(tags=[old_tag], users=[userid]): tagger.delete(item=docid, user=userid, tag=old_tag) catalog.reindex_doc(docid, get_doc(docid)) if tagger is None: tags = () else: tags = list(tagger.getTags(users=(context.__name__, ))) tags.sort() return dict( api=api, my_tags=tags, error=error, old=old, new=new, )
def evolve(site): """ Add precomputed cloud data to Tags. """ tags = find_tags(site) tags._global_cloud = PersistentMapping() tags._community_clouds = OOBTree.OOBTree() for tag in tags._tagid_to_obj.values(): update_clouds(tags, tag)
def manage_tags_view(context, request): layout = request.layout_manager.layout layout.page_title = 'Manage Tags' api = TemplateAPI(context, request, layout.page_title) tagger = find_tags(context) userid = context.__name__ error = '' old = '' new = '' catalog = find_catalog(context) address_for_docid = catalog.document_map.address_for_docid def get_doc(docid): path = address_for_docid(docid) return find_resource(context, path) if 'form.rename' in request.POST and 'old_tag' in request.POST: old_tag = request.POST['old_tag'] new_tag = request.POST['new_tag'] # check that tag contains only valid characters if re_tag.match(new_tag) is None: error = u'Value contains characters that are not allowed in a tag.' old = old_tag new = new_tag else: docids = tagger.getItems(tags=[old_tag], users=[userid]) to_update = {} for tagob in tagger.getTagObjects(items=docids, users=[userid]): if tagob.name == old_tag: name = new_tag else: name = tagob.name to_update.setdefault(tagob.item, []).append(name) for docid in docids: tagger.update(item=docid, user=userid, tags=to_update.get(docid, [])) catalog.reindex_doc(docid, get_doc(docid)) if 'form.delete' in request.POST and 'todelete' in request.POST: old_tag = request.POST['todelete'] for docid in tagger.getItems(tags=[old_tag], users=[userid]): tagger.delete(item=docid, user=userid, tag=old_tag) catalog.reindex_doc(docid, get_doc(docid)) if tagger is None: tags = () else: tags = list(tagger.getTags(users=(context.__name__,))) tags.sort() return dict( api=api, my_tags=tags, error=error, old=old, new=new, )
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 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 tag_listing_view(context, request): page_title = 'Tag Listing' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is None: entries = () else: entries = [{'name': x[0], 'count': x[1]} for x in tags.getFrequency()] entries.sort(key=lambda x: x['name']) return dict(api=api, entries=entries, scope='site')
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 = catalog.document_map.docid_for_address(path) tags = find_tags(context) if tags is not None: # testing tags.update(item=docid, user=username, tags=values)
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 = resource_path(context) catalog = find_catalog(context) docid = catalog.document_map.docid_for_address(path) tags = find_tags(context) if tags is not None: # testing tags.update(item=docid, user=username, tags=values) catalog.reindex_doc(docid, context)
def evolve(root): tags = find_tags(root) dupe_ids = [] print "Searching for duplicate tags..." seen_tags = set() for id, tag in tags._tagid_to_obj.items(): if tag in seen_tags: dupe_ids.append(id) else: seen_tags.add(tag) tags._delTags(dupe_ids) print "Removed %d duplicate tags" % len(dupe_ids)
def manage_tags_view(context, request): page_title = 'Manage Tags' api = TemplateAPI(context, request, page_title) tagger = find_tags(context) userid = context.__name__ error = '' old = '' new = '' if 'form.rename' in request.POST: old_tag = request.POST['old_tag'] new_tag = request.POST['new_tag'] # check that tag contains only valid characters if re_tag.match(new_tag) is None: error = u'Value contains characters that are not allowed in a tag.' old = old_tag new = new_tag else: docids = tagger.getItems(tags=[old_tag], users=[userid]) to_update = {} for tagob in tagger.getTagObjects(items=docids, users=[userid]): if tagob.name == old_tag: name = new_tag else: name = tagob.name to_update.setdefault(tagob.item, []).append(name) for docid in docids: tagger.update(item=docid, user=userid, tags=to_update.get(docid, [])) if 'form.delete' in request.POST: old_tag = request.POST['old_tag'] for docid in tagger.getItems(tags=[old_tag], users=[userid]): tagger.delete(item=docid, user=userid, tag=old_tag) if tagger is None: tags = () else: tags = list(tagger.getTags(users=(context.__name__,))) tags.sort() return render_template_to_response( 'templates/profile_tagedit.pt', api=api, tags=tags, error=error, old=old, new=new, )
def tag_listing_view(context, request): page_title = 'Tag Listing' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is None: entries = () else: entries = [{'name': x[0], 'count': x[1]} for x in tags.getFrequency()] entries.sort(key=lambda x: x['name']) return dict( api=api, entries=entries, )
def tag_cloud_view(context, request): page_title = 'Tag Cloud' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is not None: cloud = [{'name': x[0], 'count': x[1]} for x in tags.getCloud()] limited = list(reversed(sorted(cloud, key=lambda x: x['count'])))[:100] entries = sorted(_calculateTagWeights(limited), key=lambda x: x['name']) else: entries = () return dict( api=api, entries=entries, )
def evolve(context): # Added a community index to tags print "Addinng a community index to tags..." tags = find_tags(context) assert not hasattr(tags, '_community_to_tagids') index = OOBTree.OOBTree() tags._community_to_tagids = index tag_objects = tags._tagid_to_obj.items() n_tags = len(tag_objects) for count, (id, tag) in enumerate(tag_objects): print "Updating %d/%d" % (count, n_tags), tag.name.encode('utf8') ids = index.get(tag.community) if ids is None: index[tag.community] = IOBTree.IOSet((id,)) else: ids.insert(id)
def evolve(context): # Added a community index to tags print "Addinng a community index to tags..." tags = find_tags(context) assert not hasattr(tags, '_community_to_tagids') index = OOBTree.OOBTree() tags._community_to_tagids = index tag_objects = tags._tagid_to_obj.items() n_tags = len(tag_objects) for count, (id, tag) in enumerate(tag_objects): print "Updating %d/%d" % (count, n_tags), tag.name.encode('utf8') ids = index.get(tag.community) if ids is None: index[tag.community] = IOBTree.IOSet((id, )) else: ids.insert(id)
def _getInfo(profile, content): community = context = find_community(content) if context is None: # try for content inside a profile context = find_interface(content, IProfile) if context is None: context_name = context_url = None else: context_name = context.title context_url = resource_path(context) tagger = find_tags(content) if tagger is not None: cloud = list(tagger.getCloud(items=(content.docid,))) tag_counts = sorted(cloud, key=lambda x: x[1], reverse=True)[:3] tags = [x[0] for x in tag_counts] else: tags = () content_type = get_content_type(content) desc = getattr(content, 'description', '') short = len(desc) > 256 and '%s...' % desc[:256] or desc if IPosts.providedBy(content): comment_count = len(content.get('comments', ())) else: comment_count = False content_creator = profile.__name__ if IComment.providedBy(content): # my content filter needs to know if a comment was made inside my post content_creator = content.__parent__.__parent__.creator return {'content_type': content_type.getTaggedValue('name'), 'userid': profile.__name__, 'context_name': context_name, 'context_url': context_url, 'content_creator': content_creator, 'url': resource_path(content), 'title': content.title, 'description': desc, 'short_description': short, 'allowed': principals_allowed_by_permission(content, 'view'), 'comment_count': comment_count, 'tags': tags, #XXX 'author': profile.title, 'profile_url': '/profiles/%s' % profile.__name__, 'thumbnail': '/profiles/%s/profile_thumbnail' % profile.__name__, 'timestamp': _NOW(), }
def community_tag_users_view(context, request): page_title = 'Tag Users' api = TemplateAPI(context, request, 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_resource(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=resource_url(target, request), title=target.title, users=users, )
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 _getInfo(profile, content): community = context = find_community(content) if context is None: # try for content inside a profile context = find_interface(content, IProfile) if context is None: context_name = context_url = None else: context_name = context.title context_url = resource_path(context) tagger = find_tags(content) if tagger is not None: cloud = list(tagger.getCloud(items=(content.docid,))) tag_counts = sorted(cloud, key=lambda x: x[1], reverse=True)[:3] tags = [x[0] for x in tag_counts] else: tags = () content_type = get_content_type(content) desc = getattr(content, "description", "") short = len(desc) > 80 and "%s..." % desc[:80] or desc if IPosts.providedBy(content): comment_count = len(content.get("comments", ())) else: comment_count = False content_creator = profile.__name__ if IComment.providedBy(content): # my content filter needs to know if a comment was made inside my post content_creator = content.__parent__.__parent__.creator return { "content_type": content_type.getTaggedValue("name"), "userid": profile.__name__, "context_name": context_name, "context_url": context_url, "content_creator": content_creator, "url": resource_path(content), "title": content.title, "description": desc, "short_description": short, "allowed": principals_allowed_by_permission(content, "view"), "comment_count": comment_count, "tags": tags, # XXX "author": profile.title, "profile_url": "/profiles/%s" % profile.__name__, "thumbnail": "/profiles/%s/profile_thumbnail" % profile.__name__, "timestamp": _NOW(), }
def visit(self, context): if ICommunity.providedBy(context): self.community = context self.row = { 'community': context.title, 'id': context.__name__, 'is_private': is_private(context), 'members': len(context.member_names), 'moderators': len(context.moderator_names), 'last_activity': context.content_modified, 'create_date': context.created, 'wiki_pages': 0, 'blog_entries': 0, 'blog_comments': 0, 'files': 0, 'calendar_events': 0, 'community_tags': set(), 'hits_this_month': 'Unknown', 'percent_engaged': 'Unknown' } elif self.community is None: return else: last_activity = getattr(context, 'content_modified', None) if (last_activity is not None and last_activity > self.row['last_activity']): self.row['last_activity'] = last_activity if IWikiPage.providedBy(context): self.row['wiki_pages'] += 1 elif IBlogEntry.providedBy(context): self.row['blog_entries'] += 1 elif IComment.providedBy(context): self.row['blog_comments'] += 1 elif ICommunityFile.providedBy(context): self.row['files'] += 1 elif ICalendarEvent.providedBy(context): self.row['calendar_events'] += 1 tags = find_tags(context) docid = getattr(context, 'docid', None) if docid is not None: for tag in tags.getTags([docid,]): self.row['community_tags'].add(tag)
def tag_listing_view(context, request): layout = request.layout_manager.layout layout.section_style = 'none' layout.page_title = 'Tag Listing' api = TemplateAPI(context, request, layout.page_title) tags = find_tags(context) if tags is None: entries = () else: entries = [{'name': x[0], 'count': x[1]} for x in tags.getFrequency()] entries.sort(key=lambda x: x['name']) return dict( api=api, entries=entries, scope='site' )
def community_tag_listing_view(context, request): page_title = 'Tag Listing' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is None: entries = () else: entries = [{'name': x[0], 'count': x[1]} for x in tags.getFrequency(community=context.__name__)] entries.sort(key=lambda x: x['name']) system_name = get_setting(context, 'system_name', 'KARL') return dict( api=api, entries=entries, crumbs='%s / Communities / %s' % (system_name, context.__name__), )
def add_tags(context, request, values): """ Add the specified tags. o Existing tags remain assigned. """ if values: if isinstance(values, basestring): values = [values] path = resource_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) catalog.reindex_doc(docid, context)
def community_tag_listing_view(context, request): page_title = 'Tag Listing' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is None: entries = () else: entries = [{'name': x[0], 'count': x[1]} for x in tags.getFrequency(community=context.__name__)] entries.sort(key=lambda x: x['name']) system_name = get_setting(context, 'title', 'KARL') return dict( api=api, entries=entries, scope='community', crumbs='%s / Communities / %s' % (system_name, context.__name__), )
def community_tag_users_view(context, request): layout = request.layout_manager.layout layout.page_title = 'Tag Users' api = TemplateAPI(context, request, layout.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_resource(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=resource_url(target, request), title=target.title, users=users, )
def community_tag_cloud_view(context, request): page_title = 'Tag Cloud' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is not None: cloud = [{'name': x[0], 'count': x[1]} for x in tags.getCloud(community=context.__name__)] limited = list(reversed(sorted(cloud, key=lambda x: x['count'])))[:100] entries = sorted(_calculateTagWeights(limited), key=lambda x: x['name']) else: entries = () system_name = get_setting(context, 'title', 'KARL') return dict( api=api, entries=entries, crumbs='%s / Communities / %s' % (system_name, context.__name__), )
def profile_tag_listing_view(context, request): page_title = 'Tag Listing' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is None: entries = () else: names = tags.getTags(users=(context.__name__,)) entries = [{'name': x[0], 'count': x[1]} for x in tags.getFrequency(names, user=context.__name__)] entries.sort(key=lambda x: x['name']) system_name = get_setting(context, 'title', 'KARL') return dict( api=api, entries=entries, scope='site', crumbs='%s / Profiles / %s' % (system_name, context.__name__), )
def tag_users_view(context, request): page_title = 'Tag Users' api = TemplateAPI(context, request, 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]): profile = profiles[userid] fullname = profile.firstname + ' ' + profile.lastname also = [x for x in tags.getTags(items=[docid], users=[userid]) if x != tag] users.append({'login': userid, 'fullname': fullname, 'also': also, }) else: users = () return render_template_to_response( 'templates/tagusers.pt', api=api, tag=tag, url=model_url(target, request), title=target.title, users=users, )
def profile_tag_listing_view(context, request): page_title = 'Tag Listing' api = TemplateAPI(context, request, page_title) tags = find_tags(context) if tags is None: entries = () else: names = tags.getTags(users=(context.__name__, )) entries = [{ 'name': x[0], 'count': x[1] } for x in tags.getFrequency(names, user=context.__name__)] entries.sort(key=lambda x: x['name']) system_name = get_setting(context, 'system_name', 'KARL') return dict( api=api, entries=entries, scope='site', crumbs='%s / Profiles / %s' % (system_name, context.__name__), )
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 = TemplateAPI(context, request, 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 = resource_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] catalog = find_catalog(context) dm = catalog.document_map tags = find_tags(context) if community is None and user is None: # Only show related tags portlet in global view related = tags.getRelatedTags(tag, user=user, community=community) else: related = [] 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_resource(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 = resource_url(context, request, 'tagusers.html', query={'tag': tag, 'docid': docid}) entry = { 'title': resource.title, 'description': getattr(resource, 'description', ''), 'href': resource_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, 'title', 'KARL') args['crumbs'] = '%s / %s / %s' % ( system_name, crumb_title, context.__name__) return dict(**args)
def get_object_tags(obj): path = resource_path(obj) catalog = find_catalog(obj) docid = catalog.document_map.docid_for_address(path) tags = find_tags(obj) return [tag.name for tag in tags.getTagObjects(items=(docid,))]
def show_profile_view(context, request): """Show a profile with actions if the current user""" page_title = 'View Profile' api = TemplateAPI(context, request, page_title) # Create display values from model object profile = {} for name in [name for name in context.__dict__.keys() if not name.startswith("_")]: profile_value = getattr(context, name) if profile_value is not None: # Don't produce u'None' profile[name] = unicode(profile_value) else: profile[name] = None if 'fax' not in profile: profile['fax'] = '' # BBB # 'websites' is a property, so the loop above misses it profile["websites"] = context.websites # ditto for 'title' profile["title"] = context.title if profile.has_key("languages"): profile["languages"] = context.languages if profile.has_key("department"): profile["department"] = context.department if profile.get("last_login_time"): stamp = context.last_login_time.strftime('%Y-%m-%dT%H:%M:%SZ') profile["last_login_time"] = stamp if profile.has_key("country"): # translate from country code to country name country_code = profile["country"] country = countries.as_dict.get(country_code, u'') profile["country"] = country # Display portrait photo = context.get('photo') display_photo = {} if photo is not None: display_photo["url"] = thumb_url(photo, request, PROFILE_THUMB_SIZE) else: display_photo["url"] = api.static_url + "/images/defaultUser.gif" profile["photo"] = display_photo # provide client data for rendering current tags in the tagbox client_json_data = dict( tagbox = get_tags_client_data(context, request), ) # Get communities this user is a member of, along with moderator info # communities = {} communities_folder = find_communities(context) user_info = find_users(context).get_by_id(context.__name__) if user_info is not None: for group in user_info["groups"]: if group.startswith("group.community:"): unused, community_name, role = group.split(":") if (communities.has_key(community_name) and role != "moderators"): continue community = communities_folder.get(community_name, None) if community is None: continue if has_permission('view', community, request): communities[community_name] = { "title": community.title, "moderator": role == "moderators", "url": resource_url(community, request), } communities = communities.values() communities.sort(key=lambda x:x["title"]) preferred_communities = [] my_communities = None name = context.__name__ # is this the current user's profile? if authenticated_userid(request) == name: preferred_communities = get_preferred_communities(communities_folder, request) my_communities = get_my_communities(communities_folder, request) tagger = find_tags(context) if tagger is None: tags = () else: tags = [] names = tagger.getTags(users=[context.__name__]) for name, count in sorted(tagger.getFrequency(names, user=context.__name__), key=lambda x: x[1], reverse=True, )[:10]: tags.append({'name': name, 'count': count}) # List recently added content num, docids, resolver = ICatalogSearch(context)( sort_index='creation_date', reverse=True, interfaces=[IContent], limit=5, creator=context.__name__, allowed={'query': effective_principals(request), 'operator': 'or'}, ) recent_items = [] for docid in docids: item = resolver(docid) if item is None: continue adapted = getMultiAdapter((item, request), IGridEntryInfo) recent_items.append(adapted) return render_to_response( 'templates/profile.pt', dict(api=api, profile=profile, actions=get_profile_actions(context, request), photo=photo, head_data=convert_to_script(client_json_data), communities=communities, my_communities=my_communities, preferred_communities=preferred_communities, tags=tags, recent_items=recent_items), request=request, )
def showtag_view(context, request, community=None, user=None, crumb_title=None): """Show a page for a particular tag, optionally refined by context.""" layout = request.layout_manager.layout layout.page_title = 'Show Tag' api = TemplateAPI(context, request, layout.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 = resource_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] layout.page_title = 'Show Tag ' + tag catalog = find_catalog(context) dm = catalog.document_map tags = find_tags(context) if community is None and user is None: # Only show related tags portlet in global view related = tags.getRelatedTags(tag, user=user, community=community) layout.add_portlet('related_tags', related) layout.section_style = 'none' else: related = [] 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_resource(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 = resource_url(context, request, 'tagusers.html', query={'tag': tag, 'docid': docid}) entry = { 'title': resource.title, 'description': getattr(resource, 'description', ''), 'href': resource_url(resource, request), 'type': get_content_type_name(resource), 'tagusers_href': tuhref, 'tagusers_count': tuh, } entries.append(entry) args = dict( api=api, # deprecated in ux2 tag=tag, entries=entries, related=related, # deprecated in ux2 ) 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)
def collect_profile_stats(context): """ Returns an iterator where for each user profile a dict is returned with the following keys:: + first_name + last_name + userid + date_created + is_staff + num_communities + num_communities_moderator + location + department + roles + num_documents + num_tags + documents_this_month """ communities = find_communities(context) search = ICatalogSearch(context) profiles = find_profiles(context) users = find_users(context) # Collect community membership membership = {} moderatorship = {} for community in communities.values(): for name in community.member_names: if name not in membership: membership[name] = 1 else: membership[name] += 1 for name in community.moderator_names: if name not in moderatorship: moderatorship[name] = 1 else: moderatorship[name] += 1 for profile in profiles.values(): info = users.get_by_id(profile.__name__) if info is not None: groups = info['groups'] else: groups = [] name = profile.__name__ stats = dict( first_name=profile.firstname, last_name=profile.lastname, userid=name, date_created=profile.created, location=profile.location, department=profile.department, is_staff='group.KarlStaff' in groups, roles=','.join(groups), num_communities=membership.get(name, 0), num_communities_moderator=moderatorship.get(name, 0), ) count, docids, resolver = search(creator=name) stats['num_documents'] = count begin = coarse_datetime_repr(datetime.datetime.now() - THIRTY_DAYS) count, docids, resolver = search( creator=name, creation_date=(begin, None), ) stats['documents_this_month'] = count tags = find_tags(context) stats['num_tags'] = len(tags.getTags(users=(name,))) yield stats
def tags(self): if self._tags is None: self._tags = find_tags(self.context) return self._tags
def show_profile_view(context, request): """Show a profile with actions if the current user""" page_title = "Profile: %s" % context.title api = TemplateAPI(context, request, page_title) # Create display values from model object profile = {} for name in [ name for name in context.__dict__.keys() if not name.startswith("_") ]: profile_value = getattr(context, name) if profile_value is not None: # Don't produce u'None' profile[name] = unicode(profile_value) else: profile[name] = None if 'fax' not in profile: profile['fax'] = '' # BBB # 'websites' is a property, so the loop above misses it profile["websites"] = context.websites # ditto for 'title' profile["title"] = context.title if profile.has_key("languages"): profile["languages"] = context.languages if profile.has_key("department"): profile["department"] = context.department if profile.get("last_login_time"): stamp = context.last_login_time.strftime('%Y-%m-%dT%H:%M:%SZ') profile["last_login_time"] = stamp if profile.has_key("country"): # translate from country code to country name country_code = profile["country"] country = countries.as_dict.get(country_code, u'') profile["country"] = country # Display portrait photo = context.get('photo') display_photo = {} if photo is not None: display_photo["url"] = thumb_url(photo, request, PROFILE_THUMB_SIZE) else: display_photo["url"] = api.static_url + "/images/defaultUser.gif" profile["photo"] = display_photo # provide client data for rendering current tags in the tagbox client_json_data = dict(tagbox=get_tags_client_data(context, request), ) # Get communities this user is a member of, along with moderator info # communities = {} communities_folder = find_communities(context) user_info = find_users(context).get_by_id(context.__name__) if user_info is not None: for group in user_info["groups"]: if group.startswith("group.community:"): unused, community_name, role = group.split(":") if (communities.has_key(community_name) and role != "moderators"): continue community = communities_folder.get(community_name, None) if community is None: continue if has_permission('view', community, request): communities[community_name] = { "title": community.title, "moderator": role == "moderators", "url": resource_url(community, request), } communities = communities.values() communities.sort(key=lambda x: x["title"]) preferred_communities = [] my_communities = None name = context.__name__ # is this the current user's profile? if authenticated_userid(request) == name: preferred_communities = get_preferred_communities( communities_folder, request) my_communities = get_my_communities(communities_folder, request) tagger = find_tags(context) if tagger is None: tags = () else: tags = [] names = tagger.getTags(users=[context.__name__]) for name, count in sorted( tagger.getFrequency(names, user=context.__name__), key=lambda x: x[1], reverse=True, )[:10]: tags.append({'name': name, 'count': count}) # List recently added content num, docids, resolver = ICatalogSearch(context)( sort_index='creation_date', reverse=True, interfaces=[IContent], limit=5, creator=context.__name__, allowed={ 'query': effective_principals(request), 'operator': 'or' }, ) recent_items = [] for docid in docids: item = resolver(docid) if item is None: continue adapted = getMultiAdapter((item, request), IGridEntryInfo) recent_items.append(adapted) recent_url = request.resource_url(context, 'recent_content.html') return dict(api=api, profile=profile, actions=get_profile_actions(context, request), photo=photo, head_data=convert_to_script(client_json_data), communities=communities, my_communities=my_communities, preferred_communities=preferred_communities, tags=tags, recent_items=recent_items, recent_url=recent_url)
def collect_community_stats(context): """ Returns an iterator of dicts where for each community in the site a dict is returned containing the following keys:: + 'community': The community's full title. + 'id': The community's name, used in the path to the community. + 'security state': The name of the community's current security state. Will be 'custom' if acl has been manually changed with edit_acl.html. + 'members': Total number of members, including moderators. + 'moderators': Number of moderators. + 'last_activity': Date of last time some content was added to or edited in this community. + 'create_date': Date community was created. + 'wiki_pages': Number of wiki pages in this community. + 'blog_entries': Number of blog entries in this community. + 'comments': Number of comments in this community. + 'files': Number of files in this community. + 'calendar_events': Number of calendar events in this community. + 'community_tags': Number of tags used in this community. Includes tags on content contained by the community. + 'percent_engaged': Percentage of community members that have contributed 2 items or more in the last 30 days. """ now = datetime.datetime.now() communities = find_communities(context) for community in communities.values(): stats = dict( community=community.title, id=community.__name__, members=len(community.member_names), moderators=len(community.moderator_names), last_activity=community.content_modified, create_date=community.created, wiki_pages=0, blog_entries=0, comments=0, files=0, calendar_events=0, ) active_users = {} def count(node): from pyramid.traversal import resource_path if IWikiPage.providedBy(node): stats['wiki_pages'] += 1 elif IBlogEntry.providedBy(node): stats['blog_entries'] += 1 elif IComment.providedBy(node): stats['comments'] += 1 elif ICommunityFile.providedBy(node): stats['files'] += 1 elif ICalendarEvent.providedBy(node): stats['calendar_events'] += 1 created = getattr(node, 'created', None) if created is not None and now - created < THIRTY_DAYS: creator = getattr(node, 'creator', None) if creator is not None: if creator not in active_users: active_users[creator] = 1 else: active_users[creator] += 1 if hasattr(node, '__getitem__') and hasattr(node, 'values'): for child in node.values(): count(child) if hasattr(node, '_p_deactivate'): node._p_deactivate() count(community) tags = find_tags(context) stats['community_tags'] = len(tags.getTags( community=community.__name__ )) if hasattr(community, '__custom_acl__'): stats['security_state'] = 'custom' else: workflow = get_workflow(ICommunity, 'security', community) stats['security_state'] = workflow.state_of(community) if stats['members'] != 0: engaged_users = len([v for v in active_users.values() if v >= 2]) stats['percent_engaged'] = 100.0 * engaged_users / stats['members'] else: stats['percent_engaged'] = 0 yield stats
def collect_community_stats(context): """ Returns an iterator of dicts where for each community in the site a dict is returned containing the following keys:: + 'community': The community's full title. + 'id': The community's name, used in the path to the community. + 'security state': The name of the community's current security state. Will be 'custom' if acl has been manually changed with edit_acl.html. + 'members': Total number of members, including moderators. + 'moderators': Number of moderators. + 'last_activity': Date of last time some content was added to or edited in this community. + 'create_date': Date community was created. + 'wiki_pages': Number of wiki pages in this community. + 'blog_entries': Number of blog entries in this community. + 'comments': Number of comments in this community. + 'files': Number of files in this community. + 'calendar_events': Number of calendar events in this community. + 'community_tags': Number of tags used in this community. Includes tags on content contained by the community. + 'percent_engaged': Percentage of community members that have contributed 2 items or more in the last 30 days. """ now = datetime.datetime.now() communities = find_communities(context) for community in communities.values(): stats = dict( community=community.title, id=community.__name__, members=len(community.member_names), moderators=len(community.moderator_names), last_activity=community.content_modified, create_date=community.created, wiki_pages=0, blog_entries=0, comments=0, files=0, calendar_events=0, ) active_users = {} def count(node): from repoze.bfg.traversal import model_path if IWikiPage.providedBy(node): stats['wiki_pages'] += 1 elif IBlogEntry.providedBy(node): stats['blog_entries'] += 1 elif IComment.providedBy(node): stats['comments'] += 1 elif ICommunityFile.providedBy(node): stats['files'] += 1 elif ICalendarEvent.providedBy(node): stats['calendar_events'] += 1 created = getattr(node, 'created', None) if created is not None and now - created < THIRTY_DAYS: creator = getattr(node, 'creator', None) if creator is not None: if creator not in active_users: active_users[creator] = 1 else: active_users[creator] += 1 if hasattr(node, '__getitem__') and hasattr(node, 'values'): for child in node.values(): count(child) if hasattr(node, '_p_deactivate'): node._p_deactivate() count(community) tags = find_tags(context) stats['community_tags'] = len(tags.getTags( community=community.__name__ )) if hasattr(community, '__custom_acl__'): stats['security_state'] = 'custom' else: workflow = get_workflow(ICommunity, 'security', community) stats['security_state'] = workflow.state_of(community) if stats['members'] != 0: engaged_users = len([v for v in active_users.values() if v >= 2]) stats['percent_engaged'] = 100.0 * engaged_users / stats['members'] else: stats['percent_engaged'] = 0 yield stats
def get_object_tags(obj): path = resource_path(obj) catalog = find_catalog(obj) docid = catalog.document_map.docid_for_address(path) tags = find_tags(obj) return [tag.name for tag in tags.getTagObjects(items=(docid, ))]
def test_find_tags(self): from karl.utils import find_tags context = testing.DummyModel() self.assertEqual(find_tags(context), None) context.tags = '1' self.assertEqual(find_tags(context), '1')
def get_tags(context): tags = find_tags(context) #community = find_community(context) return tags.getTags(items=[context.docid], #community=[community.docid], )