Example #1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'launchpad_project',
        help='Your Launchpad project name.')
    parser.add_argument(
        '--debug', action='store_true',
        help='Enable debugging output.')
    parser.add_argument(
        '--purge-cache', action='store_true',
        help='Purge the local cache before running.')
    parser.add_argument(
        '--header-map', action='append',
        default=['ID:id',
                 'Link:web_link',
                 'Name:title',
                 'Backlog:date_created',
                 'Approved:',
                 'In Progress:date_assigned',
                 'Dev Done:date_fix_committed',
                 'Done:date_fix_released'],
        help='Mapping of header name to launchpad attribute, e.g., '
             '--header-map Approved:Triaged --header-map "Doing:In Progress"')
    parser.add_argument(
        '--date-format',
        default='%m/%d/%Y',
        help='Format to normalize date-time values to')
    parser.add_argument(
        '--output-file',
        help='Location to store the output of the csv conversion')

    args = parser.parse_args()

    logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO)

    if args.purge_cache:
        cache.purge()

    header_map = [i.split(':', 1) for i in args.header_map]
    headers = [i[0] for i in header_map]
    attribute_names = [i[1] for i in header_map]

    lp_project = lp.get_project(args.launchpad_project)

    with csvwriter.CSVFormatterWriter(args.output_file, headers,
                                      attribute_names) as csvconverter:
        for bug in lp.list_bugs(lp_project):
            normalize_datetime_values(bug, args.date_format)
            csvconverter.record_bug(bug)
Example #2
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("launchpad_project", help="Your Launchpad project name.")
    parser.add_argument("trello_key", help="Your Trello API key.")
    parser.add_argument("trello_secret", help="Your Trello API secret.")
    parser.add_argument("trello_board_id", help="Your Trello board ID.")
    parser.add_argument("--trello-token", metavar="trello_token", help="Your Trello API token.")
    parser.add_argument("--debug", action="store_true", help="Enable debugging output.")
    parser.add_argument("--purge-cache", action="store_true", help="Purge the local cache before running.")

    args = parser.parse_args()

    logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO)

    if args.purge_cache:
        cache.purge()

    lp_project = lp.get_project(args.launchpad_project)
    lp_milestones = lp.get_milestones(lp_project)

    trello_token = args.trello_token or trello.authorize(args.trello_key, args.trello_secret)

    trello_board_id = trello.normalize_board_id(args.trello_key, trello_token, args.trello_board_id)

    lists_by_name = trello.create_lists_as_necessary(
        args.trello_key, trello_token, trello_board_id, ["Backlog", "Approved", "Doing", "Dev Done", "Released"]
    )

    cards_by_bug_id, cards_by_blueprint_id = trello.index_cards(args.trello_key, trello_token, trello_board_id)

    def update_card_name(card, name):
        if name != card["name"]:
            LOG.info("Updating card name...")
            trello.update_card_name(args.trello_key, trello_token, card["id"], name)

    def update_card_list(card, list_id):
        if list_id != card["idList"]:
            LOG.info("Updating card list...")
            trello.update_card_list(args.trello_key, trello_token, card["id"], list_id)

    def ensure_label(card, label_id, condition=True):
        """Ensures a card is labeled appropriately if the condition is true.

        If the condition is not true, ensures the card is not
        labeled as such.
        """
        if label_id not in card["idLabels"] and condition:
            LOG.info("Adding label %s to card..." % label_id)
            trello.label_card(args.trello_key, trello_token, card["id"], label_id)

        if label_id in card["idLabels"] and not condition:
            LOG.info("Removing label %s from card..." % label_id)
            trello.unlabel_card(args.trello_key, trello_token, card["id"], label_id)

    labels = trello.list_labels(args.trello_key, trello_token, trello_board_id)
    labels_by_name = dict((x["name"], x) for x in labels)

    def ensure_label_exists(board_id, name, color):
        if name not in labels_by_name.keys():
            label = trello.create_label(args.trello_key, trello_token, trello_board_id, name, color)
            labels_by_name[name] = label

    # create static labels
    for label_name, label_color in EXPECTED_LABELS.iteritems():
        ensure_label_exists(trello_board_id, label_name, label_color)

    # create labels for each LP milestone
    milestone_names = []
    for milestone in lp_milestones:
        ensure_label_exists(trello_board_id, milestone["name"], color=None)
        milestone_names.append(milestone["name"])

    for bug in lp.list_bugs(lp_project):
        if bug["status"] in ("Triaged",):
            list_id = lists_by_name["Approved"]["id"]
        elif bug["status"] in ("In Progress",):
            list_id = lists_by_name["Doing"]["id"]
        elif bug["status"] in ("Fix Committed",):
            list_id = lists_by_name["Dev Done"]["id"]
        elif bug["status"] in ("Fix Released",):
            list_id = lists_by_name["Released"]["id"]
        elif bug.get("milestone") and bug["milestone"] != "next":
            list_id = lists_by_name["Approved"]["id"]
        else:
            # by default, we put everything else in the backlog:
            # New, Incomplete, Opinion, Invalid, Won't Fix, Confirmed
            list_id = lists_by_name["Backlog"]["id"]

        # bug IDs are integers, but they're unicode as dict keys
        bug_id = unicode(bug["id"])
        card_name = "Bug %s: %s" % (bug_id, bug["title"])
        card_description = "Bug #%s" % bug["id"]

        if bug_id not in cards_by_bug_id.keys():
            LOG.info("Creating card for Bug %s" % bug["id"])
            card = trello.create_card(
                args.trello_key,
                trello_token,
                list_id=list_id,
                name=card_name,
                description=card_description,
                url=bug["url"],
            )
            cards_by_bug_id[unicode(bug["id"])] = card

        card = cards_by_bug_id[unicode(bug["id"])]

        update_card_name(card, card_name)
        update_card_list(card, list_id)

        ensure_label(card, labels_by_name["Critical"]["id"], condition=bug["importance"] == "Critical")

        ensure_label(card, labels_by_name["High"]["id"], condition=bug["importance"] == "High")

        ensure_label(card, labels_by_name["Medium"]["id"], condition=bug["importance"] == "Medium")

        ensure_label(card, labels_by_name["Low"]["id"], condition=bug["importance"] == "Low")

        ensure_label(card, labels_by_name["Wishlist"]["id"], condition=bug["importance"] == "Wishlist")

        for milestone in milestone_names:
            condition = bug.get("milestone", {}).get("name") == milestone
            ensure_label(card, labels_by_name[milestone]["id"], condition)

    for blueprint in lp.list_specifications(lp_project):
        if blueprint["lifecycle_status"] in ("Unknown",):
            list_id = lists_by_name["Backlog"]["id"]
        elif blueprint["lifecycle_status"] in ("Not started",):
            list_id = lists_by_name["Approved"]["id"]
        elif blueprint["lifecycle_status"] in ("Started", "Slow progress", "Good progress"):
            list_id = lists_by_name["Doing"]["id"]
        elif blueprint["lifecycle_status"] in ("Blocked",):
            # "Equivalent status but with Trello label = blocked" -gist (??)
            pass
        elif blueprint["lifecycle_status"] in ("Beta available", "Needs code review", "Implemented"):
            list_id = lists_by_name["Doing"]["id"]
        else:
            # by default, we put everything else in the backlog:
            # New, Incomplete, Opinion, Invalid, Won't Fix, Confirmed
            list_id = lists_by_name["Dev Done"]["id"]

        blueprint_id = blueprint["name"]
        card_name = "BP %s: %s" % (blueprint_id, blueprint["title"])
        card_description = "BP %s" % blueprint["name"]

        if blueprint_id not in cards_by_blueprint_id.keys():
            LOG.info("Creating card for BP %s" % blueprint_id)
            card = trello.create_card(
                args.trello_key,
                trello_token,
                list_id=list_id,
                name=card_name,
                description=card_description,
                url=blueprint["web_link"],
            )
            cards_by_blueprint_id[blueprint_id] = card

        card = cards_by_blueprint_id[blueprint_id]

        update_card_name(card, card_name)
        update_card_list(card, list_id)

        ensure_label(card, labels_by_name["Not"]["id"], condition=blueprint["priority"] == "Not")

        ensure_label(card, labels_by_name["Undefined"]["id"], condition=blueprint["priority"] == "Undefined")

        ensure_label(card, labels_by_name["Low"]["id"], condition=blueprint["priority"] == "Low")

        ensure_label(card, labels_by_name["Medium"]["id"], condition=blueprint["priority"] == "Medium")

        ensure_label(card, labels_by_name["High"]["id"], condition=blueprint["priority"] == "High")

        ensure_label(card, labels_by_name["Essential"]["id"], condition=blueprint["priority"] == "Essential")

        ensure_label(card, labels_by_name["Blocked"]["id"], condition=blueprint["implementation_status"] == "Blocked")

        for milestone in milestone_names:
            condition = blueprint.get("milestone", {}).get("name") == milestone
            ensure_label(card, labels_by_name[milestone]["id"], condition)