Compare commits
3 commits
main
...
quieter-re
Author | SHA1 | Date | |
---|---|---|---|
fc8195b15f | |||
702161e1de | |||
fa8a14e539 |
4 changed files with 15 additions and 79 deletions
|
@ -1,33 +0,0 @@
|
|||
when:
|
||||
branch: main
|
||||
event: [push, pull_request]
|
||||
|
||||
variables:
|
||||
- &file Dockerfile
|
||||
- &repo scm.gruezi.net/${CI_REPO}
|
||||
|
||||
steps:
|
||||
dryrun:
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
dockerfile: *file
|
||||
platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le
|
||||
dry_run: true
|
||||
repo: *repo
|
||||
tags: latest
|
||||
when:
|
||||
event: pull_request
|
||||
|
||||
publish:
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
dockerfile: *file
|
||||
platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le
|
||||
repo: *repo
|
||||
registry: scm.gruezi.net
|
||||
tags: latest
|
||||
username: ${CI_REPO_OWNER}
|
||||
password:
|
||||
from_secret: FORGEJO_API_TOKEN
|
||||
when:
|
||||
event: push
|
|
@ -1,5 +1,4 @@
|
|||
from shapely import MultiPolygon, Polygon, Geometry, to_wkb, from_wkb
|
||||
from sqlalchemy.types import TypeDecorator, LargeBinary
|
||||
from shapely import MultiPolygon, Polygon
|
||||
|
||||
|
||||
def convert_outage_geometry(event) -> MultiPolygon:
|
||||
|
@ -10,21 +9,3 @@ def convert_outage_geometry(event) -> MultiPolygon:
|
|||
for ring in event["polygons"]["rings"]:
|
||||
polygon_list.append(Polygon(ring))
|
||||
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
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
blurhash==1.1.4
|
||||
certifi==2024.12.14
|
||||
charset-normalizer==3.4.1
|
||||
certifi==2024.8.30
|
||||
charset-normalizer==3.4.0
|
||||
decorator==5.1.1
|
||||
greenlet==3.1.1
|
||||
idna==3.10
|
||||
pip-install==1.3.5
|
||||
Mastodon.py==1.8.1
|
||||
numpy==2.2.1
|
||||
pillow==11.1.0
|
||||
numpy==2.1.2
|
||||
pillow==11.0.0
|
||||
python-dateutil==2.9.0.post0
|
||||
python-magic==0.4.27
|
||||
PyYAML==6.0.2
|
||||
requests==2.32.3
|
||||
shapely==2.0.6
|
||||
six==1.17.0
|
||||
SQLAlchemy==2.0.37
|
||||
six==1.16.0
|
||||
SQLAlchemy==2.0.35
|
||||
staticmap==0.5.7
|
||||
typing_extensions==4.12.2
|
||||
urllib3==2.3.0
|
||||
urllib3==2.2.3
|
||||
|
|
26
scl.py
26
scl.py
|
@ -5,16 +5,15 @@ from typing import Optional
|
|||
import mastodon
|
||||
import requests
|
||||
import shapely
|
||||
import staticmap
|
||||
import yaml
|
||||
from mastodon import Mastodon
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from shapely import Geometry
|
||||
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
|
||||
|
||||
from geospatial import DBGeometry, convert_outage_geometry
|
||||
from geospatial import convert_outage_geometry
|
||||
|
||||
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):
|
||||
self.attribution = "© Stadia Maps © OpenMapTiles © OpenStreetMap"
|
||||
super(AttribStaticMap, self).__init__(*args, **kwargs)
|
||||
|
@ -138,7 +137,7 @@ def do_initial_post(
|
|||
)
|
||||
assert event["polygons"]["type"] == "polygon"
|
||||
for ring in event["polygons"]["rings"]:
|
||||
polygon = staticmap.Polygon(
|
||||
polygon = Polygon(
|
||||
ring,
|
||||
# Appending 7F to the fill_color makes it 50% transparent
|
||||
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_media_post = mastodon_client.media_post(
|
||||
map_image_file.getvalue(),
|
||||
mime_type="image/webp",
|
||||
mime_type="image/png",
|
||||
description=alt_text,
|
||||
)
|
||||
map_media_post_id = map_media_post["id"]
|
||||
|
@ -273,9 +272,7 @@ Cause: {}
|
|||
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
type_annotation_map = {
|
||||
Geometry: DBGeometry,
|
||||
}
|
||||
pass
|
||||
|
||||
|
||||
class SclOutage(Base):
|
||||
|
@ -295,11 +292,9 @@ class SclOutage(Base):
|
|||
max_num_people: Mapped[int] = mapped_column()
|
||||
neighborhood: 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:
|
||||
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")
|
||||
|
@ -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
|
||||
existing_record.max_num_people = event["numPeople"]
|
||||
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:
|
||||
updated_properties.sort()
|
||||
|
@ -435,8 +426,6 @@ with Session(engine) as session:
|
|||
existing_record.map_media_post_id = initial_post_result[
|
||||
"map_media_post_id"
|
||||
]
|
||||
else:
|
||||
print("Existing record was found, and no properties were updated.")
|
||||
session.commit()
|
||||
|
||||
except NoResultFound:
|
||||
|
@ -487,7 +476,6 @@ with Session(engine) as session:
|
|||
max_num_people=event["numPeople"],
|
||||
neighborhood=neighborhood,
|
||||
city=city,
|
||||
outage_geometries=outage_geometries,
|
||||
)
|
||||
session.add(new_outage_record)
|
||||
session.commit()
|
||||
|
|
Loading…
Add table
Reference in a new issue