pivotalcli/commands/_stories_info.py

152 lines
4.5 KiB
Python
Raw Normal View History

2018-04-03 10:56:07 +00:00
import re
import sys
from datetime import datetime
from typing import Any, Dict
2019-09-04 14:42:23 +00:00
from consolemd import Renderer
2018-04-03 10:56:07 +00:00
2018-07-22 09:45:15 +00:00
import base32_crockford as base32
2018-04-03 10:56:07 +00:00
import api.stories
from config import Config
from util import print_wrap
2019-09-04 14:42:23 +00:00
from . import COLOR_HEADER, COLOR_TITLE, COLOR_WHITE, _format_state, _get_persons
2018-04-03 10:56:07 +00:00
2018-07-22 09:45:15 +00:00
def __print_story(story: Dict[str, Any]) -> None:
2018-04-03 10:56:07 +00:00
"""
Prints the title, the current state and the estimate of the story, if
available.
TODO: Split up in functions.
"""
2019-09-04 14:42:23 +00:00
COLOR_TITLE.print(story["name"])
print(story["url"], end="\n\n")
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
if "current_state" in story:
state = _format_state(story["current_state"])
COLOR_HEADER.print("State:", state, end="")
2018-07-22 09:45:15 +00:00
2019-09-04 14:42:23 +00:00
if story["current_state"] == "accepted":
print(f" (at {story['accepted_at']})", end="")
2018-07-22 09:45:15 +00:00
2019-09-04 14:42:23 +00:00
print(end="\n\n")
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
if "estimate" in story:
COLOR_HEADER.print("Estimate: ", end="")
print(story["estimate"], "points", end="")
if len(story.get("owner_ids", [])) > 1:
points = story["estimate"] / len(story["owner_ids"])
print(f" ({points} each)", end="")
print(end="\n\n")
2018-04-03 10:56:07 +00:00
def __print_owners(story: Dict[str, Any], persons: Dict[int, Any]) -> None:
"""Prints the owners of the story, if available."""
2019-09-04 14:42:23 +00:00
if story.get("owner_ids"):
COLOR_HEADER.print("Owners:")
2018-04-03 10:56:07 +00:00
owners = []
2019-09-04 14:42:23 +00:00
for owner_id in story["owner_ids"]:
name = persons[owner_id]["name"]
initials = persons[owner_id]["initials"]
owners.append(f" - {name} ({initials})")
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
print("\n".join(owners), end="\n\n")
2018-04-03 10:56:07 +00:00
def __print_description(story: Dict[str, Any]) -> None:
"""Prints the description of the story, if available."""
2019-09-04 14:42:23 +00:00
COLOR_HEADER.print("Description:")
if "description" in story:
description = story["description"].strip()
Renderer().render(description, width=80)
print()
2018-04-03 10:56:07 +00:00
else:
2019-09-04 14:42:23 +00:00
print(" (No description)", end="\n\n")
2018-04-03 10:56:07 +00:00
def __print_labels(story: Dict[str, Any]) -> None:
"""Prints the labels of the story, if available."""
2019-09-04 14:42:23 +00:00
if not story.get("labels"):
2018-04-03 10:56:07 +00:00
return
2019-09-04 14:42:23 +00:00
COLOR_HEADER.print("Labels:")
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
template = "\033[97;48;5;22m {} \033[0m"
labels = " ".join(template.format(label["name"]) for label in story["labels"])
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
print(f" {labels}", end="\n\n")
2018-04-03 10:56:07 +00:00
def __print_tasks(project_id: int, story_id: int) -> None:
2018-04-03 10:56:07 +00:00
"""Prints the tasks of the story, if available."""
tasks = api.stories.get_tasks(project_id, story_id)
2018-04-03 10:56:07 +00:00
if tasks:
2019-09-04 14:42:23 +00:00
COLOR_HEADER.print("Tasks:")
2018-04-03 10:56:07 +00:00
for task in tasks:
2019-09-04 14:42:23 +00:00
print(end=" ")
print("[X]" if task["complete"] else "[ ]", end=" \033[34m")
print(base32.encode(task["id"]), end=":\033[0m ")
print(task["description"])
2018-04-03 10:56:07 +00:00
print()
2019-09-04 14:42:23 +00:00
def __print_comments(
project_id: int, story_id: int, persons: Dict[int, Dict[str, Any]]
) -> None:
2018-04-03 10:56:07 +00:00
"""Prints the comments on the story, if available."""
comments = api.stories.get_comments(project_id, story_id)
2018-04-03 10:56:07 +00:00
if comments:
2019-09-04 14:42:23 +00:00
COLOR_HEADER.print("Comments:")
2018-04-03 10:56:07 +00:00
for comment in comments:
2019-09-04 14:42:23 +00:00
text = comment.get("text", "[Empty comment]").strip()
print_wrap(text, indent=" ")
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
person_id = comment["person_id"]
name = persons[person_id]["name"]
COLOR_WHITE.print(" -", name, end=" ")
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
date = datetime.strptime(comment["created_at"], "%Y-%m-%dT%H:%M:%SZ")
date_str = date.strftime("on %a %Y-%m-%d at %H:%M")
print(date_str, end="\n\n")
2018-04-03 10:56:07 +00:00
def __print_blockers(project_id: int, story_id: int) -> None:
2018-04-03 10:56:07 +00:00
"""Prints the stories that block this story, if available."""
blockers = api.stories.get_blockers(project_id, story_id)
2018-04-03 10:56:07 +00:00
if blockers:
2019-09-04 14:42:23 +00:00
COLOR_HEADER.print("Blockers:")
2018-04-03 10:56:07 +00:00
def blocker_repl(matchgroup: Any) -> str:
id = int(matchgroup.group(1))
2018-07-22 09:45:15 +00:00
code = base32.encode(id)
2018-04-03 10:56:07 +00:00
return COLOR_HEADER.format(code)
2019-09-04 14:42:23 +00:00
pattern = re.compile(r"#(\d+)")
2018-04-03 10:56:07 +00:00
for blocker in blockers:
2019-09-04 14:42:23 +00:00
resolved = "X" if blocker["resolved"] else " "
desc = pattern.sub(blocker_repl, blocker["description"])
print(f" [{resolved}] {desc}")
2018-04-03 10:56:07 +00:00
2019-02-05 13:29:33 +00:00
def stories_info(story_b32: str) -> None:
story_id = base32.decode(story_b32)
story = api.stories.get(story_id)
2018-04-03 10:56:07 +00:00
2019-09-04 14:42:23 +00:00
project_id = story["project_id"]
persons = _get_persons(project_id)
2018-04-03 10:56:07 +00:00
2018-07-22 09:45:15 +00:00
__print_story(story)
2018-04-03 10:56:07 +00:00
__print_owners(story, persons)
__print_description(story)
__print_labels(story)
__print_tasks(project_id, story_id)
__print_comments(project_id, story_id, persons)
__print_blockers(project_id, story_id)