diff --git a/LICENSE b/LICENSE index 80909c9..27fc766 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Cryptomelone +Copyright (c) 2017 CrescentApricot Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 0edb62e..712b8e5 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,26 @@ # lz4unipy -unity3d compatible lz4 pack/unpack library in Python3. -## About +## 概要 -lz4unipy is unity3d compatible lz4 pack/unpack library working on Python3.
-It contains functions and simple command line tools for make/pack unity3d compatibled lz4 file. +`lz4unipy` は `unity-lz4` 互換の展開/圧縮を行うコマンドラインツールと簡易なライブラリです。 -## Install +## インストール ```bash pip3 install lz4unipy ``` -## Usage +## 使い方 -### command line +### コマンドライン ```bash -lz4unipy [pack|unpack] target_file [target dir] +lz4unipy [-h] [--dir DIR] infile [infile ...] ``` -### import +指定したファイルより自動的に動作モードを、パスより自動的に出力ファイル名を決定します。 + +### ライブラリ ```python import lz4unipy @@ -38,14 +38,13 @@ with open("target_file.unity3d", "rb") as f: w.write(lz4unipy.compress(data)) ``` -## Test +## テスト ```bash git clone git@github.com/CrescentApricot/lz4unipy.git cd lz4unipy -pip3 install -r requirements.txt python3 setup.py test ``` -### Notice +### 謝辞 テスト用ファイル [sample.png](/tests/sample.png) にはバンダイナムコエンターテインメント株式会社の提供するスマートフォン向けリズムゲーム、[アイドルマスターミリオンライブ! シアターデイズ](https://millionlive.idolmaster.jp/theaterdays/)のゲーム内スクリーンショットを利用しています。この場を借りてお礼申し上げます。 diff --git a/lz4unipy/cmd.py b/lz4unipy/cmd.py index ab5ca5a..92a6563 100644 --- a/lz4unipy/cmd.py +++ b/lz4unipy/cmd.py @@ -1,73 +1,78 @@ -import sys -import os +import pathlib +import argparse +import traceback from . import handler -def main(): - if len(sys.argv) <= 2: - __message("Please specify file.\nUsage: lz4unipy [pack|unpack] target_file [target dir]") - elif 3 <= len(sys.argv) <= 4: - if len(sys.argv) is 4: - if not os.path.exists(sys.argv[3]): - __message(f"Target directory did not exist: {sys.argv[2]}") - return False - save_dir = sys.argv[3] - __message(f"Target directory:: {save_dir}") - else: - __message("Target directory does not specified. Output to current directory.") - save_dir = "" - - file_path = sys.argv[2] - - if not os.path.exists(file_path): - __message(f"入力ファイルが存在しませんでした: {file_path}") - return False - - spl = file_path.split(".") +prefix = "[lz4unipy]" - set_mode = sys.argv[1] - if set_mode == "pack": # pack - __message("Starting pack.") - export_path = file_path + ".lz4" - with open(file_path, "rb") as f: - data = f.read() - if handler.is_compressed(data): - __message("This file is already may be compressed with unity3d compatible lz4. pack aborted.") - return False - else: - if os.path.exists(os.path.join(save_dir, export_path)): - __message(f"A file with the same name as the file scheduled to be output already exists: {export_path}\npack aborted.") - return False - with open(os.path.join(save_dir, export_path), "wb") as w: - w.write(handler.compress(data)) - __message(f"Pack completed: {export_path}") - elif set_mode == "unpack": # unpack - __message("Staring unpack.") - if len(spl) is 1: - export_path = file_path + ".dat" - else: - if spl[-1] == "lz4": - export_path = file_path[:-4] +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("infile", nargs="+", help="ファイルを指定します(複数可)。") + parser.add_argument("--dir", required=False, default=False, help="結果の出力先ディレクトリを指定します。") + args = parser.parse_args() + current_dir = pathlib.Path().parent + if args.dir: + save_dir = pathlib.Path(args.dir) + if not save_dir.is_dir(): + i = input(f"{prefix} 指定されたディレクトリが見つかりませんでした。カレントディレクトリ({current_dir.absolute()})を出力先ディレクトリとして使用します。よろしいですか?[Y/n]: ") + while True: + if "y" in i.lower(): + save_dir = current_dir + break + elif "n" in i.lower(): + print(f"{prefix} 処理を中断します。") + exit() else: - export_path = file_path + ".dat" + i = input(f"{prefix} Y/nで入力してください。") + continue + else: + save_dir = current_dir + print(f"{prefix} 出力先フォルダ: {save_dir.absolute()}") - with open(file_path, "rb") as f: - data = f.read() - if handler.is_compressed(data): - if os.path.exists(os.path.join(save_dir, export_path)): - __message(f"A file with the same name as the file scheduled to be output already exists: {export_path}\nunpack aborted.") - return False - with open(os.path.join(save_dir, export_path), "wb") as w: - w.write(handler.decompress(data)) - __message(f"Unpack completed: {export_path}") + for filename in args.infile: + file = pathlib.Path(filename) + if file.is_file(): + print(f"{prefix} ファイル、 {file.absolute()} の処理を開始します。") + with open(file, "rb") as f: + binary = f.read() + if handler.is_compressed(binary): + print(f"{prefix} このファイルはunitylz4形式で圧縮されています。展開を試みます。") + if file.suffix == ".lz4": + output = save_dir / file.stem + else: + output = save_dir / (file.name + ".dat") + while True: + if output.is_file(): + output = save_dir / (output.name + ".dat") + continue + else: + break + print(f"{prefix} 出力先: {output.absolute()}") + try: + dec = handler.decompress(binary) + with open(output, "wb") as w: + w.write(dec) + print(f"{prefix} 展開に成功しました。") + except Exception as _: + print(f"{prefix} 展開に失敗しました。") + traceback.print_exc() else: - __message("This file is not may be compressed with unity3d compatible lz4. unpack aborted.") - return False - else: - __message("Specified mode was invalid. please spec `pack` or `unpack`.") - return False - - -def __message(msg: str): - print(f"[lz4unipy] {msg}") + print(f"{prefix} このファイルは圧縮されていません。圧縮を試みます。") + output = save_dir / (file.name + ".lz4") + while True: + if output.is_file(): + output = save_dir / (output.name + ".lz4") + continue + else: + break + print(f"{prefix} 出力先: {output.absolute()}") + try: + com = handler.compress(binary) + with open(output, "wb") as w: + w.write(com) + print(f"{prefix} 圧縮に成功しました。") + except Exception as _: + print(f"{prefix} 圧縮に失敗しました。") + traceback.print_exc() diff --git a/lz4unipy/handler.py b/lz4unipy/handler.py index 3f8c982..8eb9891 100644 --- a/lz4unipy/handler.py +++ b/lz4unipy/handler.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -import lz4 +import lz4.block from io import BytesIO from struct import pack, unpack diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 468bf88..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -lz4 \ No newline at end of file diff --git a/setup.py b/setup.py index f90b82b..8c4db2c 100644 --- a/setup.py +++ b/setup.py @@ -4,24 +4,31 @@ with open('README.md') as f: - readme = f.read() + long_description = f.read() with open('LICENSE') as f: li = f.read() setup( name='lz4unipy', - version='1.0.1', - description='unity3d compatible lz4 pack/unpack library working on Python3.', - long_description=readme, + version='2.0.0', + description='unity3d compatible lz4 (un)compress tool working on Python3.', + long_description=long_description, author='CrescentApricot', - author_email='crescentapricot@users.noreply.github.com', + author_email='anzu-noreply@googlegroups.com', license=li, url='https://github.com/CrescentApricot/lz4unipy', packages=find_packages(exclude=('tests',)), - install_requires=["lz4"], + install_requires=["lz4 < 3.0.0"], entry_points={ 'console_scripts': [ 'lz4unipy = lz4unipy.cmd:main', ], - } + }, + classifiers=[ + "Programming Language :: Python :: 3", + "Development Status :: 4 - Beta", + "License :: OSI Approved :: MIT License", + "Topic :: System :: Archiving :: Compression", + "Topic :: Software Development :: Libraries :: Python Modules" + ], )