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 get_ideas(self): idea_repository = IdeaRepository() current_user = get_current_user() if not current_user: query = idea_repository.get_by_home_settings() else: query = idea_repository.get_by_home_settings(current_user.home_settings) query = query.order_by(None) # remove the default ordering return idea_repository.sort_by_last_wf_comment_date(query)
def get_ideas(self): idea_repository = IdeaRepository() current_user = get_current_user() if not current_user: query = idea_repository.get_by_home_settings() else: query = idea_repository.get_by_home_settings( current_user.home_settings) query = query.order_by(None) # remove the default ordering return idea_repository.sort_by_last_wf_comment_date(query)
def create_idea_box(idea_ids, page_title=_(u'Ideas on alert')): query = lambda: IdeaRepository().get_by_ids(idea_ids) pager = IdeaPager(self.parent, query) return IdeaPagerBox(pager, model='simple', title=page_title, ok_button=_(u'Back to the dashboard'))
def submit(self, comp): if self.commit((), ('value', )): idea_data = IdeaRepository().get_by_id(int(self.value())) if idea_data: comp.answer((int(self.value()), '', 'idea')) else: self.value.error = _('No such idea')
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 render_portal_xml_published_ideas(self, h, comp, *args, **kw): ir = IdeaRepository() with h.ideas: for idea in get_all_published_ideas().limit(10): with h.idea: h << h.title(idea.title) h << h.description(idea.description) # The author is not available in the idea result i = ir.get_by_id(idea.id) user_data = i.authors[0] if i.authors else None # We must wrap it with the heavyweight User class to access the photo_url user = User(None, user_data.uid) with h.author: h << h.uid(user.uid) h << h.lastname(user.user.lastname) h << h.firstname(user.user.firstname) h << h.avatar(user.photo_url) return h.root
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 goto(self, idea_id, mode=u"view"): assert is_integer(idea_id) self.idea_i = None self.content.becomes(None) idea = IdeaRepository().get_by_id(idea_id) if not idea: raise HTTPNotFound() i = self._create_idea(idea) # Show the editor when the current user is the creator and the # idea state is DRAFT or AUTHOR_NORMALIZATION workflow = get_workflow() edit_state = i.i.wf_context.state.label in ( workflow.WFStates.INITIAL_STATE, workflow.WFStates.DRAFT_STATE, workflow.WFStates.AUTHOR_NORMALIZE_STATE, workflow.WFStates.RETURNED_BY_DI_STATE) # FIXME: is this a good idea to force the mode like this?! current_user = get_current_user() if current_user and (current_user in i.i.authors) and edit_state: mode = u"edit" if mode == u"edit": self.content.becomes(IdeaUpdater(i), model='form') else: self.content.becomes(i, model='detail') if current_user: # FIXME: WTF! Remove this! # Note: we do not use the association proxy and even no # entity to avoid the index crawling extension to be # notified of a change: we do not want to update the # document each time it is viewed! ReadIdeaData(user_uid=current_user.uid, idea_id=i.id, timestamp=datetime.now()) idea.readers_updated() event_management._emit_signal(self, "VIEW_IDEA", mode=mode)
def goto(self, idea_id, mode=u"view"): assert is_integer(idea_id) self.idea_i = None self.content.becomes(None) idea = IdeaRepository().get_by_id(idea_id) if not idea: raise HTTPNotFound() i = self._create_idea(idea) # Show the editor when the current user is the creator and the # idea state is DRAFT or AUTHOR_NORMALIZATION workflow = get_workflow() edit_state = i.i.wf_context.state.label in (workflow.WFStates.INITIAL_STATE, workflow.WFStates.DRAFT_STATE, workflow.WFStates.AUTHOR_NORMALIZE_STATE, workflow.WFStates.RETURNED_BY_DI_STATE) # FIXME: is this a good idea to force the mode like this?! current_user = get_current_user() if current_user and (current_user in i.i.authors) and edit_state: mode = u"edit" if mode == u"edit": self.content.becomes(IdeaUpdater(i), model='form') else: self.content.becomes(i, model='detail') if current_user: # FIXME: WTF! Remove this! # Note: we do not use the association proxy and even no # entity to avoid the index crawling extension to be # notified of a change: we do not want to update the # document each time it is viewed! ReadIdeaData(user_uid=current_user.uid, idea_id=i.id, timestamp=datetime.now()) idea.readers_updated() event_management._emit_signal(self, "VIEW_IDEA", mode=mode)
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 show_form(self, id): self.menu().selected(id) factory = self.choices[id][0]() elt_id, message, action = self.form.call(factory, model='form') if action in ['idea', 'direction']: if action == 'idea': idea = Idea(None, IdeaRepository().get_by_id(elt_id)) self.send_email_idea(idea) else: direction_label = get_direction_label(elt_id) self.send_email_direction(direction_label, message) flashmessage.set_flash( _(u'Your message has been sent. Thank you for your awareness !' )) self.idea.goto()
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 edit_idea(self, draft): # read the fields submission_date = self.idea.i.submission_date if self.idea else datetime.now() title = self.title.value description = self.description.value impact = self.impact.value domain = DomainRepository().get_by_id(self.domain_id.value) challenge_id = self.challenge_id.value challenge = ChallengeRepository().get_by_id( challenge_id) if challenge_id else None # make sure the challenge was active at the submission_date if challenge and not challenge.is_active(submission_date): challenge = None tags = [self.get_or_create_tag(tag.lower()) for tag in self.tags.value] # create or update the idea # mandatory fields mandatory_fields = dict( title=title, description=description, impact=impact, domain=domain, challenge=challenge, tags=tags, ) if not self.idea: idea = IdeaRepository().create(submitted_by=get_current_user(), submission_date=submission_date, **mandatory_fields) else: idea = IdeaRepository().get_by_id(self.idea.id) idea.set(**mandatory_fields) # Optional fields idea.benefit_department = self.benefit_department.value idea.origin = self.origin.value idea.implementation = self.implementation.value self.update_idea_authors(idea) for attr in ('attachment_1', 'attachment_2', 'attachment_3'): property_value = getattr(self, attr).value if property_value is not None: idea_attachment = getattr(idea, attr) if idea_attachment: setattr(idea, attr, None) # idea_attachment.delete() setattr(idea, attr, self.create_attachement(property_value)) idea.show_creator = not self.anonymous.value idea.already_done = self.already_done.value # workflow workflow = get_workflow() draft_event = workflow.WFEvents.DRAFT_EVENT submit_event = workflow.WFEvents.SUBMIT_EVENT def process_event(idea, event): wf_process_event(from_user=get_current_user(), idea=idea, event=event, notify=flashmessage.set_flash) if draft: # save as a draft process_event(idea, draft_event) else: # submit the idea process_event(idea, submit_event) return idea
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
def i(self): return IdeaRepository().get_by_id(self.id)
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
def __init__(self): self.user_repository = UserRepository() self.idea_repository = IdeaRepository() self.vote_idea_repository = VoteIdeaRepository() self.comment_repository = CommentRepository()
def find_ideas_count(self): return IdeaRepository().get_by_workflow_state().count()
def get_ideas_by_states(self, states): return IdeaRepository().get_by_states(states)
def get_ideas_on_alert(self): return IdeaRepository().get_by_reminder_before_date( datetime.now(), ReminderType.UnchangedState)
def __init__(self): self.user_repository = UserRepository() self.idea_repository = IdeaRepository() self.vote_idea_repository = VoteIdeaRepository() self.comment_repository = CommentRepository()