[+] ruff line-length 100, add meson:install:list, bump pr34 v0.1.5.66

1. set ruff line-length to 100, reformat 18 files;
  2. move pr34 version to pyproject.common.toml, read via toml in meson.build;
  3. fix meson install_subdir to only include meson/toolchains, not entire meson/;
  4. add meson:install:list command with --mode meson|pyproject for dry-run;
  5. add .venv-whl-cache to .gitignore exceptions and .gitattributes lfs tracking;
  6. release pr34 v0.1.5.66 .whl;
  7. commit python/.venv-whl-cache and archlinux/.venv-whl-cache via lfs;
This commit is contained in:
LLM 2026-04-06 09:56:11 +00:00
parent 5e1a06a6b5
commit c2bfca5550
115 changed files with 657 additions and 755 deletions

2
.gitattributes vendored

@ -4,3 +4,5 @@ python/online/fxreader/pr34/commands_typed/archlinux/tests/res/*.db filter=lfs d
python/deps/whl/** filter=lfs diff=lfs merge=lfs -text python/deps/whl/** filter=lfs diff=lfs merge=lfs -text
docker/*/deps/whl/** filter=lfs diff=lfs merge=lfs -text docker/*/deps/whl/** filter=lfs diff=lfs merge=lfs -text
**/*.gpg filter=lfs diff=lfs merge=lfs -text **/*.gpg filter=lfs diff=lfs merge=lfs -text
python/.venv-whl-cache/** filter=lfs diff=lfs merge=lfs -text
meson/**/.venv-whl-cache/** filter=lfs diff=lfs merge=lfs -text

2
.gitignore vendored

@ -23,3 +23,5 @@ python/pyproject.toml
!docker/*/deps/whl/** !docker/*/deps/whl/**
!dotfiles/.vim !dotfiles/.vim
!python/.venv-whl-cache/**
!meson/**/.venv-whl-cache/**

BIN
python/.venv-whl-cache/annotated_doc-0.0.4-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/anyio-4.10.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/argcomplete-3.6.2-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/asgiref-3.9.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/build-1.3.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/click-8.2.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/click-8.3.2-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/django-5.2.5-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/django_stubs-5.2.2-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/fastapi-0.116.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/h11-0.16.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/idna-3.10-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/jmespath-1.1.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/markdown_it_py-4.0.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/mdurl-0.1.2-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/meson-1.9.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/meson_python-0.18.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/nodeenv-1.9.1-py2.py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/packaging-25.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/pathspec-0.12.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/pip-25.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/pybind11-3.0.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/pycparser-2.22-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/pydantic-2.12.3-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/pygments-2.20.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/pyright-1.1.407-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/python_dotenv-1.2.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/rich-14.3.3-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/setuptools-80.9.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/sniffio-1.3.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/sqlparse-0.5.3-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/starlette-0.47.3-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/toml_cli-0.8.2-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/tomlkit-0.13.3-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/tomlkit-0.14.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/tomlq-0.1.0-py2.py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/typer-0.24.1-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
python/.venv-whl-cache/uvicorn-0.35.0-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/xmltodict-0.14.2-py2.py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
python/.venv-whl-cache/yq-3.4.3-py3-none-any.whl (Stored with Git LFS) Normal file

Binary file not shown.

@ -53,10 +53,7 @@ def js(argv: list[str]) -> int:
'--project-directory', '--project-directory',
Settings.settings().project_root, Settings.settings().project_root,
'-f', '-f',
Settings.settings().project_root Settings.settings().project_root / 'docker' / 'js' / 'docker-compose.yml',
/ 'docker'
/ 'js'
/ 'docker-compose.yml',
*argv, *argv,
] ]
) )

@ -37,6 +37,7 @@ class Command(enum.Enum):
deploy_wheel = 'deploy:wheel' deploy_wheel = 'deploy:wheel'
tests = 'tests' tests = 'tests'
meson_setup = 'meson:setup' meson_setup = 'meson:setup'
meson_install_list = 'meson:install:list'
module_switch = 'module:switch' module_switch = 'module:switch'
pyrefly = 'pyrefly' pyrefly = 'pyrefly'
@ -58,12 +59,7 @@ class CLI(_cli.CLI):
self._projects: dict[str, _cli.Project] = { self._projects: dict[str, _cli.Project] = {
'online.fxreader.pr34': _cli.Project( 'online.fxreader.pr34': _cli.Project(
source_dir=self.settings.base_dir / 'python', source_dir=self.settings.base_dir / 'python',
build_dir=self.settings.base_dir build_dir=self.settings.base_dir / 'tmp' / 'online' / 'fxreader' / 'pr34' / 'build',
/ 'tmp'
/ 'online'
/ 'fxreader'
/ 'pr34'
/ 'build',
dest_dir=self.settings.base_dir dest_dir=self.settings.base_dir
/ 'tmp' / 'tmp'
/ 'online' / 'online'
@ -73,10 +69,37 @@ class CLI(_cli.CLI):
meson_path=self.settings.base_dir / 'python' / 'meson.build', meson_path=self.settings.base_dir / 'python' / 'meson.build',
), ),
'online.fxreader.pr34.commands_typed.archlinux': _cli.Project( 'online.fxreader.pr34.commands_typed.archlinux': _cli.Project(
source_dir=self.settings.base_dir / 'meson' / 'online' / 'fxreader' / 'pr34' / 'commands_typed' / 'archlinux', source_dir=self.settings.base_dir
build_dir=self.settings.base_dir / 'tmp' / 'online' / 'fxreader' / 'pr34' / 'commands_typed' / 'archlinux' / 'build', / 'meson'
dest_dir=self.settings.base_dir / 'tmp' / 'online' / 'fxreader' / 'pr34' / 'commands_typed' / 'archlinux' / 'install', / 'online'
meson_path=self.settings.base_dir / 'meson' / 'online' / 'fxreader' / 'pr34' / 'commands_typed' / 'archlinux' / 'meson.build', / 'fxreader'
/ 'pr34'
/ 'commands_typed'
/ 'archlinux',
build_dir=self.settings.base_dir
/ 'tmp'
/ 'online'
/ 'fxreader'
/ 'pr34'
/ 'commands_typed'
/ 'archlinux'
/ 'build',
dest_dir=self.settings.base_dir
/ 'tmp'
/ 'online'
/ 'fxreader'
/ 'pr34'
/ 'commands_typed'
/ 'archlinux'
/ 'install',
meson_path=self.settings.base_dir
/ 'meson'
/ 'online'
/ 'fxreader'
/ 'pr34'
/ 'commands_typed'
/ 'archlinux'
/ 'meson.build',
), ),
} }
@ -135,9 +158,7 @@ class CLI(_cli.CLI):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('command', choices=[o.value for o in Command]) parser.add_argument('command', choices=[o.value for o in Command])
parser.add_argument( parser.add_argument('-p', '--project', choices=[o for o in self.projects])
'-p', '--project', choices=[o for o in self.projects]
)
parser.add_argument( parser.add_argument(
'-o', '-o',
'--output_dir', '--output_dir',
@ -203,6 +224,13 @@ class CLI(_cli.CLI):
argv=args, argv=args,
force=options.force, force=options.force,
) )
elif options.command is Command.meson_install_list:
assert not options.project is None
self.meson_install_list(
project_name=options.project,
argv=args,
)
elif options.command is Command.mypy: elif options.command is Command.mypy:
self.mypy( self.mypy(
argv=args, argv=args,

@ -86,9 +86,7 @@ class PyProject:
third_party_roots: list[ThirdPartyRoot] = dataclasses.field( third_party_roots: list[ThirdPartyRoot] = dataclasses.field(
default_factory=lambda: [], default_factory=lambda: [],
) )
requirements: dict[str, pathlib.Path] = dataclasses.field( requirements: dict[str, pathlib.Path] = dataclasses.field(default_factory=lambda: dict())
default_factory=lambda: dict()
)
modules: list[Module] = dataclasses.field( modules: list[Module] = dataclasses.field(
default_factory=lambda: [], default_factory=lambda: [],
@ -276,9 +274,7 @@ def pyproject_load(
res.early_features = pr34_tool['early_features'] res.early_features = pr34_tool['early_features']
if 'pip_find_links' in pr34_tool: if 'pip_find_links' in pr34_tool:
res.pip_find_links = [ res.pip_find_links = [d.parent / pathlib.Path(o) for o in pr34_tool['pip_find_links']]
d.parent / pathlib.Path(o) for o in pr34_tool['pip_find_links']
]
if 'runtime_libdirs' in pr34_tool: if 'runtime_libdirs' in pr34_tool:
res.runtime_libdirs = [ res.runtime_libdirs = [
@ -297,9 +293,7 @@ def pyproject_load(
if 'third_party_roots' in pr34_tool: if 'third_party_roots' in pr34_tool:
for o in check_list(pr34_tool['third_party_roots']): for o in check_list(pr34_tool['third_party_roots']):
o2 = check_dict(o, str, str) o2 = check_dict(o, str, str)
assert all( assert all([k in {'package', 'module_root', 'path'} for k in o2])
[k in {'package', 'module_root', 'path'} for k in o2]
)
res.third_party_roots.append( res.third_party_roots.append(
PyProject.ThirdPartyRoot( PyProject.ThirdPartyRoot(
@ -313,9 +307,7 @@ def pyproject_load(
res.requirements = { res.requirements = {
k: d.parent / pathlib.Path(v) k: d.parent / pathlib.Path(v)
# pathlib.Path(o) # pathlib.Path(o)
for k, v in check_dict( for k, v in check_dict(pr34_tool['requirements'], str, str).items()
pr34_tool['requirements'], str, str
).items()
} }
if 'modules' in pr34_tool: if 'modules' in pr34_tool:
@ -382,9 +374,7 @@ class BootstrapSettings:
).strip() ).strip()
) )
pip_check_conflicts: Optional[bool] = dataclasses.field( pip_check_conflicts: Optional[bool] = dataclasses.field(
default_factory=lambda: os.environ.get( default_factory=lambda: os.environ.get('PIP_CHECK_CONFLICTS', json.dumps(True))
'PIP_CHECK_CONFLICTS', json.dumps(True)
)
in [json.dumps(True)], in [json.dumps(True)],
) )
uv_cache_dir: str = dataclasses.field( uv_cache_dir: str = dataclasses.field(
@ -399,9 +389,18 @@ class BootstrapSettings:
'--no-index -U', '--no-index -U',
).split(), ).split(),
) )
whl_cache_update: Optional[bool] = dataclasses.field(default_factory=lambda: os.environ.get('WHL_CACHE_UPDATE', json.dumps(False)) in [json.dumps(True)]) whl_cache_update: Optional[bool] = dataclasses.field(
uv_compile_allow_index: bool = dataclasses.field(default_factory=lambda: os.environ.get('UV_COMPILE_ALLOW_INDEX', json.dumps(False)) in [json.dumps(True)]) default_factory=lambda: os.environ.get('WHL_CACHE_UPDATE', json.dumps(False))
venv_partial: bool = dataclasses.field(default_factory=lambda: os.environ.get('VENV_PARTIAL', json.dumps(False)) in [json.dumps(True)]) in [json.dumps(True)]
)
uv_compile_allow_index: bool = dataclasses.field(
default_factory=lambda: os.environ.get('UV_COMPILE_ALLOW_INDEX', json.dumps(False))
in [json.dumps(True)]
)
venv_partial: bool = dataclasses.field(
default_factory=lambda: os.environ.get('VENV_PARTIAL', json.dumps(False))
in [json.dumps(True)]
)
@classmethod @classmethod
def get( def get(
@ -459,9 +458,7 @@ def requirements_name_get(
else: else:
requirements_path = source_dir / 'requirements.txt' requirements_path = source_dir / 'requirements.txt'
requirements_path_in = requirements_path.parent / ( requirements_path_in = requirements_path.parent / (requirements_path.stem + '.in')
requirements_path.stem + '.in'
)
requirements_in: list[str] = [] requirements_in: list[str] = []
@ -542,7 +539,9 @@ def whl_cache_download(
logger.info(dict(msg='downloading missing wheels', count=len(missing_reqs), pkgs=missing_reqs)) logger.info(dict(msg='downloading missing wheels', count=len(missing_reqs), pkgs=missing_reqs))
with tempfile.NamedTemporaryFile(mode='w', prefix='requirements_missing_', suffix='.txt', delete=False) as f: with tempfile.NamedTemporaryFile(
mode='w', prefix='requirements_missing_', suffix='.txt', delete=False
) as f:
f.write('\n'.join(missing_reqs)) f.write('\n'.join(missing_reqs))
f.flush() f.flush()
missing_req_path = f.name missing_req_path = f.name
@ -576,7 +575,9 @@ def check_host_prerequisites() -> None:
stderr=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
) )
except (subprocess.CalledProcessError, FileNotFoundError): except (subprocess.CalledProcessError, FileNotFoundError):
logger.error('[bootstrap] %s -m %s is not available on the host system' % (sys.executable, mod)) logger.error(
'[bootstrap] %s -m %s is not available on the host system' % (sys.executable, mod)
)
sys.exit(1) sys.exit(1)
@ -617,9 +618,7 @@ def env_bootstrap(
requirements_in: list[str] = [] requirements_in: list[str] = []
requirements_in.extend( requirements_in.extend(['uv', 'pip', 'build', 'setuptools', 'meson-python', 'pybind11'])
['uv', 'pip', 'build', 'setuptools', 'meson-python', 'pybind11']
)
if pyproject.early_features: if pyproject.early_features:
early_dependencies = sum( early_dependencies = sum(
@ -671,7 +670,9 @@ def env_bootstrap(
constraint_args: list[str] = [] constraint_args: list[str] = []
if bootstrap_settings.venv_partial and requirements_path.exists(): if bootstrap_settings.venv_partial and requirements_path.exists():
logger.info('[bootstrap] VENV_PARTIAL: recompiling with existing requirements.txt as constraints') logger.info(
'[bootstrap] VENV_PARTIAL: recompiling with existing requirements.txt as constraints'
)
needs_compile = True needs_compile = True
constraint_args = ['-c', str(requirements_path)] constraint_args = ['-c', str(requirements_path)]
@ -699,7 +700,9 @@ def env_bootstrap(
uv_compile_args = bootstrap_settings.uv_args uv_compile_args = bootstrap_settings.uv_args
if bootstrap_settings.uv_compile_allow_index: if bootstrap_settings.uv_compile_allow_index:
uv_compile_args = [o for o in uv_compile_args if o not in ('--no-index', '-U', '--upgrade')] uv_compile_args = [
o for o in uv_compile_args if o not in ('--no-index', '-U', '--upgrade')
]
if len(constraint_args) > 0: if len(constraint_args) > 0:
uv_compile_args = [o for o in uv_compile_args if o not in ('-U', '--upgrade')] uv_compile_args = [o for o in uv_compile_args if o not in ('-U', '--upgrade')]
@ -749,7 +752,11 @@ def env_bootstrap(
'uv', 'uv',
'--cache-dir', '--cache-dir',
bootstrap_settings.uv_cache_dir, bootstrap_settings.uv_cache_dir,
*[o for o in bootstrap_settings.uv_args if o not in ['-U', '--upgrade', '--no-index']], *[
o
for o in bootstrap_settings.uv_args
if o not in ['-U', '--upgrade', '--no-index']
],
'venv', 'venv',
*venv_python_version, *venv_python_version,
*cache_find_links_args, *cache_find_links_args,

@ -5,7 +5,10 @@ project(
).stdout().strip('\n'), ).stdout().strip('\n'),
# 'online.fxreader.uv', # 'online.fxreader.uv',
# ['c', 'cpp'], # ['c', 'cpp'],
version: '0.1.5.65', version: run_command(
'.venv/bin/toml', 'get', '--toml-path', 'pyproject.toml', 'project.version',
check: true
).stdout().strip('\n'),
# default_options: [ # default_options: [
# 'cpp_std=c++23', # 'cpp_std=c++23',
# # 'prefer_static=true', # # 'prefer_static=true',
@ -80,8 +83,8 @@ if mode == 'pyproject'
) )
# #
install_subdir( install_subdir(
project_root / '..' / 'meson', project_root / '..' / 'meson' / 'toolchains',
install_dir : module_root, install_dir : module_root / 'meson',
strip_directory: false, strip_directory: false,
# install_tag: 'devel', # install_tag: 'devel',
install_tag: 'devel', install_tag: 'devel',

@ -60,10 +60,7 @@ def custom_notify(
if sys.platform == 'darwin': if sys.platform == 'darwin':
osascript_translate = functools.partial( osascript_translate = functools.partial(
custom_translate, custom_translate,
check=lambda a, b: not re.compile( check=lambda a, b: not re.compile(r'^[a-zA-Z0-9\<\>\/\(\)\s\.\,\:]*$').match(b) is None,
r'^[a-zA-Z0-9\<\>\/\(\)\s\.\,\:]*$'
).match(b)
is None,
) )
subprocess.check_call( subprocess.check_call(
@ -78,9 +75,7 @@ def custom_notify(
] ]
) )
else: else:
subprocess.check_call( subprocess.check_call(['notify-send', '-t', '%d' % timeout2, title, msg[-128:]])
['notify-send', '-t', '%d' % timeout2, title, msg[-128:]]
)
class intercept_output_t: class intercept_output_t:
@ -137,8 +132,7 @@ def intercept_output(
while not (not current_subprocess.poll() is None and not last_data is None): while not (not current_subprocess.poll() is None and not last_data is None):
if ( if (
not timeout is None not timeout is None
and (datetime.datetime.now() - start_timestamp).total_seconds() and (datetime.datetime.now() - start_timestamp).total_seconds() > timeout
> timeout
): ):
break break
@ -209,9 +203,7 @@ def player_metadata() -> Optional[str]:
for k in range(20): for k in range(20):
try: try:
metadata = { metadata = {
k: subprocess.check_output(['playerctl', 'metadata', k]) k: subprocess.check_output(['playerctl', 'metadata', k]).decode('utf-8').strip()
.decode('utf-8')
.strip()
for k in ['artist', 'title'] for k in ['artist', 'title']
} }
return '%s - %s' % (metadata['artist'], metadata['title']) return '%s - %s' % (metadata['artist'], metadata['title'])
@ -233,9 +225,7 @@ def memory_stats() -> memory_stats_t.res_t:
with io.BytesIO(subprocess.check_output('free', shell=True)) as f: with io.BytesIO(subprocess.check_output('free', shell=True)) as f:
t1 = f.read().decode('utf-8').splitlines() t1 = f.read().decode('utf-8').splitlines()
mem_total = int(t1[1].strip().split()[1]) mem_total = int(t1[1].strip().split()[1])
mem_used = int(t1[1].strip().split()[2]) + int( mem_used = int(t1[1].strip().split()[2]) + int(t1[1].strip().split()[4])
t1[1].strip().split()[4]
)
return dict( return dict(
mem_total=mem_total, mem_total=mem_total,
@ -257,9 +247,7 @@ def memory_stats() -> memory_stats_t.res_t:
t1 = subprocess.check_output('vm_stat').decode('utf-8') t1 = subprocess.check_output('vm_stat').decode('utf-8')
t2 = [o.split(':') for o in t1.splitlines() if ':' in o] t2 = [o.split(':') for o in t1.splitlines() if ':' in o]
t3 = { t3 = {
o[0].replace(' ', '_').replace('-', '_').lower(): int( o[0].replace(' ', '_').replace('-', '_').lower(): int(o[1].strip().rstrip('.'))
o[1].strip().rstrip('.')
)
for o in t2 for o in t2
if len(o) == 2 if len(o) == 2
and len(o[0]) > 0 and len(o[0]) > 0
@ -400,9 +388,7 @@ def eternal_oom(argv: list[str]) -> None:
p = config[app] p = config[app]
try: try:
t1 = subprocess.check_output( t1 = subprocess.check_output(['pgrep', '-a', '-f', p[0]]).decode('utf-8')
['pgrep', '-a', '-f', p[0]]
).decode('utf-8')
except Exception: except Exception:
continue continue
t2 = t1.splitlines() t2 = t1.splitlines()
@ -519,8 +505,7 @@ def eternal_oom(argv: list[str]) -> None:
columns: dict[str, list[Any]] columns: dict[str, list[Any]]
merged_data_frame: MergedDataFrame = dict( merged_data_frame: MergedDataFrame = dict(
header=[column + '_x' for column in left] header=[column + '_x' for column in left] + [column + '_y' for column in right],
+ [column + '_y' for column in right],
columns={}, columns={},
) )
@ -528,9 +513,7 @@ def eternal_oom(argv: list[str]) -> None:
merged_data_frame['columns'][column] = [] merged_data_frame['columns'][column] = []
common_values: set[Any] = { common_values: set[Any] = {
left_value left_value for left_value in index['left'] if left_value in index['right']
for left_value in index['left']
if left_value in index['right']
} }
class RowMatch(TypedDict): class RowMatch(TypedDict):
@ -554,9 +537,7 @@ def eternal_oom(argv: list[str]) -> None:
values[ values[
common_row[ common_row[
cast( cast(
Literal[ Literal['left_row_index' | 'right_row_index'],
'left_row_index' | 'right_row_index'
],
'left_row_index' 'left_row_index'
if index_name == 'left' if index_name == 'left'
else 'right_row_index' else 'right_row_index'
@ -590,8 +571,7 @@ def eternal_oom(argv: list[str]) -> None:
)[::-1] )[::-1]
] ]
return { return {
column: [values[row_index] for row_index in t1] column: [values[row_index] for row_index in t1] for column, values in data_frame.items()
for column, values in data_frame.items()
} }
def pandas_filter_values(data_frame, condition): def pandas_filter_values(data_frame, condition):
@ -603,22 +583,14 @@ def eternal_oom(argv: list[str]) -> None:
t1 = [ t1 = [
row_index row_index
for row_index in range(shape[1]) for row_index in range(shape[1])
if condition( if condition({column: values[row_index] for column, values in data_frame.items()})
{
column: values[row_index]
for column, values in data_frame.items()
}
)
] ]
return { return {
column: [values[row_index] for row_index in t1] column: [values[row_index] for row_index in t1] for column, values in data_frame.items()
for column, values in data_frame.items()
} }
def pandas_row(data_frame, row_index): def pandas_row(data_frame, row_index):
return { return {column: values[row_index] for column, values in data_frame.items()}
column: values[row_index] for column, values in data_frame.items()
}
def pandas_shape(data_frame): def pandas_shape(data_frame):
columns_count = len(data_frame) columns_count = len(data_frame)
@ -645,9 +617,7 @@ def eternal_oom(argv: list[str]) -> None:
def oom_get_processes( def oom_get_processes(
extra_filter=None, extra_filter=None,
): ):
with io.BytesIO( with io.BytesIO(subprocess.check_output('ps -e -o pid,rss,user,%cpu', shell=True)) as f:
subprocess.check_output('ps -e -o pid,rss,user,%cpu', shell=True)
) as f:
t1 = pandas_data_frame( t1 = pandas_data_frame(
f.read().decode('utf-8').splitlines(), f.read().decode('utf-8').splitlines(),
ps_regex(4), ps_regex(4),
@ -661,11 +631,7 @@ def eternal_oom(argv: list[str]) -> None:
del t1['%CPU'] del t1['%CPU']
assert set(t1.keys()) == set(['PID', 'RSS', 'USER', 'CPU']) assert set(t1.keys()) == set(['PID', 'RSS', 'USER', 'CPU'])
t5 = ( t5 = subprocess.check_output('ps -e -o pid,args', shell=True).decode('utf-8').splitlines()
subprocess.check_output('ps -e -o pid,args', shell=True)
.decode('utf-8')
.splitlines()
)
t6 = pandas_data_frame( t6 = pandas_data_frame(
t5, t5,
r'^\s*(\d+)\s(.*)$', r'^\s*(\d+)\s(.*)$',
@ -772,9 +738,7 @@ def eternal_oom(argv: list[str]) -> None:
if t11['total_cpu'] > options.cpu_limit: if t11['total_cpu'] > options.cpu_limit:
oom_display_rows(t11['by_cpu']) oom_display_rows(t11['by_cpu'])
free_before_oom = ( free_before_oom = options.memory_limit - current_memory_stats['mem_used']
options.memory_limit - current_memory_stats['mem_used']
)
print( print(
'available %5.2f %% out of %5.2f %% of cpu limit before OOC' 'available %5.2f %% out of %5.2f %% of cpu limit before OOC'
@ -826,10 +790,7 @@ def eternal_oom(argv: list[str]) -> None:
if last_cpu_high is None: if last_cpu_high is None:
last_cpu_high = datetime.datetime.now().timestamp() last_cpu_high = datetime.datetime.now().timestamp()
if ( if datetime.datetime.now().timestamp() - last_cpu_high > options.cpu_wait:
datetime.datetime.now().timestamp() - last_cpu_high
> options.cpu_wait
):
last_cpu_high = None last_cpu_high = None
del last_total_cpu[:] del last_total_cpu[:]
return True return True
@ -852,8 +813,7 @@ def eternal_oom(argv: list[str]) -> None:
mem_used = mem_stat['mem_used'] mem_used = mem_stat['mem_used']
if options.memory_limit < mem_stat['mem_total'] and not oom_mem_high( if options.memory_limit < mem_stat['mem_total'] and not oom_mem_high(
mem_stat['mem_total'] mem_stat['mem_total'] - (mem_stat['mem_total'] - options.memory_limit) / 2
- (mem_stat['mem_total'] - options.memory_limit) / 2
): ):
extra_filters = lambda row: ( extra_filters = lambda row: (
'chrome' in row['COMMAND_y'] 'chrome' in row['COMMAND_y']
@ -901,9 +861,7 @@ def eternal_oom(argv: list[str]) -> None:
def resilient_vlc(stream=None): def resilient_vlc(stream=None):
if stream is None: if stream is None:
streams_path = os.path.join( streams_path = os.path.join(os.environ['CACHE_PATH'], 'resilient-vlc-streams.json')
os.environ['CACHE_PATH'], 'resilient-vlc-streams.json'
)
if os.path.exists(streams_path): if os.path.exists(streams_path):
with io.open(streams_path, 'r') as f: with io.open(streams_path, 'r') as f:
@ -944,9 +902,7 @@ def resilient_vlc(stream=None):
'main interface error', 'main interface error',
] ]
] ]
) and any( ) and any([o in t1 for o in ['pulse audio output debug: underflow']]):
[o in t1 for o in ['pulse audio output debug: underflow']]
):
print('shit') print('shit')
p.kill() p.kill()
while True: while True:
@ -1024,12 +980,7 @@ def eternal_firefox(
) as p: ) as p:
try: try:
if debug: if debug:
assert ( assert subprocess.check_call(['notify-send', '%s:Starting' % group_name]) == 0
subprocess.check_call(
['notify-send', '%s:Starting' % group_name]
)
== 0
)
# t3 = '' # t3 = ''
for k in range(300): for k in range(300):
@ -1114,18 +1065,10 @@ def eternal_firefox(
reposition() reposition()
if debug: if debug:
assert ( assert subprocess.check_call(['notify-send', '%s:Started' % group_name]) == 0
subprocess.check_call(
['notify-send', '%s:Started' % group_name]
)
== 0
)
start = datetime.datetime.now() start = datetime.datetime.now()
is_to_restart = ( is_to_restart = lambda: (datetime.datetime.now() - start).total_seconds() >= 900 * 4
lambda: (datetime.datetime.now() - start).total_seconds()
>= 900 * 4
)
polling_count = 0 polling_count = 0
while not is_to_restart(): while not is_to_restart():
@ -1138,12 +1081,7 @@ def eternal_firefox(
polling_count += 1 polling_count += 1
if debug: if debug:
assert ( assert subprocess.check_call(['notify-send', '%s:Closing' % group_name]) == 0
subprocess.check_call(
['notify-send', '%s:Closing' % group_name]
)
== 0
)
# assert os.system('wmctrl -i -c %s' % t2) == 0 # assert os.system('wmctrl -i -c %s' % t2) == 0
assert ( assert (
@ -1179,12 +1117,7 @@ def eternal_firefox(
pprint.pprint([p.pid, '20 seconds timeout', 'kill']) pprint.pprint([p.pid, '20 seconds timeout', 'kill'])
p.kill() p.kill()
if debug: if debug:
assert ( assert subprocess.check_call(['notify-send', '%s:Closed' % group_name]) == 0
subprocess.check_call(
['notify-send', '%s:Closed' % group_name]
)
== 0
)
def resilient_ethernet(ip_addr, ethernet_device): def resilient_ethernet(ip_addr, ethernet_device):
@ -1199,9 +1132,7 @@ do ping -c 3 -w 3 -W 1 {{IP_ADDR}} || (\
); \ ); \
sleep 10; clear; date; \ sleep 10; clear; date; \
done' done'
""".replace('{{IP_ADDR}}', ip_addr).replace( """.replace('{{IP_ADDR}}', ip_addr).replace('{{ETHERNET_DEVICE}}}', ethernet_device),
'{{ETHERNET_DEVICE}}}', ethernet_device
),
shell=True, shell=True,
) )
@ -1289,10 +1220,7 @@ def http_server(argv):
# options.host # options.host
# ]) # ])
assert options.host in sum( assert options.host in sum(
[ [[o2.local for o2 in o.addr_info] for o in commands_os.interfaces_index()],
[o2.local for o2 in o.addr_info]
for o in commands_os.interfaces_index()
],
[], [],
) )
except Exception: except Exception:
@ -1342,9 +1270,7 @@ def http_server(argv):
] ]
) )
location_section = ( location_section = ('location / {deny all;}location /%s/ {alias %s/;%s%s}') % (
'location / {deny all;}location /%s/ {alias %s/;%s%s}'
) % (
path, path,
APP_DIR, APP_DIR,
'\n'.join(['add_header %s;' % o for o in options.response_headers]), '\n'.join(['add_header %s;' % o for o in options.response_headers]),
@ -1553,8 +1479,7 @@ def pass_ssh_osx(argv):
assert len(t1) > 0 assert len(t1) > 0
print( print(
'select on of pass names\n%s' 'select on of pass names\n%s' % '\n'.join(['%d: %s' % (k, v) for k, v in enumerate(t1)])
% '\n'.join(['%d: %s' % (k, v) for k, v in enumerate(t1)])
) )
while True: while True:
@ -1619,9 +1544,7 @@ def pass_ssh_osx(argv):
p.wait(1) p.wait(1)
assert p.poll() == 0 assert p.poll() == 0
with subprocess.Popen( with subprocess.Popen(ssh_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p:
ssh_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
) as p:
password = None password = None
last_chunk = None last_chunk = None
@ -1741,9 +1664,7 @@ def vpn(argv: list[str]) -> None:
python_path: list[str] python_path: list[str]
if (pathlib.Path(__file__).parent / 'env3').exists(): if (pathlib.Path(__file__).parent / 'env3').exists():
python_path = [ python_path = [str(pathlib.Path(__file__).parent / 'env3' / 'bin' / 'python3')]
str(pathlib.Path(__file__).parent / 'env3' / 'bin' / 'python3')
]
elif (pathlib.Path(__file__).parent.parent.parent.parent / 'm').exists(): elif (pathlib.Path(__file__).parent.parent.parent.parent / 'm').exists():
python_path = [ python_path = [
str(pathlib.Path(__file__).parent.parent.parent.parent / 'm'), str(pathlib.Path(__file__).parent.parent.parent.parent / 'm'),
@ -1874,9 +1795,7 @@ def pm_service(argv):
wu = 0 wu = 0
while True: while True:
subprocess.check_call( subprocess.check_call(['osascript', '-e', 'tell application "Finder" to sleep'])
['osascript', '-e', 'tell application "Finder" to sleep']
)
subprocess.check_call( subprocess.check_call(
['pmset', 'sleepnow'], ['pmset', 'sleepnow'],
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
@ -1921,10 +1840,7 @@ def pm_service(argv):
or 'PMRD: kIOMessageSystemWillPowerOn' in cmd or 'PMRD: kIOMessageSystemWillPowerOn' in cmd
): ):
if ( if (
( ('AppleMultitouchDevice' in cmd and 'tp' in options.events)
'AppleMultitouchDevice' in cmd
and 'tp' in options.events
)
or ('AppleACPIButton' in cmd and 'pb' in options.events) or ('AppleACPIButton' in cmd and 'pb' in options.events)
or ('eventType:29' in cmd and 'kb' in options.events) or ('eventType:29' in cmd and 'kb' in options.events)
): ):
@ -1945,8 +1861,7 @@ def pm_service(argv):
) )
else: else:
print( print(
'\r%s wu : %d, la : %s' '\r%s wu : %d, la : %s' % (datetime.datetime.now().isoformat(), wu, action),
% (datetime.datetime.now().isoformat(), wu, action),
end='', end='',
) )
@ -2067,9 +1982,7 @@ def scrap_yt_music(argv: list[str]) -> None:
break break
if p is None and not current_name is None: if p is None and not current_name is None:
output_name = os.path.join( output_name = os.path.join(options.library_path, '%s.mp3' % current_name)
options.library_path, '%s.mp3' % current_name
)
logging.info('audio_record, new recording') logging.info('audio_record, new recording')
p = subprocess.Popen( p = subprocess.Popen(
['sox', '-d', output_name], ['sox', '-d', output_name],
@ -2107,9 +2020,7 @@ def scrap_yt_music(argv: list[str]) -> None:
target=functools.partial( target=functools.partial(
http_events, http_events,
context=context, context=context,
res_cb=lambda *args, **kwargs: context['http_on_event']( res_cb=lambda *args, **kwargs: context['http_on_event'](*args, **kwargs),
*args, **kwargs
),
) )
), ),
threading.Thread( threading.Thread(
@ -2124,9 +2035,7 @@ def scrap_yt_music(argv: list[str]) -> None:
def http_on_event(event, events): def http_on_event(event, events):
with context['track_cv']: with context['track_cv']:
if 'title' in event and event['title'].strip() != '': if 'title' in event and event['title'].strip() != '':
context['track_name'] = str(event['title'])[:128].replace( context['track_name'] = str(event['title'])[:128].replace('\n', '')
'\n', ''
)
else: else:
context['track_name'] = None context['track_name'] = None
@ -2374,8 +2283,7 @@ class Battery:
else: else:
pass pass
print( print(
'\r%s % 5.2f%% %s' '\r%s % 5.2f%% %s' % (datetime.datetime.now().isoformat(), t3, str(t5)),
% (datetime.datetime.now().isoformat(), t3, str(t5)),
end='', end='',
) )
except Exception: except Exception:
@ -2462,9 +2370,7 @@ def desktop_services(argv):
t2 = [] t2 = []
try: try:
t1 = subprocess.check_output( t1 = subprocess.check_output(['swaymsg', '-t', 'get_tree']).decode('utf-8')
['swaymsg', '-t', 'get_tree']
).decode('utf-8')
t2 = json.loads(t1) t2 = json.loads(t1)
except Exception: except Exception:
logging.error(traceback.format_exc()) logging.error(traceback.format_exc())
@ -2539,9 +2445,7 @@ def desktop_services(argv):
@classmethod @classmethod
def dpms_get(cls): def dpms_get(cls):
try: try:
t1 = subprocess.check_output( t1 = subprocess.check_output(['swaymsg', '-r', '-t', 'get_outputs'], timeout=1)
['swaymsg', '-r', '-t', 'get_outputs'], timeout=1
)
t2 = t1.decode('utf-8') t2 = t1.decode('utf-8')
t3 = json.loads(t2) t3 = json.loads(t2)
t4 = [ t4 = [
@ -2798,9 +2702,7 @@ def desktop_services(argv):
]: ]:
if os.path.exists('/sys/bus/platform/devices/applesmc.768'): if os.path.exists('/sys/bus/platform/devices/applesmc.768'):
return 'applesmc.768' return 'applesmc.768'
elif os.path.exists( elif os.path.exists('/sys/devices/system/cpu/intel_pstate/no_turbo'):
'/sys/devices/system/cpu/intel_pstate/no_turbo'
):
return 'intel_pstate' return 'intel_pstate'
elif os.path.exists('/sys/devices/system/cpu/amd_pstate'): elif os.path.exists('/sys/devices/system/cpu/amd_pstate'):
return 'amd_pstate' return 'amd_pstate'
@ -3059,10 +2961,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
def skip_loop_long_ago(self): def skip_loop_long_ago(self):
if ( if (
self.last_skip_loop is None self.last_skip_loop is None
or ( or (datetime.datetime.now() - self.last_skip_loop).total_seconds() >= 30
datetime.datetime.now() - self.last_skip_loop
).total_seconds()
>= 30
): ):
self.last_skip_loop = datetime.datetime.now() self.last_skip_loop = datetime.datetime.now()
return True return True
@ -3070,9 +2969,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
return False return False
def background_check(self): def background_check(self):
if ( if (self.bg is None or not self.bg.poll() is None) and not self.bg_terminate:
self.bg is None or not self.bg.poll() is None
) and not self.bg_terminate:
if not options.background_image is None: if not options.background_image is None:
self.bg = subprocess.Popen( self.bg = subprocess.Popen(
[ [
@ -3101,10 +2998,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
def force_idle(self): def force_idle(self):
if ( if (
self.last_force_idle is None self.last_force_idle is None
or ( or (datetime.datetime.now() - self.last_force_idle).total_seconds() >= 10
datetime.datetime.now() - self.last_force_idle
).total_seconds()
>= 10
): ):
self.last_force_idle = datetime.datetime.now() self.last_force_idle = datetime.datetime.now()
return True return True
@ -3150,9 +3044,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
self.data.append(chunk) self.data.append(chunk)
if b'\n' in chunk['data']: if b'\n' in chunk['data']:
total = b''.join([o['data'] for o in self.data]).decode( total = b''.join([o['data'] for o in self.data]).decode('utf-8')
'utf-8'
)
sep_pos = total.rfind('\n') sep_pos = total.rfind('\n')
lines = total[:sep_pos].splitlines() lines = total[:sep_pos].splitlines()
self.data = [ self.data = [
@ -3191,10 +3083,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
while True: while True:
logging.info('retry i = %d, cnt = %d' % (i, cnt)) logging.info('retry i = %d, cnt = %d' % (i, cnt))
if not ( if not (subprocess.call(['swaymsg', '-t', 'get_version']) == 0):
subprocess.call(['swaymsg', '-t', 'get_version'])
== 0
):
continue continue
if cb() == 0: if cb() == 0:
@ -3204,11 +3093,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
i += 1 i += 1
if ( if len(new_events) > 0 or len(self.events) > 0 and self.skip_loop_long_ago():
len(new_events) > 0
or len(self.events) > 0
and self.skip_loop_long_ago()
):
self.events.extend(new_events) self.events.extend(new_events)
skip_loop = False skip_loop = False
@ -3257,9 +3142,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
# subprocess.check_call(self.commands['lock'], shell=True) # subprocess.check_call(self.commands['lock'], shell=True)
logging.info('started t1') logging.info('started t1')
if self.force_idle(): if self.force_idle():
subprocess.check_call( subprocess.check_call(self.commands['timeout1'], shell=True)
self.commands['timeout1'], shell=True
)
logging.info('done t1') logging.info('done t1')
self.release_lock() self.release_lock()
elif o == 't2': elif o == 't2':
@ -3270,12 +3153,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
msg='loginctl lock started', msg='loginctl lock started',
) )
while True: while True:
if ( if not subprocess.call(self.commands['lock'], shell=True) == 0:
not subprocess.call(
self.commands['lock'], shell=True
)
== 0
):
continue continue
if ( if (
not subprocess.call( not subprocess.call(
@ -3302,42 +3180,24 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
elif o == 't4': elif o == 't4':
logging.info('started t4') logging.info('started t4')
if self.force_idle(): if self.force_idle():
subprocess.check_call( subprocess.check_call(self.commands['lock'], shell=True)
self.commands['lock'], shell=True subprocess.call(self.commands['timeout2'], shell=True)
) subprocess.check_call(self.commands['timeout1'], shell=True)
subprocess.call(
self.commands['timeout2'], shell=True
)
subprocess.check_call(
self.commands['timeout1'], shell=True
)
logging.info('done t4') logging.info('done t4')
self.release_lock() self.release_lock()
elif o == 't5': elif o == 't5':
logging.info('started timeout resume') logging.info('started timeout resume')
if self.force_idle(): if self.force_idle():
subprocess.check_call( subprocess.check_call(self.commands['lock'], shell=True)
self.commands['lock'], shell=True
)
retry( retry(
lambda: subprocess.call( lambda: subprocess.call(self.commands['resume'], shell=True),
self.commands['resume'], shell=True
),
) )
logging.info('done timeout resume') logging.info('done timeout resume')
elif o == 't6': elif o == 't6':
logging.info('started before-sleep') logging.info('started before-sleep')
if self.force_idle(): if self.force_idle():
( (subprocess.call(self.commands['timeout2'], shell=True),)
subprocess.call( (subprocess.check_call(self.commands['timeout1'], shell=True),)
self.commands['timeout2'], shell=True
),
)
(
subprocess.check_call(
self.commands['timeout1'], shell=True
),
)
logging.info('done before-sleep') logging.info('done before-sleep')
self.release_lock() self.release_lock()
elif o == 't7': elif o == 't7':
@ -3345,12 +3205,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
# if self.force_idle(): # if self.force_idle():
# subprocess.check_call(self.commands['lock'], shell=True) # subprocess.check_call(self.commands['lock'], shell=True)
while True: while True:
if ( if subprocess.call(self.commands['resume'], shell=True) == 0:
subprocess.call(
self.commands['resume'], shell=True
)
== 0
):
break break
else: else:
time.sleep(0.5) time.sleep(0.5)
@ -3376,13 +3231,7 @@ echo 1 | tee /sys/devices/system/cpu/cpu*/cpufreq/boost
if options.polkit_service: if options.polkit_service:
services.extend( services.extend(
[ [subprocess.Popen(['/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1'])]
subprocess.Popen(
[
'/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1'
]
)
]
) )
services.extend( services.extend(
@ -3573,9 +3422,7 @@ def gnome_shortcuts(argv: list[str]) -> None:
[ [
'gsettings', 'gsettings',
'get', 'get',
( ('org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:%s')
'org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:%s'
)
% o, % o,
k, k,
] ]
@ -3776,18 +3623,10 @@ def share_wifi(argv):
print('enter password:') print('enter password:')
pw = subprocess.check_output('read -s PW; echo -n $PW', shell=True).decode( pw = subprocess.check_output('read -s PW; echo -n $PW', shell=True).decode('utf-8')
'utf-8'
)
if len(pw) == 0: if len(pw) == 0:
pw = ( pw = subprocess.check_output('pwgen -syn 20 1', shell=True).decode('utf-8').strip()
subprocess.check_output('pwgen -syn 20 1', shell=True) with subprocess.Popen(['qrencode', '-t', 'UTF8'], stdin=subprocess.PIPE) as p:
.decode('utf-8')
.strip()
)
with subprocess.Popen(
['qrencode', '-t', 'UTF8'], stdin=subprocess.PIPE
) as p:
p.stdin.write(pw.encode('utf-8')) p.stdin.write(pw.encode('utf-8'))
p.stdin.flush() p.stdin.flush()
p.stdin.close() p.stdin.close()
@ -3854,9 +3693,7 @@ def share_wifi(argv):
if shutdown: if shutdown:
break break
if ( if (datetime.datetime.now() - last_timestamp).total_seconds() > options.restart_delay:
datetime.datetime.now() - last_timestamp
).total_seconds() > options.restart_delay:
restart = True restart = True
last_timestamp = datetime.datetime.now() last_timestamp = datetime.datetime.now()
@ -3975,14 +3812,8 @@ def media_keys(argv):
if mode == 'mocp': if mode == 'mocp':
raise NotImplementedError raise NotImplementedError
elif mode == 'playerctl': elif mode == 'playerctl':
pos = float( pos = float(subprocess.check_output(['playerctl', 'position']).decode('utf-8'))
subprocess.check_output(['playerctl', 'position']).decode( subprocess.check_call(['playerctl', 'position', '%f' % (pos - float(args[0]))])
'utf-8'
)
)
subprocess.check_call(
['playerctl', 'position', '%f' % (pos - float(args[0]))]
)
# msg = player_metadata() # msg = player_metadata()
else: else:
raise NotImplementedError raise NotImplementedError
@ -3990,14 +3821,8 @@ def media_keys(argv):
if mode == 'mocp': if mode == 'mocp':
raise NotImplementedError raise NotImplementedError
elif mode == 'playerctl': elif mode == 'playerctl':
pos = float( pos = float(subprocess.check_output(['playerctl', 'position']).decode('utf-8'))
subprocess.check_output(['playerctl', 'position']).decode( subprocess.check_call(['playerctl', 'position', '%f' % (pos + float(args[0]))])
'utf-8'
)
)
subprocess.check_call(
['playerctl', 'position', '%f' % (pos + float(args[0]))]
)
# msg = player_metadata() # msg = player_metadata()
else: else:
raise NotImplementedError raise NotImplementedError
@ -4011,13 +3836,9 @@ def media_keys(argv):
else: else:
raise NotImplementedError raise NotImplementedError
elif options.command == 'media-lower-volume': elif options.command == 'media-lower-volume':
subprocess.check_call( subprocess.check_call(['pactl', 'set-sink-volume', '@DEFAULT_SINK@', '-5%'])
['pactl', 'set-sink-volume', '@DEFAULT_SINK@', '-5%']
)
msg = ( msg = (
subprocess.check_output( subprocess.check_output(['pactl', 'get-sink-volume', '@DEFAULT_SINK@'])
['pactl', 'get-sink-volume', '@DEFAULT_SINK@']
)
.decode('utf-8') .decode('utf-8')
.strip() .strip()
) )
@ -4031,20 +3852,14 @@ def media_keys(argv):
] ]
) )
msg = ( msg = (
subprocess.check_output( subprocess.check_output(['pactl', 'get-sink-volume', '@DEFAULT_SINK@'])
['pactl', 'get-sink-volume', '@DEFAULT_SINK@']
)
.decode('utf-8') .decode('utf-8')
.strip() .strip()
) )
elif options.command == 'media-raise-volume': elif options.command == 'media-raise-volume':
subprocess.check_call( subprocess.check_call(['pactl', 'set-sink-volume', '@DEFAULT_SINK@', '+5%'])
['pactl', 'set-sink-volume', '@DEFAULT_SINK@', '+5%']
)
msg = ( msg = (
subprocess.check_output( subprocess.check_output(['pactl', 'get-sink-volume', '@DEFAULT_SINK@'])
['pactl', 'get-sink-volume', '@DEFAULT_SINK@']
)
.decode('utf-8') .decode('utf-8')
.strip() .strip()
) )
@ -4120,9 +3935,7 @@ def install(argv: list[str]) -> None:
final_target = options.target / relative_source final_target = options.target / relative_source
logger.info( logger.info(dict(final_target=final_target, relative_source=relative_source))
dict(final_target=final_target, relative_source=relative_source)
)
if final_target.exists(): if final_target.exists():
if not options.overwrite: if not options.overwrite:

