Skip to content

Commit

Permalink
local helper refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
comasqw committed Nov 12, 2024
1 parent 7d3dbe0 commit dc395f5
Show file tree
Hide file tree
Showing 35 changed files with 809 additions and 325 deletions.
5 changes: 5 additions & 0 deletions Tools/_CP14/LocalizationHelper/LocalizationHelper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .logger import get_logger, LogText
from .exceptions import *
from .parsers import YamlParser, FtlParser
from .prototype import Prototype, check_prototype_attrs
from .localization_helper import LocalizationHelper
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ErrorWhileWritingToFile(Exception):
pass


class ErrorWhileReadingFromFile(Exception):
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import json
import os

from . import Prototype, check_prototype_attrs, get_logger, LogText, ErrorWhileWritingToFile, ErrorWhileReadingFromFile
from .parsers import FtlParser, YamlParser, create_ftl

logger = get_logger(__name__)

SAVE_RESULT_TO = "entities.ftl"
YAML_PARSER_LAST_LAUNCH_RESULT_PATH = "last_launch_result/result.json"


class LocalizationHelper:

def __init__(self):
logger.debug("%s LocalizationHelper ", LogText.CLASS_INITIALIZATION)

@staticmethod
def _save_to_json(path: str, data: dict):
os.makedirs(os.path.dirname(path), exist_ok=True)
try:
logger.debug("%s: %s", LogText.SAVING_DATA_TO_FILE, path)
with open(path, "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=4)
except Exception as e:
raise ErrorWhileWritingToFile(e)

@staticmethod
def _read_from_json(path: str) -> dict:
if os.path.exists(path):
try:
logger.debug("%s: %s", LogText.READING_DATA_FROM_FILE, path)
with open(path, encoding="utf-8") as file:
return json.load(file)
except Exception as e:
raise ErrorWhileReadingFromFile(e)
return {}

def _save_yaml_parser_last_launch_result(self, last_launch_result: dict[str, Prototype]):
logger.debug("%s %s", LogText.SAVING_LAST_LAUNCH_RESULT, YAML_PARSER_LAST_LAUNCH_RESULT_PATH)

prototypes_dict = {}
for prototype_id, prototype_obj in last_launch_result.items():
prototypes_dict[prototype_id] = prototype_obj.attrs_dict

self._save_to_json(YAML_PARSER_LAST_LAUNCH_RESULT_PATH, prototypes_dict)

def _read_prototypes_from_last_launch_result(self) -> dict[str, Prototype] | None:
if os.path.isfile(YAML_PARSER_LAST_LAUNCH_RESULT_PATH):
last_launch_result = self._read_from_json(YAML_PARSER_LAST_LAUNCH_RESULT_PATH)
last_launch_result_dict = {}
for prototype_id, prototype_attrs in last_launch_result.items():
last_launch_result_dict[prototype_id] = Prototype(prototype_attrs)

return last_launch_result_dict
return None

@staticmethod
def _update_prototype_if_attrs_has_been_changed(yaml_prototype_obj: Prototype, last_launch_prototype_obj: Prototype,
final_prototype_obj: Prototype):
if yaml_prototype_obj.attrs_dict != last_launch_prototype_obj.attrs_dict:
log_text = f"Has been updated from: {final_prototype_obj.attrs_dict}, to: "

final_prototype_obj.attrs_dict.update(yaml_prototype_obj.attrs_dict)
final_prototype_obj.reinitialize_with_attrs_dict()

log_text += f"{final_prototype_obj.attrs_dict}"
logger.debug(log_text)

return final_prototype_obj

def _merge_yaml_parser_prototypes_and_ftl_parser_prototypes(self, yaml_parser_prototypes: dict[str, Prototype],
ftl_parser_prototypes: dict[str, Prototype]) -> dict[str, Prototype]:

general_prototypes_dict = {}

last_launch_result = self._read_prototypes_from_last_launch_result()

for prototype_id, yaml_prototype_obj in yaml_parser_prototypes.items():
final_prototype_obj = yaml_prototype_obj
if prototype_id in ftl_parser_prototypes:
final_prototype_obj = ftl_parser_prototypes[prototype_id]

if last_launch_result and prototype_id in last_launch_result:
last_launch_prototype_obj = last_launch_result[prototype_id]
final_prototype_obj = self._update_prototype_if_attrs_has_been_changed(yaml_prototype_obj,
last_launch_prototype_obj,
final_prototype_obj)
general_prototypes_dict[prototype_id] = final_prototype_obj

return general_prototypes_dict

@staticmethod
def _set_parent_attrs(prototype_parent_id: str, prototype_obj: Prototype, parent_prototype_obj: Prototype):
for attr_name, attr_value in prototype_obj.attrs_dict.items():
if attr_value or attr_name in ("parent", "id"):
continue

parent_prototype_attr_value = parent_prototype_obj.attrs_dict.get(attr_name)
if parent_prototype_attr_value:
if attr_name == "name":
prototype_obj.name = f"{{ ent-{prototype_parent_id} }}"
elif attr_name == "description":
prototype_obj.description = f"{{ ent-{prototype_parent_id}.desc }}"
elif attr_name == "suffix":
prototype_obj.suffix = parent_prototype_attr_value

return prototype_obj

def _parent_checks(self, general_prototypes_dict: dict[str, Prototype]):
to_delete = []
for prototype_id, prototype_obj in general_prototypes_dict.items():
prototype_parent_id = prototype_obj.parent
if isinstance(prototype_parent_id, list):
continue

parent_prototype_obj = general_prototypes_dict.get(prototype_parent_id)

if parent_prototype_obj and check_prototype_attrs(parent_prototype_obj, False):
self._set_parent_attrs(prototype_parent_id, prototype_obj, parent_prototype_obj)
else:
if not check_prototype_attrs(prototype_obj, False):
to_delete.append(prototype_id)

for prototype_id in to_delete:
logger.debug("%s %s: %s", prototype_id, LogText.HAS_BEEN_DELETED, general_prototypes_dict[prototype_id])
del general_prototypes_dict[prototype_id]

return general_prototypes_dict

def _create_general_prototypes_dict(self, yaml_parser_prototypes: dict[str, Prototype],
ftl_parser_prototypes: dict[str, Prototype]) -> dict[str, Prototype]:
general_prototypes_dict = self._merge_yaml_parser_prototypes_and_ftl_parser_prototypes(yaml_parser_prototypes,
ftl_parser_prototypes)
general_prototypes_dict = self._parent_checks(general_prototypes_dict)

return general_prototypes_dict

@staticmethod
def _create_result_ftl(general_prototypes_dict: dict[str, Prototype]) -> str:
result = ""
for prototype_obj in general_prototypes_dict.values():
result += create_ftl(prototype_obj)
return result

def _save_result(self, general_prototypes_dict: dict[str, Prototype]):
logger.debug("%s: %s", LogText.SAVING_FINAL_RESULT, SAVE_RESULT_TO)
result = self._create_result_ftl(general_prototypes_dict)
try:
with open(SAVE_RESULT_TO, "w", encoding="utf-8") as file:
file.write(result)
except Exception as e:
raise ErrorWhileWritingToFile(e)

@staticmethod
def _print_info(general_prototypes_dict):
logger.info("%s: %s prototypes", LogText.HAS_BEEN_PROCESSED, len(general_prototypes_dict))
logger.info("Logs in: 'logs/helper.log'")

def main(self, yaml_prototypes_path: str, ftl_prototypes_path: str):
try:
logger.debug("%s: %s", LogText.GETTING_PROTOTYPES_FROM_YAML, yaml_prototypes_path)
prototypes_list_parsed_from_yaml = YamlParser().get_prototypes(yaml_prototypes_path)

logger.debug("%s: %s", LogText.GETTING_PROTOTYPES_FROM_FTL, ftl_prototypes_path)
prototypes_list_parsed_from_ftl = FtlParser().get_prototypes(ftl_prototypes_path)

logger.debug(LogText.FORMING_FINAL_DICTIONARY)
general_prototypes_dict = self._create_general_prototypes_dict(prototypes_list_parsed_from_yaml,
prototypes_list_parsed_from_ftl)

self._save_yaml_parser_last_launch_result(prototypes_list_parsed_from_yaml)
self._save_result(general_prototypes_dict)
self._print_info(general_prototypes_dict)
except ErrorWhileWritingToFile as e:
logger.error("%s: %s", LogText.ERROR_WHILE_WRITING_DATA_TO_FILE, e, exc_info=True)
except ErrorWhileReadingFromFile as e:
logger.error("%s: %s", LogText.ERROR_WHILE_READING_DATA_FROM_FILE, e, exc_info=True)
except Exception as e:
logger.error("%s: %s", LogText.UNKNOWN_ERROR, e, exc_info=True)
43 changes: 43 additions & 0 deletions Tools/_CP14/LocalizationHelper/LocalizationHelper/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import logging
import os


LOG_FILE_PATH = os.path.join("logs", "helper.log")
os.makedirs(os.path.dirname(LOG_FILE_PATH), exist_ok=True)

file_handler = logging.FileHandler(LOG_FILE_PATH, mode='w', encoding="utf-8")
file_handler.setLevel(logging.DEBUG)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[
file_handler,
console_handler
]
)


