def test_run_multiple_forms(self): # needs more details from kivy.garden.formmanager import FormManager, Form fm = FormManager() self._fm_instance = fm fm.run() tmpdir = mkdtemp() for i in range(3): tmp_form = join(tmpdir, 'form{}.py'.format(i + 1)) form_name = split_ext(basename(abspath(tmp_form)))[0] with open(tmp_form, 'w') as f: f.write(self.form_template.format(form_name.capitalize())) form = Form(tmp_form) fm.add_form(form) fm.run_form(form) # Form application is basically another Kivy app run in # a separate process, therefore we have to wait for it to load sleep(3) self.assertTrue(fm.forms[form.name]['active']) # remove form test? fm.kill() rmtree(tmpdir)
def test_name(self): from kivy.garden.formmanager import Form tmpfd, tmpfn = mkstemp('.py') FormTestCase._tmpfiles.append([tmpfd, tmpfn]) form = Form(tmpfn) self.assertEqual(form.name, split_ext(basename(abspath(tmpfn)))[0])
def gen_bins(*, bin_dst_dir:str) -> None: errSL('bin_dst_dir:', bin_dst_dir) assert bin_dst_dir.startswith('/'), bin_dst_dir py_path = path_join(bin_dst_dir, 'python3') for src_dir in bin_src_dirs: for name in listdir(src_dir): stem, ext = split_ext(name) if stem[0] in '._' or ext != '.py': continue path = path_join(bin_dst_dir, stem.replace('_', '-')) # Omit extension from bin name. module = path_join(src_dir, stem).replace('/', '.') errSL(f'generating script for {module}: {path}') with open(path, 'w') as f: f.write(bin_template.format(py_path=py_path, module=module)) chmod(f.fileno(), 0o755)
def __init__(self, source=None, kb_name='rdflib_test', sqlize=True): """Initialize the KnowledgeFile. Arguments: source (str): Path to the knowledge base. If None, an in-memory knowledge base will be created. Defaults to None. kb_name (str): The name of the knowledge base. This must match the name used to create the knowledge base, if the source is an rdfsqlite file. Defaults to 'rdflib_test'. sqlize (bool): Whether to create a sqlite version of the knowledge base for faster future access. Defaults to True. Raises: FileNotFoundError: If the specified source is not found. ValueError: If the format of the source cannot be determined. """ super().__init__() ident = URIRef(kb_name) store = plugin.get('SQLAlchemy', Store)(identifier=ident) self.graph = Graph(store, identifier=ident) if source is None: self.graph.open(Literal('sqlite://')) return source = realpath(expanduser(source)) if not file_exists(source): raise FileNotFoundError(source) filepath, ext = split_ext(source) rdf_format = guess_format(source) if rdf_format is not None: # FIXME need to add prefix definitions for other formats preamble = '' if rdf_format == 'n3': preamble = '\n'.join( f'@prefix {prefix}: <{url}>.' for prefix, url in Value.NAMESPACES.items() if url != '_') with open(source) as fd: data = fd.read() if preamble: data = preamble + '\n' + data if sqlize: sql_uri = 'sqlite:///' + filepath + '.rdfsqlite' else: sql_uri = 'sqlite://' self.graph.open(Literal(sql_uri), create=True) self.graph.parse(data=data, format=rdf_format) elif ext[1:] in ['db', 'sqlite', 'rdfsqlite']: sql_uri = 'sqlite:///' + source self.graph.open(Literal(sql_uri)) else: raise ValueError('Cannot determine format of {}'.format(source))
def generate_coverage(): coverage_directory = 'target/coverage/tests' run_command('rm', '-rf', coverage_directory) run_command('mkdir', '-p', coverage_directory) for path, directories, files in walk('.'): # If this is the top-level of a rust project if 'Cargo.toml' in files: for directory in ('src', 'examples', 'target', '.git', 'tests'): try: directories.remove(directory) except ValueError: continue # If `src` is somehow missing from the top, skip this directory source = join(path, 'src') if not exists(source): continue command = ('kcov', '--verify', f'--include-path={source}', coverage_directory) # Get unit tests for executable_name in executable_names(path): latest_build = find_latest_test_build(executable_name) if latest_build: run_command(*command, latest_build) break # Get all the integration tests try: # TODO: Unfortunately Cargo does not use any sort of hierarchy # or namespacing, which means if two members (or in fact # the root) of a workspace have files or directories with # the same name in their `tests` directories then those # are going to be compiled at the same level under the # same name in the shared `target` directory but with # different _hash_ suffixes -- which makes it impossible # to differentiate between them. This means that for now # `rustcov` will associate only one of the binaries with # the correct source all the others will mismatch for test in list_dir(join(path, 'tests')): latest_build = find_latest_test_build(split_ext(test)[0]) run_command(*command, latest_build) except FileNotFoundError: continue run_command('kcov', '--merge', 'target/coverage', coverage_directory) run_command('rm', '-rf', coverage_directory)
def generate_thumbnail_name(self, raw_name, thumb_name, size): """ Return a thumbnail file path like:: `path/to/thumb_name-raw_name-sizes[0]xsizes[1].jpg` """ filepath, filename = split_path(raw_name) fn, ext = split_ext(filename) thumbnail_filename = "%s-%s-%sx%s%s" % (thumb_name, fn, size[0], size[1], ext) # join path and new filename thumbnail_full_path = join_path(filepath, thumbnail_filename) return thumbnail_full_path
def generate_thumbnail_name(self, raw_name, thumb_name, size): """ Return a thumbnail file path like:: `path/to/thumb_name-raw_name-sizes[0]xsizes[1].jpg` """ filepath, filename = split_path(raw_name) fn, ext = split_ext(filename) thumbnail_filename = "%s-%s-%sx%s%s" % ( thumb_name, fn, size[0], size[1], ext) # join path and new filename thumbnail_full_path = join_path(filepath, thumbnail_filename) return thumbnail_full_path
def test_run_form_request_action(self): from kivy.garden.formmanager import FormManager, Form, FormManagerException fm = FormManager() self._fm_instance = fm fm.run() # request action on non-existing Form with self.assertRaises(FormManagerException): fm.request_action('form4', 'print', 'nope') self.assertEqual(fm.queue, {}) tmpdir = mkdtemp() tmp_form = join(tmpdir, 'form4.py') form_name = split_ext(basename(abspath(tmp_form)))[0] with open(tmp_form, 'w') as f: f.write(self.form_template.format(form_name.capitalize())) form = Form(tmp_form) fm.add_form(form) fm.run_form(form) # Form application is basically another Kivy app run in # a separate process, therefore we have to wait for it to load sleep(2) self.assertTrue(fm.forms[form.name]['active']) # request action for Form1 fm.request_action('form4', 'print', 'test') self.assertEqual(fm.queue, {'form4': [['print', 'test']]}) sleep(1) # after request the action is popped, # but Form remains in the queue as a key self.assertEqual(fm.queue, {"form4": []}) # after the Form is removed, the key should too fm.remove_form(form) self.assertNotIn(form.name, fm.forms) self.assertEqual(fm.queue, {}) fm.kill() rmtree(tmpdir)
def __init__(self, source=None, kb_name='rdflib_test', sqlize=True): """Initialize the KnowledgeFile. Arguments: source (str): Path to the knowledge base. If None, an in-memory knowledge base will be created. Defaults to None. kb_name (str): The name of the knowledge base. This must match the name used to create the knowledge base, if the source is an rdfsqlite file. Defaults to 'rdflib_test'. sqlize (bool): Whether to create a sqlite version of the knowledge base for faster future access. Defaults to True. Raises: FileNotFoundError: If the specified source is not found. ValueError: If the format of the source cannot be determined. """ super().__init__() ident = URIRef(kb_name) store = plugin.get('SQLAlchemy', Store)(identifier=ident) self.graph = Graph(store, identifier=ident) if source is None: self.graph.open(Literal('sqlite://')) return source = realpath(expanduser(source)) if not file_exists(source): raise FileNotFoundError(source) filepath, ext = split_ext(source) rdf_format = guess_format(source) if rdf_format is not None: if sqlize: sql_uri = 'sqlite:///' + filepath + '.rdfsqlite' else: sql_uri = 'sqlite://' self.graph.open(Literal(sql_uri), create=True) self.graph.parse(source, format=rdf_format) elif ext[1:] in ['db', 'sqlite', 'rdfsqlite']: sql_uri = 'sqlite:///' + source self.graph.open(Literal(sql_uri)) else: raise ValueError('Cannot determine format of {}'.format(source))
def load_ids(dir, langs): if not langs: langs = LANGS # root bsnlp/sample_pl_cs_ru_bg/raw/cs # filename brexit_cs.txt_file_100.txt for root, subdirs, filenames in walk(dir): tail, lang = split_path(root) if lang not in langs: continue tail, type = split_path(tail) if type not in (ANNOTATED, RAW): # raw/nord_stream/ru/nord_stream_ru.txt_file_44.txt tail, type = split_path(tail) assert type in (ANNOTATED, RAW), root for filename in filenames: name, ext = split_ext(filename) if ext not in (TXT, OUT): continue path = join_path(root, filename) yield BsnlpId(lang, type, name, path)
def load_menu_data(source, desktop_dirs, lang_id, conditions): """The main menu loader function. Call this.""" import time programs = {} menus = {} categories = {} category_index = [] # -------------------------------------------------------------------------- # Step 1: Parse inputs total_start = time.clock() start_time = total_start logger.info('Have {0} sources for menu data'.format(len(source))) for n, s in enumerate(source): try: if s[0] == 'f': logger.info('load_menu_data(): loading a file "{0}" for ' 'locale "{1}"...'.format(s[1], lang_id)) p, m, c = __parse_yml_file(s[1], lang_id, conditions) elif s[0] == 's': logger.info('load_menu_data(): loading a string for ' 'locale "{0}"...'.format(lang_id)) p, m, c = __parse_yml_string(s[1], lang_id, conditions) else: logger.error('Source type "{0}" is not valid, skipping'.format( s[0])) continue except Exception as e: if s[0] == 'f': logger.error( 'Could not load source file {0} ("{1}"): {2}'.format( n + 1, s[1], str(e))) else: logger.error('Could not load source string {0}: {1}'.format( n + 1, str(e))) logger.traceback(traceback.format_exc()) continue # IDs must be unique within a file, but not across files; a file # loaded later can overwrite/replace earlier definitions. This is # by design. programs.update(p) menus.update(m) categories.update(c) # Remove missing and/or invalid entries. We've reserved their IDs, # but we couldn't load them. programs = {k: v for k, v in programs.items() if programs[k] is not None} menus = {k: v for k, v in menus.items() if menus[k] is not None} categories = { k: v for k, v in categories.items() if categories[k] is not None } end_time = time.clock() logger.print_time('YAML loading time', start_time, end_time) # -------------------------------------------------------------------------- # Step 2: Load the .desktop files for desktop programs start_time = time.clock() if __is_empty(desktop_dirs): logger.warn('No .desktop file search paths specified!') for i in programs: p = programs[i] if p.hidden or p.type != PROGRAM_TYPE_DESKTOP: continue # Locate the .desktop file dd_name = None for d in desktop_dirs: full = path_join(d, p.name + '.desktop') if is_file(full): dd_name = full break if dd_name is None: logger.error('.desktop file for "{0}" not found'.format(p.name)) p.missing_desktop = True continue p.original_desktop_file = p.name + '.desktop' # Try to load it try: desktop_data = __load_dotdesktop_file(dd_name) except Exception as e: logger.error('Could not load file "{0}": {1}'.format( dd_name, str(e))) logger.traceback(traceback.format_exc()) p.missing_desktop = True continue if 'Desktop Entry' not in desktop_data: logger.error('Can\'t load "{0}" for "{1}": No [Desktop Entry] ' 'section in the file'.format(dd_name, i)) p.missing_desktop = True continue entry = desktop_data['Desktop Entry'] # Try to load the parts that we don't have yet from it if p.title is None: key = 'Name[' + lang_id + ']' if key in entry: # The best case: we have a localized name p.title = entry[key] else: # "Name" and "GenericName" aren't interchangeable, but this # is the best we can do. For example, if "Name" is "Mozilla", # then "GenericName" could be "Web Browser". key = 'GenericName[' + lang_id + ']' if key in entry: p.title = entry[key] else: # Last resort #logger.warn('Have to use "Name" entry for program "{0}"'. # format(p.name)) p.title = entry.get('Name', '') if __is_empty(p.title): logger.error( 'Empty name for program "{0}", program ignored'.format( p.name)) p.missing_desktop = True continue if p.description is None: key = 'Comment[' + lang_id + ']' # Accept *ONLY* localized comments if key in entry: p.description = entry[key] if __is_empty(p.description): logger.warn('Empty comment specified for program "{0}" in ' 'the .desktop file "{1}"'.format( p.name, dd_name)) p.comment = None if __is_empty(p.keywords): key = 'Keywords[' + lang_id + ']' # Accept *ONLY* localized keyword strings if key in entry: p.keywords = list(filter(None, entry[key].split(";"))) if p.icon is None: if 'Icon' not in entry: logger.warn('Program "{0}" has no icon defined for it in the ' '.desktop file "{1}"'.format(p.name, dd_name)) else: p.icon = entry.get('Icon', '') if __is_empty(p.icon): logger.warn('Program "{0}" has an empty/invalid icon name, will ' 'display incorrectly'.format(p.name)) p.icon = None if p.command is None: if 'Exec' not in entry or __is_empty(entry['Exec']): logger.warn( 'Program "{0}" has an empty or missing "Exec" ' 'line in the desktop file "{1}", program ignored'.format( p.name, dd_name)) p.missing_desktop = True continue # Remove %XX parameters from the Exec key in the same way # Webmenu does it. It has worked fine for Webmenu, maybe # it works fine for us too...? # (Reference: file parts/webmenu/src/parseExec.coffee, line 24) import re p.command = re.sub(r"%[fFuUdDnNickvm]{1}", "", entry['Exec']) # Detect icon types for i in programs: p = programs[i] if p.hidden or p.icon is None: continue # Is the icon name a full path to an icon file, or just # a generic name? _, ext = split_ext(p.icon) if not __is_empty(ext) and ext in ICON_EXTENSIONS: p.icon_is_path = True end_time = time.clock() logger.print_time('Desktop file parsing', start_time, end_time) # -------------------------------------------------------------------------- # Step 3: Convert textual references into actual object references and # build the final menu data. Also mark used programs and menus while # we're at it. start_time = time.clock() for m in menus: menu = menus[m] if menu.hidden: continue new_programs = [] for p in menu.programs: if p in programs: if programs[p].missing_desktop: # Silently ignore desktop programs with missing # .desktop files. continue if not programs[p].hidden: new_programs.append(programs[p]) programs[p].used = True else: logger.error('Menu "{0}" references to a non-existent ' 'program "{1}"'.format(m, p)) menu.programs = new_programs for c in categories: cat = categories[c] if cat.hidden: continue new_menus = [] new_programs = [] for m in cat.menus: if m in menus: if not menus[m].hidden: new_menus.append(menus[m]) menus[m].used = True else: logger.error('Category "{0}" references to a non-existent ' 'menu "{1}"'.format(c, m)) for p in cat.programs: if p in programs: if programs[p].missing_desktop: # silently ignore desktop programs with missing # .desktop files continue if not programs[p].hidden: new_programs.append(programs[p]) programs[p].used = True else: logger.error('Category "{0}" references to a non-existent ' 'program "{1}"'.format(c, p)) cat.menus = new_menus cat.programs = new_programs # Remove desktop prorgams with .desktop files that could not be loaded. # This is done here so that we don't complain about "missing" programs # above when trying to find programs with broken .desktop files. These # programs exist, they just cannot be used. programs = { k: v for k, v in programs.items() if not programs[k].missing_desktop } # Warn about unused (and unhidden) programs, they just take up resources num_used_programs = 0 num_used_menus = 0 num_used_categories = 0 for i in programs: p = programs[i] if not p.hidden and not p.used: logger.warn('Program "{0}" defined but not used'.format(p.name)) if p.used and not p.hidden: num_used_programs += 1 for i in menus: m = menus[i] if not m.hidden and not m.used: logger.warn('Menu "{0}" defined but not used'.format(m.name)) if m.used and not m.hidden: num_used_menus += 1 for i in categories: c = categories[i] if not c.hidden: num_used_categories += 1 # Finally remove all hidden items programs = {k: v for k, v in programs.items() if not programs[k].hidden} menus = {k: v for k, v in menus.items() if not menus[k].hidden} categories = { k: v for k, v in categories.items() if not categories[k].hidden } # -------------------------------------------------------------------------- # Step 4: Sort the categories # Sort the categories by position, but if the positions are identical, # sort by names. Warning: the sort is not locale-aware or case # insensitive! index = [] for i in categories: c = categories[i] if not c.hidden: index.append((c.position, c.name, i)) index.sort(key=lambda c: (c[0], c[1])) # only IDs are used from hereon for c in index: category_index.append(c[1]) end_time = time.clock() logger.print_time('Menu data building time', start_time, end_time) # -------------------------------------------------------------------------- # Done logger.info('Have {n_progs} programs ({n_used_progs} actually used), ' '{n_menus} menus ({n_used_menus} actually used) and ' '{n_cats} categories ({n_used_cats} actually used)'.format( n_progs=len(programs), n_used_progs=num_used_programs, n_menus=len(menus), n_used_menus=num_used_menus, n_cats=len(categories), n_used_cats=num_used_categories)) end_time = time.clock() logger.print_time('Total menu parsing time', total_start, end_time) return programs, menus, categories, category_index
def path_ext(path): return split_ext(path)[1].lower()
def __init__(self, form_file, timeout=0.5): self.manager = FormManager.get_manager() self.__name, ext = split_ext( basename(abspath(form_file)) ) self.__path = abspath(form_file)