def dispatch(self): sprint_id = self.request.GET.get('sprint_id') sprint = Sprint.query.get(sprint_id) form = SprintForm(self.request.POST, obj=sprint) if self.request.method == 'POST' and form.validate(): project_id = form.project_id.data project = Project.query.get(project_id) sprint.name = form.name.data sprint.client_id = project.client_id sprint.project_id = project.id sprint.team_id = form.team_id.data or None sprint.bugs_project_ids = map(int, form.bugs_project_ids.data) sprint.start = form.start.data sprint.end = form.end.data sprint.goal = form.goal.data sprint.board = form.board.data sprint.retrospective_note = form.retrospective_note.data DBSession.add(sprint) self.flash(self._(u"Sprint edited")) LOG(u"Sprint edited") if self.request.POST.get('save-and-go'): url = self.request.url_for('/scrum/sprint/board', sprint_id=sprint.id) else: url = self.request.url_for('/scrum/sprint/edit', sprint_id=sprint.id) return HTTPFound(location=url) return dict( form=form, sprint=sprint )
def calculate_velocities(self): self.velocity = \ 8.0 * self.achieved_points / self.worked_hours \ if self.worked_hours else 0.0 self.story_velocity = \ 8.0 * self.achieved_points / self.bugs_worked_hours \ if self.bugs_worked_hours else 0.0 sprint_velocities = DBSession.query( Sprint.velocity, Sprint.story_velocity, ).filter(Sprint.project_id == self.project_id) \ .filter(Sprint.id != self.id) \ .all() sprint_velocities.append((self.velocity, self.story_velocity)) velocities, story_velocities = zip(*sprint_velocities) self.velocity_mean = float(sum(velocities)) / len(velocities) self.story_velocity_mean = \ float(sum(story_velocities)) / len(story_velocities) DBSession.add(self)
def post(self): if not self.request.is_xhr: return HTTPBadRequest() date = self.v['date'] form = TimeEntryForm(self.request.POST) if form.validate(): project_id = form.project_id.data time = TimeEntry(date=date, user_id=self.request.user.id, time=form.time.data, description=form.description.data, ticket_id=form.ticket_id.data, project_id=project_id if project_id else None) DBSession.add(time) LOG(u'Ajax - Time entry added') entries = self._get_time_entries(date) total_sum = sum(entry.time for (tracker, entry) in entries if not entry.deleted) template = render('/times/_list.html', dict(entries=entries, total_sum=total_sum), request=self.request) return dict(status='success', html=template) errors = u'<br />'.join((u"%s - %s" % (field, u', '.join(errors)) for field, errors in form.errors.iteritems())) return dict(status='error', errors=errors)
def post(self): lateness = self.request.json.get('lateness') form = LateApplicationForm(MultiDict(**lateness), user=self.request.user) if form.validate(): date = form.popup_date.data explanation = form.popup_explanation.data in_future = date > datetime.date.today() late = Late( user_id=self.request.user.id, date=date, explanation=explanation, justified=in_future or None, late_start=form.late_start.data, late_end=form.late_end.data, work_from_home=form.work_from_home.data, ) DBSession.add(late) memcache.delete(MEMCACHED_NOTIFY_KEY % date) if in_future and is_production: event_id = self._add_event(date, explanation) return dict( entry=True ) self.request.response.status = 400 return form.errors
def dispatch(self): client_id = self.request.GET.get('client_id') client = Client.query.get(client_id) form = ProjectForm(self.request.POST) if self.request.method == 'POST' and form.validate(): tracker_id = form.tracker_id.data coordinator_id = int(form.coordinator_id.data) if form.coordinator_id.data.isdigit() else None project = Project( client=client, name=form.name.data, coordinator_id=coordinator_id, tracker_id=tracker_id, turn_off_selectors=form.turn_off_selectors.data, project_selector=form.project_selector.data, component_selector=form.component_selector.data, version_selector=form.version_selector.data, ticket_id_selector=form.ticket_id_selector.data, active=form.active.data, google_card=form.google_card.data, google_wiki=form.google_wiki.data, mailing_url=form.mailing_url.data, working_agreement=form.working_agreement.data, definition_of_done=form.definition_of_done.data, definition_of_ready=form.definition_of_ready.data, continuous_integration_url=form.continuous_integration_url.data, backlog_url=form.backlog_url.data, status = form.status.data, ) DBSession.add(project) DBSession.flush() self.flash(self._(u"Project added")) LOG(u"Project added") SelectorMapping.invalidate_for(tracker_id) return HTTPFound(location=self.request.url_for('/client/view', client_id=project.client_id)) return dict(client=client, form=form)
def post(self): tracker_id = self.request.GET.get('tracker_id') tracker = Tracker.query.get(tracker_id) credentials = self._get_current_users_credentials_for_tracker(tracker) form = TrackerLoginForm(self.request.POST, obj=credentials) _add_tracker_login_validator(tracker.name, form) if form.validate(): if credentials is None: credentials = TrackerCredentials( user_id=self.request.user.id, tracker_id=tracker.id, login=form.login.data, password=form.password.data, ) DBSession.add(credentials) else: credentials.login = form.login.data credentials.password = form.password.data self.flash(self._(u"Credentials saved")) LOG(u"Credentials saved") url = self.request.url_for('/tracker/list') return HTTPFound(location=url) return dict(form=form, tracker=tracker)
def dispatch(self): form = AbsenceCreateForm(self.request.POST, request=self.request) days, mandated, used, left = 0, 0, 0, 0 if form.popup_date_start.data: mandated, used, left = user_leave(self.request, form.popup_date_start.data.year) if form.popup_date_end.data: days = h.get_working_days(form.popup_date_start.data, form.popup_date_end.data) left -= days if self.request.method == 'POST' and form.validate(): date_start = form.popup_date_start.data date_end = form.popup_date_end.data type = form.popup_type.data remarks = form.popup_remarks.data user_id = form.popup_user_id.data absence = Absence( user_id=user_id, date_start=date_start, date_end=date_end, days=days, type=type, remarks=remarks, ) DBSession.add(absence) return Response(self._('Done') + RELOAD_PAGE) return dict(form=form, days=days, mandated=mandated, used=used, left=left)
def dispatch(self): form = SprintForm(self.request.POST) if self.request.method == 'POST' and form.validate(): project = Project.query.get(int(form.project_id.data)) sprint = Sprint( name=form.name.data, client_id=project.client_id, project_id=project.id, team_id=form.team_id.data or None, bugs_project_ids = map(int, form.bugs_project_ids.data), start=form.start.data, end=form.end.data, board=form.board.data, goal=form.goal.data, retrospective_note = form.retrospective_note.data, ) DBSession.add(sprint) DBSession.flush() self.flash(self._(u"New sprint added")) LOG(u"Sprint added") url = self.request.url_for('/scrum/sprint/show', sprint_id=sprint.id) return HTTPFound(location=url) return dict( form=form, )
def add_time(user_id, date, bug_id, project_id, hours, subject): # try finding existing entry for this bug session = DBSession() bug_id = str(bug_id) entry = TimeEntry.query.filter(TimeEntry.user_id==user_id) \ .filter(TimeEntry.date==date.date()) \ .filter(TimeEntry.ticket_id==bug_id) \ .filter(TimeEntry.project_id==project_id).first() if not entry: # create new entry entry = TimeEntry(user_id=user_id, date=date.date(), time=hours, description=subject, ticket_id=bug_id, project_id=project_id, modified_ts=date) session.add(entry) LOG(u'Adding new entry') else: # update existing entry if not entry.frozen: entry.time += hours entry.modified_ts = date # TODO: this might remove an already existing lateness session.add(entry) LOG(u'Updating existing entry') else: LOG(u'Omission of an existing entry because it is frozen')
def post(self): lateness = self.request.json.get('lateness') form = LateApplicationForm(MultiDict(**lateness), user=self.request.user) if form.validate(): date = form.popup_date.data explanation = form.popup_explanation.data in_future = date > datetime.date.today() late = Late( user_id=self.request.user.id, date=date, explanation=explanation, justified=in_future or None, late_start=form.late_start.data, late_end=form.late_end.data, work_from_home=form.work_from_home.data, ) DBSession.add(late) memcache.delete(MEMCACHED_NOTIFY_KEY % date) if in_future and is_production: event_id = self._add_event(date, explanation) return dict(entry=True) self.request.response.status = 400 return form.errors
def add_time(user_id, date, bug_id, project_id, hours, subject): # try finding existing entry for this bug session = DBSession() bug_id = str(bug_id) entry = TimeEntry.query.filter(TimeEntry.user_id==user_id) \ .filter(TimeEntry.date==date.date()) \ .filter(TimeEntry.ticket_id==bug_id) \ .filter(TimeEntry.project_id==project_id).first() if not entry: # create new entry entry = TimeEntry( user_id=user_id, date=date.date(), time=hours, description=subject, ticket_id=bug_id, project_id = project_id, modified_ts=date ) session.add(entry) LOG(u'Adding new entry') else: # update existing entry if not entry.frozen: entry.time += hours entry.modified_ts = date # TODO: this might remove an already existing lateness session.add(entry) LOG(u'Updating existing entry') else: LOG(u'Omission of an existing entry because it is frozen')
def make_admin(config_path): from intranet3.models import DBSession, Base from intranet3.models import User user_login = sys.argv[-1] if len(sys.argv) < 4: print u"Provide user login" return session = DBSession() user = session.query(User).filter(User.email==user_login).first() if not user: print u"No such user: %s" % user_login return if 'admin' in user.groups: print u'Removing %s from group admin' % user.name groups = list(user.groups) groups.remove('admin') user.groups = groups else: print u'Adding %s to group admin' % user.name groups = list(user.groups) groups.append('admin') user.groups = groups session.add(user) transaction.commit()
def dispatch(self): client_id = self.request.GET.get('client_id') client = Client.query.get(client_id) form = ClientForm(self.request.POST, obj=client) if self.request.method == 'POST' and form.validate(): coordinator_id = int(form.coordinator_id.data) if form.coordinator_id.data.isdigit() else None client.name = form.name.data client.active = client.active client.google_card = form.google_card.data client.google_wiki = form.google_wiki.data client.color=form.color.data client.selector = form.selector.data client.emails = form.emails.data client.coordinator_id = coordinator_id client.street = form.street.data client.city = form.city.data client.postcode = form.postcode.data client.nip = form.nip.data client.note = form.note.data client.wiki_url = form.wiki_url.data client.mailing_url = form.mailing_url.data DBSession.add(client) self.flash(self._(u"Client saved")) LOG(u"Client saved") return HTTPFound(location=self.request.url_for("/client/view", client_id=client.id)) projects = client.projects return dict(client_id=client.id, form=form, projects=projects)
def post(self): tracker_id = self.request.GET.get('tracker_id') tracker = Tracker.query.get(tracker_id) credentials = self._get_current_users_credentials_for_tracker(tracker) form = TrackerLoginForm(self.request.POST, obj=credentials) _add_tracker_login_validator(tracker.name, form) if form.validate(): if credentials is None: credentials = TrackerCredentials( user_id=self.request.user.id, tracker_id=tracker.id, login=form.login.data, password=form.password.data, ) DBSession.add(credentials) else: credentials.login=form.login.data credentials.password=form.password.data self.flash(self._(u"Credentials saved")) LOG(u"Credentials saved") url = self.request.url_for('/tracker/list') return HTTPFound(location=url) return dict(form=form, tracker=tracker)
def dispatch(self): form = AbsenceCreateForm(self.request.POST, request=self.request) days, mandated, used, left = 0, 0, 0, 0 if form.popup_date_start.data: mandated, used, left = user_leave(self.request, form.popup_date_start.data.year) if form.popup_date_end.data: days = h.get_working_days(form.popup_date_start.data, form.popup_date_end.data) left -= days if self.request.method == 'POST' and form.validate(): date_start = form.popup_date_start.data date_end = form.popup_date_end.data type = form.popup_type.data remarks = form.popup_remarks.data user_id = form.popup_user_id.data absence = Absence( user_id=user_id, date_start=date_start, date_end=date_end, days=days, type=type, remarks=remarks, ) DBSession.add(absence) return Response(self._('Done') + RELOAD_PAGE) return dict( form=form, days=days, mandated=mandated, used=used, left=left )
def post(self): if not self.request.is_xhr: return HTTPBadRequest() date = self.v['date'] form = TimeEntryForm(self.request.POST) if form.validate(): project_id = form.project_id.data time = TimeEntry( date = date, user_id = self.request.user.id, time = form.time.data, description = form.description.data, ticket_id = form.ticket_id.data, project_id = project_id if project_id else None ) DBSession.add(time) LOG(u'Ajax - Time entry added') entries = self._get_time_entries(date) total_sum = sum(entry.time for (tracker, entry) in entries if not entry.deleted) template = render( '/times/_list.html', dict(entries=entries, total_sum=total_sum), request=self.request ) return dict(status='success', html=template) errors = u'<br />'.join((u"%s - %s" % (field, u', '.join(errors)) for field, errors in form.errors.iteritems())) return dict(status='error', errors=errors)
def post(self): args = self.request.json year = int(args.pop('year')) if 1999 > year > 2099: return dict(status='nok', reason='ZÅ‚y rok %s' % year) leaves = Leave.query.filter(Leave.year==year).all() leaves = groupby(leaves, lambda l: l.user_id) for user_id, (mandated, remarks) in args.iteritems(): user_id = int(user_id) try: mandated = int(mandated) except Exception: user = User.query.get(user_id) return dict( status='nok', reason=self._(u'Wrong hours format: ${hours} for user ${name}', hours=mandated, name=user.name) ) if 0 > mandated or mandated > 99: user = User.query.get(user_id) return dict( status='nok', reason=self._(u'Wrong hours number: ${hours} for user ${name}', hours=mandated, name=user.name) ) leave_obj = leaves.get(user_id) if not leave_obj: leave_obj = Leave(user_id=user_id, year=year) else: leave_obj = leave_obj[0] leave_obj.number = mandated leave_obj.remarks = remarks DBSession.add(leave_obj) return dict(status='ok')
def dispatch(self): form = ClientAddForm(self.request.POST) if self.request.method == 'POST' and form.validate(): coordinator_id = int(form.coordinator_id.data) if form.coordinator_id.data.isdigit() else None client = Client( name=form.name.data, google_card=form.google_card.data, google_wiki=form.google_wiki.data, color=form.color.data, selector=form.selector.data, emails=form.emails.data, coordinator_id=coordinator_id, street=form.street.data, city=form.city.data, postcode=form.postcode.data, nip=form.nip.data, note=form.note.data, wiki_url=form.wiki_url.data, mailing_url=form.mailing_url.data ) DBSession.add(client) DBSession.flush() self.flash(self._(u"New client added")) LOG(u"Client added") return HTTPFound(location=self.request.url_for("/client/view", client_id=client.id)) return dict(form=form)
def make_admin(config_path): from intranet3.models import DBSession, Base from intranet3.models import User user_login = sys.argv[-1] if len(sys.argv) < 4: print u"Provide user login" return session = DBSession() user = session.query(User).filter(User.email == user_login).first() if not user: print u"No such user: %s" % user_login return if 'admin' in user.groups: print u'Removing %s from group admin' % user.name groups = list(user.groups) groups.remove('admin') user.groups = groups else: print u'Adding %s to group admin' % user.name groups = list(user.groups) groups.append('admin') user.groups = groups session.add(user) transaction.commit()
def dispatch(self): subpage = self.request.GET.get('subpage', 'general') if subpage not in ['general', 'reports', 'spreadsheets', 'access']: return HTTPForbidden() config_obj = ApplicationConfig.get_current_config(allow_empty=True) FormRef = getattr(config_forms, "%sForm" % subpage.title()) if config_obj is not None: LOG(u"Found config object from %s" % (config_obj.date, )) form = FormRef(self.request.POST, obj=config_obj) else: LOG(u"Config object not found") form = FormRef(self.request.POST) if self.request.method == 'POST' and form.validate(): if config_obj is None: config_obj = ApplicationConfig() # Add/Edit data if subpage == 'general': config_obj.office_ip = form.office_ip.data config_obj.google_user_email = form.google_user_email.data config_obj.google_user_password = form.google_user_password.data config_obj.cleaning_time_presence = form.cleaning_time_presence.data config_obj.absence_project_id = form.absence_project_id.data if form.absence_project_id.data else None config_obj.monthly_late_limit = form.monthly_late_limit.data config_obj.monthly_incorrect_time_record_limit = form.monthly_incorrect_time_record_limit.data elif subpage == 'reports': config_obj.reports_project_ids = [ int(id) for id in form.reports_project_ids.data ] config_obj.reports_omit_user_ids = [ int(id) for id in form.reports_omit_user_ids.data ] config_obj.reports_without_ticket_project_ids = [ int(id) for id in form.reports_without_ticket_project_ids.data ] config_obj.reports_without_ticket_omit_user_ids = [ int(id) for id in form.reports_without_ticket_omit_user_ids.data ] elif subpage == 'spreadsheets': config_obj.holidays_spreadsheet = form.holidays_spreadsheet.data config_obj.hours_employee_project = form.hours_employee_project.data config_obj.hours_ticket_user_id = form.hours_ticket_user_id.data if form.hours_ticket_user_id.data else None elif subpage == "access": config_obj.freelancers = form.freelancers.data DBSession.add(config_obj) config_obj.invalidate_office_ip() LOG(u"Config object saved") self.flash(self._(u'Application Config saved'), klass='success') return HTTPFound( location=self.request.url_for('/config/view', subpage=subpage)) return dict(form=form, subpage=subpage)
def create_config(env): from intranet3.models import * import transaction config = ApplicationConfig( office_ip='', google_user_email='', google_user_password='', holidays_spreadsheet='', hours_employee_project='', ) DBSession.add(config) transaction.commit()
def __call__(self, *args, **kwargs): config = ApplicationConfig.get_current_config(allow_empty=True) if config is None: WARN(u'Application config not found, emails cannot be checked') return trackers = dict( (tracker.mailer, tracker) for tracker in Tracker.query.filter(Tracker.mailer != None).filter(Tracker.mailer != '') ) if not len(trackers): WARN(u'No trackers have mailers configured, email will not be checked') return username = config.google_user_email.encode('utf-8') password = config.google_user_password.encode('utf-8') # TODO logins_mappings = dict( (tracker.id, TrackerCredentials.get_logins_mapping(tracker)) for tracker in trackers.itervalues() ) selector_mappings = dict( (tracker.id, SelectorMapping(tracker)) for tracker in trackers.itervalues() ) # find all projects connected to the tracker projects = dict( (project.id, project) for project in Project.query.all() ) # all pre-conditions should be checked by now # start fetching fetcher = MailFetcher( username, password, ) # ok, we have all mails, lets create timeentries from them extractor = TimeEntryMailExtractor( trackers, logins_mappings, projects, selector_mappings, ) for msg in fetcher: timeentry = extractor.get(msg) if timeentry: DBSession.add(timeentry) transaction.commit()
def dispatch(self): subpage = self.request.GET.get('subpage', 'general') if subpage not in ['general', 'reports', 'spreadsheets', 'access']: return HTTPForbidden() config_obj = ApplicationConfig.get_current_config(allow_empty=True) FormRef = getattr(config_forms, "%sForm"% subpage.title()) if config_obj is not None: LOG(u"Found config object from %s" % (config_obj.date, )) form = FormRef(self.request.POST, obj=config_obj) else: LOG(u"Config object not found") form = FormRef(self.request.POST) if self.request.method == 'POST' and form.validate(): if config_obj is None: config_obj = ApplicationConfig() # Add/Edit data if subpage == 'general': config_obj.office_ip = form.office_ip.data config_obj.google_user_email = form.google_user_email.data config_obj.google_user_password = form.google_user_password.data config_obj.cleaning_time_presence = form.cleaning_time_presence.data config_obj.absence_project_id = form.absence_project_id.data if form.absence_project_id.data else None config_obj.monthly_late_limit = form.monthly_late_limit.data config_obj.monthly_incorrect_time_record_limit = form.monthly_incorrect_time_record_limit.data elif subpage == 'reports': config_obj.reports_project_ids = [int(id) for id in form.reports_project_ids.data] config_obj.reports_omit_user_ids = [int(id) for id in form.reports_omit_user_ids.data] config_obj.reports_without_ticket_project_ids = [int(id) for id in form.reports_without_ticket_project_ids.data] config_obj.reports_without_ticket_omit_user_ids = [int(id) for id in form.reports_without_ticket_omit_user_ids.data] elif subpage == 'spreadsheets': config_obj.holidays_spreadsheet = form.holidays_spreadsheet.data config_obj.hours_employee_project = form.hours_employee_project.data config_obj.hours_ticket_user_id = form.hours_ticket_user_id.data if form.hours_ticket_user_id.data else None elif subpage == "access": config_obj.freelancers = form.freelancers.data DBSession.add(config_obj) config_obj.invalidate_office_ip() LOG(u"Config object saved") self.flash(self._(u'Application Config saved'), klass='success') return HTTPFound(location=self.request.url_for('/config/view', subpage=subpage)) return dict( form=form, subpage=subpage )
def post(self): form = TrackerForm(self.request.POST) if form.validate(): tracker = Tracker(type=form.type.data, name=form.name.data, url=form.url.data, mailer=form.mailer.data) DBSession.add(tracker) self.flash(self._(u"New tracker added")) LOG(u"Tracker added") url = self.request.url_for('/tracker/list') return HTTPFound(location=url) return dict(form=form)
def post(self): form = WrongTimeJustificationForm(self.request.POST, user=self.request.user) if form.validate(): wrongtime = WrongTime( user_id=self.request.user.id, date=form.popup_date.data, explanation=form.popup_explanation.data, ) DBSession.add(wrongtime) LOG(u"WrongTime added") response = '%s %s' % (self._(u'Explanation added'), CHANGE_STATUS % self._('Waits for verification')) return Response(response) return dict(form=form)
def post(self): timeentry = self.v['timeentry'] next_ = self.request.GET.get('next') if not next_: next_ = self.request.url_for( '/times/list', date=timeentry.date.strftime('%d.%m.%Y'), ) form = TimeEntryForm(self.request.POST, obj=timeentry) date = timeentry.date today = datetime.date.today() if form.validate(): if timeentry.project_id != int( form.project_id.data) and today > date: timeentry.deleted = True timeentry.modified_ts = datetime.datetime.now() time = TimeEntry(date=date, user_id=timeentry.user_id, time=form.time.data, description=form.description.data, ticket_id=form.ticket_id.data, project_id=form.project_id.data if form.project_id.data else None, timer_ts=datetime.datetime.now() if form.timer.data else None) DBSession.add(time) else: ticket_id = form.ticket_id.data if timeentry.time != form.time.data or\ timeentry.project_id != form.project_id.data: timeentry.modified_ts = datetime.datetime.now() timeentry.time = form.time.data timeentry.description = form.description.data timeentry.ticket_id = ticket_id timeentry.project_id = form.project_id.data if form.project_id.data else None self.flash(self._(u'Time entry saved')) LOG(u'Time entry saved') return HTTPFound(next_) return dict( timeentry_id=timeentry.id, form=form, date=date, next=next_, )
def post(self): timeentry = self.v['timeentry'] next_ = self.request.GET.get('next') if not next_: next_ = self.request.url_for( '/times/list', date=timeentry.date.strftime('%d.%m.%Y'), ) form = TimeEntryForm(self.request.POST, obj=timeentry) date = timeentry.date today = datetime.date.today() if form.validate(): if timeentry.project_id != int(form.project_id.data) and today > date: timeentry.deleted = True timeentry.modified_ts = datetime.datetime.now() time = TimeEntry( date=date, user_id = timeentry.user_id, time = form.time.data, description = form.description.data, ticket_id = form.ticket_id.data, project_id = form.project_id.data if form.project_id.data else None, timer_ts = datetime.datetime.now() if form.timer.data else None ) DBSession.add(time) else: ticket_id = form.ticket_id.data if timeentry.time != form.time.data or\ timeentry.project_id != form.project_id.data: timeentry.modified_ts = datetime.datetime.now() timeentry.time = form.time.data timeentry.description = form.description.data timeentry.ticket_id = ticket_id timeentry.project_id = form.project_id.data if form.project_id.data else None self.flash(self._(u'Time entry saved')) LOG(u'Time entry saved') return HTTPFound(next_) return dict( timeentry_id=timeentry.id, form=form, date=date, next=next_, )
def post(self): form = LateJustificationForm(self.request.POST, user=self.request.user) if form.validate(): late = Late( user_id=self.request.user.id, date=form.popup_date.data, explanation=form.popup_explanation.data, ) DBSession.add(late) LOG(u"Late added") return Response(self._(u'Explanation added') + CHANGE_STATUS % self._('Waits for verification')) return dict(form=form)
def __call__(self, *args, **kwargs): config = ApplicationConfig.get_current_config(allow_empty=True) if config is None: WARN(u'Application config not found, emails cannot be checked') return trackers = dict( (tracker.mailer, tracker) for tracker in Tracker.query.filter( Tracker.mailer != None).filter(Tracker.mailer != '')) if not len(trackers): WARN( u'No trackers have mailers configured, email will not be checked' ) return username = config.google_user_email.encode('utf-8') password = config.google_user_password.encode('utf-8') # TODO logins_mappings = dict( (tracker.id, TrackerCredentials.get_logins_mapping(tracker)) for tracker in trackers.itervalues()) selector_mappings = dict((tracker.id, SelectorMapping(tracker)) for tracker in trackers.itervalues()) # find all projects connected to the tracker projects = dict( (project.id, project) for project in Project.query.all()) # all pre-conditions should be checked by now # start fetching fetcher = MailFetcher( username, password, ) # ok, we have all mails, lets create timeentries from them extractor = TimeEntryMailExtractor( trackers, logins_mappings, projects, selector_mappings, ) for msg in fetcher: timeentry = extractor.get(msg) if timeentry: DBSession.add(timeentry) transaction.commit()
def post(self): _id = self.request.POST.get('id') name = self.request.POST.get('name') val = self.request.POST.get('val') val = bool(int(val)) if name == 'late': late = m.Late.query.get(_id) late.justified = val DBSession.add(late) elif name == 'wrongtime': wrongtime = m.WrongTime.query.get(_id) wrongtime.justified = val DBSession.add(wrongtime) return Response('')
def post(self): form = TrackerForm(self.request.POST) if form.validate(): tracker = Tracker( type=form.type.data, name=form.name.data, url=form.url.data, mailer=form.mailer.data ) DBSession.add(tracker) self.flash(self._(u"New tracker added")) LOG(u"Tracker added") url = self.request.url_for('/tracker/list') return HTTPFound(location=url) return dict(form=form)
def on_retrieve(self, lines): """ When single message was retrieved """ msg = email.message_from_string('\n'.join(lines)) sender = decode(msg['From']) tracker = self.match_tracker(msg) if tracker is None: DEBUG(u'Email from %s ignored, no tracker matched' % (sender, )) return # find appopriate handler handler = getattr(self, 'handle_%s_email' % tracker.type) # handler should parse the response and return essential info or None data = handler(msg, tracker) if data is None: # email should be ignored return user_id, date, bug_id, project_id, hours, subject = data # try finding existing entry for this bug session = DBSession() bug_id = str(bug_id) entry = TimeEntry.query.filter(TimeEntry.user_id==user_id)\ .filter(TimeEntry.date==date.date())\ .filter(TimeEntry.ticket_id==bug_id)\ .filter(TimeEntry.project_id==project_id)\ .first() if not entry: # create new entry entry = TimeEntry( user_id=user_id, date=date.date(), time=hours, description=subject, ticket_id=bug_id, project_id = project_id, modified_ts=date ) session.add(entry) LOG(u'Adding new entry') else: # update existing entry if not entry.frozen: entry.time += hours entry.modified_ts = date # TODO: this might remove an already existing lateness session.add(entry) LOG(u'Updating existing entry') else: LOG(u'Omission of an existing entry because it is frozen') transaction.commit()
def post(self): form = LateJustificationForm(self.request.POST, user=self.request.user) if form.validate(): late = Late( user_id=self.request.user.id, date=form.popup_date.data, explanation=form.popup_explanation.data, ) DBSession.add(late) LOG(u"Late added") return Response( self._(u'Explanation added') + CHANGE_STATUS % self._('Waits for verification')) return dict(form=form)
def _note_presence(self): """ Check if request IP equals database-stored office IP. If it does, add a presence entry. If no office IP was configured, this method does nothing. Adds a presence entry to the datastore """ office_ips = models.ApplicationConfig.get_office_ip() if not office_ips: # not yet configured return current_ip = self.request.headers.get('X-Forwarded-For', '127.0.0.1') for office_ip in office_ips: if _check_ip(current_ip, office_ip): presence = models.PresenceEntry(url=self.request.url, user_id=self.request.user.id) DBSession.add(presence) LOG(u'Noticed presence of user %s (%s)' % (self.request.user.email, current_ip)) break else: LOG(u'User %s presence ignored (%s)' % (self.request.user.email, current_ip))
def dispatch(self): client_id = self.request.GET.get('client_id') client = Client.query.get(client_id) form = ProjectForm(self.request.POST) if self.request.method == 'POST' and form.validate(): tracker_id = form.tracker_id.data coordinator_id = int( form.coordinator_id.data) if form.coordinator_id.data.isdigit( ) else None project = Project( client=client, name=form.name.data, coordinator_id=coordinator_id, tracker_id=tracker_id, turn_off_selectors=form.turn_off_selectors.data, project_selector=form.project_selector.data, component_selector=form.component_selector.data, version_selector=form.version_selector.data, ticket_id_selector=form.ticket_id_selector.data, active=form.active.data, google_card=form.google_card.data, google_wiki=form.google_wiki.data, mailing_url=form.mailing_url.data, working_agreement=form.working_agreement.data, definition_of_done=form.definition_of_done.data, definition_of_ready=form.definition_of_ready.data, continuous_integration_url=form.continuous_integration_url. data, backlog_url=form.backlog_url.data, status=form.status.data, ) DBSession.add(project) DBSession.flush() self.flash(self._(u"Project added")) LOG(u"Project added") SelectorMapping.invalidate_for(tracker_id) return HTTPFound(location=self.request.url_for( '/client/view', client_id=project.client_id)) return dict(client=client, form=form)
def post(self): args = self.request.json year = int(args.pop('year')) if 1999 > year > 2099: return dict(status='nok', reason='ZÅ‚y rok %s' % year) leaves = Leave.query.filter(Leave.year == year).all() leaves = groupby(leaves, lambda l: l.user_id) for user_id, (mandated, remarks) in args.iteritems(): user_id = int(user_id) try: mandated = int(mandated) except Exception: user = User.query.get(user_id) return dict( status='nok', reason=self._( u'Wrong hours format: ${hours} for user ${name}', hours=mandated, name=user.name)) if 0 > mandated or mandated > 99: user = User.query.get(user_id) return dict( status='nok', reason=self._( u'Wrong hours number: ${hours} for user ${name}', hours=mandated, name=user.name)) leave_obj = leaves.get(user_id) if not leave_obj: leave_obj = Leave(user_id=user_id, year=year) else: leave_obj = leave_obj[0] leave_obj.number = mandated leave_obj.remarks = remarks DBSession.add(leave_obj) return dict(status='ok')
def post(self): _id = self.request.POST.get('id') name = self.request.POST.get('name') if name == 'late': late = m.Late.query.get(_id) late.deleted = True DBSession.add(late) elif name == 'wrongtime': wrongtime = m.WrongTime.query.get(_id) wrongtime.deleted = True DBSession.add(wrongtime) elif name == 'absence': absence = m.Absence.query.get(_id) absence.deleted = True DBSession.add(absence) return Response('')
class Boards(ApiView): def get(self): boards = [board.to_dict() for board in DBSession.query(m.SprintBoard)] return dict(boards=boards) def post(self): json_board = self.request.json_body board_schema = BoardSchema() try: board = board_schema.deserialize(json_board) except colander.Invalid, e: errors = e.asdict() raise HTTPBadRequest(errors) board = m.SprintBoard(**board) board.user_id = self.request.user.id DBSession.add(board) try: DBSession.flush() except IntegrityError: raise HTTPBadRequest('Board exists') return dict(id=board.id, )
def callback(request): code = request.params.get('code', '') try: credentials = flow.step2_exchange(code) except FlowExchangeError: raise HTTPForbidden data = requests.get(USER_INFO_URI % credentials.access_token, verify=False) google_profile = data.json() email = google_profile['email'] EXTRA_EMAILS = request.registry.settings.get('GOOGLE_EXTRA_EMAILS', '') EXTRA_EMAILS = EXTRA_EMAILS.split('\n') config = ApplicationConfig.get_current_config(allow_empty=True) freelancers = config.get_freelancers() clients_emails = Client.get_emails() is_employee = ( email.endswith('@%s' % request.registry.settings['COMPANY_DOMAIN']) or email in EXTRA_EMAILS ) if is_employee: group = 'employee' elif email in freelancers: group = 'freelancer' elif email in clients_emails: group = 'client' else: WARN_LOG(u"Forbidden acccess for profile:\n%s\n client's emails:\n%s\nfreelancer's emails:\n%s" % (google_profile, clients_emails, freelancers)) return HTTPForbidden() user = DBSession.query(User).filter(User.email==email).first() if user is not None: if credentials.refresh_token: DEBUG(u'Adding refresh token %s for user %s' % ( credentials.refresh_token, user.name, )) user.refresh_token = credentials.refresh_token DBSession.add(user) DEBUG(u'Signing in existing user %s' % (user.name, )) else: LOG(u'Creating new user with name %s and email %s, group: %s' % (google_profile['name'], google_profile['email'], group)) user = User( name=google_profile['name'], email=email, refresh_token=credentials.refresh_token or '', groups=[group], roles=[], ) DBSession.add(user) DBSession.flush() headers = remember(request, user.id) DEBUG(u'User %s set' % user.name) if group == 'client': location = request.url_for('/scrum/sprint/list') else: location = '/' return HTTPFound( location=location, headers=headers, )
def post(self): date = self.v['date'] form = AddTimeEntryForm(self.request.POST) if self.request.POST.get('start_timer'): form.timer.data = u'1' if not form.time.data: form.time.data = 0.0 else: form.timer.data = u'' user = self.v.get('user', self.request.user) next_ = self.request.GET.get('next') if not next_: next_ = self.request.url_for('/times/list', date=date.strftime('%d.%m.%Y')) if form.validate(): now = datetime.datetime.now() project_id = form.project_id.data project = Project.query.get(project_id) if project_id else None if isinstance(form.ticket_id.data, __builtin__.list): count = len(form.ticket_id.data) for ticket_id in form.ticket_id.data: time = TimeEntry( date=date, user_id=user.id, time=form.time.data / count, description=form.description.data, ticket_id=ticket_id, project_id=project_id if project_id else None, timer_ts=datetime.datetime.now() if form.timer.data and count == 1 else None, frozen=bool(self.request.POST.get('start_timer')) and count == 1) DBSession.add(time) else: time = TimeEntry(date=date, user_id=user.id, time=form.time.data, description=form.description.data, ticket_id=form.ticket_id.data, project_id=project_id if project_id else None, timer_ts=datetime.datetime.now() if form.timer.data else None, frozen=bool( self.request.POST.get('start_timer'))) DBSession.add(time) if form.add_to_harvest.data: self._add_to_harvest(form) self.flash(self._(u'Time entry added')) LOG(u'Time entry added') return HTTPFound(location=next_) return dict(user=user, date=date, form=form, next=next_ or self.request.url_for('/times/list', date=date.strftime('%d.%m.%Y')))
def post(self): absence = self.request.json.get('absence') form = AbsentApplicationForm(MultiDict(**absence), request=self.request) if form.validate(): response = { u'request': False, u'hours': False, u'calendar_entry': False, } memcache.clear() date_start = form.popup_date_start.data date_end = form.popup_date_end.data days = 0 if date_start and date_end: days = h.get_working_days(date_start, date_end) type = form.popup_type.data remarks = form.popup_remarks.data absence = Absence( user_id=self.request.user.id, date_start=date_start, date_end=date_end, days=days, type=type, remarks=remarks, ) DBSession.add(absence) memcache.delete(MEMCACHED_NOTIFY_KEY % date_start) if absence.type != 'inne': holidays = Holiday.all() date = date_start oneday = datetime.timedelta(days=1) description = self._(u'Auto Leave: ${type} - ${remarks}', type=dict(ABSENCE_TYPES)[type], remarks=remarks) project_id = L4_PROJECT_ID if type == u'l4' else LEAVE_PROJECT_ID while date <= date_end: if not Holiday.is_holiday(date, holidays=holidays): timeentry = TimeEntry( user_id=self.request.user.id, date=date, time=8, description=description, project_id=project_id, ) DBSession.add(timeentry) date += oneday self._send_email( absence.type, date_start.strftime('%Y-%m-%d'), date_end.strftime('%Y-%m-%d'), days, remarks, ) response[u'request'] = True response[u'hours'] = True calendar = cal.Calendar(self.request.user) event = cal.Event(date_start, date_end + cal.oneday, u'NIEOB-[%s]' % self.request.user.name, remarks) event_id = calendar.addEvent(event) response[u'calendar_entry'] = bool(event_id) return response self.request.response.status = 400 return form.errors
class Teams(ApiView): def get(self): def get_worked_hours(startDate, endDate, projects_ids): worked_hours = DBSession.query( TimeEntry.project_id, func.sum(TimeEntry.time) ) return worked_hours\ .filter(TimeEntry.project_id.in_(projects_ids))\ .filter(TimeEntry.date >= startDate)\ .filter(TimeEntry.date <= endDate)\ .group_by(TimeEntry.project_id) def get_project_worked_hours(project_id, worked_hours): worked_hours = filter(lambda x: x[0] == project_id, worked_hours) return worked_hours[0][1] if worked_hours else 0.0 tickets_end_date = datetime.now() tickets_start_date = tickets_end_date.replace(day=1) tickets_end_date = tickets_end_date.replace(day=1) tickets_end_date += relativedelta(months=1) tickets_end_date -= relativedelta(days=1) tickets_last_month_end_date = tickets_start_date - timedelta(days=1) tickets_last_month_start_date = tickets_last_month_end_date.replace( day=1) teams = DBSession.query(Team_m, TeamMember.user_id)\ .outerjoin(TeamMember) team_to_project = DBSession.query(Team_m.id, Project, Client)\ .filter(Sprint.team_id==Team_m.id)\ .filter(Sprint.project_id==Project.id)\ .filter(Project.client_id==Client.id)\ .order_by(Sprint.end.desc()) teams = h.groupby( teams, lambda x: x[0], lambda x: x[1] ) team_to_project = h.groupby( team_to_project, lambda x: x[0], lambda x: x[1:] ) projects_ids = [] for value in team_to_project.values(): for projectAndClient in value: projects_ids.append(projectAndClient[0].id) this_month_worked_hours = get_worked_hours( tickets_start_date, tickets_end_date, projects_ids) last_month_worked_hours = get_worked_hours( tickets_last_month_start_date, tickets_start_date, projects_ids) result = [] for team, members in teams.iteritems(): team = team.to_dict() team['users'] = members projects = team_to_project.get(team['id'], []) team['projects'] = [ dict( id=project.id, name=project.name, client=dict( id=client.id, name=client.name, ), this_month_worked_hours= get_project_worked_hours(project.id, this_month_worked_hours), last_month_worked_hours= get_project_worked_hours(project.id, last_month_worked_hours) ) for project, client in projects ] result.append(team) return dict( teams=result ) @has_perm('can_edit_teams') def post(self): try: json_team = self.request.json_body except ValueError: raise HTTPBadRequest('Expect json') team_schema = TeamAddSchema() try: team_des = team_schema.deserialize(json_team) except colander.Invalid, e: errors = e.asdict() raise HTTPBadRequest(errors) team = Team_m(name=team_des['name']) DBSession.add(team) try: DBSession.flush() except IntegrityError: raise HTTPBadRequest('Team exists') if team_des.get('swap_with_preview'): preview = Preview(self.request) if not preview.swap_avatar(type='teams', id=team.id): raise HTTPBadRequest('No preview to swap') return team.to_dict()
def remove(config_path): from intranet3.models import * user_login = sys.argv[-1] session = DBSession() TrackerCredentials.query.delete() Sprint.query.delete() ac = ApplicationConfig.query.first() ac.office_ip = '127.0.0' ac.google_user_email = '' ac.google_user_password = '******' ac.freelancers = '' ac.hours_employee_project = '' ac.holidays_spreadsheet = '' session.add(ac) for i, client in enumerate(Client.query): print 'client %s' % i client.name = 'Client_%s' % i client.emails = '' client.google_card = '' client.google_wiki = '' client.selector = '' client.street = '' client.city = ' ' client.postcode = '' client.nip = '' client.mailing_url = '' client.wiki_url = '' client.note = '' session.add(client) for i, project in enumerate(Project.query): print 'project %s' % i project.name = 'Project_%s' % i project.project_selector = '' project.component_selector = '' project.version_selector = '' project.ticket_id_selector = '' project.google_card = '' project.google_wiki = '' project.mailing_url = '' project.working_agreement = '' project.definition_of_done = '' project.definition_of_ready = '' project.continuous_integration_url = '' project.backlog_url = '' session.add(project) for i, user in enumerate(User.query): print 'user %s' % i user.email = '*****@*****.**' % i user.name = 'User_%s' % i user.availability_link = '' user.tasks_link = '' user.skype = '' user.irc = '' user.phone = '' user.phone_on_desk = '' user.description = '' user.refresh_token = '' user._access_token = '' session.add(user) for i, timeentry in enumerate(TimeEntry.query): if i % 1000 == 0: print 'timeentry %s' % i timeentry.description = 'description %s' % i timeentry.ticket_id = i timeentry.time = round(random.uniform(0.1, 1.2), 2) session.add(timeentry) for i, tracker in enumerate(Tracker.query): print 'tracker %s' % i tracker.name = 'Tracker_%s' % i tracker.url = 'http://tracker%s.url.com' % i tracker.mailer = 'tracker_mailer_%s' % i session.add(tracker) transaction.commit()
def post(self): date = self.v['date'] form = AddTimeEntryForm(self.request.POST) if self.request.POST.get('start_timer'): form.timer.data = u'1' if not form.time.data: form.time.data = 0.0 else: form.timer.data = u'' user = self.v.get('user', self.request.user) next_ = self.request.GET.get('next') if not next_: next_ = self.request.url_for( '/times/list', date=date.strftime('%d.%m.%Y') ) if form.validate(): now = datetime.datetime.now() project_id = form.project_id.data project = Project.query.get(project_id) if project_id else None if isinstance(form.ticket_id.data, __builtin__.list): count = len(form.ticket_id.data) for ticket_id in form.ticket_id.data: time = TimeEntry( date = date, user_id=user.id, time = form.time.data / count, description = form.description.data, ticket_id = ticket_id, project_id = project_id if project_id else None, timer_ts = datetime.datetime.now() if form.timer.data and count == 1 else None, frozen = bool(self.request.POST.get('start_timer')) and count == 1 ) DBSession.add(time) else: time = TimeEntry( date = date, user_id=user.id, time = form.time.data, description = form.description.data, ticket_id = form.ticket_id.data, project_id = project_id if project_id else None, timer_ts = datetime.datetime.now() if form.timer.data else None, frozen = bool(self.request.POST.get('start_timer')) ) DBSession.add(time) if form.add_to_harvest.data: self._add_to_harvest(form) self.flash(self._(u'Time entry added')) LOG(u'Time entry added') return HTTPFound(location=next_) return dict( user=user, date=date, form=form, next=next_ or self.request.url_for( '/times/list', date=date.strftime('%d.%m.%Y') ) )
def callback(request): code = request.params.get('code', '') try: credentials = flow.step2_exchange(code) except FlowExchangeError: raise HTTPForbidden data = requests.get(USER_INFO_URI % credentials.access_token, verify=False) google_profile = data.json() email = google_profile['email'] EXTRA_EMAILS = request.registry.settings.get('GOOGLE_EXTRA_EMAILS', '') EXTRA_EMAILS = EXTRA_EMAILS.split('\n') config = ApplicationConfig.get_current_config(allow_empty=True) freelancers = config.get_freelancers() clients_emails = Client.get_emails() is_employee = (email.endswith( '@%s' % request.registry.settings['COMPANY_DOMAIN']) or email in EXTRA_EMAILS) if is_employee: group = 'employee' elif email in freelancers: group = 'freelancer' elif email in clients_emails: group = 'client' else: WARN_LOG( u"Forbidden acccess for profile:\n%s\n client's emails:\n%s\nfreelancer's emails:\n%s" % (google_profile, clients_emails, freelancers)) return HTTPForbidden() user = DBSession.query(User).filter(User.email == email).first() if user is not None: if credentials.refresh_token: DEBUG(u'Adding refresh token %s for user %s' % ( credentials.refresh_token, user.name, )) user.refresh_token = credentials.refresh_token DBSession.add(user) DEBUG(u'Signing in existing user %s' % (user.name, )) else: LOG(u'Creating new user with name %s and email %s, group: %s' % (google_profile['name'], google_profile['email'], group)) user = User( name=google_profile['name'], email=email, refresh_token=credentials.refresh_token or '', groups=[group], roles=[], ) DBSession.add(user) DBSession.flush() headers = remember(request, user.id) DEBUG(u'User %s set' % user.name) if group == 'client': location = request.url_for('/scrum/sprint/list') else: location = '/' return HTTPFound( location=location, headers=headers, )
def post(self): absence = self.request.json.get('absence') form = AbsentApplicationForm(MultiDict(**absence), request=self.request) if form.validate(): response = { u'request': False, u'hours': False, u'calendar_entry': False, } memcache.clear() date_start = form.popup_date_start.data date_end = form.popup_date_end.data days = 0 if date_start and date_end: days = h.get_working_days(date_start, date_end) type = form.popup_type.data remarks = form.popup_remarks.data absence = Absence( user_id=self.request.user.id, date_start=date_start, date_end=date_end, days=days, type=type, remarks=remarks, ) DBSession.add(absence) memcache.delete(MEMCACHED_NOTIFY_KEY % date_start) if absence.type != 'inne': holidays = Holiday.all() date = date_start oneday = datetime.timedelta(days=1) description = self._( u'Auto Leave: ${type} - ${remarks}', type=dict(ABSENCE_TYPES)[type], remarks=remarks ) project_id = L4_PROJECT_ID if type == u'l4' else LEAVE_PROJECT_ID while date <= date_end: if not Holiday.is_holiday(date, holidays=holidays): timeentry = TimeEntry( user_id=self.request.user.id, date=date, time=8, description=description, project_id=project_id, ) DBSession.add(timeentry) date += oneday self._send_email( absence.type, date_start.strftime('%Y-%m-%d'), date_end.strftime('%Y-%m-%d'), days, remarks, ) response[u'request'] = True response[u'hours'] = True calendar = cal.Calendar(self.request.user) event = cal.Event( date_start, date_end + cal.oneday, u'NIEOB-[%s]' % self.request.user.name, remarks ) event_id = calendar.addEvent(event) response[u'calendar_entry'] = bool(event_id) return response self.request.response.status = 400 return form.errors