def get_logger(name: str) -> logging.Logger:
return logging.getLogger(name)


class LogText:
CLASS_INITIALIZATION = "initializing"
GETTING_PROTOTYPES_FROM_YAML = "Getting prototypes from YAML files"
GETTING_PROTOTYPES_FROM_FTL = "Getting prototypes from FTL files"
FORMING_FINAL_DICTIONARY = "Forming the final prototypes dictionary"
SAVING_LAST_LAUNCH_RESULT = "Saving yaml_parser result to file"
READING_LAST_LAUNCH_RESULT = "Reading data from last launch"
SAVING_FINAL_RESULT = "Saving the final prototypes dictionary to FTL file"
SAVING_DATA_TO_FILE = "Saving data to file"
READING_DATA_FROM_FILE = "Reading data from file"
ERROR_WHILE_WRITING_DATA_TO_FILE = "Error while writing data to a file"
ERROR_WHILE_READING_DATA_FROM_FILE = "Error while writing data to a file"
UNKNOWN_ERROR = "An error occurred during execution"
HAS_BEEN_DELETED = "Has been deleted due to lack of relevant data"
HAS_BEEN_PROCESSED = "Has been processed"
FORMING_FTL_FOR_PROTOTYPE = "Forming FTL for Prototype"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .base_parser import BaseParser
from .yaml import YamlParser
from .fluent import FtlParser, create_ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os
from abc import ABC, abstractmethod


