Upd: [ALAS] installer

This commit is contained in:
LmeSzinc 2023-09-09 18:36:14 +08:00
parent f7bc6980f9
commit 0067e343b2
15 changed files with 161 additions and 31 deletions

View File

@ -1,8 +1,9 @@
Deploy: Deploy:
Git: Git:
# URL of AzurLaneAutoScript repository # URL of AzurLaneAutoScript repository
# [Other] Use 'https://github.com/LmeSzinc/StarRailCopilot' # [CN user] Use 'cn' to get update from git-over-cdn service
Repository: https://e.coding.net/llop18870/alas/AzurLaneAutoScript.git # [Other] Use 'global' to get update from https://github.com/LmeSzinc/StarRailCopilot
Repository: cn
# Branch of Alas # Branch of Alas
# [Developer] Use 'dev', 'app', etc, to try new features # [Developer] Use 'dev', 'app', etc, to try new features
# [Other] Use 'master', the stable branch # [Other] Use 'master', the stable branch
@ -156,3 +157,6 @@ Deploy:
# '["alas"]' specified "alas" config # '["alas"]' specified "alas" config
# '["alas","alas2"]' specified "alas" "alas2" configs # '["alas","alas2"]' specified "alas" "alas2" configs
Run: null Run: null
# --no-sandbox. https://github.com/electron/electron/issues/30966
# Some Windows systems cannot call the GPU normally for virtualization, and you need to manually turn off sandbox mode
NoSandbox: false

View File

@ -1,8 +1,9 @@
Deploy: Deploy:
Git: Git:
# URL of AzurLaneAutoScript repository # URL of AzurLaneAutoScript repository
# [Other] Use 'https://github.com/LmeSzinc/StarRailCopilot' # [CN user] Use 'cn' to get update from git-over-cdn service
Repository: https://github.com/LmeSzinc/StarRailCopilot # [Other] Use 'global' to get update from https://github.com/LmeSzinc/StarRailCopilot
Repository: global
# Branch of Alas # Branch of Alas
# [Developer] Use 'dev', 'app', etc, to try new features # [Developer] Use 'dev', 'app', etc, to try new features
# [Other] Use 'master', the stable branch # [Other] Use 'master', the stable branch
@ -156,3 +157,6 @@ Deploy:
# '["alas"]' specified "alas" config # '["alas"]' specified "alas" config
# '["alas","alas2"]' specified "alas" "alas2" configs # '["alas","alas2"]' specified "alas" "alas2" configs
Run: null Run: null
# --no-sandbox. https://github.com/electron/electron/issues/30966
# Some Windows systems cannot call the GPU normally for virtualization, and you need to manually turn off sandbox mode
NoSandbox: false

View File

@ -1,8 +1,8 @@
import logging import logging
import os
from deploy.Windows.emulator import EmulatorManager from deploy.Windows.emulator import EmulatorManager
from deploy.Windows.logger import logger from deploy.Windows.logger import Progress, logger
from deploy.Windows.utils import *
def show_fix_tip(module): def show_fix_tip(module):
@ -23,9 +23,11 @@ class AdbManager(EmulatorManager):
if self.ReplaceAdb: if self.ReplaceAdb:
logger.hr('Replace ADB', 1) logger.hr('Replace ADB', 1)
self.adb_replace() self.adb_replace()
Progress.AdbReplace()
if self.AutoConnect: if self.AutoConnect:
logger.hr('ADB Connect', 1) logger.hr('ADB Connect', 1)
self.brute_force_connect() self.brute_force_connect()
Progress.AdbConnect()
if False: if False:
logger.hr('Uiautomator2 Init', 1) logger.hr('Uiautomator2 Init', 1)

View File

@ -1,9 +1,10 @@
import os
import time import time
import typing as t import typing as t
from deploy.Windows.config import DeployConfig from deploy.Windows.config import DeployConfig
from deploy.Windows.logger import logger from deploy.Windows.logger import Progress, logger
from deploy.Windows.utils import * from deploy.Windows.utils import DataProcessInfo, cached_property, iter_process
class AlasManager(DeployConfig): class AlasManager(DeployConfig):
@ -43,8 +44,9 @@ class AlasManager(DeployConfig):
if proc.pid == self.self_pid: if proc.pid == self.self_pid:
continue continue
if in_alas: if in_alas:
cmdline = proc.cmdline.replace(r"\\", "/").replace("\\", "/")
for folder in self.alas_folder: for folder in self.alas_folder:
if folder in proc.cmdline: if folder in cmdline:
yield proc yield proc
else: else:
yield proc yield proc
@ -56,15 +58,20 @@ class AlasManager(DeployConfig):
self.execute(f'taskkill /f /t /pid {process.pid}', allow_failure=True, output=False) self.execute(f'taskkill /f /t /pid {process.pid}', allow_failure=True, output=False)
def alas_kill(self): def alas_kill(self):
while 1: for _ in range(10):
logger.hr(f'Kill existing Alas', 0) logger.hr(f'Kill existing Alas', 0)
proc_list = list(self.iter_process_by_names(['alas.exe', 'python.exe'], in_alas=True)) proc_list = list(self.iter_process_by_names(['python.exe'], in_alas=True))
if not len(proc_list): if not len(proc_list):
break Progress.KillExisting()
return True
for proc in proc_list: for proc in proc_list:
logger.info(proc) logger.info(proc)
self.kill_process(proc) self.kill_process(proc)
logger.warning('Unable to kill existing Alas, skip')
Progress.KillExisting()
return False
if __name__ == '__main__': if __name__ == '__main__':
self = AlasManager() self = AlasManager()

