def stitch_argparse(args): patterns = pipeable.input_many(args.image_files, skip_blank=True, strip=True) files = [file for pattern in patterns for file in winglob.glob(pattern)] images = [PIL.Image.open(file) for file in files] if args.vertical: direction = VERTICAL else: direction = HORIZONTAL gapcount = len(images) - 1 if direction is HORIZONTAL: width = sum(i.size[0] for i in images) + (gapcount * args.gap) height = max(i.size[1] for i in images) else: width = max(i.size[0] for i in images) height = sum(i.size[1] for i in images) + (gapcount * args.gap) final_image = PIL.Image.new('RGBA', [width, height]) offset = 0 for image in images: if direction is VERTICAL: final_image.paste(image, (0, offset)) offset += image.size[1] + args.gap else: final_image.paste(image, (offset, 0)) offset += image.size[0] + args.gap log.info(args.output) final_image.save(args.output)
def moveall_argparse(args): files = (pathclass.Path(file) for pattern in pipeable.input(args.source) for file in winglob.glob(pattern)) destination = pathclass.Path(args.destination) if not destination.is_dir: pipeable.stderr('destination must be a directory.') return 1 pairs = [] fail = False for file in files: new_path = destination.with_child(file.basename) if new_path.exists: pipeable.stderr(f'{file.basename} cannot be moved.') fail = True continue pairs.append((file, new_path)) if fail: return 1 for (file, new_path) in pairs: pipeable.output(new_path.absolute_path) shutil.move(file.absolute_path, new_path.absolute_path)
def crop_argparse(args): filenames = winglob.glob(args.pattern) for filename in filenames: crop( filename, crops=args.crops, inplace=args.inplace, )
def crc32_argparse(args): files = (file for arg in args.source for pattern in pipeable.input(arg) for file in winglob.glob(pattern)) for file in files: try: with open(file, 'rb') as handle: crc = zlib.crc32(handle.read()) print(hex(crc)[2:].rjust(8, '0'), file) except Exception as e: print(file, e)
def nonempty_directories_argparse(args): if args.patterns: 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)) else: directories = pathclass.cwd().listdir() directories = (d for d in directories if d.is_dir) for directory in directories: if len(directory.listdir()) != 0: pipeable.stdout(directory.absolute_path)
def ffstreams_argparse(args): for pattern in args.input_filename: for input_filename in winglob.glob(pattern): input_file = pathclass.Path(input_filename) ffstreams( input_file, do_videos=args.videos, do_audios=args.audios, do_subtitles=args.subtitles, dry=args.dry, moveto=args.moveto, )
def resize_argparse(args): filenames = winglob.glob(args.pattern) for filename in filenames: resize( filename, args.new_x, args.new_y, inplace=args.inplace, nearest_neighbor=args.nearest_neighbor, only_shrink=args.only_shrink, scale=args.scale, quality=args.quality, )
def touch_argparse(args): patterns = [ pattern for arg in args.patterns for pattern in pipeable.input(arg) ] for pattern in patterns: filenames = winglob.glob(pattern) if len(filenames) == 0 and not winglob.is_glob(pattern): open(pattern, 'a').close() print(pattern) for filename in filenames: os.utime(filename) print(filename)
def adbinstall_argparse(args): patterns = pipeable.input_many(args.apks, skip_blank=True, strip=True) apks = [file for pattern in patterns for file in winglob.glob(pattern)] installs = [] for apk in args.apks: apk = pathclass.Path(apk) if apk.is_dir: files = apk.glob('*.apk') files.sort(key=lambda x: natural_sorter(x.basename.lower())) apk = files[-1] installs.append(apk) if not args.autoyes: for apk in installs: print(apk.absolute_path) if not interactive.getpermission('Is that okay?', must_pick=True): return 1 for apk in installs: command = f'adb install "{apk.absolute_path}"' log.info(command) os.system(command)
def bitwise_or_argparse(args): 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.Path(file) for file in files] if len(files) < 2: log.fatal('Need at least two input files.') return 1 handles = [file.open('rb') for file in files] output = pathclass.Path(args.output) if output.is_dir: log.fatal('Output path "%s" is a directory.', args.output) return 1 if not output.exists: pass elif args.overwrite: pass elif not interactive.getpermission(f'Overwrite "{output.absolute_path}"?'): return 1 output_handle = output.open('wb') while True: chunk = 0 length = 1 for handle in handles[:]: read = handle.read(CHUNK_SIZE) length = max(length, len(read)) if not read: handles.remove(handle) chunk |= int.from_bytes(read, 'big') if not handles: break output_handle.write(chunk.to_bytes(length, 'big')) pipeable.stdout(output.absolute_path)
''' Drag a file on top of this .py file, and it will have its filename scrambled into a combination of 12 digits. ''' import os import random import string import sys from voussoirkit import pathclass from voussoirkit import winglob argv = sys.argv[1:] for pattern in argv: for path in winglob.glob(pattern): path = pathclass.Path(path) newname = [random.choice(string.digits) for x in range(12)] newname = ''.join(newname) + path.dot_extension newname = path.parent.with_child(newname) os.rename(path.absolute_path, newname.absolute_path) print('%s -> %s' % (path.absolute_path, newname.basename))
def main(args): for line in pipeable.go(args, strip=True, skip_blank=True): for filename in winglob.glob(line): pipeable.output(filename) crlf(filename)
def move(pattern, directory): files = winglob.glob(pattern) for file in files: print(file) shutil.move(file, directory)
import os import send2trash from voussoirkit import pipeable from voussoirkit import winglob for pattern in pipeable.go(skip_blank=True): for name in winglob.glob(pattern): name = os.path.abspath(name) pipeable.output(name) send2trash.send2trash(name)
def grayscale_argparse(args): filenames = winglob.glob(args.pattern) for filename in filenames: grayscale(filename, inplace=args.inplace)