def main(argv=sys.argv): parser = create_karl_argparser( description='Add a fake blog tool to community for receiving mailin ' 'trace emails.') parser.add_argument('community', help='Community name.') parser.add_argument('file', help='Path to file to touch when a tracer ' 'email is received.') args = parser.parse_args(argv[1:]) env = args.bootstrap(args.config_uri) root, closer = env['root'], env['closer'] root, closer = args.get_root(args.inst) community = find_communities(root).get(args.community) if community is None: args.parser.error('Could not find community: %s' % args.community) blog = community.get('blog') if blog is not None: if len(blog) > 0: args.parser.error('Cannot replace blog with blog entries.') else: del community['blog'] community['blog'] = blog = MailinTraceBlog() out = args.out print >> out, 'Added mailin trace tool at: %s' % model_path(blog) settings = root._p_jar.root.instance_config settings['mailin_trace_file'] = args.file print >> out, 'The mailin trace file is: %s' % args.file transaction.commit() print >> out, ('You must restart the mailin daemon in order for the new ' 'settings to take effect.')
def checkPermission(self, info): """ Does user have permission to author content in the given context? Uses ACL security policy to test. """ users = find_users(self.context) for target in info['targets']: if 'error' in target: continue report_name = target.get('report') if report_name is not None: pd = find_peopledirectory(self.context) context = find_model(pd, report_name.split('+')) permission = "email" else: communities = find_communities(self.context) community = communities[target['community']] context = community[target['tool']] permission = "create" # XXX In theory could depend on target user = users.get_by_id(info['author']) if user is not None: user = dict(user) user['repoze.who.userid'] = info['author'] # BFG Security API always assumes http request, so we fabricate a # fake request. request = webob.Request.blank('/') request.environ['repoze.who.identity'] = user if not has_permission(permission, context, request): target['error'] = 'Permission Denied'
def checkPermission(self, info): """ Does user have permission to author content in the given context? Uses ACL security policy to test. """ users = find_users(self.context) for target in info['targets']: if 'error' in target: continue report_name = target.get('report') if report_name is not None: pd = find_peopledirectory(self.context) context = find_resource(pd, report_name.split('+')) permission = "email" else: communities = find_communities(self.context) community = communities[target['community']] context = community[target['tool']] permission = "create" # XXX In theory could depend on target user = users.get_by_id(info['author']) if user is not None: user = dict(user) # XXX check this! user['karl.identity'] = {'id': info['author']} # BFG Security API always assumes http request, so we fabricate a # fake request. request = Request.blank('/') request.environ['karl.identity'] = user request.context = self.context if not has_permission(permission, context, request): target['error'] = 'Permission Denied'
def main(argv=sys.argv): parser = create_karl_argparser( description='Add a fake blog tool to community for receiving mailin ' 'trace emails.' ) parser.add_argument('community', help='Community name.') parser.add_argument('file', help='Path to file to touch when a tracer ' 'email is received.') args = parser.parse_args(argv[1:]) env = args.bootstrap(args.config_uri) root, closer = env['root'], env['closer'] root, closer = args.get_root(args.inst) community = find_communities(root).get(args.community) if community is None: args.parser.error('Could not find community: %s' % args.community) blog = community.get('blog') if blog is not None: if len(blog) > 0: args.parser.error('Cannot replace blog with blog entries.') else: del community['blog'] community['blog'] = blog = MailinTraceBlog() out = args.out print >> out, 'Added mailin trace tool at: %s' % model_path(blog) settings = root._p_jar.root.instance_config settings['mailin_trace_file'] = args.file print >> out, 'The mailin trace file is: %s' % args.file transaction.commit() print >> out, ('You must restart the mailin daemon in order for the new ' 'settings to take effect.')
def __call__(self): context, request = self.context, self.request api = AdminTemplateAPI(context, request, "Admin UI: Send Email") admin_email = get_setting(context, "admin_email") system_name = get_setting(context, "system_name") profiles = find_profiles(context) admin = profiles[authenticated_userid(request)] from_emails = [ ("self", "%s <%s>" % (admin.title, admin.email)), ("admin", "%s Administrator <%s>" % (system_name, admin_email)), ] if "send_email" in request.params: mailer = getUtility(IMailDelivery) group = request.params["to_group"] users = find_users(context) search = ICatalogSearch(context) count, docids, resolver = search(interfaces=[IProfile]) n = 0 for docid in docids: profile = resolver(docid) if getattr(profile, "security_state", None) == "inactive": continue userid = profile.__name__ if group and not users.member_of_group(userid, group): continue message = Message() if request.params["from_email"] == "self": message["From"] = from_emails[0][1] message_from = admin.email else: message["From"] = from_emails[1][1] message_from = admin_email message["To"] = "%s <%s>" % (profile.title, profile.email) message["Subject"] = request.params["subject"] body = u"<html><body>%s</body></html>" % (request.params["text"]) message.set_payload(body.encode("UTF-8"), "UTF-8") message.set_type("text/html") mailer.send([profile.email], message) n += 1 status_message = "Sent message to %d users." % n if has_permission(ADMINISTER, context, request): redirect_to = model_url(context, request, "admin.html", query=dict(status_message=status_message)) else: redirect_to = model_url( find_communities(context), request, "all_communities.html", query=dict(status_message=status_message), ) return HTTPFound(location=redirect_to) return dict(api=api, menu=_menu_macro(), to_groups=self.to_groups, from_emails=from_emails)
def jquery_edit_preferred_view(context, request): request.response.cache_expires = 0 communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request, ignore_preferred=True) preferred = get_preferred_communities(communities_folder, request) return { 'api': TemplateAPI(context, request), 'my_communities': communities, 'preferred': preferred }
def jquery_edit_preferred_view(context, request): request.response_headerlist = [('Cache-Control', 'max-age=0, no-cache, no-store, private, must-revalidate')] communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request, ignore_preferred=True) preferred = get_preferred_communities(communities_folder, request) return { 'api': TemplateAPI(context, request), 'my_communities': communities, 'preferred': preferred }
def jquery_clear_preferred_view(context, request): request.response.cache_expires = 0 communities_folder = find_communities(context) set_preferred_communities(communities_folder, request, None) updated_communities = get_my_communities(communities_folder, request) return { 'api': TemplateAPI(context, request), 'my_communities': updated_communities, 'preferred': None, 'show_all': False, 'profile': None, 'status_message': 'Cleared preferred communities.'}
def jquery_list_preferred_view(context, request): request.response.cache_expires = 0 communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request) preferred = get_preferred_communities(communities_folder, request) return { 'api': TemplateAPI(context, request), 'my_communities': communities, 'preferred': preferred, 'show_all': False, 'profile': None, 'status_message': None}
def jquery_clear_preferred_view(context, request): request.response.cache_expires = 0 communities_folder = find_communities(context) set_preferred_communities(communities_folder, request, None) updated_communities = get_my_communities(communities_folder, request) return {'api': TemplateAPI(context, request), 'my_communities': updated_communities, 'preferred': None, 'show_all': False, 'profile': None, 'status_message': _(u'Cleared preferred communities.')}
def jquery_list_preferred_view(context, request): request.response_headerlist = [('Cache-Control', 'max-age=0, no-cache, no-store, private, must-revalidate')] communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request) preferred = get_preferred_communities(communities_folder, request) return { 'api': TemplateAPI(context, request), 'my_communities': communities, 'preferred': preferred, 'show_all': False, 'profile': None, 'status_message': None}
def jquery_set_preferred_view(context, request): request.response.cache_expires = 0 communities_folder = find_communities(context) communities = request.params.getall('preferred[]') set_preferred_communities(communities_folder, request, communities) updated_communities = get_my_communities(communities_folder, request) return { 'api': TemplateAPI(context, request), 'my_communities': updated_communities, 'preferred': communities, 'show_all': False, 'profile': None, 'status_message': 'Set preferred communities.'}
def jquery_set_preferred_view(context, request): request.response.cache_expires = 0 communities_folder = find_communities(context) communities = request.params.getall('preferred[]') set_preferred_communities(communities_folder, request, communities) updated_communities = get_my_communities(communities_folder, request) return {'api': TemplateAPI(context, request), 'my_communities': updated_communities, 'preferred': communities, 'show_all': False, 'profile': None, 'status_message': _(u'Set preferred communities.')}
def processMessage(self, message, info, text, attachments): community = find_communities(self.root)[info["community"]] target = tool = community[info["tool"]] # XXX this should be more like: if info["in_reply_to"] is not None: docid = int(hex_to_docid(info["in_reply_to"])) catalog = find_catalog(target) path = catalog.document_map.address_for_docid(docid) item = find_model(self.root, path) target = item IMailinHandler(target).handle(message, info, text, attachments)
def get_user_home(context, request): # Respect user's home_path, if set home, extra_path = _get_user_home_path(context, request) if home is not None: return home, extra_path # If user is member of only one community, home is that community communities = find_communities(context) community_names = get_user_community_names(context, request) if len(community_names) == 1: community = communities.get(community_names.pop(), None) if community is not None: return community, [] return communities, []
def get_user_home(context, request): # Respect user's home_path, if set home, extra_path = _get_user_home_path(context, request) if home is not None: return home, extra_path communities = find_communities(context) behavior = get_setting(context, 'default_home_behavior', 'one_community') if behavior == 'one_community': # If user is member of only one community, home is that community community_names = get_user_community_names(context, request) if len(community_names) == 1: community = communities.get(community_names.pop(), None) if community is not None: return community, [] return communities, []
def process_message(self, message, info, target, text, attachments): report_name = target.get('report') if report_name is not None: pd = find_peopledirectory(self.root) context = find_model(pd, report_name.split('+')) else: community = find_communities(self.root)[target['community']] context = tool = community[target['tool']] if target['in_reply_to'] is not None: docid = int(hex_to_docid(target['in_reply_to'])) catalog = find_catalog(context) path = catalog.document_map.address_for_docid(docid) item = find_model(self.root, path) context = item IMailinHandler(context).handle(message, info, text, attachments)
def processMessage(self, message, info, text, attachments): report_name = info.get('report') if report_name is not None: pd = find_peopledirectory(self.root) target = find_model(pd, report_name.split('+')) else: community = find_communities(self.root)[info['community']] target = tool = community[info['tool']] # XXX this should be more like: if info['in_reply_to'] is not None: docid = int(hex_to_docid(info['in_reply_to'])) catalog = find_catalog(target) path = catalog.document_map.address_for_docid(docid) item = find_model(self.root, path) target = item IMailinHandler(target).handle(message, info, text, attachments)
def process_message(self, message, info, target, text, attachments): report_name = target.get('report') if report_name is not None: pd = find_peopledirectory(self.root) context = find_resource(pd, report_name.split('+')) else: community = find_communities(self.root)[target['community']] context = community[target['tool']] if target['in_reply_to'] is not None: docid = int(hex_to_docid(target['in_reply_to'])) catalog = find_catalog(context) path = catalog.document_map.address_for_docid(docid) if path is None: # replied-to content doesn't exist anymore. # Do not process. return 'Content no longer exists.' item = find_resource(self.root, path) context = item IMailinHandler(context).handle(message, info, text, attachments)
def checkPermission(self, info): """ Uses ACL security policy to determine whether user has permission to author content in the given context. """ communities = find_communities(self.context) community = communities[info['community']] target = community[info['tool']] users = find_users(self.context) user = users.get_by_id(info['author']) if user is not None: user['repoze.who.userid'] = info['author'] permission = "create" # XXX In theory could depend on target # BFG Security API always assumes http request, so we fabricate a fake # request. request = webob.Request.blank('/') request.environ['repoze.who.identity'] = user info = {} if not has_permission(permission, target, request): info['error'] = 'Permission Denied' return info
def main(args): root, closer = args.get_root(args.inst) community = find_communities(root).get(args.community) if community is None: args.parser.error('Could not find community: %s' % args.community) blog = community.get('blog') if blog is not None: if len(blog) > 0: args.parser.error('Cannot replace blog with blog entries.') else: del community['blog'] community['blog'] = blog = MailinTraceBlog() out = args.out print >> out, 'Added mailin trace tool at: %s' % model_path(blog) settings = root._p_jar.root.instance_config settings['mailin_trace_file'] = args.file print >> out, 'The mailin trace file is: %s' % args.file transaction.commit() print >> out, ('You must restart the mailin daemon in order for the new ' 'settings to take effect.')
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 manage_communities_view(context, request): page_title = 'Manage Communities' api = TemplateAPI(context, request, page_title) users = find_users(context) communities_folder = find_communities(context) userid = context.__name__ # Handle cancel if request.params.get("form.cancel", False): return HTTPFound(location=resource_url(context, request)) # Handle form submission if request.params.get("form.submitted", False): for key in request.params: if key.startswith("leave_"): community_name = key[6:] community = communities_folder[community_name] # Not concerned about catching this exception, since checkbox # should not have been displayed in form unless user allowed # to leave. Assert merely guards integrity of the system. assert may_leave(userid, community) if userid in community.moderator_names: users.remove_group(userid, community.moderators_group_name) if userid in community.member_names: users.remove_group(userid, community.members_group_name) elif key.startswith("alerts_pref_"): community_name = key[12:] preference = int(request.params.get(key)) context.set_alerts_preference(community_name, preference) context.alert_attachments = request.params.get('attachments', 'link') path = resource_url(context, request) msg = '?status_message=Community+preferences+updated.' return HTTPFound(location=path + msg) # XXX Iterating over every community in the system isn't a particularly # efficient solution. Should use catalog. communities = [] for community in communities_folder.values(): if (userid in community.member_names or userid in community.moderator_names): alerts_pref = context.get_alerts_preference(community.__name__) display_community = { 'name': community.__name__, 'title': community.title, 'alerts_pref': [ { "value": IProfile.ALERT_IMMEDIATELY, "label": "Immediately", "selected": alerts_pref == IProfile.ALERT_IMMEDIATELY, }, { "value": IProfile.ALERT_DAILY_DIGEST, "label": "Daily Digest", "selected": alerts_pref == IProfile.ALERT_DAILY_DIGEST, }, { "value": IProfile.ALERT_NEVER, "label": "Never", "selected": alerts_pref == IProfile.ALERT_NEVER, }, { "value": IProfile.ALERT_WEEKLY_DIGEST, "label": "Weekly Digest", "selected": alerts_pref == IProfile.ALERT_WEEKLY_DIGEST, }, { "value": IProfile.ALERT_BIWEEKLY_DIGEST, "label": "Every two weeks Digest", "selected": alerts_pref == IProfile.ALERT_BIWEEKLY_DIGEST, }, ], 'may_leave': may_leave(userid, community), } communities.append(display_community) if len(communities) > 1: communities.sort(key=lambda x: x["title"]) return render_to_response( 'karl.views:templates/manage_communities.pt', dict(api=api, communities=communities, post_url=request.url, formfields=api.formfields, attachments=context.alert_attachments), request=request, )
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_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 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 __call__(self): context, request = self.context, self.request request.layout_manager.use_layout('admin') api = AdminTemplateAPI(context, request, 'Admin UI: Send Email') admin_email = get_setting(context, 'admin_email') system_name = get_setting(context, 'system_name') profiles = find_profiles(context) admin = profiles[authenticated_userid(request)] from_emails = [ ('self', '%s <%s>' % (admin.title, admin.email)), ('admin', '%s Administrator <%s>' % (system_name, admin_email)), ] if 'send_email' in request.params or 'submit' in request.params: mailer = getUtility(IMailDelivery) group = request.params['to_group'] users = find_users(context) search = ICatalogSearch(context) count, docids, resolver = search(interfaces=[IProfile]) n = 0 for docid in docids: profile = resolver(docid) if getattr(profile, 'security_state', None) == 'inactive': continue userid = profile.__name__ if group and not users.member_of_group(userid, group): continue message = Message() if request.params['from_email'] == 'self': message['From'] = from_emails[0][1] message_from = admin.email else: message['From'] = from_emails[1][1] message_from = admin_email message['To'] = '%s <%s>' % (profile.title, profile.email) message['Subject'] = request.params['subject'] body = u'<html><body>%s</body></html>' % ( request.params['text'] ) message.set_payload(body.encode('UTF-8'), 'UTF-8') message.set_type('text/html') mailer.send([profile.email], message) n += 1 status_message = "Sent message to %d users." % n if has_permission(ADMINISTER, context, request): redirect_to = resource_url( context, request, 'admin.html', query=dict(status_message=status_message)) else: redirect_to = resource_url( find_communities(context), request, 'all_communities.html', query=dict(status_message=status_message)) return HTTPFound(location=redirect_to) return dict( api=api, menu=_menu_macro(), to_groups = self.to_groups, from_emails=from_emails, )
def myprofile_ajax_view(context, request): results = {} # template provision if request.params.get('needsTemplate', 'false') in ('true', 'True'): # We need the template. So, let's fetch it. layout = request.layout_manager.layout results['microtemplate'] = layout.microtemplates['myprofile'] results['partials'] = [] # Fetch the data # 2nd column: my communities (preferred communities) communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request) communities = sorted(communities, key=attrgetter('last_activity_date'), reverse=True) communities_info = [ dict( title=community.title, description=community.description, url=community.url, actions=[dict( url=community.url + (a_name if a_name != 'overview' else 'view.html'), title=a_name.capitalize(), last=a_name == 'wiki', ) for a_name in ('overview', 'blog', 'calendar', 'files', 'wiki')], ) for community in communities[:5] ] # 3rd column: My Recent Activity recent_items = [] recent_items_batch = get_catalog_batch(context, request, batch_size=5, interfaces=[ICommunityContent], sort_index="modified_date", reverse=True, modified_by=authenticated_userid(request), allowed={'query': effective_principals(request), 'operator': 'or'}) for item in recent_items_batch["entries"]: adapted = getMultiAdapter((item, request), IGridEntryInfo) community = find_community(item) if community is not None: community_adapter = getMultiAdapter((community, request), ICommunityInfo) community_info = dict( url=community_adapter.url, title=community_adapter.title, ) else: community_info = None # Since this is json, we need a real dict... recent_items.append(dict( title=adapted.title, url=adapted.url, modified=item.modified.strftime('%Y-%m-%dT%H:%M:%S'), creator_title=adapted.creator_title, type=adapted.type, community=community_info, )) profiles = find_profiles(request.context) userid = authenticated_userid(request) profile = profiles.get(userid) photo = profile.get('photo') if photo is not None: icon_url = thumb_url(photo, request, (45,60)) else: icon_url = request.static_url('karl.views:static/images/defaultUser.gif') # Assemble the final result. results['data'] = { 'profile_name': profile.title, 'profile_url': request.resource_url(profile), 'icon_url': icon_url, 'logout_url': "%s/logout.html" % request.application_url, 'department': profile.department, 'position': profile.position, 'email': profile.email, 'extension': profile.extension, 'phone': profile.phone, 'panels': [{ 'class': 'mycommunities', 'title': 'My Active Communities', 'communities': communities_info, }, { 'class': 'myrecentitems', 'title': 'My Recent Activity', 'contexts': recent_items, }], } return results
def radar_ajax_view(context, request): # Example result set, for demonstrating the widget without # a real server database. results = {} # Datetime of the current search. (The client will pass it back # to us the next time, and we can decide if an update is needed) now = datetime.datetime.now() now_iso = now.isoformat() results['ts'] = now_iso ts_iso = request.params.get('ts', '') # template provision if request.params.get('needsTemplate', 'false') in ('true', 'True'): # We need the template. So, let's fetch it. layout = request.layout_manager.layout results['microtemplate'] = layout.microtemplates['radar'] results['partials'] = [] # Sometimes there is no need for an update. The server can just return # empty data. A condition is that a ts parameter is sent to us. The # other condition (does the client need an update?) is now simulated # with a random choice. if ts_iso and random.choice([False, True]): results['data'] = None else: # Fetch the data # 2nd column: my communities (preferred communities) communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request) communities_info = [ dict( title=community.title, description=community.description, url=community.url, actions=[ dict( url=community.url + (a_name if a_name != 'overview' else 'view.html'), title=a_name.capitalize(), last=a_name == 'files', ) for a_name in ('overview', 'blog', 'calendar', 'files', 'wiki') ], ) for community in communities[:5] ] # 3rd column: My Recent Activity recent_items = [] recent_items_batch = get_catalog_batch( context, request, batch_size=5, interfaces=[ICommunityContent], sort_index="modified_date", reverse=True, modified_by=authenticated_userid(request), allowed={ 'query': effective_principals(request), 'operator': 'or' }) for item in recent_items_batch["entries"]: adapted = getMultiAdapter((item, request), IGridEntryInfo) community = find_community(item) if community is not None: community_adapter = getMultiAdapter((community, request), ICommunityInfo) community_info = dict( url=community_adapter.url, title=community_adapter.title, ) else: community_info = None # Since this is json, we need a real dict... recent_items.append( dict( title=adapted.title, url=adapted.url, modified=adapted.modified, creator_title=adapted.creator_title, type=adapted.type, community=community_info, )) # Provide fake "approval items" for the "approvals" tab. approval_waitinglist_items = [{ 'title': 'Approval Waiting List', 'group': [{ 'title': 'e-Payment', 'count': 0, 'id': 'table1' }, { 'title': 'Grant Payment', 'count': 2, 'id': 'table2' }, { 'title': 'Contract Review', 'count': 3, }, { 'title': 'Contract Approval', 'count': 2, }, { 'title': 'Contract Payment', 'count': 1, }, { 'title': 'Hardware / Software Request', 'count': 4, }] }, { 'title': 'Payment Waiting List', 'group': [{ 'title': 'e-Payment', 'count': 0, }, { 'title': 'Grant Payment', 'count': 133, }, { 'title': 'Contract Payment', 'count': 116, }] }, { 'title': 'Accrual Waiting List', 'group': [{ 'title': 'Grant Accrual', 'count': 7, }] }, { 'title': 'Fixed Assets Waiting List', 'group': [{ 'title': 'e-Approval', 'count': 7, }, { 'title': 'e-Bridge for Posting', 'count': 3, }] }] approval_table1_items = [{ 'amt': '45.09', 'via': 'Check', 'approvedBy': 'Some Person', 'status': 'Approved', 'statusDate': '02/09/2012', 'overdueBy': '13', }, { 'amt': '13.00', 'via': 'Wire', 'approvedBy': 'Another Person', 'status': 'Submitted', 'statusDate': '02/14/2012', 'overdueBy': '16', }, { 'amt': '71.21', 'via': 'Check', 'approvedBy': 'Last Person', 'status': 'Approved', 'statusDate': '02/13/2012', 'overdueBy': '18', }] for i, row in enumerate(approval_table1_items): row['rowClass'] = 'even' if i % 2 else 'odd' import copy approval_table2_items = 2 * copy.deepcopy(approval_table1_items) for i, row in enumerate(approval_table2_items): row['rowClass'] = 'even' if i % 2 else 'odd' # Assemble the final result. results['data'] = { # home section 'home': [{ 'class': 'homepanel1', 'title': 'My Communities', 'communities': communities_info, }, { 'class': 'homepanel2', 'title': 'My Recent Activity', 'contexts': recent_items, }], # approvals section 'approvals': [{ 'class': 'approvalpanel1', 'waitinglist': { 'items': approval_waitinglist_items, }, }, { 'class': 'approvalpanel2', 'tables': [{ 'id': 'table1', 'title': 'Open Project Project', 'items': approval_table1_items, }, { 'id': 'table2', 'title': 'Very Open Project', 'items': approval_table2_items, }], }], } results['state'] = { 'chart1': { 'options': { 'title': 'Company Performance', 'hAxis': { 'title': 'Year', 'titleTextStyle': { 'color': 'red' }, }, 'width': 200, # Must have fixed width! (matching css) }, 'columns': [ ['string', 'Year'], ['number', 'Sales'], ['number', 'Expenses'], ], 'rows': [ ['2004', 1000, 400], ['2005', 1170, 460], ['2006', 660, 1120], ['2007', 1030, 540], ], }, 'chart2': { 'options': { 'title': 'Monthly Operating Revenue', 'hAxis': { 'title': 'Project', 'titleTextStyle': { 'color': 'red' }, }, 'width': 400, # Must have fixed width! (matching css) }, 'columns': [ ['string', 'Project'], ['number', 'Budgeted'], ['number', 'Actual'], ], 'rows': [ ['My First Project', 1000, 400], ['Another Project', 1170, 460], ['A Third Project', 660, 1120], ], }, } return results
def __call__(self): context, request = self.context, self.request api = AdminTemplateAPI(context, request, 'Admin UI: Send Email') admin_email = get_setting(context, 'admin_email') system_name = get_setting(context, 'system_name') profiles = find_profiles(context) admin = profiles[authenticated_userid(request)] from_emails = [ ('self', '%s <%s>' % (admin.title, admin.email)), ('admin', '%s Administrator <%s>' % (system_name, admin_email)), ] if 'send_email' in request.params: mailer = getUtility(IMailDelivery) group = request.params['to_group'] users = find_users(context) search = ICatalogSearch(context) count, docids, resolver = search(interfaces=[IProfile]) n = 0 for docid in docids: profile = resolver(docid) if getattr(profile, 'security_state', None) == 'inactive': continue userid = profile.__name__ if group and not users.member_of_group(userid, group): continue message = Message() if request.params['from_email'] == 'self': message['From'] = from_emails[0][1] message_from = admin.email else: message['From'] = from_emails[1][1] message_from = admin_email message['To'] = '%s <%s>' % (profile.title, profile.email) message['Subject'] = request.params['subject'] body = u'<html><body>%s</body></html>' % ( request.params['text']) message.set_payload(body.encode('UTF-8'), 'UTF-8') message.set_type('text/html') mailer.send([profile.email], message) n += 1 status_message = "Sent message to %d users." % n if has_permission(ADMINISTER, context, request): redirect_to = resource_url( context, request, 'admin.html', query=dict(status_message=status_message)) else: redirect_to = resource_url( find_communities(context), request, 'all_communities.html', query=dict(status_message=status_message)) return HTTPFound(location=redirect_to) return dict( api=api, menu=_menu_macro(), to_groups=self.to_groups, from_emails=from_emails, )
def test_find_communities(self): from karl.utils import find_communities context = testing.DummyModel() self.assertEqual(find_communities(context), None) cf = context['communities'] = testing.DummyModel() self.failUnless(find_communities(context) is cf)
def radar_ajax_view(context, request): # Example result set, for demonstrating the widget without # a real server database. results = {} # Datetime of the current search. (The client will pass it back # to us the next time, and we can decide if an update is needed) now = datetime.datetime.now() now_iso = now.isoformat() results['ts'] = now_iso ts_iso = request.params.get('ts', '') # template provision if request.params.get('needsTemplate', 'false') in ('true', 'True'): # We need the template. So, let's fetch it. layout = request.layout_manager.layout results['microtemplate'] = layout.microtemplates['radar'] results['partials'] = [] # Sometimes there is no need for an update. The server can just return # empty data. A condition is that a ts parameter is sent to us. The # other condition (does the client need an update?) is now simulated # with a random choice. if ts_iso and random.choice([False, True]): results['data'] = None else: # Fetch the data # 2nd column: my communities (preferred communities) communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request) communities_info = [ dict( title=community.title, description=community.description, url=community.url, actions=[dict( url=community.url + (a_name if a_name != 'overview' else 'view.html'), title=a_name.capitalize(), last=a_name == 'files', ) for a_name in ('overview', 'blog', 'calendar', 'files', 'wiki')], ) for community in communities[:5] ] # 3rd column: My Recent Activity recent_items = [] recent_items_batch = get_catalog_batch(context, request, batch_size=5, interfaces=[ICommunityContent], sort_index="modified_date", reverse=True, modified_by=authenticated_userid(request), allowed={'query': effective_principals(request), 'operator': 'or'}) for item in recent_items_batch["entries"]: adapted = getMultiAdapter((item, request), IGridEntryInfo) community = find_community(item) if community is not None: community_adapter = getMultiAdapter((community, request), ICommunityInfo) community_info = dict( url=community_adapter.url, title=community_adapter.title, ) else: community_info = None # Since this is json, we need a real dict... recent_items.append(dict( title=adapted.title, url=adapted.url, modified=adapted.modified, creator_title=adapted.creator_title, type=adapted.type, community=community_info, )) # Provide fake "approval items" for the "approvals" tab. approval_waitinglist_items = [{ 'title': 'Approval Waiting List', 'group': [{ 'title': 'e-Payment', 'count': 0, 'id': 'table1' }, { 'title': 'Grant Payment', 'count': 2, 'id': 'table2' }, { 'title': 'Contract Review', 'count': 3, }, { 'title': 'Contract Approval', 'count': 2, }, { 'title': 'Contract Payment', 'count': 1, }, { 'title': 'Hardware / Software Request', 'count': 4, } ] }, { 'title': 'Payment Waiting List', 'group': [{ 'title': 'e-Payment', 'count': 0, }, { 'title': 'Grant Payment', 'count': 133, }, { 'title': 'Contract Payment', 'count': 116, } ] }, { 'title': 'Accrual Waiting List', 'group': [{ 'title': 'Grant Accrual', 'count': 7, } ] }, { 'title': 'Fixed Assets Waiting List', 'group': [{ 'title': 'e-Approval', 'count': 7, }, { 'title': 'e-Bridge for Posting', 'count': 3, } ] }]; approval_table1_items = [{ 'amt': '45.09', 'via': 'Check', 'approvedBy': 'Some Person', 'status': 'Approved', 'statusDate': '02/09/2012', 'overdueBy': '13', }, { 'amt': '13.00', 'via': 'Wire', 'approvedBy': 'Another Person', 'status': 'Submitted', 'statusDate': '02/14/2012', 'overdueBy': '16', }, { 'amt': '71.21', 'via': 'Check', 'approvedBy': 'Last Person', 'status': 'Approved', 'statusDate': '02/13/2012', 'overdueBy': '18', }] for i, row in enumerate(approval_table1_items): row['rowClass'] = 'even' if i % 2 else 'odd' import copy approval_table2_items = 2 * copy.deepcopy(approval_table1_items) for i, row in enumerate(approval_table2_items): row['rowClass'] = 'even' if i % 2 else 'odd' # Assemble the final result. results['data'] = { # home section 'home': [{ 'class': 'homepanel1', 'title': 'My Communities', 'communities': communities_info, }, { 'class': 'homepanel2', 'title': 'My Recent Activity', 'contexts': recent_items, }], # approvals section 'approvals': [{ 'class': 'approvalpanel1', 'waitinglist': { 'items': approval_waitinglist_items, }, }, { 'class': 'approvalpanel2', 'tables': [{ 'id': 'table1', 'title': 'Open Project Project', 'items': approval_table1_items, }, { 'id': 'table2', 'title': 'Very Open Project', 'items': approval_table2_items, }], }], } results['state'] = { 'chart1': { 'options' : { 'title': 'Company Performance', 'hAxis': { 'title': 'Year', 'titleTextStyle': {'color': 'red'}, }, 'width': 200, # Must have fixed width! (matching css) }, 'columns': [ ['string', 'Year'], ['number', 'Sales'], ['number', 'Expenses'], ], 'rows': [ ['2004', 1000, 400], ['2005', 1170, 460], ['2006', 660, 1120], ['2007', 1030, 540], ], }, 'chart2': { 'options' : { 'title': 'Monthly Operating Revenue', 'hAxis': { 'title': 'Project', 'titleTextStyle': {'color': 'red'}, }, 'width': 400, # Must have fixed width! (matching css) }, 'columns': [ ['string', 'Project'], ['number', 'Budgeted'], ['number', 'Actual'], ], 'rows': [ ['My First Project', 1000, 400], ['Another Project', 1170, 460], ['A Third Project', 660, 1120], ], }, } return results
def manage_communities_view(context, request): assert IProfile.providedBy(context) page_title = 'Manage Communities' api = TemplateAPI(context, request, page_title) users = find_users(context) communities_folder = find_communities(context) userid = context.__name__ # Handle cancel if request.params.get("form.cancel", False): return HTTPFound(location=resource_url(context, request)) # Handle form submission if request.params.get("form.submitted", False): for key in request.params: if key.startswith("leave_"): community_name = key[6:] community = communities_folder[community_name] # Not concerned about catching this exception, since checkbox # should not have been displayed in form unless user allowed # to leave. Assert merely guards integrity of the system. assert may_leave(userid, community) if userid in community.moderator_names: users.remove_group(userid, community.moderators_group_name) if userid in community.member_names: users.remove_group(userid, community.members_group_name) elif key.startswith("alerts_pref_"): community_name = key[12:] preference = int(request.params.get(key)) context.set_alerts_preference(community_name, preference) context.alert_attachments = request.params.get('attachments', 'link') path = resource_url(context, request) msg = '?status_message=Community+preferences+updated.' return HTTPFound(location=path+msg) # XXX Iterating over every community in the system isn't a particularly # efficient solution. Should use catalog. communities = [] for community in communities_folder.values(): if (userid in community.member_names or userid in community.moderator_names): alerts_pref = context.get_alerts_preference(community.__name__) display_community = { 'name': community.__name__, 'title': community.title, 'alerts_pref': [ { "value": IProfile.ALERT_IMMEDIATELY, "label": "Immediately", "selected": alerts_pref == IProfile.ALERT_IMMEDIATELY, }, { "value": IProfile.ALERT_DIGEST, "label": "Digest", "selected": alerts_pref == IProfile.ALERT_DIGEST, }, { "value": IProfile.ALERT_NEVER, "label": "Never", "selected": alerts_pref == IProfile.ALERT_NEVER, }], 'may_leave': may_leave(userid, community), } communities.append(display_community) if len(communities) > 1: communities.sort(key=lambda x: x["title"]) return render_to_response( 'karl.views:templates/manage_communities.pt', dict(api=api, communities=communities, post_url=request.url, formfields=api.formfields, attachments=context.alert_attachments), request=request, )
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 make_non_staff(profile, inform_moderators=True): """ When a user is removed from the KarlStaff role, their community memberships are removed. Moderators of their communities are optionally informed via email. """ id = profile.__name__ moderators = {} users = find_users(profile) profile.categories = {} for group in list(users.get_by_id(id)['groups']): if group.startswith('group.community'): # Remove user from group users.remove_user_from_group(id, group) if not inform_moderators: continue # Keep track of moderators we need to email making sure # each moderator is emailed only once and each community is # only mentioned once in any given email. community_name = group.split(':')[1] moderators_group = ('group.community:%s:moderators' % community_name) for moderator in users.users_in_group(moderators_group): if moderator == id: continue # Really should only come up in unittests if moderator not in moderators: moderators[moderator] = set() moderators[moderator].add(community_name) if not inform_moderators: return communities = find_communities(profile) profiles = profile.__parent__ mailer = getUtility(IMailDelivery) for moderator_id in moderators: moderator = profiles[moderator_id] msg = Message() msg['From'] = get_setting(profile, 'admin_email') msg['To'] = '%s <%s>' % (moderator.title, moderator.email) msg['Subject'] = 'Notice that %s is now former staff' % profile.title former_communities = sorted( [communities[c] for c in moderators[moderator_id]], key=lambda x: x.title) app_url = get_setting(profile, 'offline_app_url') communities_info = [ dict(title=c.title, unremove_url='%s%s?user_id=%s' % (app_url, model_path(c, 'members', 'add_existing.html'), id)) for c in former_communities ] body = render( 'templates/email_notify_former_staff.pt', dict(name=profile.title, communities=communities_info), ) if isinstance(body, unicode): body = body.encode('UTF-8') msg.set_payload(body, 'UTF-8') msg.set_type('text/html') mailer.send([msg['To']], msg)
def myprofile_ajax_view(context, request): results = {} # template provision if request.params.get('needsTemplate', 'false') in ('true', 'True'): # We need the template. So, let's fetch it. layout = request.layout_manager.layout results['microtemplate'] = layout.microtemplates['myprofile'] results['partials'] = [] # Fetch the data # 2nd column: my communities (preferred communities) communities_folder = find_communities(context) communities = get_my_communities(communities_folder, request) communities = sorted(communities, key=attrgetter('last_activity_date'), reverse=True) communities_info = [ dict( title=community.title, description=community.description, url=community.url, actions=[ dict( url=community.url + (a_name if a_name != 'overview' else 'view.html'), title=a_name.capitalize(), last=a_name == 'wiki', ) for a_name in ('overview', 'blog', 'calendar', 'files', 'wiki') ], ) for community in communities[:5] ] # 3rd column: My Recent Activity recent_items = [] recent_items_batch = get_catalog_batch( context, request, batch_size=5, interfaces=[ICommunityContent], sort_index="modified_date", reverse=True, modified_by=authenticated_userid(request), allowed={ 'query': effective_principals(request), 'operator': 'or' }) for item in recent_items_batch["entries"]: adapted = getMultiAdapter((item, request), IGridEntryInfo) community = find_community(item) if community is not None: community_adapter = getMultiAdapter((community, request), ICommunityInfo) community_info = dict( url=community_adapter.url, title=community_adapter.title, ) else: community_info = None # Since this is json, we need a real dict... recent_items.append( dict( title=adapted.title, url=adapted.url, modified=item.modified.strftime('%Y-%m-%dT%H:%M:%S'), creator_title=adapted.creator_title, type=adapted.type, community=community_info, )) profiles = find_profiles(request.context) userid = authenticated_userid(request) profile = profiles.get(userid) photo = profile.get('photo') if photo is not None: icon_url = thumb_url(photo, request, (45, 60)) else: icon_url = request.static_url( 'karl.views:static/images/defaultUser.gif') # Assemble the final result. results['data'] = { 'profile_name': profile.title, 'profile_url': request.resource_url(profile), 'icon_url': icon_url, 'logout_url': "%s/logout.html" % request.application_url, 'department': profile.department, 'position': profile.position, 'email': profile.email, 'extension': profile.extension, 'phone': profile.phone, 'panels': [{ 'class': 'mycommunities', 'title': 'My Active Communities', 'communities': communities_info, }, { 'class': 'myrecentitems', 'title': 'My Recent Activity', 'contexts': recent_items, }], } return results
def isCommunity(self, name): """ See IMailinDispatcher. """ return name in find_communities(self.context)
def lookup_community(site, community_slug): communities = find_communities(site) return communities and communities.get(community_slug)