View File

@ -1,9 +1,9 @@
import filecmp import filecmp
import os
import shutil import shutil
from deploy.Windows.config import DeployConfig from deploy.Windows.config import DeployConfig
from deploy.Windows.logger import logger from deploy.Windows.logger import Progress, logger
from deploy.Windows.utils import *
class AppManager(DeployConfig): class AppManager(DeployConfig):
@ -50,6 +50,8 @@ class AppManager(DeployConfig):
if not self.AutoUpdate: if not self.AutoUpdate:
logger.info('AutoUpdate is disabled, skip') logger.info('AutoUpdate is disabled, skip')
Progress.UpdateAlasApp()
return False return False
return self.app_asar_replace(os.getcwd()) self.app_asar_replace(os.getcwd())
Progress.UpdateAlasApp()

View File

@ -1,9 +1,10 @@
import copy import copy
import os
import subprocess import subprocess
from typing import Optional, Union from typing import Optional, Union
from deploy.Windows.logger import logger from deploy.Windows.logger import logger
from deploy.Windows.utils import * from deploy.Windows.utils import DEPLOY_CONFIG, DEPLOY_TEMPLATE, cached_property, poor_yaml_read, poor_yaml_write
class ExecutionError(Exception): class ExecutionError(Exception):
@ -54,7 +55,7 @@ class ConfigModel:
# Webui # Webui
WebuiHost: str = "0.0.0.0" WebuiHost: str = "0.0.0.0"
WebuiPort: int = 22367 WebuiPort: int = 22267
Language: str = "en-US" Language: str = "en-US"
Theme: str = "default" Theme: str = "default"
DpiScaling: bool = True DpiScaling: bool = True
@ -73,10 +74,7 @@ class DeployConfig(ConfigModel):
self.config = {} self.config = {}
self.config_template = {} self.config_template = {}
self.read() self.read()
if self.Repository == 'https://gitee.com/LmeSzinc/AzurLaneAutoScript':
self.Repository = 'https://e.coding.net/llop18870/alas/AzurLaneAutoScript.git'
if self.Repository == 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror':
self.Repository = 'https://e.coding.net/llop18870/alas/AzurLaneAutoScript.git'
self.write() self.write()
self.show_config() self.show_config()

View File

