def get_preferred_communities(context, request): profiles = find_profiles(context) userid = authenticated_userid(request) profile = profiles[userid] # old profiles will not have this attribute, so to be safe use getattr preferred_communities = getattr(profile, 'preferred_communities', None) return preferred_communities
def author(self): profiles = find_profiles(self.context) profile = profiles[self.context.creator] return { "name": profile.title, "uri": model_url(profile, self.request) }
def test_delete_message(self): api = uuid.uuid4().hex with Replacer() as r: r.replace('opencore.views.mbox.authenticated_userid', _authenticated_user_id) site, from_, _, msg, thread_id, msg_id, _, _, _, _ = get_data() to = find_profiles(site)['admin'] self.mbt.send_message(site, from_, to, msg, should_commit=True) request = DummyRequest() request.api = api request.params['thread_id'] = thread_id request.params['message_id'] = msg_id delete_message(site, request) transaction.commit() try: raw_msg, msg = self.mbt.get_message(site, from_, 'inbox', thread_id, msg_id) except NoSuchThreadException: pass else: raise Exception('Expected a NoSuchThreadException here')
def test_add_message(self): subject = uuid.uuid4().hex payload = uuid.uuid4().hex site, _ = open_root(get_default_config()) to = find_profiles(site)['sarah'] with Replacer() as r: r.replace('opencore.views.mbox.authenticated_userid', _authenticated_user_id) r.replace('opencore.views.mbox._get_profile_details', lambda context, request, user: {}) request = DummyRequest(method='POST') request.api = DummyAPI() request.api.find_profile = (lambda userid: self.bob if userid == 'bob' else self.alice) request.POST = MultiDict([ ('to[]', 'bob'), ('subject', subject), ('payload', payload), ]) response = add_message(site, request) self.assertTrue("mbox_thread" in response.location) transaction.commit()
def test_get_unread(self): api = uuid.uuid4().hex user_name = 'admin' with Replacer() as r: r.replace('opencore.views.mbox.authenticated_userid', _authenticated_user_id) site, from_, _, msg, thread_id, msg_id, _, _, _, _ = get_data() to = find_profiles(site)[user_name] self.mbt.send_message(site, from_, to, msg, should_commit=True) request = DummyRequest() request.api = api request.params['thread_id'] = thread_id request.params['message_id'] = msg_id mark_message_read(site, request) transaction.commit() self.mbt.send_message(site, from_, to, msg, should_commit=True) transaction.commit() unread = self.mbt.get_unread(site, user_name) self.assertTrue(unread >= 0)
def _get_user_home_path(context, request): """If currently authenticated user has a 'home_path' set, create a response redirecting user to that path. Otherwise return None. """ userid = authenticated_userid(request) if userid is None: return None, None site = find_site(context) profiles = find_profiles(site) profile = profiles.get(userid, None) if profile is None: return None, None home_path = getattr(profile, 'home_path', None) if home_path: # OSI sets this to a single space to mean None home_path = home_path.strip() if not home_path: return None, None tdict = traverse(site, home_path) target = tdict['context'] view_name = tdict['view_name'] subpath = list(tdict['subpath']) if view_name: subpath.insert(0, view_name) return target, subpath
def creator_url(self): if self._profiles is None: self._profiles = find_profiles(self.context) if self._profile is None: self._profile = self._profiles.get(self.context.creator, None) if self._creator_url is None: self._creator_url = model_url(self._profile, self.request) return self._creator_url
def modified_by_profile(self): if self._modified_by_profile is None: modified_by = getattr(self.context, 'modified_by', None) if modified_by is None: modified_by = self.context.creator if self._profiles is None: self._profiles = find_profiles(self.context) self._modified_by_profile = self._profiles.get(modified_by, None) return self._modified_by_profile
def handle_submit(self, converted): try: context = self.context request = self.request key = request.params.get('key') if not key or len(key) != 40: e = ResetFailed() e.page_title = 'Password Reset URL Problem' raise e users = find_users(context) user = users.get_by_login(converted['login']) if user is None: # XXX should be part of form validation raise Exception(login='******') userid = user.get('id') if userid is None: userid = user['login'] profiles = find_profiles(context) profile = profiles.get(userid) if profile is None: # XXX should be part of form validation raise Exception(login='******') if key != getattr(profile, 'password_reset_key', None): e = ResetFailed() e.page_title = 'Password Reset Confirmation Problem' raise e now = datetime.datetime.now() t = getattr(profile, 'password_reset_time', None) if t is None or now - t > max_reset_timedelta: e = ResetFailed() e.page_title = 'Password Reset Confirmation Key Expired' raise e # The key matched. Clear the key and reset the password. profile.password_reset_key = None profile.password_reset_time = None password = converted['password'].encode('UTF-8') users.change_password(userid, password) page_title = 'Password Reset Complete' api = request.api api.page_title = page_title return render_template_to_response( 'templates/reset_complete.pt', api=api, login=converted['login'], password=converted['password'], ) except ResetFailed, e: api = request.api api.page_title = e.page_title return render_template_to_response('templates/reset_failed.pt', api=api)
def __init__(self, *args): super(MembersBaseController,self).__init__(*args) self.community = find_interface(self.context, ICommunity) self.actions = _get_manage_actions(self.community, self.request) self.profiles = find_profiles(self.context) self.system_name = get_setting( self.context, 'system_name', 'OpenCore' ) self.data['actions']=self.actions
def creator_title(self): if self._profiles is None: self._profiles = find_profiles(self.context) if self._profile is None: self._profile = self._profiles.get(self.context.creator, None) if self._creator_title is None: self._creator_title = getattr(self._profile, "title", "no profile title") return self._creator_title
def _emit(self, event): # Get community in which event occurred and alert members community = find_community(event['content']) if not community: log.warning('No community found for event: %s' % str(event)) return profiles = find_profiles(event['content']) all_names = community.member_names | community.moderator_names for profile in [profiles[name] for name in all_names]: self.emit_to_user(profile, community, event)
def show_forum_view(context, request): page_title = context.title api = request.api actions = [] if has_permission('create', context, request): actions.append(('Add Forum Topic', 'add_forum_topic.html')) if has_permission('edit', context, request): actions.append(('Edit', 'edit.html')) if has_permission('delete', context, request): actions.append(('Delete', 'delete.html')) profiles = find_profiles(context) appdates = getUtility(IAppDates) topic_batch = get_topic_batch(context, request) topic_entries = topic_batch['entries'] topics = [] for topic in topic_entries: D = {} profile = profiles.get(topic.creator) posted_by = getattr(profile, 'title', None) date = appdates(topic.created, 'longform') D['url'] = model_url(topic, request) D['title'] = topic.title D['posted_by'] = posted_by D['date'] = date D['number_of_comments'] = len(topic['comments']) topics.append(D) # In the intranet side, the backlinks should go to the show_forums # view (the default) forums = context.__parent__ backto = { 'href': model_url(forums, request), 'title': forums.title, } # Get a layout layout_provider = get_layout_provider(context, request) layout = layout_provider('generic') return render_template_to_response( 'templates/show_forum.pt', api = api, actions = actions, title = context.title, topics = topics, batch_info = topic_batch, backto=backto, layout=layout, )
def __init__(self, context, request): self.context = context self.request = request self.community = find_interface(context, ICommunity) self.profiles = find_profiles(self.community) self.api = request.api self.actions = _get_manage_actions(self.community, request) self.desc = ('Use the form below to remove members or to resend invites ' 'to people who have not accepted your invitation to join ' 'this community.') self.defaults = self.form_defaults()
def _member_profile_batch(context, request): community = find_interface(context, ICommunity) member_names = community.member_names profiles_path = model_path(find_profiles(context)) batch = get_catalog_batch( context, request, batch_size = 12, interfaces = [IProfile], path={'query': profiles_path, 'depth': 1}, allowed={'query': effective_principals(request), 'operator': 'or'}, name = list(member_names), sort_index='lastfirst', ) return batch
def _grid_item(item, request): creator_name, creator_url = 'Unknown', None profiles = find_profiles(item) creator = getattr(item, 'creator', None) if creator is not None and creator in profiles: profile = profiles[creator] creator_name = profile.title creator_url = model_url(profile, request) return dict( path=model_path(item), url=model_url(item, request), title=item.title, modified=_format_date(item.modified), creator_name=creator_name, creator_url=creator_url, )
def community_tag_users_view(context, request): page_title = 'Tag Users' api = request.api api.page_title = page_title tag = request.params.get('tag', None) docid = request.params.get('docid', None) # Test for some cases if tag is None: return HTTPBadRequest('Missing parameter for tag') if docid is None: return HTTPBadRequest('Missing parameter for docid') docid = int(docid) tags = find_tags(context) profiles = find_profiles(context) catalog = find_catalog(context) address = catalog.document_map.address_for_docid(docid) target = find_model(context, address) if tags is not None and profiles is not None: users = [] for userid in tags.getUsers(tags=[tag], items=[docid], community=context.__name__): profile = profiles[userid] fullname = profile.firstname + ' ' + profile.lastname also = [x for x in tags.getTags(items=[docid], users=[userid], community=context.__name__) if x != tag] users.append({'login': userid, 'fullname': fullname, 'also': also, }) else: users = () return dict( api=api, tag=tag, url=model_url(target, request), title=target.title, users=users, )
def test_mark_message_read(self): api = uuid.uuid4().hex with Replacer() as r: r.replace('opencore.views.mbox.authenticated_userid', _authenticated_user_id) site, from_, _, msg, thread_id, msg_id, _, _, _, _ = get_data() to = find_profiles(site)['admin'] self.mbt.send_message(site, from_, to, msg, should_commit=True) request = DummyRequest() request.api = api request.params['thread_id'] = thread_id request.params['message_id'] = msg_id mark_message_read(site, request) transaction.commit() raw_msg, msg = self.mbt.get_message(site, from_, 'inbox', thread_id, msg_id) self.assertEquals(raw_msg.flags, ['READ'])
def _send_moderators_changed_email(community, community_href, new_moderators, old_moderators, cur_moderators, prev_moderators): info = _get_common_email_info(community, community_href) subject_fmt = 'Change in moderators for %s' subject = subject_fmt % info['c_title'] body_template = get_template('templates/email_moderators_changed.pt') profiles = find_profiles(community) all_moderators = cur_moderators | prev_moderators to_profiles = [profiles[name] for name in all_moderators] to_addrs = ["%s <%s>" % (p.title, p.email) for p in to_profiles] mailer = getUtility(IMailDelivery) msg = Message() msg['From'] = info['mfrom'] msg['To'] = ",".join(to_addrs) msg['Subject'] = subject body = body_template( system_name=info['system_name'], community_href=info['c_href'], community_name=info['c_title'], new_moderators=[profiles[name].title for name in new_moderators], old_moderators=[profiles[name].title for name in old_moderators], cur_moderators=[profiles[name].title for name in cur_moderators], prev_moderators=[profiles[name].title for name in prev_moderators] ) if isinstance(body, unicode): body = body.encode("UTF-8") msg.set_payload(body, "UTF-8") msg.set_type('text/html') mailer.send(info['mfrom'], to_addrs, msg)
def comments_to_display(request, profile_thumb_size=None): from opencore.views.people import PROFILE_THUMB_SIZE profile_thumb_size = profile_thumb_size or PROFILE_THUMB_SIZE def thumb_url(image, request, size): """ Return the url for displaying the image with dimensions bounded by given size. """ assert IImage.providedBy(image), "Cannot take thumbnail of non-image." return model_url(image, request, 'thumb', '%dx%d.jpg' % size) context = request.context appdates = getUtility(IAppDates) profiles = find_profiles(context) api = request.api # Convert comments into a digestable form for the template comments = [] if 'comments' not in context: return comments for comment in context['comments'].values(): profile = profiles.get(comment.creator) author_name = profile.title author_url = model_url(profile, request) newc = {} newc['id'] = comment.__name__ if has_permission('edit', comment, request): newc['edit_url'] = model_url(comment, request, 'edit.html') newc['delete_url'] = model_url(comment, request, 'delete.html') else: newc['edit_url'] = None newc['delete_url'] = None # Display portrait photo = profile.get('photo') photo_url = {} if photo is not None: photo_url = thumb_url(photo, request, profile_thumb_size) else: photo_url = api.static_url + "/img/default_user.png" newc["portrait_url"] = photo_url newc['author_url'] = author_url newc['author_name'] = author_name newc['author_country'] = profile.country newc['author_organization'] = profile.organization newc['date'] = appdates(comment.created, 'longform') newc['timestamp'] = comment.created newc['text'] = comment.text if( 'IComment' not in api.get_interfaces(comment.__parent__.__parent__) ): # this is a level 1 comment newc['url'] = model_url(comment.__parent__.__parent__, request) + '#comment-' + comment.__name__ else : # this is a reply newc['url'] = model_url(comment.__parent__.__parent__.__parent__.__parent__, request) + '#comment-' + comment.__parent__.__parent__.__name__ + '-' + comment.__name__ # a bit crude if hasattr(api, 'like_count'): newc['nlikes'] = api.like_count(comment) # Fetch the attachments info newc['attachments'] = fetch_attachments(comment, request) # handle comment replies newc['comment_reply_url'] = model_url(comment, request, 'comment.html') replies = [] if 'comments' in comment: for reply in comment['comments'].values(): newr = {} newr['id'] = reply.__name__ if has_permission('edit', reply, request): newr['edit_url'] = model_url(reply, request, 'edit.html') newr['delete_url'] = model_url(reply, request, 'delete.html') else: newr['edit_url'] = None newr['delete_url'] = None reply_profile = profiles.get(reply.creator) reply_author_name = reply_profile.title reply_author_url = model_url(reply_profile, request) # Display portrait reply_photo = reply_profile.get('photo') reply_photo_url = {} if reply_photo is not None: reply_photo_url = thumb_url(reply_photo, request, profile_thumb_size) else: reply_photo_url = api.static_url + "/img/default_user.png" newr["portrait_url"] = reply_photo_url newr['author_url'] = reply_author_url newr['author_name'] = reply_author_name newr['author_country'] = reply_profile.country newr['author_organization'] = reply_profile.organization newr['date'] = appdates(reply.created, 'longform') newr['timestamp'] = reply.created newr['text'] = reply.text # a bit crude if hasattr(api, 'like_count'): newc['nlikes'] = api.like_count(reply) replies.append(newr) replies.sort(key=lambda x: x['timestamp']) newc['comment_replies'] = replies comments.append(newc) comments.sort(key=lambda x: x['timestamp']) return comments
def find_profile(self, uid): profiles = find_profiles(self.context) return profiles.get(uid, None)
def login_view(context, request): plugins = request.environ.get('repoze.who.plugins', {}) auth_tkt = plugins.get('auth_tkt') came_from = _fixup_came_from(request, request.POST.get('came_from')) if request.params.get('form.submitted', None) is not None: challenge_qs = {'came_from': came_from} # identify login = request.POST.get('login') password = request.POST.get('password') if login is None or password is None: return HTTPFound(location='%s/login.html' % request.application_url) credentials = {'login': login, 'password': password} max_age = request.POST.get('max_age') if max_age is not None: credentials['max_age'] = int(max_age) # authenticate authenticators = filter(None, [plugins.get(name) for name in ['zodb', 'zodb_impersonate']]) userid = None if authenticators: reason = 'Bad username or password' else: reason = 'No authenticatable users' for plugin in authenticators: userid = plugin.authenticate(request.environ, credentials) if userid: break # if not successful, try again if not userid: challenge_qs['reason'] = reason return HTTPFound(location='%s/login.html?%s' % (request.application_url, urlencode(challenge_qs, doseq=True))) # else, remember credentials['repoze.who.userid'] = userid if auth_tkt is not None: remember_headers = auth_tkt.remember(request.environ, credentials) else: remember_headers = [] # log the time on the user's profile. profiles = find_profiles(context) if profiles is not None: profile = profiles.get(userid) if profile is not None: profile.last_login_time = datetime.utcnow() # and redirect return HTTPFound(headers=remember_headers, location=came_from) page_title = '' # Per #366377, don't say what screen api = request.api api.page_title = page_title came_from = _fixup_came_from(request, request.params.get('came_from', request.url)) api.status_message = request.params.get('reason', None) response = render_template_to_response( 'templates/login.pt', api=api, came_from=came_from, nothing='', app_url=request.application_url, ) if auth_tkt is not None: forget_headers = auth_tkt.forget(request.environ, {}) response.headers.update(forget_headers) return response
def test_show_mbox(self): _people_url = uuid.uuid4().hex _firstname = uuid.uuid4().hex _lastname = uuid.uuid4().hex _country = uuid.uuid4().hex class _DummyAPI(object): static_url = '/foo/bar' def find_profile(*ignored_args, **ignored_kwargs): class _Dummy(object): firstname = _firstname lastname = _lastname country = _country organization = uuid.uuid4().hex thumb_url = lambda _profile, _request: '/test-thumb.jpg' return _Dummy() people_url = _people_url with Replacer() as r: r.replace('opencore.views.mbox.authenticated_userid', _authenticated_user_id) r.replace('opencore.views.mbox._get_profile_details', lambda context, request, user: {}) site, from_, _, msg, thread_id, _, _, _, payload, _ = get_data() to = find_profiles(site)['admin'] self.mbt.send_message(site, from_, to, msg, should_commit=True) site, _ = open_root(get_default_config()) request = DummyRequest() request.params['thread_id'] = thread_id request.api = _DummyAPI() response = show_mbox_thread(site, request) self.assertTrue(isinstance(response['api'], _DummyAPI)) self.assertTrue(len(response['messages']), 1) message = response['messages'][0] flags = message['flags'] if flags: self.assertEquals(flags, ['READ']) self.assertEquals(message['from'], 'admin') self.assertEquals(message['from_country'], _country) self.assertEquals(message['from_firstname'], _firstname) self.assertEquals(message['from_lastname'], _lastname) self.assertEquals(message['from_photo'], '/test-thumb.jpg') self.assertEquals(message['payload'], payload) self.assertTrue(len(message['payload']) > 20) self.assertTrue(len(message['queue_id']) > 20) self.assertTrue(len(message['to_data']) == 2) to_data = message['to_data'] for to_datum in to_data: self.assertEquals(to_datum['country'], _country) self.assertEquals(to_datum['firstname'], _firstname) self.assertEquals(to_datum['lastname'], _lastname) name = to_datum['name'] self.assertTrue(name in ('joe', 'sarah')) self.assertEquals(to_datum['photo_url'], '/test-thumb.jpg')
def send_digests(self, context): mailer = getUtility(IMailDelivery) system_name = get_setting(context, "system_name", "OpenCore") admin_email = get_setting(None, 'admin_email', '*****@*****.**') #system_email_domain = get_setting(context, "system_email_domain") sent_from = admin_email #"%s@%s" % (admin_name, system_email_domain) from_addr = "%s notification <%s>" % (system_name, sent_from) subject = "%s: Today's Challenge Daily Digest" % system_name site_url = get_setting(context, 'public_domain_root', 'http://localhost:6543/') template = get_template("email_digest.pt") for profile in find_profiles(context).values(): if not profile._pending_alerts: continue # Perform each in its own transaction, so a problem with one # user's email doesn't block all others transaction.manager.begin() try: attachments = [] for alert in profile._pending_alerts: attachments += alert['attachments'] msg = MIMEMultipart() if attachments else Message() msg["From"] = from_addr msg["To"] = "%s <%s>" % (profile.title, profile.email) msg["Subject"] = subject profile_url='%sprofiles/%s/' % (site_url, profile.__name__) body_text = template( system_name=system_name, alerts=profile._pending_alerts, site_url=site_url, manage_preferences_href=profile_url, creator=profile, profile_image_url='%sprofile_thumbnail' % profile_url, profile_image_thumb_url='%sprofile_thumbnail' % profile_url ) if isinstance(body_text, unicode): body_text = body_text.encode("UTF-8") if attachments: # pragma: no cover body = MIMEText(body_text, 'html', 'utf-8') msg.attach(body) else: msg.set_payload(body_text, "UTF-8") msg.set_type("text/html") for attachment in attachments: # pragma: no cover msg.attach(attachment) mailer.send(sent_from, [profile.email,], msg) del profile._pending_alerts[:] transaction.manager.commit() except Exception, e: # Log error and continue log.error("Error sending digest to %s <%s>" % (profile.title, profile.email)) b = StringIO() traceback.print_exc(file=b) log.error(b.getvalue()) b.close() transaction.manager.abort()
def rename_user(context, old_name, new_name, merge=False, out=None): """ Renames a user with the given userid to a new userid. If `merge` is `True` a user is expected to already exist with userid `new_name`. Moves all content and group memberships from old user to new user before removing the old user. """ profiles = find_profiles(context) users = find_users(context) old_user = users.get_by_id(old_name) if old_name not in profiles: raise ValueError("No such profile: %s" % old_name) if merge: if old_user is not None and users.get_by_id(new_name) is None: raise ValueError("No such user: %s" % new_name) if new_name not in profiles: raise ValueError("No such profile: %s" % new_name) if out is not None: print >> out, "Merging user from %s to %s." % (old_name, new_name) if old_user is not None: for group in old_user["groups"]: if not users.member_of_group(new_name, group): users.add_user_to_group(new_name, group) users.remove(old_name) del profiles[old_name] else: if users.get_by_id(new_name) is not None: raise ValueError("User already exists: %s" % new_name) if new_name in profiles: raise ValueError("Profile already exists: %s" % new_name) if out is not None: print >> out, "Renaming user %s to %s." % (old_name, new_name) if old_user is not None: users.add(new_name, new_name, old_user["password"], old_user["groups"], encrypted=True) users.remove(old_name) profile = profiles[old_name] del profiles[old_name] profiles[new_name] = profile catalog = find_catalog(context) search = ICatalogSearch(context) index = catalog["creator"] count, docids, resolver = search(creator=old_name) for docid in docids: doc = resolver(docid) if out is not None: print >> out, "Updating creator for %s." % model_path(doc) doc.creator = new_name index.reindex_doc(docid, doc) index = catalog["modified_by"] count, docids, resolver = search(modified_by=old_name) for docid in docids: doc = resolver(docid) if out is not None: print >> out, "Updating modified_by for %s." % model_path(doc) doc.modified_by = new_name index.reindex_doc(docid, doc)
def __init__(self, context, request): self.context = context self.request = request self.profile = find_profiles(context).get(context.creator)
def join_community_view(context, request): """ User sends an email to community moderator(s) asking to join the community. Email contains a link to "add_existing" view, in members, that a moderator can use to add member to the community. """ assert ICommunity.providedBy(context) # Get logged in user profiles = find_profiles(context) user = authenticated_userid(request) profile = profiles[user] # Handle form submission if "form.submitted" in request.POST: message = request.POST.get("message", "") moderators = [profiles[id] for id in context.moderator_names] mail = Message() mail["From"] = "%s <%s>" % (profile.title, profile.email) mail["To"] = ",".join( ["%s <%s>" % (p.title, p.email) for p in moderators] ) mail["Subject"] = "Request to join %s community" % context.title body_template = get_template("templates/email_join_community.pt") profile_url = model_url(profile, request) accept_url=model_url(context, request, "members", "add_existing.html", query={"user_id": user}) body = body_template( message=message, community_title=context.title, person_name=profile.title, profile_url=profile_url, accept_url=accept_url ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [p.email for p in moderators] mailer = getUtility(IMailDelivery) mailer.send(profile.email, recipients, mail) status_message = "Your request has been sent to the moderators." location = model_url(context, request, query={"status_message": status_message}) return HTTPFound(location=location) # Show form page_title = "Join " + context.title api = request.api api.page_title = page_title return render_template_to_response( "templates/join_community.pt", api=api, profile=profile, community=context, post_url=model_url(context, request, "join.html"), formfields=api.formfields, )
def set_preferred_communities(context, request, communities): profiles = find_profiles(context) userid = authenticated_userid(request) profile = profiles[userid] profile.preferred_communities = communities
def show_members_view(context, request): """Default view of community members (with/without pictures).""" page_title = 'Community Members' api = request.api api.page_title = page_title # Filter the actions based on permission in the **community** community = find_interface(context, ICommunity) actions = _get_manage_actions(community, request) # Did we get the "show pictures" flag? hp = request.params.has_key('hide_pictures') mu = model_url(context, request) submenu = [ {'label': 'Show Pictures', 'href': mu, 'make_link': hp}, {'label': 'Hide Pictures', 'href': mu + '?hide_pictures', 'make_link': not(hp)}, ] profiles = find_profiles(context) member_batch = _member_profile_batch(context, request) member_entries = member_batch['entries'] moderator_names = community.moderator_names member_info = [] for i in range(len(member_entries)): derived = {} entry = member_entries[i] derived['title'] = entry.title derived['href'] = model_url(entry, request) derived['position'] = entry.position derived['organization'] = entry.organization derived['phone'] = entry.phone derived['department'] = entry.department derived['email'] = entry.email derived['city'] = entry.location photo = entry.get('photo') if photo is not None: derived['photo_url'] = thumb_url(photo, request, PROFILE_THUMB_SIZE) else: derived['photo_url'] = api.static_url + "/img/default_user.png" derived['is_moderator'] = entry.__name__ in moderator_names # Chameleon's tal:repeat and repeat variable support for # things like index is pretty iffy. Fix the entry info to # supply the CSS class information. derived['css_class'] = 'photoProfile' if derived['is_moderator']: derived['css_class'] += ' moderator' member_info.append(derived) moderator_info = [] profiles = find_profiles(context) for moderator_name in moderator_names: if moderator_name in profiles: derived = {} profile = profiles[moderator_name] if not has_permission('view', profile, request): continue derived['title'] = profile.title derived['href'] = model_url(profile, request) moderator_info.append(derived) return render_template_to_response( 'templates/show_members.pt', api=api, actions=actions, submenu=submenu, moderators=moderator_info, members=member_info, batch_info=member_batch, hide_pictures=hp, )