Improv paths (#936)

* Refactored main

Improved the main script.
Added configurable directories that default to sane places outside of the install directory.
This should resolve the write permission errors.

* Modified paths to use environment variables

Replaced relative paths with better and configurable ones.

* Reformatted

* Added default paths to init

The tests do not run the main script
This commit is contained in:
gentlegiantJGC 2023-07-03 17:02:37 +01:00 committed by GitHub
parent d36f241ac9
commit e0379a878f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 49 deletions

View File

@ -1,4 +1,5 @@
import logging
import os
import platformdirs
experimental_bedrock_resources = False
@ -6,6 +7,22 @@ from ._version import get_versions
__version__ = get_versions()["version"]
del get_versions
# Initialise default paths. These should be initialised in main before this is imported
# but the tests don't run main so a default is required for that case.
data_dir = platformdirs.user_data_dir("AmuletMapEditor", "AmuletTeam")
os.environ.setdefault("DATA_DIR", data_dir)
config_dir = platformdirs.user_config_dir("AmuletMapEditor", "AmuletTeam")
if config_dir == data_dir:
config_dir = os.path.join(data_dir, "Config")
os.environ.setdefault("CONFIG_DIR", config_dir)
os.environ.setdefault(
"CACHE_DIR", platformdirs.user_cache_dir("AmuletMapEditor", "AmuletTeam")
)
os.environ.setdefault(
"LOG_DIR", platformdirs.user_log_dir("AmuletMapEditor", "AmuletTeam")
)
from amulet_map_editor.api import config as CONFIG, lang
from amulet_map_editor.api.framework.app import open_level, close_level

View File

@ -3,24 +3,31 @@
def _on_error(e):
"""Code to handle errors"""
err_list = []
try:
import traceback
import sys
import os
err_list.append(traceback.format_exc())
except:
pass
if isinstance(e, ImportError):
err_list.append(
f"Failed to import requirements. Check that you extracted correctly."
except ImportError as e:
# Something has gone seriously wrong
print(e)
print("Failed to import requirements. Check that you extracted correctly.")
input("Press ENTER to continue.")
else:
err = "\n".join(
[traceback.format_exc()]
+ ["Failed to import requirements. Check that you extracted correctly."]
* isinstance(e, ImportError)
+ [str(e)]
)
err_list.append(str(e))
err = "\n".join(err_list)
print(err)
with open("./logs/crash.log", "w") as f:
f.write(err)
input("Press ENTER to continue.")
sys.exit(1)
print(err)
try:
with open("crash.log", "w") as f:
f.write(err)
except OSError:
pass
input("Press ENTER to continue.")
sys.exit(1)
try:
@ -34,16 +41,17 @@ try:
import glob
import time
import wx
import platformdirs
if sys.platform == "linux" and wx.VERSION >= (4, 1, 1):
# bug 247
os.environ["PYOPENGL_PLATFORM"] = "egl"
except Exception as e:
_on_error(e)
except Exception as e_:
_on_error(e_)
def _init_log():
logs_path = os.path.join(".", "logs")
logs_path = os.environ["LOG_DIR"]
# set up handlers
os.makedirs(logs_path, exist_ok=True)
# remove all log files older than a week
@ -72,22 +80,36 @@ def _init_log():
def main():
try:
# Initialise default paths.
data_dir = platformdirs.user_data_dir("AmuletMapEditor", "AmuletTeam")
os.environ.setdefault("DATA_DIR", data_dir)
config_dir = platformdirs.user_config_dir("AmuletMapEditor", "AmuletTeam")
if config_dir == data_dir:
config_dir = os.path.join(data_dir, "Config")
os.environ.setdefault("CONFIG_DIR", config_dir)
os.environ.setdefault(
"CACHE_DIR", platformdirs.user_cache_dir("AmuletMapEditor", "AmuletTeam")
)
os.environ.setdefault(
"LOG_DIR", platformdirs.user_log_dir("AmuletMapEditor", "AmuletTeam")
)
_init_log()
from amulet_map_editor.api.framework import AmuletApp
except Exception as e:
_on_error(e)
AmuletApp = None
else:
try:
app = AmuletApp(0)
app.MainLoop()
except Exception as e:
log = logging.getLogger(__name__)
log.critical(
f"Amulet Crashed. Sorry about that. Please report it to a developer if you think this is an issue. \n{traceback.format_exc()}"
)
input("Press ENTER to continue.")
try:
app = AmuletApp(0)
app.MainLoop()
except Exception as e:
log = logging.getLogger(__name__)
log.critical(
f"Amulet Crashed. Sorry about that. Please report it to a developer if you think this is an issue. \n{traceback.format_exc()}"
)
input("Press ENTER to continue.")
sys.exit(0)

View File

@ -3,7 +3,7 @@ import pickle
import gzip
from typing import Any
_path = os.path.abspath(os.path.join(".", "config"))
_path = os.path.abspath(os.path.join(os.environ["CONFIG_DIR"]))
def get(identifier: str, default: Any = None) -> Any:

View File

@ -113,7 +113,7 @@ class OpenGLResourcePack:
default=0,
)
cache_dir = os.path.join(".", "cache", "resource_pack")
cache_dir = os.path.join(os.environ["CACHE_DIR"], "resource_packs", "atlas")
img_path = os.path.join(cache_dir, f"{cache_id}.png")
bounds_path = os.path.join(cache_dir, f"{cache_id}.json")
try:

View File

@ -77,16 +77,13 @@ class BaseEditCanvas(EventCanvas):
self._mouse: MouseMovement = MouseMovement(self)
self._mouse.set_middle()
resource_packs_dir = os.path.join(os.environ["DATA_DIR"], "resource_packs")
readme_path = os.path.join(resource_packs_dir, "readme.txt")
# create the resource packs location
try:
os.makedirs("resource_packs", exist_ok=True)
if not os.path.isfile("resource_packs/readme.txt"):
with open("resource_packs/readme.txt", "w") as f:
f.write("Put the Java resource pack you want loaded in here.")
except PermissionError as e:
raise PermissionError(
"Amulet is not able to write to the install directory. Try moving Amulet to somewhere else on your computer."
) from e
os.makedirs(resource_packs_dir, exist_ok=True)
if not os.path.isfile(readme_path):
with open(readme_path, "w") as f:
f.write("Put the Java resource pack you want loaded in here.")
self._renderer: Optional[Renderer] = None
self._opengl_resource_pack = None
@ -97,10 +94,11 @@ class BaseEditCanvas(EventCanvas):
All code in here must be thread safe and not touch the OpenGL state.
"""
packs = []
resource_packs_dir = os.path.join(os.environ["DATA_DIR"], "resource_packs")
user_packs = [
load_resource_pack(os.path.join("resource_packs", rp))
for rp in os.listdir("resource_packs")
if os.path.isdir(os.path.join("resource_packs", rp))
load_resource_pack(os.path.join(resource_packs_dir, rp))
for rp in os.listdir(resource_packs_dir)
if os.path.isdir(os.path.join(resource_packs_dir, rp))
]
if (
self.world.level_wrapper.platform == "bedrock"

View File

@ -36,7 +36,8 @@ class UIOperationLoader(BaseOperationLoader):
"""Parse the export dictionary and setup as required."""
options_path = os.path.abspath(
os.path.join(
"config",
os.environ["CONFIG_DIR"],
"plugins",
"edit_plugins",
f"""{''.join(c for c in self._name if c in ValidChrs)}_{
struct.unpack(

View File

@ -1,13 +1,8 @@
import os
import pkgutil
import sys
from typing import Optional
from types import ModuleType
import importlib.util
from amulet_map_editor.programs.edit.plugins.operations import stock_plugins
STOCK_PLUGINS_DIR: str = stock_plugins.__path__[0]
STOCK_PLUGINS_NAME: str = stock_plugins.__name__
CUSTOM_PLUGINS_DIR = os.path.abspath("plugins")
CUSTOM_PLUGINS_DIR = os.path.join(os.environ["DATA_DIR"], "plugins")

View File

@ -25,6 +25,7 @@ install_requires =
amulet-nbt~=2.0
pymctranslate~=1.2
minecraft-resource-pack~=1.3
platformdirs~=3.1
packages = find: