Skip to content

Commit

Permalink
Added batch folder deserialization and support for argparse arguments…
Browse files Browse the repository at this point in the history
… to both executables.
  • Loading branch information
Shararamosh committed Aug 22, 2024
1 parent 35925c6 commit d3d10f8
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 26 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/build_executable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ jobs:
run: |
pyinstaller --onefile --name="flatc_deserializer" --console --icon=images\flatbuffers-logo-clean.png --add-data="images:images" --add-data="localization:localization" flatc_deserializer.py
pyinstaller --onefile --name="flatc_downloader" --console --icon=images\flatbuffers-downloader-logo-clean.png --add-data="images:images" --add-data="localization:localization" flatc_downloader.py
pyinstaller --onefile --name="flatc_deserializer_batch" --console --icon=images\flatbuffers-batch-logo-clean.png --add-data="images:images" --add-data="localization:localization" flatc_deserializer_batch.py
- name: Move Deserializer and Downloader Executables from dist to root directory and delete dist directory
run: |
move dist\flatc_deserializer.exe .
move dist\flatc_downloader.exe .
move dist\flatc_deserializer_batch.exe .
rd /s /q dist
shell: cmd
- name: Create Automatic Windows Release
Expand All @@ -35,4 +37,5 @@ jobs:
title: Latest Build
files: |
flatc_deserializer.exe
flatc_downloader.exe
flatc_downloader.exe
flatc_deserializer_batch.exe
18 changes: 15 additions & 3 deletions flatc_deserializer.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
"""
Десериализация бинарных файлов Flatbuffers по заданной схеме c открытием диалогового окна для
поиска компилятора схемы при его отсутствии в рабочей директории.
Десериализация выбранных бинарных файлов Flatbuffers по выбранной схеме.
"""
import os
import sys
import argparse
from i18n import t

from main import prepare_app, get_flatc_path, execute_deserialize # pylint: disable=import-error

