Source code for lookatme.utils

"""
"""


import urwid


[docs]def prefix_text(text: str, prefix: str, split: str = "\n") -> str: return split.join(prefix + part for part in text.split(split))
[docs]def row_text(rendered_row): """Return all text joined together from the rendered row """ return b"".join(x[-1] for x in rendered_row)
[docs]def resolve_bag_of_text_markup_or_widgets(items): """Resolve the list of items into either contiguous urwid.Text() instances, or pre-existing urwid.Widget objects """ res = [] curr_text_markup = [] for item in items: if isinstance(item, tuple) or isinstance(item, str): curr_text_markup.append(item) else: if len(curr_text_markup) > 0: res.append(urwid.Text(curr_text_markup)) curr_text_markup = [] res.append(item) if len(curr_text_markup) > 0: res.append(urwid.Text(curr_text_markup)) return res
[docs]def dict_deep_update(to_update, new_vals): """Deeply update the to_update dict with the new_vals """ for key, value in new_vals.items(): if isinstance(value, dict): node = to_update.setdefault(key, {}) dict_deep_update(node, value) else: to_update[key] = value
[docs]def spec_from_style(styles): """Create an urwid.AttrSpec from a {fg:"", bg:""} style dict. If styles is a string, it will be used as the foreground """ if isinstance(styles, str): return urwid.AttrSpec(styles, "") else: return urwid.AttrSpec(styles.get("fg", ""), styles.get("bg", ""))
[docs]def get_fg_bg_styles(style): if style is None: return [], [] def non_empty_split(data): res = [x.strip() for x in data.split(",")] return list(filter(None, res)) # from lookatme.config.get_style() if isinstance(style, dict): return non_empty_split(style["fg"]), non_empty_split(style["bg"]) # just a str will only set the foreground color elif isinstance(style, str): return non_empty_split(style), [] elif isinstance(style, urwid.AttrSpec): return non_empty_split(style.foreground), non_empty_split(style.background) else: raise ValueError("Unsupported style value {!r}".format(style))
[docs]def overwrite_spec(orig_spec, new_spec): if orig_spec is None: orig_spec = urwid.AttrSpec("", "") if new_spec is None: new_spec = urwid.AttrSpec("", "") fg_orig = orig_spec.foreground.split(",") fg_orig_color = orig_spec._foreground_color() fg_orig.remove(fg_orig_color) bg_orig = orig_spec.background.split(",") bg_orig_color = orig_spec._background() bg_orig.remove(bg_orig_color) fg_new = new_spec.foreground.split(",") fg_new_color = new_spec._foreground_color() fg_new.remove(fg_new_color) bg_new = new_spec.background.split(",") bg_new_color = new_spec._background() bg_new.remove(bg_new_color) if fg_new_color == "default": fg_orig.append(fg_orig_color) else: fg_new.append(fg_new_color) if bg_new_color == "default": bg_orig.append(bg_orig_color) else: bg_new.append(bg_new_color) return urwid.AttrSpec( ",".join(set(fg_orig + fg_new)), ",".join(set(bg_orig + bg_new)), )
[docs]def flatten_text(text, new_spec=None): """Return a flattend list of tuples that can be used as the first argument to a new urwid.Text(). :param urwid.Text text: The text to flatten :param urwid.AttrSpec new_spec: A new spec to merge with existing styles :returns: list of tuples """ text, chunk_stylings = text.get_text() res = [] total_len = 0 for spec, chunk_len in chunk_stylings: split_text = text[total_len:total_len + chunk_len] total_len += chunk_len split_text_spec = overwrite_spec(new_spec, spec) res.append((split_text_spec, split_text)) if len(text[total_len:]) > 0: res.append((new_spec, text[total_len:])) return res
[docs]def can_style_item(item): """Return true/false if ``style_text`` can work with the given item """ return isinstance(item, (urwid.Text, list, tuple))
[docs]def styled_text(text, new_styles, old_styles=None, supplement_style=False): """Return a styled text tuple that can be used within urwid.Text. .. note:: If an urwid.Text instance is passed in as the ``text`` parameter, alignment values will be lost and must be explicitly re-added by the caller. """ if isinstance(text, urwid.Text): new_spec = spec_from_style(new_styles) return flatten_text(text, new_spec) elif (isinstance(text, tuple) and isinstance(text[0], urwid.AttrSpec) and isinstance(text[1], urwid.Text)): text = text[1].text old_styles = text[0] new_fg, new_bg = get_fg_bg_styles(new_styles) old_fg, old_bg = get_fg_bg_styles(old_styles) def join(items): return ",".join(set(items)) spec = urwid.AttrSpec( join(new_fg + old_fg), join(new_bg + old_bg), ) return (spec, text)
[docs]def pile_or_listbox_add(container, widgets): """Add the widget/widgets to the container """ if isinstance(container, urwid.ListBox): return listbox_add(container, widgets) elif isinstance(container, urwid.Pile): return pile_add(container, widgets) else: raise ValueError("Container was not listbox, nor pile")
[docs]def listbox_add(listbox, widgets): if not isinstance(widgets, list): widgets = [widgets] for w in widgets: if len(listbox.body) > 0 \ and isinstance(w, urwid.Divider) \ and isinstance(listbox.body[-1], urwid.Divider): continue listbox.body.append(w)
[docs]def pile_add(pile, widgets): """ """ if not isinstance(widgets, list): widgets = [widgets] for w in widgets: if len(pile.contents) > 0 \ and isinstance(w, urwid.Divider) \ and isinstance(pile.contents[-1][0], urwid.Divider): continue pile.contents.append((w, pile.options()))
[docs]def int_to_roman(integer): integer = int(integer) ints = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] nums = ["m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i"] result = [] for i in range(len(ints)): count = integer // ints[i] result.append(nums[i] * count) integer -= ints[i] * count return "".join(result)