def __init__(self, user): super(UserFIEditor, self).__init__(None) self.uid = user if is_string(user) else user.uid self.user_repository = UserRepository() fi_uid = self.user.fi.uid if self.user.fi else '' self.fi_uid = editor.Property(fi_uid).validate( validators.non_empty_string)
class UserFIEditor(editor.Editor): def __init__(self, user): super(UserFIEditor, self).__init__(None) self.uid = user if is_string(user) else user.uid self.user_repository = UserRepository() fi_uid = self.user.fi.uid if self.user.fi else '' self.fi_uid = editor.Property(fi_uid).validate( validators.non_empty_string) @property def is_mine(self): current_user = security.get_user() return current_user and (current_user.uid == self.uid) @property def user(self): return self.user_repository.get_by_uid(self.uid) def get_facilitators(self): return UserData.get_facilitators() def commit(self): if not super(UserFIEditor, self).commit((), ('fi_uid',)): return False new_facilitator = self.user_repository.get_by_uid(self.fi_uid()) self.user.fi = new_facilitator flashmessage.set_flash(_(u'Facilitator changed')) return True
class UserFIEditor(editor.Editor): def __init__(self, user): super(UserFIEditor, self).__init__(None) self.uid = user if is_string(user) else user.uid self.user_repository = UserRepository() fi_uid = self.user.fi.uid if self.user.fi else '' self.fi_uid = editor.Property(fi_uid).validate( validators.non_empty_string) @property def is_mine(self): current_user = security.get_user() return current_user and (current_user.uid == self.uid) @property def user(self): return self.user_repository.get_by_uid(self.uid) def get_facilitators(self): return UserData.get_facilitators() def commit(self): if not super(UserFIEditor, self).commit((), ('fi_uid', )): return False new_facilitator = self.user_repository.get_by_uid(self.fi_uid()) self.user.fi = new_facilitator flashmessage.set_flash(_(u'Facilitator changed')) return True
def setUp(self): super(TestWorkflow, self).setUp() # create the profiles that will interact with the idea user_repository = UserRepository() self.facilitator = user_repository.facilitator self.developer = user_repository.developer self.admin = user_repository.admin self.author = user_repository.create(uid=u'author', email=u'*****@*****.**', firstname=u'John', lastname=u'Doe', position=u'author', fi=self.facilitator) # create an idea domain domain = DomainData( label=u'domain', rank=100, en_label=u'en', fr_label=u'fr', ) # create an idea self.idea = IdeaRepository().create(title=u'Title', description=u'description', impact=u'impact', submitted_by=self.author, domain=domain)
def apply_rule(idea, state, event, context, *args, **kw): from eureka.domain.repositories import UserRepository di_uid = kw['di'] di = UserRepository().get_by_uid(di_uid) or UserRepository().developer context.assignated_di = di return WFStates.DI_APPRAISAL_STATE
def setUp(self): super(TestWorkflow, self).setUp() # create the profiles that will interact with the idea user_repository = UserRepository() self.facilitator = user_repository.facilitator self.developer = user_repository.developer self.admin = user_repository.admin self.author = user_repository.create( uid=u'author', email=u'*****@*****.**', firstname=u'John', lastname=u'Doe', position=u'author', fi=self.facilitator ) # create an idea domain domain = DomainData( label=u'domain', rank=100, en_label=u'en', fr_label=u'fr', ) # create an idea self.idea = IdeaRepository().create( title=u'Title', description=u'description', impact=u'impact', submitted_by=self.author, domain=domain )
def populate_users(default_users): """Populate the default users (special accounts)""" facilitator_uid = default_users['FACILITATOR'] developer_uid = default_users['DEVELOPER'] admin_uid = default_users['ADMIN'] innovator_uid = default_users['INNOVATOR'] special_users = ( (facilitator_uid, facilitator_uid, facilitator_uid.capitalize(), facilitator_uid.capitalize(), u'{}@eureka-open.com'.format(facilitator_uid), facilitator_uid, [RoleType.Facilitator]), (developer_uid, developer_uid, u'Ideas', developer_uid.capitalize(), u'{}@eureka-open.com'.format(developer_uid), facilitator_uid, [RoleType.Developer]), (admin_uid, admin_uid, admin_uid.capitalize(), u'Eureka', u'{}@eureka-open.com'.format(admin_uid), facilitator_uid, [RoleType.DSIG]), (innovator_uid, innovator_uid, innovator_uid.capitalize(), u'User', u'{}@eureka-open.com'.format(innovator_uid), facilitator_uid, []), ) for (uid, password, firstname, lastname, email, fi_uid, roles) in special_users: user = UserRepository().create(uid=uid, password=password, firstname=firstname, lastname=lastname, email=email, fi_uid=fi_uid) for role in roles: user.add_role(role) session.flush()
def commit(self): properties = ('title', 'short_title', 'created_by', 'organization', 'associated_dis', 'starting_date', 'ending_date', 'summary', 'description', 'mobile_description', 'outcome', 'tags') if not super(ChallengeEditor, self).commit((), properties): return False user_repository = UserRepository() created_by = user_repository.get_by_email(self.created_by.value) associated_dis = [user_repository.get_by_email(email) for email in self.associated_dis.value] challenge = self.challenge or self.challenge_repository.create() challenge.title = self.title.value challenge.short_title = self.short_title.value challenge.created_by = created_by challenge.organization = self.organization.value challenge.associated_dis = associated_dis challenge.starting_date = self.starting_date.value challenge.ending_date = self.ending_date.value + timedelta(days=1) # ending_date is not included challenge.summary = self.summary.value challenge.description = self.description.value challenge.mobile_description = self.mobile_description.value challenge.outcome = self.outcome.value challenge.tags = self.tags.value # For each selected DI, if the corresponding account isn't DI, add the role to the user di_role = RoleType.Developer for u in associated_dis: u.add_role(di_role) return True
def __init__(self, uid, email_unique=True, mobile_access=False): super(UserLineEditor, self).__init__(None) self.email_unique = email_unique self.mobile_access = mobile_access self.uid = uid self.user_repository = UserRepository() self.reset()
def __init__(self): from eureka.domain.repositories import (CommentRepository, IdeaRepository, UserRepository, VoteIdeaRepository) self.user_repository = UserRepository() self.idea_repository = IdeaRepository() self.vote_idea_repository = VoteIdeaRepository() self.comment_repository = CommentRepository()
class PointsAdmin(editor.Editor): """User interface to assign points to some users""" def __init__(self): super(PointsAdmin, self).__init__(None) self._ActionList = ( (PointCategory.GIFT_BOUGHT, _(u"Gift purchase"), -1), (PointCategory.OTHER_EXPENSE, _(u"Other expense"), -1), (PointCategory.BONUS_POINTS, _(u"Bonus points"), +1), (PointCategory.PENALTY_POINTS, _(u"Penalty points"), -1), ) self.category = editor.Property(PointCategory.GIFT_BOUGHT) self.users_emails = editor.Property(u'').validate(validators.user_email_list) self.points = editor.Property(u'').validate(validators.positive_integer) self.reason = editor.Property(u'').validate(validators.non_empty_string) self.user_repository = UserRepository() def _find_sign(self, category): for id, _, sign in self._ActionList: if id == category: return sign def is_validated(self): return super(PointsAdmin, self).is_validated(('category', 'points', 'users_emails', 'reason')) def check_users_have_enough_points(self): emails = self.users_with_not_enough_points() if emails: msg = _(u'The following users do not have enough available points: %s') % ', '.join(emails) self.users_emails.error = msg def users_with_not_enough_points(self): if self._find_sign(self.category.value) > 0: return [] emails = [] for email in self.users_emails.value: user = self.user_repository.get_by_email(email) if user.available_points < self.points.value: emails.append(email) return emails def commit(self): if not self.is_validated(): return False category = self.category.value sign = self._find_sign(category) nb_points = self.points.value * sign reason = self.reason.value for email in self.users_emails.value: user = self.user_repository.get_by_email(email) user.add_points(category, nb_points, reason=reason) flashmessage.set_flash(_(u'Modifications done')) return True
def update_idea_authors(self, idea): co_authors = [self.co_author_1.value, self.co_author_2.value, self.co_author_3.value, self.co_author_4.value, self.co_author_5.value] authors = [idea.submitted_by] user_repository = UserRepository() for email in co_authors: if email: email = email.strip().lower() authors.append(user_repository.get_by_email(email)) idea.authors = authors
def __init__(self, uid): super(DIEditor, self).__init__(None) self.uid = uid self.user_repository = UserRepository() self.domains = editor.Property( [str(elt.id) for elt in self.get_domains()]) self.successor = editor.Property('').validate( validators.non_empty_string) self.di_business_area = editor.Property( self.user.di_business_area or '').validate(validators.non_empty_string)
def __init__(self): super(PointsAdmin, self).__init__(None) self._ActionList = ( (PointCategory.GIFT_BOUGHT, _(u"Gift purchase"), -1), (PointCategory.OTHER_EXPENSE, _(u"Other expense"), -1), (PointCategory.BONUS_POINTS, _(u"Bonus points"), +1), (PointCategory.PENALTY_POINTS, _(u"Penalty points"), -1), ) self.category = editor.Property(PointCategory.GIFT_BOUGHT) self.users_emails = editor.Property(u'').validate(validators.user_email_list) self.points = editor.Property(u'').validate(validators.positive_integer) self.reason = editor.Property(u'').validate(validators.non_empty_string) self.user_repository = UserRepository()
def __init__(self, uid=None, email_unique=True, mobile_access=False): """User's informations editor In: - ``uid`` -- the uid of the user to edit (if we are in edit mode) - ``email_unique`` -- do we have to check for the email uniqueness or not (default yes) """ super(UserEditor, self).__init__(None) self.assignable_roles = [RoleType.Facilitator, RoleType.Developer] if mobile_access: self.assignable_roles.append(RoleType.MobileAccess) self.email_unique = email_unique self.uid = uid self.user_repository = UserRepository() self.reset_fields()
def create_user(**kw): repository = UserRepository() # initialize the user fields if 'enabled' not in kw: kw['enabled'] = True if 'fi_uid' not in kw: kw['fi_uid'] = u'facilitateur' for f in ('uid', 'lastname', 'firstname', 'email', 'position'): if f not in kw.keys(): kw[f] = random_string() u = repository.create(**kw) u = session.merge(u) return repository.get_by_uid(u.uid) # make sure the new user is found in the session
def __init__(self): from eureka.domain.repositories import ( CommentRepository, IdeaRepository, UserRepository, VoteIdeaRepository ) self.user_repository = UserRepository() self.idea_repository = IdeaRepository() self.vote_idea_repository = VoteIdeaRepository() self.comment_repository = CommentRepository()
def _validate_user(self, login): user = UserRepository().get_by_uid(login) if user is None: raise ValueError(_(u"This user does not exist")) if not user.enabled: raise ValueError(_(u"This user account is disabled")) return login
def create_user(**kw): repository = UserRepository() # initialize the user fields if 'enabled' not in kw: kw['enabled'] = True if 'fi_uid' not in kw: kw['fi_uid'] = u'facilitateur' for f in ('uid', 'lastname', 'firstname', 'email', 'position'): if f not in kw.keys(): kw[f] = random_string() u = repository.create(**kw) u = session.merge(u) return repository.get_by_uid( u.uid) # make sure the new user is found in the session
def __init__(self, uid): super(DIEditor, self).__init__(None) self.uid = uid self.user_repository = UserRepository() self.domains = editor.Property( [str(elt.id) for elt in self.get_domains()]) self.successor = editor.Property('').validate( validators.non_empty_string) self.di_business_area = editor.Property( self.user.di_business_area or '').validate( validators.non_empty_string)
class DIAdmin(object): def __init__(self): self.user_repository = UserRepository() def _users(self): return self.user_repository.get_developers().order_by( UserData.lastname, UserData.firstname) def confirm_delete_di(self, uid, comp): full_name = self.user_repository.get_by_uid(uid).fullname confirm = PortalBox(Confirmation( _(u'The expert role of the user "%s" will be removed. ' u'You must confirm this change.') % full_name, _(u'Ok'), _(u'Cancel'))) if comp.call(confirm): user = self.user_repository.get_by_uid(uid) user.remove_role(RoleType.Developer) user.remove_responsibilities(RoleType.Developer)
def send(template_filename, to, delivery_priority=DeliveryPriority.Normal, attachments=None, **kw): from eureka.domain.models import MailDeliveryFrequency from eureka.domain.repositories import UserRepository user_repository = UserRepository() locale = to.locale if to else 'fr' # creates the email contents substitutions = _get_substitutions(to=to, **kw) content = _perform_substitutions(template_filename, locale, substitutions) # extracts and remove the metadata content, subject, sender, to_recipients, cc_recipients, bcc_recipients = _extract_metadata(content) # attachments attachments = attachments or () # if there's no recipient, no need to send an email if not to_recipients: return mailer = mail.get_mailer() if (delivery_priority == DeliveryPriority.Normal) or attachments: # FIXME: for consistency, we should also send one email per recipient, using the target user locale # send now (one message with all the recipients) mailer.send_mail(subject, from_=sender, to=to_recipients, cc=cc_recipients, bcc=bcc_recipients, content=content, type='html', attachments=attachments) elif delivery_priority == DeliveryPriority.Low: # send one message per user (since we need the examine the mail delivery setting of each user) for user_email in to_recipients + cc_recipients + bcc_recipients: user = user_repository.get_by_email(unicode(user_email)) send_now = not user or user.mail_delivery_frequency == MailDeliveryFrequency.Immediately if send_now: # sends the email now mailer.send_mail(subject, from_=sender, to=[user_email], content=content, type='html') else: # add the message to the user's pending email messages user.add_pending_email_message(subject, content)
def render_comment(self, h, comp, *args): voters = self.voters voters_uids = [voter.uid for voter in voters] pager = UserPager(self, lambda uids=voters_uids: UserRepository().get_by_uids(uids)) relevant_comment_users_dialog = component.Component(ModalBox(AsyncWrapper(component.Component(pager, model='minimal')), title=_(u'Users finding this comment relevant'), visible=False)) with h.li: h << h.a(name='comment%s' % self.id) # so we can navigate to comments sync = h.SyncRenderer() h << relevant_comment_users_dialog.render(sync) with h.div(class_='user'): # creator avatar h << component.Component(User(self, self.comment.created_by)).render(sync, model='avatar100') if voters: with h.div(class_='alert'): nb_voters = len(voters_uids) if nb_voters > 1: message = _(u"%s people find this comment relevant") % nb_voters else: message = _(u"One people find this comment relevant") h << h.a(message, title=message, href='javascript:' + relevant_comment_users_dialog().show_js(), class_='votes') with h.div(class_='author'): # author h << _(u"From") << " " h << comp.render(sync, model='author') << " " # date if self.comment.submission_date: # deal with missing dates in the database h << _(u'on') << " " with h.span(class_='date'): h << format_datetime(self.comment.submission_date) h << " " h << h.p(text_to_html_elements(h, self.comment.content)) # attachment if self.comment.attachment: with h.p: h << component.Component(Attachment(self.comment.attachment)).render(h) with h.div(class_='links'): h << comp.render(h, model='actions') # delete form h << comp.render(h, model='delete_form') return h.root
def __init__(self): editor.Editor.__init__(self, None) self.user_repository = UserRepository() self.uid = editor.Property(u'') self.corporation_id = editor.Property(-1).validate(validators.integer) self.direction_id = editor.Property(-1).validate(validators.integer) self.service_id = editor.Property(-1).validate(validators.integer) self.site_id = editor.Property(-1).validate(validators.integer) self.subsite_id = editor.Property(-1).validate(validators.integer) self.enabled = editor.Property('-1') self.fi_uid = editor.Property('-1')
def __init__(self, uid): super(FIEditor, self).__init__(None) self.uid = uid self.user_repository = UserRepository() # FI self.fi_uid = editor.Property(u'').validate( validators.non_empty_string) self.corporation_id = editor.Property(' - 1') self.direction_id = editor.Property(' - 1') self.service_id = editor.Property(' - 1') self.site_id = editor.Property(' - 1') self.subsite_id = editor.Property(' - 1') self.successor = editor.Property('').validate( validators.non_empty_string) self.filter = component.Component(UserFilter()) if self.user: self.filter().initialize_from_user_organization(self.user)
def apply_rule(idea, state, event, context, *args, **kw): from eureka.domain.queries import get_published_challenge_ideas from eureka.domain.repositories import UserRepository # Affect to DI di_uid = kw['di'] di = UserRepository().get_by_uid(di_uid) or UserRepository().developer context.assignated_di = di context.publication_date = datetime.now() # Give points to creator for user in idea.authors: user.process_point_event(PointEvent.PUBLISH_IDEA, idea=idea) if (idea.challenge is not None and [e for e in get_published_challenge_ideas(idea.challenge.id)()] == []): user.process_point_event(PointEvent.PUBLISH_CHALLENGE_FIRST_IDEA, idea=idea) idea.show_creator = True return WFStates.DI_APPRAISAL_STATE
class DIAdmin(object): def __init__(self): self.user_repository = UserRepository() def _users(self): return self.user_repository.get_developers().order_by( UserData.lastname, UserData.firstname) def confirm_delete_di(self, uid, comp): full_name = self.user_repository.get_by_uid(uid).fullname confirm = PortalBox( Confirmation( _(u'The expert role of the user "%s" will be removed. ' u'You must confirm this change.') % full_name, _(u'Ok'), _(u'Cancel'))) if comp.call(confirm): user = self.user_repository.get_by_uid(uid) user.remove_role(RoleType.Developer) user.remove_responsibilities(RoleType.Developer)
def add_comment(self, expert_email, content): current_user = security.get_user() assert current_user creator = current_user.entity expert = UserRepository().get_by_email(expert_email) c = EvalCommentData(created_by=creator, expert=expert, content=content, submission_date=datetime.today()) self.data.comments.append(c)
def commit(self): properties = ('title', 'short_title', 'created_by', 'organization', 'associated_dis', 'starting_date', 'ending_date', 'summary', 'description', 'mobile_description', 'outcome', 'tags') if not super(ChallengeEditor, self).commit((), properties): return False user_repository = UserRepository() created_by = user_repository.get_by_email(self.created_by.value) associated_dis = [ user_repository.get_by_email(email) for email in self.associated_dis.value ] challenge = self.challenge or self.challenge_repository.create() challenge.title = self.title.value challenge.short_title = self.short_title.value challenge.created_by = created_by challenge.organization = self.organization.value challenge.associated_dis = associated_dis challenge.starting_date = self.starting_date.value challenge.ending_date = self.ending_date.value + timedelta( days=1) # ending_date is not included challenge.summary = self.summary.value challenge.description = self.description.value challenge.mobile_description = self.mobile_description.value challenge.outcome = self.outcome.value challenge.tags = self.tags.value # For each selected DI, if the corresponding account isn't DI, add the role to the user di_role = RoleType.Developer for u in associated_dis: u.add_role(di_role) return True
def populate_users(default_users): """Populate the default users (special accounts)""" facilitator_uid = default_users['FACILITATOR'] developer_uid = default_users['DEVELOPER'] admin_uid = default_users['ADMIN'] innovator_uid = default_users['INNOVATOR'] special_users = ( (facilitator_uid, facilitator_uid, facilitator_uid.capitalize(), facilitator_uid.capitalize(), u'{}@eureka-open.com'.format(facilitator_uid), facilitator_uid, [RoleType.Facilitator]), (developer_uid, developer_uid, u'Ideas', developer_uid.capitalize(), u'{}@eureka-open.com'.format(developer_uid), facilitator_uid, [RoleType.Developer]), (admin_uid, admin_uid, admin_uid.capitalize(), u'Eureka', u'{}@eureka-open.com'.format(admin_uid), facilitator_uid, [RoleType.DSIG]), (innovator_uid, innovator_uid, innovator_uid.capitalize(), u'User', u'{}@eureka-open.com'.format(innovator_uid), facilitator_uid, []), ) for (uid, password, firstname, lastname, email, fi_uid, roles) in special_users: user = UserRepository().create( uid=uid, password=password, firstname=firstname, lastname=lastname, email=email, fi_uid=fi_uid ) for role in roles: user.add_role(role) session.flush()
def is_unused_uid(self, msg=_L(u'User id already used')): """Check that there is no user with this identifier In: - ``msg`` -- message to raise Return: - ``self`` """ if not self.value: return self if UserRepository().get_by_uid(self.value): raise ValueError(msg) return self
def user_email_list(text, separator=',', check_user_email=True): """Validate a list of email addresses between commas""" emails = [item.strip() for item in text.split(separator) if item.strip() != ''] if not emails: raise ValueError(_L(u"Can't be empty")) for email in emails: if not validateEmail(email): raise ValueError(_L(u"%s is not a valid email address") % email) if check_user_email and not UserRepository().get_by_email(email): raise ValueError( _L(u"There's no user with this email address: %s") % email) return emails
def is_user_email(self, msg=_L(u"No user with this email")): """Check that there is a known user with this email In: - ``msg`` -- message to raise Return: - ``self`` """ if not self.value: return self if not UserRepository().get_by_email(self.value): raise ValueError(msg) return self
def rebuild_indexes(logger): global apps logger.info('Creating search indexes') search_engine = apps['eureka'].search_engine search_engine.clear() logger.info('Re-indexing ideas') # We index *all* ideas. We are safe because results are filtered by 'published' status ideas = IdeaRepository().get_all().options( eagerload('tags'), eagerload('authors_association')).all() search_engine.index_many(ideas) logger.info('Re-indexing users') users = UserRepository().get_all() search_engine.index_many(users) logger.info('Done')
def __init__(self, parent, user, selected_tab=None, online_shop=None): self.parent = parent event_management._register_listener(parent, self) self.uid = user if is_string(user) else user.uid self.user_repository = UserRepository() self.user_comp = User(parent, self.uid) self.tabs = self._create_tabs() selected_tab = selected_tab if selected_tab in self.tabs else 'profile' self.selected_tab = var.Var(selected_tab) # inner components displayed in the tabs or the header # FIXME: all these should be wrapped into a component.Component self.fi_editor = UserFIEditor(self.uid) event_management._register_listener(self, self.fi_editor) self.avatar_editor = AvatarEditor(self.uid) event_management._register_listener(self, self.avatar_editor) self.password_editor = PasswordEditor(self.user) event_management._register_listener(self, self.password_editor) self.profile_editor = ProfileEditor(self.user) event_management._register_listener(self, self.profile_editor) self.settings_editor = component.Component(SettingsEditor(self.user)) event_management._register_listener(self, self.settings_editor()) self.idea_pager = self._create_pager() # FIXME: the pager should not depend on the parent # event_management._register_listener(self, self.idea_pager) self.online_shop = online_shop(self) self.tab_labels = { 'profile': _("My Profile") if self.is_mine else _("Her Profile"), 'settings': _("My Settings") if self.is_mine else _("Her Settings"), 'tracked_ideas': (_("My Tracked Ideas") if self.is_mine else _("Her Tracked Ideas")) + " (%d)" % self.new_events_count(), 'ideas': (_("My Ideas") if self.is_mine else _("Her Ideas")) + " (%d)" % self.ideas_count, 'points': (_("My Points") if self.is_mine else _("Her Points")) + " (%d)" % self.user.acquired_points, # 'rank': self.user.status_level_label, } self.menu_items = [(self.tab_labels[name], name, None, '', None) for name in self.tabs] self.menu = component.Component(Menu(self.menu_items), model='tab_renderer') self.menu.on_answer(self.select_tab) if selected_tab: index_tab = self.tabs.index(selected_tab) else: index_tab = 0 self.select_tab(index_tab)
def render_user_admin_users_list(self, h, comp, *args): current_uid = security.get_user().uid protected_uids = [e.uid for e in UserRepository().protected_accounts if e] async = h.AsyncRenderer() with h.h1(class_="tab active big"): h << h.span(h.a(_(u'User management'))) with h.div(class_='user-admin-item user_list'): h << h.h1(_(u'Manage users')) with h.div: # filters h << self.filter.render(h) with h.table(class_="inline-edit-list with-delete" if self.with_delete else 'inline-edit-list'): with h.thead: with h.tr: with h.th: h << h.span(_(u'Name'), class_='name') h << h.span(_(u'Corporation')) h << h.span(_(u'Direction')) h << h.span(_(u'Service')) h << h.span(_(u'Site')) h << h.span(_(u'Facilitator')) h << h.span(_(u'Enabled'), class_='enabled') h << h.span("", class_="last") if self.with_delete: with h.th(class_='delete-column'): h << h.span(_(u'Delete')) with h.tbody: for ind, elt in enumerate(self.get_users_comp()[:self.batch_size]): with h.tr(class_=['odd', 'even'][ind % 2]): with h.td: h << elt.render(async) if self.with_delete: with h.td(class_='delete-column'): if current_uid != elt().uid and elt().uid not in protected_uids: link = h.a(_('Delete')).action(lambda uid=elt().uid: self.delete(uid)) msg = _('''User deletion can't be reverted, are you sure you want to delete the account %s ?''') % elt().fullname link.set('onclick', 'if (! confirm(%s)) return false;' % (json.dumps(msg))) h << link h << comp.render(h, 'batch') return h.root
def __init__(self, email_unique=True, can_delete_users=False, mobile_access=False): self.email_unique = email_unique self.mobile_access = mobile_access self.user_repository = UserRepository() self.create_user = component.Component( UserEditor(email_unique=self.email_unique, mobile_access=self.mobile_access)) self.create_user.on_answer(lambda v: self.create_user().reset_fields()) event_management._register_listener(self, self.create_user()) self.start = 0 self.batch_size = 10 self.radius = 3 self.filter = component.Component(UserFilter()) self.with_delete = can_delete_users
def commit(self): properties = ('show_progressing_ideas', 'show_tracked_ideas', 'show_challenges_ideas', 'domains_choice', 'keyword_filter', 'users_filter', 'period_filter') if not super(HomeSettingsEditor, self).is_validated(properties): return False domains = [ domain for domain in self.domains if domain.id in self.domains_choice.value ] # write down the settings into the user's settings user = self.user home_settings = user.home_settings home_settings.show_progressing_ideas = self.show_progressing_ideas.value home_settings.show_tracked_ideas = self.show_tracked_ideas.value home_settings.show_challenges_ideas = self.show_challenges_ideas.value home_settings.domains = domains home_settings.keyword_filter = self.keyword_filter.value home_settings.period_filter = self.period_filter.value users_filter = [ UserRepository().get_by_email(email.strip()) for email in self.users_filter.value.split(',') if email.strip() ] for followed in set(users_filter) - set( [u for u in home_settings.users_filter]): mail_notification.send('mail-followed-user-notify.html', to=followed, comment_author=user) # add entry in timeline user.add_timeline_user(followed) home_settings.users_filter = users_filter return True
def create_user_box(user_uids, title): query = lambda: UserRepository().get_by_uids(user_uids) pager = UserPager(self.parent, query) return PagerBox(pager, title='Users', ok_button=_(u'Back to the dashboard'))
def __init__(self, parent, user): event_management._register_listener(parent, self) self.uid = user if is_string(user) else user.uid self.user_repository = UserRepository() self.pager = None
class StatisticsService(Unpicklable): """ Service that compute statistics """ def __init__(self): from eureka.domain.repositories import ( CommentRepository, IdeaRepository, UserRepository, VoteIdeaRepository ) self.user_repository = UserRepository() self.idea_repository = IdeaRepository() self.vote_idea_repository = VoteIdeaRepository() self.comment_repository = CommentRepository() @cached def _active_users(self): # Users enabled and who have logged in at least once return set(self.user_repository.get_active()) @cached def _votes(self): return set(self.vote_idea_repository.get_all()) @cached def _votes_by_challenge(self): votes_by_challenge = collections.defaultdict(set) for k, v in itertools.groupby( self._votes(), lambda v: v.idea.challenge): votes_by_challenge[k].update(set(v)) return votes_by_challenge @cached def _comments(self): return set(self.comment_repository.get_all()) @cached def _comments_by_challenge(self): comments_by_challenge = collections.defaultdict(set) for k, v in itertools.groupby( self._comments(), lambda c: c.idea.challenge): comments_by_challenge[k].update(set(v)) return comments_by_challenge @cached def _ideas(self): return set(self.idea_repository.get_published_ideas()) @cached def _ideas_by_challenge(self): ideas_by_challenge = collections.defaultdict(set) for i in self._ideas(): ideas_by_challenge[i.challenge].add(i) return ideas_by_challenge def get_users_statistics_on_connections(self, users, after_date=None): intersection = users.intersection(self._active_users()) if after_date: return len([u for u in intersection if u.last_connection_date > after_date]) else: return len(intersection) def get_users_statistics_on_ideas(self, users, after_date=None, challenge=NO_FILTER): ideas = ( self._ideas_by_challenge()[challenge] if challenge is not NO_FILTER else self._ideas() ) ideas = set(i for i in ideas if not set(i.authors).isdisjoint(users)) if after_date: ideas = [ idea for idea in ideas if idea.wf_context.publication_date and idea.wf_context.publication_date > after_date ] unique_authors = set( author for idea in ideas for author in idea.authors if author in users ) return len(ideas), len(unique_authors) def get_users_statistics_on_votes(self, users, after_date=None, challenge=NO_FILTER): votes = ( self._votes_by_challenge()[challenge] if challenge is not NO_FILTER else self._votes() ) votes = set(v for v in votes if v.user in users) if after_date: votes = set( v for v in votes if v.timestamp and v.timestamp > after_date ) unique_voters = set(vote.user for vote in votes) return len(votes), len(unique_voters) def get_users_statistics_on_comments(self, users, after_date=None, challenge=NO_FILTER): comments = ( self._comments_by_challenge()[challenge] if challenge is not NO_FILTER else self._comments() ) if after_date: comments = set( c for c in comments if c.submission_date and c.submission_date > after_date ) comments = set(c for c in comments if c.created_by in users) unique_commentators = set(comment.created_by for comment in comments) return len(comments), len(unique_commentators) def get_users_statistics(self, users, after_date=None, challenge=NO_FILTER): """ Compute various statistics for a given group of users, returns an instance of UsersStatistics """ users = set(users) # first connections nb_connected_users = self.get_users_statistics_on_connections( users, after_date ) # ideas total_ideas, nb_authors = self.get_users_statistics_on_ideas( users, after_date, challenge ) # votes total_votes, nb_voters = self.get_users_statistics_on_votes( users, after_date, challenge ) # comments total_comments, nb_commentators = ( self.get_users_statistics_on_comments(users, after_date, challenge) ) return UsersStatistics( nb_connected=nb_connected_users, total_ideas=total_ideas, nb_authors=nb_authors, total_votes=total_votes, nb_voters=nb_voters, total_comments=total_comments, nb_commentators=nb_commentators, ) def get_users_points_statistics(self, users): """Compute statistics on users points""" statistics = {} users_status_levels = [ (user, user.status_level_label) for user in users if user ] for user, level in users_status_levels: statistics.setdefault(level, []).append(user) return statistics
class ProfileBox(object): """Show profile pages in a profile box""" def __init__(self, parent, user, selected_tab=None, online_shop=None): self.parent = parent event_management._register_listener(parent, self) self.uid = user if is_string(user) else user.uid self.user_repository = UserRepository() self.user_comp = User(parent, self.uid) self.tabs = self._create_tabs() selected_tab = selected_tab if selected_tab in self.tabs else 'profile' self.selected_tab = var.Var(selected_tab) # inner components displayed in the tabs or the header # FIXME: all these should be wrapped into a component.Component self.fi_editor = UserFIEditor(self.uid) event_management._register_listener(self, self.fi_editor) self.avatar_editor = AvatarEditor(self.uid) event_management._register_listener(self, self.avatar_editor) self.password_editor = PasswordEditor(self.user) event_management._register_listener(self, self.password_editor) self.profile_editor = ProfileEditor(self.user) event_management._register_listener(self, self.profile_editor) self.settings_editor = component.Component(SettingsEditor(self.user)) event_management._register_listener(self, self.settings_editor()) self.idea_pager = self._create_pager() # FIXME: the pager should not depend on the parent # event_management._register_listener(self, self.idea_pager) self.online_shop = online_shop(self) self.tab_labels = { 'profile': _("My Profile") if self.is_mine else _("Her Profile"), 'settings': _("My Settings") if self.is_mine else _("Her Settings"), 'tracked_ideas': (_("My Tracked Ideas") if self.is_mine else _("Her Tracked Ideas")) + " (%d)" % self.new_events_count(), 'ideas': (_("My Ideas") if self.is_mine else _("Her Ideas")) + " (%d)" % self.ideas_count, 'points': (_("My Points") if self.is_mine else _("Her Points")) + " (%d)" % self.user.acquired_points, # 'rank': self.user.status_level_label, } self.menu_items = [(self.tab_labels[name], name, None, '', None) for name in self.tabs] self.menu = component.Component(Menu(self.menu_items), model='tab_renderer') self.menu.on_answer(self.select_tab) if selected_tab: index_tab = self.tabs.index(selected_tab) else: index_tab = 0 self.select_tab(index_tab) def select_tab(self, value): self.selected_tab(self.menu_items[value][1]) self.menu().selected(value) @property def user(self): return self.user_repository.get_by_uid(self.uid) @property def is_mine(self): current_user = security.get_user() return current_user and (current_user.uid == self.uid) def _create_tabs(self): can_edit = security.has_permissions('edit_user', self) can_view_tracked_ideas = security.has_permissions('view_tracked_ideas', self) menu_items = ( ('profile', True), ('settings', can_edit), ('tracked_ideas', can_view_tracked_ideas), ('ideas', True), ('points', True), # ('rank', True), ) return [name for name, enabled in menu_items if enabled] def profile_url(self, uid=None): return get_url_service().expand_url(['profile', (uid or self.uid)]) def view_profile(self, uid=None): # FIXME: fix the mess with profile-related events event_management._emit_signal(self, "VIEW_USER_PROFILE", user_uid=(uid or self.uid)) def show_status_level_help(self): event_management._emit_signal(self, "VIEW_HELP", section='faq_1_7bis') # roles related methods @property def privileged_roles(self): relevant_roles = (RoleType.DSIG, RoleType.Developer, RoleType.Facilitator) return [unicode(RoleLabels[role]) for role in relevant_roles if self.user.has_role(role)] # ideas related methods def _create_pager(self): # FIXME: late import to avoid circular dependencies problem idea_pager = IdeaPager(self, lambda: self._ideas) idea_pager.change_transform("user") idea_pager.change_order("publication_date_desc") idea_pager = InfinitePager(component.Component(idea_pager, model='ideas-list')) return idea_pager @property def _ideas(self): if security.has_permissions('view_unpublished_ideas', self): return get_all_user_ideas(self.uid) else: return get_published_user_ideas(self.uid) @property def ideas_count(self): return self._ideas.count() # events related methods def events(self, days_ago=30): date = datetime.today() - timedelta(days_ago) return sorted(self.user.visible_events(date), key=operator.attrgetter('date'), reverse=True) def new_events_count(self, days_ago=30): date = datetime.today() - timedelta(days_ago) return len(set([e.idea.id for e in self.user.unread_events(date)])) def hide_event(self, event_id): self.user.hide_event(event_id) flashmessage.set_flash(_(u'Event removed')) def read_event(self, event_id): event = self.user.read_event(event_id) self.view_idea(event.idea.id) def read_all_events(self): self.user.read_all_events() # tracked ideas related methods def tracked_ideas(self): return self.user.tracked_ideas def view_idea(self, idea_id): event_management._emit_signal(self, "VIEW_IDEA", mode='view', idea_id=idea_id) def remove_tracked_idea(self, idea_id): self.user.untrack_idea(idea_id) flashmessage.set_flash(_(u'Idea removed from tracking')) def remove_point(self, point_id): PointData.get(point_id).delete() flashmessage.set_flash(_(u"Points deleted"))
class DIEditor(editor.Editor): def __init__(self, uid): super(DIEditor, self).__init__(None) self.uid = uid self.user_repository = UserRepository() self.domains = editor.Property( [str(elt.id) for elt in self.get_domains()]) self.successor = editor.Property('').validate( validators.non_empty_string) self.di_business_area = editor.Property( self.user.di_business_area or '').validate( validators.non_empty_string) @property def user(self): return self.user_repository.get_by_uid(self.uid) def get_domains(self): return DomainRepository().get_by_di(self.user) def get_all_domains(self): return DomainRepository().get_all() def get_di_users(self): return self.user_repository.get_developers() def clear_domains(self): self.domains([]) def update_domains(self): if not super(DIEditor, self).commit((), ('domains',)): return False user = self.user if user: domain_ids = [int(elt) for elt in self.domains.value] # FIXME: use the domain repository user.managed_domains = DomainData.query.filter( DomainData.id.in_(domain_ids)).all() flashmessage.set_flash(_(u'Domains changed')) return True def clear_successor(self): self.successor('') def idea_url(self, idea): return get_url_service().expand_url(['idea', idea.id]) def replace_developer(self): if not super(DIEditor, self).commit((), ('successor',)): return False # prepare the content of the confirmation email assigned_ideas = IdeaRepository().get_assigned_to_developer(self.user) comment = '\n'.join(_('%(title)s: %(url)s') % dict(title=idea.title, url=self.idea_url( idea)) for idea in assigned_ideas) # transfer the DI responsibilities to the new user new_developer = self.user_repository.get_by_uid(self.successor()) self.user.transfer_responsibilities(RoleType.Developer, new_developer) # send the confirmation email mail_notification.send('mail-developer-replaced.html', to=new_developer, previous_di=self.user, comment=comment) flashmessage.set_flash(_(u'Expert replaced')) return True def update_di_business_area(self): if not super(DIEditor, self).commit((), ('di_business_area',)): return False self.user.di_business_area = self.di_business_area.value flashmessage.set_flash(_(u"Expert's business area updated")) return True
def user(self): return UserRepository().get_by_uid(self.uid)
def __init__(self): self.user_repository = UserRepository() self.idea_repository = IdeaRepository() self.vote_idea_repository = VoteIdeaRepository() self.comment_repository = CommentRepository()
class UserLineEditor(editor.Editor): def __init__(self, uid, email_unique=True, mobile_access=False): super(UserLineEditor, self).__init__(None) self.email_unique = email_unique self.mobile_access = mobile_access self.uid = uid self.user_repository = UserRepository() self.reset() def reset(self): user = self.user_repository.get_by_uid(self.uid) self.orig_corp_id = user.corporation_id or -1L self.orig_dir_id = user.direction_id or -1L self.orig_service_id = user.service_id or -1L self.orig_site_id = user.site_id or -1L self.orig_subsite_id = user.subsite_id or -1L self.orig_enabled = user.enabled self.orig_fi_uid = (user.fi_uid or u'') self.corporation_id = editor.Property(self.orig_corp_id) self.direction_id = editor.Property(self.orig_dir_id) self.service_id = editor.Property(self.orig_service_id) self.site_id = editor.Property(self.orig_site_id) self.subsite_id = editor.Property(self.orig_subsite_id) self.enabled = editor.Property(user.enabled) self.fi_uid = editor.Property(user.fi_uid or u'').validate( validators.non_empty_string) self.firstname = user.firstname self.lastname = user.lastname @property def profile_imported(self): return getattr(self.user_repository.get_by_uid(self.uid), 'imported', False) if self.uid else False @property def fullname(self): return u' '.join((self.firstname, self.lastname)) def need_update(self): new_corporation_id = long(self.corporation_id()) if self.corporation_id() else None if self.orig_corp_id != new_corporation_id: return True new_direction_id = long(self.direction_id()) if self.direction_id() else None if new_direction_id != self.orig_dir_id: return True new_service_id = long(self.service_id()) if self.service_id() else None if new_service_id != self.orig_service_id: return True new_site_id = long(self.site_id()) if self.site_id() else None if new_site_id != self.orig_site_id: return True new_subsite_id = long(self.subsite_id()) if self.subsite_id() else None if new_subsite_id != self.orig_subsite_id: return True return self.orig_enabled != bool(self.enabled()) or self.orig_fi_uid != unicode(self.fi_uid()) def change_corp(self): self.direction_id('-1') self.service_id('-1') self.site_id('-1') self.subsite_id('-1') def change_dir(self): self.service_id('-1') self.site_id('-1') self.subsite_id('-1') def change_service(self): self.site_id('-1') self.subsite_id('-1') def change_site(self): self.subsite_id('-1') def update_user(self): # checks the other fields and updates data if super(UserLineEditor, self).commit((), ('corporation_id', 'direction_id', 'site_id', 'service_id', 'fi_uid', 'enabled')): # FIXME: use the OrganizationRepository get_orga = lambda id: OrganizationData.get( id) if id != -1 else None u = self.user_repository.get_by_uid(self.uid) u.corporation = get_orga(self.corporation_id()) u.direction = get_orga(self.direction_id()) u.service = get_orga(self.service_id()) u.site = get_orga(self.site_id()) u.subsite = get_orga(self.subsite_id()) u.enabled = self.enabled() u.fi_uid = self.fi_uid() session.flush() self.orig_corp_id = u.corporation_id or -1L self.orig_dir_id = u.direction_id or -1L self.orig_service_id = u.service_id or -1L self.orig_site_id = u.site_id or -1L self.orig_subsite_id = u.subsite_id or -1L self.orig_enabled = u.enabled self.orig_fi_uid = u.fi_uid flashmessage.set_flash(_(u'User modified')) return True def get_fi_name(self): ci = self.user_repository.get_by_uid(self.fi_uid.value) if ci: return ci.fullname return u"" # Refactor def get_corporations(self): return OrganizationData.get_corporations() def get_directions(self): return OrganizationData.get_directions(parent_id=self.corporation_id()) def get_services(self): return OrganizationData.get_services(parent_id=self.direction_id()) def get_sites(self): return OrganizationData.get_sites(parent_id=self.service_id()) def get_subsites(self): return OrganizationData.get_subsites(parent_id=self.site_id()) def edit_user(self, comp): message = comp.call(UserEditor(self.uid, email_unique=self.email_unique, mobile_access=self.mobile_access)) self.reset() if message: flashmessage.set_flash(message) def get_facilitators(self): return UserData.get_facilitators() def delete(self): UserRepository().delete(self.uid)
class TestUsers(DatabaseEnabledTestCase): def setUp(self): super(TestUsers, self).setUp() self.user_repository = UserRepository() def test_unpicklable(self): user = create_user(uid=u'jdoe', firstname=u'John', lastname=u'Doe') self.assertRaises(UnpicklableError, lambda: pickle.dumps(user)) def test_creation(self): uid = u'jdoe' firstname = u'John' lastname = u'Doe' create_user(uid=uid, firstname=firstname, lastname=lastname) session.flush() user = self.user_repository.get_by_uid(uid) self.assertEquals(user.uid, uid) self.assertEquals(user.firstname, firstname) self.assertEquals(user.lastname, lastname) self.assert_(user.enabled) def test_creation_not_enabled(self): uid = u'login' create_user(uid=uid, enabled=False) session.flush() user = self.user_repository.get_by_uid(uid) self.assert_(not user.enabled) def test_set_firstname_and_lastname(self): uid = u'jdoe' user = create_user(uid=uid) firstname = u'John' lastname = u'Doe' user.firstname = firstname user.lastname = lastname session.flush() user = self.user_repository.get_by_uid(uid) self.assertEquals(user.firstname, firstname) self.assertEquals(user.lastname, lastname) def test_enabled(self): uid = u'jdoe' create_user(uid=uid) session.flush() user = self.user_repository.get_by_uid(uid) self.assert_(user.enabled) # this is what we want most of the time user.enabled = False session.flush() user = self.user_repository.get_by_uid(uid) self.assert_(not user.enabled) def test_by_uid(self): user = create_user( uid=u'jdoe', firstname=u'John', lastname=u'Doe', ) self.assert_( self.user_repository.get_by_uid(user.uid) is not None) self.assert_( self.user_repository.get_by_uid(user.uid + u'XXX') is None) def test_by_email(self): email = u'*****@*****.**' create_user( uid=u'jdoe', firstname=u'John', lastname=u'Doe', email=email, ) user = self.user_repository.get_by_email(email) self.assert_(user is not None) self.assertEquals(email, user.email) self.assert_( self.user_repository.get_by_email(user.email + u'XXX') is None) def test_store_password(self): user = create_user( uid=u'jdoe', firstname=u'John', lastname=u'Doe', password=u'password', ) self.assertEqual(user.password, user.encrypt_password(u'password')) self.assert_(not user.should_change_password()) def test_validate_password(self): user = create_user( uid=u'jdoe', firstname=u'John', lastname=u'Doe', password=u'password', ) self.assert_(user.validate_password('newpass') is None) self.assert_(isinstance(user.validate_password('a'), basestring)) def test_change_password_success(self): user = create_user( uid=u'jdoe', firstname=u'John', lastname=u'Doe', password=u'password' ) new_password = u'newpass' user.change_password(new_password) session.flush() self.assertEqual(user.password, user.encrypt_password(new_password)) def test_change_password_failure(self): user = create_user( uid=u'jdoe', firstname=u'John', lastname=u'Doe', password=u'password', ) new_password = u'a' with self.assertRaises(ValueError): user.change_password(new_password) def test_reset_password(self): user = create_user( uid=u'jdoe', firstname=u'John', lastname=u'Doe', password=u'password', ) new_password = user.reset_password() self.assertEqual(user.password, user.encrypt_password(new_password)) self.assert_(user.should_change_password()) def test_set_fi(self): user = create_user() fi = create_user() user.fi = fi self.assertEquals(fi, user.fi) def test_add_role(self): user = create_user() user.add_role(RoleType.Facilitator) self.assert_(user.has_role(RoleType.Facilitator)) def test_remove_missing_role(self): user = create_user() user.add_role(RoleType.Facilitator) user.remove_role(RoleType.Developer) self.assert_(user.has_role(RoleType.Facilitator)) self.assert_(not user.has_role(RoleType.Developer)) def test_deleting_a_user_also_remove_her_roles(self): user = create_user() user.add_role(RoleType.Facilitator) session.flush() user_uid = user.uid user.delete() session.flush() facilitators_uids = [ u.uid for u in self.user_repository.get_facilitators() ] self.assertFalse(user_uid in facilitators_uids) def test_remove_existing_role(self): user = create_user() user.add_role(RoleType.Facilitator) session.flush() user.remove_role(RoleType.Facilitator) self.assert_(not user.has_role(RoleType.Facilitator)) session.flush() facilitators = self.user_repository.get_facilitators() self.assert_(user not in facilitators) def test_get_by_role(self): user = create_user() create_user() user.add_role(RoleType.Facilitator) session.flush() facilitators = self.user_repository.get_facilitators() self.assertTrue(user in facilitators) def create_photo(self, size=100): out = StringIO() image = Image.new("RGB", (size, size)) image.save(out, "PNG") return out.getvalue() def test_photo(self): user = create_user() photo = self.create_photo(50) user.photo = photo session.flush() self.assertTrue(user.photo is not None) user.photo = None self.assertTrue(user.photo is None)
def __init__(self): self.user_repository = UserRepository()
class UserEditor(editor.Editor): def __init__(self, uid=None, email_unique=True, mobile_access=False): """User's informations editor In: - ``uid`` -- the uid of the user to edit (if we are in edit mode) - ``email_unique`` -- do we have to check for the email uniqueness or not (default yes) """ super(UserEditor, self).__init__(None) self.assignable_roles = [RoleType.Facilitator, RoleType.Developer] if mobile_access: self.assignable_roles.append(RoleType.MobileAccess) self.email_unique = email_unique self.uid = uid self.user_repository = UserRepository() self.reset_fields() @property def user(self): return self.user_repository.get_by_uid(self.uid) @property def profile_imported(self): return getattr(self.user, 'imported', False) @property def profile_url(self): return get_url_service().expand_url(['profile', self.uid]) def view_profile(self): event_management._emit_signal(self, "VIEW_USER_PROFILE", user_uid=self.uid) @property def creation_mode(self): return self.uid is None def pre_action(self): self.clear_roles() def validate_login(self, value): if self.creation_mode or value != self.user.uid: value = validators.unused_uid(value, True) return value def validate_email(self, value): if not self.email_unique: # We just check that a non empty email address has been supplied value = validators.non_empty_string(value) elif self.creation_mode or value != self.user.email: value = validators.unused_email(value, True) return value def reset_fields(self): user = self.user uid = user.uid if user else u'' email = user.email if user else u'' firstname = user.firstname if user else u'' lastname = user.lastname if user else u'' fi_uid = user.fi_uid if user else u'' roles = [role for role in self.assignable_roles if user.has_role(role)] if user else [] work_phone = (user.work_phone or u'') if user else u'' mobile_phone = (user.mobile_phone or u'') if user else u'' position = user.position if user else u'' corporation_id = (user.corporation_id or u'-1') if user else u'-1' direction_id = (user.direction_id or u'-1') if user else u'-1' service_id = (user.service_id or u'-1') if user else u'-1' site_id = (user.site_id or u'-1') if user else u'-1' subsite_id = (user.subsite_id or u'-1') if user else u'-1' enabled = user.enabled if user else True incorporated = user.incorporated if user else False self.login = editor.Property(uid).validate(self.validate_login) self.email = editor.Property(email).validate(self.validate_email) self.firstname = editor.Property(firstname).validate( validators.non_empty_string) self.lastname = editor.Property(lastname).validate( validators.non_empty_string) self.fi_uid = editor.Property(fi_uid).validate( validators.non_empty_string) self.roles = editor.Property(roles) self.work_phone = editor.Property(work_phone) self.mobile_phone = editor.Property(mobile_phone) self.position = editor.Property(position) self.corporation_id = editor.Property(corporation_id) self.direction_id = editor.Property(direction_id) self.service_id = editor.Property(service_id) self.site_id = editor.Property(site_id) self.subsite_id = editor.Property(subsite_id) self.enabled = editor.Property(enabled) self.incorporated = editor.Property(incorporated) def clear_roles(self): self.roles([]) def add_role(self, role): self.roles().append(role) def change_corp(self): self.direction_id('-1') self.service_id('-1') self.site_id('-1') self.subsite_id('-1') def change_dir(self): self.service_id('-1') self.site_id('-1') self.subsite_id('-1') def change_service(self): self.site_id('-1') self.subsite_id('-1') def change_site(self): self.subsite_id('-1') def get_corporations(self): return OrganizationData.get_corporations() def get_directions(self): return OrganizationData.get_directions(parent_id=self.corporation_id()) def get_services(self): return OrganizationData.get_services(parent_id=self.direction_id()) def get_sites(self): return OrganizationData.get_sites(parent_id=self.service_id()) def get_subsites(self): return OrganizationData.get_subsites(parent_id=self.site_id()) def get_facilitators(self): return UserData.get_facilitators() def commit(self): if not super(UserEditor, self).commit( (), ('login', 'email', 'roles', 'fi_uid', 'work_phone', 'mobile_phone', 'firstname', 'lastname', 'position', 'corporation_id', 'direction_id', 'site_id', 'service_id')): return False # FIXME: use the OrganizationRepository get_organization = lambda id: OrganizationData.get( id) if id != -1 else None corporation = get_organization(self.corporation_id.value) direction = get_organization(self.direction_id.value) service = get_organization(self.service_id.value) site = get_organization(self.site_id.value) subsite = get_organization(self.subsite_id.value) facilitator = self.user_repository.get_by_uid(self.fi_uid.value) # create or update the user updates = dict( email=self.email.value, firstname=self.firstname.value, lastname=self.lastname.value, enabled=self.enabled.value, position=self.position.value, corporation=corporation, direction=direction, service=service, site=site, incorporated=self.incorporated.value, work_phone=self.work_phone.value, mobile_phone=self.mobile_phone.value, fi=facilitator, subsite=subsite, ) if self.user: u = self.user u.set(**updates) else: u = self.user_repository.create(uid=self.login.value, **updates) password = u.reset_password() u.send_welcome_email(password) # roles for role in self.assignable_roles: if role in self.roles(): u.add_role(role) else: u.remove_role(role) return True
class StatisticsService(Unpicklable): """ Service that compute statistics """ def __init__(self): from eureka.domain.repositories import (CommentRepository, IdeaRepository, UserRepository, VoteIdeaRepository) self.user_repository = UserRepository() self.idea_repository = IdeaRepository() self.vote_idea_repository = VoteIdeaRepository() self.comment_repository = CommentRepository() @cached def _active_users(self): # Users enabled and who have logged in at least once return set(self.user_repository.get_active()) @cached def _votes(self): return set(self.vote_idea_repository.get_all()) @cached def _votes_by_challenge(self): votes_by_challenge = collections.defaultdict(set) for k, v in itertools.groupby(self._votes(), lambda v: v.idea.challenge): votes_by_challenge[k].update(set(v)) return votes_by_challenge @cached def _comments(self): return set(self.comment_repository.get_all()) @cached def _comments_by_challenge(self): comments_by_challenge = collections.defaultdict(set) for k, v in itertools.groupby(self._comments(), lambda c: c.idea.challenge): comments_by_challenge[k].update(set(v)) return comments_by_challenge @cached def _ideas(self): return set(self.idea_repository.get_published_ideas()) @cached def _ideas_by_challenge(self): ideas_by_challenge = collections.defaultdict(set) for i in self._ideas(): ideas_by_challenge[i.challenge].add(i) return ideas_by_challenge def get_users_statistics_on_connections(self, users, after_date=None): intersection = users.intersection(self._active_users()) if after_date: return len([ u for u in intersection if u.last_connection_date > after_date ]) else: return len(intersection) def get_users_statistics_on_ideas(self, users, after_date=None, challenge=NO_FILTER): ideas = (self._ideas_by_challenge()[challenge] if challenge is not NO_FILTER else self._ideas()) ideas = set(i for i in ideas if not set(i.authors).isdisjoint(users)) if after_date: ideas = [ idea for idea in ideas if idea.wf_context.publication_date and idea.wf_context.publication_date > after_date ] unique_authors = set(author for idea in ideas for author in idea.authors if author in users) return len(ideas), len(unique_authors) def get_users_statistics_on_votes(self, users, after_date=None, challenge=NO_FILTER): votes = (self._votes_by_challenge()[challenge] if challenge is not NO_FILTER else self._votes()) votes = set(v for v in votes if v.user in users) if after_date: votes = set(v for v in votes if v.timestamp and v.timestamp > after_date) unique_voters = set(vote.user for vote in votes) return len(votes), len(unique_voters) def get_users_statistics_on_comments(self, users, after_date=None, challenge=NO_FILTER): comments = (self._comments_by_challenge()[challenge] if challenge is not NO_FILTER else self._comments()) if after_date: comments = set( c for c in comments if c.submission_date and c.submission_date > after_date) comments = set(c for c in comments if c.created_by in users) unique_commentators = set(comment.created_by for comment in comments) return len(comments), len(unique_commentators) def get_users_statistics(self, users, after_date=None, challenge=NO_FILTER): """ Compute various statistics for a given group of users, returns an instance of UsersStatistics """ users = set(users) # first connections nb_connected_users = self.get_users_statistics_on_connections( users, after_date) # ideas total_ideas, nb_authors = self.get_users_statistics_on_ideas( users, after_date, challenge) # votes total_votes, nb_voters = self.get_users_statistics_on_votes( users, after_date, challenge) # comments total_comments, nb_commentators = ( self.get_users_statistics_on_comments(users, after_date, challenge)) return UsersStatistics( nb_connected=nb_connected_users, total_ideas=total_ideas, nb_authors=nb_authors, total_votes=total_votes, nb_voters=nb_voters, total_comments=total_comments, nb_commentators=nb_commentators, ) def get_users_points_statistics(self, users): """Compute statistics on users points""" statistics = {} users_status_levels = [(user, user.status_level_label) for user in users if user] for user, level in users_status_levels: statistics.setdefault(level, []).append(user) return statistics
class FIEditor(editor.Editor): def __init__(self, uid): super(FIEditor, self).__init__(None) self.uid = uid self.user_repository = UserRepository() # FI self.fi_uid = editor.Property(u'').validate( validators.non_empty_string) self.corporation_id = editor.Property(' - 1') self.direction_id = editor.Property(' - 1') self.service_id = editor.Property(' - 1') self.site_id = editor.Property(' - 1') self.subsite_id = editor.Property(' - 1') self.successor = editor.Property('').validate( validators.non_empty_string) self.filter = component.Component(UserFilter()) if self.user: self.filter().initialize_from_user_organization(self.user) @property def user(self): return self.user_repository.get_by_uid(self.uid) def get_fi_users(self): query = self.user_repository.get_facilitators() return self.filter().apply(query) # Refactor def change_corp(self): self.direction_id('-1') self.service_id('-1') self.site_id('-1') self.subsite_id('-1') def change_dir(self): self.service_id('-1') self.site_id('-1') self.subsite_id('-1') def change_service(self): self.site_id('-1') self.subsite_id('-1') def change_site(self): self.subsite_id('-1') def get_corporations(self): return OrganizationData.get_corporations() def get_directions(self): return OrganizationData.get_directions(parent_id=self.corporation_id()) def get_services(self): return OrganizationData.get_services(parent_id=self.direction_id()) def get_sites(self): return OrganizationData.get_sites(parent_id=self.service_id()) def get_subsites(self): return OrganizationData.get_subsites(parent_id=self.site_id()) def clear_successor(self): self.successor('') def replace_facilitator(self): if not super(FIEditor, self).commit((), ('successor',)): return False # transfer the FI responsibilities to the new user new_facilitator = self.user_repository.get_by_uid(self.successor()) self.user.transfer_responsibilities(RoleType.Facilitator, new_facilitator) flashmessage.set_flash(_(u'Facilitator replaced')) return True def _get_organization_label(self, org_id): if org_id == -1: return None # FIXME: use the OrganizationRepository instead return OrganizationData.get(org_id).label def add_entity(self): if not super(FIEditor, self).commit( (), ('corporation_id', 'direction_id', 'service_id', 'site_id')): return False corporation = self._get_organization_label(long(self.corporation_id())) direction = self._get_organization_label(long(self.direction_id())) service = self._get_organization_label(long(self.service_id())) site = self._get_organization_label(long(self.site_id())) subsite = self._get_organization_label(long(self.subsite_id())) users = self.user_repository.get_by_organization(corporation, direction, service, site, subsite, True) for user in users: user.fi_uid = self.uid flashmessage.set_flash(_(u'Entity assigned to the facilitator')) return True
class User(object): def __init__(self, parent, user): event_management._register_listener(parent, self) self.uid = user if is_string(user) else user.uid self.user_repository = UserRepository() self.pager = None @property def user(self): return self.user_repository.get_by_uid(self.uid) # the user represented by this block @property def _photo_filename(self): return photo_filename(self.uid, self.user.photo_date) def thumbnail_url(self, size): return get_url_service().expand_url(['profile-thumbnails', size, self._photo_filename]) @property def photo_url(self): return get_url_service().expand_url(['profile-photo', self._photo_filename]) @property def privileged_roles(self): relevant_roles = (RoleType.DSIG, RoleType.Developer, RoleType.Facilitator) return [unicode(RoleLabels[role]) for role in relevant_roles if self.user.has_role(role)] def profile_url(self, uid=None): return get_url_service().expand_url(['profile', (uid or self.uid)]) def view_profile(self, uid=None): event_management._emit_signal(self, "VIEW_USER_PROFILE", user_uid=(uid or self.uid)) def view_tracked_ideas(self, uid=None): event_management._emit_signal(self, "VIEW_USER_TRACKED_IDEAS", user_uid=(uid or self.uid)) def view_basket(self, uid=None): event_management._emit_signal(self, "VIEW_USER_BASKET", user_uid=(uid or self.uid)) def view_dsig_basket(self, uid=None): event_management._emit_signal(self, "VIEW_DSIG_BASKET", user_uid=(uid or self.uid)) def view_di_basket(self, uid=None): event_management._emit_signal(self, "VIEW_DI_BASKET", user_uid=(uid or self.uid)) def view_fi_basket(self, uid=None): event_management._emit_signal(self, "VIEW_FI_BASKET", user_uid=(uid or self.uid)) def view_administration(self, uid=None): event_management._emit_signal(self, "VIEW_ADMINISTRATION") @property def _ideas(self): if security.has_permissions('view_unpublished_ideas', self): return get_all_user_ideas(self.uid) else: return get_published_user_ideas(self.uid) @property def ideas_count(self): return self._ideas.count() def get_idea_pager(self): # FIXME: late import to avoid circular dependencies problem if self.pager is None: idea_pager = IdeaPager(self, lambda: self._ideas) idea_pager.change_transform("user") idea_pager.change_order("publication_date_desc") self.pager = InfinitePager(component.Component(idea_pager, model='ideas-list')) return self.pager def get_tracked_idea_count(self): return len(self.get_tracked_ideas()) def get_tracked_ideas(self): return self.user.tracked_ideas def remove_tracked_idea(self, idea_id): self.user.untrack_idea(idea_id) flashmessage.set_flash(_(u'Idea removed from tracking')) def events_history(self, days_ago=30): date = datetime.today() - timedelta(days_ago) return sorted(self.user.visible_events(date), key=operator.attrgetter('date'), reverse=True) def new_events_count(self, days_ago=30): date = datetime.today() - timedelta(days_ago) return len(set([e.idea.id for e in self.user.unread_events(date)])) def remove_event(self, event_id): self.user.hide_event(event_id) flashmessage.set_flash(_(u'Event removed')) def read_event(self, event_id): event = self.user.read_event(event_id) self.view_idea(event.idea.id) def read_all_events(self): self.user.read_all_events() def get_fi_ideas_basket_count(self): return get_fi_process_ideas(self.uid)().count() def get_di_ideas_basket_count(self): return get_di_process_ideas(self.uid)().count()
def setUp(self): super(TestUsers, self).setUp() self.user_repository = UserRepository()