0f303e69a4a7b64a4c6f5be2ea1e7289f8673674
[philipp/winterrodeln/wrpylib.git] / wrpylib / wrintermaps.py
1 import datetime
2 import itertools
3 import json
4 from sqlalchemy import orm
5 from wrpylib.wrorm import Page, WrIntermapsSledrun, WrIntermapsReport, WrIntermapsReportHistory
6
7
8 def investigate(filename: str, write_back_formatted: bool):
9     """Displays statistics about a Intermaps json file."""
10     with open(filename) as fp:
11         content = json.load(fp)
12     regions = content['items']
13     sledruns = list(itertools.chain.from_iterable(region['sledruns']['items'] for region in regions))
14     sledrun_ids_list = [sledrun['id'] for sledrun in sledruns]
15     sledrun_ids_set = set(sledrun_ids_list)
16     duplicates = {sledrun_id for sledrun_id in sledrun_ids_set if sum(sr_id == sledrun_id for sr_id in sledrun_ids_list) >= 2}
17     print(duplicates)
18     print(max(map(len, sledrun_ids_set)))  # 36
19     if write_back_formatted:
20         with open(filename, 'w') as fp:
21             json.dump(content, fp, indent='\t')
22
23
24 class UpdateError(RuntimeError):
25     pass
26
27
28 def find_intermaps_sledrun(intermaps_sledrun_id: str, json_content: dict):
29     """Returns iterator of tuples (region, sledrun) for given sledrun_id"""
30     regions = json_content['items']
31     for region in regions:
32         for sledrun in region['sledruns']['items']:
33             if sledrun['id'] == intermaps_sledrun_id:
34                 yield region, sledrun
35
36
37 def region_to_region_with_sledrun_dict(region: dict):
38     region = region.copy()
39     region.update({'sledruns': {sledrun['id']: sledrun for sledrun in region['sledruns']['items']}})
40     return region
41
42
43 def json_content_to_region_dict(json_content: dict) -> dict:
44     return {region['id']: region_to_region_with_sledrun_dict(region) for region in json_content['items']}
45
46
47 def update_wrintermapssledrun(session, json_content: dict):
48     """Updates the wrintermapssledrun table from the wiki. By filling in the missing fields of rows as long as
49     intermaps_sledrun_id and wr_page_id are set.
50     If convert errors occur, an UpdateError exception
51     is raised. No other exception type should be raised under normal circumstances.
52
53     >>> import json
54     >>> from sqlalchemy.engine import create_engine
55     >>> engine = create_engine('mysql://philipp@localhost:3306/philipp_winterrodeln_wiki?charset=utf8&use_unicode=1')
56     >>> Session = orm.sessionmaker(bind=engine)
57     >>> with open('2019-12-06_090500.json') as fp:
58     >>>     content = json.load(fp)
59     >>> update_wrintermapssledrun(Session(), content)
60     """
61     q = session.query(WrIntermapsSledrun)
62     for intermaps_sledrun in q:
63         if intermaps_sledrun.intermaps_sledrun_name is None or intermaps_sledrun.intermaps_region_id is None or \
64                 intermaps_sledrun.intermaps_region_name is None or intermaps_sledrun.intermaps_country is None:
65             region_json, sledrun_json = \
66                 next(find_intermaps_sledrun(intermaps_sledrun.intermaps_sledrun_id, json_content), (None, None))
67             if region_json is None:
68                 raise UpdateError(
69                     f'Sledrun with intermaps id {intermaps_sledrun.intermaps_sledrun_id} not found in JSON')
70         if intermaps_sledrun.intermaps_sledrun_name is None:
71             intermaps_sledrun.intermaps_sledrun_name = sledrun_json['name']
72         if intermaps_sledrun.intermaps_region_id is None:
73             intermaps_sledrun.intermaps_region_id = region_json['id']
74         if intermaps_sledrun.intermaps_region_name is None:
75             intermaps_sledrun.intermaps_region_name = region_json['names']['de']
76         if intermaps_sledrun.intermaps_country is None:
77             intermaps_sledrun.intermaps_country = region_json['countryCode']
78
79         if intermaps_sledrun.wr_page_title is None:
80             page = session.query(Page).get(intermaps_sledrun.wr_page_id)
81             intermaps_sledrun.wr_page_title = page.page_title
82
83     session.commit()
84
85
86 def update_wrintermapsreport(session, json_content: dict, last_check: datetime.datetime):
87     # add current content of intermaps_report to intermaps_history
88     pass
89
90     # delete content of intermaps_report
91     session.query(WrIntermapsReport).delete()
92
93     # add JSON content to intermaps_report
94     regions = json_content_to_region_dict(json_content)
95     for sledrun in session.query(WrIntermapsSledrun):
96         region = regions.get(sledrun.intermaps_region_id)
97         if region is None:
98             continue
99         sledrun_json = region['sledruns'].get(sledrun.intermaps_sledrun_id)
100         if sledrun_json is None:
101             continue
102         report = WrIntermapsReport()
103         report.intermaps_sledrun_id = sledrun.intermaps_sledrun_id
104         report.status = sledrun_json['status']
105         report.last_update = region['lastUpdate']
106         report.last_check = last_check
107         report.utc_offset = 1
108         session.add(report)
109     session.commit()
110
111
112 if __name__ == '__main__':
113     from sqlalchemy.engine import create_engine
114     engine = create_engine('mysql://philipp@localhost:3306/philipp_winterrodeln_wiki?charset=utf8&use_unicode=1')
115     Session = orm.sessionmaker(bind=engine)
116     filename = '/home/philipp/daten/Winterrodeln/Intermaps/intermaps_winterrodeln_2019-12-06_090501.json'
117     with open(filename) as fp:
118         content = json.load(fp)
119     session = Session()
120     update_wrintermapssledrun(session, content)
121     update_wrintermapsreport(session, content, datetime.datetime.now())