feat: add various system and theme icons, configuration files, and support assets

This commit is contained in:
jschantli committed 2026-10-03 08:14:42 -07:00
1 parent 848dac4264
commit 54baea79f4
15893 files changed
+781426 -2

No files matched your search

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+249
View File
@@ -0,0 +1,249 @@
#!/usr/bin/perl
# WARNING: do not edit!
# Generated by Makefile from ../tools/c_rehash.in
# Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
# Perl c_rehash script, scan all files in a directory
# and add symbolic links to their hash values.
my $dir = "/usr/lib/ssl";
my $prefix = "/usr";
my $errorcount = 0;
my $openssl = $ENV{OPENSSL} || "openssl";
my $pwd;
my $verbose = 0;
my $symlink_exists=eval {symlink("",""); 1};
my $removelinks = 1;
## Parse flags.
while ( $ARGV[0] =~ /^-/ ) {
my $flag = shift @ARGV;
last if ( $flag eq '--');
if ( $flag eq '-h' || $flag eq '-help' ) {
help();
} elsif ( $flag eq '-n' ) {
$removelinks = 0;
} elsif ( $flag eq '-v' ) {
$verbose++;
}
else {
print STDERR "Usage error; try -h.\n";
exit 1;
}
}
sub help {
print "Usage: c_rehash [-old] [-h] [-help] [-v] [dirs...]\n";
print " -old use old-style digest\n";
print " -h or -help print this help text\n";
print " -v print files removed and linked\n";
exit 0;
}
eval "require Cwd";
if (defined(&Cwd::getcwd)) {
$pwd=Cwd::getcwd();
} else {
$pwd=`pwd`;
chomp($pwd);
}
# DOS/Win32 or Unix delimiter? Prefix our installdir, then search.
my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':';
$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : "");
if (! -x $openssl) {
my $found = 0;
foreach (split /$path_delim/, $ENV{PATH}) {
if (-x "$_/$openssl") {
$found = 1;
$openssl = "$_/$openssl";
last;
}
}
if ($found == 0) {
print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
exit 0;
}
}
if (@ARGV) {
@dirlist = @ARGV;
} elsif ($ENV{SSL_CERT_DIR}) {
@dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
} else {
$dirlist[0] = "$dir/certs";
}
if (-d $dirlist[0]) {
chdir $dirlist[0];
$openssl="$pwd/$openssl" if (!-x $openssl);
chdir $pwd;
}
foreach (@dirlist) {
if (-d $_ ) {
if ( -w $_) {
hash_dir($_);
} else {
print "Skipping $_, can't write\n";
$errorcount++;
}
}
}
exit($errorcount);
sub copy_file {
my ($src_fname, $dst_fname) = @_;
if (open(my $in, "<", $src_fname)) {
if (open(my $out, ">", $dst_fname)) {
print $out $_ while (<$in>);
close $out;
} else {
warn "Cannot open $dst_fname for write, $!";
}
close $in;
} else {
warn "Cannot open $src_fname for read, $!";
}
}
sub hash_dir {
my $dir = shift;
my %hashlist;
print "Doing $dir\n";
if (!chdir $dir) {
print STDERR "WARNING: Cannot chdir to '$dir', $!\n";
return;
}
opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n";
my @flist = sort readdir(DIR);
closedir DIR;
if ( $removelinks ) {
# Delete any existing symbolic links
foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
if (-l $_) {
print "unlink $_\n" if $verbose;
unlink $_ || warn "Can't unlink $_, $!\n";
}
}
}
FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
# Check to see if certificates and/or CRLs present.
my ($cert, $crl) = check_file($fname);
if (!$cert && !$crl) {
print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
next;
}
link_hash_cert($fname) if ($cert);
link_hash_crl($fname) if ($crl);
}
chdir $pwd;
}
sub check_file {
my ($is_cert, $is_crl) = (0,0);
my $fname = $_[0];
open(my $in, "<", $fname);
while(<$in>) {
if (/^-----BEGIN (.*)-----/) {
my $hdr = $1;
if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
$is_cert = 1;
last if ($is_crl);
} elsif ($hdr eq "X509 CRL") {
$is_crl = 1;
last if ($is_cert);
}
}
}
close $in;
return ($is_cert, $is_crl);
}
sub compute_hash {
my $fh;
if ( $^O eq "VMS" ) {
# VMS uses the open through shell
# The file names are safe there and list form is unsupported
if (!open($fh, "-|", join(' ', @_))) {
print STDERR "Cannot compute hash on '$fname'\n";
return;
}
} else {
if (!open($fh, "-|", @_)) {
print STDERR "Cannot compute hash on '$fname'\n";
return;
}
}
return (<$fh>, <$fh>);
}
# Link a certificate to its subject name hash value, each hash is of
# the form <hash>.<n> where n is an integer. If the hash value already exists
# then we need to up the value of n, unless its a duplicate in which
# case we skip the link. We check for duplicates by comparing the
# certificate fingerprints
sub link_hash_cert {
link_hash($_[0], 'cert', '-subject_hash');
link_hash($_[0], 'cert', '-subject_hash_old');
}
# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
sub link_hash_crl {
link_hash($_[0], 'crl', '-hash');
link_hash($_[0], 'crl', '-hash_old');
}
sub link_hash {
my ($fname, $type, $hash_name) = @_;
my $is_cert = $type eq 'cert' or $type eq 'cert_old';
my ($hash, $fprint) = compute_hash($openssl,
$is_cert ? "x509" : "crl",
$hash_name,
"-fingerprint", "-noout",
"-in", $fname);
chomp $hash;
$hash =~ s/^.*=// if !$is_cert;
chomp $fprint;
return if !$hash;
$fprint =~ s/^.*=//;
$fprint =~ tr/://d;
my $suffix = 0;
# Search for an unused hash filename
my $crlmark = $is_cert ? "" : "r";
while(exists $hashlist{"$hash.$crlmark$suffix"}) {
# Hash matches: if fingerprint matches its a duplicate cert
if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) {
my $what = $is_cert ? 'certificate' : 'CRL';
print STDERR "WARNING: Skipping duplicate $what $fname\n";
return;
}
$suffix++;
}
$hash .= ".$crlmark$suffix";
if ($symlink_exists) {
print "link $fname -> $hash\n" if $verbose;
symlink $fname, $hash || warn "Can't symlink, $!";
} else {
print "copy $fname -> $hash\n" if $verbose;
copy_file($fname, $hash);
}
$hashlist{$hash} = $fprint;
}
+1
View File
@@ -0,0 +1 @@
chardetect
+8
View File
@@ -0,0 +1,8 @@
#! usr/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from chardet.cli.chardetect import main
if __name__ == "__main__":
sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0])
sys.exit(main())
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
../lib/x86_64-linux-gnu/glib-2.0/gio-querymodules
+1
View File
@@ -0,0 +1 @@
../lib/x86_64-linux-gnu/glib-2.0/glib-compile-schemas
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
setarch
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
last
+1
View File
@@ -0,0 +1 @@
setarch
+1
View File
@@ -0,0 +1 @@
setarch
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
export PYTHONPATH="${APPDIR}/usr/share/mhwmm:${PYTHONPATH}"
exec python3 -m mhwmm "$@"
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
pdb3.12
+1
View File
@@ -0,0 +1 @@
../lib/python3.12/pdb.py
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
pgrep
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+210
View File
@@ -0,0 +1,210 @@
#! usr/bin/python3
# vim: et ts=4 sw=4
# Copyright © 2010-2012 Piotr Ożarowski <piotr@debian.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import logging
import optparse
import sys
# glob1() is not in the public documentation, UTSL.
from glob import glob1
from os import environ, remove, rmdir
from os.path import dirname, basename, exists, join, splitext
sys.path.insert(1, '/usr/share/python3/')
from debpython import files as dpf
from debpython.interpreter import Interpreter
from debpython.version import SUPPORTED, getver, vrepr
# initialize script
logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: '
'%(message)s')
log = logging.getLogger(__name__)
"""TODO: move it to manpage
Examples:
py3clean -p python3-mako # all .py[co] files and __pycache__ directories from the package
py3clean /usr/lib/python3.1/dist-packages # python3.1
py3clean -V 3.3 /usr/lib/python3/ # python 3.3 only
py3clean -V 3.3 /usr/lib/foo/bar.py # bar/__pycache__/bar.cpython-33.py[co]
py3clean /usr/lib/python3/ # all Python 3.X
"""
def get_magic_tag_to_remove(version):
"""Returns magic tag or True if all of them should be removed."""
i = Interpreter('python')
map_ = {}
for v in SUPPORTED:
try:
map_[v] = i.magic_tag(v)
except Exception:
log.debug('magic tag for %s not recognized', vrepr(v), exc_info=True)
if version not in map_:
try:
map_[version] = i.magic_tag(version)
except Exception as e:
log.error('cannot find magic tag for Python %s: %s', vrepr(version), e)
exit(4)
tag = map_[version]
# skip shared tags
for v, t in map_.items():
if v == version:
continue
if t == tag:
log.info('magic tag(s) used by python%s. Nothing to remove.',
vrepr(v))
exit(0)
log.debug('magic tags to remove: %s', tag)
return tag
def destroyer(magic_tag=None): # ;-)
"""Remove every .py[co] file associated to received .py file.
:param magic_tag:
* If None, removes all associated .py[co] files from __pycache__
directory. If the resulting directory is empty, and is not a system
site package, then the directory is also removed.
* If False, removes python3.1's .pyc files only
* Otherwise removes given magic tag from __pycache__ directory. If
the resulting directory is empty, and is not a system site package,
then the directory is also removed.
:type magic_tag: None or False or str
"""
if magic_tag is None:
# remove compiled files in __pycache__ directory
def find_files_to_remove(pyfile):
directory = join(dirname(pyfile), '__pycache__')
fname = splitext(basename(pyfile))[0]
for fn in glob1(directory, "%s.*" % fname):
yield join(directory, fn)
# remove "classic" .pyc files as well
for filename in ("%sc" % pyfile, "%so" % pyfile):
if exists(filename):
yield filename
# workaround for http://bugs.python.org/issue22966
if '.' in fname:
sane_fname = join(dirname(pyfile), fname.split('.', 1)[0])
for fn in find_files_to_remove(sane_fname):
yield join(directory, fn)
elif magic_tag is False:
# remove 3.1's .pyc files only
def find_files_to_remove(pyfile): # NOQA
for filename in ("%sc" % pyfile, "%so" % pyfile):
if exists(filename):
yield filename
else:
# remove .pyc files for no longer needed magic tags
def find_files_to_remove(pyfile): # NOQA
directory = join(dirname(pyfile), '__pycache__')
fname = splitext(basename(pyfile))[0]
for fn in glob1(directory, "%s.%s.py[co]" % (fname, magic_tag)):
yield join(directory, fn)
# workaround for http://bugs.python.org/issue22966
if '.' in fname:
sane_fname = join(dirname(pyfile), fname.split('.', 1)[0])
for fn in find_files_to_remove(sane_fname):
yield join(directory, fn)
def myremove(fname):
remove(fname)
directory = dirname(fname)
# remove __pycache__ directory if it's empty
if directory.endswith('__pycache__'):
try:
rmdir(directory)
except Exception:
pass
counter = 0
try:
while True:
pyfile = (yield)
for filename in find_files_to_remove(pyfile):
try:
myremove(filename)
counter += 1
except (IOError, OSError) as e:
log.error('cannot remove %s', filename)
log.debug(e)
except GeneratorExit:
log.info("removed files: %s", counter)
def main():
usage = '%prog [-V VERSION] [-p PACKAGE] [DIR_OR_FILE]'
parser = optparse.OptionParser(usage, version='%prog 3.12.3-0ubuntu2.1')
parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
help='turn verbose mode on')
parser.add_option('-q', '--quiet', action='store_false', dest='verbose',
default=False, help='be quiet')
parser.add_option('-p', '--package',
help='specify Debian package name to clean')
parser.add_option('-V', dest='version',
help='specify Python version to clean')
(options, args) = parser.parse_args()
if options.verbose or environ.get('PYCLEAN_DEBUG') == '1':
log.setLevel(logging.DEBUG)
log.debug('argv: %s', sys.argv)
log.debug('options: %s', options)
log.debug('args: %s', args)
else:
log.setLevel(logging.WARNING)
if options.version:
if options.version.endswith('3.1'): # 3.1, -3.1
magic_tag = False
else:
magic_tag = get_magic_tag_to_remove(getver(options.version))
d = destroyer(magic_tag)
else:
d = destroyer() # remove everything
next(d) # initialize coroutine
if not options.package and not args:
parser.print_usage()
exit(1)
if options.package:
log.info('cleaning package %s', options.package)
pfiles = set(dpf.from_package(options.package))
if args:
log.info('cleaning directories: %s', args)
files = set(dpf.from_directory(args))
if options.package:
files = files & pfiles
else:
files = pfiles
for filename in files:
d.send(filename)
if __name__ == '__main__':
main()
+323
View File
@@ -0,0 +1,323 @@
#! usr/bin/python3
# vim: et ts=4 sw=4
# Copyright © 2010-2012 Piotr Ożarowski <piotr@debian.org>
# Copyright © 2010 Canonical Ltd
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import logging
import optparse
import os
import struct
import sys
from os import environ, listdir, mkdir
from os.path import dirname, exists, isdir, join
from subprocess import PIPE, Popen
sys.path.insert(1, '/usr/share/python3/')
from debpython.version import SUPPORTED, debsorted, vrepr, \
get_requested_versions, parse_vrange, getver
from debpython import files as dpf, PUBLIC_DIR_RE, memoize
from debpython.interpreter import Interpreter
from debpython.option import Option, compile_regexpr
# initialize script
logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: '
'%(message)s')
log = logging.getLogger(__name__)
STDINS = {}
WORKERS = {}
"""TODO: move it to manpage
Examples:
pycompile -p python3-mako # package's public files
pycompile -p python3-foo /usr/share/foo # package's private files
pycompile -V 3.1 /usr/lib/python3.1/ # python3.1 only
pycompile -V 3.1 /usr/lib/foo/bar.py # python3.1 only
pycompile -V 3.2- /usr/lib/python3/
"""
### EXCLUDES ###################################################
@memoize
def get_exclude_patterns_from_dir(name='/usr/share/python3/bcep/'):
"""Return patterns for files that shouldn't be bytecompiled."""
if not isdir(name):
return []
result = []
for fn in listdir(name):
if fn.startswith('.'):
continue
with open(join(name, fn), 'r', encoding='utf-8') as lines:
for line in lines:
if line.startswith('#'):
continue
line = line.rstrip('\n')
try:
type_, vrange, dname, pattern = line.split('|', 3)
except ValueError:
pattern = '.*'
type_, vrange, dname = line.split('|', 2)
if type_ != 'file':
dname = dname.rstrip('/') + '/' # make sure it ends with slash
vrange = parse_vrange(vrange)
versions = get_requested_versions(vrange, available=True)
if not versions:
# pattern doesn't match installed Python versions
continue
if type_ == 're' or pattern:
try:
pattern = compile_regexpr(None, None, pattern)
except Exception:
log.warning('skipping invalid pattern in file %s, line: %s', fn, line)
continue
result.append((type_, versions, dname, pattern))
return result
def get_exclude_patterns(directory='/', patterns=None, versions=None):
"""Return patterns for files that shouldn't be compiled in given dir."""
# make sure directory name ends with a slash
directory = directory.rstrip('/') + '/'
if versions is not None:
# make sure it's a set (debsorted returns a list)
versions = set(versions)
if patterns:
if versions is None:
versions = set(SUPPORTED)
patterns = [('re', versions, directory, i) for i in patterns]
else:
patterns = []
for type_, vers, dname, pattern in get_exclude_patterns_from_dir():
# skip patterns that do not match requested directory
if not dname.startswith(directory[:len(dname)]):
continue
# skip patterns that do not match requested versions
if versions and not versions & vers:
continue
patterns.append((type_, vers, dname, pattern))
return patterns
def filter_files(files, e_patterns, compile_versions):
"""Generate (file, versions_to_compile) pairs."""
for fpath in files:
valid_versions = set(compile_versions) # all by default
for type_, vers, dname, pattern in e_patterns:
if not fpath.startswith(dname):
continue
rfpath = fpath[len(dname):] # relative to dname
if type_ == 'dir': # fpath.startswith(dname) - see above
valid_versions = valid_versions - vers
elif type_ == 'file' and fpath == dname:
valid_versions = valid_versions - vers
elif type_ == 're' and (pattern.match(fpath) or pattern.match(rfpath)):
# NOTE: directory is checked at the beginning of this loop
valid_versions = valid_versions - vers
# move to the next file if all versions were removed
if not valid_versions:
break
if valid_versions:
public_dir = PUBLIC_DIR_RE.match(fpath)
if public_dir and len(public_dir.group(1)) != 1:
yield fpath, set([getver(public_dir.group(1))])
else:
yield fpath, valid_versions
### COMPILE ####################################################
def py_compile(version, optimize, workers):
if not isinstance(version, str):
version = vrepr(version)
cmd = ["/usr/bin/python" + version]
if optimize:
cmd.append("-O")
cmd += ["-m", "py_compile", "-"]
process = Popen(cmd, bufsize=0,
stdin=PIPE, close_fds=True)
workers[version] = process # keep the reference for .communicate()
stdin = process.stdin
while True:
filename = (yield)
stdin.write(filename.encode('utf-8') + b'\n')
def compile(files, versions, force, optimize, e_patterns=None):
global STDINS, WORKERS
# start Python interpreters that will handle byte compilation
for version in versions:
if version not in STDINS:
coroutine = py_compile(version, optimize, WORKERS)
next(coroutine)
STDINS[version] = coroutine
interpreter = Interpreter('python' if not optimize else 'python -O')
# byte compile files
skip_dirs = set()
for fn, versions_to_compile in filter_files(files, e_patterns, versions):
for version in versions_to_compile:
cfn = interpreter.cache_file(fn, version)
if version == (3, 1):
if exists(cfn) and not force:
ftime = os.stat(fn).st_mtime
try:
ctime = os.stat(cfn).st_mtime
except os.error:
ctime = 0
if ctime > ftime:
continue
else:
pycache_dir = dirname(cfn)
if not force:
try:
mtime = int(os.stat(fn).st_mtime)
expect = struct.pack('<4sLL',
interpreter.magic_number(version),
0,
mtime & 0xFFFF_FFFF)
with open(cfn, 'rb') as chandle:
actual = chandle.read(12)
if expect == actual:
continue
except (IOError, OSError):
pass
if pycache_dir not in skip_dirs and not exists(pycache_dir):
try:
mkdir(pycache_dir)
except Exception as e:
log.error("cannot create directory %s: %r", pycache_dir, e)
skip_dirs.add(pycache_dir)
continue
pipe = STDINS[version]
pipe.send(fn)
################################################################
def main():
usage = '%prog [-V [X.Y][-][A.B]] DIR_OR_FILE [-X REGEXPR]\n' +\
' %prog -p PACKAGE'
parser = optparse.OptionParser(usage, version='%prog 3.12.3-0ubuntu2.1',
option_class=Option)
parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
help='turn verbose mode on')
parser.add_option('-q', '--quiet', action='store_false', dest='verbose',
default=False, help='be quiet')
parser.add_option('-f', '--force', action='store_true', dest='force',
default=False,
help='force rebuild even if timestamps are up-to-date')
parser.add_option('-O', action='store_true', dest='optimize',
default=False, help="byte-compile to .pyo files")
parser.add_option('-p', '--package',
help='specify Debian package name whose files should be bytecompiled')
parser.add_option('-V', type='version_range', dest='vrange',
help="""force private modules to be bytecompiled
with Python version from given range, regardless of the default Python version
in the system. If there are no other options, bytecompile all public modules
for installed Python versions that match given range.
VERSION_RANGE examples: '3.1' (version 3.1 only), '3.1-' (version 3.1 or
newer), '3.1-3.3' (version 3.1 or 3.2), '-4.0' (all supported 3.X versions)""")
parser.add_option('-X', '--exclude', action='append',
dest='regexpr', type='regexpr',
help='exclude items that match given REGEXPR. \
You may use this option multiple times to build up a list of things to exclude.')
(options, args) = parser.parse_args()
if options.verbose or environ.get('PYCOMPILE_DEBUG') == '1':
log.setLevel(logging.DEBUG)
log.debug('argv: %s', sys.argv)
log.debug('options: %s', options)
log.debug('args: %s', args)
else:
log.setLevel(logging.WARN)
if options.regexpr and not args:
parser.error('--exclude option works with private directories '
'only, please use /usr/share/python3/bcep to specify '
'public modules to skip')
if options.vrange and options.vrange[0] == options.vrange[1] and\
options.vrange != (None, None) and\
exists("/usr/bin/python%d.%d" % options.vrange[0]):
# specific version requested, use it even if it's not in SUPPORTED
versions = {options.vrange[0]}
else:
versions = get_requested_versions(options.vrange, available=True)
if not versions:
log.error('Requested versions are not installed')
exit(3)
if options.package and args: # package's private directories
# get requested Python version
compile_versions = debsorted(versions)[:1]
log.debug('compile versions: %s', versions)
pkg_files = tuple(dpf.from_package(options.package))
for item in args:
e_patterns = get_exclude_patterns(item, options.regexpr,
compile_versions)
if not exists(item):
log.warning('No such file or directory: %s', item)
else:
log.debug('byte compiling %s using Python %s',
item, compile_versions)
files = dpf.filter_directory(pkg_files, item)
compile(files, compile_versions, options.force,
options.optimize, e_patterns)
elif options.package: # package's public modules
# no need to limit versions here, it's either pyr mode or version is
# hardcoded in path / via -V option
e_patterns = get_exclude_patterns()
files = dpf.from_package(options.package)
files = dpf.filter_public(files, versions)
compile(files, versions,
options.force, options.optimize, e_patterns)
elif args: # other directories/files
for item in args:
e_patterns = get_exclude_patterns(item, options.regexpr, versions)
files = dpf.from_directory(item)
compile(files, versions,
options.force, options.optimize, e_patterns)
else:
parser.print_usage()
exit(1)
# wait for all processes to finish
rv = 0
for process in WORKERS.values():
process.communicate()
if process.returncode not in (None, 0):
rv = process.returncode
exit(rv)
if __name__ == '__main__':
main()
+1
View File
@@ -0,0 +1 @@
../share/python3/py3versions.py
+1
View File
@@ -0,0 +1 @@
pydoc3.12
+5
View File
@@ -0,0 +1,5 @@
#! usr/bin/python3.12
import pydoc
if __name__ == '__main__':
pydoc.cli()
+1
View File
@@ -0,0 +1 @@
pygettext3.12
+681
View File
@@ -0,0 +1,681 @@
#! /usr/bin/python3.12
# -*- coding: iso-8859-1 -*-
# Originally written by Barry Warsaw <barry@python.org>
#
# Minimally patched to make it even more xgettext compatible
# by Peter Funk <pf@artcom-gmbh.de>
#
# 2002-11-22 Jürgen Hermann <jh@web.de>
# Added checks that _() only contains string literals, and
# command line args are resolved to module lists, i.e. you
# can now pass a filename, a module or package name, or a
# directory (including globbing chars, important for Win32).
# Made docstring fit in 80 chars wide displays using pydoc.
#
# for selftesting
try:
import fintl
_ = fintl.gettext
except ImportError:
_ = lambda s: s
__doc__ = _("""pygettext -- Python equivalent of xgettext(1)
Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
internationalization of C programs. Most of these tools are independent of
the programming language and can be used from within Python programs.
Martin von Loewis' work[1] helps considerably in this regard.
There's one problem though; xgettext is the program that scans source code
looking for message strings, but it groks only C (or C++). Python
introduces a few wrinkles, such as dual quoting characters, triple quoted
strings, and raw strings. xgettext understands none of this.
Enter pygettext, which uses Python's standard tokenize module to scan
Python source code, generating .pot files identical to what GNU xgettext[2]
generates for C and C++ code. From there, the standard GNU tools can be
used.
A word about marking Python strings as candidates for translation. GNU
xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
and gettext_noop. But those can be a lot of text to include all over your
code. C and C++ have a trick: they use the C preprocessor. Most
internationalized C source includes a #define for gettext() to _() so that
what has to be written in the source is much less. Thus these are both
translatable strings:
gettext("Translatable String")
_("Translatable String")
Python of course has no preprocessor so this doesn't work so well. Thus,
pygettext searches only for _() by default, but see the -k/--keyword flag
below for how to augment this.
[1] https://www.python.org/workshops/1997-10/proceedings/loewis.html
[2] https://www.gnu.org/software/gettext/gettext.html
NOTE: pygettext attempts to be option and feature compatible with GNU
xgettext where ever possible. However some options are still missing or are
not fully implemented. Also, xgettext's use of command line switches with
option arguments is broken, and in these cases, pygettext just defines
additional switches.
Usage: pygettext [options] inputfile ...
Options:
-a
--extract-all
Extract all strings.
-d name
--default-domain=name
Rename the default output file from messages.pot to name.pot.
-E
--escape
Replace non-ASCII characters with octal escape sequences.
-D
--docstrings
Extract module, class, method, and function docstrings. These do
not need to be wrapped in _() markers, and in fact cannot be for
Python to consider them docstrings. (See also the -X option).
-h
--help
Print this help message and exit.
-k word
--keyword=word
Keywords to look for in addition to the default set, which are:
%(DEFAULTKEYWORDS)s
You can have multiple -k flags on the command line.
-K
--no-default-keywords
Disable the default set of keywords (see above). Any keywords
explicitly added with the -k/--keyword option are still recognized.
--no-location
Do not write filename/lineno location comments.
-n
--add-location
Write filename/lineno location comments indicating where each
extracted string is found in the source. These lines appear before
each msgid. The style of comments is controlled by the -S/--style
option. This is the default.
-o filename
--output=filename
Rename the default output file from messages.pot to filename. If
filename is `-' then the output is sent to standard out.
-p dir
--output-dir=dir
Output files will be placed in directory dir.
-S stylename
--style stylename
Specify which style to use for location comments. Two styles are
supported:
Solaris # File: filename, line: line-number
GNU #: filename:line
The style name is case insensitive. GNU style is the default.
-v
--verbose
Print the names of the files being processed.
-V
--version
Print the version of pygettext and exit.
-w columns
--width=columns
Set width of output to columns.
-x filename
--exclude-file=filename
Specify a file that contains a list of strings that are not be
extracted from the input files. Each string to be excluded must
appear on a line by itself in the file.
-X filename
--no-docstrings=filename
Specify a file that contains a list of files (one per line) that
should not have their docstrings extracted. This is only useful in
conjunction with the -D option above.
If `inputfile' is -, standard input is read.
""")
import os
import importlib.machinery
import importlib.util
import sys
import glob
import time
import getopt
import ast
import token
import tokenize
__version__ = '1.5'
default_keywords = ['_']
DEFAULTKEYWORDS = ', '.join(default_keywords)
EMPTYSTRING = ''
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
# there.
pot_header = _('''\
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\\n"
"POT-Creation-Date: %(time)s\\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
"Language-Team: LANGUAGE <LL@li.org>\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=%(charset)s\\n"
"Content-Transfer-Encoding: %(encoding)s\\n"
"Generated-By: pygettext.py %(version)s\\n"
''')
def usage(code, msg=''):
print(__doc__ % globals(), file=sys.stderr)
if msg:
print(msg, file=sys.stderr)
sys.exit(code)
def make_escapes(pass_nonascii):
global escapes, escape
if pass_nonascii:
# Allow non-ascii characters to pass through so that e.g. 'msgid
# "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we
# escape any character outside the 32..126 range.
mod = 128
escape = escape_ascii
else:
mod = 256
escape = escape_nonascii
escapes = [r"\%03o" % i for i in range(mod)]
for i in range(32, 127):
escapes[i] = chr(i)
escapes[ord('\\')] = r'\\'
escapes[ord('\t')] = r'\t'
escapes[ord('\r')] = r'\r'
escapes[ord('\n')] = r'\n'
escapes[ord('\"')] = r'\"'
def escape_ascii(s, encoding):
return ''.join(escapes[ord(c)] if ord(c) < 128 else c for c in s)
def escape_nonascii(s, encoding):
return ''.join(escapes[b] for b in s.encode(encoding))
def is_literal_string(s):
return s[0] in '\'"' or (s[0] in 'rRuU' and s[1] in '\'"')
def safe_eval(s):
# unwrap quotes, safely
return eval(s, {'__builtins__':{}}, {})
def normalize(s, encoding):
# This converts the various Python string types into a format that is
# appropriate for .po files, namely much closer to C style.
lines = s.split('\n')
if len(lines) == 1:
s = '"' + escape(s, encoding) + '"'
else:
if not lines[-1]:
del lines[-1]
lines[-1] = lines[-1] + '\n'
for i in range(len(lines)):
lines[i] = escape(lines[i], encoding)
lineterm = '\\n"\n"'
s = '""\n"' + lineterm.join(lines) + '"'
return s
def containsAny(str, set):
"""Check whether 'str' contains ANY of the chars in 'set'"""
return 1 in [c in str for c in set]
def getFilesForName(name):
"""Get a list of module files for a filename, a module or package name,
or a directory.
"""
if not os.path.exists(name):
# check for glob chars
if containsAny(name, "*?[]"):
files = glob.glob(name)
list = []
for file in files:
list.extend(getFilesForName(file))
return list
# try to find module or package
try:
spec = importlib.util.find_spec(name)
name = spec.origin
except ImportError:
name = None
if not name:
return []
if os.path.isdir(name):
# find all python files in directory
list = []
# get extension for python source files
_py_ext = importlib.machinery.SOURCE_SUFFIXES[0]
for root, dirs, files in os.walk(name):
# don't recurse into CVS directories
if 'CVS' in dirs:
dirs.remove('CVS')
# add all *.py files to list
list.extend(
[os.path.join(root, file) for file in files
if os.path.splitext(file)[1] == _py_ext]
)
return list
elif os.path.exists(name):
# a single file
return [name]
return []
class TokenEater:
def __init__(self, options):
self.__options = options
self.__messages = {}
self.__state = self.__waiting
self.__data = []
self.__lineno = -1
self.__freshmodule = 1
self.__curfile = None
self.__enclosurecount = 0
def __call__(self, ttype, tstring, stup, etup, line):
# dispatch
## import token
## print('ttype:', token.tok_name[ttype], 'tstring:', tstring,
## file=sys.stderr)
self.__state(ttype, tstring, stup[0])
def __waiting(self, ttype, tstring, lineno):
opts = self.__options
# Do docstring extractions, if enabled
if opts.docstrings and not opts.nodocstrings.get(self.__curfile):
# module docstring?
if self.__freshmodule:
if ttype == tokenize.STRING and is_literal_string(tstring):
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
self.__freshmodule = 0
return
if ttype in (tokenize.COMMENT, tokenize.NL, tokenize.ENCODING):
return
self.__freshmodule = 0
# class or func/method docstring?
if ttype == tokenize.NAME and tstring in ('class', 'def'):
self.__state = self.__suiteseen
return
if ttype == tokenize.NAME and tstring in opts.keywords:
self.__state = self.__keywordseen
return
if ttype == tokenize.STRING:
maybe_fstring = ast.parse(tstring, mode='eval').body
if not isinstance(maybe_fstring, ast.JoinedStr):
return
for value in filter(lambda node: isinstance(node, ast.FormattedValue),
maybe_fstring.values):
for call in filter(lambda node: isinstance(node, ast.Call),
ast.walk(value)):
func = call.func
if isinstance(func, ast.Name):
func_name = func.id
elif isinstance(func, ast.Attribute):
func_name = func.attr
else:
continue
if func_name not in opts.keywords:
continue
if len(call.args) != 1:
print(_(
'*** %(file)s:%(lineno)s: Seen unexpected amount of'
' positional arguments in gettext call: %(source_segment)s'
) % {
'source_segment': ast.get_source_segment(tstring, call) or tstring,
'file': self.__curfile,
'lineno': lineno
}, file=sys.stderr)
continue
if call.keywords:
print(_(
'*** %(file)s:%(lineno)s: Seen unexpected keyword arguments'
' in gettext call: %(source_segment)s'
) % {
'source_segment': ast.get_source_segment(tstring, call) or tstring,
'file': self.__curfile,
'lineno': lineno
}, file=sys.stderr)
continue
arg = call.args[0]
if not isinstance(arg, ast.Constant):
print(_(
'*** %(file)s:%(lineno)s: Seen unexpected argument type'
' in gettext call: %(source_segment)s'
) % {
'source_segment': ast.get_source_segment(tstring, call) or tstring,
'file': self.__curfile,
'lineno': lineno
}, file=sys.stderr)
continue
if isinstance(arg.value, str):
self.__addentry(arg.value, lineno)
def __suiteseen(self, ttype, tstring, lineno):
# skip over any enclosure pairs until we see the colon
if ttype == tokenize.OP:
if tstring == ':' and self.__enclosurecount == 0:
# we see a colon and we're not in an enclosure: end of def
self.__state = self.__suitedocstring
elif tstring in '([{':
self.__enclosurecount += 1
elif tstring in ')]}':
self.__enclosurecount -= 1
def __suitedocstring(self, ttype, tstring, lineno):
# ignore any intervening noise
if ttype == tokenize.STRING and is_literal_string(tstring):
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
self.__state = self.__waiting
elif ttype not in (tokenize.NEWLINE, tokenize.INDENT,
tokenize.COMMENT):
# there was no class docstring
self.__state = self.__waiting
def __keywordseen(self, ttype, tstring, lineno):
if ttype == tokenize.OP and tstring == '(':
self.__data = []
self.__lineno = lineno
self.__state = self.__openseen
else:
self.__state = self.__waiting
def __openseen(self, ttype, tstring, lineno):
if ttype == tokenize.OP and tstring == ')':
# We've seen the last of the translatable strings. Record the
# line number of the first line of the strings and update the list
# of messages seen. Reset state for the next batch. If there
# were no strings inside _(), then just ignore this entry.
if self.__data:
self.__addentry(EMPTYSTRING.join(self.__data))
self.__state = self.__waiting
elif ttype == tokenize.STRING and is_literal_string(tstring):
self.__data.append(safe_eval(tstring))
elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT,
token.NEWLINE, tokenize.NL]:
# warn if we see anything else than STRING or whitespace
print(_(
'*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
) % {
'token': tstring,
'file': self.__curfile,
'lineno': self.__lineno
}, file=sys.stderr)
self.__state = self.__waiting
def __addentry(self, msg, lineno=None, isdocstring=0):
if lineno is None:
lineno = self.__lineno
if not msg in self.__options.toexclude:
entry = (self.__curfile, lineno)
self.__messages.setdefault(msg, {})[entry] = isdocstring
def set_filename(self, filename):
self.__curfile = filename
self.__freshmodule = 1
def write(self, fp):
options = self.__options
timestamp = time.strftime('%Y-%m-%d %H:%M%z')
encoding = fp.encoding if fp.encoding else 'UTF-8'
print(pot_header % {'time': timestamp, 'version': __version__,
'charset': encoding,
'encoding': '8bit'}, file=fp)
# Sort the entries. First sort each particular entry's keys, then
# sort all the entries by their first item.
reverse = {}
for k, v in self.__messages.items():
keys = sorted(v.keys())
reverse.setdefault(tuple(keys), []).append((k, v))
rkeys = sorted(reverse.keys())
for rkey in rkeys:
rentries = reverse[rkey]
rentries.sort()
for k, v in rentries:
# If the entry was gleaned out of a docstring, then add a
# comment stating so. This is to aid translators who may wish
# to skip translating some unimportant docstrings.
isdocstring = any(v.values())
# k is the message string, v is a dictionary-set of (filename,
# lineno) tuples. We want to sort the entries in v first by
# file name and then by line number.
v = sorted(v.keys())
if not options.writelocations:
pass
# location comments are different b/w Solaris and GNU:
elif options.locationstyle == options.SOLARIS:
for filename, lineno in v:
d = {'filename': filename, 'lineno': lineno}
print(_(
'# File: %(filename)s, line: %(lineno)d') % d, file=fp)
elif options.locationstyle == options.GNU:
# fit as many locations on one line, as long as the
# resulting line length doesn't exceed 'options.width'
locline = '#:'
for filename, lineno in v:
d = {'filename': filename, 'lineno': lineno}
s = _(' %(filename)s:%(lineno)d') % d
if len(locline) + len(s) <= options.width:
locline = locline + s
else:
print(locline, file=fp)
locline = "#:" + s
if len(locline) > 2:
print(locline, file=fp)
if isdocstring:
print('#, docstring', file=fp)
print('msgid', normalize(k, encoding), file=fp)
print('msgstr ""\n', file=fp)
def main():
global default_keywords
try:
opts, args = getopt.getopt(
sys.argv[1:],
'ad:DEhk:Kno:p:S:Vvw:x:X:',
['extract-all', 'default-domain=', 'escape', 'help',
'keyword=', 'no-default-keywords',
'add-location', 'no-location', 'output=', 'output-dir=',
'style=', 'verbose', 'version', 'width=', 'exclude-file=',
'docstrings', 'no-docstrings',
])
except getopt.error as msg:
usage(1, msg)
# for holding option values
class Options:
# constants
GNU = 1
SOLARIS = 2
# defaults
extractall = 0 # FIXME: currently this option has no effect at all.
escape = 0
keywords = []
outpath = ''
outfile = 'messages.pot'
writelocations = 1
locationstyle = GNU
verbose = 0
width = 78
excludefilename = ''
docstrings = 0
nodocstrings = {}
options = Options()
locations = {'gnu' : options.GNU,
'solaris' : options.SOLARIS,
}
# parse options
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt in ('-a', '--extract-all'):
options.extractall = 1
elif opt in ('-d', '--default-domain'):
options.outfile = arg + '.pot'
elif opt in ('-E', '--escape'):
options.escape = 1
elif opt in ('-D', '--docstrings'):
options.docstrings = 1
elif opt in ('-k', '--keyword'):
options.keywords.append(arg)
elif opt in ('-K', '--no-default-keywords'):
default_keywords = []
elif opt in ('-n', '--add-location'):
options.writelocations = 1
elif opt in ('--no-location',):
options.writelocations = 0
elif opt in ('-S', '--style'):
options.locationstyle = locations.get(arg.lower())
if options.locationstyle is None:
usage(1, _('Invalid value for --style: %s') % arg)
elif opt in ('-o', '--output'):
options.outfile = arg
elif opt in ('-p', '--output-dir'):
options.outpath = arg
elif opt in ('-v', '--verbose'):
options.verbose = 1
elif opt in ('-V', '--version'):
print(_('pygettext.py (xgettext for Python) %s') % __version__)
sys.exit(0)
elif opt in ('-w', '--width'):
try:
options.width = int(arg)
except ValueError:
usage(1, _('--width argument must be an integer: %s') % arg)
elif opt in ('-x', '--exclude-file'):
options.excludefilename = arg
elif opt in ('-X', '--no-docstrings'):
fp = open(arg)
try:
while 1:
line = fp.readline()
if not line:
break
options.nodocstrings[line[:-1]] = 1
finally:
fp.close()
# calculate escapes
make_escapes(not options.escape)
# calculate all keywords
options.keywords.extend(default_keywords)
# initialize list of strings to exclude
if options.excludefilename:
try:
with open(options.excludefilename) as fp:
options.toexclude = fp.readlines()
except IOError:
print(_(
"Can't read --exclude-file: %s") % options.excludefilename, file=sys.stderr)
sys.exit(1)
else:
options.toexclude = []
# resolve args to module lists
expanded = []
for arg in args:
if arg == '-':
expanded.append(arg)
else:
expanded.extend(getFilesForName(arg))
args = expanded
# slurp through all the files
eater = TokenEater(options)
for filename in args:
if filename == '-':
if options.verbose:
print(_('Reading standard input'))
fp = sys.stdin.buffer
closep = 0
else:
if options.verbose:
print(_('Working on %s') % filename)
fp = open(filename, 'rb')
closep = 1
try:
eater.set_filename(filename)
try:
tokens = tokenize.tokenize(fp.readline)
for _token in tokens:
eater(*_token)
except tokenize.TokenError as e:
print('%s: %s, line %d, column %d' % (
e.args[0], filename, e.args[1][0], e.args[1][1]),
file=sys.stderr)
finally:
if closep:
fp.close()
# write the output
if options.outfile == '-':
fp = sys.stdout
closep = 0
else:
if options.outpath:
options.outfile = os.path.join(options.outpath, options.outfile)
fp = open(options.outfile, 'w')
closep = 1
try:
eater.write(fp)
finally:
if closep:
fp.close()
if __name__ == '__main__':
main()
# some more test strings
# this one creates a warning
_('*** Seen unexpected token "%(token)s"') % {'token': 'test'}
_('more' 'than' 'one' 'string')
+1
View File
@@ -0,0 +1 @@
python3.12
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
skill
Loaded 100 of 15893 files, more files were not shown because too many files have changed in this diff. Show more