Cache the json files to disentangle them from Tuhi

Tuhi caches the json data but has no guarantee about storage. So we cache the
json we get from Tuhi and store it in our settings dir through our Config
backend. Then we use  those cached values to generate the SVG files.
This commit is contained in:
Peter Hutterer 2019-07-16 13:52:54 +10:00
parent b34dbcf899
commit ff35e5bfc5
3 changed files with 67 additions and 10 deletions

View File

@ -17,6 +17,7 @@ from gi.repository import GObject
import xdg.BaseDirectory
import configparser
import logging
import json
from pathlib import Path
logger = logging.getLogger('config')
@ -33,7 +34,9 @@ class Config(GObject.Object):
self.config = configparser.ConfigParser()
# Don't lowercase options
self.config.optionxform = str
self._drawings = []
self._load()
self._load_cached_drawings()
def _load(self):
if not self.path.exists():
@ -42,6 +45,15 @@ class Config(GObject.Object):
logger.debug(f'configuration found')
self.config.read(self.path)
def _load_cached_drawings(self):
if not ROOT_PATH.exists():
return
for filename in ROOT_PATH.glob('*.json'):
with open(filename) as fd:
self._drawings.append(json.load(fd))
self.notify('drawings')
def _write(self):
self.path.resolve().parent.mkdir(parents=True, exist_ok=True)
with open(self.path, 'w') as fd:
@ -65,6 +77,25 @@ class Config(GObject.Object):
assert(orientation in ['landscape', 'portrait'])
self._add_key('Device', 'Orientation', orientation)
@GObject.property
def drawings(self):
return self._drawings
def add_drawing(self, timestamp, json_string):
'''Add a drawing JSON with the given timestamp to the backend
storage. This will update self.drawings.'''
ROOT_PATH.mkdir(parents=True, exist_ok=True)
path = Path(ROOT_PATH, f'{timestamp}.json')
if path.exists():
return
with open(path, 'w') as fd:
fd.write(json_string)
self._drawings.append(json.loads(json_string))
self.notify('drawings')
@classmethod
def load(cls):
if cls._config_obj is None:

View File

@ -51,6 +51,7 @@ class Drawing(Gtk.Box):
self.label_timestamp.set_text(f'{day} {hour}')
self.image_svg.set_from_file(svg.filename)
self.image_completed.set_visible(False)
self.timestamp = svg.timestamp
@GObject.Property
def name(self):

View File

@ -16,7 +16,6 @@ from .drawing import Drawing
from .svg import JsonSvg
from .config import Config
import json
import time
import gi
import logging
@ -73,18 +72,35 @@ class DrawingPerspective(Gtk.Stack):
self.flowbox_drawings.remove(child)
child = self.flowbox_drawings.get_child_at_index(0)
self._update_drawings(self.device, None)
self._update_drawings(Config.load(), None)
def _update_drawings(self, device, pspec):
for ts in reversed(sorted(self.device.drawings_available)):
if ts in self.known_drawings:
def _cache_drawings(self, device, pspec):
# The config backend filters duplicates anyway, so don't care here
for ts in self.device.drawings_available:
json_string = self.device.json(ts)
Config.load().add_drawing(ts, json_string)
def _update_drawings(self, config, pspec):
for js in config.drawings:
if js in self.known_drawings:
continue
self.known_drawings.append(ts)
js = json.loads(self.device.json(ts))
self.known_drawings.append(js)
svg = JsonSvg(js)
drawing = Drawing(svg)
self.flowbox_drawings.add(drawing)
# We don't know which order we get drawings from the device, so
# let's do a sorted insert here
index = 0
child = self.flowbox_drawings.get_child_at_index(index)
while child is not None:
if child.get_child().timestamp < drawing.timestamp:
break
index += 1
child = self.flowbox_drawings.get_child_at_index(index)
self.flowbox_drawings.insert(drawing, index)
@GObject.Property
def device(self):
@ -99,11 +115,20 @@ class DrawingPerspective(Gtk.Stack):
device.connect('notify::sync-state', self._on_sync_state)
device.connect('notify::battery-percent', self._on_battery_changed)
device.connect('notify::battery-state', self._on_battery_changed)
device.connect('notify::drawings-available', self._update_drawings)
# This is a bit convoluted. We need to cache all drawings
# because Tuhi doesn't have guaranteed storage. So any json that
# comes in from Tuhi, we pass to our config backend to save
# somewhere.
# The config backend adds the json file and emits a notify for the
# json itself (once cached) that we then actually use for SVG
# generation.
device.connect('notify::drawings-available', self._cache_drawings)
Config.load().connect('notify::drawings', self._update_drawings)
self._on_battery_changed(device, None)
self._update_drawings(self.device, None)
self._update_drawings(Config.load(), None)
# We always want to sync on startup
logger.debug(f'{device.name} - starting to listen')