@ -1,8 +1,9 @@
import configparser import configparser
import os
from deploy.Windows.config import DeployConfig from deploy.Windows.config import DeployConfig
from deploy.Windows.logger import logger from deploy.Windows.logger import Progress, logger
from deploy.Windows.utils import * from deploy.Windows.utils import cached_property
class GitConfigParser(configparser.ConfigParser): class GitConfigParser(configparser.ConfigParser):
@ -41,6 +42,7 @@ class GitManager(DeployConfig):
self.remove('./.git/HEAD') self.remove('./.git/HEAD')
self.remove('./.git/ORIG_HEAD') self.remove('./.git/ORIG_HEAD')
self.execute(f'"{self.git}" init') self.execute(f'"{self.git}" init')
Progress.GitInit()
logger.hr('Set Git Proxy', 1) logger.hr('Set Git Proxy', 1)
if proxy: if proxy:
@ -60,14 +62,17 @@ class GitManager(DeployConfig):
else: else:
if not self.git_config.check('http', 'sslVerify', value='false'): if not self.git_config.check('http', 'sslVerify', value='false'):
self.execute(f'"{self.git}" config --local http.sslVerify false', allow_failure=True) self.execute(f'"{self.git}" config --local http.sslVerify false', allow_failure=True)
Progress.GitSetConfig()
logger.hr('Set Git Repository', 1) logger.hr('Set Git Repository', 1)
if not self.git_config.check(f'remote "{source}"', 'url', value=repo): if not self.git_config.check(f'remote "{source}"', 'url', value=repo):
if not self.execute(f'"{self.git}" remote set-url {source} {repo}', allow_failure=True): if not self.execute(f'"{self.git}" remote set-url {source} {repo}', allow_failure=True):
self.execute(f'"{self.git}" remote add {source} {repo}') self.execute(f'"{self.git}" remote add {source} {repo}')
Progress.GitSetRepo()
logger.hr('Fetch Repository Branch', 1) logger.hr('Fetch Repository Branch', 1)
self.execute(f'"{self.git}" fetch {source} {branch}') self.execute(f'"{self.git}" fetch {source} {branch}')
Progress.GitFetch()
logger.hr('Pull Repository Branch', 1) logger.hr('Pull Repository Branch', 1)
# Remove git lock # Remove git lock
@ -93,18 +98,22 @@ class GitManager(DeployConfig):
self.execute(f'"{self.git}" pull --ff-only {source} {branch}') self.execute(f'"{self.git}" pull --ff-only {source} {branch}')
else: else:
self.execute(f'"{self.git}" reset --hard {source}/{branch}') self.execute(f'"{self.git}" reset --hard {source}/{branch}')
Progress.GitReset()
# Since `git fetch` is already called, checkout is faster # Since `git fetch` is already called, checkout is faster
if not self.execute(f'"{self.git}" checkout {branch}', allow_failure=True): if not self.execute(f'"{self.git}" checkout {branch}', allow_failure=True):
self.execute(f'"{self.git}" pull --ff-only {source} {branch}') self.execute(f'"{self.git}" pull --ff-only {source} {branch}')
Progress.GitCheckout()
logger.hr('Show Version', 1) logger.hr('Show Version', 1)
self.execute(f'"{self.git}" --no-pager log --no-merges -1') self.execute(f'"{self.git}" --no-pager log --no-merges -1')
Progress.GitShowVersion()
def git_install(self): def git_install(self):
logger.hr('Update Alas', 0) logger.hr('Update Alas', 0)
if not self.AutoUpdate: if not self.AutoUpdate:
logger.info('AutoUpdate is disabled, skip') logger.info('AutoUpdate is disabled, skip')
Progress.GitShowVersion()
return return
self.git_repository_init( self.git_repository_init(

View File

@ -102,6 +102,7 @@ DataAdbDevice(serial='127.0.0.1:16384', status='device')
DataAdbDevice(serial='127.0.0.1:16480', status='device') DataAdbDevice(serial='127.0.0.1:16480', status='device')
DataAdbDevice(serial='127.0.0.1:7555', status='device') DataAdbDevice(serial='127.0.0.1:7555', status='device')
Process: [ 100% ] Process: [ 100% ]
中文测试@#nfoir
""" """

View File

@ -34,3 +34,34 @@ def hr(title, level=3):
logger.hr = hr logger.hr = hr
class Percentage:
def __init__(self, progress):
self.progress = progress
def __call__(self, *args, **kwargs):
logger.info(f'Process: [ {self.progress}% ]')
class Progress:
Start = Percentage(0)
ShowDeployConfig = Percentage(10)
GitInit = Percentage(12)
GitSetConfig = Percentage(13)
GitSetRepo = Percentage(15)
GitFetch = Percentage(40)
GitReset = Percentage(45)
GitCheckout = Percentage(48)
GitShowVersion = Percentage(50)
KillExisting = Percentage(60)
UpdateDependency = Percentage(70)
UpdateAlasApp = Percentage(75)
AdbReplace = Percentage(80)
AdbConnect = Percentage(95)
# Must have a 100%
Finish = Percentage(100)

View File

@ -1,10 +1,12 @@
import os
import re
import typing as t import typing as t
from dataclasses import dataclass from dataclasses import dataclass
from urllib.parse import urlparse from urllib.parse import urlparse
from deploy.Windows.config import DeployConfig from deploy.Windows.config import DeployConfig
from deploy.Windows.logger import logger from deploy.Windows.logger import logger, Progress
from deploy.Windows.utils import * from deploy.Windows.utils import cached_property
@dataclass @dataclass
@ -20,6 +22,7 @@ class DataDependency:
# PyYaml -> pyyaml # PyYaml -> pyyaml
self.name = self.name.lower() self.name = self.name.lower()
self.version = self.version.strip() self.version = self.version.strip()
self.version = re.sub(r'\.0$', '', self.version)
@cached_property @cached_property
def pretty_name(self): def pretty_name(self):
@ -93,10 +96,12 @@ class PipManager(DeployConfig):
if not self.InstallDependencies: if not self.InstallDependencies:
logger.info('InstallDependencies is disabled, skip') logger.info('InstallDependencies is disabled, skip')
Progress.UpdateDependency()
return return
if not len(self.set_dependency_to_install): if not len(self.set_dependency_to_install):
logger.info('All dependencies installed') logger.info('All dependencies installed')
Progress.UpdateDependency()
return return
else: else:
logger.info(f'Dependencies to install: {self.set_dependency_to_install}') logger.info(f'Dependencies to install: {self.set_dependency_to_install}')
@ -124,3 +129,4 @@ class PipManager(DeployConfig):
logger.hr('Update Dependencies', 1) logger.hr('Update Dependencies', 1)
arg = ' ' + ' '.join(arg) if arg else '' arg = ' ' + ' '.join(arg) if arg else ''
self.execute(f'{self.pip} install -r {self.requirements_file}{arg}') self.execute(f'{self.pip} install -r {self.requirements_file}{arg}')
Progress.UpdateDependency()

View File

@ -1,8 +1,9 @@
Deploy: Deploy:
Git: Git:
# URL of AzurLaneAutoScript repository # URL of AzurLaneAutoScript repository
# [Other] Use 'https://github.com/LmeSzinc/StarRailCopilot' # [CN user] Use 'cn' to get update from git-over-cdn service
Repository: 'https://github.com/LmeSzinc/StarRailCopilot' # [Other] Use 'global' to get update from https://github.com/LmeSzinc/StarRailCopilot
Repository: 'global'
# Branch of Alas # Branch of Alas
# [Developer] Use 'dev', 'app', etc, to try new features # [Developer] Use 'dev', 'app', etc, to try new features
# [Other] Use 'master', the stable branch # [Other] Use 'master', the stable branch
@ -156,3 +157,6 @@ Deploy:
# '["alas"]' specified "alas" config # '["alas"]' specified "alas" config
# '["alas","alas2"]' specified "alas" "alas2" configs # '["alas","alas2"]' specified "alas" "alas2" configs
Run: null Run: null
# --no-sandbox. https://github.com/electron/electron/issues/30966
# Some Windows systems cannot call the GPU normally for virtualization, and you need to manually turn off sandbox mode
NoSandbox: false

View File

@ -1,7 +1,7 @@
import os import os
import re import re
from dataclasses import dataclass from dataclasses import dataclass
from typing import Callable, Iterable, Generic, TypeVar from typing import Callable, Generic, Iterable, TypeVar
T = TypeVar("T") T = TypeVar("T")

View File

@ -1,3 +1,4 @@
from deploy.Windows.logger import Progress, logger
from deploy.Windows.patch import pre_checks from deploy.Windows.patch import pre_checks
pre_checks() pre_checks()
@ -22,5 +23,12 @@ class Installer(GitManager, PipManager, AdbManager, AppManager, AlasManager):
exit(1) exit(1)
if __name__ == '__main__': def run():
Installer().install() Progress.Start()
installer = Installer()
Progress.ShowDeployConfig()
installer.install()
logger.info('Finish')
Progress.Finish()

54
installer.py Normal file
View File

@ -0,0 +1,54 @@
import argparse
import sys
import typing as t
sys.stdout.reconfigure(encoding='utf-8')
"""
Alas installer
"""
def run_install():
from deploy.installer import run
run()
def run_print_test():
from deploy.Windows.installer_test import run
run()
def run_set(modify=t.List[str]) -> t.Dict[str, str]:
data = {}
for kv in modify:
if "=" in kv:
key, value = kv.split('=', maxsplit=1)
data[key] = value
from deploy.set import config_set
return config_set(data)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Alas installer")
parser.add_argument(
"--print-test",
help="To print example installer outputs instead of making an actual installation",
action="store_true",
)
parser.add_argument(
"--set",
help="Use key=value format to modify config/deploy.yaml\n"
"Example: python installer.py --set Branch=dev",
type=str,
nargs="*",
)
args, _ = parser.parse_known_args()
if args.set:
run_set(args.set)
elif args.print_test:
run_print_test()
else:
run_install()

View File

@ -472,7 +472,7 @@ class ConfigGenerator:
def generate_deploy_template(): def generate_deploy_template():
template = poor_yaml_read(DEPLOY_TEMPLATE) template = poor_yaml_read(DEPLOY_TEMPLATE)
cn = { cn = {
'Repository': 'https://e.coding.net/llop18870/alas/AzurLaneAutoScript.git', 'Repository': 'cn',
'PypiMirror': 'https://pypi.tuna.tsinghua.edu.cn/simple', 'PypiMirror': 'https://pypi.tuna.tsinghua.edu.cn/simple',
'Language': 'zh-CN', 'Language': 'zh-CN',
} }