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 datetime import datetime
from typing import Optional from typing import Optional
import requests import requests
from mastodon import Mastodon from mastodon import Mastodon
from PIL import Image, ImageDraw, ImageFont
from sqlalchemy import create_engine, select from sqlalchemy import create_engine, select
from sqlalchemy.exc import NoResultFound from sqlalchemy.exc import NoResultFound
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
from staticmap import Polygon, StaticMap
post_datetime_format = "%b %e %l:%M %p" post_datetime_format = "%b %e %l:%M %p"
@ -19,6 +22,51 @@ except requests.JSONDecodeError:
mastodon = Mastodon(access_token="scl_bot_mastodon.secret") 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): class Base(DeclarativeBase):
pass pass
@ -56,10 +104,13 @@ with Session(engine) as session:
lookup_result = session.scalars(lookup_statement) lookup_result = session.scalars(lookup_statement)
if event["numPeople"] < 250: if event["numPeople"] < 250:
outage_size = "Small" outage_size = "Small"
outage_color = "#F97316"
elif event["numPeople"] < 1000: elif event["numPeople"] < 1000:
outage_size = "Medium" outage_size = "Medium"
outage_color = "#EF4444"
else: else:
outage_size = "Large" outage_size = "Large"
outage_color = "991B1B"
if "status" in event: if "status" in event:
status = event["status"] status = event["status"]
@ -142,9 +193,35 @@ Cause: {}
hashtag_string, 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( mastodon_post_result = mastodon.status_post(
status=post_text, status=post_text, media_ids=map_media_post, visibility="public"
visibility="public",
) )
new_outage_record = SclOutage( new_outage_record = SclOutage(