mirror of https://github.com/tuhiproject/tuhi.git
Switch to pathlib everywhere
gresources and svgwrite don't (yet?) take a Path though, so we have to use os.fspath() to convert those. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>pull/168/head
parent
c8759eb400
commit
be6d57562a
|
@ -28,9 +28,10 @@ import time
|
||||||
import svgwrite
|
import svgwrite
|
||||||
import xdg.BaseDirectory
|
import xdg.BaseDirectory
|
||||||
import configparser
|
import configparser
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
CONFIG_PATH = os.path.join(xdg.BaseDirectory.xdg_data_home, 'tuhi-kete')
|
CONFIG_PATH = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi-kete')
|
||||||
|
|
||||||
|
|
||||||
class ColorFormatter(logging.Formatter):
|
class ColorFormatter(logging.Formatter):
|
||||||
|
@ -759,14 +760,11 @@ class TuhiKeteShell(cmd.Cmd):
|
||||||
# patching get_names to hide some functions we do not want in the help
|
# patching get_names to hide some functions we do not want in the help
|
||||||
self.get_names = self._filtered_get_names
|
self.get_names = self._filtered_get_names
|
||||||
|
|
||||||
try:
|
CONFIG_PATH.mkdir(exist_ok=True)
|
||||||
os.mkdir(CONFIG_PATH)
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self._config_file = os.path.join(CONFIG_PATH, 'settings.ini')
|
self._config_file = Path(CONFIG_PATH, 'settings.ini')
|
||||||
self._config = configparser.ConfigParser()
|
self._config = configparser.ConfigParser()
|
||||||
if os.path.exists(self._config_file):
|
if self._config_file.exists():
|
||||||
self._config.read(self._config_file)
|
self._config.read(self._config_file)
|
||||||
else:
|
else:
|
||||||
# Populate config file with a configuration example
|
# Populate config file with a configuration example
|
||||||
|
@ -791,7 +789,7 @@ HandlePressure = true
|
||||||
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
self._history_file = os.path.join(CONFIG_PATH, 'histfile')
|
self._history_file = Path(CONFIG_PATH, 'histfile')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
readline.read_history_file(self._history_file)
|
readline.read_history_file(self._history_file)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import gi
|
import gi
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
gi.require_version('Gio', '2.0') # NOQA
|
gi.require_version('Gio', '2.0') # NOQA
|
||||||
gi.require_version('Gtk', '3.0') # NOQA
|
gi.require_version('Gtk', '3.0') # NOQA
|
||||||
|
@ -10,7 +11,7 @@ from gi.repository import Gio, Gtk, Gdk
|
||||||
|
|
||||||
|
|
||||||
@devel@ # NOQA
|
@devel@ # NOQA
|
||||||
resource = Gio.resource_load(os.path.join('@pkgdatadir@', 'tuhi.gresource'))
|
resource = Gio.resource_load(os.fspath(Path('@pkgdatadir@', 'tuhi.gresource')))
|
||||||
Gio.Resource._register(resource)
|
Gio.Resource._register(resource)
|
||||||
|
|
||||||
|
|
||||||
|
|
6
tuhi.in
6
tuhi.in
|
@ -12,11 +12,11 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
tuhi_server = os.path.join('@libexecdir@', 'tuhi-server')
|
tuhi_server = Path('@libexecdir@', 'tuhi-server')
|
||||||
tuhi_gui = os.path.join('@libexecdir@', 'tuhi-gui')
|
tuhi_gui = Path('@libexecdir@', 'tuhi-gui')
|
||||||
|
|
||||||
|
|
||||||
@devel@ # NOQA
|
@devel@ # NOQA
|
||||||
|
|
|
@ -14,16 +14,16 @@
|
||||||
from gi.repository import GObject
|
from gi.repository import GObject
|
||||||
|
|
||||||
import xdg.BaseDirectory
|
import xdg.BaseDirectory
|
||||||
import os
|
|
||||||
import configparser
|
import configparser
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
from .drawing import Drawing
|
from .drawing import Drawing
|
||||||
from .protocol import ProtocolVersion
|
from .protocol import ProtocolVersion
|
||||||
|
|
||||||
logger = logging.getLogger('tuhi.config')
|
logger = logging.getLogger('tuhi.config')
|
||||||
|
|
||||||
DEFAULT_CONFIG_PATH = os.path.join(xdg.BaseDirectory.xdg_data_home, 'tuhi')
|
DEFAULT_CONFIG_PATH = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi')
|
||||||
|
|
||||||
|
|
||||||
def is_btaddr(addr):
|
def is_btaddr(addr):
|
||||||
|
@ -37,10 +37,7 @@ class TuhiConfig(GObject.Object):
|
||||||
config_dir = DEFAULT_CONFIG_PATH
|
config_dir = DEFAULT_CONFIG_PATH
|
||||||
self.config_dir = config_dir
|
self.config_dir = config_dir
|
||||||
logger.debug(f'Using config directory: {self.config_dir}')
|
logger.debug(f'Using config directory: {self.config_dir}')
|
||||||
try:
|
Path(config_dir).mkdir(parents=True, exist_ok=True)
|
||||||
os.mkdir(config_dir)
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self._devices = {}
|
self._devices = {}
|
||||||
self._scan_config_dir()
|
self._scan_config_dir()
|
||||||
|
@ -53,28 +50,23 @@ class TuhiConfig(GObject.Object):
|
||||||
return self._devices
|
return self._devices
|
||||||
|
|
||||||
def _scan_config_dir(self):
|
def _scan_config_dir(self):
|
||||||
with os.scandir(self.config_dir) as it:
|
dirs = [d for d in Path(self.config_dir).iterdir() if d.is_dir() and is_btaddr(d.name)]
|
||||||
for entry in it:
|
for directory in dirs:
|
||||||
if entry.is_file():
|
settings = Path(directory, 'settings.ini')
|
||||||
continue
|
if not settings.is_file():
|
||||||
|
continue
|
||||||
|
|
||||||
if not is_btaddr(entry.name):
|
logger.debug(f'{directory}: configuration found')
|
||||||
continue
|
config = configparser.ConfigParser()
|
||||||
|
config.read(settings)
|
||||||
|
|
||||||
path = os.path.join(entry, 'settings.ini')
|
self._purge_drawings(directory)
|
||||||
if not os.path.isfile(path):
|
|
||||||
continue
|
|
||||||
|
|
||||||
logger.debug(f'{entry.name}: configuration found')
|
btaddr = directory.name
|
||||||
config = configparser.ConfigParser()
|
assert config['Device']['Address'] == btaddr
|
||||||
config.read(path)
|
if 'Protocol' not in config['Device']:
|
||||||
|
config['Device']['Protocol'] = ProtocolVersion.ANY.name.lower()
|
||||||
self._purge_drawings(entry)
|
self._devices[btaddr] = config['Device']
|
||||||
|
|
||||||
assert config['Device']['Address'] == entry.name
|
|
||||||
if 'Protocol' not in config['Device']:
|
|
||||||
config['Device']['Protocol'] = ProtocolVersion.ANY.name.lower()
|
|
||||||
self._devices[entry.name] = config['Device']
|
|
||||||
|
|
||||||
def new_device(self, address, uuid, protocol):
|
def new_device(self, address, uuid, protocol):
|
||||||
assert is_btaddr(address)
|
assert is_btaddr(address)
|
||||||
|
@ -82,17 +74,14 @@ class TuhiConfig(GObject.Object):
|
||||||
assert protocol != ProtocolVersion.ANY
|
assert protocol != ProtocolVersion.ANY
|
||||||
|
|
||||||
logger.debug(f'{address}: adding new config, UUID {uuid}')
|
logger.debug(f'{address}: adding new config, UUID {uuid}')
|
||||||
path = os.path.join(self.config_dir, address)
|
path = Path(self.config_dir, address)
|
||||||
try:
|
path.mkdir(exist_ok=True)
|
||||||
os.mkdir(path)
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# The ConfigParser default is to write out options as lowercase, but
|
# The ConfigParser default is to write out options as lowercase, but
|
||||||
# the ini standard is Capitalized. But it's convenient to have
|
# the ini standard is Capitalized. But it's convenient to have
|
||||||
# write-out nice but read-in flexible. So have two different config
|
# write-out nice but read-in flexible. So have two different config
|
||||||
# parsers for writing and then for handling the reads later
|
# parsers for writing and then for handling the reads later
|
||||||
path = os.path.join(path, 'settings.ini')
|
path = Path(path, 'settings.ini')
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.optionxform = str
|
config.optionxform = str
|
||||||
config.read(path)
|
config.read(path)
|
||||||
|
@ -119,7 +108,7 @@ class TuhiConfig(GObject.Object):
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.debug(f'{address}: adding new drawing, timestamp {drawing.timestamp}')
|
logger.debug(f'{address}: adding new drawing, timestamp {drawing.timestamp}')
|
||||||
path = os.path.join(self.config_dir, address, f'{drawing.timestamp}.json')
|
path = Path(self.config_dir, address, f'{drawing.timestamp}.json')
|
||||||
|
|
||||||
with open(path, 'w') as f:
|
with open(path, 'w') as f:
|
||||||
f.write(drawing.to_json())
|
f.write(drawing.to_json())
|
||||||
|
@ -127,39 +116,29 @@ class TuhiConfig(GObject.Object):
|
||||||
def load_drawings(self, address):
|
def load_drawings(self, address):
|
||||||
assert is_btaddr(address)
|
assert is_btaddr(address)
|
||||||
|
|
||||||
drawings = []
|
|
||||||
if address not in self.devices:
|
if address not in self.devices:
|
||||||
return drawings
|
return []
|
||||||
|
|
||||||
configdir = os.path.join(self.config_dir, address)
|
configdir = Path(self.config_dir, address)
|
||||||
with os.scandir(configdir) as it:
|
return [Drawing.from_json(f) for f in configdir.glob('*.json')]
|
||||||
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
|
|
||||||
|
|
||||||
def _purge_drawings(self, directory):
|
def _purge_drawings(self, directory):
|
||||||
'''Removes all but the most recent 10 files from the config
|
'''Removes all but the most recent 10 files from the config
|
||||||
directory. This is primarily done so that no-one relies on the tuhi
|
directory. This is primarily done so that no-one relies on the tuhi
|
||||||
daemon for permanent storage.'''
|
daemon for permanent storage.'''
|
||||||
|
|
||||||
files = []
|
files = [x for x in Path(directory).glob('*.json')]
|
||||||
with os.scandir(directory) as it:
|
|
||||||
for entry in it:
|
|
||||||
if entry.is_file() and entry.name.endswith('.json'):
|
|
||||||
files.append(entry)
|
|
||||||
|
|
||||||
if len(files) <= 10:
|
if len(files) > 10:
|
||||||
|
files.sort(key=lambda e: e.name)
|
||||||
|
for f in files[:-10]:
|
||||||
|
logger.debug(f'{directory.name}: purging {f.name}')
|
||||||
|
f.unlink()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_base_path(cls, path):
|
||||||
|
if cls._instance is not None:
|
||||||
|
logger.error('Trying to set config base path but we already have the singleton object')
|
||||||
return
|
return
|
||||||
|
|
||||||
files.sort(key=lambda e: e.name)
|
cls._base_path = Path(path)
|
||||||
for f in files[:-10]:
|
|
||||||
logger.debug(f'{directory.name}: purging {f.name}')
|
|
||||||
os.remove(f)
|
|
||||||
|
|
|
@ -16,21 +16,19 @@ from gi.repository import GObject
|
||||||
import xdg.BaseDirectory
|
import xdg.BaseDirectory
|
||||||
import svgwrite
|
import svgwrite
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
DATA_PATH = os.path.join(xdg.BaseDirectory.xdg_data_home, 'tuhi', 'svg')
|
DATA_PATH = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi', 'svg')
|
||||||
|
|
||||||
|
|
||||||
class JsonSvg(GObject.Object):
|
class JsonSvg(GObject.Object):
|
||||||
def __init__(self, json, orientation, *args, **kwargs):
|
def __init__(self, json, orientation, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.json = json
|
self.json = json
|
||||||
try:
|
DATA_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
os.mkdir(DATA_PATH)
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.timestamp = json['timestamp']
|
self.timestamp = json['timestamp']
|
||||||
self.filename = os.path.join(DATA_PATH, f'{self.timestamp}.svg')
|
self.filename = os.fspath(Path(DATA_PATH, f'{self.timestamp}.svg'))
|
||||||
self.orientation = orientation
|
self.orientation = orientation
|
||||||
self._convert()
|
self._convert()
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ import binascii
|
||||||
import enum
|
import enum
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
import errno
|
import errno
|
||||||
|
from pathlib import Path
|
||||||
from gi.repository import GObject
|
from gi.repository import GObject
|
||||||
from .drawing import Drawing
|
from .drawing import Drawing
|
||||||
from .uhid import UHIDDevice
|
from .uhid import UHIDDevice
|
||||||
|
@ -188,8 +188,8 @@ class DataLogger(object):
|
||||||
self.logger = logging.getLogger('tuhi.fw')
|
self.logger = logging.getLogger('tuhi.fw')
|
||||||
self.device = bluez_device
|
self.device = bluez_device
|
||||||
self.btaddr = bluez_device.address
|
self.btaddr = bluez_device.address
|
||||||
self.logdir = os.path.join(xdg.BaseDirectory.xdg_data_home, 'tuhi', self.btaddr, 'raw')
|
self.logdir = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi', self.btaddr, 'raw')
|
||||||
os.makedirs(self.logdir, exist_ok=True)
|
self.logdir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
bluez_device.connect('connected', self._on_bluez_connected)
|
bluez_device.connect('connected', self._on_bluez_connected)
|
||||||
bluez_device.connect('disconnected', self._on_bluez_disconnected)
|
bluez_device.connect('disconnected', self._on_bluez_disconnected)
|
||||||
|
@ -212,7 +212,7 @@ class DataLogger(object):
|
||||||
timestamp = int(time.time())
|
timestamp = int(time.time())
|
||||||
t = time.strftime('%Y-%m-%d-%H:%M:%S')
|
t = time.strftime('%Y-%m-%d-%H:%M:%S')
|
||||||
fname = f'log-{timestamp}-{t}.yaml'
|
fname = f'log-{timestamp}-{t}.yaml'
|
||||||
path = os.path.join(self.logdir, fname)
|
path = Path(self.logdir, fname)
|
||||||
self.logfile = open(path, 'w+')
|
self.logfile = open(path, 'w+')
|
||||||
|
|
||||||
self.logfile.write(f'name: {self.device.name}\n')
|
self.logfile.write(f'name: {self.device.name}\n')
|
||||||
|
|
Loading…
Reference in New Issue