Big migrations and linting.
With pathclass.glob_many, we can clean up and feel more confident about many programs that use pipeable to take glob patterns. Added return 0 to all programs that didn't have it, so we have consistent and explicit command line return values. Other linting and whitespace.
This commit is contained in:
parent
6751a5d6c9
commit
4a9051e617
64 changed files with 345 additions and 228 deletions
|
@ -1,37 +1,24 @@
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import interactive
|
from voussoirkit import interactive
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
from voussoirkit import stringtools
|
||||||
from voussoirkit import vlogging
|
from voussoirkit import vlogging
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
log = vlogging.getLogger(__name__, 'adbinstall')
|
log = vlogging.getLogger(__name__, 'adbinstall')
|
||||||
|
|
||||||
def natural_sorter(x):
|
|
||||||
'''
|
|
||||||
Used for sorting files in 'natural' order instead of lexicographic order,
|
|
||||||
so that you get 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
|
|
||||||
instead of 1 10 11 12 13 2 3 4 5 ...
|
|
||||||
Thank you Mark Byers
|
|
||||||
http://stackoverflow.com/a/11150413
|
|
||||||
'''
|
|
||||||
convert = lambda text: int(text) if text.isdigit() else text.lower()
|
|
||||||
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
|
|
||||||
return alphanum_key(x)
|
|
||||||
|
|
||||||
def adbinstall_argparse(args):
|
def adbinstall_argparse(args):
|
||||||
patterns = pipeable.input_many(args.apks, skip_blank=True, strip=True)
|
patterns = pipeable.input_many(args.apks, skip_blank=True, strip=True)
|
||||||
apks = [file for pattern in patterns for file in winglob.glob(pattern)]
|
apks = pathclass.glob_many(patterns, files=True)
|
||||||
installs = []
|
installs = []
|
||||||
for apk in apks:
|
for apk in apks:
|
||||||
apk = pathclass.Path(apk)
|
apk = pathclass.Path(apk)
|
||||||
if apk.is_dir:
|
if apk.is_dir:
|
||||||
files = apk.glob('*.apk')
|
files = apk.glob('*.apk')
|
||||||
files.sort(key=lambda x: natural_sorter(x.basename.lower()))
|
files.sort(key=lambda x: stringtools.natural_sorter(x.basename.lower()))
|
||||||
apk = files[-1]
|
apk = files[-1]
|
||||||
installs.append(apk)
|
installs.append(apk)
|
||||||
|
|
||||||
|
@ -46,6 +33,8 @@ def adbinstall_argparse(args):
|
||||||
log.info(command)
|
log.info(command)
|
||||||
os.system(command)
|
os.system(command)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
def windows():
|
def windows():
|
||||||
paths = os.getenv('PATH').strip(' ;').split(';')
|
paths = os.getenv('PATH').strip(' ;').split(';')
|
||||||
|
@ -30,7 +31,9 @@ def main(argv):
|
||||||
executables = linux()
|
executables = linux()
|
||||||
|
|
||||||
for executable in executables:
|
for executable in executables:
|
||||||
print(executable.absolute_path)
|
pipeable.stdout(executable.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
raise SystemExit(main(sys.argv[1:]))
|
raise SystemExit(main(sys.argv[1:]))
|
||||||
|
|
|
@ -7,16 +7,13 @@ Merge two or more files by performing bitwise or on their bits.
|
||||||
> bitwise_or file1 file2 --output file3
|
> bitwise_or file1 file2 --output file3
|
||||||
'''
|
'''
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import betterhelp
|
from voussoirkit import betterhelp
|
||||||
from voussoirkit import interactive
|
from voussoirkit import interactive
|
||||||
from voussoirkit import operatornotify
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import vlogging
|
from voussoirkit import vlogging
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
log = vlogging.getLogger(__name__, 'bitwise_or')
|
log = vlogging.getLogger(__name__, 'bitwise_or')
|
||||||
|
|
||||||
|
@ -24,8 +21,7 @@ CHUNK_SIZE = 2**20
|
||||||
|
|
||||||
def bitwise_or_argparse(args):
|
def bitwise_or_argparse(args):
|
||||||
patterns = pipeable.input_many(args.files, skip_blank=True, strip=True)
|
patterns = pipeable.input_many(args.files, skip_blank=True, strip=True)
|
||||||
files = [file for pattern in patterns for file in winglob.glob(pattern)]
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
files = [pathclass.Path(file) for file in files]
|
|
||||||
|
|
||||||
if len(files) < 2:
|
if len(files) < 2:
|
||||||
log.fatal('Need at least two input files.')
|
log.fatal('Need at least two input files.')
|
||||||
|
|
|
@ -23,6 +23,8 @@ def breplace_argparse(args):
|
||||||
command = f'x.replace("{replace_from}", "{replace_to}")'
|
command = f'x.replace("{replace_from}", "{replace_to}")'
|
||||||
brename.brename(command, autoyes=args.autoyes, recurse=args.recurse)
|
brename.brename(command, autoyes=args.autoyes, recurse=args.recurse)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(__doc__)
|
parser = argparse.ArgumentParser(__doc__)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ def clipboard_argparse(args):
|
||||||
text = text.replace('\r', '')
|
text = text.replace('\r', '')
|
||||||
print(text)
|
print(text)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import argparse
|
import argparse
|
||||||
import codecs
|
import codecs
|
||||||
import os
|
|
||||||
import pyperclip
|
import pyperclip
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
@ -71,6 +70,8 @@ def contentreplace_argparse(args):
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
log.error('%s encountered unicode decode error.', file.absolute_path)
|
log.error('%s encountered unicode decode error.', file.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
26
crc32.py
26
crc32.py
|
@ -1,26 +1,32 @@
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import zlib
|
import zlib
|
||||||
|
|
||||||
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
from voussoirkit import vlogging
|
||||||
|
|
||||||
|
log = vlogging.getLogger(__name__, 'crc32')
|
||||||
|
|
||||||
def crc32_argparse(args):
|
def crc32_argparse(args):
|
||||||
files = (
|
return_status = 0
|
||||||
file
|
|
||||||
for pattern in pipeable.input_many(args.patterns)
|
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
||||||
for file in winglob.glob(pattern)
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
if os.path.isfile(file)
|
|
||||||
)
|
|
||||||
for file in files:
|
for file in files:
|
||||||
try:
|
try:
|
||||||
with open(file, 'rb') as handle:
|
with open(file, 'rb') as handle:
|
||||||
crc = zlib.crc32(handle.read())
|
crc = zlib.crc32(handle.read())
|
||||||
print(hex(crc)[2:].rjust(8, '0'), file)
|
crc = hex(crc)[2:].rjust(8, '0')
|
||||||
|
pipeable.stdout(f'{crc} {file}')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(file, e)
|
log.error('%s %s', file, e)
|
||||||
|
return_status = 1
|
||||||
|
|
||||||
|
return return_status
|
||||||
|
|
||||||
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
36
crlf.py
36
crlf.py
|
@ -1,28 +1,46 @@
|
||||||
'''
|
'''
|
||||||
Convert LF line endings to CRLF.
|
Convert LF line endings to CRLF.
|
||||||
'''
|
'''
|
||||||
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
CR = b'\x0D'
|
CR = b'\x0D'
|
||||||
LF = b'\x0A'
|
LF = b'\x0A'
|
||||||
CRLF = CR + LF
|
CRLF = CR + LF
|
||||||
|
|
||||||
def crlf(filename):
|
def crlf(file):
|
||||||
with open(filename, 'rb') as handle:
|
with file.open('rb') as handle:
|
||||||
content = handle.read()
|
content = handle.read()
|
||||||
|
|
||||||
|
original = content
|
||||||
content = content.replace(CRLF, LF)
|
content = content.replace(CRLF, LF)
|
||||||
content = content.replace(LF, CRLF)
|
content = content.replace(LF, CRLF)
|
||||||
with open(filename, 'wb') as handle:
|
if content == original:
|
||||||
|
return
|
||||||
|
|
||||||
|
with file.open('wb') as handle:
|
||||||
handle.write(content)
|
handle.write(content)
|
||||||
|
|
||||||
def main(args):
|
def crlf_argparse(args):
|
||||||
for line in pipeable.go(args, strip=True, skip_blank=True):
|
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
||||||
for filename in winglob.glob(line):
|
files = pathclass.glob_many(patterns)
|
||||||
pipeable.stdout(filename)
|
for file in files:
|
||||||
crlf(filename)
|
crlf(file)
|
||||||
|
pipeable.stdout(file)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
parser.add_argument('patterns')
|
||||||
|
parser.set_defaults(func=crlf_argparse)
|
||||||
|
|
||||||
|
args = parser.parse_args(argv)
|
||||||
|
return args.func(args)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
raise SystemExit(main(sys.argv[1:]))
|
raise SystemExit(main(sys.argv[1:]))
|
||||||
|
|
26
crop.py
26
crop.py
|
@ -1,13 +1,12 @@
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
def crop(filename, crops, *, inplace=False):
|
def crop(file, crops, *, inplace=False):
|
||||||
image = PIL.Image.open(filename)
|
image = PIL.Image.open(file.absolute_path)
|
||||||
if len(crops) == 2:
|
if len(crops) == 2:
|
||||||
crops.extend(image.size)
|
crops.extend(image.size)
|
||||||
|
|
||||||
|
@ -20,24 +19,27 @@ def crop(filename, crops, *, inplace=False):
|
||||||
|
|
||||||
image = image.crop(crops)
|
image = image.crop(crops)
|
||||||
if inplace:
|
if inplace:
|
||||||
newname = filename
|
newname = file
|
||||||
else:
|
else:
|
||||||
suffix = '_'.join(str(x) for x in crops)
|
suffix = '_'.join(str(x) for x in crops)
|
||||||
suffix = f'_{suffix}'
|
suffix = f'_{suffix}'
|
||||||
(base, extension) = os.path.splitext(filename)
|
base = file.replace_extension('').basename
|
||||||
newname = base + suffix + extension
|
newname = file.parent.with_child(base + suffix).add_extension(file.extension)
|
||||||
|
|
||||||
pipeable.stdout(newname)
|
pipeable.stdout(newname.absolute_path)
|
||||||
image.save(newname, exif=image.info.get('exif', b''), quality=100)
|
image.save(newname.absolute_path, exif=image.info.get('exif', b''), quality=100)
|
||||||
|
|
||||||
def crop_argparse(args):
|
def crop_argparse(args):
|
||||||
filenames = winglob.glob(args.pattern)
|
patterns = pipeable.input(args.pattern, skip_blank=True, strip=True)
|
||||||
for filename in filenames:
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
crop(
|
crop(
|
||||||
filename,
|
file,
|
||||||
crops=args.crops,
|
crops=args.crops,
|
||||||
inplace=args.inplace,
|
inplace=args.inplace,
|
||||||
)
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
23
delete.py
23
delete.py
|
@ -1,14 +1,19 @@
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
for pattern in pipeable.go(skip_blank=True):
|
def main(argv):
|
||||||
for name in winglob.glob(pattern):
|
for path in pathclass.glob_many(pipeable.go(argv, skip_blank=True)):
|
||||||
if os.path.isfile(name):
|
if path.is_file:
|
||||||
pipeable.stdout(name)
|
pipeable.stdout(path.absolute_path)
|
||||||
os.remove(name)
|
os.remove(path.absolute_path)
|
||||||
elif os.path.isdir(name):
|
elif path.is_dir:
|
||||||
pipeable.stdout(name)
|
pipeable.stdout(path.absolute_path)
|
||||||
shutil.rmtree(name)
|
shutil.rmtree(path.absolute_path)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
raise SystemExit(main(sys.argv[1:]))
|
||||||
|
|
|
@ -45,6 +45,8 @@ def directory_discrepancy_argparse(args):
|
||||||
for discrepancy in sorted(files2.difference(files1)):
|
for discrepancy in sorted(files2.difference(files1)):
|
||||||
print(discrepancy)
|
print(discrepancy)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -55,6 +55,8 @@ def drawquarter_argparse(args):
|
||||||
print(output_filename.relative_path)
|
print(output_filename.relative_path)
|
||||||
piece.save(output_filename.absolute_path)
|
piece.save(output_filename.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,17 @@ import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
def empty_directories_argparse(args):
|
def empty_directories_argparse(args):
|
||||||
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
||||||
directories = (pathclass.Path(d) for pattern in patterns for d in winglob.glob(pattern))
|
directories = pathclass.glob_many(patterns, directories=True)
|
||||||
directories = (d for d in directories if d.is_dir)
|
|
||||||
|
|
||||||
for directory in directories:
|
for directory in directories:
|
||||||
if len(directory.listdir()) == 0:
|
if len(directory.listdir()) == 0:
|
||||||
pipeable.stdout(directory.absolute_path)
|
pipeable.stdout(directory.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
2
eval.py
2
eval.py
|
@ -25,6 +25,8 @@ def eval_argparse(args):
|
||||||
x = line
|
x = line
|
||||||
pipeable.stdout(eval(args.eval_string))
|
pipeable.stdout(eval(args.eval_string))
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ import bs4
|
||||||
import requests
|
import requests
|
||||||
import sys
|
import sys
|
||||||
import tenacity
|
import tenacity
|
||||||
import time
|
|
||||||
|
|
||||||
from voussoirkit import betterhelp
|
from voussoirkit import betterhelp
|
||||||
from voussoirkit import downloady
|
from voussoirkit import downloady
|
||||||
|
|
|
@ -138,6 +138,8 @@ def ffstreams_argparse(args):
|
||||||
moveto=args.moveto,
|
moveto=args.moveto,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -16,9 +16,8 @@ argv = sys.argv[1:]
|
||||||
|
|
||||||
randname = [random.choice(string.digits) for x in range(12)]
|
randname = [random.choice(string.digits) for x in range(12)]
|
||||||
randname = int(''.join(randname))
|
randname = int(''.join(randname))
|
||||||
for pattern in argv:
|
|
||||||
for path in winglob.glob(pattern):
|
for path in pathclass.glob_many(argv):
|
||||||
path = pathclass.Path(path)
|
|
||||||
newname = str(randname).rjust(12, '0') + path.dot_extension
|
newname = str(randname).rjust(12, '0') + path.dot_extension
|
||||||
randname += 1
|
randname += 1
|
||||||
newname = path.parent.with_child(newname)
|
newname = path.parent.with_child(newname)
|
||||||
|
|
|
@ -9,13 +9,10 @@ import string
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
argv = sys.argv[1:]
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
for pattern in argv:
|
for path in pathclass.glob_many(argv):
|
||||||
for path in winglob.glob(pattern):
|
|
||||||
path = pathclass.Path(path)
|
|
||||||
newname = [random.choice(string.ascii_lowercase) for x in range(9)]
|
newname = [random.choice(string.ascii_lowercase) for x in range(9)]
|
||||||
newname = ''.join(newname) + path.dot_extension
|
newname = ''.join(newname) + path.dot_extension
|
||||||
newname = path.parent.with_child(newname)
|
newname = path.parent.with_child(newname)
|
||||||
|
|
|
@ -9,13 +9,10 @@ import string
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
argv = sys.argv[1:]
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
for pattern in argv:
|
for path in pathclass.glob_many(argv):
|
||||||
for path in winglob.glob(pattern):
|
|
||||||
path = pathclass.Path(path)
|
|
||||||
newname = [random.choice(string.digits) for x in range(12)]
|
newname = [random.choice(string.digits) for x in range(12)]
|
||||||
newname = ''.join(newname) + path.dot_extension
|
newname = ''.join(newname) + path.dot_extension
|
||||||
newname = path.parent.with_child(newname)
|
newname = path.parent.with_child(newname)
|
||||||
|
|
|
@ -42,6 +42,7 @@ def filepull(pull_from='.', autoyes=False):
|
||||||
|
|
||||||
def filepull_argparse(args):
|
def filepull_argparse(args):
|
||||||
filepull(pull_from=args.pull_from, autoyes=args.autoyes)
|
filepull(pull_from=args.pull_from, autoyes=args.autoyes)
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
17
grayscale.py
17
grayscale.py
|
@ -3,7 +3,7 @@ import PIL.Image
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import winglob
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
def grayscale(filename, *, inplace=False):
|
def grayscale(filename, *, inplace=False):
|
||||||
filename = pathclass.Path(filename)
|
filename = pathclass.Path(filename)
|
||||||
|
@ -20,18 +20,23 @@ def grayscale(filename, *, inplace=False):
|
||||||
|
|
||||||
image = PIL.Image.open(filename.absolute_path)
|
image = PIL.Image.open(filename.absolute_path)
|
||||||
image = image.convert('LA').convert(image.mode)
|
image = image.convert('LA').convert(image.mode)
|
||||||
print(f'{new_filename.absolute_path}')
|
|
||||||
image.save(new_filename.absolute_path, exif=image.info.get('exif', b''))
|
image.save(new_filename.absolute_path, exif=image.info.get('exif', b''))
|
||||||
|
return new_filename
|
||||||
|
|
||||||
def grayscale_argparse(args):
|
def grayscale_argparse(args):
|
||||||
filenames = winglob.glob(args.pattern)
|
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
||||||
for filename in filenames:
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
grayscale(filename, inplace=args.inplace)
|
for file in files:
|
||||||
|
new_filename = grayscale(file, inplace=args.inplace)
|
||||||
|
if new_filename:
|
||||||
|
pipeable.stdout(new_filename.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
parser.add_argument('pattern')
|
parser.add_argument('patterns', nargs='+')
|
||||||
parser.add_argument('--inplace', action='store_true')
|
parser.add_argument('--inplace', action='store_true')
|
||||||
parser.set_defaults(func=grayscale_argparse)
|
parser.set_defaults(func=grayscale_argparse)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ def groupsof_argparse(args):
|
||||||
for chunk in chunks:
|
for chunk in chunks:
|
||||||
chunk = args.separator.join(chunk)
|
chunk = args.separator.join(chunk)
|
||||||
pipeable.stdout(chunk)
|
pipeable.stdout(chunk)
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -65,6 +65,8 @@ def hash_hardlink_argparse(args):
|
||||||
send2trash.send2trash(follower.absolute_path)
|
send2trash.send2trash(follower.absolute_path)
|
||||||
os.link(leader.absolute_path, follower.absolute_path)
|
os.link(leader.absolute_path, follower.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -27,7 +27,11 @@ def root():
|
||||||
|
|
||||||
def heresmyclipboard_argparse(args):
|
def heresmyclipboard_argparse(args):
|
||||||
log.info(f'Starting server on port {args.port}, pid={os.getpid()}')
|
log.info(f'Starting server on port {args.port}, pid={os.getpid()}')
|
||||||
|
try:
|
||||||
site.run(host='0.0.0.0', port=args.port)
|
site.run(host='0.0.0.0', port=args.port)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
|
|
|
@ -5,7 +5,6 @@ import argparse
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def full_hex(h):
|
def full_hex(h):
|
||||||
h = h.replace('#', '')
|
h = h.replace('#', '')
|
||||||
if len(h) in [3, 4]:
|
if len(h) in [3, 4]:
|
||||||
|
@ -28,6 +27,7 @@ def make_hexpng(h, width=1, height=1):
|
||||||
|
|
||||||
def hexpng_argparse(args):
|
def hexpng_argparse(args):
|
||||||
make_hexpng(args.hex_value, width=args.width, height=args.height)
|
make_hexpng(args.hex_value, width=args.width, height=args.height)
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -131,43 +131,59 @@ def load_image(filename):
|
||||||
return image
|
return image
|
||||||
|
|
||||||
def build_ico_header_blob(image_count):
|
def build_ico_header_blob(image_count):
|
||||||
datablob = (b''
|
datablob = b''.join([
|
||||||
+ little(0, 2) # reserved
|
# reserved
|
||||||
+ little(1, 2) # 1 = ico type
|
little(0, 2),
|
||||||
+ little(image_count, 2)
|
# 1 = ico type
|
||||||
)
|
little(1, 2),
|
||||||
|
little(image_count, 2),
|
||||||
|
])
|
||||||
return datablob
|
return datablob
|
||||||
|
|
||||||
def build_icon_directory_blob(image, offset_from_start):
|
def build_icon_directory_blob(image, offset_from_start):
|
||||||
(width, height) = image.size
|
(width, height) = image.size
|
||||||
datablob = (b''
|
datablob = b''.join([
|
||||||
+ little(width if width < 256 else 0, 1)
|
little(width if width < 256 else 0, 1),
|
||||||
+ little(height if height < 256 else 0, 1)
|
little(height if height < 256 else 0, 1),
|
||||||
+ little(0, 1) # colors in palette
|
# colors in palette
|
||||||
+ little(0, 1) # reserved
|
little(0, 1),
|
||||||
+ little(1, 2) # color planes
|
# reserved
|
||||||
+ little(32, 2) # bit depth
|
little(0, 1),
|
||||||
+ little((width * height * 4) + BMP_HEADER_LENGTH, 4) # image bytes length
|
# color planes
|
||||||
+ little(offset_from_start, 4)
|
little(1, 2),
|
||||||
)
|
# bit depth
|
||||||
|
little(32, 2),
|
||||||
|
# image bytes length
|
||||||
|
little((width * height * 4) + BMP_HEADER_LENGTH, 4),
|
||||||
|
little(offset_from_start, 4),
|
||||||
|
])
|
||||||
return datablob
|
return datablob
|
||||||
|
|
||||||
def build_image_data_blob(image):
|
def build_image_data_blob(image):
|
||||||
datablob = (b''
|
datablob = b''.join([
|
||||||
+ little(40, 4) # header size
|
# header size
|
||||||
+ little(image.size[0], 4)
|
little(40, 4),
|
||||||
|
little(image.size[0], 4),
|
||||||
# "Even if the AND mask is not supplied, if the image is in Windows BMP
|
# "Even if the AND mask is not supplied, if the image is in Windows BMP
|
||||||
# format, the BMP header must still specify a doubled height." - wikipedia
|
# format, the BMP header must still specify a doubled height." - wikipedia
|
||||||
+ little(image.size[1] * 2, 4)
|
little(image.size[1] * 2, 4),
|
||||||
+ little(1, 2) # color planes
|
# color planes
|
||||||
+ little(32, 2) # bit depth
|
little(1, 2),
|
||||||
+ little(0, 4) # no compression
|
# bit depth
|
||||||
+ little(0, 4) # bytes length, inferred
|
little(32, 2),
|
||||||
+ little(0, 4) # hor print
|
# no compression
|
||||||
+ little(0, 4) # ver print
|
little(0, 4),
|
||||||
+ little(0, 4) # palette
|
# bytes length, inferred
|
||||||
+ little(0, 4) # important palette
|
little(0, 4),
|
||||||
)
|
# hor print
|
||||||
|
little(0, 4),
|
||||||
|
# ver print
|
||||||
|
little(0, 4),
|
||||||
|
# palette
|
||||||
|
little(0, 4),
|
||||||
|
# important palette
|
||||||
|
little(0, 4),
|
||||||
|
])
|
||||||
pixeldata = []
|
pixeldata = []
|
||||||
# Image.getdata() is a list of (r, g, b, a) channels
|
# Image.getdata() is a list of (r, g, b, a) channels
|
||||||
# But the BMP are written (b, g, r, a)
|
# But the BMP are written (b, g, r, a)
|
||||||
|
@ -214,11 +230,10 @@ def images_to_ico(images):
|
||||||
final_data = b''.join(datablobs)
|
final_data = b''.join(datablobs)
|
||||||
return final_data
|
return final_data
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
inputfiles = sys.argv[1:]
|
inputfiles = sys.argv[1:]
|
||||||
except:
|
except Exception:
|
||||||
print('Please provide an image file')
|
print('Please provide an image file')
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
print('Iconifying', inputfiles)
|
print('Iconifying', inputfiles)
|
||||||
|
|
20
inodes.py
20
inodes.py
|
@ -1,12 +1,24 @@
|
||||||
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from voussoirkit import betterhelp
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
|
def inodes_argparse(args):
|
||||||
|
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
||||||
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
|
for file in files:
|
||||||
|
pipeable.stdout(f'{file.stat.st_dev} {file.stat.st_ino} {file.relative_path}')
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
for file in pathclass.cwd().listdir():
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
if not file.is_file:
|
|
||||||
continue
|
parser.add_argument('patterns', nargs='+')
|
||||||
print(file.stat.st_dev, file.stat.st_ino, file.relative_path)
|
parser.set_defaults(func=inodes_argparse)
|
||||||
|
|
||||||
|
return betterhelp.single_main(argv, parser, __doc__)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
raise SystemExit(main(sys.argv[1:]))
|
raise SystemExit(main(sys.argv[1:]))
|
||||||
|
|
|
@ -17,7 +17,7 @@ def inputrename_argparse(args):
|
||||||
files = (file for file in pathclass.cwd().listdir() if args.keyword in file.basename)
|
files = (file for file in pathclass.cwd().listdir() if args.keyword in file.basename)
|
||||||
prev = None
|
prev = None
|
||||||
for file in files:
|
for file in files:
|
||||||
print(file.relative_path)
|
pipeable.stderr(file.relative_path)
|
||||||
this = input('> ')
|
this = input('> ')
|
||||||
if this == '' and prev is not None:
|
if this == '' and prev is not None:
|
||||||
this = prev
|
this = prev
|
||||||
|
@ -27,6 +27,8 @@ def inputrename_argparse(args):
|
||||||
os.rename(file.absolute_path, new_name.absolute_path)
|
os.rename(file.absolute_path, new_name.absolute_path)
|
||||||
prev = this
|
prev = this
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@ def main(argv):
|
||||||
check_forever()
|
check_forever()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
raise SystemExit(main(sys.argv[1:]))
|
raise SystemExit(main(sys.argv[1:]))
|
||||||
|
|
|
@ -12,7 +12,9 @@ def linenumbers_argparse(args):
|
||||||
digits = len(str(len(lines)))
|
digits = len(str(len(lines)))
|
||||||
form = '{no:>0%d} | {line}' % digits
|
form = '{no:>0%d} | {line}' % digits
|
||||||
for (index, line) in enumerate(lines):
|
for (index, line) in enumerate(lines):
|
||||||
print(form.format(no=index+1, line=line))
|
pipeable.stdout(form.format(no=index+1, line=line))
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -3,7 +3,6 @@ lint_argparse_returns
|
||||||
=====================
|
=====================
|
||||||
'''
|
'''
|
||||||
import ast
|
import ast
|
||||||
import argparse
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
|
|
||||||
for line in pipeable.go():
|
for line in pipeable.go():
|
||||||
pipeable.stdout(line.lower())
|
pipeable.stdout(line.lower())
|
||||||
|
|
16
move_all.py
16
move_all.py
|
@ -8,17 +8,15 @@ import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
def moveall_argparse(args):
|
def moveall_argparse(args):
|
||||||
files = (
|
patterns = pipeable.input(args.source, skip_blank=True, strip=True)
|
||||||
pathclass.Path(file)
|
files = pathclass.glob_many(patterns)
|
||||||
for pattern in pipeable.input(args.source)
|
|
||||||
for file in winglob.glob(pattern)
|
|
||||||
)
|
|
||||||
destination = pathclass.Path(args.destination)
|
|
||||||
|
|
||||||
if not destination.is_dir:
|
destination = pathclass.Path(args.destination)
|
||||||
|
try:
|
||||||
|
destination.assert_is_directory()
|
||||||
|
except pathclass.NotDirectory:
|
||||||
pipeable.stderr('destination must be a directory.')
|
pipeable.stderr('destination must be a directory.')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@ -39,6 +37,8 @@ def moveall_argparse(args):
|
||||||
pipeable.stdout(new_path.absolute_path)
|
pipeable.stdout(new_path.absolute_path)
|
||||||
shutil.move(file.absolute_path, new_path.absolute_path)
|
shutil.move(file.absolute_path, new_path.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import sys
|
||||||
|
|
||||||
from voussoirkit import bytestring
|
from voussoirkit import bytestring
|
||||||
|
|
||||||
|
|
||||||
def parse_rules(lines):
|
def parse_rules(lines):
|
||||||
rules = []
|
rules = []
|
||||||
for (times, title) in lines[::-1]:
|
for (times, title) in lines[::-1]:
|
||||||
|
@ -125,7 +124,7 @@ def _unitconvert(value):
|
||||||
else:
|
else:
|
||||||
return bytestring.parsebytes(value)
|
return bytestring.parsebytes(value)
|
||||||
|
|
||||||
def example_argparse(args):
|
def mp3slice_argparse(args):
|
||||||
if len(args.rules) == 1 and os.path.isfile(args.rules[0]):
|
if len(args.rules) == 1 and os.path.isfile(args.rules[0]):
|
||||||
rules = read_rulefile(args.rules[0])
|
rules = read_rulefile(args.rules[0])
|
||||||
else:
|
else:
|
||||||
|
@ -155,14 +154,14 @@ def example_argparse(args):
|
||||||
command = 'ffmpeg -i "%s" %s' % (args.input_filename, outputters)
|
command = 'ffmpeg -i "%s" %s' % (args.input_filename, outputters)
|
||||||
print(command)
|
print(command)
|
||||||
os.system(command)
|
os.system(command)
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
parser.add_argument('input_filename')
|
parser.add_argument('input_filename')
|
||||||
parser.add_argument('rules', nargs='+', default=None)
|
parser.add_argument('rules', nargs='+', default=None)
|
||||||
parser.set_defaults(func=example_argparse)
|
parser.set_defaults(func=mp3slice_argparse)
|
||||||
|
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
return args.func(args)
|
return args.func(args)
|
||||||
|
|
|
@ -3,17 +3,17 @@ import sys
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
def nonempty_directories_argparse(args):
|
def nonempty_directories_argparse(args):
|
||||||
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
||||||
directories = (pathclass.Path(d) for pattern in patterns for d in winglob.glob(pattern))
|
directories = pathclass.glob_many(patterns, directories=True)
|
||||||
directories = (d for d in directories if d.is_dir)
|
|
||||||
|
|
||||||
for directory in directories:
|
for directory in directories:
|
||||||
if len(directory.listdir()) != 0:
|
if len(directory.listdir()) != 0:
|
||||||
pipeable.stdout(directory.absolute_path)
|
pipeable.stdout(directory.absolute_path)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
15
pickn.py
15
pickn.py
|
@ -1,26 +1,31 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
import itertools
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
def shuffle_argparse(args):
|
def pickn_argparse(args):
|
||||||
if args.count < 1:
|
if args.count < 1:
|
||||||
pipeable.stderr('count must be >= 1.')
|
pipeable.stderr('count must be >= 1.')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
lines = pipeable.input(args.source, read_files=True, skip_blank=True, strip=True)
|
lines = pipeable.input(args.source, read_files=True, skip_blank=True, strip=True)
|
||||||
lines = list(lines)
|
|
||||||
lines = lines[:args.count]
|
|
||||||
|
|
||||||
for line in lines:
|
for line in itertools.islice(lines, args.count):
|
||||||
pipeable.stdout(line)
|
pipeable.stdout(line)
|
||||||
|
|
||||||
|
# Exhaust the rest of stdin so we don't get Broken Pipe error
|
||||||
|
for line in lines:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
parser.add_argument('source')
|
parser.add_argument('source')
|
||||||
parser.add_argument('count', type=int)
|
parser.add_argument('count', type=int)
|
||||||
parser.set_defaults(func=shuffle_argparse)
|
parser.set_defaults(func=pickn_argparse)
|
||||||
|
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
return args.func(args)
|
return args.func(args)
|
||||||
|
|
|
@ -38,11 +38,12 @@ def pip_download(package):
|
||||||
os.rename(os.path.join(tmpdir.name, filename), os.path.join(new_directory, filename))
|
os.rename(os.path.join(tmpdir.name, filename), os.path.join(new_directory, filename))
|
||||||
tmpdir.cleanup()
|
tmpdir.cleanup()
|
||||||
|
|
||||||
|
|
||||||
def pip_download_argparse(args):
|
def pip_download_argparse(args):
|
||||||
for package in args.packages:
|
for package in args.packages:
|
||||||
pip_download(package)
|
pip_download(package)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ from voussoirkit import betterhelp
|
||||||
from voussoirkit import spinal
|
from voussoirkit import spinal
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
|
|
||||||
|
|
||||||
def prune_dirs(starting):
|
def prune_dirs(starting):
|
||||||
starting = pathclass.Path(starting)
|
starting = pathclass.Path(starting)
|
||||||
walker = spinal.walk(starting, yield_directories=True, yield_files=False)
|
walker = spinal.walk(starting, yield_directories=True, yield_files=False)
|
||||||
|
@ -36,7 +35,6 @@ def prune_dirs(starting):
|
||||||
directory = double_check.pop()
|
directory = double_check.pop()
|
||||||
pruneme(directory)
|
pruneme(directory)
|
||||||
|
|
||||||
|
|
||||||
def prune_dirs_argparse(args):
|
def prune_dirs_argparse(args):
|
||||||
return prune_dirs(args.starting)
|
return prune_dirs(args.starting)
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ def make_randomfile(length, filename=None):
|
||||||
f.close()
|
f.close()
|
||||||
print('Created %s' % filename)
|
print('Created %s' % filename)
|
||||||
|
|
||||||
|
|
||||||
bytes = listget(sys.argv, 1, None)
|
bytes = listget(sys.argv, 1, None)
|
||||||
if bytes is None:
|
if bytes is None:
|
||||||
bytes = 2 ** 10
|
bytes = 2 ** 10
|
||||||
|
|
17
recycle.py
17
recycle.py
|
@ -1,11 +1,14 @@
|
||||||
import os
|
|
||||||
import send2trash
|
import send2trash
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
for pattern in pipeable.go(skip_blank=True):
|
def main(argv):
|
||||||
for name in winglob.glob(pattern):
|
for path in pathclass.glob_many(pipeable.go(argv, skip_blank=True)):
|
||||||
name = os.path.abspath(name)
|
pipeable.stdout(path.absolute_path)
|
||||||
pipeable.stdout(name)
|
send2trash.send2trash(path.absolute_path)
|
||||||
send2trash.send2trash(name)
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
raise SystemExit(main(sys.argv[1:]))
|
||||||
|
|
|
@ -5,7 +5,7 @@ from voussoirkit import pipeable
|
||||||
|
|
||||||
for line in pipeable.go():
|
for line in pipeable.go():
|
||||||
if os.path.isfile(line):
|
if os.path.isfile(line):
|
||||||
print('Recycling', line)
|
pipeable.stdout(line)
|
||||||
send2trash.send2trash(line)
|
send2trash.send2trash(line)
|
||||||
else:
|
else:
|
||||||
print('Not a file', line)
|
pipeable.stderr('Not a file', line)
|
||||||
|
|
11
rejpg.py
11
rejpg.py
|
@ -12,6 +12,9 @@ from voussoirkit import bytestring
|
||||||
from voussoirkit import imagetools
|
from voussoirkit import imagetools
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import spinal
|
from voussoirkit import spinal
|
||||||
|
from voussoirkit import vlogging
|
||||||
|
|
||||||
|
log = vlogging.getLogger(__name__, 'rejpg')
|
||||||
|
|
||||||
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
|
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||||
|
|
||||||
|
@ -24,7 +27,7 @@ def rejpg_argparse(args):
|
||||||
bytes_saved = 0
|
bytes_saved = 0
|
||||||
remaining_size = 0
|
remaining_size = 0
|
||||||
for filename in files:
|
for filename in files:
|
||||||
print(filename)
|
log.info('Processing %s.', filename)
|
||||||
bytesio = io.BytesIO()
|
bytesio = io.BytesIO()
|
||||||
image = PIL.Image.open(filename)
|
image = PIL.Image.open(filename)
|
||||||
|
|
||||||
|
@ -43,9 +46,11 @@ def rejpg_argparse(args):
|
||||||
f.write(new_bytes)
|
f.write(new_bytes)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
print('Saved', bytestring.bytestring(bytes_saved))
|
log.info('Saved', bytestring.bytestring(bytes_saved))
|
||||||
print('Remaining are', bytestring.bytestring(remaining_size))
|
log.info('Remaining are', bytestring.bytestring(remaining_size))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
23
repeat.py
23
repeat.py
|
@ -2,6 +2,9 @@
|
||||||
Repeat the input as many times as you want.
|
Repeat the input as many times as you want.
|
||||||
|
|
||||||
> repeat "hello" 8
|
> repeat "hello" 8
|
||||||
|
|
||||||
|
> repeat "yowza" inf
|
||||||
|
|
||||||
> echo hi | repeat !i 4
|
> echo hi | repeat !i 4
|
||||||
'''
|
'''
|
||||||
import argparse
|
import argparse
|
||||||
|
@ -9,17 +12,16 @@ import sys
|
||||||
|
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
def repeat_argparse(args):
|
def repeat_inf(text):
|
||||||
text = pipeable.input(args.text, split_lines=False)
|
|
||||||
if args.times == 'inf':
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
print(text)
|
pipeable.stdout(text)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
return 0
|
return 0
|
||||||
else:
|
|
||||||
|
def repeat_times(text, times):
|
||||||
try:
|
try:
|
||||||
times = int(args.times)
|
times = int(times)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pipeable.stderr('times should be an integer >= 1.')
|
pipeable.stderr('times should be an integer >= 1.')
|
||||||
return 1
|
return 1
|
||||||
|
@ -30,10 +32,17 @@ def repeat_argparse(args):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for t in range(times):
|
for t in range(times):
|
||||||
print(text)
|
pipeable.stdout(text)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def repeat_argparse(args):
|
||||||
|
text = pipeable.input(args.text, split_lines=False)
|
||||||
|
if args.times == 'inf':
|
||||||
|
return repeat_inf(text)
|
||||||
|
else:
|
||||||
|
return repeat_times(text, args.times)
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import sys
|
||||||
|
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
|
|
||||||
lines = pipeable.input(sys.argv[1])
|
lines = pipeable.input(sys.argv[1])
|
||||||
replace_from = sys.argv[2]
|
replace_from = sys.argv[2]
|
||||||
replace_to = sys.argv[3]
|
replace_to = sys.argv[3]
|
||||||
|
|
1
repr.py
1
repr.py
|
@ -1,5 +1,4 @@
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
|
|
||||||
for line in pipeable.go():
|
for line in pipeable.go():
|
||||||
print(repr(line))
|
print(repr(line))
|
||||||
|
|
10
resize.py
10
resize.py
|
@ -38,7 +38,6 @@ from voussoirkit import imagetools
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import vlogging
|
from voussoirkit import vlogging
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
log = vlogging.getLogger(__name__, 'resize')
|
log = vlogging.getLogger(__name__, 'resize')
|
||||||
|
|
||||||
|
@ -102,10 +101,11 @@ def resize(
|
||||||
image.save(new_name.absolute_path, exif=image.info.get('exif', b''), quality=quality)
|
image.save(new_name.absolute_path, exif=image.info.get('exif', b''), quality=quality)
|
||||||
|
|
||||||
def resize_argparse(args):
|
def resize_argparse(args):
|
||||||
filenames = winglob.glob(args.pattern)
|
patterns = pipeable.input(args.pattern, skip_blank=True, strip=True)
|
||||||
for filename in filenames:
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
|
for file in files:
|
||||||
resize(
|
resize(
|
||||||
filename,
|
file,
|
||||||
args.new_w,
|
args.new_w,
|
||||||
args.new_h,
|
args.new_h,
|
||||||
inplace=args.inplace,
|
inplace=args.inplace,
|
||||||
|
@ -115,6 +115,8 @@ def resize_argparse(args):
|
||||||
quality=args.quality,
|
quality=args.quality,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -4,13 +4,17 @@ Reverse a string.
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
def reverse_argparse(args):
|
def reverse_argparse(args):
|
||||||
print(''.join(reversed(args.string)))
|
text = pipeable.input(args.text, split_lines=False)
|
||||||
|
pipeable.stdout(''.join(reversed(text)))
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
parser.add_argument('string')
|
parser.add_argument('text')
|
||||||
parser.set_defaults(func=reverse_argparse)
|
parser.set_defaults(func=reverse_argparse)
|
||||||
|
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
|
|
|
@ -8,8 +8,8 @@ from voussoirkit import pipeable
|
||||||
|
|
||||||
def reverse_argparse(args):
|
def reverse_argparse(args):
|
||||||
lines = list(pipeable.input(args.lines))
|
lines = list(pipeable.input(args.lines))
|
||||||
lines.reverse()
|
pipeable.stdout('\n'.join(reversed(lines)))
|
||||||
print('\n'.join(lines))
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
26
rotate.py
26
rotate.py
|
@ -1,28 +1,29 @@
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import imagetools
|
from voussoirkit import imagetools
|
||||||
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import vlogging
|
from voussoirkit import vlogging
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
log = vlogging.getLogger(__name__, 'rotate')
|
log = vlogging.getLogger(__name__, 'rotate')
|
||||||
|
|
||||||
def rotate_argparse(args):
|
def rotate_argparse(args):
|
||||||
if args.angle is None and not args.exif:
|
if args.angle is None and not args.exif:
|
||||||
pipeable.stderr('Either an angle or --exif must be provided.')
|
log.fatal('Either an angle or --exif must be provided.')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
filenames = winglob.glob(args.pattern)
|
patterns = pipeable.input(args.pattern, skip_blank=True, strip=True)
|
||||||
for filename in filenames:
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
image = PIL.Image.open(filename)
|
|
||||||
|
for file in files:
|
||||||
|
image = PIL.Image.open(file.absolute_path)
|
||||||
|
|
||||||
if args.exif:
|
if args.exif:
|
||||||
(new_image, exif) = imagetools.rotate_by_exif(image)
|
(new_image, exif) = imagetools.rotate_by_exif(image)
|
||||||
if new_image is image:
|
if new_image is image:
|
||||||
log.debug('%s doesn\'t need exif rotation.', filename)
|
log.debug('%s doesn\'t need exif rotation.', file.absolute_path)
|
||||||
continue
|
continue
|
||||||
image = new_image
|
image = new_image
|
||||||
else:
|
else:
|
||||||
|
@ -30,16 +31,19 @@ def rotate_argparse(args):
|
||||||
image = image.rotate(args.angle, expand=True)
|
image = image.rotate(args.angle, expand=True)
|
||||||
|
|
||||||
if args.inplace:
|
if args.inplace:
|
||||||
newname = filename
|
newname = file
|
||||||
else:
|
else:
|
||||||
if args.exif:
|
if args.exif:
|
||||||
suffix = f'_exifrot'
|
suffix = f'_exifrot'
|
||||||
else:
|
else:
|
||||||
suffix = f'_{args.angle}'
|
suffix = f'_{args.angle}'
|
||||||
(base, extension) = os.path.splitext(filename)
|
|
||||||
newname = base + suffix + extension
|
base = file.replace_extension('').basename
|
||||||
|
newname = base + suffix
|
||||||
|
newname = file.parent.with_child(newname).add_extension(file.extension)
|
||||||
|
|
||||||
pipeable.stdout(newname)
|
pipeable.stdout(newname)
|
||||||
image.save(newname, exif=exif, quality=args.quality)
|
image.save(file.absolute_path, exif=exif, quality=args.quality)
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
|
|
|
@ -251,6 +251,7 @@ def _search_argparse(args):
|
||||||
result_count += 1
|
result_count += 1
|
||||||
if args.show_count:
|
if args.show_count:
|
||||||
print('%d items.' % result_count)
|
print('%d items.' % result_count)
|
||||||
|
return 0
|
||||||
|
|
||||||
@pipeable.ctrlc_return1
|
@pipeable.ctrlc_return1
|
||||||
def search_argparse(args):
|
def search_argparse(args):
|
||||||
|
|
|
@ -12,6 +12,8 @@ def shuffle_argparse(args):
|
||||||
for line in lines:
|
for line in lines:
|
||||||
pipeable.stdout(line)
|
pipeable.stdout(line)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
3
size.py
3
size.py
|
@ -14,7 +14,8 @@ def main(argv):
|
||||||
elif path.is_dir:
|
elif path.is_dir:
|
||||||
total += spinal.get_dir_size(path)
|
total += spinal.get_dir_size(path)
|
||||||
|
|
||||||
print(total)
|
pipeable.stdout(total)
|
||||||
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
raise SystemExit(main(sys.argv[1:]))
|
raise SystemExit(main(sys.argv[1:]))
|
||||||
|
|
|
@ -53,6 +53,8 @@ def sole_lift_argparse(args):
|
||||||
os.rmdir(temp_dir.absolute_path)
|
os.rmdir(temp_dir.absolute_path)
|
||||||
queue.append(directory.parent)
|
queue.append(directory.parent)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -14,6 +14,8 @@ def sorted_argparse(args):
|
||||||
for line in lines:
|
for line in lines:
|
||||||
pipeable.stdout(line)
|
pipeable.stdout(line)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ def printstderr_argparse(args):
|
||||||
for line in text:
|
for line in text:
|
||||||
pipeable.stderr(line)
|
pipeable.stderr(line)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -12,6 +12,8 @@ def printstdout_argparse(args):
|
||||||
for line in text:
|
for line in text:
|
||||||
pipeable.stdout(line)
|
pipeable.stdout(line)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -2,10 +2,10 @@ import PIL.Image
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from voussoirkit import pathclass
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
from voussoirkit import sentinel
|
from voussoirkit import sentinel
|
||||||
from voussoirkit import vlogging
|
from voussoirkit import vlogging
|
||||||
from voussoirkit import winglob
|
|
||||||
|
|
||||||
log = vlogging.getLogger(__name__, 'stitch')
|
log = vlogging.getLogger(__name__, 'stitch')
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@ HORIZONTAL = sentinel.Sentinel('horizontal')
|
||||||
|
|
||||||
def stitch_argparse(args):
|
def stitch_argparse(args):
|
||||||
patterns = pipeable.input_many(args.image_files, skip_blank=True, strip=True)
|
patterns = pipeable.input_many(args.image_files, skip_blank=True, strip=True)
|
||||||
files = [file for pattern in patterns for file in winglob.glob(pattern)]
|
files = pathclass.glob_many(patterns, files=True)
|
||||||
images = [PIL.Image.open(file) for file in files]
|
images = [PIL.Image.open(file.absolute_path) for file in files]
|
||||||
if args.vertical:
|
if args.vertical:
|
||||||
direction = VERTICAL
|
direction = VERTICAL
|
||||||
else:
|
else:
|
||||||
|
@ -42,6 +42,7 @@ def stitch_argparse(args):
|
||||||
|
|
||||||
log.info(args.output)
|
log.info(args.output)
|
||||||
final_image.save(args.output)
|
final_image.save(args.output)
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
|
|
3
sum.py
3
sum.py
|
@ -1,5 +1,4 @@
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
|
||||||
|
|
||||||
total = sum(float(x) for x in pipeable.go() if x.strip())
|
total = sum(float(x) for x in pipeable.go() if x.strip())
|
||||||
pipeable.stdout(f'{total}\n')
|
pipeable.stdout(f'{total}')
|
||||||
|
|
|
@ -88,6 +88,8 @@ def svgrender_argparse(args):
|
||||||
axis='y' if args.y else 'x',
|
axis='y' if args.y else 'x',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
@vlogging.main_decorator
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -8,6 +8,10 @@ import time
|
||||||
from voussoirkit import bytestring
|
from voussoirkit import bytestring
|
||||||
from voussoirkit import downloady
|
from voussoirkit import downloady
|
||||||
from voussoirkit import pipeable
|
from voussoirkit import pipeable
|
||||||
|
from voussoirkit import vlogging
|
||||||
|
|
||||||
|
log = vlogging.getLogger(__name__, 'threaded_dl')
|
||||||
|
downloady.log.setLevel(vlogging.WARNING)
|
||||||
|
|
||||||
def clean_url_list(urls):
|
def clean_url_list(urls):
|
||||||
for url in urls:
|
for url in urls:
|
||||||
|
@ -29,7 +33,7 @@ def clean_url_list(urls):
|
||||||
yield url
|
yield url
|
||||||
|
|
||||||
def download_thread(url, filename, *, bytespersecond=None, headers=None, timeout=None):
|
def download_thread(url, filename, *, bytespersecond=None, headers=None, timeout=None):
|
||||||
print(f' Starting "{filename}"')
|
log.info(f'Starting "{filename}"')
|
||||||
downloady.download_file(
|
downloady.download_file(
|
||||||
url,
|
url,
|
||||||
filename,
|
filename,
|
||||||
|
@ -37,7 +41,7 @@ def download_thread(url, filename, *, bytespersecond=None, headers=None, timeout
|
||||||
headers=headers,
|
headers=headers,
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
print(f'+Finished "{filename}"')
|
log.info(f'Finished "{filename}"')
|
||||||
|
|
||||||
def remove_finished(threads):
|
def remove_finished(threads):
|
||||||
return [t for t in threads if t.is_alive()]
|
return [t for t in threads if t.is_alive()]
|
||||||
|
@ -87,7 +91,7 @@ def threaded_dl(
|
||||||
)
|
)
|
||||||
|
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
print(f'Skipping existing file "{filename}"')
|
log.info(f'Skipping existing file "{filename}"')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
kwargs = {
|
kwargs = {
|
||||||
|
@ -103,7 +107,7 @@ def threaded_dl(
|
||||||
|
|
||||||
while len(threads) > 0:
|
while len(threads) > 0:
|
||||||
threads = remove_finished(threads)
|
threads = remove_finished(threads)
|
||||||
print(f'{len(threads)} threads remaining\r', end='', flush=True)
|
pipeable.stderr(f'{len(threads)} threads remaining\r', end='')
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
def threaded_dl_argparse(args):
|
def threaded_dl_argparse(args):
|
||||||
|
@ -132,6 +136,9 @@ def threaded_dl_argparse(args):
|
||||||
timeout=args.timeout,
|
timeout=args.timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@vlogging.main_decorator
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
2
touch.py
2
touch.py
|
@ -21,6 +21,8 @@ def touch_argparse(args):
|
||||||
os.utime(filename)
|
os.utime(filename)
|
||||||
pipeable.stdout(filename)
|
pipeable.stdout(filename)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ def unique_argparse(args):
|
||||||
if line not in seen:
|
if line not in seen:
|
||||||
pipeable.stdout(line)
|
pipeable.stdout(line)
|
||||||
seen.add(line)
|
seen.add(line)
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -42,6 +42,7 @@ def watchforlinks_argparse(args):
|
||||||
loop_forever(extension=args.extension, regex=args.regex)
|
loop_forever(extension=args.extension, regex=args.regex)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
return 0
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
|
|
@ -4,10 +4,8 @@ import sys
|
||||||
|
|
||||||
from voussoirkit import bytestring
|
from voussoirkit import bytestring
|
||||||
|
|
||||||
|
|
||||||
filename = os.path.abspath(sys.argv[1])
|
filename = os.path.abspath(sys.argv[1])
|
||||||
|
|
||||||
|
|
||||||
def zerofile(filename, length):
|
def zerofile(filename, length):
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
raise ValueError(f'{filename} already exists.')
|
raise ValueError(f'{filename} already exists.')
|
||||||
|
|
Loading…
Reference in a new issue