-
Notifications
You must be signed in to change notification settings - Fork 12
Refactor: open json files by JSONHandler #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
565b3fc
050b675
738a125
6339826
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| import json | ||
| import os | ||
|
|
||
| from src.Utils.JSONHandler import JSONHandler | ||
|
|
||
|
|
||
| class ConfigManager: | ||
| __slots__ = ("init", | ||
|
|
@@ -13,7 +15,6 @@ class ConfigManager: | |
| "paths", | ||
| "ui") | ||
|
|
||
|
|
||
| def __init__(self, ui): | ||
| self.init = False | ||
| self.ui = ui | ||
|
|
@@ -24,8 +25,7 @@ def __init__(self, ui): | |
| self.__block_pref = 0 | ||
| self.__first_time_launch = False | ||
| self.paths = None | ||
|
|
||
|
|
||
|
|
||
| def get_style_pref(self): | ||
| return self.__style_pref | ||
|
|
||
|
|
@@ -89,8 +89,7 @@ def load_config(self): | |
| self.__first_time_launch = False | ||
|
|
||
| def read_config(self): | ||
| with open(os.path.join(self.paths.config_loc, "config.json"), 'r') as F: | ||
| config_data = json.load(F) | ||
| with JSONHandler(os.path.join(self.paths.config_loc, "config.json"), "Error reading 'config.json'") as config_data: | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps extend the message to |
||
| self.__game_loc = config_data.get("game_loc") | ||
| self.__lang_pref = config_data.get("language") | ||
| self.__style_pref = config_data.get("style") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,14 @@ | ||
| import json | ||
| import os | ||
| import shutil | ||
|
|
||
| from PyQt5 import QtCore | ||
|
|
||
| from src.Utils.Path import splitpath | ||
| from src.Utils.JSONHandler import JSONHandler | ||
|
|
||
| translate = QtCore.QCoreApplication.translate | ||
|
|
||
|
|
||
| ##################### | ||
| # DEFINE FLAG TYPES # | ||
| ##################### | ||
|
|
@@ -19,6 +21,7 @@ def __init__(self, options): | |
| def get_flag_status(self): | ||
| return {self.name: self.value} | ||
|
|
||
|
|
||
| class Flag: | ||
| def __init__(self, options): | ||
| self.name = options['Name'] | ||
|
|
@@ -29,6 +32,7 @@ def __init__(self, options): | |
| def get_flag_status(self): | ||
| return {self.name: self.value} | ||
|
|
||
|
|
||
| class ChooseOne: | ||
| def __init__(self, options): | ||
| self.type = options['Type'] | ||
|
|
@@ -47,6 +51,7 @@ def get_flag_status(self): | |
|
|
||
| wizard_flags = {class_.__name__: class_ for class_ in [HiddenFlag, Flag, ChooseOne]} | ||
|
|
||
|
|
||
| ############################ | ||
| # DEFINE BOOLEAN OPERATORS # | ||
| ############################ | ||
|
|
@@ -61,6 +66,7 @@ def and_operator(arguments, operator_list, flag_list): | |
| parsed_flags.append(flag_list[item]) | ||
| return all(parsed_flags) | ||
|
|
||
|
|
||
| def or_operator(arguments, operator_list, flag_list): | ||
| parsed_flags = [] | ||
| for item in arguments: | ||
|
|
@@ -72,6 +78,7 @@ def or_operator(arguments, operator_list, flag_list): | |
| parsed_flags.append(flag_list[item]) | ||
| return any(parsed_flags) | ||
|
|
||
|
|
||
| def not_operator(arguments, operator_list, flag_list): | ||
| to_flip = None | ||
|
|
||
|
|
@@ -84,10 +91,12 @@ def not_operator(arguments, operator_list, flag_list): | |
|
|
||
| return not(to_flip) | ||
|
|
||
| boolean_operators = {'and': and_operator, | ||
|
|
||
| boolean_operators = {'and': and_operator, | ||
| 'or': or_operator, | ||
| 'not': not_operator} | ||
|
|
||
|
|
||
| ############################# | ||
| # DEFINE INSTALLATION RULES # | ||
| ############################# | ||
|
|
@@ -105,18 +114,22 @@ def copy_rule(path_prefix, rule, source, destination): | |
| else: | ||
| assert 0, translate("ModWizards::CYMIS::Logging", "{filepath} is neither a file nor a directory.").format(filepath=source) | ||
|
|
||
|
|
||
| installation_rules = {'copy': copy_rule} | ||
|
|
||
|
|
||
| ################ | ||
| # SAFETY UTILS # | ||
| ################ | ||
| def validate_path(path): | ||
| path_directories = splitpath(path) | ||
| assert not(any([check_if_only_periods(item) for item in path_directories])), translate("ModWizards::CYMIS::Logging", "Paths may not contain relative references.") | ||
|
|
||
|
|
||
| def check_if_only_periods(string): | ||
| return all(char == '.' for char in string) and len(string) > 1 | ||
|
|
||
|
|
||
| ########################## | ||
| # DEFINE CYMIS INSTALLER # | ||
| ########################## | ||
|
|
@@ -127,13 +140,13 @@ def __init__(self): | |
| self.wizard_pages = [] | ||
| self.installation_steps = [] | ||
| self.version = None | ||
| self.enable_debug=None | ||
| self.enable_debug = None | ||
| self.log = None | ||
|
|
||
| @classmethod | ||
| def init_from_script(cls, filepath, log): | ||
| with open(filepath, 'r') as F: | ||
| cymis = json.load(F) | ||
| with JSONHandler(filepath, f"Error Reading '{filepath}'") as stream: | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't call this a stream since it's a dict and not a filestream; maybe change the variable name to 'json_data'.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd make the error message |
||
| cymis = stream | ||
|
|
||
| instance = cls() | ||
| instance.version = cymis['Version'] | ||
|
|
@@ -160,6 +173,7 @@ def install_mod(self): | |
| if installer_step.check_should_execute(): | ||
| installer_step.execute_step() | ||
|
|
||
|
|
||
| class CymisInstallerPage: | ||
| def __init__(self, page, log=None): | ||
| self.title = page.get("Title", translate("ModWizards::CYMIS::FallbackUI", "No Title")) | ||
|
|
@@ -179,6 +193,7 @@ def retrieve_flags(self): | |
| retval.update(flag_status) | ||
| return retval | ||
|
|
||
|
|
||
| class CymisInstallationStep: | ||
| def __init__(self, path_prefix, step_info, flag_table, log): | ||
| execution_condition = step_info.get("if") | ||
|
|
@@ -199,6 +214,7 @@ def check(): | |
| elif type(execution_condition) == dict: | ||
| assert len(execution_condition) == 1, f"More than one boolean operator in dictionary: {execution_condition}." | ||
| operator_name, operator_arguments = list(execution_condition.items())[0] | ||
|
|
||
| def check(): | ||
| result = boolean_operators[operator_name](operator_arguments, boolean_operators, flag_table) | ||
| if log is not None: | ||
|
|
@@ -217,4 +233,4 @@ def execute_step(self): | |
| self.get_rule(instruction["rule"])(self.path_prefix, **instruction) | ||
|
|
||
| def get_rule(self, rule): | ||
| return installation_rules[rule] | ||
| return installation_rules[rule] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,3 @@ | ||
| import array | ||
| import json | ||
| import os | ||
| import sys | ||
|
|
||
|
|
@@ -11,10 +9,12 @@ | |
| from src.CoreOperations.PluginLoaders.ArchivesPluginLoader import get_archivetype_plugins_dict | ||
| from src.CoreOperations.PluginLoaders.FilePacksPluginLoader import get_filepack_plugins_dict, get_filetype_to_filepack_plugins_map | ||
| from src.Utils.Path import calc_has_dir_changed_info | ||
| from src.Utils.JSONHandler import JSONHandler | ||
|
|
||
|
|
||
| translate = QtCore.QCoreApplication.translate | ||
|
|
||
|
|
||
| class BuildStep: | ||
| __slots__ = ('mod', 'src', 'rule', 'rule_args', 'softcodes') | ||
|
|
||
|
|
@@ -25,6 +25,7 @@ def __init__(self, mod, src, rule, softcodes, *rule_args): | |
| self.rule_args = rule_args | ||
| self.softcodes = softcodes | ||
|
|
||
|
|
||
| def make_interned_buildstep(dct): | ||
| if 'mod' in dct: | ||
| softcodes = dct.get('softcodes', {}) | ||
|
|
@@ -39,9 +40,11 @@ def make_interned_buildstep(dct): | |
| else: | ||
| return dct | ||
|
|
||
|
|
||
| def get_interned_mod_index(path): | ||
| with open(os.path.join(path, "INDEX.json"), 'r') as F: | ||
| return json.load(F, object_hook=make_interned_buildstep) | ||
| with JSONHandler(os.path.join(path, "INDEX.json"), "Error reading 'INDEX.json'", object_hook=make_interned_buildstep) as stream: | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please change 'stream' to 'json_data' or 'index_data' here |
||
| return stream | ||
|
|
||
|
|
||
| def trim_dead_nodes(build_pipeline, rules): | ||
| debug_n_thrown = 0 | ||
|
|
@@ -83,6 +86,7 @@ def trim_dead_nodes(build_pipeline, rules): | |
|
|
||
| return list(steps) | ||
|
|
||
|
|
||
| def categorise_build_targets(build_graphs, ops, log, updateLog): | ||
| filetypes = get_targettable_filetypes() | ||
| filepacks = get_filepack_plugins_dict() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,11 +7,13 @@ | |
| from src.CoreOperations.PluginLoaders.FilePacksPluginLoader import get_filepack_plugins_dict | ||
| from src.CoreOperations.PluginLoaders.PatchersPluginLoader import get_patcher_plugins_dict | ||
| from src.Utils.Signals import StandardRunnableSignals | ||
| from src.Utils.JSONHandler import JSONHandler | ||
|
|
||
| translate = QtCore.QCoreApplication.translate | ||
|
|
||
| patchers = get_patcher_plugins_dict() | ||
|
|
||
|
|
||
| class PipelineRunner(QtCore.QRunnable): | ||
| __slots__ = ("softcodes", "target", "filepack", "path_prefix", "paths", "cache_index", "archive_postaction", "signals") | ||
|
|
||
|
|
@@ -111,6 +113,7 @@ def execute(self): | |
| except Exception as e: | ||
| self.handleException(e) | ||
|
|
||
|
|
||
| class ArchivePipelineCollection(QtCore.QObject): | ||
| __slots__ = ("archive", "ops", "ui", "softcodes", "threadpool", "pre_message", "cache_index") | ||
|
|
||
|
|
@@ -171,11 +174,11 @@ def make_link(actor): | |
| self.raise_exception.emit(e) | ||
|
|
||
| def finalise_build(self): | ||
| with open(self.ops.paths.patch_cache_index_loc, 'r') as F: | ||
| total_cache = json.load(F) | ||
| with JSONHandler(self.ops.paths.patch_cache_index_loc, f"Error reading '{self.ops.paths.patch_cache_index_loc}'") as stream: | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe |
||
| total_cache = stream | ||
|
Comment on lines
+177
to
+178
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please change 'stream' to 'cache_data' |
||
| for file, hashval in self.cache_index.items(): | ||
| total_cache[os.path.join(self.archive.get_prefix(), file)] = hashval | ||
| with open(self.ops.paths.patch_cache_index_loc, 'w') as F: | ||
| json.dump(total_cache, F, indent=2) | ||
|
|
||
| self.finished.emit() | ||
| self.finished.emit() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| import json | ||
| import os | ||
| import sys | ||
| import shutil | ||
|
|
||
| from PyQt5 import QtCore | ||
|
|
@@ -9,18 +9,21 @@ | |
| from src.CoreOperations.ModInstallation.PipelineRunners import ArchivePipelineCollection | ||
| from src.CoreOperations.ModInstallation.VariableParser import parse_mod_variables, scan_variables_for_softcodes | ||
| from src.CoreOperations.PluginLoaders.FilePacksPluginLoader import get_filepack_plugins_dict | ||
| from src.Utils.JSONHandler import JSONHandler | ||
| from src.Utils.MBE import mbetable_to_dict, dict_to_mbetable | ||
| from libs.dscstools import DSCSTools | ||
|
|
||
| translate = QtCore.QCoreApplication.translate | ||
|
|
||
|
|
||
| def generate_step_message(cur_items, cur_total): | ||
| return translate("ModInstall", "[Step {ratio}]").format(ratio=f"{cur_items}/{cur_total}") | ||
|
|
||
|
|
||
|
|
||
| def generate_prefixed_message(cur_items, cur_total, msg): | ||
| return f">> {generate_step_message(cur_items, cur_total)} {msg}" | ||
| import sys | ||
|
|
||
|
|
||
| def format_exception(exception): | ||
| return type(exception)(f"Error on line {sys.exc_info()[-1].tb_lineno} in file {__file__}:" + f" {exception}") | ||
|
|
||
|
|
@@ -149,8 +152,8 @@ def process_graph(self, build_graphs, softcode_lookup): | |
|
|
||
| # Create the cache folder if it doesn't exist | ||
| os.makedirs(self.ops.paths.patch_cache_loc, exist_ok=True) | ||
| with open(self.ops.paths.patch_cache_index_loc, 'r') as F: | ||
| cache_index = json.load(F) | ||
| with JSONHandler(self.ops.paths.patch_cache_index_loc, f"Error reading '{self.ops.paths.patch_cache_index_loc}") as stream: | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe "SDMM cache index '{self.ops.paths.patch_cache_index_loc}' is not a valid JSON file" might be a clearer error message? |
||
| cache_index = stream | ||
|
Comment on lines
+155
to
+156
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please change 'stream' to 'cache_data' |
||
|
|
||
| # Now prepare the process the build graph | ||
| # Init some variables to count the number of packs in the build graph, | ||
|
|
@@ -214,6 +217,7 @@ def sendLog(self, msg): | |
| def sendUpdateLog(self, msg): | ||
| self.updateLog.emit(generate_prefixed_message(self.substep, self.nsteps, msg)) | ||
|
|
||
|
|
||
| class ResourceBootstrapper(QtCore.QObject): | ||
| log = QtCore.pyqtSignal(str) | ||
| updateLog = QtCore.pyqtSignal(str) | ||
|
|
@@ -246,8 +250,8 @@ def execute(self): | |
| try: | ||
| self.log.emit(translate("ModInstall", "{curr_step_msg} Checking required resources...").format(curr_step_msg=self.pre_message)) | ||
|
|
||
| with open(os.path.join(self.ops.paths.config_loc, "filelist.json")) as F: | ||
| resource_archives = json.load(F) | ||
| with JSONHandler(os.path.join(self.ops.paths.config_loc, "filelist.json"), "Error reading 'filelist.json'") as stream: | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe "SDMM config file 'filelist.json' is not a valid JSON file" might be a clearer error message? |
||
| resource_archives = stream | ||
|
Comment on lines
+253
to
+254
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please change 'stream' to 'filelist_data' |
||
|
|
||
| required_resources = {} | ||
| for archive_type, archives in self.build_graphs.items(): | ||
|
|
@@ -368,6 +372,7 @@ def make_link(actor): | |
| except Exception as e: | ||
| self.raise_exception.emit(e) | ||
|
|
||
|
|
||
| # 1) Skip sort if data isn't in the build graph | ||
| # 2) Enumerate the sorts | ||
| # 3) Make it work for all MDB1 archives | ||
|
|
@@ -623,6 +628,7 @@ def sortmode_compress_keygen_digimarket(self, item_id, build_item_para, build_it | |
| name = self.name_getter(item_id[0], build_item_name, 1)[1] | ||
| return (int(item_sort_id), name.encode('utf8')) | ||
|
|
||
|
|
||
| class ArchiveBuilder(QtCore.QObject): | ||
| finished = QtCore.pyqtSignal() | ||
| clean_up = QtCore.pyqtSignal() | ||
|
|
@@ -777,5 +783,3 @@ def install(self): | |
| self.thread.start() | ||
| except Exception as e: | ||
| self.raise_exception.emit(e) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good change, but please also