if __name__ == "__main__":
prepare_app("images/flatbuffers-logo-clean.png")
sys.exit(execute_deserialize(get_flatc_path(True, os.getcwd(), True)))
parser = argparse.ArgumentParser(prog=t("main.flatc_deserializer_name"),
description=t("main.flatc_deserializer_desc"))
parser.add_argument("-s", "--schema_path", type=str, default="", help=t("main.schema_file_arg"))
parser.add_argument("-b", "--binary_paths", nargs="+", default=[],
help=t("main.binary_files_arg"))
parser.add_argument("-o", "--output_path", type=str, default="",
help=t("main.output_directory_arg"))
parser.add_argument("-f", "--flatc_path", type=str, default="", help=t("main.flatc_path_arg"))
args = parser.parse_args()
sys.exit(execute_deserialize(
get_flatc_path(os.getcwd(), True) if args.flatc_path == "" else args.flatc_path,
args.schema_path, args.binary_paths, args.output_path))
27 changes: 27 additions & 0 deletions flatc_deserializer_batch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
Десериализация бинарных файлов Flatbuffers в выбранной директории по всем схемам в другой
выбранной директории.
"""
import os
import sys
import argparse
from i18n import t

from main import prepare_app, get_flatc_path, \
execute_deserialize_batch # pylint: disable=import-error

if __name__ == "__main__":
prepare_app("images/flatbuffers-batch-logo-clean.png")
parser = argparse.ArgumentParser(prog=t("main.flatc_deserializer_name"),
description=t("main.flatc_derializer_desc"))
parser.add_argument("-s", "--schemas_path", type=str, default="",
help=t("main.schemas_directory_arg"))
parser.add_argument("-b", "--binaries_path", type=str, default="",
help=t("main.binaries_directory_arg"))
parser.add_argument("-o", "--output_path", type=str, default="",
help=t("main.output_directory_arg"))
parser.add_argument("-f", "--flatc_path", type=str, default="", help=t("main.flatc_path_arg"))
args = parser.parse_args()
sys.exit(execute_deserialize_batch(
get_flatc_path(os.getcwd(), True) if args.flatc_path == "" else args.flatc_path,
args.schemas_path, args.binaries_path, args.output_path))
Binary file added images/flatbuffers-batch-logo-clean.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion localization/en_US/flatc_download_funcs.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
download_start: Retrieving Flatbuffers latest release data...
download_failed: Can't find valid latest Flatbuffers release.
download_finish: "Downloaded latest Flatbuffers release to %s."
download_finish: Downloaded latest Flatbuffers release to %s.
unpack_path: Unpacked %s archive to %s.
archive_removed: Flatbuffers archive is removed.
17 changes: 14 additions & 3 deletions localization/en_US/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
tkinter_flatc_select: Select scheme compiler
tkinter_flatc_select: Select schema compiler
exe_filetype: Windows Executable
tkinter_fbs_select: Select scheme file
tkinter_fbs_select: Select schema file
fbs_filetype: Flatbuffers scheme
tkinter_binaries_select: Select binary files
flatc_binary_filetype: Binary Flatbuffers file
Expand All @@ -12,4 +12,15 @@ file_not_found: File %s not found.
directory_not_found: Directory %s not found.
file_removed: File %s is removed.
flatc_already_exists: "Flabuffers schema compiler already exists in working directory: %s."
file_not_executable: File %s is not executable.
file_not_executable: File %s is not executable.
tkinter_fbs_directory_select: Select directory with schema files
tkinter_binary_directory_select: Select directory with binary files
no_schema_files_found: No schema files found in directory %s.
schemas_directory_arg: Directory with schema files
binaries_directory_arg: Directory with binary files
output_directory_arg: Output directory for deserialized files
schema_file_arg: Schema file
binary_files_arg: Binary files
flatc_path_arg: Path to schema compiler (flatc)
flatc_deserializer_name: Flatbuffers Batch Deserializer
flatc_deserializer_desc: Program for batch deserialization of Flatbuffers binary files.
2 changes: 1 addition & 1 deletion localization/ru_RU/flatc_download_funcs.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
download_start: Получение данных о последней версии Flatbuffers...
download_failed: Не удалось найти валидную последнюю версию Flatbuffers.
download_finish: "Последняя версия Flatbuffers была загружена в %s."
download_finish: Последняя версия Flatbuffers была загружена в %s.
unpack_path: Архив %s распакован в %s.
archive_removed: Архив Flatbuffers был удалён.
13 changes: 12 additions & 1 deletion localization/ru_RU/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,15 @@ file_not_found: Файл %s не найден.
directory_not_found: Директория %s не найдена.
file_removed: Файл %s был удалён.
flatc_already_exists: "Компилятор схемы Flatbuffers уже существует в рабочей директории: %s"
file_not_executable: Файл %s не является исполняемым.
file_not_executable: Файл %s не является исполняемым.
tkinter_fbs_directory_select: Выбор директории с файлами схем
tkinter_binary_directory_select: Выбор директории с бинарными файлами
no_schema_files_found: Файлы схем не были найдены в директории %s.
schemas_directory_arg: Директория с файлами схем
binaries_directory_arg: Директория с бинарными файлами
output_directory_arg: Директория вывода для десериализованных файлов
schema_file_arg: Файл схемы
binary_files_arg: Бинарные файлы
flatc_path_arg: Путь к компилятору схемы (flatc)
flatc_deserializer_name: Flatbuffers Batch Deserializer
flatc_deserializer_desc: Программа для пакетной десериализации бинарных файлов Flatbuffers.
131 changes: 115 additions & 16 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def prepare_app(icon_path: str):
"""
logging.basicConfig(stream=sys.stdout, format="%(message)s", level=logging.INFO)
filterwarnings("ignore", category=DeprecationWarning)
# noinspection PyDeprecation
i18n.set("locale", getdefaultlocale()[0]) # pylint: disable=deprecated-method
i18n.set("fallback", "en_US")
i18n.load_path.append(get_resource_path("localization"))
Expand All @@ -49,20 +50,14 @@ def prepare_app(icon_path: str):
root.iconphoto(True, PhotoImage(file=get_resource_path(icon_path)))


