Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Another refactor #9

Merged
merged 9 commits into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 164 additions & 38 deletions src/charts.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,191 @@
""" Text Chart Printing Functions """

from math import ceil
from tools import Color, Attr
from colored import fg, attr, stylize

class Options:
"""Options"""

class ChartPrint():
"""Draws chart with user selected color and symbol"""
_graph_color = fg("white")
_header_color = fg("red")
_pre_graph_color = fg("white")
_post_graph_color = fg("white")
_footer_color = fg("white")
_fsymbol = "█"
_msymbol = "▒"
_esymbol = "░"

def __init__(self,
graph: Color = None,
symbol: str = None) -> None:
if graph:
self.graph = fg(graph.value)
else:
self.graph = graph
def __init__(self):
return

@property
def graph_color(self):
""" Graph Color """
return self._graph_color

@graph_color.setter
def graph_color(self, color):
self._graph_color = fg(color)

@property
def header_color(self):
""" Header Color """
return self._header_color

@header_color.setter
def header_color(self, color):
self._header_color = fg(color)

@property
def pre_graph_color(self):
""" pre_graph_color """
return self._pre_graph_color

@pre_graph_color.setter
def pre_graph_color(self, color):
self._pre_graph_color = fg(color)

@property
def post_graph_color(self):
""" post_graph_color """
return self._post_graph_color

@post_graph_color.setter
def post_graph_color(self, color):
self._post_graph_color = fg(color)

@property
def footer_color(self):
""" footer_color """
return self._footer_color

@footer_color.setter
def footer_color(self, color):
self._footer_color = fg(color)

@property
def symbol(self):
""" graph symbols to use """
return [self._fsymbol, self._msymbol, self.esymbol]

@symbol.setter
def symbol(self, symbol):
if symbol:
self.fsymbol = symbol
self.msymbol = '>'
self.esymbol = '-'
self._fsymbol = symbol
self._msymbol = ">"
self._esymbol = "-"
else:
self.fsymbol = '█'
self.msymbol = '▒'
self.esymbol = '░'
self._check_graph_color()

def _check_graph_color(self):
if self.graph:
self.fsymbol = stylize(self.fsymbol, self.graph)
self.msymbol = stylize(self.msymbol, self.graph)
self.esymbol = stylize(self.esymbol, self.graph)

def draw_horizontal_bar(self, capacity: int, used: int) -> str:
self._fsymbol = "█"
self._msymbol = "▒"
self._esymbol = "░"

@property
def fsymbol(self):
""" The final symbol """
return self._fsymbol

@property
def esymbol(self):
""" The empty symbol """
return self._esymbol

@property
def msymbol(self):
""" The used symbol """
return self._msymbol


class Chart:
"""Abstract base object for charts"""
options: Options = None

def __init__(self, options: Options = None):
if options is None:
self.options = Options()
else:
self.options = options


class BarChart(Chart):
"""Draws chart with user selected color and symbol"""

def chart(
self,
title: str,
pre_graph_text: str,
post_graph_text: str,
footer: str,
maximum: float,
current: float,
):
print(stylize(title, self.options.header_color))

if pre_graph_text:
print(stylize(pre_graph_text, self.options.pre_graph_color))

print(
"[%s]"
% stylize(
self.draw_horizontal_bar(maximum, current), self.options.graph_color
),
end=" ",
)
if post_graph_text:
print(stylize(post_graph_text, self.options.post_graph_color))
else:
print()

if footer:
print(stylize(footer, self.options.footer_color))

def draw_horizontal_bar(self, maximum: int, current: int) -> str:
"""Draw a horizontal bar chart

Return:
drawn horizontal bar chart
"""
bar = ''
usage = int((used / capacity) * 36)
textBar = ""
usage = int((current / maximum) * 36)
for i in range(1, usage + 1):
bar += self.fsymbol
bar += self.msymbol
textBar += self.options.fsymbol
textBar += self.options.msymbol
for i in range(1, 37 - usage):
bar += self.esymbol
textBar += self.options.esymbol
# check if the user set up graph color
if '█' not in self.fsymbol:
return f'[{bar}]'
return bar
if "█" not in self.options.fsymbol:
return f"[{textBar}]"
return textBar


class verticalBarChar(Chart):
def draw_vertical_bar(self, capacity: int, used: int) -> str:
"""Draw a vertical bar chart

Returns:
drawn vertical bar chart
"""
bar = '\n'
textBar = "\n"
n = (used / capacity) * 8
# If the usage is below 1% print empty chart
if n < 0.1:
n = 0
else:
n = ceil(n)
bar += f'{self.esymbol * 9} \n' * (8 - n)
bar += f'{self.fsymbol * 9} \n' * n
return bar
textBar += f"{self.esymbol * 9} \n" * (8 - n)
textBar += f"{self.fsymbol * 9} \n" * n
return textBar


