Auto-format Python sources with black, fix all issues reported by flake8 (#1010)

* Update config for black and flake8
* Auto-format Python sources with black
* Fix issues reported by flake8
* Exclude protobuf files from black
* Address formatting feedback
This commit is contained in:
nucleogenic
2022-11-30 05:19:17 +00:00
committed by GitHub
parent 5afc6b911f
commit 315ef9f248
44 changed files with 1073 additions and 725 deletions
@@ -5,6 +5,7 @@ from menu.screensaver import ScreenSaver
class BlankScreenSaver(ScreenSaver):
"""Class implementing a blank screen safer that simply blanks the screen after a
configured activation delay"""
def __init__(self, activation_delay, menu_renderer):
super().__init__(activation_delay, menu_renderer)
self._initial_draw_call = None
+12 -4
View File
@@ -8,9 +8,17 @@ class Cycler:
"""Class implementing button cycling functionality. Message is shown at the center of
the screen where repeated button presses cycle through the available selection
possibilities. Inactivity (cycle_timeout) actives cycle entry last shown on the screen."""
def __init__(self, menu_controller, sock_cmd, ractl_cmd,
cycle_timeout=3, return_string="Return ->",
return_entry=True, empty_messages=True):
def __init__(
self,
menu_controller,
sock_cmd,
ractl_cmd,
cycle_timeout=3,
return_string="Return ->",
return_entry=True,
empty_messages=True,
):
self._cycle_profile_timer_flag = Timer(activation_delay=cycle_timeout)
self._menu_controller = menu_controller
self.sock_cmd = sock_cmd
@@ -39,7 +47,7 @@ class Cycler:
"""Perform the return action, i.e., when no selection is chosen"""
def update(self):
""" Returns True if object has completed its task and can be deleted """
"""Returns True if object has completed its task and can be deleted"""
if self._cycle_profile_timer_flag is None:
return None
+3 -2
View File
@@ -4,6 +4,7 @@ from typing import List
class Menu:
"""Class implement the Menu class"""
def __init__(self, name: str):
self.entries: List = []
self.item_selection = 0
@@ -17,11 +18,11 @@ class Menu:
def get_current_text(self):
"""Returns the text content of the currently selected text in the menu."""
return self.entries[self.item_selection]['text']
return self.entries[self.item_selection]["text"]
def get_current_info_object(self):
"""Returns the data object to the currently selected menu item"""
return self.entries[self.item_selection]['data_object']
return self.entries[self.item_selection]["data_object"]
def __repr__(self):
print("entries: " + str(self.entries))
@@ -6,6 +6,7 @@ from menu.menu import Menu
# pylint: disable=too-few-public-methods
class MenuBuilder(ABC):
"""Base class for menu builders"""
def __init__(self):
pass
+62 -21
View File
@@ -18,6 +18,7 @@ from menu.screensaver import ScreenSaver
class MenuRenderer(ABC):
"""The abstract menu renderer class provides the base for concrete menu
renderer classes that implement functionality based on conrete hardware or available APIs."""
def __init__(self, config: MenuRendererConfig):
self.message = ""
self.mini_message = ""
@@ -25,7 +26,7 @@ class MenuRenderer(ABC):
self._config = config
self.disp = self.display_init()
self.image = Image.new('1', (self.disp.width, self.disp.height))
self.image = Image.new("1", (self.disp.width, self.disp.height))
self.draw = ImageDraw.Draw(self.image)
self.font = ImageFont.truetype(config.font_path, size=config.font_size)
# just a sample text to work with the font height
@@ -83,14 +84,21 @@ class MenuRenderer(ABC):
def draw_row(self, row_number: int, text: str, selected: bool):
"""Draws a single row of the menu."""
x_pos = 0
y_pos = row_number*self.font_height
y_pos = row_number * self.font_height
if selected:
selection_extension = 0
if row_number < self.rows_per_screen():
selection_extension = self._config.row_selection_pixel_extension
self.draw.rectangle((x_pos, y_pos, self.disp.width,
y_pos+self._config.font_size+selection_extension),
outline=0, fill=255)
self.draw.rectangle(
(
x_pos,
y_pos,
self.disp.width,
y_pos + self._config.font_size + selection_extension,
),
outline=0,
fill=255,
)
# in stage 1, we initialize scrolling for the currently selected line
if self._perform_scrolling_stage == 1:
@@ -99,9 +107,9 @@ class MenuRenderer(ABC):
# in stage 2, we know the details and can thus perform the scrolling to the left
if self._perform_scrolling_stage == 2:
if self._current_line_horizontal_overlap+self._x_scrolling > 0:
if self._current_line_horizontal_overlap + self._x_scrolling > 0:
self._x_scrolling -= 1
if self._current_line_horizontal_overlap+self._x_scrolling == 0:
if self._current_line_horizontal_overlap + self._x_scrolling == 0:
self._stage_timestamp = int(time.time())
self._perform_scrolling_stage = 3
@@ -115,11 +123,12 @@ class MenuRenderer(ABC):
# in stage 4, we scroll back to the right
if self._perform_scrolling_stage == 4:
if self._current_line_horizontal_overlap+self._x_scrolling >= 0:
if self._current_line_horizontal_overlap + self._x_scrolling >= 0:
self._x_scrolling += 1
if (self._current_line_horizontal_overlap +
self._x_scrolling) == self._current_line_horizontal_overlap:
if (
self._current_line_horizontal_overlap + self._x_scrolling
) == self._current_line_horizontal_overlap:
self._stage_timestamp = int(time.time())
self._perform_scrolling_stage = 5
@@ -131,8 +140,14 @@ class MenuRenderer(ABC):
self._stage_timestamp = None
self._perform_scrolling_stage = 2
self.draw.text((x_pos+self._x_scrolling, y_pos), text, font=self.font,
spacing=0, stroke_fill=0, fill=0)
self.draw.text(
(x_pos + self._x_scrolling, y_pos),
text,
font=self.font,
spacing=0,
stroke_fill=0,
fill=0,
)
else:
self.draw.text((x_pos, y_pos), text, font=self.font, spacing=0, stroke_fill=0, fill=255)
@@ -143,8 +158,15 @@ class MenuRenderer(ABC):
centered_height = (self.disp.height - font_height) / 2
self.draw.rectangle((0, 0, self.disp.width, self.disp.height), outline=0, fill=255)
self.draw.text((centered_width, centered_height), text, align="center", font=self.font,
stroke_fill=0, fill=0, textsize=20)
self.draw.text(
(centered_width, centered_height),
text,
align="center",
font=self.font,
stroke_fill=0,
fill=0,
textsize=20,
)
def draw_mini_message(self, text: str):
"""Draws a fullscreen message, i.e., a message covering only the center portion of
@@ -153,16 +175,33 @@ class MenuRenderer(ABC):
centered_width = (self.disp.width - font_width) / 2
centered_height = (self.disp.height - self.font_height) / 2
self.draw.rectangle((0, centered_height-4, self.disp.width,
centered_height+self.font_height+4), outline=0, fill=255)
self.draw.text((centered_width, centered_height), text, align="center", font=self.font,
stroke_fill=0, fill=0, textsize=20)
self.draw.rectangle(
(
0,
centered_height - 4,
self.disp.width,
centered_height + self.font_height + 4,
),
outline=0,
fill=255,
)
self.draw.text(
(centered_width, centered_height),
text,
align="center",
font=self.font,
stroke_fill=0,
fill=0,
textsize=20,
)
def draw_menu(self):
"""Method draws the menu set to the class instance."""
if self._menu.item_selection >= self.frame_start_row + self.rows_per_screen():
if self._config.scroll_behavior == "page":
self.frame_start_row = self.frame_start_row + (round(self.rows_per_screen()/2)) + 1
self.frame_start_row = (
self.frame_start_row + (round(self.rows_per_screen() / 2)) + 1
)
if self.frame_start_row > len(self._menu.entries) - self.rows_per_screen():
self.frame_start_row = len(self._menu.entries) - self.rows_per_screen()
else: # extend as default behavior
@@ -170,13 +209,15 @@ class MenuRenderer(ABC):
if self._menu.item_selection < self.frame_start_row:
if self._config.scroll_behavior == "page":
self.frame_start_row = self.frame_start_row - (round(self.rows_per_screen()/2)) - 1
self.frame_start_row = (
self.frame_start_row - (round(self.rows_per_screen() / 2)) - 1
)
if self.frame_start_row < 0:
self.frame_start_row = 0
else: # extend as default behavior
self.frame_start_row = self._menu.item_selection
self.draw_menu_frame(self.frame_start_row, self.frame_start_row+self.rows_per_screen())
self.draw_menu_frame(self.frame_start_row, self.frame_start_row + self.rows_per_screen())
def draw_menu_frame(self, frame_start_row: int, frame_end_row: int):
"""Draws row frame_start_row to frame_end_row of the class instance menu, i.e., it
@@ -11,8 +11,9 @@ class MenuRendererAdafruitSSD1306(MenuRenderer):
def display_init(self):
i2c = busio.I2C(SCL, SDA)
self.disp = adafruit_ssd1306.SSD1306_I2C(self._config.width, self._config.height, i2c,
addr=self._config.i2c_address)
self.disp = adafruit_ssd1306.SSD1306_I2C(
self._config.width, self._config.height, i2c, addr=self._config.i2c_address
)
self.disp.rotation = self._config.get_mapped_rotation()
self.disp.fill(0)
self.disp.show()
@@ -5,20 +5,16 @@
class MenuRendererConfig:
"""Class for configuring menu renderer instances. Provides configuration options
such as width, height, i2c address, font, transitions, etc."""
_rotation_mapper = {
0: 0,
90: 1,
180: 2,
270: 3
}
_rotation_mapper = {0: 0, 90: 1, 180: 2, 270: 3}
def __init__(self):
self.width = 128
self.height = 64
self.i2c_address = 0x3c
self.i2c_address = 0x3C
self.i2c_port = 1
self.display_type = "ssd1306" # luma-oled supported devices, "sh1106", "ssd1306", ...
self.font_path = 'resources/DejaVuSansMono-Bold.ttf'
self.font_path = "resources/DejaVuSansMono-Bold.ttf"
self.font_size = 12
self.row_selection_pixel_extension = 2
self.scroll_behavior = "page" # "extend" or "page"
@@ -5,14 +5,19 @@ from menu.menu_renderer import MenuRenderer
class MenuRendererLumaOled(MenuRenderer):
"""Class implementing the luma oled menu renderer"""
def display_init(self):
serial = i2c(port=self._config.i2c_port, address=self._config.i2c_address)
import luma.oled.device
device = getattr(luma.oled.device, self._config.display_type)
self.disp = device(serial_interface=serial, width=self._config.width,
height=self._config.height,
rotate=self._config.get_mapped_rotation())
self.disp = device(
serial_interface=serial,
width=self._config.width,
height=self._config.height,
rotate=self._config.get_mapped_rotation(),
)
self.disp.clear()
self.disp.show()
+1
View File
@@ -5,6 +5,7 @@ import time
class Timer:
"""Class implementing a timer class. Takes an activation delay and
sets a flag if the activation delay exprires."""
def __init__(self, activation_delay):
self.start_timestamp = int(time.time())
self.activation_delay = activation_delay
+4 -3
View File
@@ -17,6 +17,7 @@ class Transition:
class PushTransition(Transition):
"""Class implementing a push left/right transition."""
PUSH_LEFT_TRANSITION = "push_left"
PUSH_RIGHT_TRANSITION = "push_right"
@@ -32,7 +33,7 @@ class PushTransition(Transition):
if transition_attributes is not None and transition_attributes != {}:
direction = transition_attributes["direction"]
transition_image = Image.new('1', (self.disp.width, self.disp.height))
transition_image = Image.new("1", (self.disp.width, self.disp.height))
if direction == PushTransition.PUSH_LEFT_TRANSITION:
self.perform_push_left(end_image, start_image, transition_image)
@@ -57,8 +58,8 @@ class PushTransition(Transition):
"""Implements a push right transition. Is called by perform depending on the transition
attribute 'direction'."""
for x_pos in range(0, 128, self.transition_attributes["transition_speed"]):
left_region = start_image.crop((0, 0, 128-x_pos, 64))
right_region = end_image.crop((128-x_pos, 0, 128, 64))
left_region = start_image.crop((0, 0, 128 - x_pos, 64))
right_region = end_image.crop((128 - x_pos, 0, 128, 64))
transition_image.paste(left_region, (x_pos, 0, 128, 64))
transition_image.paste(right_region, (0, 0, x_pos, 64))
self.disp.display(transition_image)