mirror of
https://github.com/lifegpc/pixiv_downloader.git
synced 2026-06-06 05:49:01 +08:00
226 lines
6.6 KiB
Python
226 lines
6.6 KiB
Python
from argparse import ArgumentParser, Namespace
|
|
from os import system, devnull, environ, remove, makedirs, listdir, chdir
|
|
from typing import List
|
|
from sys import exit
|
|
from subprocess import Popen, PIPE
|
|
from re import search, IGNORECASE
|
|
from os.path import splitext, exists, abspath, isdir, isfile, join, basename
|
|
from tempfile import NamedTemporaryFile
|
|
from shutil import copy2
|
|
|
|
|
|
def add_path_ext(path: str) -> str:
|
|
p, n = splitext(path)
|
|
if n != '':
|
|
return path
|
|
else:
|
|
pext = environ['PATHEXT']
|
|
pextl = pext.split(';')
|
|
for ext in pextl:
|
|
if ext == '':
|
|
continue
|
|
if exists(p + ext):
|
|
return p + ext
|
|
return path
|
|
|
|
|
|
def check_pdb(path: str) -> str:
|
|
p = splitext(path)[0] + '.pdb'
|
|
if exists(p):
|
|
return p
|
|
|
|
|
|
def check_needed_prog():
|
|
if system(f'ldd-rust --help > {devnull}'):
|
|
return False
|
|
if system(f'7z --help > {devnull}'):
|
|
return False
|
|
return True
|
|
|
|
|
|
def check_prog(prog: str) -> List[str]:
|
|
r = Popen(f'ldd-rust {prog}', stdout=PIPE, stderr=PIPE)
|
|
out: bytes = r.communicate()[0]
|
|
r.wait()
|
|
out += r.communicate()[0]
|
|
if not r.returncode:
|
|
sl = out.splitlines(False)
|
|
rl = []
|
|
for r in sl:
|
|
r = r.decode()
|
|
rs = search(r'=?-?> (.+) ?(\(0x[0-9a-f]+\))?$', r, IGNORECASE)
|
|
if rs is not None:
|
|
rl.append(abspath(rs.groups()[0]))
|
|
else:
|
|
raise ValueError(f'Can not find path for {r}.')
|
|
return rl
|
|
return None
|
|
|
|
|
|
def getUnixPath(path: str) -> str:
|
|
rs = search(r'^[A-Z]:', path, IGNORECASE)
|
|
if rs is None:
|
|
return path.replace('\\', '/')
|
|
return '/' + path[0].lower() + path[2:].replace('\\', '/')
|
|
|
|
|
|
def getWindowsPath(path: str) -> str:
|
|
rs = search(r'^[\\/][A-Z][\\/]', path, IGNORECASE)
|
|
if rs is None:
|
|
return path.replace('/', '\\')
|
|
return path[1].upper() + ":" + path[2:].replace('/', '\\')
|
|
|
|
|
|
def listdirs(loc: str, ignore_hidden_files: bool = True):
|
|
bl = listdir(loc)
|
|
r = []
|
|
for i in bl:
|
|
if i.startswith('.'):
|
|
if ignore_hidden_files or i == '.' or i == '..':
|
|
continue
|
|
p = join(loc, i)
|
|
if isfile(p):
|
|
r.append(p)
|
|
elif isdir(p):
|
|
r += listdirs(p)
|
|
return r
|
|
|
|
|
|
def remove_dirs(loc: str):
|
|
bl = listdirs(loc, False)
|
|
for i in bl:
|
|
if isfile(i):
|
|
remove(i)
|
|
elif isdir(i):
|
|
try:
|
|
remove_dirs(i)
|
|
except Exception:
|
|
remove_dirs(i)
|
|
remove(loc)
|
|
|
|
class Prog:
|
|
def __init__(self):
|
|
self._loc = []
|
|
self.strip = False
|
|
self.num_cpu = None
|
|
|
|
def add_dep(self, path: str):
|
|
path_w = getWindowsPath(path)
|
|
if path_w.upper().startswith('C:\\WINDOWS'):
|
|
return
|
|
if path_w not in self._loc:
|
|
print(f'add dependence: "{path_w}"')
|
|
self._loc.append(path_w)
|
|
|
|
def add_prog(self, path: str):
|
|
pro = add_path_ext(path)
|
|
pro_w = getWindowsPath(pro)
|
|
if pro_w not in self._loc:
|
|
print(f'add program: "{pro_w}"')
|
|
self._loc.append(pro_w)
|
|
|
|
def add_file(self, path: str):
|
|
p = getWindowsPath(path)
|
|
if p not in self._loc:
|
|
print(f'add file: "{p}"')
|
|
self._loc.append(p)
|
|
|
|
def to_7z(self, output: str):
|
|
if self.strip:
|
|
makedirs('temp', exist_ok=True)
|
|
p = NamedTemporaryFile(delete=False)
|
|
for i in self._loc:
|
|
if not self.strip:
|
|
p.write((i + '\n').encode('UTF8'))
|
|
else:
|
|
bn = basename(i)
|
|
dest = f'temp/{bn}'
|
|
print(f'Copying {i} to {dest}')
|
|
copy2(i, dest)
|
|
pr = Popen(['strip', dest])
|
|
pr.wait()
|
|
p.write((bn + '\n').encode('UTF8'))
|
|
fp = p.name
|
|
p.close()
|
|
output = getWindowsPath(abspath(output))
|
|
try:
|
|
num_cpu = '' if self.num_cpu is None else f' -mmt{self.num_cpu}'
|
|
if self.strip:
|
|
chdir('temp')
|
|
system(f'7z a{num_cpu} -mx9 -y {output} @{fp}')
|
|
if self.strip:
|
|
chdir('../')
|
|
except Exception:
|
|
remove(fp)
|
|
from traceback import print_exc
|
|
print_exc()
|
|
remove(fp)
|
|
if self.strip:
|
|
try:
|
|
remove_dirs('temp')
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def main(prog: List[str], output: str = None, adds: List[str] = None,
|
|
pdbs: List[str] = None, args: Namespace = None):
|
|
if output is None:
|
|
output = 'programs.7z'
|
|
if not check_needed_prog():
|
|
print('ldd and 7z is needed.')
|
|
p = Prog()
|
|
for pro in prog:
|
|
pro = abspath(pro)
|
|
pro = add_path_ext(pro)
|
|
# pro_u = getUnixPath(pro)
|
|
rel = check_prog(pro)
|
|
if rel is None:
|
|
print(f'Can not get dependencies for {pro},')
|
|
exit(-1)
|
|
p.add_prog(pro)
|
|
for i in rel:
|
|
p.add_dep(i)
|
|
if adds is not None:
|
|
for f in adds:
|
|
p.add_file(f)
|
|
if pdbs:
|
|
for i in pdbs:
|
|
pro = abspath(i)
|
|
pro = add_path_ext(pro)
|
|
rel = check_prog(pro)
|
|
if rel is None:
|
|
print(f'Can not get dependencies for {pro},')
|
|
exit(-1)
|
|
fn = check_pdb(pro)
|
|
if fn:
|
|
p.add_file(fn)
|
|
for i in rel:
|
|
fn = check_pdb(i)
|
|
if fn:
|
|
p.add_file(fn)
|
|
if args and args.strip:
|
|
p.strip = True
|
|
if args and args.num_cpu:
|
|
p.num_cpu = args.num_cpu
|
|
p.to_7z(output)
|
|
|
|
|
|
p = ArgumentParser(description='Pack programs into a 7-zip file.')
|
|
p.add_argument('PROG', action='append', help='Program to pack', nargs='*', default=[])
|
|
p.add_argument('-p', '--pdb', action='append', help='Program\'s PDB file to pack', default=[], dest='pdb')
|
|
p.add_argument('-o', '--output', help='Output file', default='programs.7z', dest='output')
|
|
p.add_argument('-a', '--add', action='append', help='Additional files to pack', default=[], dest='add')
|
|
p.add_argument('-s', '--strip', help='Strip before package', default=False, action='store_true', dest='strip')
|
|
p.add_argument('-n', '--num_cpu', help='Number of CPU to use', default=None, type=int, dest='num_cpu')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
args = p.parse_args()
|
|
main(args.PROG[0], args.output, args.add, args.pdb, args)
|
|
except Exception:
|
|
from traceback import print_exc
|
|
from sys import exit
|
|
print_exc()
|
|
exit(-1)
|