Preface
Goal: Add common feature such as configuration, terminal interface, and web server
This is a multiparts article.
We are going to apply pattern we have created from Rich Live
article series.
Prerequisite
Reference
This article relies heavily on other article series. I strongly suggest you to read this article first before you begin.
14A: Apply Rich Panel: Base Class
Based on article above, we can integrate rich into our monitoring application.
Preview TUI in CLI
Our final output in terminal would be as below figure:
Python Source Code
The script is availabe. You might consider to have a look.
Required Package
Just add any rich related package.
import asyncio, websockets, json, os, tomli
from watchfiles import awatch
from rich.layout import Layout
from rich.panel import Panel
from rich.table import Table
Constructor
Excel to Web, Abstract Base Class
We need to save the self.live
and self.layout
.
class Xl2Web:
def __init__(self, sheet_ident,
ref_live, ref_layout, layout_name):
with open('config.toml', 'rb') as file_obj:
...
# websocket broadcast collection
self.connections = set()
# openpyxl: required in descendent class
self.xlsx = None
# rich: required in descendent class
self.live = ref_live
self.layout = ref_layout
self.layout_name = layout_name
Rich TUI Related
Instead of print data to terminal, we would use rich panel.
def _dump_data(self, data):
self.live.update(
self.get_layout(data))
Then I put get_layout
in separate method,
because we also need to initialize layout without any data.
def get_layout(self, data) -> Layout:
self.layout[self.layout_name].update(
self.get_panel(data))
return self.layout
And finally the get_panel
method.
def get_panel(self, data) -> Panel:
message = Table.grid(padding=1, expand=True)
message.add_column(no_wrap=True)
if data != None:
message.add_row(
"Timestamp : %s" % data["timestamp"])
message.add_row(
"File Modified : %s" % data["file"])
message.add_row(self.generate_table(data))
panel = Panel(message, title=self.filepath)
return panel
I put these three methods in base class. We need to implement descendant class. And call them in main program.
14B: Apply Left Panel: Global Review Sheet
Python Source Code
Reading script is not mandatory. But I share the script anyway.
Example Sheet: C Review
This works for either Microsoft Excel or Libreoffice Calc.
You can download the source here:
Preview TUI in CLI
Simplified
A single panel result would be similar as preview figure below:
Required Package
Include the xl2web_25
base class.
import asyncio, openpyxl, time
import xl2web_25
from openpyxl import load_workbook
from rich.table import Table
Skeleton
Consider append three rich
related methods.
class Xl2Web_c(xl2web_25.Xl2Web):
# Excel Reader
def _pack_data(self, fullname):
# Legacy, for use without rich TUI
def _dump_data_text(self, data):
# Rich TUI related
def format_table(self, dataTable):
def to_str(self, label, m):
def generate_table(self, data) -> Table:
Cell Reader
Pack Data
Due to narrow table width for dual panel, we need to shorten the full file path, into just file name.
def _pack_data(self, fullname):
# reopen the worksheet all over again
wb = load_workbook(self.xlsx, data_only=True)
ws = wb["Example"]
...
short = fullname.replace(self.filepath, '')
return {
"timestamp" : time.ctime(),
"file" : short,
"month_09" : month_09,
"month_10" : month_10
}
Legacy
Legacy, for use without rich TUI
Consider dispose this obsolete function, or just rename it.
def _dump_data_text(self, data):
print("Timestamp : %s" % data["timestamp"])
print("File Modified : %s" % data["file"])
print("September : %s" % data["month_09"])
print("October : %s" % data["month_10"])
print()
Renderable: Table
Rich TUI Related
This method may vary beetwen different sheet. So this method should be in descendant class.
def generate_table(self, data) -> Table:
# Make a new table
table = Table(
"Month", "Budget", "Actual", "Gap",
expand=True)
self.format_table(table)
table.add_row(*self.to_str(
"September", data["month_09"]))
table.add_row(*self.to_str(
"October", data["month_10"]))
return table
And so is this helper below, we have three columns, that needed to be converted to string.
def to_str(self, label, m):
return [label, str(m["budget"]),
str(m["actual"]), str(m["gap"])]
Renderable: Table Formatting
Pretty Color
We require a few aestethic enhancement. One row header, with three columns.
def format_table(self, dataTable):
c = dataTable.columns
c[1].header_style = "bold blue"
c[2].header_style = "bold green"
c[3].header_style = "bold yellow"
c[0].style = "bold"
c[1].style = "blue"
c[2].style = "green"
c[3].style = "yellow"
What is Next 🤔?
We are not done yet.
Since this article become too long, I decide to separate this article into two parts. So we can take a deep breath and amke a cup of hot coffee.
When break over. Consider continue reading [ Excel - Monitor - Dual Rich Panel ].