Beispiel #1
0
 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
     )
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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
Beispiel #6
0
 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)
Beispiel #7
0
    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)
Beispiel #8
0
    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)
Beispiel #9
0
 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,
     )
Beispiel #10
0
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')
Beispiel #11
0
    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
Beispiel #12
0
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')
Beispiel #13
0
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()
Beispiel #14
0
    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)
Beispiel #15
0
    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)
Beispiel #16
0
    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
        )
Beispiel #17
0
    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)
Beispiel #18
0
    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')
Beispiel #19
0
 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)
Beispiel #20
0
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()
Beispiel #21
0
    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)
Beispiel #22
0
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()
Beispiel #23
0
    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()
Beispiel #24
0
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()
Beispiel #25
0
    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
        )
Beispiel #26
0
 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)
Beispiel #27
0
 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)
Beispiel #28
0
    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_,
        )
Beispiel #29
0
    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_,
        )
Beispiel #30
0
    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()
Beispiel #32
0
    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('')
Beispiel #33
0
    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('')
Beispiel #34
0
 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)
Beispiel #35
0
 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)
Beispiel #36
0
    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()
Beispiel #37
0
    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)
Beispiel #38
0
 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))
Beispiel #39
0
 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)
Beispiel #40
0
    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')
Beispiel #41
0
 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))
Beispiel #42
0
 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('')
Beispiel #43
0
 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('')
Beispiel #44
0
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, )
Beispiel #45
0
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,
    )
Beispiel #46
0
    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')))
Beispiel #47
0
    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
Beispiel #48
0
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()
Beispiel #49
0
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()
Beispiel #50
0
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()
Beispiel #51
0
    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')
            )
        )
Beispiel #52
0
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,
    )
Beispiel #53
0
    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