if __name__ == "__main__":
ch = BarChart()
ch.options.post_graph_color = "green"
ch.options.pre_graph_color = "blue"
ch.options.footer_color = "yellow"
ch.chart(
title="Test Content",
maximum=100,
current=32,
pre_graph_text="Lorem: Sit ea dolore ad accusantium",
post_graph_text="Good job!",
footer="This concludes our test",
)
131 changes: 26 additions & 105 deletions src/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import click

from disks import DiskUsage
from tools import Color, Attr, Chart
from charts import Options
from colored import fg, attr, stylize


# Command line arguments for vizex
# Command line arguments for cli
@click.command()
@click.argument("chart", nargs=1, default=Chart.BARH, metavar="[CHART_TYPE]")
@click.argument("chart", nargs=1, default="barh", metavar="[CHART_TYPE]")
@click.option(
"-P",
"--path",
Expand All @@ -27,6 +27,7 @@
@click.option(
"--details",
is_flag=True,
default=False,
help="Display additinal details like fstype and mountpoint",
)
@click.option(
Expand Down Expand Up @@ -65,111 +66,31 @@
"-m", "--mark", default=None, help="Choose the symbols used for the graph"
)
def cli(chart, path, every, details, exclude, header, style, text, graph, mark):
"""** Displays Disk Usage in the terminal, graphically **

Customize visual representation by setting colors and attributes

Select one of the available graph types:

barv : Vertical Bars
*barh : Horizontal Bars (buggy)
*pie : Pie Chart (coming soon)


COLORS: light_red, red, dark_red, dark_blue, blue, cyan, yellow,
green, neon, white, black, purple, pink, grey, beige, orange.

ATTRIBUTES: bold, dim, underlined, blink, reverse, hidden.
"""

chart = _check_chart(chart)
graph_color = _check_color(graph)
graph_symbol = mark
header_color = _check_color(header) or Color.RED
style = _check_attr(style) or Attr.BOLD
text_color = _check_color(text)
""" Displays charts in the terminal, graphically """
chart = "barh"

options: Options = Options()
if mark:
options.symbol = mark
if header:
options.header_color = header
if text:
options.text_color = text
if graph:
options.graph_color = graph

chart = chart
style = style
exclude_list = list(exclude)

renderer = DiskUsage(
chart=chart,
path=path,
header=header_color,
details=details,
symbol=graph_symbol,
style=style,
exclude=exclude_list,
text=text_color,
graph=graph_color,
every=every,
)

renderer.main()


def _check_color(option: str) -> Color:
"""Checks if the string argument for color is in
Color(Enum) list and returns enum for that selection

args:
option (str): user input for selected color
rtype:
Color: enum with a selected color
"""
if option is None:
return None

# Build a dict of available colors so look ups are O(1) instead of O(n)
if "colors" not in _check_color.__dict__:
_check_color.colors = {}
for name in Color.__members__.items():
_check_color.colors[name[0].upper()] = name
try:
# This will fail with a KeyError if color does not exist
return _check_color.colors[option.upper()][1]
except:
print(f'----- color {option} is not available')
return None


def _check_attr(option: str) -> Attr:
"""Checks if the string argument for attribute is in
Attr(Enum) list and returns enum for that selection

args:
option (str): user input for selected attribute
rtype:
Attr: enum with a selected attribute
"""
if option is None:
return None

# Build a dict of available arrts so look ups are O(1) instead of O(n)
if "attrs" not in _check_attr.__dict__:
_check_attr.attrs = {}
for name in Attr.__members__.items():
_check_attr.attrs[name[0].upper()] = name
try:
# This will fail with a KeyError if attr does not exist
return _check_attr.attrs[option.upper()][1]
except:
print(f'----- attribute {option} is not available')
return None
renderer = None
if chart == "barh":
renderer = DiskUsage(
path=path, exclude=exclude_list, details=details, every=every
)

renderer.print_charts(options)

def _check_chart(chart: str) -> Chart:
"""Checks what type of bar user wants to be displayed"""
if isinstance(chart, str):
chart = chart.lower()
ret = None
if chart in [Chart.BARH, "barh"]:
ret = Chart.BARH
elif chart in [Chart.BARV, "barv"]:
ret = Chart.BARV
elif chart in [Chart.PIE, "pie"]:
ret = Chart.PIE
else:
raise NameError("Unsupported chart type!")
return ret

if __name__ == "__main__":
cli()
Loading