from LocalizationHelper.prototype import Prototype


class BaseParser(ABC):
@staticmethod
def _get_files_paths_in_dir(path: str) -> list[str]:
files_paths_lst = []

for dirpath, _, filenames in os.walk(path):
for filename in filenames:
file_path = f"{dirpath}\\{filename}"
files_paths_lst.append(file_path)

return files_paths_lst

@staticmethod
def _check_file_extension(path: str, extension: str) -> bool:
if path.endswith(extension):
return True
return False

@abstractmethod
def get_prototypes(self, prototypes_files_path: str) -> list[Prototype]:
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .ftl_reader import read_ftl
from .ftl_parser import FtlParser
from .ftl_writer import create_ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from . import read_ftl
from LocalizationHelper import get_logger, LogText
from LocalizationHelper.prototype import Prototype
from LocalizationHelper.parsers import BaseParser

logger = get_logger(__name__)


class FtlParser(BaseParser):
def __init__(self):
logger.debug("%s FtlParser", LogText.CLASS_INITIALIZATION)

def get_prototypes(self, ftl_prototypes_path: str) -> dict[str, Prototype]:
prototypes = {}
ftl_prototypes_files_path = self._get_files_paths_in_dir(ftl_prototypes_path)

for prototype_file_path in ftl_prototypes_files_path:
if not self._check_file_extension(prototype_file_path, "ftl"):
continue

file_prototypes_dict = read_ftl(prototype_file_path)

for prototype_dict in file_prototypes_dict.values():
prototype_obj = Prototype(prototype_dict)
logger.debug("%s: %s", LogText.HAS_BEEN_PROCESSED, prototype_obj)
prototypes[prototype_obj.id] = prototype_obj

return prototypes
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
def read_ftl(paths: tuple) -> dict:
"""
The function looks at each line of the ftl
file and determines by the indentation in the line whether
it is a new prototype or an attribute of an old one.
"""
from LocalizationHelper import get_logger, LogText

logger = get_logger(__name__)


def read_ftl(path: str) -> dict:

prototypes = {}

last_prototype = ""
path, error_log_path = paths
try:
logger.debug("%s: %s", LogText.READING_DATA_FROM_FILE, path)
with open(path, encoding="utf-8") as file:
for line in file.readlines():
if line.startswith("#") or line.startswith("\n"):
Expand All @@ -19,19 +20,19 @@ def read_ftl(paths: tuple) -> dict:
proto_id = proto_id.replace("ent-", "")
last_prototype = proto_id
prototypes[proto_id] = {
"name": proto_name.strip(),
"desc": None,
"suffix": None
}
"id": proto_id,
"name": proto_name.strip(),
"description": None,
"suffix": None
}
else:
if "desc" in line:
attr = "desc"
attr = "description"
elif "suffix" in line:
attr = "suffix"

prototypes[last_prototype][attr] = line.split(" = ")[-1].strip()
prototypes[last_prototype][attr] = line.split(" = ", 1)[1].strip()
except Exception as e:
with open(error_log_path, "a") as file:
file.write(f"FTL-ERROR:\nAn error occurred while reading a file {path}, error - {e}\n")

return prototypes
logger.error("%s: %s - %s", LogText.ERROR_WHILE_READING_DATA_FROM_FILE, path, e, exc_info=True)
else:
return prototypes
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from LocalizationHelper import get_logger, LogText
from LocalizationHelper.prototype import Prototype

logger = get_logger(__name__)

INDENT = " "


def create_ftl(prototype: Prototype) -> str:
logger.debug("%s: %s", LogText.FORMING_FTL_FOR_PROTOTYPE, prototype.attrs_dict)
ftl = ""

ftl += f"ent-{prototype.id} = {prototype.name}\n"

if prototype.description:
ftl += f"{INDENT}.desc = {prototype.description}\n"

if prototype.suffix:
ftl += f"{INDENT}.suffix = {prototype.suffix}\n"

ftl += "\n"

return ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .yaml_reader import read_yaml
from .yaml_parser import YamlParser
Loading

0 comments on commit dc395f5

Please sign in to comment.