Compare commits
No commits in common. "53a5cc8aa0b426934762c72a53dfa8f4fddfac49" and "c5cdf4a2ca4ffb62feeb272d8d98a2655fd4dffb" have entirely different histories.
53a5cc8aa0
...
c5cdf4a2ca
2 changed files with 3 additions and 95 deletions
|
@ -1,18 +1,3 @@
|
||||||
beautifulsoup4==4.12.2
|
|
||||||
blurhash==1.1.4
|
|
||||||
certifi==2023.11.17
|
|
||||||
charset-normalizer==3.3.2
|
|
||||||
decorator==5.1.1
|
|
||||||
greenlet==3.0.3
|
|
||||||
idna==3.6
|
|
||||||
Mastodon.py==1.8.1
|
Mastodon.py==1.8.1
|
||||||
pillow==10.2.0
|
|
||||||
python-dateutil==2.8.2
|
|
||||||
python-magic==0.4.27
|
|
||||||
requests==2.28.2
|
requests==2.28.2
|
||||||
six==1.16.0
|
sqlalchemy==2.0.25
|
||||||
soupsieve==2.5
|
|
||||||
SQLAlchemy==2.0.25
|
|
||||||
staticmap==0.5.7
|
|
||||||
typing_extensions==4.9.0
|
|
||||||
urllib3==1.26.18
|
|
81
scl.py
81
scl.py
|
@ -1,14 +1,11 @@
|
||||||
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"
|
||||||
|
|
||||||
|
@ -22,51 +19,6 @@ 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
|
||||||
|
@ -104,13 +56,10 @@ 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"]
|
||||||
|
@ -193,35 +142,9 @@ 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, media_ids=map_media_post, visibility="public"
|
status=post_text,
|
||||||
|
visibility="public",
|
||||||
)
|
)
|
||||||
|
|
||||||
new_outage_record = SclOutage(
|
new_outage_record = SclOutage(
|
||||||
|
|
Loading…
Reference in a new issue