covid: add top3 subcommand

This commit is contained in:
ducklet 2021-03-29 19:06:27 +02:00
parent 14b4a350ee
commit dfc9420a3f

View file

@ -8,7 +8,7 @@ from typing import *
import requests
from ..functions import localizedtz, reply
from ..functions import localizedtz, react, reply
from ..models import Job, Message
from ..tz import cest
@ -181,7 +181,7 @@ class Store:
for row in self.connection.execute(sql, params):
yield Probe.from_row(row)
def find_one(self, term) -> Optional["Probe"]:
def find_one(self, term: str = "%") -> Optional["Probe"]:
cond = """
where county_name like ?
or state_name like ?
@ -317,11 +317,11 @@ async def update_store(job: Job):
store.add(load_data())
def pfloat(n):
def pfloat(n: float):
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)
# since = now - probe.ts
# 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):
if message.command not in ("cov", "covid") or not message.args:
return
@ -359,12 +429,8 @@ async def handle(message: Message):
# return
store: Store = message.app.shared["covid.store"]
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"]),
)
if message.args.get(0) == "top3":
await top3(store, message)
else:
await reply(message, "No such county or state.", in_thread=True)
await search(store, message)