Adafruit_Learning_System_Gu.../PyPortal_Electioncal_US/electioncal_graphics.py
2022-09-07 16:23:08 -04:00

159 lines
5.9 KiB
Python

# SPDX-FileCopyrightText: 2020 Alvaro Figueroa for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import json
import displayio
from adafruit_display_text.label import Label
from adafruit_bitmap_font import bitmap_font
cwd = ("/"+__file__).rsplit('/', 1)[0] # the current working directory (where this file is)
small_font = cwd+"/fonts/Arial-12.bdf"
medium_font = cwd+"/fonts/Arial-16.bdf"
class Electioncal_Graphics(displayio.Group):
def __init__(self, root_group, *, am_pm=True):
super().__init__()
self.am_pm = am_pm
root_group.append(self)
self._icon_group = displayio.Group()
self.append(self._icon_group)
self._text_group = displayio.Group()
self.append(self._text_group)
self._icon_sprite = None
self._icon_file = None # Remove when CircuitPython 6 support is dropped
self.set_icon(cwd+"/icons/electioncal.bmp")
self.small_font = bitmap_font.load_font(small_font)
self.medium_font = bitmap_font.load_font(medium_font)
glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
self.small_font.load_glyphs(glyphs)
self.medium_font.load_glyphs(glyphs)
self.date_text = Label(self.small_font)
self.date_text.x = 15
self.date_text.y = 195
self.date_text.color = 0xFFFFFF
self._text_group.append(self.date_text)
self.url_text = Label(self.small_font)
self.url_text.x = 15
self.url_text.y = 220
self.url_text.color = 0xFFFFFF
self._text_group.append(self.url_text)
self.url_text.text = "Visit us at https://electioncal.us"
self.state_text = Label(self.small_font)
self.state_text.x = 15
self.state_text.y = 10
self.state_text.color = 0xFFFFFF
self._text_group.append(self.state_text)
self.election_date_text = Label(self.medium_font)
self.election_date_text.x = 15
self.election_date_text.y = 60
self.election_date_text.color = 0xFFFFFF
self._text_group.append(self.election_date_text)
self.election_name_text = Label(self.small_font)
self.election_name_text.x = 15
self.election_name_text.y = 95
self.election_name_text.color = 0xFFFFFF
self._text_group.append(self.election_name_text)
self.election_name_text_line2 = Label(self.small_font)
self.election_name_text_line2.x = 15
self.election_name_text_line2.y = 120
self.election_name_text_line2.color = 0xFFFFFF
self._text_group.append(self.election_name_text_line2)
def load_data(self, election_data):
try:
self.electioncal = json.loads(election_data) # pylint: disable=attribute-defined-outside-init
self.state_text.text = self.electioncal["dates"][1]["county"] + ", " + self.electioncal["dates"][0]["state"] # pylint: disable=line-too-long
except ValueError:
print("Error loading JSON data: Please check the configuration of county and state, in code.py") # pylint: disable=line-too-long
raise
def elections_cycle(self):
self.update_time()
num_elections = len(self.electioncal["dates"])
for i in range(0,num_elections):
if self.date_text.text[10:] < self.electioncal["dates"][i]["date"]:
self.election_date_text.text = self.electioncal["dates"][i]["date"]
# splitting the line at around 40 chars seems ok for regular PyPortal
self.election_name_text_line2.text, self.election_name_text.text = self.paragrapher(self.electioncal["dates"][i]["name"], 40) # pylint: disable=line-too-long
time.sleep(30)
def update_time(self):
"""Fetch the time.localtime(), parse it out and update the display text"""
now = time.localtime()
hour = now[3]
minute = now[4]
year = now[0]
month = now[1]
day = now[2]
time_format_str = "%d:%02d"
date_format_str = "%d-%02d-%02d"
if self.am_pm:
if hour >= 12:
hour -= 12
time_format_str = time_format_str+" PM"
else:
time_format_str = time_format_str+" AM"
if hour == 0:
hour = 12
time_str = time_format_str % (hour, minute) # pylint: disable=unused-variable
date_str = date_format_str % (year, month, day)
self.date_text.text = "Today is: " + date_str
def paragrapher(self, text, cut): # pylint: disable=no-self-use
""" Cuts a long line into two, having spaces in mind.
Note we return line2 first as it looks better to clear the line2
before printing a line1 with empty line2
We run from cut, backwards till we find a space.
"""
if len(text) > cut:
for i in range(cut,0,-1):
if text[i] == " ":
break
line1 = text[0:i]
line2 = text[i+1:80]
else:
line1 = text
line2 = ""
return line2, line1
def set_icon(self, filename):
"""The background image to a bitmap file.
:param filename: The filename of the chosen icon
"""
print("Set icon to ", filename)
if self._icon_group:
self._icon_group.pop()
if not filename:
return # we're done, no icon desired
# CircuitPython 6 & 7 compatible
if self._icon_file:
self._icon_file.close()
self._icon_file = open(filename, "rb")
icon = displayio.OnDiskBitmap(self._icon_file)
self._icon_sprite = displayio.TileGrid(
icon,
pixel_shader=getattr(icon, 'pixel_shader', displayio.ColorConverter())
)
# # CircuitPython 7+ compatible
# icon = displayio.OnDiskBitmap(filename)
# self._icon_sprite = displayio.TileGrid(icon, pixel_shader=icon.pixel_shader)
self._icon_group.append(self._icon_sprite)