Skip to content

Commit

Permalink
object oriented approach for output_format handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
oaken-source committed Mar 7, 2022
1 parent af97140 commit d5e1d16
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 97 deletions.
14 changes: 0 additions & 14 deletions py3status/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,6 @@
"output_format": "i3bar",
}

OUTPUT_FORMAT_NEEDS_SEPARATOR = [
"dzen2",
"xmobar",
"lemonbar",
"tmux",
"term",
"none",
]

DEFAULT_SEPARATOR = {
"dzen2": "^p(5;-2)^ro(2)^p()^p(5)",
# if it's not listed here, it defaults to " | "
}

MAX_NESTING_LEVELS = 4

TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
Expand Down
98 changes: 15 additions & 83 deletions py3status/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import time

from collections import deque
from json import dumps
from pathlib import Path
from pprint import pformat
from signal import signal, Signals, SIGTERM, SIGUSR1, SIGTSTP, SIGCONT
Expand All @@ -13,13 +12,13 @@
from traceback import extract_tb, format_tb, format_stack

from py3status.command import CommandServer
from py3status.constants import OUTPUT_FORMAT_NEEDS_SEPARATOR, DEFAULT_SEPARATOR
from py3status.events import Events
from py3status.formatter import expand_color
from py3status.helpers import print_stderr
from py3status.i3status import I3status
from py3status.parse_config import process_config
from py3status.module import Module
from py3status.output import OutputFormat
from py3status.profiling import profile
from py3status.udev_monitor import UdevMonitor

Expand Down Expand Up @@ -679,20 +678,18 @@ def setup(self):
self.load_modules(self.py3_modules, user_modules)

# determine the target output format
self.output_format = self.config["py3_config"]["general"]["output_format"]
self.output_format = OutputFormat.instance_for(
self.config["py3_config"]["general"]["output_format"]
)

# determine the output separator, if needed
self.separator = None
if self.output_format in OUTPUT_FORMAT_NEEDS_SEPARATOR:
default_separator = DEFAULT_SEPARATOR.get(self.output_format, " | ")
self.separator = self.config["py3_config"]["general"].get(
"separator", default_separator
)
if self.config["py3_config"]["general"]["colors"]:
self.separator = self.format_separator(
self.separator,
self.config["py3_config"]["general"]["color_separator"],
)
color_separator = None
if self.config["py3_config"]["general"]["colors"]:
color_separator = self.config["py3_config"]["general"]["color_separator"]
self.output_format.format_separator(
self.config["py3_config"]["general"].get("separator", None),
color_separator,
)

def notify_user(
self,
Expand Down Expand Up @@ -971,53 +968,6 @@ def create_mappings(self, config):
# Store mappings for later use.
self.mappings_color = mappings

def format_color(self, output):
"""
Format the output of a module according to the value of output_format.
"""
full_text = output["full_text"]
if "color" in output:
if self.output_format == "dzen2":
full_text = f"^fg({output['color']})" + output["full_text"]
if self.output_format == "xmobar":
full_text = f"<fc={output['color']}>{output['full_text']}</fc>"
if self.output_format == "lemonbar":
full_text = f"%{{F{output['color']}}}" + output["full_text"]
if self.output_format == "tmux":
full_text = f"#[fg={output['color'].lower()}]" + output["full_text"]
if self.output_format == "term":
col = int(output["color"][1:], 16)
r = (col & (0xFF << 0)) // 0x80
g = (col & (0xFF << 8)) // 0x8000
b = (col & (0xFF << 16)) // 0x800000
col = (r << 2) | (g << 1) | b
full_text = f"\033[3{col};1m" + output["full_text"]
if self.output_format == "none":
pass # colors are ignored
return full_text

def format_separator(self, separator, color_separator):
"""
Format the output separator according to the value of output_format.
"""
if self.output_format == "dzen2":
return f"^fg({color_separator}){separator}^fg()"
if self.output_format == "xmobar":
return f"<fc={color_separator}>{separator}</fc>"
if self.output_format == "lemonbar":
return f"%{{F{color_separator}}}{separator}%{{F-}}"
if self.output_format == "tmux":
return f"#[fg={color_separator}]{separator}#[default]"
if self.output_format == "term":
col = int(color_separator[1:], 16)
r = (col & (0xFF << 0)) // 0x80
g = (col & (0xFF << 8)) // 0x8000
b = (col & (0xFF << 16)) // 0x800000
col = (r << 2) | (g << 1) | b
return f"\033[3{col};1m{separator}\033[0m"
else: # output_format == "none"
return separator # color_separator is ignored

def process_module_output(self, module):
"""
Process the output for a module and return a json string representing it.
Expand All @@ -1034,15 +984,8 @@ def process_module_output(self, module):
# Color: substitute the config defined color
if "color" not in output:
output["color"] = color
# concatenate string output, if needed.
if self.output_format in OUTPUT_FORMAT_NEEDS_SEPARATOR:
# FIXME: `output_format = none` in config will default to i3bar.
# `output_format = "none"` is required instead. this is different
# in i3status, which behaves correctly for `output_status = none`
return "".join(self.format_color(x) for x in outputs)
# otherwise create the json string output.
else:
return ",".join(dumps(x) for x in outputs)
# format output and return
return self.output_format.format(outputs)

def i3bar_stop(self, signum, frame):
if time.time() - self.i3bar_inhibit_stp > 1:
Expand Down Expand Up @@ -1103,18 +1046,13 @@ def run(self):
# items in the bar
output = [None] * len(py3_config["order"])

write = sys.__stdout__.write
flush = sys.__stdout__.flush

# start our output
header = {
"version": 1,
"click_events": self.config["click_events"],
"stop_signal": self.stop_signal or 0,
}
if self.output_format not in OUTPUT_FORMAT_NEEDS_SEPARATOR:
write(dumps(header))
write("\n[[]\n")
self.output_format.write_header(header)

update_due = None
# main loop
Expand Down Expand Up @@ -1142,10 +1080,4 @@ def run(self):
output[index] = out

# build output string and dump to stdout
if self.output_format in OUTPUT_FORMAT_NEEDS_SEPARATOR:
out = self.separator.join(x for x in output if x)
write(f"{out}\n")
else:
out = ",".join(x for x in output if x)
write(f",[{out}]\n")
flush()
self.output_format.write_line(output)
Loading

0 comments on commit d5e1d16

Please sign in to comment.