def __init__(self, parent, challenge_id): # FIXME: late import to avoid circular dependencies problem from eureka.ui.desktop.idea import SubmitIdeaBox event_management._register_listener(parent, self) self.challenge_id = challenge_id self.challenge_repository = ChallengeRepository() self.submit_idea_box = component.Component(SubmitIdeaBox(self)) self._ideas = None if not self.challenge: raise ValueError('Invalid challenge id')
def init_portal_submit(self, url, *args): challenge_id = None if len(url) == 2: challenge_id = to_int(url[1]) # make sure the challenge exists and is active; otherwise, redirect to the "normal" submission challenge = ChallengeRepository().get_by_id(challenge_id) now = datetime.now() if not challenge or not challenge.is_active(now): raise redirect_to('/submit', permanent=True, base_url=get_url_service().base_url) self.show_submit_idea(challenge_id)
class ChallengesAdmin(object): def __init__(self, mobile_access): self.challenge_repository = ChallengeRepository() self.content = component.Component(None) self.mobile_access = mobile_access @property def challenges(self): return self.challenge_repository.get_all() def delete_challenge(self, id): challenge = self.challenge_repository.get_by_id(id) challenge.delete()
def __init__(self, challenge=None, mobile_access=False): self.id = challenge if (is_integer(challenge) or challenge is None) else challenge.id self.challenge_repository = ChallengeRepository() self.mobile_access = mobile_access challenge = self.challenge # properties self.title = editor.Property(u'').validate(validators.non_empty_string) self.short_title = editor.Property(u'').validate( validators.non_empty_string) self.created_by = editor.Property(u'').validate( lambda t: validators.user_email(t, True)) self.organization = editor.Property(u'').validate( validators.non_empty_string) self.associated_dis = editor.Property(u'').validate( validators.user_email_list) self.starting_date = editor.Property(u'').validate( validators.non_empty_date) self.ending_date = editor.Property(u'').validate( validators.non_empty_date) self.summary = editor.Property(u'').validate( validators.non_empty_string) self.description = editor.Property(u'').validate( validators.non_empty_string) self.mobile_description = editor.Property(u'') self.outcome = editor.Property(u'').validate(validators.string) self.tags = editor.Property(u'').validate( lambda t: validators.word_list(t, duplicates='remove')) if challenge: self.title.set(challenge.title) self.short_title.set(challenge.short_title) self.created_by.set(challenge.created_by.email) self.organization.set(challenge.organization) associated_dis_email = ','.join( user.email for user in challenge.associated_dis) self.associated_dis.set(associated_dis_email) self.starting_date.set( challenge.starting_date.date().strftime('%d/%m/%Y')) self.ending_date.set( challenge.ending_date.date().strftime('%d/%m/%Y')) self.summary.set(challenge.summary) self.description.set(challenge.description) self.mobile_description.set(challenge.mobile_description) self.outcome.set(challenge.outcome) self.tags.set(u', '.join(challenge.tags)) # Because the mobile description is optional in each eureka instance # and the validator will be triggered if we do this before self.mobile_description.validate(validators.non_empty_string)
def __init__(self, parent, challenge_id): # FIXME: late import to avoid circular dependencies problem from eureka.ui.desktop.idea import SubmitIdeaBox event_management._register_listener(parent, self) self.challenge_id = challenge_id self.challenge_repository = ChallengeRepository() self.submit_idea_box = component.Component(SubmitIdeaBox(self)) self._ideas = None if not self.challenge: raise ValueError('Invalid challenge id')
def __init__(self, challenge=None, mobile_access=False): self.id = challenge if (is_integer(challenge) or challenge is None) else challenge.id self.challenge_repository = ChallengeRepository() self.mobile_access = mobile_access challenge = self.challenge # properties self.title = editor.Property(u'').validate(validators.non_empty_string) self.short_title = editor.Property(u'').validate( validators.non_empty_string) self.created_by = editor.Property(u'').validate( lambda t: validators.user_email(t, True)) self.organization = editor.Property(u'').validate( validators.non_empty_string) self.associated_dis = editor.Property(u'').validate( validators.user_email_list) self.starting_date = editor.Property(u'').validate( validators.non_empty_date) self.ending_date = editor.Property(u'').validate( validators.non_empty_date) self.summary = editor.Property(u'').validate( validators.non_empty_string) self.description = editor.Property(u'').validate( validators.non_empty_string) self.mobile_description = editor.Property(u'') self.outcome = editor.Property(u'').validate(validators.string) self.tags = editor.Property(u'').validate( lambda t: validators.word_list(t, duplicates='remove')) if challenge: self.title.set(challenge.title) self.short_title.set(challenge.short_title) self.created_by.set(challenge.created_by.email) self.organization.set(challenge.organization) associated_dis_email = ','.join( user.email for user in challenge.associated_dis) self.associated_dis.set(associated_dis_email) self.starting_date.set( challenge.starting_date.date().strftime('%d/%m/%Y')) self.ending_date.set( challenge.ending_date.date().strftime('%d/%m/%Y')) self.summary.set(challenge.summary) self.description.set(challenge.description) self.mobile_description.set(challenge.mobile_description) self.outcome.set(challenge.outcome) self.tags.set(u', '.join(challenge.tags)) # Because the mobile description is optional in each eureka instance # and the validator will be triggered if we do this before self.mobile_description.validate(validators.non_empty_string)
class Challenge(object): def __init__(self, parent, challenge_id): # FIXME: late import to avoid circular dependencies problem from eureka.ui.desktop.idea import SubmitIdeaBox event_management._register_listener(parent, self) self.challenge_id = challenge_id self.challenge_repository = ChallengeRepository() self.submit_idea_box = component.Component(SubmitIdeaBox(self)) self._ideas = None if not self.challenge: raise ValueError('Invalid challenge id') @property def challenge(self): return self.challenge_repository.get_by_id(self.challenge_id) @property def challenge_url(self): return get_url_service().expand_url(['challenge', self.challenge.id]) @property def challenge_ideas_url(self): return get_url_service().expand_url( ['challenge_ideas', self.challenge.id]) @property def ideas(self): # lazy initialization if not self._ideas: self._ideas = self.create_idea_pager() return self._ideas def create_idea_pager(self): """Get an idea pager that show ideas in this challenge""" # FIXME: late import to avoid circular dependencies problem from eureka.ui.desktop.idea import IdeaPager q = queries.get_published_challenge_ideas(self.challenge_id) pager = IdeaPager(self, q) pager.specific_challenge() return pager
class Challenge(object): def __init__(self, parent, challenge_id): # FIXME: late import to avoid circular dependencies problem from eureka.ui.desktop.idea import SubmitIdeaBox event_management._register_listener(parent, self) self.challenge_id = challenge_id self.challenge_repository = ChallengeRepository() self.submit_idea_box = component.Component(SubmitIdeaBox(self)) self._ideas = None if not self.challenge: raise ValueError('Invalid challenge id') @property def challenge(self): return self.challenge_repository.get_by_id(self.challenge_id) @property def challenge_url(self): return get_url_service().expand_url(['challenge', self.challenge.id]) @property def challenge_ideas_url(self): return get_url_service().expand_url(['challenge_ideas', self.challenge.id]) @property def ideas(self): # lazy initialization if not self._ideas: self._ideas = self.create_idea_pager() return self._ideas def create_idea_pager(self): """Get an idea pager that show ideas in this challenge""" # FIXME: late import to avoid circular dependencies problem from eureka.ui.desktop.idea import IdeaPager q = queries.get_published_challenge_ideas(self.challenge_id) pager = IdeaPager(self, q) pager.specific_challenge() return pager
def _active_challenge_id(self): challenges = list(ChallengeRepository().get_by_active_at_date()) return challenges[0].id if challenges else None
def render_ideas_on_alert(self, h, comp, *args): challenges = [None] + list(ChallengeRepository().get_all()) domains = list(DomainRepository().get_all()) workflow = get_workflow() states = [ s for s in workflow.get_progression_states() if s != workflow.WFStates.RETURNED_BY_DI_STATE ] ideas_on_alert = self.get_ideas_on_alert() all_ideas = self.get_ideas_by_states(states) ideas_on_alert_grouped = self.group_by_challenge_and_domain(ideas_on_alert) all_ideas_grouped = self.group_by_challenge_and_domain(all_ideas) with h.table(class_='datatable'): # data with h.tbody: for challenge in challenges: available_domains = [ domain for domain in domains if (challenge, domain) in ideas_on_alert_grouped ] if available_domains: with h.tr: domain = available_domains[0] h << h.td(challenge.title if challenge else _(u'Off challenge'), rowspan=len(available_domains)) h << h.td(domain.i18n_label) render_ideas_on_alert_item( h, states, ideas_on_alert_grouped[(challenge, domain)], all_ideas_grouped[(challenge, domain)], comp.answer) for domain in available_domains[1:]: with h.tr: h << h.td(domain.i18n_label) render_ideas_on_alert_item( h, states, ideas_on_alert_grouped[(challenge, domain)], all_ideas_grouped[(challenge, domain)], comp.answer) # column headings with h.thead: with h.tr: h << h.th(colspan=2) h << h.th(_(u'State'), colspan=len(states)) with h.tr: h << h.th(_(u'Challenge')) h << h.th(_(u'Domain')) for state in states: h << h.th(_(state)) # totals with h.tfoot: with h.tr: h << h.td(_(u'Totals'), colspan=2) for state in states: total = len([ idea for idea in ideas_on_alert if idea.wf_context.state.label == state ]) total_all = len([ idea for idea in all_ideas if idea.wf_context.state.label == state ]) h << h.td('%s (%s)' % (total, total_all), style='white-space:nowrap') return h.root
def get_challenges(self): return ChallengeRepository().get_all()
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
def __init__(self, mobile_access): self.challenge_repository = ChallengeRepository() self.content = component.Component(None) self.mobile_access = mobile_access
class ChallengeEditor(editor.Editor): def __init__(self, challenge=None, mobile_access=False): self.id = challenge if (is_integer(challenge) or challenge is None) else challenge.id self.challenge_repository = ChallengeRepository() self.mobile_access = mobile_access challenge = self.challenge # properties self.title = editor.Property(u'').validate(validators.non_empty_string) self.short_title = editor.Property(u'').validate(validators.non_empty_string) self.created_by = editor.Property(u'').validate(lambda t: validators.user_email(t, True)) self.organization = editor.Property(u'').validate(validators.non_empty_string) self.associated_dis = editor.Property(u'').validate(validators.user_email_list) self.starting_date = editor.Property(u'').validate(validators.non_empty_date) self.ending_date = editor.Property(u'').validate(validators.non_empty_date) self.summary = editor.Property(u'').validate(validators.non_empty_string) self.description = editor.Property(u'').validate(validators.non_empty_string) self.mobile_description = editor.Property(u'') self.outcome = editor.Property(u'').validate(validators.string) self.tags = editor.Property(u'').validate(lambda t: validators.word_list(t, duplicates='remove')) if challenge: self.title.set(challenge.title) self.short_title.set(challenge.short_title) self.created_by.set(challenge.created_by.email) self.organization.set(challenge.organization) associated_dis_email = ','.join(user.email for user in challenge.associated_dis) self.associated_dis.set(associated_dis_email) self.starting_date.set(challenge.starting_date.date().strftime('%d/%m/%Y')) self.ending_date.set(challenge.ending_date.date().strftime('%d/%m/%Y')) self.summary.set(challenge.summary) self.description.set(challenge.description) self.mobile_description.set(challenge.mobile_description) self.outcome.set(challenge.outcome) self.tags.set(u', '.join(challenge.tags)) # Because the mobile description is optional in each eureka instance # and the validator will be triggered if we do this before self.mobile_description.validate(validators.non_empty_string) def gallery_url(self, editor_id): return get_url_service().expand_url(['gallery-for', editor_id]) def post_validate(self): """Inter-field validation""" if self.ending_date.value < self.starting_date.value: self.ending_date.error = _(u'Ending date must be later than starting date') @property def challenge(self): return self.challenge_repository.get_by_id(self.id) @property def finished(self): challenge = self.challenge return (challenge.status() == ChallengeStatus.Finished) if challenge else False 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
class ChallengeEditor(editor.Editor): def __init__(self, challenge=None, mobile_access=False): self.id = challenge if (is_integer(challenge) or challenge is None) else challenge.id self.challenge_repository = ChallengeRepository() self.mobile_access = mobile_access challenge = self.challenge # properties self.title = editor.Property(u'').validate(validators.non_empty_string) self.short_title = editor.Property(u'').validate( validators.non_empty_string) self.created_by = editor.Property(u'').validate( lambda t: validators.user_email(t, True)) self.organization = editor.Property(u'').validate( validators.non_empty_string) self.associated_dis = editor.Property(u'').validate( validators.user_email_list) self.starting_date = editor.Property(u'').validate( validators.non_empty_date) self.ending_date = editor.Property(u'').validate( validators.non_empty_date) self.summary = editor.Property(u'').validate( validators.non_empty_string) self.description = editor.Property(u'').validate( validators.non_empty_string) self.mobile_description = editor.Property(u'') self.outcome = editor.Property(u'').validate(validators.string) self.tags = editor.Property(u'').validate( lambda t: validators.word_list(t, duplicates='remove')) if challenge: self.title.set(challenge.title) self.short_title.set(challenge.short_title) self.created_by.set(challenge.created_by.email) self.organization.set(challenge.organization) associated_dis_email = ','.join( user.email for user in challenge.associated_dis) self.associated_dis.set(associated_dis_email) self.starting_date.set( challenge.starting_date.date().strftime('%d/%m/%Y')) self.ending_date.set( challenge.ending_date.date().strftime('%d/%m/%Y')) self.summary.set(challenge.summary) self.description.set(challenge.description) self.mobile_description.set(challenge.mobile_description) self.outcome.set(challenge.outcome) self.tags.set(u', '.join(challenge.tags)) # Because the mobile description is optional in each eureka instance # and the validator will be triggered if we do this before self.mobile_description.validate(validators.non_empty_string) def gallery_url(self, editor_id): return get_url_service().expand_url(['gallery-for', editor_id]) def post_validate(self): """Inter-field validation""" if self.ending_date.value < self.starting_date.value: self.ending_date.error = _( u'Ending date must be later than starting date') @property def challenge(self): return self.challenge_repository.get_by_id(self.id) @property def finished(self): challenge = self.challenge return (challenge.status() == ChallengeStatus.Finished) if challenge else False 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