Initial map support

This commit is contained in:
Liam Steckler 2024-01-13 17:13:38 -08:00
parent 217fccb8ea
commit 53a5cc8aa0

81
scl.py
View file

@ -1,11 +1,14 @@
import io
from datetime import datetime
from typing import Optional
import requests
from mastodon import Mastodon
from PIL import Image, ImageDraw, ImageFont
from sqlalchemy import create_engine, select
from sqlalchemy.exc import NoResultFound
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
from staticmap import Polygon, StaticMap
post_datetime_format = "%b %e %l:%M %p"
@ -19,6 +22,51 @@ except requests.JSONDecodeError:
mastodon = Mastodon(access_token="scl_bot_mastodon.secret")
with open("stadiamaps_api_key.secret", "r+") as stadiamaps_api_key_file:
# Reading from a file
stadiamaps_api_key = stadiamaps_api_key_file.read()
class AttribStaticMap(StaticMap, object):
def __init__(self, *args, **kwargs):
self.attribution = "© Stadia Maps © OpenMapTiles © OpenStreetMap"
super(AttribStaticMap, self).__init__(*args, **kwargs)
def _draw_features(self, image):
super(AttribStaticMap, self)._draw_features(image)
txt = Image.new("RGBA", image.size, (255, 255, 255, 0))
# get a font
# fnt = ImageFont.truetype('FreeMono.ttf', 12)
fnt = ImageFont.load_default()
# get a drawing context
d = ImageDraw.Draw(txt)
textSize = fnt.getbbox(self.attribution)
textPosition = (image.size[0] - textSize[2], image.size[1] - textSize[3])
offset = 2
options = {"fill": (255, 255, 255, 180)}
d.rectangle(
[
(textPosition[0] - (2 * offset), textPosition[1] - (2 * offset)),
(
textSize[2] + textPosition[0] + (2 * offset),
textSize[3] + textPosition[1] + (2 * offset),
),
],
**options,
)
# draw text, full opacity
d.text(
(textPosition[0] - offset, textPosition[1] - offset),
self.attribution,
font=fnt,
fill="black",
)
image.paste(txt, (0, 0), txt)
class Base(DeclarativeBase):
pass
@ -56,10 +104,13 @@ with Session(engine) as session:
lookup_result = session.scalars(lookup_statement)
if event["numPeople"] < 250:
outage_size = "Small"
outage_color = "#F97316"
elif event["numPeople"] < 1000:
outage_size = "Medium"
outage_color = "#EF4444"
else:
outage_size = "Large"
outage_color = "991B1B"
if "status" in event:
status = event["status"]
@ -142,9 +193,35 @@ Cause: {}
hashtag_string,
)
try:
map = AttribStaticMap(
512,
512,
url_template="https://tiles.stadiamaps.com/tiles/outdoors/{z}/{x}/{y}.png?api_key="
+ stadiamaps_api_key,
)
assert event["polygons"]["type"] == "polygon"
for ring in event["polygons"]["rings"]:
polygon = Polygon(
ring, "{}7F".format(outage_color), outage_color, simplify=True
)
map.add_polygon(polygon)
map_image = map.render()
with io.BytesIO() as map_image_file:
map_image.save(map_image_file, format="PNG", optimize=True)
map_media_post = mastodon.media_post(
map_image_file.getvalue(), mime_type="image/png"
)
except Exception as e:
print(e)
print(
"Ran into an issue with generating/uploading the map. Will post without it."
)
map_media_post = None
mastodon_post_result = mastodon.status_post(
status=post_text,
visibility="public",
status=post_text, media_ids=map_media_post, visibility="public"
)
new_outage_record = SclOutage(