def get_flatc_path(allow_system_path: bool, root_path: str, allow_ask: bool,
suppress_ask_error: bool = True) -> str:
def get_flatc_path(root_path: str, allow_ask: bool, suppress_ask_error: bool = True) -> str:
"""
Получение пути к файлу компилятора Flatbuffers.
:param allow_system_path: Позволить искать файл в системных директориях Python.
:param root_path: Путь к текущей рабочей директории.
:param allow_ask: Позволить открыть файл через диалоговое окно, если файла нет в рабочей директории.
:param suppress_ask_error: Игнорировать ошибку FileNotFoundError, если не выводится диалоговое окно для файла.
:return: Путь к файлу.
"""
if allow_system_path:
flatc_path = which("flatc")
if flatc_path is not None:
return os.path.abspath(flatc_path)
flatc_path = which("flatc", path=root_path + os.sep)
if flatc_path is not None:
return os.path.abspath(flatc_path)
Expand All @@ -89,33 +84,47 @@ def execute_download(root_path: str) -> int | str:
:param root_path: Путь к текущей рабочей директории.
:return: Код ошибки или строка об ошибке.
"""
flatc_path = get_flatc_path(False, root_path, False, True)
flatc_path = get_flatc_path(root_path, False, True)
if flatc_path != "":
logging.info(i18n.t("main.flatc_already_exists"), flatc_path)
else:
download_flatc(os.getcwd())
return os.EX_OK


def execute_deserialize(flatc_path: str) -> int | str:
def execute_deserialize(flatc_path: str, schema_path: str, binary_paths: list[str], output_path:
str) -> (int | str):
"""
Десериализация бинарных файлов Flatbuffers по заданной схеме.
:param flatc_path: Путь к файлу компилятора схемы.
:param schema_path: Путь к файлу схемы.
:param binary_paths: Список путей к бинарным файлам.
:param output_path: Путь к директории вывода для десериализованных файлов.
:return: Код ошибки или строка об ошибке.
"""
if not os.path.isfile(flatc_path):
raise FileNotFoundError(i18n.t("main.file_not_found") % flatc_path)
if which(os.path.split(flatc_path)[1], path=os.path.split(flatc_path)[0]) is None:
raise FileNotFoundError(i18n.t("main.file_not_executable") % flatc_path)
schema_path = askopenfilename(title=i18n.t("main.tkinter_fbs_select"),
filetypes=[(i18n.t("main.fbs_filetype"), "*.fbs")])
if schema_path == "":
return os.EX_OK
schema_path = askopenfilename(title=i18n.t("main.tkinter_fbs_select"),
filetypes=[(i18n.t("main.fbs_filetype"), "*.fbs")])
if schema_path == "":
return os.EX_OK
elif not os.path.isfile(schema_path):
raise FileNotFoundError(i18n.t("main.file_not_found") % schema_path)
schema_name = os.path.splitext(os.path.basename(schema_path))[0]
binary_paths = askopenfilenames(title=i18n.t("main.tkinter_binaries_select"),
filetypes=[
(i18n.t("main.flatc_binary_filetype"), "*." + schema_name)])
output_path = askdirectory(title=i18n.t("main.tkinter_output_select"))
if len(binary_paths) < 1:
binary_paths = askopenfilenames(title=i18n.t("main.tkinter_binaries_select"), filetypes=[
(i18n.t("main.flatc_binary_filetype"), "*." + schema_name)])
if len(binary_paths) < 1:
return os.EX_OK
else:
binary_paths = [binary_path for binary_path in binary_paths if os.path.isfile(binary_path)]
if output_path == "":
output_path = askdirectory(title=i18n.t("main.tkinter_output_select"))
elif not os.path.isdir(output_path):
raise FileNotFoundError(i18n.t("main.directory_not_found") % output_path)
full_size = sum(os.stat(binary_path).st_size for binary_path in binary_paths)
with logging_redirect_tqdm():
pbar = tqdm(total=full_size, position=0, unit="B", unit_scale=True,
Expand All @@ -128,3 +137,93 @@ def execute_deserialize(flatc_path: str) -> int | str:
pbar.set_postfix_str("")
pbar.close()
return os.EX_OK


def get_schema_paths(root_path: str) -> list[str]:
"""
Получение списка путей к файлам схем Flatbuffers внутри заданной корневой директории.
:param root_path: Путь к корневой директории.
:return: Список путей к файлам схем.
"""
schema_paths = []
if not os.path.isdir(root_path):
return schema_paths
for subdir, _, files in os.walk(root_path):
for file in files:
file_path = os.path.abspath(os.path.join(subdir, file))
if os.path.splitext(file_path)[1].lower() == ".fbs":
schema_paths.append(file_path)
return schema_paths


def get_binary_tuples(binaries_path: str, schema_paths: list[str]) -> tuple[
list[tuple[str, str]], int]:
"""
Получение списка кортежей из двух элементов: (путь к бинарному файлу, путь к соответствующему ему файлу схемы)
:param binaries_path: Список путей к бинарным файлам.
:param schema_paths: Список путей к файлам схем.
:return: Кортеж из двух строковых элементов.
"""
binary_tuples = []
full_size = 0
for subdir, _, files in os.walk(binaries_path):
for file in files:
file_path = os.path.abspath(os.path.join(subdir, file))
for schema_path in schema_paths:
if os.path.splitext(os.path.basename(schema_path))[0].casefold() == \
os.path.splitext(file)[1][1:].casefold():
binary_tuples.append((file_path, schema_path))
full_size += os.stat(file_path).st_size
break
return binary_tuples, full_size


def execute_deserialize_batch(flatc_path: str, schemas_path: str, binaries_path: str,
output_path: str) -> (int | str):
"""
Десериализация всех файлов Flatbuffers в директории по всем схемам из другой директории.
:param flatc_path: Путь к файлу компилятора схемы.
:param schemas_path: Путь к директории с файлами схем.
:param binaries_path: Путь к директории с бинарными файлами.
:param output_path: Путь к директории вывода.
:return: Код ошибки или строка об ошибке.
"""
if not os.path.isfile(flatc_path):
raise FileNotFoundError(i18n.t("main.file_not_found") % flatc_path)
if which(os.path.split(flatc_path)[1], path=os.path.split(flatc_path)[0]) is None:
raise FileNotFoundError(i18n.t("main.file_not_executable") % flatc_path)
if schemas_path == "":
schemas_path = askdirectory(title=i18n.t("main.tkinter_fbs_directory_select"))
if schemas_path == "":
return os.EX_OK
elif not os.path.isdir(schemas_path):
raise FileNotFoundError(i18n.t("main.directory_not_found") % schemas_path)
if binaries_path == "":
binaries_path = askdirectory(title=i18n.t("main.tkinter_binary_directory_select"))
if binaries_path == "":
return os.EX_OK
elif not os.path.isdir(binaries_path):
raise FileNotFoundError(i18n.t("main.directory_not_found") % binaries_path)
if output_path == "":
output_path = askdirectory(title=i18n.t("main.tkinter_output_select"))
if output_path == "":
output_path = os.path.split(flatc_path)[0]
elif not os.path.isdir(output_path):
raise FileNotFoundError(i18n.t("main.directory_not_found") % output_path)
schema_paths = get_schema_paths(schemas_path)
if len(schema_paths) < 1:
logging.info(i18n.t("main.no_schema_files_found"), binaries_path)
return os.EX_OK
binary_tuples, full_size = get_binary_tuples(binaries_path, schema_paths)
with logging_redirect_tqdm():
pbar = tqdm(total=full_size, position=0, unit="B", unit_scale=True,
desc=i18n.t("main.files"))
for binary_path, schema_path in binary_tuples:
pbar.set_postfix_str(binary_path)
pbar.clear()
deserialize(flatc_path, schema_path, binary_path, output_path + os.sep +
os.path.split(os.path.relpath(binary_path, binaries_path))[0])
pbar.update(os.stat(binary_path).st_size)
pbar.set_postfix_str("")
pbar.close()
return os.EX_OK

0 comments on commit d3d10f8

Please sign in to comment.