Example #1
0
    def save(self, path):
        """Dump as JSON into home."""
        logger.info('Saving preset to %s', path)

        touch(path)

        with open(path, 'w') as file:
            if self._config.get('mapping') is not None:
                logger.error(
                    '"mapping" is reserved and cannot be used as config key')
            preset_dict = self._config

            # make sure to keep the option to add metadata if ever needed,
            # so put the mapping into a special key
            json_ready_mapping = {}
            # tuple keys are not possible in json, encode them as string
            for key, value in self._mapping.items():
                new_key = '+'.join([
                    ','.join([str(value) for value in sub_key])
                    for sub_key in key
                ])
                json_ready_mapping[new_key] = value

            preset_dict['mapping'] = json_ready_mapping
            json.dump(preset_dict, file, indent=4)
            file.write('\n')

        self.changed = False
Example #2
0
    def populate(self):
        """Get a mapping of all available names to their keycodes."""
        logger.debug('Gathering available keycodes')
        self.clear()
        xmodmap_dict = {}
        try:
            xmodmap = subprocess.check_output(
                ['xmodmap', '-pke'], stderr=subprocess.STDOUT).decode()
            xmodmap = xmodmap
            self._xmodmap = re.findall(r'(\d+) = (.+)\n', xmodmap + '\n')
            xmodmap_dict = self._find_legit_mappings()
        except (subprocess.CalledProcessError, FileNotFoundError):
            # might be within a tty
            pass

        if USER != 'root':
            # write this stuff into the key-mapper config directory, because
            # the systemd service won't know the user sessions xmodmap
            path = get_config_path(XMODMAP_FILENAME)
            touch(path)
            with open(path, 'w') as file:
                logger.debug('Writing "%s"', path)
                json.dump(xmodmap_dict, file, indent=4)

        for name, code in xmodmap_dict.items():
            self._set(name, code)

        for name, ecode in evdev.ecodes.ecodes.items():
            if name.startswith('KEY') or name.startswith('BTN'):
                self._set(name, ecode)

        self._set(DISABLE_NAME, DISABLE_CODE)
Example #3
0
    def test_save_load(self):
        self.assertEqual(len(config.iterate_autoload_presets()), 0)

        config.load_config()
        self.assertEqual(len(config.iterate_autoload_presets()), 0)

        config.set_autoload_preset('d1', 'a')
        config.set_autoload_preset('d2.foo', 'b')
        config.save_config()

        # ignored after load
        config.set_autoload_preset('d3', 'c')

        config.load_config()
        self.assertListEqual(list(config.iterate_autoload_presets()),
                             [('d1', 'a'), ('d2.foo', 'b')])

        config_2 = os.path.join(tmp, 'config_2.json')
        touch(config_2)
        with open(config_2, 'w') as f:
            f.write('{"a":"b"}')

        config.load_config(config_2)
        self.assertEqual(config.get("a"), "b")
        self.assertEqual(config.get(["a"]), "b")
Example #4
0
    def save_config(self):
        """Save the config to the file system."""
        touch(self.path)

        with open(self.path, 'w') as file:
            json.dump(self._config, file, indent=4)
            logger.info('Saved config to %s', self.path)
            shutil.chown(self.path, USER, USER)
            file.write('\n')
Example #5
0
 def test_migrate(self):
     old = os.path.join(CONFIG_PATH, 'config')
     new = os.path.join(CONFIG_PATH, 'config.json')
     os.remove(new)
     touch(old)
     with open(old, 'w') as f:
         f.write('{}')
     GlobalConfig()
     self.assertTrue(os.path.exists(new))
     self.assertFalse(os.path.exists(old))
Example #6
0
    def save_config(self):
        """Save the config to the file system."""
        if USER == 'root':
            logger.debug('Skipping config file creation for the root user')
            return

        touch(self.path)

        with open(self.path, 'w') as file:
            json.dump(self._config, file, indent=4)
            logger.info('Saved config to %s', self.path)
            file.write('\n')