@ -224,9 +224,7 @@ class CLI(abc.ABC):
self.projects[project].source_dir / 'pyproject.toml' self.projects[project].source_dir / 'pyproject.toml'
) )
dependencies = sum( dependencies = sum([pyproject.dependencies[o] for o in features], cast(list[str], []))
[pyproject.dependencies[o] for o in features], cast(list[str], [])
)
pip_find_links: list[pathlib.Path] = [] pip_find_links: list[pathlib.Path] = []
@ -268,9 +266,7 @@ class CLI(abc.ABC):
force: bool, force: bool,
) -> None: ) -> None:
for k, d in self.dependencies.items(): for k, d in self.dependencies.items():
whl_glob = self.dist_settings.wheel_dir / ( whl_glob = self.dist_settings.wheel_dir / ('*%s*.whl' % d.name.replace('.', '_'))
'*%s*.whl' % d.name.replace('.', '_')
)
if len(glob.glob(str(whl_glob))) == 0 or force: if len(glob.glob(str(whl_glob))) == 0 or force:
if d.source_path.exists(): if d.source_path.exists():
@ -310,9 +306,7 @@ class CLI(abc.ABC):
def index_get(o: dict[str, Any]) -> tuple[Any, ...]: def index_get(o: dict[str, Any]) -> tuple[Any, ...]:
return (o['path'], o['stat']) return (o['path'], o['stat'])
present_files_index = { present_files_index = {index_get(o): o for o in present_files}
index_get(o): o for o in present_files
}
new_files: list[dict[str, Any]] = [] new_files: list[dict[str, Any]] = []
@ -351,13 +345,7 @@ class CLI(abc.ABC):
[ [
pathlib.Path(o) pathlib.Path(o)
for o in glob.glob( for o in glob.glob(
str( str(self.dist_settings.env_path / 'lib' / 'python*' / '**' / 'pkgconfig'),
self.dist_settings.env_path
/ 'lib'
/ 'python*'
/ '**'
/ 'pkgconfig'
),
recursive=True, recursive=True,
) )
] ]
@ -481,12 +469,7 @@ class CLI(abc.ABC):
'-Csetup-args=%s' '-Csetup-args=%s'
% ( % (
'-Dthird_party_roots=%s' '-Dthird_party_roots=%s'
% json.dumps( % json.dumps([str(o.absolute()) for o in self.third_party_roots(project_name)])
[
str(o.absolute())
for o in self.third_party_roots(project_name)
]
)
) )
) )
@ -523,14 +506,21 @@ class CLI(abc.ABC):
from . import cli_bootstrap from . import cli_bootstrap
pyproject = cli_bootstrap.pyproject_load(project.source_dir / 'pyproject.toml') pyproject = cli_bootstrap.pyproject_load(project.source_dir / 'pyproject.toml')
whl_name_prefix = (pyproject.name or project_name).replace('.', '_').replace('-', '_') whl_name_prefix = (
(pyproject.name or project_name).replace('.', '_').replace('-', '_')
)
whl_name_prefix += '-' + pyproject.version if pyproject.version else '' whl_name_prefix += '-' + pyproject.version if pyproject.version else ''
conflicting = [o for o in glob.glob(str(pathlib.Path(output_dir) / '*.whl')) if pathlib.Path(o).name.startswith(whl_name_prefix + '-')] conflicting = [
o
for o in glob.glob(str(pathlib.Path(output_dir) / '*.whl'))
if pathlib.Path(o).name.startswith(whl_name_prefix + '-')
]
if len(conflicting) > 0: if len(conflicting) > 0:
raise FileExistsError( raise FileExistsError(
'wheel(s) already exist in %s: %s. Use --force-whl-overwrite to overwrite.' % (output_dir, [pathlib.Path(o).name for o in conflicting]) 'wheel(s) already exist in %s: %s. Use --force-whl-overwrite to overwrite.'
% (output_dir, [pathlib.Path(o).name for o in conflicting])
) )
logger.info(dict(env=env, cmd=cmd)) logger.info(dict(env=env, cmd=cmd))
@ -551,6 +541,44 @@ class CLI(abc.ABC):
] ]
) )
def meson_install_list(
self,
project_name: str,
argv: Optional[list[str]] = None,
) -> None:
from . import argparse as pr34_argparse
project = self.projects[project_name]
parser = argparse.ArgumentParser()
parser.add_argument(
'--mode',
choices=['meson', 'pyproject'],
default='meson',
)
options, rest = pr34_argparse.parse_args(parser, argv)
cmd = [
str(self.dist_settings.python_path),
'-m',
'mesonbuild.mesonmain',
'install',
'-C',
str(project.build_dir / options.mode),
'--destdir',
str(project.dest_dir),
'--dry-run',
*rest,
]
logger.info(dict(cmd=cmd))
subprocess.check_call(
cmd,
env=self.make_env(),
)
def meson_install( def meson_install(
self, self,
project_name: str, project_name: str,
@ -574,21 +602,11 @@ class CLI(abc.ABC):
preserve_top_path=True, preserve_top_path=True,
) )
pyproject = cli_bootstrap.pyproject_load( pyproject = cli_bootstrap.pyproject_load(project.source_dir / 'pyproject.toml')
project.source_dir / 'pyproject.toml'
)
pyproject_tool = ( pyproject_tool = pydantic.RootModel[PyProject.Tool].model_validate(pyproject.tool).root
pydantic.RootModel[PyProject.Tool]
.model_validate(pyproject.tool)
.root
)
if ( if pyproject_tool.meson and pyproject_tool.meson.args and pyproject_tool.meson.args.install:
pyproject_tool.meson
and pyproject_tool.meson.args
and pyproject_tool.meson.args.install
):
argv = pyproject_tool.meson.args.install + argv argv = pyproject_tool.meson.args.install + argv
cmd = [ cmd = [
@ -633,9 +651,7 @@ class CLI(abc.ABC):
content = f.read() content = f.read()
with io.open(o, 'w') as f: with io.open(o, 'w') as f:
f.write( f.write(content.replace('prefix=/', 'prefix=${pcfiledir}/../../'))
content.replace('prefix=/', 'prefix=${pcfiledir}/../../')
)
def ninja( def ninja(
self, self,
@ -736,8 +752,8 @@ class CLI(abc.ABC):
for third_party_root in pyproject.third_party_roots: for third_party_root in pyproject.third_party_roots:
if third_party_root.package: if third_party_root.package:
if not third_party_root.module_root: if not third_party_root.module_root:
third_party_root.module_root = ( third_party_root.module_root = third_party_root.package.replace(
third_party_root.package.replace('.', os.path.sep) '.', os.path.sep
) )
if not third_party_root.path: if not third_party_root.path:
packages = pip_show([third_party_root.package]) packages = pip_show([third_party_root.package])
@ -771,9 +787,7 @@ class CLI(abc.ABC):
def meson_toolchains( def meson_toolchains(
self, self,
) -> dict[str, meson_toolchains_t.res_t.toolchain_t]: ) -> dict[str, meson_toolchains_t.res_t.toolchain_t]:
t1 = pathlib.Path( t1 = pathlib.Path(importlib.import_module('online.fxreader.pr34').__path__[0])
importlib.import_module('online.fxreader.pr34').__path__[0]
)
toolchains = glob.glob(str(t1 / 'meson' / 'toolchains' / '*')) toolchains = glob.glob(str(t1 / 'meson' / 'toolchains' / '*'))
res: dict[str, CLI.meson_toolchains_t.res_t.toolchain_t] = dict() res: dict[str, CLI.meson_toolchains_t.res_t.toolchain_t] = dict()
@ -798,11 +812,7 @@ class CLI(abc.ABC):
) -> list[str]: ) -> list[str]:
from . import argparse as pr34_argparse from . import argparse as pr34_argparse
if ( if pyproject_tool.meson and pyproject_tool.meson.args and pyproject_tool.meson.args.setup:
pyproject_tool.meson
and pyproject_tool.meson.args
and pyproject_tool.meson.args.setup
):
extra_args = pyproject_tool.meson.args.setup + extra_args extra_args = pyproject_tool.meson.args.setup + extra_args
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -821,9 +831,7 @@ class CLI(abc.ABC):
not options.cross_file.is_absolute() not options.cross_file.is_absolute()
and options.cross_file.stem in self.meson_toolchains and options.cross_file.stem in self.meson_toolchains
): ):
options.cross_file = self.meson_toolchains[ options.cross_file = self.meson_toolchains[options.cross_file.stem].path
options.cross_file.stem
].path
extra_args = ['--cross-file', str(options.cross_file)] + args extra_args = ['--cross-file', str(options.cross_file)] + args
@ -852,15 +860,9 @@ class CLI(abc.ABC):
if env is None: if env is None:
env = dict() env = dict()
pyproject = cli_bootstrap.pyproject_load( pyproject = cli_bootstrap.pyproject_load(project.source_dir / 'pyproject.toml')
project.source_dir / 'pyproject.toml'
)
pyproject_tool = ( pyproject_tool = pydantic.RootModel[PyProject.Tool].model_validate(pyproject.tool).root
pydantic.RootModel[PyProject.Tool]
.model_validate(pyproject.tool)
.root
)
logger.info(dict(env=env)) logger.info(dict(env=env))
@ -884,12 +886,7 @@ class CLI(abc.ABC):
if len(self.third_party_roots(project_name)) > 0: if len(self.third_party_roots(project_name)) > 0:
extra_args.append( extra_args.append(
'-Dthird_party_roots=%s' '-Dthird_party_roots=%s'
% json.dumps( % json.dumps([str(o.absolute()) for o in self.third_party_roots(project_name)])
[
str(o.absolute())
for o in self.third_party_roots(project_name)
]
)
) )
cmd = [ cmd = [
@ -955,9 +952,7 @@ class CLI(abc.ABC):
argv, argv,
) )
pyproject = cli_bootstrap.pyproject_load( pyproject = cli_bootstrap.pyproject_load(project.source_dir / 'pyproject.toml')
project.source_dir / 'pyproject.toml'
)
dependencies = sum( dependencies = sum(
[pyproject.dependencies[o] for o in options.features], [pyproject.dependencies[o] for o in options.features],
@ -967,9 +962,7 @@ class CLI(abc.ABC):
pip_find_links: list[pathlib.Path] = [] pip_find_links: list[pathlib.Path] = []
if not pyproject.pip_find_links is None: if not pyproject.pip_find_links is None:
pip_find_links.extend( pip_find_links.extend([o for o in pyproject.pip_find_links if o.exists()])
[o for o in pyproject.pip_find_links if o.exists()]
)
requirements_name_get_res = cli_bootstrap.requirements_name_get( requirements_name_get_res = cli_bootstrap.requirements_name_get(
source_dir=project.source_dir, source_dir=project.source_dir,
@ -1078,9 +1071,7 @@ class CLI(abc.ABC):
assert options.module in [o.name for o in pyproject.modules] assert options.module in [o.name for o in pyproject.modules]
modules: dict[str, cli_bootstrap.PyProject.Module] = { modules: dict[str, cli_bootstrap.PyProject.Module] = {o.name: o for o in pyproject.modules}
o.name: o for o in pyproject.modules
}
module = modules[options.module] module = modules[options.module]

Some files were not shown because too many files have changed in this diff Show More