137 lines
6.0 KiB
Python
137 lines
6.0 KiB
Python
import os
|
|
import json
|
|
import pathlib
|
|
import shutil
|
|
import subprocess
|
|
from tempfile import mkstemp
|
|
from shutil import move, copymode
|
|
from os import fdopen, remove
|
|
from threading import Thread
|
|
|
|
from libs.noSys.noSysModule import NoSysModule
|
|
from libs.vueNoSys.vueNoSysApiBlueprint import Blueprint
|
|
from libs.app.common.logging import get_logger
|
|
from libs.app.common.paths import ROOT_DIR
|
|
from libs.app.common.network_utils import check_url
|
|
|
|
logger = get_logger()
|
|
|
|
class VueNoSys(NoSysModule):
|
|
def __init__(self, nosys_core):
|
|
super().__init__(nosys_core)
|
|
self.server_port = self.config.get("server", {"port":"3001"}).get("port", "3001")
|
|
self.npm_cmd = "npm.cmd" if os.name == "nt" else "npm"
|
|
self.npm_cwd = os.path.join(pathlib.Path(__file__).parent.resolve())
|
|
|
|
def setup(self):
|
|
self.nosys_core.modules.api.register_blueprint(Blueprint(self).blueprint)
|
|
self.move_modules_vue_files()
|
|
self.install_modules_dependencies()
|
|
self.config_env()
|
|
|
|
self.check_npm_version()
|
|
if self.config.get("server", {"enabled":False}).get("enabled", False):
|
|
self.run_npm_dev()
|
|
self.run_npm_build()
|
|
|
|
def on_nosys_ready(self, event):
|
|
pass
|
|
|
|
def check_npm_version(self):
|
|
try:
|
|
out = subprocess.check_output([self.npm_cmd, "--version"], shell=True, cwd=self.npm_cwd)
|
|
except subprocess.CalledProcessError:
|
|
# TODO Open npm download page
|
|
logger.exception("Command NPM version failed. Please install Node.js to fix this error. https://nodejs.org/en/download")
|
|
return None
|
|
logger.debug(f"NPM Version {out.decode()}")
|
|
|
|
def run_npm_dev(self):
|
|
try:
|
|
dev_server_url = f"https://localhost:{self.server_port}"
|
|
if check_url(dev_server_url, timeout=3, retries=2):
|
|
logger.debug(f"Not starting dev server - HTTP already running in {dev_server_url}")
|
|
return
|
|
|
|
subprocess.check_call([self.npm_cmd, "install"], shell=True, cwd=self.npm_cwd)
|
|
flag = subprocess.CREATE_NEW_CONSOLE # subprocess.CREATE_NO_WINDOW
|
|
npm_process = subprocess.Popen([self.npm_cmd, "run", "dev"], cwd=self.npm_cwd, creationflags=flag)
|
|
logger.debug(f"NPM dev server started, PID={npm_process.pid}")
|
|
except:
|
|
logger.exception(f"Failed to start npm dev server")
|
|
|
|
def run_npm_build(self):
|
|
try:
|
|
subprocess.check_call([self.npm_cmd, "install"], cwd=self.npm_cwd)
|
|
subprocess.check_call([self.npm_cmd, "run", "build"], cwd=self.npm_cwd)
|
|
logger.info("Vue build completed successfully")
|
|
except:
|
|
logger.exception(f"Failed to build Vue frontend")
|
|
return None
|
|
return os.path.join(self.npm_cwd, "dist")
|
|
|
|
def install_modules_dependencies(self, lib_id=None):
|
|
modules_path = os.path.join(pathlib.Path(__file__).parent.resolve(), 'src', 'modules')
|
|
modules = [lib_id] if lib_id else os.listdir(modules_path)
|
|
|
|
for module in modules:
|
|
module_path = os.path.join(modules_path, module)
|
|
dep_file = os.path.join(module_path, "dependencies.txt")
|
|
|
|
if os.path.exists(dep_file):
|
|
with open(dep_file, "r") as f:
|
|
dependencies = [
|
|
line.strip() for line in f.readlines() if line.strip()
|
|
]
|
|
|
|
if dependencies:
|
|
logger.debug(f"Installing dependencies for {module}: {dependencies}")
|
|
try:
|
|
subprocess.run(
|
|
["npm.cmd", "install"] + dependencies,
|
|
cwd=self.npm_cwd,
|
|
check=True
|
|
)
|
|
except:
|
|
logger.exception(f"Error installing dependencies for module {module}")
|
|
else:
|
|
logger.debug(f"Module {module} has no dependencies.txt")
|
|
|
|
|
|
def move_modules_vue_files(self):
|
|
for lib in self.nosys_core.config.get("app", "libs"):
|
|
lib_id = lib.get("id")
|
|
frontend = self.nosys_core.config.get(lib_id, "info", "frontend")
|
|
if frontend == 'vue':
|
|
from_path = os.path.join(ROOT_DIR, 'libs', lib_id, 'vue')
|
|
to_path = os.path.join(pathlib.Path(__file__).parent.resolve(), 'src', 'modules', lib_id)
|
|
if(os.path.exists(from_path)):
|
|
if(os.path.exists(to_path)):
|
|
shutil.rmtree(to_path)
|
|
pathlib.Path(to_path).mkdir(parents=True, exist_ok=True)
|
|
try:
|
|
for file_name in os.listdir(from_path):
|
|
shutil.move(os.path.join(from_path, file_name), os.path.join(to_path, file_name))
|
|
shutil.rmtree(from_path)
|
|
except Exception as e:
|
|
logger.error(f'Error while moving files from {os.path.join(from_path, file_name)} to {os.path.join(to_path, file_name)}: {e}')
|
|
|
|
def config_env(self):
|
|
api_config = self.nosys_core.config.get("api")
|
|
env_file = os.path.join(pathlib.Path(__file__).parent.resolve(), '.env')
|
|
fh, abs_path = mkstemp()
|
|
with fdopen(fh,'w') as new_file:
|
|
with open(env_file) as old_file:
|
|
for line in old_file:
|
|
if "VITE_PORT=" in line:
|
|
line = f"VITE_PORT={self.server_port}\n"
|
|
elif "VITE_BACKEND_API_HOST=" in line:
|
|
vite_backend_api_host = api_config["server"]["host"]
|
|
line = f"VITE_BACKEND_API_HOST=https://{vite_backend_api_host}\n"
|
|
elif "VITE_BACKEND_API_PORT=" in line:
|
|
vite_backend_api_port = api_config["server"]["port"]
|
|
line = f"VITE_BACKEND_API_PORT={vite_backend_api_port}\n"
|
|
new_file.write(line)
|
|
copymode(env_file, abs_path)
|
|
remove(env_file)
|
|
move(abs_path, env_file) |