Skip to content

Commit

Permalink
💄 Revamp Cards UI
Browse files Browse the repository at this point in the history
Closes #59
Closes #25
Closes #53
Closes #34
  • Loading branch information
gwennlbh committed Jun 22, 2020
1 parent 6db5312 commit 57ba9cb
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 31 deletions.
57 changes: 36 additions & 21 deletions ideaseed/dumb_utf8_art.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from ideaseed.constants import COLOR_NAME_TO_HEX_MAP, C_PRIMARY
from typing import *

from github.Repository import Repository
from ideaseed.utils import dye, english_join
from github.Label import Label
from ideaseed.utils import dye, english_join, readable_text_color_on
from wcwidth import wcswidth
import textwrap
import cli_box
Expand Down Expand Up @@ -74,13 +74,15 @@
→ Project card available at {url}
"""


def strwidth(o: str) -> int:
"""
Smartly calculates the actual width taken on a terminal of `o`.
Handles ANSI codes (using `strip-ansi`) and Unicode (using `wcwidth`)
"""
return wcswidth(strip_ansi(o))


def make_card_header(left: str, right: str) -> str:
"""
Returns
Expand All @@ -102,11 +104,10 @@ def make_card_header(left: str, right: str) -> str:
return left + spaces + right


ISSUE_CARD_ART = f"""\
{{card_header}}
{{content}}
{CARD_LINE_SEPARATOR}
{{labels}}
ISSUE_CARD_ART = """\
{card_header}
{content}{labels}
"""

TAGS_ART = "[{tag}]"
Expand All @@ -119,11 +120,10 @@ def make_card_header(left: str, right: str) -> str:
→ Available at {url}
"""

GOOGLE_KEEP_CARD_ART = f"""\
{{card_header}}
{{content}}
{CARD_LINE_SEPARATOR}
{{tags}}
GOOGLE_KEEP_CARD_ART = """\
{card_header}
{content}{tags}
"""

GOOGLE_KEEP_PINNED = "⚲ Pinned"
Expand All @@ -137,23 +137,22 @@ def make_google_keep_art(
body: str,
color: str,
) -> str:
hex_color = COLOR_NAME_TO_HEX_MAP.get(color)
card_header = make_card_header(
left=dye(title or "", style="bold"), right=GOOGLE_KEEP_PINNED if pinned else ""
)
card = cli_box.rounded(
GOOGLE_KEEP_CARD_ART.format(
card_header=card_header,
content=body,
tags=" ".join([TAGS_ART.format(tag=t) for t in tags])
tags="\n\n" + " ".join([format_label(t, hex_color or 0xDDD) for t in tags])
if tags
else "No tags.",
else "",
),
align="left",
)

card = "\n".join(
[dye(line, fg=COLOR_NAME_TO_HEX_MAP.get(color)) for line in card.split("\n")]
)
card = "\n".join([dye(line, fg=hex_color) for line in card.split("\n")])
return GOOGLE_KEEP_ART.format(card=card, url=url)


Expand Down Expand Up @@ -182,7 +181,7 @@ def make_github_user_project_art(
card_header = make_card_header(left=f"@{username}", right=f"{column} in {project}")
card = cli_box.rounded(
GITHUB_CARD_ART.format(
content=wrap_card_content(body), card_header=card_header
content=wrap_card_content(body), card_header=dye(card_header, style="dim")
),
align="left",
)
Expand All @@ -196,8 +195,8 @@ def make_github_issue_art(
column: str,
username: str,
url: str,
issue_number: int,
labels: List[str],
issue_number: Union[str, int],
labels: List[Label],
body: str,
title: Optional[str],
assignees: List[str],
Expand Down Expand Up @@ -229,7 +228,10 @@ def make_github_issue_art(
ISSUE_CARD_ART.format(
card_header=card_header,
content=wrap_card_content(body),
labels=" ".join([TAGS_ART.format(tag=t) for t in labels]),
labels="\n\n"
+ " ".join([format_label(l.name, int(l.color, 16)) for l in labels])
if labels
else "",
),
align="left",
)
Expand All @@ -246,3 +248,16 @@ def make_github_issue_art(
timeline_item_assignees=timeline_item_assignees,
)


def format_label(
name: str, color: int = 0xDDDDDD, text_color: Optional[int] = None
) -> str:
"""
Renders a label using a color
``text_color`` defaults to ``readable_text_color_on(color)``
WARN: ``color`` and ``text_color`` must be a 6-digit-long hex int representing the color.
"""
text_color = readable_text_color_on(color) if text_color is None else text_color
return dye(f" {name} ", bg=color, fg=text_color)
20 changes: 13 additions & 7 deletions ideaseed/github.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from github.Label import Label
from ideaseed.dumb_utf8_art import (
make_github_issue_art,
make_github_project_art,
Expand All @@ -6,15 +7,11 @@
import os
import re
import webbrowser
import pprint
from os.path import dirname
import github
from github import Issue
from github.GithubException import BadCredentialsException, TwoFactorException
from ideaseed.utils import (
ask,
dye,
get_random_color_hexstring,
get_token_cache_filepath,
print_dry_run,
)
Expand Down Expand Up @@ -163,10 +160,11 @@ def push_to_repo(args: Dict[str, Any]) -> None:
)

# Get all labels
labels = repo.get_labels()
all_labels = repo.get_labels()
labels: List[Label] = []
for label_name in args["--tag"]:
if (
label_name.lower() not in [t.name.lower() for t in labels]
label_name.lower() not in [t.name.lower() for t in all_labels]
and args["--create-missing"]
):
if ask(
Expand Down Expand Up @@ -198,7 +196,14 @@ def push_to_repo(args: Dict[str, Any]) -> None:
+ dye(label_name, fg=color, style="reverse")
+ " ..."
)
repo.create_label(name=label_name, color=f"{color:6x}", **label_data)
labels += [
repo.create_label(
name=label_name, color=f"{color:6x}", **label_data
)
]

else:
labels += [repo.get_label(label_name)]

project = None
for p in repo.get_projects():
Expand Down Expand Up @@ -306,6 +311,7 @@ def push_to_repo(args: Dict[str, Any]) -> None:
username=username,
url=url,
issue_number=(issue.number if issue is not None else "N/A"),
labels=labels,
body=args["IDEA"],
title=args["--title"],
assignees=assignees,
Expand Down
48 changes: 45 additions & 3 deletions ideaseed/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,39 @@ def dye(
)


def readable_text_color_on(
background: int, light: int = 0xFFFFFF, dark: int = 0x000000
) -> int:
"""
Choses either ``light`` or ``dark`` based on the background color
the text is supposed to be written on ``background`` (also given as an hex int)
WARN: All the color ints must be exactly 6 digits long.
>>> readable_text_color_on(0xFEFAFE)
0
>>> readable_text_color_on(0x333333)
16777215
"""
r, g, b = hex_to_rgb(f"{background:6x}")
luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
if luminance > 0.5:
return dark
else:
return light


def hex_to_rgb(hexstring: str) -> Tuple[int, int, int]:
"""
Converts a hexstring (without initial '#') ``hexstring`` into a
3-tuple of ints in [0, 255] representing an RGB color
>>> hex_to_rgb('FF00AA')
(255, 0, 170)
"""
return tuple(int(hexstring[i : i + 2], 16) for i in (0, 2, 4)) # skip '#'


def get_random_color_hexstring() -> str:
return f"{randint(0x0, 0xFFFFFF):6x}".upper()

Expand Down Expand Up @@ -50,6 +83,16 @@ def get_token_cache_filepath(service: str) -> str:


def english_join(items: List[str]) -> str:
"""
Joins items in a sentence-compatible way, adding "and" at the end
>>> english_join(["a", "b", "c"])
'a, b and c'
>>> english_join(["a"])
'a'
>>> english_join(["a", "b"])
'a and b'
"""
if len(items) == 1:
return items[0]
return ", ".join(items[: len(items) - 1]) + " and " + items[len(items) - 1]
Expand All @@ -63,6 +106,5 @@ def print_dry_run(text: str):
print(DRY_RUN_FMT.format(text))

if __name__ == "__main__":
assert english_join(["a", "b", "c"]) == "a, b and c"
assert english_join(["a"]) == "a"
assert english_join(["a", "b"]) == "a and b"
import doctest
doctest.testmod()

0 comments on commit 57ba9cb

Please sign in to comment.