Example #1
0
    def rows(self):
        rows = []
        for team in self.teams:
            row = []
            if len(self.teams) > 1:
                row.append({'label': team})
            for state in self.states:
                cards = [card for card in self.cards if card.state == state and card.team == team]
                if state in self.states.pre_start:
                    pri_cards = [c for c in cards if c.priority != None]
                    pri_cards = sorted(pri_cards, key=lambda c: c.priority)
                    versioned = [c for c in cards if c.priority == None and c._version != None]
                    versioned.sort(key=lambda c: c._version)
                    non_versioned = [c for c in cards if c.priority == None and c._version == None]

                    cards = pri_cards + versioned + non_versioned
                elif state in self.states.in_progress:
                    cards = sorted(cards, key=lambda c: c.current_cycle_time())
                    cards.reverse()
                else:
                    try:
                        cards = sorted(cards, key=lambda c: c.done_date)
                    except TypeError, e:
                        bad_cards = [c for c in cards if not c.done_date]
                        message = "The following cards have no done date: %s" % (bad_cards)
                        log_exception(e, message)
                        raise
                cell = {'cards': cards, 'state': state}
                row.append(cell)
            rows.append(row)
    def actually_update(self):
        super(JIRAHelper, self).update()
        self.logger.info("Fetching JIRA data for %s" % self.card.key)
        try:
            issue = self.get_issue(self.card.key)
        except Exception:
            issue = None
            log_exception("Couldn't fetch JIRA issue %s" % self.card.key)
        if issue:
            issue_dict = self.issue_to_dictionary(issue)

            # TODO: This is super specific to CMG's JIRA setup. Fixme.
            issue_dict['developers'] = self.id_devs(issue)
            issue_dict['testers'] = self.id_testers(issue)

        elif self.card._ticket_system_data:
            return None
        else:
            # We want to ensure there's at least an empty dict
            issue_dict = {}
            return None

        now = datetime.datetime.now()
        self.card._ticket_system_data = issue_dict
        self.card._ticket_system_updated_at = now
        self.update_state(self.card)
        if self.card.id:
            self.card.save()

            self.card.reload()
            self.logger.info(
                "%s updated at %s" % (self.card.key,
                    self.card._ticket_system_updated_at))
Example #3
0
def queue_service_class_reports():
    from kardboard.app import app
    from kardboard.models import ServiceClassRecord, ServiceClassSnapshot
    from kardboard.util import now, month_ranges

    logger = queue_service_class_reports.get_logger()
    report_groups = app.config.get('REPORT_GROUPS', {})
    group_slugs = report_groups.keys()
    group_slugs.append('all')

    for slug in group_slugs:
        logger.info("ServiceClassSnapshot: %s" % slug)
        ServiceClassSnapshot.calculate(slug)
        for x in [1, 3, 6, 9, 12]:
            start = now()
            months_ranges = month_ranges(start, x)
            start_date = months_ranges[0][0]
            end_date = months_ranges[-1][1]
            try:
                logger.info("ServiceClassRecord: %s %s - %s" % (slug, start_date, end_date))
                ServiceClassRecord.calculate(
                    start_date=start_date,
                    end_date=end_date,
                    group=slug,
                )
            except Exception, e:
                msg = "ERROR: Couldn't calc record: %s / %s / %s" % \
                    (slug, start_date, end_date)
                log_exception(e, msg)
Example #4
0
def queue_service_class_reports():
    from kardboard.app import app
    from kardboard.models import ServiceClassRecord, ServiceClassSnapshot
    from kardboard.util import now, month_ranges

    logger = queue_service_class_reports.get_logger()
    report_groups = app.config.get('REPORT_GROUPS', {})
    group_slugs = report_groups.keys()
    group_slugs.append('all')

    for slug in group_slugs:
        logger.info("ServiceClassSnapshot: %s" % slug)
        ServiceClassSnapshot.calculate(slug)
        for x in [1, 3, 6, 9, 12]:
            start = now()
            months_ranges = month_ranges(start, x)
            start_date = months_ranges[0][0]
            end_date = months_ranges[-1][1]
            try:
                logger.info("ServiceClassRecord: %s %s - %s" %
                            (slug, start_date, end_date))
                ServiceClassRecord.calculate(
                    start_date=start_date,
                    end_date=end_date,
                    group=slug,
                )
            except Exception, e:
                msg = "ERROR: Couldn't calc record: %s / %s / %s" % \
                    (slug, start_date, end_date)
                log_exception(e, msg)
Example #5
0
 def rows(self):
     if self._rows:
         return self._rows
     rows = []
     for team in self.teams:
         row = []
         if len(self.teams) > 1:
             row.append({"label": team})
         for state in self.states:
             cards = [card for card in self.cards if card.state == state and card.team == team]
             if state in self.states.pre_start:
                 pri_cards = [c for c in cards if c.priority is not None]
                 pri_cards = sorted(pri_cards, key=lambda c: c.priority)
                 non_pri = [c for c in cards if c not in pri_cards]
                 non_pri.sort(key=lambda c: c.created_at)
                 non_pri.reverse()
                 cards = pri_cards + non_pri
             elif state in self.states.in_progress:
                 cards = sorted(cards, key=lambda c: c.current_cycle_time())
                 cards.reverse()
             else:
                 try:
                     cards = sorted(cards, key=lambda c: c.done_date)
                 except TypeError, e:
                     bad_cards = [c for c in cards if not c.done_date]
                     message = "The following cards have no done date: %s" % (bad_cards)
                     log_exception(e, message)
                     raise
             cell = {"cards": cards, "state": state}
             row.append(cell)
         rows.append(row)
