covid: add top3 subcommand
This commit is contained in:
parent
14b4a350ee
commit
dfc9420a3f
1 changed files with 78 additions and 12 deletions
|
|
@ -8,7 +8,7 @@ from typing import *
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from ..functions import localizedtz, reply
|
from ..functions import localizedtz, react, reply
|
||||||
from ..models import Job, Message
|
from ..models import Job, Message
|
||||||
from ..tz import cest
|
from ..tz import cest
|
||||||
|
|
||||||
|
|
@ -181,7 +181,7 @@ class Store:
|
||||||
for row in self.connection.execute(sql, params):
|
for row in self.connection.execute(sql, params):
|
||||||
yield Probe.from_row(row)
|
yield Probe.from_row(row)
|
||||||
|
|
||||||
def find_one(self, term) -> Optional["Probe"]:
|
def find_one(self, term: str = "%") -> Optional["Probe"]:
|
||||||
cond = """
|
cond = """
|
||||||
where county_name like ?
|
where county_name like ?
|
||||||
or state_name like ?
|
or state_name like ?
|
||||||
|
|
@ -317,11 +317,11 @@ async def update_store(job: Job):
|
||||||
store.add(load_data())
|
store.add(load_data())
|
||||||
|
|
||||||
|
|
||||||
def pfloat(n):
|
def pfloat(n: float):
|
||||||
return f"{n:_.02f}".replace(".", ",")
|
return f"{n:_.02f}".replace(".", ",")
|
||||||
|
|
||||||
|
|
||||||
def as_html(probe, tzname: str, lc: str) -> str:
|
def as_html(probe: Probe, tzname: str, lc: str) -> str:
|
||||||
# now = datetime.now(tz=timezone.utc)
|
# now = datetime.now(tz=timezone.utc)
|
||||||
# since = now - probe.ts
|
# since = now - probe.ts
|
||||||
# fmt = "%A" if since.days < 7 else "%x"
|
# fmt = "%A" if since.days < 7 else "%x"
|
||||||
|
|
@ -348,6 +348,76 @@ def as_html(probe, tzname: str, lc: str) -> str:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def top3html(states: List[Probe], counties: List[Probe], tzname: str, lc: str) -> str:
|
||||||
|
assert len(states) == len(counties) == 3
|
||||||
|
posmoji = ("🥇", "🥈", "🥉")
|
||||||
|
date = localizedtz(states[0].ts, "%A, %x", tzname=tzname, lc=lc)
|
||||||
|
return (
|
||||||
|
f"<i>Höchste 7-Tage-Inzidenz von {date}</i>: "
|
||||||
|
+ ", ".join(
|
||||||
|
(
|
||||||
|
f"{medal} {escape(probe.county_name)}"
|
||||||
|
+ f" (📈 {pfloat(probe.cases7_per_100k)})"
|
||||||
|
)
|
||||||
|
for probe, medal in zip(counties, posmoji)
|
||||||
|
)
|
||||||
|
+ " — "
|
||||||
|
+ ", ".join(
|
||||||
|
(
|
||||||
|
f"{medal} {escape(probe.state_name)}"
|
||||||
|
+ f" (📈 {pfloat(probe.state_cases7_per_100k)})"
|
||||||
|
)
|
||||||
|
for probe, medal in zip(states, posmoji)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def top3(store: Store, message: Message):
|
||||||
|
latest = store.find_one()
|
||||||
|
|
||||||
|
def top_probes(scope: str, n=3):
|
||||||
|
sql = f"""
|
||||||
|
select *
|
||||||
|
from current
|
||||||
|
where ts = ?
|
||||||
|
group by {scope}_name
|
||||||
|
order by {scope}_cases7_per_100k desc
|
||||||
|
limit {n}
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
Probe.from_row(row)
|
||||||
|
for row in store.connection.execute(sql, [latest.ts.timestamp()])
|
||||||
|
]
|
||||||
|
|
||||||
|
states = top_probes("state")
|
||||||
|
counties = top_probes("county")
|
||||||
|
|
||||||
|
if states and counties:
|
||||||
|
roomconf = message.app.config.l6n[message.room.room_id]
|
||||||
|
await reply(
|
||||||
|
message,
|
||||||
|
html=top3html(
|
||||||
|
states, counties, tzname=roomconf["timezone"], lc=roomconf["locale"]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await react(message, emoji="🐛")
|
||||||
|
|
||||||
|
|
||||||
|
async def search(store: Store, message: Message):
|
||||||
|
assert message.args
|
||||||
|
|
||||||
|
term = "%".join(message.args)
|
||||||
|
if (probe := store.find_one(f"%{term}%")) :
|
||||||
|
roomconf = message.app.config.l6n[message.room.room_id]
|
||||||
|
await reply(
|
||||||
|
message,
|
||||||
|
html=as_html(probe, tzname=roomconf["timezone"], lc=roomconf["locale"]),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await reply(message, "No such county or state.", in_thread=True)
|
||||||
|
|
||||||
|
|
||||||
async def handle(message: Message):
|
async def handle(message: Message):
|
||||||
if message.command not in ("cov", "covid") or not message.args:
|
if message.command not in ("cov", "covid") or not message.args:
|
||||||
return
|
return
|
||||||
|
|
@ -359,12 +429,8 @@ async def handle(message: Message):
|
||||||
# return
|
# return
|
||||||
|
|
||||||
store: Store = message.app.shared["covid.store"]
|
store: Store = message.app.shared["covid.store"]
|
||||||
term = "%".join(message.args)
|
|
||||||
if (probe := store.find_one(f"%{term}%")) :
|
if message.args.get(0) == "top3":
|
||||||
roomconf = message.app.config.l6n[message.room.room_id]
|
await top3(store, message)
|
||||||
await reply(
|
|
||||||
message,
|
|
||||||
html=as_html(probe, tzname=roomconf["timezone"], lc=roomconf["locale"]),
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await reply(message, "No such county or state.", in_thread=True)
|
await search(store, message)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue