Refactor alerts
This commit is contained in:
parent
084dce621c
commit
606895f63b
15
main.py
15
main.py
@ -68,16 +68,21 @@ def main():
|
|||||||
from modules.weather import WeeklyWeatherModule
|
from modules.weather import WeeklyWeatherModule
|
||||||
image.paste(WeeklyWeatherModule().draw_module(config, int(480/1.6), 275), (480-int(480/1.6), 305))
|
image.paste(WeeklyWeatherModule().draw_module(config, int(480/1.6), 275), (480-int(480/1.6), 305))
|
||||||
|
|
||||||
# alerts
|
|
||||||
from modules.weather import WeatherAlertsModule
|
|
||||||
mod = WeatherAlertsModule().draw_module(config, 480, 200)
|
|
||||||
image.paste(mod, (0, 580-mod.height-5), mod)
|
|
||||||
|
|
||||||
# RATP weather
|
# RATP weather
|
||||||
from modules.ratp import RATPWeatherModule
|
from modules.ratp import RATPWeatherModule
|
||||||
ratp = RATPWeatherModule().draw_module(config, int(480/1.6), 94)
|
ratp = RATPWeatherModule().draw_module(config, int(480/1.6), 94)
|
||||||
image.paste(ratp, (480-int(480/1.6), 205))
|
image.paste(ratp, (480-int(480/1.6), 205))
|
||||||
|
|
||||||
|
# alerts
|
||||||
|
alerts = []
|
||||||
|
|
||||||
|
from modules.weather import WeatherAlerts
|
||||||
|
alerts += WeatherAlerts().gen_alerts()
|
||||||
|
|
||||||
|
from modules import AlertsModule
|
||||||
|
mod = AlertsModule(alerts).draw_module(config, 480, 200)
|
||||||
|
image.paste(mod, (0, 580-mod.height-5), mod)
|
||||||
|
|
||||||
# températures
|
# températures
|
||||||
from modules.weather import WeatherTemperatureModule
|
from modules.weather import WeatherTemperatureModule
|
||||||
image.paste(WeatherTemperatureModule().draw_module(config, 480, 200), (0, 580))
|
image.paste(WeatherTemperatureModule().draw_module(config, 480, 200), (0, 580))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
from PIL import Image, ImageDraw
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|
||||||
@ -58,6 +58,7 @@ class Config:
|
|||||||
|
|
||||||
self.charts_opts = {'style': self.pygal_custom_style, 'show_legend': False, 'margin_right': 7, 'margin_left': 2, 'margin_bottom': 4, 'margin_top': 1}
|
self.charts_opts = {'style': self.pygal_custom_style, 'show_legend': False, 'margin_right': 7, 'margin_left': 2, 'margin_bottom': 4, 'margin_top': 1}
|
||||||
|
|
||||||
|
|
||||||
class RuleModule:
|
class RuleModule:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -70,3 +71,86 @@ class RuleModule:
|
|||||||
draw.rectangle((int((1-self.coeff) * width), 0, int(self.coeff * width), height), fill="black")
|
draw.rectangle((int((1-self.coeff) * width), 0, int(self.coeff * width), height), fill="black")
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
|
||||||
|
class AlertsModule:
|
||||||
|
|
||||||
|
def __init__(self, alerts=[]):
|
||||||
|
self.icon_size = 50
|
||||||
|
self.alerts = alerts
|
||||||
|
|
||||||
|
def draw_module(self, config, width, height):
|
||||||
|
image = Image.new('RGBA', (width, height), "#000")
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
align = 0
|
||||||
|
|
||||||
|
if len(self.alerts) > 0:
|
||||||
|
fnt_R = ImageFont.truetype(config.fnt_R_path, 16)
|
||||||
|
fnt_B = ImageFont.truetype(config.fnt_RB_path, 16)
|
||||||
|
|
||||||
|
align = 9
|
||||||
|
for alert in self.alerts:
|
||||||
|
if alert["icon"] is not None:
|
||||||
|
color_img = Image.new('RGB', (self.icon_size, self.icon_size), "#fff")
|
||||||
|
icon_img = Image.open("icons/" + alert["icon"]).resize((self.icon_size, self.icon_size))
|
||||||
|
image.paste(color_img, (0, align - 5), icon_img)
|
||||||
|
|
||||||
|
draw.text(
|
||||||
|
((self.icon_size if alert["icon"] is not None else 0) - 5, align),
|
||||||
|
alert["title"],
|
||||||
|
fill="white", anchor="lt", font=fnt_B
|
||||||
|
)
|
||||||
|
if "subtitle" in alert and alert["subtitle"]:
|
||||||
|
draw.text(
|
||||||
|
((self.icon_size if alert["icon"] is not None else 0) + fnt_B.getsize(alert["title"])[0], align + 3),
|
||||||
|
alert["subtitle"],
|
||||||
|
fill="white", anchor="lt", font=fnt_R
|
||||||
|
)
|
||||||
|
|
||||||
|
align += fnt_B.getsize(alert["title"])[1]
|
||||||
|
|
||||||
|
align += display_longtext(
|
||||||
|
draw,
|
||||||
|
(self.icon_size - 5, align),
|
||||||
|
alert["description"],
|
||||||
|
fill="white", font=fnt_R,
|
||||||
|
maxwidth=width-self.icon_size-5
|
||||||
|
)
|
||||||
|
align += 7
|
||||||
|
|
||||||
|
image = image.crop((0,0,width, align))
|
||||||
|
|
||||||
|
return image
|
||||||
|
|
||||||
|
def display_longtext(draw, pos, text, font, anchor="lt", maxwidth=9999, **kwargs):
|
||||||
|
x,y = pos
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
mainlines = text.split("\n")
|
||||||
|
for line in mainlines:
|
||||||
|
words = line.split(" ")
|
||||||
|
|
||||||
|
cur = ""
|
||||||
|
while len(words) > 0:
|
||||||
|
added = (" " if len(cur) > 0 else "") + words[0]
|
||||||
|
width = font.getsize(cur + added)[0]
|
||||||
|
if width < maxwidth:
|
||||||
|
words.pop(0)
|
||||||
|
cur += added
|
||||||
|
else:
|
||||||
|
lines.append(cur)
|
||||||
|
cur = words.pop(0)
|
||||||
|
|
||||||
|
if len(cur) > 0:
|
||||||
|
lines.append(cur)
|
||||||
|
|
||||||
|
line_height = font.getsize("test")[1]
|
||||||
|
if anchor[1] == "m":
|
||||||
|
y -= line_height * len(lines) / 2
|
||||||
|
elif anchor[1] == "b":
|
||||||
|
y -= line_height * len(lines)
|
||||||
|
for line in lines:
|
||||||
|
draw.text((x,y), line, font=font, anchor=anchor, **kwargs)
|
||||||
|
y += line_height
|
||||||
|
|
||||||
|
return line_height * len(lines)
|
||||||
|
@ -6,6 +6,7 @@ from PIL import Image, ImageDraw, ImageFont
|
|||||||
|
|
||||||
import pygal
|
import pygal
|
||||||
|
|
||||||
|
from . import display_longtext
|
||||||
from .weather_api import WeatherAPI
|
from .weather_api import WeatherAPI
|
||||||
|
|
||||||
def draw_format_infos(infos, width, height, fnt_R, fnt_B, label_margin, align_height=0, margin_bf_first=True, **kwargs):
|
def draw_format_infos(infos, width, height, fnt_R, fnt_B, label_margin, align_height=0, margin_bf_first=True, **kwargs):
|
||||||
@ -39,39 +40,6 @@ def draw_format_infos(infos, width, height, fnt_R, fnt_B, label_margin, align_he
|
|||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
def display_longtext(draw, pos, text, font, anchor="lt", maxwidth=9999, **kwargs):
|
|
||||||
x,y = pos
|
|
||||||
lines = []
|
|
||||||
|
|
||||||
mainlines = text.split("\n")
|
|
||||||
for line in mainlines:
|
|
||||||
words = line.split(" ")
|
|
||||||
|
|
||||||
cur = ""
|
|
||||||
while len(words) > 0:
|
|
||||||
added = (" " if len(cur) > 0 else "") + words[0]
|
|
||||||
width = font.getsize(cur + added)[0]
|
|
||||||
if width < maxwidth:
|
|
||||||
words.pop(0)
|
|
||||||
cur += added
|
|
||||||
else:
|
|
||||||
lines.append(cur)
|
|
||||||
cur = words.pop(0)
|
|
||||||
|
|
||||||
if len(cur) > 0:
|
|
||||||
lines.append(cur)
|
|
||||||
|
|
||||||
line_height = font.getsize("test")[1]
|
|
||||||
if anchor[1] == "m":
|
|
||||||
y -= line_height * len(lines) / 2
|
|
||||||
elif anchor[1] == "b":
|
|
||||||
y -= line_height * len(lines)
|
|
||||||
for line in lines:
|
|
||||||
draw.text((x,y), line, font=font, anchor=anchor, **kwargs)
|
|
||||||
y += line_height
|
|
||||||
|
|
||||||
return line_height * len(lines)
|
|
||||||
|
|
||||||
class WeatherToolbarModule:
|
class WeatherToolbarModule:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -330,24 +298,13 @@ class WeeklyWeatherModule:
|
|||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
class WeatherAlertsModule:
|
class WeatherAlerts:
|
||||||
|
|
||||||
def __init__(self):
|
def gen_alerts(self):
|
||||||
self.icon_size = 50
|
alerts = []
|
||||||
|
|
||||||
def draw_module(self, config, width, height):
|
|
||||||
image = Image.new('RGBA', (width, height), "#000")
|
|
||||||
draw = ImageDraw.Draw(image)
|
|
||||||
align = 0
|
|
||||||
|
|
||||||
if WeatherAPI().has_alerts():
|
if WeatherAPI().has_alerts():
|
||||||
alerts = WeatherAPI().get_alerts()
|
for alert in WeatherAPI().get_alerts():
|
||||||
|
|
||||||
fnt_R = ImageFont.truetype(config.fnt_R_path, 16)
|
|
||||||
fnt_B = ImageFont.truetype(config.fnt_RB_path, 16)
|
|
||||||
|
|
||||||
align = 9
|
|
||||||
for alert in alerts:
|
|
||||||
if alert["severity"] == "watch" or alert["title"].startswith("Moderate"):
|
if alert["severity"] == "watch" or alert["title"].startswith("Moderate"):
|
||||||
icon = "wi-small-craft-advisory.png"
|
icon = "wi-small-craft-advisory.png"
|
||||||
elif alert["severity"] == "warning":
|
elif alert["severity"] == "warning":
|
||||||
@ -355,43 +312,21 @@ class WeatherAlertsModule:
|
|||||||
else:
|
else:
|
||||||
icon = None
|
icon = None
|
||||||
|
|
||||||
if icon is not None:
|
|
||||||
color_img = Image.new('RGB', (self.icon_size, self.icon_size), "#fff")
|
|
||||||
icon_img = Image.open("icons/" + icon).resize((self.icon_size, self.icon_size))
|
|
||||||
image.paste(color_img, (0, align - 5), icon_img)
|
|
||||||
|
|
||||||
draw.text(
|
|
||||||
(self.icon_size - 5, align),
|
|
||||||
alert["title"],
|
|
||||||
fill="white", anchor="lt", font=fnt_B
|
|
||||||
)
|
|
||||||
startTime = WeatherAPI().read_timestamp(alert["time"])
|
startTime = WeatherAPI().read_timestamp(alert["time"])
|
||||||
endTime = WeatherAPI().read_timestamp(alert["expires"])
|
endTime = WeatherAPI().read_timestamp(alert["expires"])
|
||||||
# Show alert timing if under a day
|
# Show alert timing if under a day
|
||||||
if startTime.hour != endTime.hour:
|
if startTime.hour != endTime.hour:
|
||||||
draw.text(
|
subtitle = startTime.strftime(("%x " if startTime.day != datetime.now().day else "") + "%X") + " - " + endTime.strftime(("%x " if startTime.day != endTime.day else "") + "%X")
|
||||||
(self.icon_size + fnt_B.getsize(alert["title"])[0], align + 3),
|
|
||||||
startTime.strftime(("%x " if startTime.day != datetime.now().day else "") + "%X") + " - " + endTime.strftime(("%x " if startTime.day != endTime.day else "") + "%X"),
|
|
||||||
fill="white", anchor="lt", font=fnt_R
|
|
||||||
)
|
|
||||||
elif startTime.day != datetime.now().day:
|
elif startTime.day != datetime.now().day:
|
||||||
draw.text(
|
subtitle = startTime.strftime("%x")
|
||||||
(self.icon_size + fnt_B.getsize(alert["title"])[0], align + 3),
|
else:
|
||||||
startTime.strftime("%x"),
|
subtitle = ""
|
||||||
fill="white", anchor="lt", font=fnt_R
|
|
||||||
)
|
|
||||||
|
|
||||||
align += fnt_B.getsize(alert["title"])[1]
|
alerts.append({
|
||||||
|
"icon": icon,
|
||||||
|
"title": alert["title"],
|
||||||
|
"subtitle": subtitle,
|
||||||
|
"description": alert["description"],
|
||||||
|
})
|
||||||
|
|
||||||
align += display_longtext(
|
return alerts
|
||||||
draw,
|
|
||||||
(self.icon_size - 5, align),
|
|
||||||
alert["description"],
|
|
||||||
fill="white", font=fnt_R,
|
|
||||||
maxwidth=width-self.icon_size-5
|
|
||||||
)
|
|
||||||
align += 7
|
|
||||||
|
|
||||||
image = image.crop((0,0,width, align))
|
|
||||||
|
|
||||||
return image
|
|
||||||
|
Loading…
Reference in New Issue
Block a user