vieles
This commit is contained in:
@@ -0,0 +1,96 @@
|
|||||||
|
import toml
|
||||||
|
import os
|
||||||
|
import db_model as db
|
||||||
|
from peewee import PostgresqlDatabase
|
||||||
|
import datetime
|
||||||
|
from sshtunnel import SSHTunnelForwarder
|
||||||
|
import verdoppelungsrate
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from dataclasses_json import dataclass_json
|
||||||
|
import scrape_bev
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass_json
|
||||||
|
@dataclass
|
||||||
|
class CoronaStatistik:
|
||||||
|
ts: datetime.datetime
|
||||||
|
quelle: str
|
||||||
|
country_region: str
|
||||||
|
typ: str
|
||||||
|
wert: float
|
||||||
|
|
||||||
|
|
||||||
|
def config_laden():
|
||||||
|
configfile = os.path.join(SKRIPTPFAD, "config.toml")
|
||||||
|
with open(configfile) as file:
|
||||||
|
return toml.loads(file.read())
|
||||||
|
|
||||||
|
|
||||||
|
SKRIPTPFAD = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
CONFIG = config_laden()
|
||||||
|
|
||||||
|
|
||||||
|
def verdoppelungsrate_bearbeiten(quelle, country):
|
||||||
|
letzter_ts = verdoppelungsrate.letzten_eintrag_ermitteln(quelle, country)
|
||||||
|
if letzter_ts is None:
|
||||||
|
letzter_ts = datetime.datetime(1970, 1, 1)
|
||||||
|
daten = verdoppelungsrate.letzte_verdopplungsraten_berechnen(quelle, country, letzter_ts)
|
||||||
|
return daten
|
||||||
|
|
||||||
|
|
||||||
|
def alle_eintraege_abarbeiten():
|
||||||
|
daten = []
|
||||||
|
bev_zahlen = {}
|
||||||
|
query_quelle = db.CoronaDaten.select(db.CoronaDaten.quelle).group_by(db.CoronaDaten.quelle)
|
||||||
|
for data in query_quelle:
|
||||||
|
if data.quelle == "rki_landkreis":
|
||||||
|
continue
|
||||||
|
query_country = db.CoronaDaten.select(db.CoronaDaten.country_region).where(
|
||||||
|
db.CoronaDaten.quelle == data.quelle).group_by(db.CoronaDaten.country_region)
|
||||||
|
for datensatz in query_country:
|
||||||
|
daten_verdoppelungsrate = verdoppelungsrate_bearbeiten(data.quelle, datensatz.country_region)
|
||||||
|
if daten_verdoppelungsrate:
|
||||||
|
daten.extend(daten_verdoppelungsrate)
|
||||||
|
if datensatz.country_region not in bev_zahlen:
|
||||||
|
bev_zahlen[datensatz.country_region] = scrape_bev.scrape_bev(datensatz.country_region)
|
||||||
|
if bev_zahlen[datensatz.country_region]:
|
||||||
|
daten_bev_prozent = scrape_bev.auslesen_unverarbeiteter_daten(data.quelle,
|
||||||
|
datensatz.country_region, bev_zahlen,
|
||||||
|
CoronaStatistik)
|
||||||
|
else:
|
||||||
|
daten_bev_prozent = None
|
||||||
|
if daten_bev_prozent:
|
||||||
|
daten.extend(daten_bev_prozent)
|
||||||
|
|
||||||
|
if len(daten) > 5000:
|
||||||
|
print("Sende Daten")
|
||||||
|
daten_senden(daten)
|
||||||
|
daten = []
|
||||||
|
return daten
|
||||||
|
|
||||||
|
|
||||||
|
def daten_senden(daten):
|
||||||
|
daten_dict = []
|
||||||
|
for data in daten:
|
||||||
|
daten_dict.append(data.to_dict())
|
||||||
|
db.CoronaStatistik.insert_many(daten_dict).execute()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with SSHTunnelForwarder(
|
||||||
|
(CONFIG["ssh"]["ip_server"], CONFIG["ssh"]["ssh_port"]), ssh_username=CONFIG["ssh"]["user"],
|
||||||
|
ssh_password=CONFIG["ssh"]["pw"], remote_bind_address=('127.0.0.1', CONFIG["pg"]["pgport"])) as server:
|
||||||
|
|
||||||
|
db.database.initialize(PostgresqlDatabase(CONFIG["pg"]["pgdb"],
|
||||||
|
user=CONFIG["pg"]["pguser"], password=CONFIG["pg"]["pgpw"],
|
||||||
|
host="127.0.0.1",
|
||||||
|
port=server.local_bind_port))
|
||||||
|
db.create_tables()
|
||||||
|
daten = alle_eintraege_abarbeiten()
|
||||||
|
daten_senden(daten)
|
||||||
|
db.Database.close(db.database)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
+1
-1
@@ -38,7 +38,7 @@ class CoronaStatistik(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
def create_tables():
|
def create_tables():
|
||||||
database.create_tables([CoronaDaten])
|
database.create_tables([CoronaDaten, CoronaStatistik])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+10
-12
@@ -17,20 +17,18 @@ class CoronaDaten:
|
|||||||
active: int
|
active: int
|
||||||
|
|
||||||
|
|
||||||
@dataclass_json
|
|
||||||
@dataclass
|
|
||||||
class CoronaCountry:
|
|
||||||
country_region: str
|
|
||||||
quelle: str
|
|
||||||
|
|
||||||
|
|
||||||
def sende_daten(url, table, headers, daten):
|
def sende_daten(url, table, headers, daten):
|
||||||
url = f"{url}{table}"
|
url = f"{url}{table}"
|
||||||
for data in daten:
|
try:
|
||||||
try:
|
r = requests.post(url, headers=headers, json=[data.to_dict() for data in daten])
|
||||||
r = requests.post(url, headers=headers, json=data.to_dict())
|
except AttributeError:
|
||||||
except AttributeError:
|
for data in daten:
|
||||||
r = requests.post(url, headers=headers, data=data)
|
try:
|
||||||
|
r = requests.post(url, headers=headers, json=data.to_dict())
|
||||||
|
except AttributeError:
|
||||||
|
r = requests.post(url, headers=headers, data=data)
|
||||||
|
status_auswerten(r, daten)
|
||||||
|
else:
|
||||||
status_auswerten(r, daten)
|
status_auswerten(r, daten)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+37
-3
@@ -1,16 +1,50 @@
|
|||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
import db_model as db
|
||||||
|
import datetime
|
||||||
|
|
||||||
countrys = ["Germany"]
|
|
||||||
|
|
||||||
|
TYP = "prozent_bev"
|
||||||
URL = "https://countrymeters.info/en/"
|
URL = "https://countrymeters.info/en/"
|
||||||
|
|
||||||
|
|
||||||
|
def letzten_eintrag_ermitteln(quelle, country_region):
|
||||||
|
ts = db.CoronaStatistik.select(
|
||||||
|
db.CoronaStatistik.ts).where((db.CoronaStatistik.typ == TYP) &
|
||||||
|
(db.CoronaStatistik.quelle == quelle) &
|
||||||
|
(db.CoronaStatistik.country_region == country_region)
|
||||||
|
).order_by(db.CoronaStatistik.ts.desc()).limit(1).scalar()
|
||||||
|
if ts is None:
|
||||||
|
ts = datetime.datetime(1970, 1, 1)
|
||||||
|
return ts
|
||||||
|
|
||||||
|
|
||||||
|
def auslesen_unverarbeiteter_daten(quelle, land, bev_zahl, CoronaStatistik):
|
||||||
|
ts = letzten_eintrag_ermitteln(quelle, land)
|
||||||
|
daten = []
|
||||||
|
query = db.CoronaDaten.select(db.CoronaDaten.ts, db.CoronaDaten.confirmed).where(
|
||||||
|
(db.CoronaDaten.quelle == quelle) & (db.CoronaDaten.country_region == land) & (
|
||||||
|
db.CoronaDaten.ts > ts)).namedtuples()
|
||||||
|
for datensatz in query:
|
||||||
|
prozent_bev = datensatz.confirmed / bev_zahl[land] * 100
|
||||||
|
prozent_bev = round(prozent_bev, 8)
|
||||||
|
print(f"Im Land {land} {prozent_bev}% infiziert")
|
||||||
|
daten.append(CoronaStatistik(datensatz.ts, quelle, land, TYP, prozent_bev))
|
||||||
|
return daten
|
||||||
|
|
||||||
|
|
||||||
def scrape_bev(land):
|
def scrape_bev(land):
|
||||||
r = requests.get(f"{URL}{land}")
|
r = requests.get(f"{URL}{land}")
|
||||||
soup = BeautifulSoup(r.text, features="html5lib")
|
soup = BeautifulSoup(r.text, features="html5lib")
|
||||||
table = soup.find("div", {"id": "cp1"})
|
table = soup.find("div", {"id": "cp1"})
|
||||||
print(table)
|
try:
|
||||||
|
value = table.get_text()
|
||||||
|
except AttributeError:
|
||||||
|
value = None
|
||||||
|
else:
|
||||||
|
value = int(value.replace(",", ""))
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
scrape_bev("Germany")
|
if __name__ == "__main__":
|
||||||
|
scrape_bev("Germany")
|
||||||
|
|||||||
+25
-1
@@ -11,6 +11,11 @@ https://services.arcgis.com/5T5nSi527N4F7luB/arcgis/rest/services/Cases_by_count
|
|||||||
Deutschland RKI:
|
Deutschland RKI:
|
||||||
https://experience.arcgis.com/experience/478220a4c454480e823b17327b2bf1d4
|
https://experience.arcgis.com/experience/478220a4c454480e823b17327b2bf1d4
|
||||||
https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/Coronaf%C3%A4lle_in_den_Bundesl%C3%A4ndern/FeatureServer/0/query?f=json&where=1%3D1&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&orderByFields=faelle_100000_EW%20desc&resultOffset=0&resultRecordCount=50&cacheHint=true
|
https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/Coronaf%C3%A4lle_in_den_Bundesl%C3%A4ndern/FeatureServer/0/query?f=json&where=1%3D1&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&orderByFields=faelle_100000_EW%20desc&resultOffset=0&resultRecordCount=50&cacheHint=true
|
||||||
|
|
||||||
|
Landkreis RKI
|
||||||
|
https://experience.arcgis.com/experience/478220a4c454480e823b17327b2bf1d4/page/page_1/
|
||||||
|
https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?f=json&where=1%3D1&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&orderByFields=cases%20desc&resultOffset=0&resultRecordCount=1000&cacheHint=true
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@@ -32,7 +37,8 @@ QUELLEN = {
|
|||||||
"rki": "https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/Coronaf%C3%A4lle_in_den_Bundesl%C3"
|
"rki": "https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/Coronaf%C3%A4lle_in_den_Bundesl%C3"
|
||||||
"%A4ndern/FeatureServer/0/query?f=json&where=1%3D1&returnGeometry=false&spatialRel"
|
"%A4ndern/FeatureServer/0/query?f=json&where=1%3D1&returnGeometry=false&spatialRel"
|
||||||
"=esriSpatialRelIntersects&outFields=*&orderByFields=faelle_100000_EW%20desc&resultOffset=0"
|
"=esriSpatialRelIntersects&outFields=*&orderByFields=faelle_100000_EW%20desc&resultOffset=0"
|
||||||
"&resultRecordCount=50&cacheHint=true "
|
"&resultRecordCount=50&cacheHint=true",
|
||||||
|
"rki_landkreis": "https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?f=json&where=1%3D1&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&orderByFields=cases%20desc&resultOffset=0&resultRecordCount=1000&cacheHint=true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -110,6 +116,22 @@ def rki_daten_erstellen(quelle, daten):
|
|||||||
return daten_dict
|
return daten_dict
|
||||||
|
|
||||||
|
|
||||||
|
def rki_landkreis_daten_erstellen(quelle, daten):
|
||||||
|
daten_dict = {}
|
||||||
|
for data in daten:
|
||||||
|
datum = data["attributes"]
|
||||||
|
daten_dict[datum["county"]] = (db.CoronaDaten(
|
||||||
|
datetime.datetime.strptime(datum["last_update"], "%d.%m.%Y, %H:%M Uhr"),
|
||||||
|
datum["county"].lower().capitalize(),
|
||||||
|
quelle,
|
||||||
|
datum["cases"],
|
||||||
|
datum["deaths"],
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
))
|
||||||
|
return daten_dict
|
||||||
|
|
||||||
|
|
||||||
def daten_erstellen(quelle, daten):
|
def daten_erstellen(quelle, daten):
|
||||||
if quelle == "jhu":
|
if quelle == "jhu":
|
||||||
daten_db = jhu_daten_erstellen(quelle, daten)
|
daten_db = jhu_daten_erstellen(quelle, daten)
|
||||||
@@ -117,6 +139,8 @@ def daten_erstellen(quelle, daten):
|
|||||||
daten_db = who_daten_erstellen(quelle, daten)
|
daten_db = who_daten_erstellen(quelle, daten)
|
||||||
elif quelle == "rki":
|
elif quelle == "rki":
|
||||||
daten_db = rki_daten_erstellen(quelle, daten)
|
daten_db = rki_daten_erstellen(quelle, daten)
|
||||||
|
elif quelle == "rki_landkreis":
|
||||||
|
daten_db = rki_landkreis_daten_erstellen(quelle, daten)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Quelle nicht bekannt")
|
raise ValueError("Quelle nicht bekannt")
|
||||||
return daten_db
|
return daten_db
|
||||||
|
|||||||
+25
-18
@@ -4,7 +4,7 @@ import db_model as db
|
|||||||
from peewee import PostgresqlDatabase
|
from peewee import PostgresqlDatabase
|
||||||
import datetime
|
import datetime
|
||||||
from sshtunnel import SSHTunnelForwarder
|
from sshtunnel import SSHTunnelForwarder
|
||||||
import sys
|
from corona_statistik import CoronaStatistik
|
||||||
|
|
||||||
|
|
||||||
def config_laden():
|
def config_laden():
|
||||||
@@ -16,6 +16,16 @@ def config_laden():
|
|||||||
SKRIPTPFAD = os.path.abspath(os.path.dirname(__file__))
|
SKRIPTPFAD = os.path.abspath(os.path.dirname(__file__))
|
||||||
CONFIG = config_laden()
|
CONFIG = config_laden()
|
||||||
QUELLEN = ["jhu", "who", "rki"]
|
QUELLEN = ["jhu", "who", "rki"]
|
||||||
|
TYP = "verdoppelungsrate"
|
||||||
|
|
||||||
|
|
||||||
|
def letzten_eintrag_ermitteln(quelle, country_region):
|
||||||
|
ts = db.CoronaStatistik.select(
|
||||||
|
db.CoronaStatistik.ts).where((db.CoronaStatistik.typ == TYP) &
|
||||||
|
(db.CoronaStatistik.quelle == quelle) &
|
||||||
|
(db.CoronaStatistik.country_region == country_region)
|
||||||
|
).order_by(db.CoronaStatistik.ts.desc()).limit(1).scalar()
|
||||||
|
return ts
|
||||||
|
|
||||||
|
|
||||||
def verdoppelungsrate_ermitteln(quelle, land, confirmed, confirmed_ts):
|
def verdoppelungsrate_ermitteln(quelle, land, confirmed, confirmed_ts):
|
||||||
@@ -30,26 +40,24 @@ def verdoppelungsrate_ermitteln(quelle, land, confirmed, confirmed_ts):
|
|||||||
return verdoppelungstage
|
return verdoppelungstage
|
||||||
|
|
||||||
|
|
||||||
def letzte_verdopplungsraten(quelle, land, ts):
|
def letzte_verdopplungsraten_berechnen(quelle, land, ts):
|
||||||
|
kein_passender_eintrag = False
|
||||||
|
daten = []
|
||||||
query = db.CoronaDaten.select(db.CoronaDaten.ts, db.CoronaDaten.confirmed).where(
|
query = db.CoronaDaten.select(db.CoronaDaten.ts, db.CoronaDaten.confirmed).where(
|
||||||
(db.CoronaDaten.quelle == quelle) & (db.CoronaDaten.country_region == land) & (db.CoronaDaten.ts > ts)).dicts()
|
(db.CoronaDaten.quelle == quelle) & (db.CoronaDaten.country_region == land) & (db.CoronaDaten.ts > ts)).dicts()
|
||||||
for datensatz in query:
|
for datensatz in query:
|
||||||
verdoppelungsrate = verdoppelungsrate_ermitteln(quelle, land, datensatz["confirmed"], datensatz["ts"])
|
verdoppelungsrate = verdoppelungsrate_ermitteln(quelle, land, datensatz["confirmed"], datensatz["ts"])
|
||||||
if verdoppelungsrate is not None:
|
if verdoppelungsrate is not None:
|
||||||
verdoppelungsrate_tage = round(verdoppelungsrate_in_tagen(verdoppelungsrate), 3)
|
verdoppelungsrate_tage = round(verdoppelungsrate_in_tagen(verdoppelungsrate), 3)
|
||||||
print(f"Verdoppelungsrate am {datensatz['ts']}: {verdoppelungsrate_tage}")
|
print(f"Verdoppelungsrate für {land} ({quelle}) am {datensatz['ts']}: {verdoppelungsrate_tage}")
|
||||||
print("Verlasse letzte_Verdoppelungsraten")
|
daten.append(CoronaStatistik(datensatz["ts"], quelle, land, TYP, verdoppelungsrate_tage))
|
||||||
|
else:
|
||||||
|
print(f"Kein passender Eintrag gefunden für {land} ({quelle})")
|
||||||
def jede_verdoppelungsrate(quelle, land):
|
kein_passender_eintrag = True
|
||||||
query = db.CoronaDaten.select(db.CoronaDaten.ts, db.CoronaDaten.confirmed).where(
|
if kein_passender_eintrag:
|
||||||
(db.CoronaDaten.quelle == quelle) & (db.CoronaDaten.country_region == land)
|
print(f"Setze -1 für {land} ({quelle})")
|
||||||
).order_by(db.CoronaDaten.ts.desc()).namedtuples()
|
daten.append(CoronaStatistik(datetime.datetime.now(), quelle, land, TYP, -1))
|
||||||
for datensatz in query:
|
return daten
|
||||||
verdoppelungsrate = verdoppelungsrate_ermitteln(quelle, land, datensatz.confirmed, datensatz.ts)
|
|
||||||
if verdoppelungsrate is not None:
|
|
||||||
verdoppelungsrate_tage = round(verdoppelungsrate_in_tagen(verdoppelungsrate), 3)
|
|
||||||
print(f"Verdoppelungsrate am {datensatz.ts}: {verdoppelungsrate_tage}")
|
|
||||||
|
|
||||||
|
|
||||||
def verdoppelungsrate_in_tagen(verdoppelungsrate):
|
def verdoppelungsrate_in_tagen(verdoppelungsrate):
|
||||||
@@ -76,9 +84,8 @@ def main():
|
|||||||
).group_by(db.CoronaDaten.country_region)
|
).group_by(db.CoronaDaten.country_region)
|
||||||
for datensatz in query_country:
|
for datensatz in query_country:
|
||||||
if data.quelle == "jhu" and datensatz.country_region == "Germany":
|
if data.quelle == "jhu" and datensatz.country_region == "Germany":
|
||||||
letzte_verdopplungsraten(data.quelle, datensatz.country_region, datetime.datetime(2020, 4, 3))
|
letzte_verdopplungsraten_berechnen(data.quelle, datensatz.country_region, datetime.datetime(2020, 4, 3))
|
||||||
print("Verlasse schleife")
|
db.Database.close(db.database)
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user