From 4751aa6ff9d379a4c114a719ac4883dda36f4893 Mon Sep 17 00:00:00 2001 From: sezanzeb Date: Mon, 2 Nov 2020 23:14:11 +0100 Subject: [PATCH] linking the whole dir --- .gitignore | 1 + bin/key-mapper-gtk | 3 ++- data/key-mapper.glade | 5 +++++ keymapper/X.py | 38 ++++++++++++++++++++++---------------- keymapper/paths.py | 38 ++++++++++++++++++++++++-------------- keymapper/presets.py | 15 +++++++++++---- tests/testcases/presets.py | 11 ++++++----- 7 files changed, 71 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index 8618ebfd..2daa111e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.glade~ +*.glade# # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/bin/key-mapper-gtk b/bin/key-mapper-gtk index 3238a418..7d50d9da 100755 --- a/bin/key-mapper-gtk +++ b/bin/key-mapper-gtk @@ -22,7 +22,6 @@ """User Interface.""" -import os import sys from argparse import ArgumentParser @@ -63,9 +62,11 @@ class SingleKeyMapping: delete_button.connect('clicked', self.on_delete_button_clicked) key_code = Gtk.Entry() + key_code.set_alignment(0.5) key_code.set_width_chars(4) original_key = Gtk.Entry() + original_key.set_alignment(0.5) original_key.set_width_chars(4) self.widgets = (delete_button, key_code, original_key) diff --git a/data/key-mapper.glade b/data/key-mapper.glade index e612eb31..7688752e 100644 --- a/data/key-mapper.glade +++ b/data/key-mapper.glade @@ -2,6 +2,11 @@ + + True + True + a + 450 False diff --git a/keymapper/X.py b/keymapper/X.py index ddd96455..e900ed1a 100644 --- a/keymapper/X.py +++ b/keymapper/X.py @@ -35,7 +35,8 @@ import os import re import subprocess -from keymapper.paths import get_home_path, get_usr_path, KEYCODES_PATH +from keymapper.paths import get_home_path, get_usr_path, KEYCODES_PATH, \ + CONFIG_PATH, SYMBOLS_PATH from keymapper.logger import logger from keymapper.data import get_data_path from keymapper.presets import get_presets @@ -56,9 +57,9 @@ def create_preset(device, name=None): name = 'new preset' # find a name that is not already taken - if name in existing_names: + if os.path.exists(get_home_path(device, name)): i = 2 - while f'{name} {i}' in existing_names: + while os.path.exists(get_home_path(device, f'{name} {i}')): i += 1 name = f'{name} {i}' @@ -78,21 +79,25 @@ def create_setxkbmap_config(device, preset, mappings): """ create_identity_mapping() - home_path = get_home_path(device, preset) - # setxkbmap cannot handle spaces - usr_path = get_usr_path(device, preset) + home_device_path = get_home_path(device) + if not os.path.exists(home_device_path): + logger.info('Creating directory "%s"', home_device_path) + os.makedirs(home_device_path, exist_ok=True) - if not os.path.exists(home_path): - logger.info('Creating config file "%s"', home_path) - os.makedirs(os.path.dirname(home_path), exist_ok=True) - os.mknod(home_path) - if not os.path.exists(usr_path): - logger.info('Creating symlink in "%s"', usr_path) - os.makedirs(os.path.dirname(usr_path), exist_ok=True) - os.symlink(home_path, usr_path) + if not os.path.exists(SYMBOLS_PATH): + # link from /usr/share/X11/xkb/symbols/key-mapper/user to + # /home/user/.config/key-mapper + logger.info('Linking "%s" to "%s"', SYMBOLS_PATH, CONFIG_PATH) + os.makedirs(os.path.dirname(SYMBOLS_PATH), exist_ok=True) + os.symlink(CONFIG_PATH, SYMBOLS_PATH, target_is_directory=True) + + home_preset_path = get_home_path(device, preset) + if not os.path.exists(home_preset_path): + logger.info('Creating config file "%s"', home_preset_path) + os.mknod(home_preset_path) logger.info('Writing key mappings') - with open(home_path, 'w') as f: + with open(home_preset_path, 'w') as f: f.write(generate_symbols_file_content(device, preset, mappings)) @@ -153,7 +158,8 @@ def create_identity_mapping(): xkb_keycodes='\n '.join(xkb_keycodes) ) - logger.info('Creating "%s"', KEYCODES_PATH) + if not os.path.exists(KEYCODES_PATH): + logger.info('Creating "%s"', KEYCODES_PATH) with open(KEYCODES_PATH, 'w') as keycodes: keycodes.write(result) diff --git a/keymapper/paths.py b/keymapper/paths.py index 5599a1c4..da07355d 100644 --- a/keymapper/paths.py +++ b/keymapper/paths.py @@ -28,26 +28,36 @@ Is a module so that tests can modify them. import os import subprocess - -# should not contain spaces -SYMBOLS_PATH = '/usr/share/X11/xkb/symbols/key-mapper' -KEYCODES_PATH = '/usr/share/X11/xkb/keycodes/key-mapper' - # since this needs to run as sudo, # get the home dir of the user who called sudo. who = subprocess.check_output('who').decode().split()[0] + CONFIG_PATH = os.path.join('/home', who, '.config/key-mapper') +# should not contain spaces +SYMBOLS_PATH = os.path.join( + '/usr/share/X11/xkb/symbols/key-mapper', + who.replace(' ', '_') +) -def get_home_path(device, preset=''): - """Get the path to the config file in /usr.""" - return os.path.join(CONFIG_PATH, device, preset) +# those are the same for every preset and user +KEYCODES_PATH = '/usr/share/X11/xkb/keycodes/key-mapper' -def get_usr_path(device, preset=''): +def get_home_path(device, preset=None): """Get the path to the config file in /usr.""" - return os.path.join( - SYMBOLS_PATH, - device.replace(' ', '_'), - preset.replace(' ', '_') - ) + if preset is not None: + return os.path.join(CONFIG_PATH, device, preset).replace(' ', '_') + else: + return os.path.join(CONFIG_PATH, device.replace(' ', '_')) + + +def get_usr_path(device, preset=None): + """Get the path to the config file in /usr. + + If preset is omitted, returns the folder for the device. + """ + if preset is not None: + return os.path.join(SYMBOLS_PATH, device, preset).replace(' ', '_') + else: + return os.path.join(SYMBOLS_PATH, device.replace(' ', '_')) diff --git a/keymapper/presets.py b/keymapper/presets.py index 4c303809..55192ba2 100644 --- a/keymapper/presets.py +++ b/keymapper/presets.py @@ -25,7 +25,7 @@ import os import glob -from keymapper.paths import CONFIG_PATH +from keymapper.paths import CONFIG_PATH, get_home_path from keymapper.logger import logger from keymapper.linux import get_devices @@ -37,7 +37,7 @@ def get_presets(device): ---------- device : string """ - device_folder = os.path.join(CONFIG_PATH, device) + device_folder = get_home_path(device) if not os.path.exists(device_folder): os.makedirs(device_folder) presets = [ @@ -75,7 +75,7 @@ def find_newest_preset(): If no device has been configured yet, return arbitrarily. """ - # sort the oldest files to the front + # sort the oldest files to the front in order to use pop to get the newest paths = sorted( glob.glob(os.path.join(CONFIG_PATH, '*/*')), key=os.path.getmtime @@ -85,7 +85,10 @@ def find_newest_preset(): logger.debug('No presets found.') return get_any_preset() - online_devices = get_devices().keys() + online_devices = [ + device.replace(' ', '_') + for device in get_devices().keys() + ] newest_path = None while len(paths) > 0: @@ -101,6 +104,10 @@ def find_newest_preset(): logger.debug('None of the configured devices is currently online.') return get_any_preset() + # ui: no underscores, filesystem: no whitespaces + device = device and device.replace('_', ' ') + preset = preset and preset.replace('_', ' ') + logger.debug('The newest preset is "%s", "%s"', device, preset) return device, preset diff --git a/tests/testcases/presets.py b/tests/testcases/presets.py index e5c5bf7c..503c74a4 100644 --- a/tests/testcases/presets.py +++ b/tests/testcases/presets.py @@ -39,23 +39,24 @@ class TestCreatePreset(unittest.TestCase): def test_create_preset_1(self): create_preset('device 1') self.assertTrue(os.path.exists(f'{tmp}/symbols/device_1/new_preset')) - self.assertTrue(os.path.exists(f'{tmp}/.config/device 1/new preset')) + self.assertTrue(os.path.exists(f'{tmp}/.config/device_1/new_preset')) def test_create_preset_2(self): create_preset('device 1') create_preset('device 1') + print(f'{tmp}/symbols/device_1/new_preset') self.assertTrue(os.path.exists(f'{tmp}/symbols/device_1/new_preset')) - self.assertTrue(os.path.exists(f'{tmp}/.config/device 1/new preset')) + self.assertTrue(os.path.exists(f'{tmp}/.config/device_1/new_preset')) self.assertTrue(os.path.exists(f'{tmp}/symbols/device_1/new_preset_2')) - self.assertTrue(os.path.exists(f'{tmp}/.config/device 1/new preset 2')) + self.assertTrue(os.path.exists(f'{tmp}/.config/device_1/new_preset_2')) def test_create_preset_3(self): create_preset('device 1', 'pre set') create_preset('device 1', 'pre set') self.assertTrue(os.path.exists(f'{tmp}/symbols/device_1/pre_set')) - self.assertTrue(os.path.exists(f'{tmp}/.config/device 1/pre set')) + self.assertTrue(os.path.exists(f'{tmp}/.config/device_1/pre_set')) self.assertTrue(os.path.exists(f'{tmp}/symbols/device_1/pre_set_2')) - self.assertTrue(os.path.exists(f'{tmp}/.config/device 1/pre set 2')) + self.assertTrue(os.path.exists(f'{tmp}/.config/device_1/pre_set_2')) class TestFindPresets(unittest.TestCase):