Esempio n. 1
0
def edit_and_validate_board_settings(board_settings_file):
    subprocess.run([get_settings()[EDITOR], board_settings_file])
    try:
        get_board_settings()
    except Exception as e:
        print(e)
        return False
    return check_defaults() and test_sorting()
Esempio n. 2
0
def render_kanban(issues):
    # generator can only be traversed once
    issues = list(issues)
    issues.sort(key=lambda issue: -get_sort_value(issue))
    box_rows = get_settings()[BOX_ROWS]
    box_width = get_settings()[BOX_WIDTH]
    statuses = get_board_settings()[STATUS_COLUMNS]
    rows = defaultdict(list)
    status_counter = Counter()
    for issue in issues:
        if STATUS in issue.keys() and issue[STATUS] in statuses:
            rows[issue[STATUS]].append(render_issue(issue, box_width,
                                                    box_rows))
            status_counter[issue[STATUS]] += 1
    hline = (1 + len(statuses) * (3 + box_width)) * '-'
    lines = [hline]
    status_line = '| ' + ' | '.join(
        [render_text(status, box_width) for status in statuses]) + ' |'
    lines.append(status_line)
    lines.append(hline)
    if len(status_counter) == 0:
        return lines
    board_height = max(status_counter.values())
    for height in range(min(board_height, get_settings()[MAX_BOARD_ROWS])):
        for sub_row in range(box_rows):
            line = '| ' + ' | '.join([
                fill_missing(rows[status], height, box_width, sub_row)
                for status in statuses
            ]) + ' |'
            lines.append(line)
        lines.append(hline)
    if board_height > get_settings()[MAX_BOARD_ROWS]:
        lines.append(' ...')
        lines.append(' ...')
    return lines
Esempio n. 3
0
def _input_user_issue(path):
    subprocess.run([get_settings()[EDITOR], path])
    with open(path, 'r') as fin:
        edited_contents = fin.read()
    if not edited_contents.isspace():
        try:
            user_json = json.loads(edited_contents)
        except Exception as e:
            print("Not valid json, please try again.")
            input("Press ENTER to continue.")
            return _input_user_issue(path)
        if TITLE not in user_json or not isinstance(
                user_json[TITLE], str) or user_json[TITLE] == '':
            print("Must use non-empty string value for attribute title.")
            input("Press ENTER to continue.")
            return _input_user_issue(path)
        if STATUS not in user_json or user_json[
                STATUS] not in get_board_settings()[STATUS_COLUMNS]:
            print(
                f"Must have status with a value in {get_board_settings()[STATUS_COLUMNS]}."
            )
            input("Press ENTER to continue.")
            return _input_user_issue(path)
        return user_json
    else:
        return None
Esempio n. 4
0
def transition_cmd(args):
    if args.new_status not in get_board_settings()[STATUS_COLUMNS]:
        print(
            f"Must use status with a value in {get_board_settings()[STATUS_COLUMNS]}."
        )
        return
    for issue in matching_issues(args):
        issue[STATUS] = args.new_status
        save_issue(issue)
Esempio n. 5
0
def check_defaults():
    board_settings = get_board_settings()
    FIELD = r'[a-zA-Z_][a-zA-Z0-9_]*'
    used_fields = set(re.findall(FIELD, board_settings[BACKLOG_SORTING]))
    fields_with_defaults = set(board_settings[CUSTOM_FIELDS])
    missing_defaults = used_fields - fields_with_defaults - {CREATED}
    if len(missing_defaults) > 0:
        print(
            f"Fields {list(missing_defaults)} in {BACKLOG_SORTING} do not have defaults in {CUSTOM_FIELDS}."
        )
        return False
    return True
Esempio n. 6
0
 def __init__(self, issue):
     self.names = {}
     self.issue = issue
     settings = get_board_settings()
     self.custom_fields = settings[CUSTOM_FIELDS]
     self.sorting_expr = settings[BACKLOG_SORTING]