From 1d7c0905e17e01ac6835b202534f1fbbf353b079 Mon Sep 17 00:00:00 2001 From: Dima Gerasimov Date: Sun, 4 Aug 2019 20:20:19 +0100 Subject: [PATCH] cachew for bluemaestro --- bluemaestro/__init__.py | 103 +++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/bluemaestro/__init__.py b/bluemaestro/__init__.py index 55974b8..252421e 100755 --- a/bluemaestro/__init__.py +++ b/bluemaestro/__init__.py @@ -1,46 +1,43 @@ #!/usr/bin/python3 -import sqlite3 -# ugh, dataset stumpled over date format -from itertools import islice, chain -from typing import Dict, Any - -from datetime import datetime import logging -from kython import setup_logzero +import sqlite3 +from datetime import datetime +from itertools import chain, islice from pathlib import Path +from typing import Any, Dict, Iterable, NamedTuple, Set + +from cachew import cachew +from kython import dictify +from kython.klogging import LazyLogger + + +CACHE = Path('/L/data/.cache/bluemaestro.cache') DIR = Path("/L/zzz_syncthing_backups/bluemaestro/") - # TODO how to move them back? DIR2 = Path("/L/zzz_syncthing_phone/phone-syncthing/backups/bluemaestro/") -def get_logger(): - return logging.getLogger('bluemaestro') +logger = LazyLogger('bluemaestro', level=logging.DEBUG) -def get_temperature(all_=False): - logger = get_logger() - - backups = list(sorted(chain( +def get_backup_files(): + return list(sorted(chain( DIR.glob('*.db'), DIR2.glob('*.db'), ))) - if not all_: - backups = [backups[-1]] - merged: Dict[datetime, Any] = {} - for f in backups: - def reg(dt: datetime, value): - v = merged.get(dt, None) - if v is None: - merged[dt] = value - return - if value == v or (isinstance(v, set) and value in v): - return - if isinstance(v, set): - v.add(value) - else: - merged[dt] = {v, value} + +class Point(NamedTuple): + dt: datetime + temp: float + + +@cachew(db_path=CACHE) +def iter_points(dbs) -> Iterable[Point]: + # I guess we can affort keeping them in sorted order + points: Set[Point] = set() + # TODO do some sanity check?? + for f in dbs: # err = f'{f}: mismatch: {v} vs {value}' # if abs(v - value) > 0.4: # logger.warning(err) @@ -48,36 +45,46 @@ def get_temperature(all_=False): # # raise AssertionError(err) # else: # pass + with sqlite3.connect(str(f)) as db: + datas = list(db.execute('select * from data')) + for _, tss, temp, hum, pres, dew in datas: + # TODO is that utc??? + tss = tss.replace('Juli', 'Jul').replace('Aug.', 'Aug') + dt = datetime.strptime(tss, '%Y-%b-%d %H:%M') + p = Point( + dt=dt, + temp=temp, + ) + if p in points: + continue + points.add(p) + for p in sorted(points, key=lambda p: p.dt): + yield p - db = sqlite3.connect(str(f)) - - datas = list(db.execute('select * from data')) - - for _, tss, temp, hum, pres, dew in datas: - # TODO is that utc??? - tss = tss.replace('Juli', 'Jul').replace('Aug.', 'Aug') - - - dt = datetime.strptime(tss, '%Y-%b-%d %H:%M') - reg(dt, temp) - - db.close() - - logger.info('total items: %d', len(merged)) + # logger.info('total items: %d', len(merged)) # TODO assert frequency? # for k, v in merged.items(): # # TODO shit. quite a few of them have varying values... how is that freaking possible???? # # most of them are withing 0.5 degree though... so just ignore? # if isinstance(v, set) and len(v) > 1: # print(k, v) - return merged + # for k, v in merged.items(): + # yield Point(dt=k, temp=v) # meh? + +# TODO does it even have to be a dict? +@dictify(key=lambda p: p.dt) +def get_temperature(backups=get_backup_files()): + yield from iter_points(backups) + def test(): - get_temperature(all_=False) + get_temperature(get_backup_files()[-1:]) def main(): - setup_logzero(get_logger(), level=logging.DEBUG) - get_temperature() + ll = list(iter_points(get_backup_files())) + print(len(ll)) + # print(get_temperature(get_backup_files()[-1:])) + # print(type(t)) if __name__ == '__main__':