Skip to content

Commit

Permalink
project restructured to be more modular
Browse files Browse the repository at this point in the history
  • Loading branch information
rifsxd committed Mar 15, 2024
1 parent 169e079 commit afff7b2
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 97 deletions.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "pydvpl"
description = "A CLI Tool Coded In Python3 To Convert WoTB ( Dava ) SmartDLC DVPL File Based On LZ4 High Compression."
readme = "README.md"
version = "0.5.0"
version = "0.6.0"
authors = [{ name = "RifsxD", email = "support@rxd-mods.xyz" }]
license = { text = "MIT License" }
requires-python = ">=3.10"
Expand All @@ -17,7 +17,7 @@ dependencies = [
]

[project.scripts]
pydvpl = "pydvpl.converter:main"
pydvpl = "pydvpl:cli"

[project.urls]
"Homepage" = "https://github.com/rifsxd/pydvpl"
Expand Down
24 changes: 17 additions & 7 deletions src/pydvpl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
from .converter import (
compress_dvpl,
decompress_dvpl,
from ._converter import (
convert_dvpl,
verify_dvpl,
cli,
)

from ._color import (
Color
)

from ._dvpl import (
read_dvpl_footer,
create_dvpl_footer
create_dvpl_footer,
compress_dvpl,
decompress_dvpl,
DVPL_FOOTER_SIZE,
DVPL_TYPE_NONE,
DVPL_TYPE_LZ4
)

from .__version__ import (
Expand All @@ -17,7 +28,6 @@
)

__all__ = ['compress_dvpl', 'decompress_dvpl', 'convert_dvpl',
'verify_dvpl', 'read_dvpl_footer', 'create_dvpl_footer',
'verify_dvpl', 'read_dvpl_footer', 'create_dvpl_footer', 'cli',
'__description__', '__title__', '__version__',
'__author__', '__date__', '__repo__']

'__author__', '__date__', '__repo__', 'DVPL_FOOTER_SIZE', 'DVPL_TYPE_NONE', 'DVPL_TYPE_LZ4', 'Color']
2 changes: 1 addition & 1 deletion src/pydvpl/__version__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__title__ = "PyDVPL"
__description__ = "A CLI Tool Coded In Python3 To Convert WoTB ( Dava ) SmartDLC DVPL File Based On LZ4 High Compression."
__version__ = "0.5.0"
__version__ = "0.6.0"
__date__ = "2024-03-14"
__author__ = "RifsxD"
__repo__ = "https://github.com/rifsxd/pydvpl"
6 changes: 6 additions & 0 deletions src/pydvpl/_color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Color:
RED = '\033[31m'
GREEN = '\033[32m'
BLUE = '\033[34m'
YELLOW = '\033[33m'
RESET = '\033[0m'
91 changes: 4 additions & 87 deletions src/pydvpl/converter.py → src/pydvpl/_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,8 @@
from pathlib import Path
from functools import partial
from .__version__ import __version__, __description__, __title__, __date__, __repo__, __author__


class Color:
RED = '\033[31m'
GREEN = '\033[32m'
BLUE = '\033[34m'
YELLOW = '\033[33m'
RESET = '\033[0m'
from ._dvpl import compress_dvpl, decompress_dvpl, read_dvpl_footer, DVPL_FOOTER_SIZE, DVPL_TYPE_NONE, DVPL_TYPE_LZ4
from ._color import Color


class Meta:
Expand All @@ -34,82 +28,6 @@ class Meta:
# Define a thread-safe queue to store processed files
processed_queue = queue.Queue()

DVPL_FOOTER_SIZE = 20
DVPL_TYPE_NONE = 0
DVPL_TYPE_LZ4 = 2
DVPL_FOOTER = b"DVPL"


class DVPLFooter:
def __init__(self, original_size, compressed_size, crc32, type_val):
self.original_size = original_size
self.compressed_size = compressed_size
self.crc32 = crc32
self.type = type_val


def create_dvpl_footer(input_size, compressed_size, crc32_val, type_val):
result = bytearray(DVPL_FOOTER_SIZE)
result[:4] = input_size.to_bytes(4, 'little')
result[4:8] = compressed_size.to_bytes(4, 'little')
result[8:12] = crc32_val.to_bytes(4, 'little')
result[12:16] = type_val.to_bytes(4, 'little')
result[16:] = DVPL_FOOTER
return result


def read_dvpl_footer(buffer):
if len(buffer) < DVPL_FOOTER_SIZE:
raise ValueError(Color.RED + "InvalidDVPLFooter: Buffer size is smaller than expected" + Color.RESET)

footer_buffer = buffer[-DVPL_FOOTER_SIZE:]

if footer_buffer[16:] != DVPL_FOOTER:
raise ValueError(Color.RED + "InvalidDVPLFooter: Footer signature mismatch" + Color.RESET)

original_size = int.from_bytes(footer_buffer[:4], 'little')
compressed_size = int.from_bytes(footer_buffer[4:8], 'little')
crc32_val = int.from_bytes(footer_buffer[8:12], 'little')
type_val = int.from_bytes(footer_buffer[12:16], 'little')

return DVPLFooter(original_size, compressed_size, crc32_val, type_val)


def compress_dvpl(buffer, compression_type="default"):
if compression_type == "fast":
mode = "fast"
elif compression_type == "hc":
mode = "high_compression"
else:
mode = "default"

compressed_block = lz4.block.compress(buffer, store_size=False, mode=mode)
footer_buffer = create_dvpl_footer(len(buffer), len(compressed_block), zlib.crc32(compressed_block), DVPL_TYPE_LZ4)
return compressed_block + footer_buffer


def decompress_dvpl(buffer):
footer_data = read_dvpl_footer(buffer)
target_block = buffer[:-DVPL_FOOTER_SIZE]

if len(target_block) != footer_data.compressed_size:
raise ValueError(Color.RED + "DVPLSizeMismatch" + Color.RESET)

if zlib.crc32(target_block) != footer_data.crc32:
raise ValueError(Color.RED + "DVPLCRC32Mismatch" + Color.RESET)

if footer_data.type == DVPL_TYPE_NONE:
if footer_data.original_size != footer_data.compressed_size or footer_data.type != DVPL_TYPE_NONE:
raise ValueError(Color.RED + "DVPLTypeSizeMismatch" + Color.RESET)
return target_block
elif footer_data.type == DVPL_TYPE_LZ4:
de_dvpl_block = lz4.block.decompress(target_block, uncompressed_size=footer_data.original_size)
if len(de_dvpl_block) != footer_data.original_size:
raise ValueError(Color.RED + "DVPLDecodeSizeMismatch" + Color.RESET)
return de_dvpl_block
else:
raise ValueError(Color.RED + "UNKNOWN DVPL FORMAT" + Color.RESET)


def print_progress_bar(processed_files, total_files):
with output_lock:
Expand Down Expand Up @@ -284,7 +202,6 @@ def verify_dvpl(directory_or_file, config, total_files=None, processed_files=Non
return success_count, failure_count, ignored_count



def process_mode(directory_or_file, config):
if config.mode in ["compress", "decompress"]:
return convert_dvpl(directory_or_file, config)
Expand Down Expand Up @@ -403,7 +320,7 @@ def print_elapsed_time(elapsed_time):
print(f"\nProcessing took {Color.RED}{int(elapsed_time / 60)} min{Color.RESET}\n")


def main():
def cli():
print(f"\n{Color.BLUE}• Name:{Color.RESET} {Meta.NAME}")
print(f"{Color.BLUE}• Version:{Color.RESET} {Meta.VERSION}")
print(f"{Color.BLUE}• Commit:{Color.RESET} {Meta.DATE}")
Expand Down Expand Up @@ -445,4 +362,4 @@ def main():


if __name__ == "__main__":
main()
cli()
80 changes: 80 additions & 0 deletions src/pydvpl/_dvpl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import lz4.block
import zlib
from ._color import Color


DVPL_FOOTER_SIZE = 20
DVPL_TYPE_NONE = 0
DVPL_TYPE_LZ4 = 2
DVPL_FOOTER = b"DVPL"


class DVPLFooter:
def __init__(self, original_size, compressed_size, crc32, type_val):
self.original_size = original_size
self.compressed_size = compressed_size
self.crc32 = crc32
self.type = type_val


def create_dvpl_footer(input_size, compressed_size, crc32_val, type_val):
result = bytearray(DVPL_FOOTER_SIZE)
result[:4] = input_size.to_bytes(4, 'little')
result[4:8] = compressed_size.to_bytes(4, 'little')
result[8:12] = crc32_val.to_bytes(4, 'little')
result[12:16] = type_val.to_bytes(4, 'little')
result[16:] = DVPL_FOOTER
return result


def read_dvpl_footer(buffer):
if len(buffer) < DVPL_FOOTER_SIZE:
raise ValueError(Color.RED + "InvalidDVPLFooter: Buffer size is smaller than expected" + Color.RESET)

footer_buffer = buffer[-DVPL_FOOTER_SIZE:]

if footer_buffer[16:] != DVPL_FOOTER:
raise ValueError(Color.RED + "InvalidDVPLFooter: Footer signature mismatch" + Color.RESET)

original_size = int.from_bytes(footer_buffer[:4], 'little')
compressed_size = int.from_bytes(footer_buffer[4:8], 'little')
crc32_val = int.from_bytes(footer_buffer[8:12], 'little')
type_val = int.from_bytes(footer_buffer[12:16], 'little')

return DVPLFooter(original_size, compressed_size, crc32_val, type_val)


def compress_dvpl(buffer, compression_type="default"):
if compression_type == "fast":
mode = "fast"
elif compression_type == "hc":
mode = "high_compression"
else:
mode = "default"

compressed_block = lz4.block.compress(buffer, store_size=False, mode=mode)
footer_buffer = create_dvpl_footer(len(buffer), len(compressed_block), zlib.crc32(compressed_block), DVPL_TYPE_LZ4)
return compressed_block + footer_buffer


def decompress_dvpl(buffer):
footer_data = read_dvpl_footer(buffer)
target_block = buffer[:-DVPL_FOOTER_SIZE]

if len(target_block) != footer_data.compressed_size:
raise ValueError(Color.RED + "DVPLSizeMismatch" + Color.RESET)

if zlib.crc32(target_block) != footer_data.crc32:
raise ValueError(Color.RED + "DVPLCRC32Mismatch" + Color.RESET)

if footer_data.type == DVPL_TYPE_NONE:
if footer_data.original_size != footer_data.compressed_size or footer_data.type != DVPL_TYPE_NONE:
raise ValueError(Color.RED + "DVPLTypeSizeMismatch" + Color.RESET)
return target_block
elif footer_data.type == DVPL_TYPE_LZ4:
de_dvpl_block = lz4.block.decompress(target_block, uncompressed_size=footer_data.original_size)
if len(de_dvpl_block) != footer_data.original_size:
raise ValueError(Color.RED + "DVPLDecodeSizeMismatch" + Color.RESET)
return de_dvpl_block
else:
raise ValueError(Color.RED + "UNKNOWN DVPL FORMAT" + Color.RESET)

0 comments on commit afff7b2

Please sign in to comment.