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))
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
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)
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())
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
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 {}
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
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)
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!!')
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'])
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
def get_default_package_cfg(): a2 = a2core.A2Obj.inst() cfg = a2util.json_read(os.path.join(a2.paths.defaults, 'default_package.json')) return cfg
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
def get_default_package_cfg(): a2 = a2core.A2Obj.inst() cfg = a2util.json_read( os.path.join(a2.paths.defaults, 'default_package.json')) return cfg
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()