config: store/load device drawing in the device's directory

pull/34/head
Peter Hutterer 2018-01-24 16:24:09 +10:00
parent 7a31a994fb
commit 3bc88bbbb6
4 changed files with 81 additions and 4 deletions

View File

@ -159,6 +159,8 @@ org.freedesktop.tuhi1.Device
or we run out of memory, whichever happens earlier.
Use GetJSONData() to retrieve the data from the daemon.
DO NOT RELY ON THE DAEMON FOR PERMANENT STORAGE
When drawings become available from the device, the DrawingsAvailable
property updates to the number of available drawings.
When the button is pressed multiple times, any new data is appended

View File

@ -45,7 +45,6 @@ class TuhiDevice(GObject.Object):
GObject.Object.__init__(self)
self.config = config
self._wacom_device = None
self.drawings = []
# We need either uuid or paired as false
assert uuid is not None or paired is False
self.paired = paired
@ -84,6 +83,12 @@ class TuhiDevice(GObject.Object):
self._tuhi_dbus_device.connect('pair-requested', self._on_pair_requested)
self._tuhi_dbus_device.connect('notify::listening', self._on_listening_updated)
drawings = self.config.load_drawings(self.address)
if drawings:
logger.debug(f'{self.address}: loaded {len(drawings)} drawings from disk')
for d in drawings:
self._tuhi_dbus_device.add_drawing(d)
@GObject.Property
def listening(self):
return self._tuhi_dbus_device.listening
@ -115,6 +120,7 @@ class TuhiDevice(GObject.Object):
def _on_drawing_received(self, device, drawing):
logger.debug('Drawing received')
self._tuhi_dbus_device.add_drawing(drawing)
self.config.store_drawing(self.address, drawing)
def _on_fetching_finished(self, device, exception, bluez_device):
bluez_device.disconnect_device()

View File

@ -18,6 +18,7 @@ import os
import configparser
import re
import logging
from .drawing import Drawing
logger = logging.getLogger('tuhi.config')
@ -97,3 +98,38 @@ class TuhiConfig(GObject.Object):
config = configparser.ConfigParser()
config.read(path)
self._devices[address] = config['Device']
def store_drawing(self, address, drawing):
assert is_btaddr(address)
assert drawing is not None
if address not in self.devices:
logger.error("{}: cannot store drawings for unknown device".format(address))
return
logger.debug("{}: adding new drawing, timestamp {}".format(address, drawing.timestamp))
path = os.path.join(ROOT_PATH, address, "{}.json".format(drawing.timestamp))
with open(path, "w") as f:
f.write(drawing.to_json())
def load_drawings(self, address):
assert is_btaddr(address)
drawings = []
if address not in self.devices:
return drawings
configdir = os.path.join(ROOT_PATH, address)
with os.scandir(configdir) as it:
for entry in it:
if not entry.is_file():
continue
if not entry.name.endswith('.json'):
continue
d = Drawing.from_json(entry)
drawings.append(d)
return drawings

View File

@ -13,6 +13,9 @@
from gi.repository import GObject
import json
import logging
logger = logging.getLogger('tuhi.drawing')
class Point(GObject.Object):
@ -73,6 +76,8 @@ class Drawing(GObject.Object):
Abstracts a drawing. The drawing is composed Strokes, each of which has
Points.
"""
JSON_FILE_FORMAT_VERSION = 1
def __init__(self, name, dimensions, timestamp):
GObject.Object.__init__(self)
self.name = name
@ -97,13 +102,41 @@ class Drawing(GObject.Object):
return l
def to_json(self):
JSON_FILE_FORMAT_VERSION = 1
json_data = {
'version': JSON_FILE_FORMAT_VERSION,
'version': self.JSON_FILE_FORMAT_VERSION,
'devicename': self.name,
'dimensions': list(self.dimensions),
'timestamp': self.timestamp,
'strokes': [s.to_dict() for s in self.strokes]
}
return json.dumps(json_data)
@classmethod
def from_json(cls, path):
d = None
with open(path, 'r') as fp:
json_data = json.load(fp)
try:
if json_data['version'] != cls.JSON_FILE_FORMAT_VERSION:
logger.error(f'{path}: Invalid file format version')
return d
name = json_data['devicename']
dimensions = tuple(json_data['dimensions'])
timestamp = json_data['timestamp']
d = Drawing(name, dimensions, timestamp)
for s in json_data['strokes']:
stroke = d.new_stroke()
for p in s['points']:
position = p.get('position', None)
pressure = p.get('pressure', None)
stroke.new_abs(position, pressure)
except KeyError:
logger.error(f'{path}: failed to parse json file')
return d
def __repr__(self):
return f'Drawing from {self.name} at {self.timestamp}, {len(self.strokes)} strokes'