base: add a flag to control the config directory

For testing it's a lot easier to just provide a /tmp/ directory than having to
clear out the normal one that may contain useful drawings for debugging.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
pull/153/head
Peter Hutterer 2019-08-09 14:44:51 +10:00
parent a323ba9aeb
commit 16c22a95ec
5 changed files with 63 additions and 24 deletions

View File

@ -11,6 +11,7 @@
# GNU General Public License for more details.
#
import sys
import os
import subprocess
@ -21,9 +22,10 @@ tuhi_gui = os.path.join('@libexecdir@', 'tuhi-gui')
@devel@ # NOQA
if __name__ == '__main__':
tuhi = subprocess.Popen(tuhi_server)
args = sys.argv[1:]
tuhi = subprocess.Popen([tuhi_server] + args)
try:
subprocess.run(tuhi_gui)
subprocess.run([tuhi_gui] + args)
except KeyboardInterrupt:
pass
tuhi.terminate()

View File

@ -288,7 +288,7 @@ class Tuhi(GObject.Object):
(GObject.SignalFlags.RUN_FIRST, None, ()),
}
def __init__(self):
def __init__(self, config_dir=None):
GObject.Object.__init__(self)
self.server = TuhiDBusServer()
self.server.connect('bus-name-acquired', self._on_tuhi_bus_name_acquired)
@ -299,7 +299,7 @@ class Tuhi(GObject.Object):
self.bluez.connect('discovery-started', self._on_bluez_discovery_started)
self.bluez.connect('discovery-stopped', self._on_bluez_discovery_stopped)
self.config = TuhiConfig()
self.config = TuhiConfig(config_dir)
self.devices = {}
@ -427,6 +427,10 @@ def main(args=sys.argv):
help='Show some debugging informations',
action='store_true',
default=False)
parser.add_argument('--config-dir',
help='Base directory for configuration',
type=str,
default=None)
ns = parser.parse_args(args[1:])
if ns.verbose:
@ -434,7 +438,7 @@ def main(args=sys.argv):
try:
mainloop = GLib.MainLoop()
tuhi = Tuhi()
tuhi = Tuhi(config_dir=ns.config_dir)
tuhi.connect('terminate', lambda tuhi: mainloop.quit())
mainloop.run()
except KeyboardInterrupt:

View File

@ -23,7 +23,7 @@ from .wacom import Protocol
logger = logging.getLogger('tuhi.config')
ROOT_PATH = os.path.join(xdg.BaseDirectory.xdg_data_home, 'tuhi')
DEFAULT_CONFIG_PATH = os.path.join(xdg.BaseDirectory.xdg_data_home, 'tuhi')
def is_btaddr(addr):
@ -31,10 +31,14 @@ def is_btaddr(addr):
class TuhiConfig(GObject.Object):
def __init__(self):
def __init__(self, config_dir=None):
GObject.Object.__init__(self)
if config_dir is None:
config_dir = DEFAULT_CONFIG_PATH
self.config_dir = config_dir
logger.debug(f'Using config directory: {self.config_dir}')
try:
os.mkdir(ROOT_PATH)
os.mkdir(config_dir)
except FileExistsError:
pass
@ -49,7 +53,7 @@ class TuhiConfig(GObject.Object):
return self._devices
def _scan_config_dir(self):
with os.scandir(ROOT_PATH) as it:
with os.scandir(self.config_dir) as it:
for entry in it:
if entry.is_file():
continue
@ -78,7 +82,7 @@ class TuhiConfig(GObject.Object):
assert protocol != Protocol.UNKNOWN
logger.debug(f'{address}: adding new config, UUID {uuid}')
path = os.path.join(ROOT_PATH, address)
path = os.path.join(self.config_dir, address)
try:
os.mkdir(path)
except FileExistsError:
@ -115,7 +119,7 @@ class TuhiConfig(GObject.Object):
return
logger.debug(f'{address}: adding new drawing, timestamp {drawing.timestamp}')
path = os.path.join(ROOT_PATH, address, f'{drawing.timestamp}.json')
path = os.path.join(self.config_dir, address, f'{drawing.timestamp}.json')
with open(path, 'w') as f:
f.write(drawing.to_json())
@ -127,7 +131,7 @@ class TuhiConfig(GObject.Object):
if address not in self.devices:
return drawings
configdir = os.path.join(ROOT_PATH, address)
configdir = os.path.join(self.config_dir, address)
with os.scandir(configdir) as it:
for entry in it:
if not entry.is_file():

View File

@ -13,6 +13,7 @@
from gi.repository import Gio, GLib, Gtk
from .window import MainWindow
from .config import Config
import gi
gi.require_version("Gio", "2.0")
@ -22,8 +23,13 @@ gi.require_version("Gtk", "3.0")
class Application(Gtk.Application):
def __init__(self):
super().__init__(application_id='org.freedesktop.Tuhi',
flags=Gio.ApplicationFlags.FLAGS_NONE)
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
GLib.set_application_name('Tuhi')
self.add_main_option('config-dir', 0,
GLib.OptionFlags.NONE,
GLib.OptionArg.STRING,
'path to configuration directory',
'/path/to/config-dir')
self._tuhi = None
def do_startup(self):
@ -34,6 +40,19 @@ class Application(Gtk.Application):
window = MainWindow(application=self)
window.present()
def do_command_line(self, command_line):
options = command_line.get_options_dict()
# convert GVariantDict -> GVariant -> dict
options = options.end().unpack()
try:
Config.set_base_path(options['config-dir'])
except KeyError:
pass
self.activate()
return 0
def _build_app_menu(self):
actions = [('about', self._about),
('quit', self._quit),

View File

@ -22,15 +22,17 @@ from pathlib import Path
logger = logging.getLogger('tuhi.gui.config')
ROOT_PATH = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi')
DEFAULT_CONFIG_PATH = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi')
class Config(GObject.Object):
_config_obj = None
_base_path = DEFAULT_CONFIG_PATH
def __init__(self):
super().__init__()
self.path = Path(ROOT_PATH, 'tuhigui.ini')
self.path = Path(self._base_path, 'tuhigui.ini')
self.base_path = self._base_path
self.config = configparser.ConfigParser()
# Don't lowercase options
self.config.optionxform = str
@ -46,10 +48,10 @@ class Config(GObject.Object):
self.config.read(self.path)
def _load_cached_drawings(self):
if not ROOT_PATH.exists():
if not self.base_path.exists():
return
for filename in ROOT_PATH.glob('*.json'):
for filename in self.base_path.glob('*.json'):
with open(filename) as fd:
self._drawings.append(json.load(fd))
self.notify('drawings')
@ -84,15 +86,15 @@ class Config(GObject.Object):
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)
self.base_path.mkdir(parents=True, exist_ok=True)
path = Path(ROOT_PATH, f'{timestamp}.json')
path = Path(self.base_path, f'{timestamp}.json')
if path.exists():
return
# Tuhi may still cache files we've 'deleted' locally. These need to
# be ignored because they're still technically deleted.
deleted = Path(ROOT_PATH, f'{timestamp}.json.deleted')
deleted = Path(self.base_path, f'{timestamp}.json.deleted')
if deleted.exists():
return
@ -105,22 +107,30 @@ class Config(GObject.Object):
def delete_drawing(self, timestamp):
# We don't delete json files immediately, we just rename them
# so we can resurrect them in the future if need be.
path = Path(ROOT_PATH, f'{timestamp}.json')
target = Path(ROOT_PATH, f'{timestamp}.json.deleted')
path = Path(self.base_path, f'{timestamp}.json')
target = Path(self.base_path, f'{timestamp}.json.deleted')
path.rename(target)
self._drawings = [d for d in self._drawings if d['timestamp'] != timestamp]
self.notify('drawings')
def undelete_drawing(self, timestamp):
path = Path(ROOT_PATH, f'{timestamp}.json')
target = Path(ROOT_PATH, f'{timestamp}.json.deleted')
path = Path(self.base_path, f'{timestamp}.json')
target = Path(self.base_path, f'{timestamp}.json.deleted')
target.rename(path)
with open(path) as fd:
self._drawings.append(json.load(fd))
self.notify('drawings')
@classmethod
def set_base_path(cls, path):
if cls._config_obj is not None:
logger.error('Trying to set config base path but we already have the singleton object')
return
cls._base_path = Path(path)
@classmethod
def instance(cls):
if cls._config_obj is None: