def user_content(self, login_bundle, atom_tag, fields, count): """Return struct containing requested content-related fields for user atom_tag. Parameters: user_id: the user_id of the user for which requesting data count: number items to return, max is 50 fields: array of zero or more of the following: 'pnews': personal news items 'topics': topics authored 'comments': comments authored 'pages': workspace pages edited 'ctopics': topics commented upon or started 'all': all of the above Returns struct containing one entry per requested field. Items are returned in reverse chronological order. Items are "Atom Tags," globally-unique content identifiers. """ cur_user = self._check_login(login_bundle) user = lookup_atom_id(atom_tag) if not user: raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Invalid user id') def item_info(item): """Return struct with standard item information.""" return dict(atom_tag=atom_id(item), title=item.watchable_name(), score=item.get_karma_score(), ) activity = user.get_activity() result = {} count = min(count or 50, 50) all = 'all' in fields if all or 'pnews' in fields: result['pnews'] = [item_info(i) for date, i \ in activity.recent_personal_news_for_reader(cur_user)][:count] if all or 'topics' in fields: result['topics'] = [item_info(i) for date, i \ in activity.recent_blog_items_for_reader(cur_user)][:count] if all or 'comments' in fields: result['comments'] = [item_info(i) for date, i, parent \ in activity.recent_blog_comments_for_reader(cur_user)][:count] if all or 'pages' in fields: result['pages'] = [item_info(p) for date, p \ in activity.recent_wiki_pages_for_reader(cur_user)][:count] if all or 'ctopics' in fields: result['ctopics'] = [item_info(i) for date, i \ in activity.recent_participation_for_reader(cur_user)][:count] return result
def _get_page(self, user, atom_tag): page = lookup_atom_id(atom_tag) if not page or not isinstance(page, qon.wiki.WikiPage): raise xmlrpclib.Fault(FAULT_INVALID_ITEM, "Invalid page name") if not page.can_read(user): raise xmlrpclib.Fault(FAULT_NO_ACCESS, "User cannot access this content") return page
def _get_item(self, user, atom_tag, allow_deleted=False): item = lookup_atom_id(atom_tag) if not item or not isinstance(item, qon.blog.BlogItem): raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Invalid topic id') if not item.can_read(user): raise xmlrpclib.Fault(FAULT_NO_ACCESS, 'User cannot access this content') if not allow_deleted and item.is_deleted(): raise xmlrpclib.Fault(FAULT_ITEM_DELETED, 'Topic has been deleted') return item
def _get_revision(self, user, atom_tag): version = lookup_atom_id(atom_tag) if not version or not isinstance(version, qon.wiki.WikiVersion): raise xmlrpclib.Fault(FAULT_INVALID_ITEM, "Invalid revision") page = version.page if not page.can_read(user): raise xmlrpclib.Fault(FAULT_NO_ACCESS, "User cannot access this content") return version
def user_info(self, login_bundle, atom_tag_list): """Given a list of users' atom_tags, return a struct for each user containing the user's display name and feedback score.""" cur_user = self._check_login(login_bundle) result = {} for atom_id in atom_tag_list: user = lookup_atom_id(atom_id) if user and not result.has_key(atom_id) \ and isinstance(user, qon.user.User): result[atom_id] = _format_user(user) return result
def convert_atom_id_to_url(self, login_bundle, atom_id): """Given an atom_id, return the URL for that object.""" cur_user = self._check_login(login_bundle) obj = lookup_atom_id(atom_id) if obj: path = path_to_obj(obj) if path: return full_url(path) raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Invalid atom_id.')
def item_edit(self, login_bundle, atom_tag, data): """Edit an item's data. Item may be a topic, comment, or workspace page. Valid fields in data are: title: new title of item text: new text of item Fields not provided are left unchanged. Editing a workspace page creates a new revision and ignores 'title' field. """ user = self._check_login(login_bundle) obj = lookup_atom_id(atom_tag) api = adapt(obj, IItemAPI, None) if api: api.set_user(user) api.edit_item(data) return True raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Cannot edit this type of item.')
def _get_wiki(self, user, atom_tag): obj = lookup_atom_id(atom_tag) if not obj: raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Invalid tag') if isinstance(obj, qon.wiki.Wiki): wiki = obj elif isinstance(obj, qon.wiki.WikiPage): wiki = obj.wiki elif isinstance(obj, qon.wiki.WikiVersion): wiki = obj.page.wiki elif isinstance(obj, qon.group.Group): wiki = obj.get_wiki() else: wiki = None if not wiki: raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Cannot find workspace from tag.') if not wiki.can_read(user): raise xmlrpclib.Fault(FAULT_NO_ACCESS, "User cannot access this content") return wiki
def _get_blog(self, user, atom_tag): obj = lookup_atom_id(atom_tag) if not obj: raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Invalid tag') if isinstance(obj, qon.blog.Blog): blog = obj elif isinstance(obj, qon.blog.BlogItem): blog = obj.blog elif isinstance(obj, qon.group.Group): blog = obj.get_blog() elif isinstance(obj, qon.user.User): blog = obj.get_blog() else: blog = None if not blog: raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Cannot find news from tag.') if not blog.can_read(user): raise xmlrpclib.Fault(FAULT_NO_ACCESS, "User cannot access this content") return blog
def item_data(self, login_bundle, atom_tag, fields): """Return struct containing requested fields for specified item. Parameters: atom_tag: atom_tag of item. fields: array of requested information: feedback: extended feedback information text: full raw (reStructuredText) text html: html of item text Returns: struct of requested information (fields) as well as: atom_tag: atom_tag of item title: title of item author: author of item created: date item created modified: date item modifed (only if modified) feedback_score: feedback score of item comment_count: number of comments (only if item is a discussion topic) revision_count: number of revisions (only if item is a workspace page) For example, if fields is an empty array, the returned struct will include all of the above fields, but not the detailed feedback, nor the actual text of the item itself. """ user = self._check_login(login_bundle) obj = lookup_atom_id(atom_tag) if not obj: raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Invalid atom_tag.') api = adapt(obj, IItemAPI, None) if api: api.set_user(user) return api.get_item(fields) raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Could not dispatch to API.')
def _get_group(self, atom_tag): group = lookup_atom_id(atom_tag) if not group or not isinstance(group, qon.group.Group): raise xmlrpclib.Fault(FAULT_INVALID_GROUP, 'Invalid group id') return group
def user_data(self, login_bundle, atom_tag, fields): """Return struct containing requested fields for user atom_tag. Parameters: atom_tag: the atom tag of the user for which requesting data fields: array of zero or more of the following: 'name': currently-specified name to be displayed 'fscore': feedback score 'fbank': feedback bank 'fpos': positive feedback received 'fneg': negative feedback received 'fposgiv': positive feedback given 'fneggiv': negative feedback given 'fcom': net comment feedback received 'fcompos': positive comment feedback received 'fcomneg': negative comment feedback received 'membsince': member since date 'lastlogin': last login (may return 'never' or 'inactive') 'idletime': idle time or 'none' if not logged in 'posffrom': positive feedback from (array of user_ids) 'posffromnum': number of positive feedback givers 'negffrom': negative feedback from (if visible) 'neggfromnum': number of negative feedback givers 'emaildomain: domain portion of email 'groupown': groups owned by user 'groupmemb': groups user is a member of 'all': all of the above Returns struct containing one entry per requested field. """ user_db = get_user_database() group_db = get_group_database() cur_user = self._check_login(login_bundle) user = lookup_atom_id(atom_tag) if not user or not isinstance(user, qon.user.User): raise xmlrpclib.Fault(FAULT_INVALID_ITEM, 'Invalid user id') all = 'all' in fields result = {} if all or 'name' in fields: result['name'] = user.display_name() if all or 'fscore' in fields: result['fscore'] = user.get_karma_score() if all or 'fbank' in fields: result['fbank'] = user.get_karma_bank_balance() if all or 'fpos' in fields: result['fpos'] = user.karma_plus_received() if all or 'fneg' in fields: result['fneg'] = user.karma_minus_received() if all or 'fposgiv' in fields: result['fposgiv'] = user.karma_plus_given() if all or 'fneggiv' in fields: result['fneggiv'] = user.karma_minus_given() if all or ('fcom' in fields) or ('fcompos' in fields) or ('fcomneg' in fields): fcompos, fcomneg = get_list_database().karma_user_content_totals(user) if all or 'fcom' in fields: result['fcom'] = fcompos + fcomneg if all or 'fcompos' in fields: result['fcompos'] = fcompos if all or 'fcomneg' in fields: result['fcomneg'] = fcomneg if all or 'membsince' in fields: dt = user.get_user_data().member_since() result['membsince'] = _format_dt(dt) if all or 'lastlogin' in fields: result['lastlogin'] = _format_dt(getattr(user, 'last_login', None)) if all or 'idletime' in fields: if user.is_disabled(): sec = 'inactive' else: idle = user.idle_time() if idle: sec = idle.seconds else: sec = 'none' result['idletime'] = sec if all or 'posffrom' in fields: result['posffrom'] = [atom_id(user_db.get_user(uid)) \ for karma, uid in user.positive_karma_givers()] if all or 'posffromnum' in fields: result['posffromnum'] = len(user.positive_karma_givers()) if all or 'negffrom' in fields: result['negffrom'] = [atom_id(user_db.get_user(uid)) \ for karma, uid in user.negative_karma_givers()] if all or 'negffromnum' in fields: result['negffromnum'] = len(user.negative_karma_givers()) if all or 'emaildomain' in fields: e = user.get_primary_email() result['emaildomain'] = e[e.find('@')+1:] if all or 'groupown' in fields: result['groupown'] = [atom_id(g) \ for g in group_db.owned_groups(user)] if all or 'groupmemb' in fields: result['groupmemb'] = [atom_id(g) \ for g in group_db.member_groups(user)] return result