From 8fd941e0a0f4d82e9e3a8ae1a5b94f1942351d6d Mon Sep 17 00:00:00 2001 From: Quantum Date: Sat, 3 Oct 2020 01:31:08 -0400 Subject: [PATCH] Add x2wincur command --- setup.py | 3 +- win2xcur/main/__init__.py | 0 win2xcur/{main.py => main/win2xcur.py} | 3 +- win2xcur/main/x2wincur.py | 44 ++++++++++++++++++++++++++ win2xcur/writer/windows.py | 9 +++++- 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 win2xcur/main/__init__.py rename win2xcur/{main.py => main/win2xcur.py} (96%) create mode 100644 win2xcur/main/x2wincur.py diff --git a/setup.py b/setup.py index 6587bb9..047048c 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,8 @@ setup( entry_points={ 'console_scripts': [ - 'win2xcur = win2xcur.main:main', + 'win2xcur = win2xcur.main.win2xcur:main', + 'x2wincur = win2xcur.main.x2wincur:main', ], }, diff --git a/win2xcur/main/__init__.py b/win2xcur/main/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/win2xcur/main.py b/win2xcur/main/win2xcur.py similarity index 96% rename from win2xcur/main.py rename to win2xcur/main/win2xcur.py index b13958b..e50b644 100644 --- a/win2xcur/main.py +++ b/win2xcur/main/win2xcur.py @@ -9,7 +9,8 @@ from typing import BinaryIO from win2xcur import shadow from win2xcur.parser import open_blob -from win2xcur.writer.x11 import check_xcursorgen, to_x11 +from win2xcur.writer import to_x11 +from win2xcur.writer.x11 import check_xcursorgen def main() -> None: diff --git a/win2xcur/main/x2wincur.py b/win2xcur/main/x2wincur.py new file mode 100644 index 0000000..308d6d5 --- /dev/null +++ b/win2xcur/main/x2wincur.py @@ -0,0 +1,44 @@ +import argparse +import os +import sys +import traceback +from multiprocessing import cpu_count +from multiprocessing.pool import ThreadPool +from threading import Lock +from typing import BinaryIO + +from win2xcur.parser import open_blob +from win2xcur.writer.windows import to_smart + + +def main() -> None: + parser = argparse.ArgumentParser(description='Converts Windows cursors to X11 cursors.') + parser.add_argument('files', type=argparse.FileType('rb'), nargs='+', + help='X11 cursor files to convert (no extension)') + parser.add_argument('-o', '--output', '--output-dir', default=os.curdir, + help='Directory to store converted cursor files.') + + args = parser.parse_args() + print_lock = Lock() + + def process(file: BinaryIO) -> None: + name = file.name + blob = file.read() + try: + cursor = open_blob(blob) + except Exception: + with print_lock: + print('Error occurred while processing %s:' % (name,), file=sys.stderr) + traceback.print_exc() + else: + ext, result = to_smart(cursor.frames) + output = os.path.join(args.output, os.path.basename(name) + ext) + with open(output, 'wb') as f: + f.write(result) + + with ThreadPool(cpu_count()) as pool: + pool.map(process, args.files) + + +if __name__ == '__main__': + main() diff --git a/win2xcur/writer/windows.py b/win2xcur/writer/windows.py index b0a099c..bfd1a73 100644 --- a/win2xcur/writer/windows.py +++ b/win2xcur/writer/windows.py @@ -1,6 +1,6 @@ from io import BytesIO from itertools import chain -from typing import List +from typing import List, Tuple from win2xcur.cursor import CursorFrame from win2xcur.parser import ANIParser, CURParser @@ -60,3 +60,10 @@ def to_ani(frames: List[CursorFrame]) -> bytes: ] body = b''.join(chunks) return ANIParser.RIFF_HEADER.pack(ANIParser.SIGNATURE, len(body) + 4, ANIParser.ANI_TYPE) + body + + +def to_smart(frames: List[CursorFrame]) -> Tuple[str, bytes]: + if len(frames) == 1: + return '.cur', to_cur(frames[0]) + else: + return '.ani', to_ani(frames)