Пример #1
0
def main():
    package_cfg = a2util.json_read(join(A2PATH, 'package.json'))
    package_name = f'a2 {PACKAGE_SUB_NAME} {package_cfg["version"]}'
    print('\n{0} finishing: {1} ... {0}'.format(15 * '#', package_name))

    distroot = join(A2PATH, '_ package')
    distpath = join(distroot, 'a2')
    distlib = join(distpath, 'lib')
    distui = join(distpath, 'ui')
    a2lib = join(A2PATH, 'lib')

    if not os.path.isdir(distpath):
        raise FileNotFoundError('No Package found at "%s"!' % distpath)

    update_readme(a2lib)

    copy_files(distpath, distlib, a2lib, distui)

    config_file = join(distlib, 'a2_config.ahk')
    a2ahk.set_variable(config_file, 'a2_title', package_name)

    with open(join(distpath, 'desktop.ini'), 'w') as file_obj:
        file_obj.write(DESKTOP_INI_CODE)

    print('{0} {1} finished! {0}\n'.format(18 * '#', package_name))
Пример #2
0
def diff_digest(distpath, digest_path):
    """Return True if there is no difference"""
    if not os.path.isfile(digest_path):
        print('diff_digest: no digest yet!')
        return False

    current_map = a2util.json_read(digest_path)
    for dir_path, _, files in os.walk(distpath):
        this_map = current_map.get(dir_path, ())
        if len(files) != len(this_map):
            print('diff_digest: num files diff: %s' % dir_path)
            return False

        for item in files:
            item_path = os.path.join(dir_path, item)
            if item not in this_map:
                print('diff_digest: new file! %s' % item_path)
                return False

            if this_map[item]['mtime'] != os.path.getmtime(item_path):
                print('diff_digest: mtime diff! %s' % item_path)
                return False
            if this_map[item]['size'] != os.path.getsize(item_path):
                print('diff_digest: size diff! %s' % item_path)
                return False
    print('diff_digest: No differences!!')
    return True
Пример #3
0
def main():
    package_cfg = a2util.json_read(join(A2PATH, 'package.json'))
    package_name = f'a2 {PACKAGE_SUB_NAME} {package_cfg["version"]}'
    print('\n{0} finishing: {1} ... {0}'.format(15 * '#', package_name))

    distroot = join(A2PATH, '_ package')
    distpath = join(distroot, 'a2')
    distlib = join(distpath, 'lib')
    distui = join(distpath, 'ui')
    a2lib = join(A2PATH, 'lib')

    if not os.path.isdir(distpath):
        raise FileNotFoundError('No Package found at "%s"!' % distpath)

    update_readme(a2lib)

    copy_files(distpath, distlib, a2lib, distui)

    config_file = join(distlib, 'a2_config.ahk')
    a2ahk.set_variable(config_file, 'a2_title', package_name)

    with open(join(distpath, 'desktop.ini'), 'w') as file_obj:
        file_obj.write(DESKTOP_INI_CODE)

    print('{0} {1} finished! {0}\n'.format(18 * '#', package_name))
Пример #4
0
 def get_config(self):
     if self.has_config_file:
         try:
             self._config = a2util.json_read(self.config_file)
             return self._config
         except Exception as error:
             log.error('config exists but could not be loaded!: '
                       '%s\nerror: %s' % (self.config_file, error))
     self._config = []
     return self._config
Пример #5
0
 def get_config(self):
     if self.has_config_file:
         try:
             self._config = a2util.json_read(self.config_file)
             return self._config
         except Exception as error:
             log.error('config exists but could not be loaded!: '
                       '%s\nerror: %s' % (self.config_file, error))
     self._config = []
     return self._config
def main(a2, mod):
    """
    :param a2: Main A2 object instance.
    :param mod: Current a2 module instance.
    """
    print('Import Hotstrings ... %s' % __name__)

    from PySide2 import QtWidgets

    file_path, _ = QtWidgets.QFileDialog.getOpenFileName(
        None, 'Import Hotstrings Data', a2.paths.a2, '(*.ahk *.json)')

    if not file_path:
        return

    import os
    import a2util
    import pprint
    import hotstrings_io
    name = 'hotstrings'
    base, ext = os.path.splitext(file_path)
    ext = ext.lower()
    if ext == '.ahk':
        hs_input = hotstrings_io.file_to_dict(file_path)
    elif ext == '.json':
        hs_input = a2util.json_read(file_path)

    hs_current = mod.get_user_cfg()[name]
    hs_collisions = {}
    for mode, scope, hstring, hs_cfg in hotstrings_io.iterate(hs_input):
        if mode == '':
            if hstring not in hs_current.get('', {}):
                target = hs_current
            else:
                target = hs_collisions
            target.setdefault('', {})[hstring] = hs_cfg
        else:
            if hstring not in hs_current.get(mode, {}).get(scope, {}):
                target = hs_current
            else:
                target = hs_collisions
            target.setdefault(mode, {}).setdefault(scope, {})[hstring] = hs_cfg

    mod.set_user_cfg({'name': name}, hs_current)
    a2.win.load_runtime_and_ui()
    a2.win.check_element(name)

    if hs_collisions:
        print('There were collisions:\n%s' % pprint.pformat(hs_collisions))
        backup_path = base + '_collisions.json'
        a2util.json_write(backup_path, hs_collisions)
        a2util.explore(backup_path)
Пример #7
0
def main(a2, mod):
    """
    :param a2: Main A2 object instance.
    :param mod: Current a2 module instance.
    """
    print('Import Hotstrings ... %s' % __name__)

    from PySide2 import QtWidgets

    file_path, _ = QtWidgets.QFileDialog.getOpenFileName(
        None, 'Import Hotstrings Data', a2.paths.a2, '(*.ahk *.json)')

    if not file_path:
        return

    import os
    import a2util
    import pprint
    import hotstrings_io
    name = 'hotstrings'
    base, ext = os.path.splitext(file_path)
    ext = ext.lower()
    if ext == '.ahk':
        hs_input = hotstrings_io.file_to_dict(file_path)
    elif ext == '.json':
        hs_input = a2util.json_read(file_path)

    hs_current = mod.get_user_cfg()[name]
    hs_collisions = {}
    for mode, scope, hstring, hs_cfg in hotstrings_io.iterate(hs_input):
        if mode == '':
            if hstring not in hs_current.get('', {}):
                target = hs_current
            else:
                target = hs_collisions
            target.setdefault('', {})[hstring] = hs_cfg
        else:
            if hstring not in hs_current.get(mode, {}).get(scope, {}):
                target = hs_current
            else:
                target = hs_collisions
            target.setdefault(mode, {}).setdefault(scope, {})[hstring] = hs_cfg

    mod.set_user_cfg({'name': name}, hs_current)
    a2.win.load_runtime_and_ui()
    a2.win.check_element(name)

    if hs_collisions:
        print('There were collisions:\n%s' % pprint.pformat(hs_collisions))
        backup_path = base + '_collisions.json'
        a2util.json_write(backup_path, hs_collisions)
        a2util.explore(backup_path)
Пример #8
0
    def build_add_source_menu(self):
        icons = a2ctrl.Icons.inst()
        menu = self.add_source_menu

        menu.clear()
        menu.addAction(icons.folder_add, 'Create Local', self.main.create_local_source)
        menu.addAction(icons.cloud_download, 'Add From URL', self.add_source_url)

        featured_path = os.path.join(self.a2.paths.defaults, 'featured_packages.json')
        featured_packages = a2util.json_read(featured_path)
        available = set(featured_packages).difference(self.a2.module_sources)
        if available:
            submenu = menu.addMenu('Featured:')
            for pack_name in available:
                action = submenu.addAction(icons.file_download, pack_name, self.on_add_featured)
                action.setData(featured_packages[pack_name])
        menu.popup(QtGui.QCursor.pos())
Пример #9
0
def _get_remote_data(url):
    url = url.lower().strip()
    if url.startswith('http') or 'github.com/' in url:
        if 'github.com/' in url:
            owner, repo = _get_github_owner_repo(url)
            download_url = '/'.join(
                ['https://raw.githubusercontent.com', owner, repo, 'master'])
        else:
            download_url = url

        if not download_url.endswith(MOD_SOURCE_NAME):
            download_url = _add_slash(download_url)
            download_url += MOD_SOURCE_NAME

        from urllib import request
        try:
            data = request.urlopen(download_url).read()
        except request.HTTPError as error:
            raise RuntimeError(
                'Could not find a2 package data at given address!\n%s' % error)

        try:
            data = data.decode(encoding='utf-8-sig')
        except Exception as error:
            log.error(error)
            raise RuntimeError('Error decoding data from given address!:\n%s' %
                               error)

        try:
            remote_data = json.loads(data)
        except Exception as error:
            log.error(error)
            raise RuntimeError('Error loading JSON from given address!:\n%s' %
                               error)

    else:
        if os.path.exists(url):
            _, base = os.path.split(url)
            if base.lower() != MOD_SOURCE_NAME:
                url = os.path.join(url, MOD_SOURCE_NAME)
            remote_data = a2util.json_read(url)
        else:
            raise FileNotFoundError()
    return remote_data
Пример #10
0
    def config(self):
        try:
            # to serve from memory most of the times, only from disk after timeout
            now = time.time()
            if self._cfg_fetched is None or now - self._cfg_fetched > STALE_CONFIG_TIMEOUT:
                self._cfg_fetched = now
                self._last_config = a2util.json_read(self.config_file)
                self._config_load_error = None
            return self._last_config

        except FileNotFoundError:
            self._config_load_error = MSG_NO_CFG_FILE

        except Exception as error:
            msg = ('Error loading config file for "%s" (%s)\n'
                   '  %s' % (self.name, self.config_file, error))
            self._config_load_error = msg
            log.error(msg)
        return {}
Пример #11
0
    def config(self):
        try:
            # to serve from memory most of the times, only from disk after timeout
            now = time.time()
            if self._cfg_fetched is None or now - self._cfg_fetched > STALE_CONFIG_TIMEOUT:
                self._cfg_fetched = now
                self._last_config = a2util.json_read(self.config_file)
                self._config_load_error = None
            return self._last_config

        except FileNotFoundError:
            self._config_load_error = MSG_NO_CFG_FILE

        except Exception as error:
            msg = ('Error loading config file for "%s" (%s)\n'
                   '  %s' % (self.name, self.config_file, error))
            self._config_load_error = msg
            log.error(msg)
        return {}
Пример #12
0
    def build_add_source_menu(self):
        icons = a2ctrl.Icons.inst()
        menu = self.add_source_menu

        menu.clear()
        menu.addAction(icons.folder_add, 'Create Local',
                       self.main.create_local_source)
        menu.addAction(icons.cloud_download, 'Add From URL',
                       self.add_source_url)

        featured_path = os.path.join(self.a2.paths.defaults,
                                     'featured_packages.json')
        featured_packages = a2util.json_read(featured_path)
        available = set(featured_packages).difference(self.a2.module_sources)
        if available:
            submenu = menu.addMenu('Featured:')
            for pack_name in available:
                action = submenu.addAction(icons.file_download, pack_name,
                                           self.on_add_featured)
                action.setData(featured_packages[pack_name])
        menu.popup(QtGui.QCursor.pos())
Пример #13
0
def _get_remote_data(url):
    url = url.lower().strip()
    if url.startswith('http') or 'github.com/' in url:
        if 'github.com/' in url:
            owner, repo = _get_github_owner_repo(url)
            download_url = '/'.join(['https://raw.githubusercontent.com', owner, repo, 'master'])
        else:
            download_url = url

        if not download_url.endswith(MOD_SOURCE_NAME):
            download_url = _add_slash(download_url)
            download_url += MOD_SOURCE_NAME

        from urllib import request
        try:
            data = request.urlopen(download_url).read()
        except request.HTTPError as error:
            raise RuntimeError('Could not find a2 package data at given address!\n%s' % error)

        try:
            data = data.decode(encoding='utf-8-sig')
        except Exception as error:
            log.error(error)
            raise RuntimeError('Error decoding data from given address!:\n%s' % error)

        try:
            remote_data = json.loads(data)
        except Exception as error:
            log.error(error)
            raise RuntimeError('Error loading JSON from given address!:\n%s' % error)

    else:
        if os.path.exists(url):
            _, base = os.path.split(url)
            if base.lower() != MOD_SOURCE_NAME:
                url = os.path.join(url, MOD_SOURCE_NAME)
            remote_data = a2util.json_read(url)
        else:
            raise FileNotFoundError()
    return remote_data
Пример #14
0
def main():
    package_cfg = a2util.json_read(join(A2PATH, 'package.json'))
    package_name = f'a2 {PACKAGE_SUB_NAME} {package_cfg["version"]}'
    print('\n{0} building installer: {1} ... {0}'.format(15 * '#', package_name))

    distroot = join(A2PATH, '_ package')
    distpath = join(distroot, 'a2')
    source_path = join(A2PATH, 'lib', '_source')

    sfx_path = join(source_path, SRC_SFX)
    if not os.path.isfile(sfx_path):
        raise FileNotFoundError('SFX file "%s" is missing!' % sfx_path)

    sfx_trg = join(distroot, SRC_SFX)
    if os.path.isfile(sfx_trg):
        os.unlink(sfx_trg)
    print('copying fresh sfx file ...')
    copy2(sfx_path, sfx_trg)

    rcedit = join(source_path, RCEDIT_EXE)
    if not os.path.isfile(rcedit):
        raise FileNotFoundError('rcedit "%s" is missing!' % rcedit)

    version_string = check_version(package_cfg['version'])
    version_label = (version_string if not PACKAGE_SUB_NAME else
                     version_string + ' ' + PACKAGE_SUB_NAME)

    manifest_trg = update_manifest(source_path, version_string, distroot)

    set_file_version(rcedit, sfx_trg, version_label)
    set_product_version(rcedit, sfx_trg, version_label)
    apply_manifest(rcedit, manifest_trg, sfx_trg)

    print('writing installer config file ...')
    with open(join(distroot, 'config.txt'), 'w') as file_obj:
        file_obj.write(INSTALLER_CFG)

    check_installer_script_executable(source_path, distpath)

    pack_installer_archive(source_path, distroot, distpath)
Пример #15
0
def check_installer_script_executable(source_path, distpath):
    script_path = os.path.join(source_path, 'a2_installer.ahk')
    if not os.path.isfile(script_path):
        raise FileNotFoundError('installer_script missing! %s' % script_path)

    json_path = os.path.join(os.environ['TEMP'], TMP_NAME, 'script_time.json')
    setup_exe = os.path.join(distpath, 'setup.exe')
    current_time = os.path.getmtime(script_path)

    if not os.path.isfile(setup_exe) or not os.path.isfile(json_path):
        print('check_installer_script_executable: Creating setup_exe!')
        _rebuild_installer_script_executable(script_path, setup_exe)
        a2util.json_write(json_path, current_time)
        return
    else:
        script_time = a2util.json_read(json_path)
        if script_time != current_time:
            print('check_installer_script_executable: Script Changed!')
            _rebuild_installer_script_executable(script_path, setup_exe)
            a2util.json_write(json_path, current_time)
            return
    print('check_installer_script_executable: Nice Nothing to-do!!')
Пример #16
0
    def refresh_style(self):
        try:
            css_values = self.a2.win.style.get_value_dict()
        except AttributeError:
            return

        scale = css_values['scale']
        values = a2util.json_read(os.path.join(_HERE, 'style_values.json'))
        # scale values for current screen, skipping the ones with "_*"
        for key, value in values.items():
            if not key.startswith('_'):
                values[key] = value * scale
        # calculating some more values
        values['color'] = css_values['color_yellow']
        values['color_button'] = css_values['color_button']
        values['font_size'] = css_values['font_size'] * values['_font_size_factor']
        values['font_size_small'] = css_values['font_size'] * values['_small_font_factor']
        values['long_key'] = values['key_height'] * 2 + values['small_spacing']
        values['wide_key'] = values['key_width'] * 2 + values['small_spacing']

        self.ui.keys_layout.setSpacing(values['big_spacing'])
        self.ui.main_layout.setSpacing(values['small_spacing'])
        self.cursor_block_widget.set_spacing(values['small_spacing'])
        self.mouse_block_widget.set_spacing(values['small_spacing'])

        main_css = load_css('main') % values
        self.ui.keys_widget.setStyleSheet(main_css)

        cursor_block_css = load_css('cursorblock') % values
        self.cursor_block_widget.setStyleSheet(cursor_block_css)
        self.numpad_block_widget.setStyleSheet(cursor_block_css)

        border_tmp = 'border: %.1fpx %%s %%s;' % css_values['border_radius']
        self._ui_styles['default'] = border_tmp % ('solid', css_values['color_button'])
        self._ui_styles['a2_button'] = border_tmp % ('solid', css_values['color_yellow'])
        self._ui_styles['win_button'] = border_tmp % ('solid', css_values['color_blue'])
        self._ui_styles['orig_button'] = border_tmp % ('dotted', css_values['color_yellow'])
Пример #17
0
def win_standard_keys():
    global _WIN_STANDARD_KEYS
    if not _WIN_STANDARD_KEYS:
        _WIN_STANDARD_KEYS = a2util.json_read(
            os.path.join(_HERE, WIN_STANDARD_FILE))
    return _WIN_STANDARD_KEYS
Пример #18
0
def get_default_package_cfg():
    a2 = a2core.A2Obj.inst()
    cfg = a2util.json_read(os.path.join(a2.paths.defaults, 'default_package.json'))
    return cfg
Пример #19
0
def iterate():
    for keyboard_id, label in a2util.json_read(os.path.join(
            THIS_DIR, CFG_FILE)).items():
        path = os.path.join(THIS_DIR, keyboard_id + '.py')
        if os.path.isfile(path):
            yield keyboard_id, label
Пример #20
0
def get_default_package_cfg():
    a2 = a2core.A2Obj.inst()
    cfg = a2util.json_read(
        os.path.join(a2.paths.defaults, 'default_package.json'))
    return cfg
Пример #21
0
 def load_style(self, style_name):
     template_path = os.path.join(STYLE_PATH, style_name, DEFAULTS_NAME)
     self.defaults = a2util.json_read(template_path)
     with open(os.path.join(STYLE_PATH, style_name, TEMPLATE_NAME)) as fobj:
         self.template = fobj.read()
Пример #22
0
 def load_style(self, style_name):
     template_path = os.path.join(STYLE_PATH, style_name, DEFAULTS_NAME)
     self.defaults = a2util.json_read(template_path)
     with open(os.path.join(STYLE_PATH, style_name, TEMPLATE_NAME)) as fobj:
         self.template = fobj.read()