Compare commits

..

No commits in common. "main" and "renovate/numpy-2.x" have entirely different histories.

2 changed files with 8 additions and 39 deletions

View file

@ -1,5 +1,4 @@
from shapely import MultiPolygon, Polygon, Geometry, to_wkb, from_wkb from shapely import MultiPolygon, Polygon
from sqlalchemy.types import TypeDecorator, LargeBinary
def convert_outage_geometry(event) -> MultiPolygon: def convert_outage_geometry(event) -> MultiPolygon:
@ -10,21 +9,3 @@ def convert_outage_geometry(event) -> MultiPolygon:
for ring in event["polygons"]["rings"]: for ring in event["polygons"]["rings"]:
polygon_list.append(Polygon(ring)) polygon_list.append(Polygon(ring))
return MultiPolygon(polygon_list) return MultiPolygon(polygon_list)
class DBGeometry(TypeDecorator):
impl = LargeBinary
cache_ok = True
def process_bind_param(self, value, dialect):
if isinstance(value, Geometry):
value = to_wkb(value)
return value
def process_result_value(self, value, dialect):
if value is None:
return value
else:
if not isinstance(value, Geometry):
value = from_wkb(value)
return value

26
scl.py
View file

@ -5,16 +5,15 @@ from typing import Optional
import mastodon import mastodon
import requests import requests
import shapely import shapely
import staticmap
import yaml import yaml
from mastodon import Mastodon from mastodon import Mastodon
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from shapely import Geometry
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
from geospatial import DBGeometry, convert_outage_geometry from geospatial import convert_outage_geometry
post_datetime_format = "%b %e %l:%M %p" post_datetime_format = "%b %e %l:%M %p"
@ -37,7 +36,7 @@ mastodon_client = Mastodon(
) )
class AttribStaticMap(staticmap.StaticMap, object): class AttribStaticMap(StaticMap, object):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.attribution = "© Stadia Maps © OpenMapTiles © OpenStreetMap" self.attribution = "© Stadia Maps © OpenMapTiles © OpenStreetMap"
super(AttribStaticMap, self).__init__(*args, **kwargs) super(AttribStaticMap, self).__init__(*args, **kwargs)
@ -138,7 +137,7 @@ def do_initial_post(
) )
assert event["polygons"]["type"] == "polygon" assert event["polygons"]["type"] == "polygon"
for ring in event["polygons"]["rings"]: for ring in event["polygons"]["rings"]:
polygon = staticmap.Polygon( polygon = Polygon(
ring, ring,
# Appending 7F to the fill_color makes it 50% transparent # Appending 7F to the fill_color makes it 50% transparent
fill_color="{}7F".format(event_class["outage_color"]), fill_color="{}7F".format(event_class["outage_color"]),
@ -222,7 +221,7 @@ def do_initial_post(
map_image.save(map_image_file, format="WebP", method=6) map_image.save(map_image_file, format="WebP", method=6)
map_media_post = mastodon_client.media_post( map_media_post = mastodon_client.media_post(
map_image_file.getvalue(), map_image_file.getvalue(),
mime_type="image/webp", mime_type="image/png",
description=alt_text, description=alt_text,
) )
map_media_post_id = map_media_post["id"] map_media_post_id = map_media_post["id"]
@ -273,9 +272,7 @@ Cause: {}
class Base(DeclarativeBase): class Base(DeclarativeBase):
type_annotation_map = { pass
Geometry: DBGeometry,
}
class SclOutage(Base): class SclOutage(Base):
@ -295,11 +292,9 @@ class SclOutage(Base):
max_num_people: Mapped[int] = mapped_column() max_num_people: Mapped[int] = mapped_column()
neighborhood: Mapped[Optional[str]] = mapped_column() neighborhood: Mapped[Optional[str]] = mapped_column()
city: Mapped[Optional[str]] = mapped_column() city: Mapped[Optional[str]] = mapped_column()
outage_geometries: Mapped[Optional[Geometry]] = mapped_column()
geometries_modified: Mapped[Optional[bool]] = mapped_column()
def __repr__(self) -> str: def __repr__(self) -> str:
return f"SclOutage(scl_outage_id={self.scl_outage_id!r}, most_recent_post_id={self.most_recent_post_id!r}, initial_post_id={self.initial_post_id!r}, map_media_post_id={self.map_media_post_id!r}, last_updated_time={self.last_updated_time!r}, no_longer_in_response_time={self.no_longer_in_response_time!r}, start_time={self.start_time!r}, num_people={self.num_people!r}, max_num_people={self.max_num_people!r}, neighborhood={self.neighborhood!r}, city={self.city!r}, outage_geometries={self.outage_geometries!r}, geometries_modified={self.geometries_modified!r})" return f"SclOutage(scl_outage_id={self.scl_outage_id!r}, most_recent_post_id={self.most_recent_post_id!r}, initial_post_id={self.initial_post_id!r}, map_media_post_id={self.map_media_post_id!r}, last_updated_time={self.last_updated_time!r}, no_longer_in_response_time={self.no_longer_in_response_time!r}, start_time={self.start_time!r}, num_people={self.num_people!r}, max_num_people={self.max_num_people!r}, neighborhood={self.neighborhood!r}, city={self.city!r})"
engine = create_engine("sqlite:///scl.db") engine = create_engine("sqlite:///scl.db")
@ -371,10 +366,6 @@ with Session(engine) as session:
# Used to determine the maximum number of people affected by this outage, to determine if it's worth posting about # Used to determine the maximum number of people affected by this outage, to determine if it's worth posting about
existing_record.max_num_people = event["numPeople"] existing_record.max_num_people = event["numPeople"]
max_event_class = classify_event_size(existing_record.max_num_people) max_event_class = classify_event_size(existing_record.max_num_people)
if existing_record.outage_geometries != outage_geometries:
print("Geometries modified")
existing_record.outage_geometries = outage_geometries
existing_record.geometries_modified = True
if updated_properties: if updated_properties:
updated_properties.sort() updated_properties.sort()
@ -435,8 +426,6 @@ with Session(engine) as session:
existing_record.map_media_post_id = initial_post_result[ existing_record.map_media_post_id = initial_post_result[
"map_media_post_id" "map_media_post_id"
] ]
else:
print("Existing record was found, and no properties were updated.")
session.commit() session.commit()
except NoResultFound: except NoResultFound:
@ -487,7 +476,6 @@ with Session(engine) as session:
max_num_people=event["numPeople"], max_num_people=event["numPeople"],
neighborhood=neighborhood, neighborhood=neighborhood,
city=city, city=city,
outage_geometries=outage_geometries,
) )
session.add(new_outage_record) session.add(new_outage_record)
session.commit() session.commit()