Example #6
0
 def rows(self):
     if self._rows:
         return self._rows
     rows = []
     for team in self.teams:
         row = []
         if len(self.teams) > 1:
             row.append({'label': team})
         for state in self.states:
             cards = [
                 card for card in self.cards
                 if card.state == state and card.team == team
             ]
             if state in self.states.pre_start:
                 pri_cards = [c for c in cards if c.priority is not None]
                 pri_cards = sorted(pri_cards, key=lambda c: c.priority)
                 non_pri = [c for c in cards if c not in pri_cards]
                 non_pri.sort(key=lambda c: c.created_at)
                 non_pri.reverse()
                 cards = pri_cards + non_pri
             elif state in self.states.in_progress:
                 cards = sorted(cards, key=lambda c: c.current_cycle_time())
                 cards.reverse()
             else:
                 try:
                     cards = sorted(cards, key=lambda c: c.done_date)
                 except TypeError, e:
                     bad_cards = [c for c in cards if not c.done_date]
                     message = "The following cards have no done date: %s" % (
                         bad_cards)
                     log_exception(e, message)
                     raise
             cell = {'cards': cards, 'state': state}
             row.append(cell)
         rows.append(row)
Example #7
0
def update_ticket(card_id):
    from kardboard.app import app

    logger = update_ticket.get_logger()
    try:
        # We want to update cards if their local update time
        # is less than their origin update time
        k = Kard.objects.with_id(card_id)
        i = k.ticket_system.get_issue(k.key)
        origin_updated = getattr(i, 'updated')
        local_updated = k.ticket_system_data.get('updated', None)

        should_update = False
        if not local_updated:
            # We've never sync'd before, time to do it right now
            should_update = True
        elif origin_updated:
            if local_updated < origin_updated:
                logger.info(
                    "%s UPDATED on origin: Local: %s < Origin: %s" % (k.key, local_updated, origin_updated)
                )
                should_update = True
            else:
                k._ticket_system_updated_at = datetime.datetime.now()
                k.save()
        else:
            # Ok well something changed with the ticket system
            # so we need fall back to the have we updated
            # from origin in THRESHOLD seconds, regardless
            # of how long ago the origin was updated
            # less efficient, but it guarantees updates
            threshold = app.config.get('TICKET_UPDATE_THRESHOLD', 60 * 60)
            now = datetime.datetime.now()
            diff = now - local_updated
            if diff.seconds >= threshold:
                should_update = True
                logger.info(
                    "%s FORCED UPDATE because no origin update date available")

        if should_update:
            logger.info("update_ticket running for %s" % (k.key, ))
            try:
                k.ticket_system.actually_update()
            except AttributeError:
                logger.warning('Updating kard: %s and we got an AttributeError' % k.key)
                raise

    except Kard.DoesNotExist:
        logger.error(
            "update_ticket: Kard with id %s does not exist" % (card_id, ))
    except Exception, e:
        message = "update_ticket: Couldn't update ticket %s from ticket system" % (card_id, )
        log_exception(e, message)
Example #8
0
    def actually_update(self, issue=None):
        statsd_conn = self.statsd.get_client('actually_update')
        counter = statsd_conn.get_client(class_=statsd.Counter)
        timer = statsd_conn.get_client(class_=statsd.Timer)
        timer.start()
        counter += 1

        super(JIRAHelper, self).update()

        if not issue:
            self.logger.info("Fetching JIRA data for %s" % self.card.key)
            try:
                issue = self.get_issue(self.card.key)
            except Exception:
                issue = None
                log_exception("Couldn't fetch JIRA issue %s" % self.card.key)

        if issue:
            issue_dict = self.issue_to_dictionary(issue)

            # TODO: This is super specific to CMG's JIRA setup. Fixme.
            issue_dict['developers'] = self.id_devs(issue)
            issue_dict['testers'] = self.id_testers(issue)
            issue_dict['service_class'] = self.id_service_class(issue)
            issue_dict['due_date'] = self.id_due_date(issue)

        elif self.card._ticket_system_data:
            return None
        else:
            # We want to ensure there's at least an empty dict
            issue_dict = {}
            return None

        now = datetime.datetime.now()
        self.card._ticket_system_data = issue_dict
        self.card._ticket_system_updated_at = now
        self.card.created_at = issue_dict['created']
        self.card = self.update_state(self.card)
        if self.card.id:
            self.card.save()

            self.card.reload()
            self.logger.info(
                "%s updated at %s" % (self.card.key,
                    self.card._ticket_system_updated_at))
        timer.stop()
Example #9
0
    def actually_update(self, issue=None):
        statsd_conn = self.statsd.get_client('actually_update')
        counter = statsd_conn.get_client(class_=statsd.Counter)
        timer = statsd_conn.get_client(class_=statsd.Timer)
        timer.start()
        counter += 1

        super(JIRAHelper, self).update()

        if not issue:
            self.logger.info("Fetching JIRA data for %s" % self.card.key)
            try:
                issue = self.get_issue(self.card.key)
            except Exception:
                issue = None
                log_exception("Couldn't fetch JIRA issue %s" % self.card.key)

        if issue:
            issue_dict = self.issue_to_dictionary(issue)

            # TODO: This is super specific to CMG's JIRA setup. Fixme.
            issue_dict['developers'] = self.id_devs(issue)
            issue_dict['testers'] = self.id_testers(issue)
            issue_dict['service_class'] = self.id_service_class(issue)
            issue_dict['due_date'] = self.id_due_date(issue)

        elif self.card._ticket_system_data:
            return None
        else:
            # We want to ensure there's at least an empty dict
            issue_dict = {}
            return None

        now = datetime.datetime.now()
        self.card._ticket_system_data = issue_dict
        self.card._ticket_system_updated_at = now
        self.card.created_at = issue_dict['created']
        self.card = self.update_state(self.card)
        if self.card.id:
            self.card.save()

            self.card.reload()
            self.logger.info(
                "%s updated at %s" %
                (self.card.key, self.card._ticket_system_updated_at))
        timer.stop()
Example #10
0
def card_add():
    f = _init_new_card_form(request.values)
    card = Kard()
    f.populate_obj(card)

    if request.method == "POST":
        if f.key.data and not f.title.data:
            try:
                f.title.data = card.ticket_system.get_title(key=f.key.data)
            except Exception, e:
                log_exception(e, "Error getting card title via helper")
                pass

        if f.validate():
            # Repopulate now that some data may have come from the ticket
            # helper above
            f.populate_obj(card)
            card.save()
            flash("Card %s successfully added" % card.key)
            return redirect(url_for("card", key=card.key))
Example #11
0
def card_add():
    f = _init_new_card_form(request.values)
    card = Kard()
    f.populate_obj(card)

    if request.method == "POST":
        if f.key.data and not f.title.data:
            try:
                f.title.data = card.ticket_system.get_title(key=f.key.data)
            except Exception, e:
                log_exception(e, "Error getting card title via helper")
                pass

        if f.validate():
            # Repopulate now that some data may have come from the ticket
            # helper above
            f.populate_obj(card)
            card.save()
            flash("Card %s successfully added" % card.key)
            return redirect(url_for("card", key=card.key))
Example #12
0
def update_ticket(card_id):
    from kardboard.app import app

    statsd_conn = app.statsd.get_client('tasks.update_ticket')
    consider_counter = statsd_conn.get_client('consider',
                                              class_=statsd.Counter)
    update_counter = statsd_conn.get_client('update', class_=statsd.Counter)
    error_counter = statsd_conn.get_client('error', class_=statsd.Counter)

    timer = statsd_conn.get_client(class_=statsd.Timer)
    timer.start()

    consider_counter += 1

    logger = update_ticket.get_logger()
    try:
        # We want to update cards if their local update time
        # is less than their origin update time
        k = Kard.objects.with_id(card_id)
        i = k.ticket_system.get_issue(k.key)
        origin_updated = getattr(i, 'updated')
        local_updated = k.ticket_system_data.get('updated', None)

        should_update = False
        if not local_updated:
            # We've never sync'd before, time to do it right now
            should_update = True
        elif origin_updated:
            if local_updated < origin_updated:
                logger.info("%s UPDATED on origin: Local: %s < Origin: %s" %
                            (k.key, local_updated, origin_updated))
                should_update = True
            else:
                k._ticket_system_updated_at = datetime.datetime.now()
                k.save()
        else:
            # Ok well something changed with the ticket system
            # so we need fall back to the have we updated
            # from origin in THRESHOLD seconds, regardless
            # of how long ago the origin was updated
            # less efficient, but it guarantees updates
            threshold = app.config.get('TICKET_UPDATE_THRESHOLD', 60 * 60)
            now = datetime.datetime.now()
            diff = now - local_updated
            if diff.seconds >= threshold:
                should_update = True
                logger.info(
                    "%s FORCED UPDATE because no origin update date available")

        if should_update:
            logger.info("update_ticket running for %s" % (k.key, ))
            try:
                update_counter += 1
                k.ticket_system.actually_update()
            except AttributeError:
                error_counter += 1
                logger.warning(
                    'Updating kard: %s and we got an AttributeError' % k.key)
                raise

    except Kard.DoesNotExist:
        error_counter += 1
        logger.error("update_ticket: Kard with id %s does not exist" %
                     (card_id, ))
    except Exception, e:
        error_counter += 1
        message = "update_ticket: Couldn't update ticket %s from ticket system" % (
            card_id, )
        log_exception(e, message)