Example #7
0
    def populate(self):
        """Get a mapping of all available names to their keycodes."""
        logger.debug('Gathering available keycodes')
        self.clear()
        xmodmap_dict = {}
        try:
            xmodmap = subprocess.check_output(['xmodmap', '-pke']).decode()
            xmodmap = xmodmap.lower()
            mappings = re.findall(r'(\d+) = (.+)\n', xmodmap + '\n')
            for keycode, names in mappings:
                # there might be multiple, like:
                # keycode  64 = Alt_L Meta_L Alt_L Meta_L
                # keycode 204 = NoSymbol Alt_L NoSymbol Alt_L
                # Alt_L should map to code 64. Writing code 204 only works
                # if a modifier is applied at the same time. So take the first
                # one.
                name = names.split()[0]
                xmodmap_dict[name] = int(keycode) - XKB_KEYCODE_OFFSET

            for keycode, names in mappings:
                # but since KP may be mapped like KP_Home KP_7 KP_Home KP_7,
                # make another pass and add all of them if they don't already
                # exist. don't overwrite any keycodes.
                for name in names.split():
                    if xmodmap_dict.get(name) is None:
                        xmodmap_dict[name] = int(keycode) - XKB_KEYCODE_OFFSET
        except (subprocess.CalledProcessError, FileNotFoundError):
            # might be within a tty
            pass

        if USER != 'root':
            # write this stuff into the key-mapper config directory, because
            # the systemd service won't know the user sessions xmodmap
            path = get_config_path(XMODMAP_FILENAME)
            touch(path)
            with open(path, 'w') as file:
                logger.info('Writing "%s"', path)
                json.dump(xmodmap_dict, file, indent=4)

        self._mapping.update(xmodmap_dict)

        for name, ecode in evdev.ecodes.ecodes.items():
            if name.startswith('KEY') or name.startswith('BTN'):
                self._set(name, ecode)

        self._set(DISABLE_NAME, DISABLE_CODE)
Example #8
0
    def test_migrate(self):
        if os.path.exists(tmp):
            shutil.rmtree(tmp)

        touch(os.path.join(tmp, 'foo1', 'bar1.json'))
        touch(os.path.join(tmp, 'foo2', 'bar2.json'))

        migrate_path()

        self.assertFalse(os.path.exists(os.path.join(tmp, 'foo1',
                                                     'bar1.json')))
        self.assertFalse(os.path.exists(os.path.join(tmp, 'foo2',
                                                     'bar2.json')))

        self.assertTrue(
            os.path.exists(os.path.join(tmp, 'presets', 'foo1', 'bar1.json')))
        self.assertTrue(
            os.path.exists(os.path.join(tmp, 'presets', 'foo2', 'bar2.json')))
Example #9
0
    def test_get_available_preset_name(self):
        # no filename conflict
        self.assertEqual(get_available_preset_name('_', 'qux 2'), 'qux 2')

        touch(get_preset_path('_', 'qux 5'))
        self.assertEqual(get_available_preset_name('_', 'qux 5'), 'qux 6')
        touch(get_preset_path('_', 'qux'))
        self.assertEqual(get_available_preset_name('_', 'qux'), 'qux 2')
        touch(get_preset_path('_', 'qux1'))
        self.assertEqual(get_available_preset_name('_', 'qux1'), 'qux1 2')
        touch(get_preset_path('_', 'qux 2 3'))
        self.assertEqual(get_available_preset_name('_', 'qux 2 3'), 'qux 2 4')

        touch(get_preset_path('_', 'qux 5'))
        self.assertEqual(get_available_preset_name('_', 'qux 5', True),
                         'qux 5 copy')
        touch(get_preset_path('_', 'qux 5 copy'))
        self.assertEqual(get_available_preset_name('_', 'qux 5', True),
                         'qux 5 copy 2')
        touch(get_preset_path('_', 'qux 5 copy 2'))
        self.assertEqual(get_available_preset_name('_', 'qux 5', True),
                         'qux 5 copy 3')

        touch(get_preset_path('_', 'qux 5copy'))
        self.assertEqual(get_available_preset_name('_', 'qux 5copy', True),
                         'qux 5copy copy')
        touch(get_preset_path('_', 'qux 5copy 2'))
        self.assertEqual(get_available_preset_name('_', 'qux 5copy 2', True),
                         'qux 5copy 2 copy')
        touch(get_preset_path('_', 'qux 5copy 2 copy'))
        self.assertEqual(
            get_available_preset_name('_', 'qux 5copy 2 copy', True),
            'qux 5copy 2 copy 2')
Example #10
0
 def test_touch(self):
     touch('/tmp/a/b/c/d/e')
     self.assertTrue(os.path.exists('/tmp/a/b/c/d/e'))
     self.assertTrue(os.path.isfile('/tmp/a/b/c/d/e'))
     self.assertRaises(ValueError, lambda: touch('/tmp/a/b/c/d/f/'))