init_wine is worked

This commit is contained in:
Mikhail Tergoev 2025-03-11 02:29:04 +03:00
parent 58bb8d4b46
commit ae36b3bddd
5 changed files with 77 additions and 48 deletions

@ -16,9 +16,9 @@ def try_download(url, save_path=None):
response = requests.get(url, stream=True) response = requests.get(url, stream=True)
response.raise_for_status() # Проверяем, что запрос успешен response.raise_for_status() # Проверяем, что запрос успешен
# Определяем имя файла, если save_path не указан # Определяем имя файла, если save_path не указан, или путь это директория
if save_path is None: if save_path is None:
save_path = os.path.basename(url) save_path = tmp_path + "/" + os.path.basename(url)
elif os.path.isdir(save_path): elif os.path.isdir(save_path):
save_path = save_path + "/" + os.path.basename(url) save_path = save_path + "/" + os.path.basename(url)
@ -39,9 +39,12 @@ def try_download(url, save_path=None):
progress_bar.update(len(chunk)) # Обновляем прогресс-бар progress_bar.update(len(chunk)) # Обновляем прогресс-бар
log.info(f"Файл успешно скачан и сохранён как {save_path}.") log.info(f"Файл успешно скачан и сохранён как {save_path}.")
return True
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
log.error(f"Ошибка при скачивании файла: {e}") log.error(f"Ошибка при скачивании файла: {e}")
except Exception as e: except Exception as e:
log.error(f"Неизвестная ошибка: {e}") log.error(f"Неизвестная ошибка: {e}")
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
log.error(f"Прервано пользователем: {e}") log.error(f"Прервано пользователем: {e}")
return False

@ -3,9 +3,24 @@ import shutil
import filecmp import filecmp
import tarfile import tarfile
import hashlib import hashlib
import tempfile
from .env_var import *
from .config_parser import *
from .log import * from .log import *
# константы:
tmp_path = tempfile.gettempdir() + "/portproton"
work_path = get_env_var("USER_WORK_PATH")
data_path = work_path + "/data"
dist_path = data_path + "/dist"
img_path = data_path + "/img"
vulkan_path = data_path + "/vulkan"
plugins_path = data_path + "/plugins_v" + var("plugins_ver")
libs_path = data_path + "/libs_v" + var("libs_ver")
log.info(f"рабочий каталог: {work_path}")
def try_copy_file(source, destination): # функция копирования если файлы различаются def try_copy_file(source, destination): # функция копирования если файлы различаются
if not os.path.exists(source): if not os.path.exists(source):
raise FileNotFoundError (f"file not found for copy: {source}") raise FileNotFoundError (f"file not found for copy: {source}")
@ -62,6 +77,21 @@ def try_force_link_dir(path, link):
except Exception as e: except Exception as e:
log.error(f"failed to create link for file: {e}") log.error(f"failed to create link for file: {e}")
def try_move_dir(src, dst): # Перемещает каталог src в dst, заменяя существующие файлы.
for src_dir, dirs, files in os.walk(src):
dst_dir = src_dir.replace(src, dst, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
if os.path.samefile(src_file, dst_file):
continue
os.remove(dst_file)
shutil.move(src_file, dst_dir)
try_remove_dir(src)
def replace_file(file_path, file_name): # функция замены файла (сначала запись во временный файл, потом замена) def replace_file(file_path, file_name): # функция замены файла (сначала запись во временный файл, потом замена)
try: try:
if os.path.exists(file_name) and os.path.getsize(file_name) > 0: if os.path.exists(file_name) and os.path.getsize(file_name) > 0:
@ -98,8 +128,6 @@ def get_last_modified_time(file_path, fallback=None): # Добавьте fallba
log.error(f"Ошибка при получении времени изменения файла {file_path}: {e}") log.error(f"Ошибка при получении времени изменения файла {file_path}: {e}")
return fallback # Возврат значения по умолчанию return fallback # Возврат значения по умолчанию
def unpack(archive_path, extract_to=None): def unpack(archive_path, extract_to=None):
# Проверяем, существует ли архив # Проверяем, существует ли архив
if not os.path.isfile(archive_path): if not os.path.isfile(archive_path):
@ -107,15 +135,15 @@ def unpack(archive_path, extract_to=None):
return False return False
try: try:
if extract_to is None: if extract_to is None:
# TODO: перенести распаковку по умолчанию в tmp extract_to = tmp_path + "/" + os.path.dirname(archive_path)
extract_to = os.path.dirname(archive_path)
elif not os.path.isdir(extract_to): elif not os.path.isdir(extract_to):
create_new_dir(extract_to) create_new_dir(extract_to)
log.info(f"unpacking file: {archive_path}")
with tarfile.open(archive_path, mode="r:*") as tar: with tarfile.open(archive_path, mode="r:*") as tar:
tar.extractall(path=extract_to) tar.extractall(path=extract_to)
full_path = os.path.realpath(extract_to) full_path = os.path.realpath(extract_to)
log.info(f"Архив {archive_path} успешно распакован в {full_path}") log.info(f"Архив {archive_path} успешно распакован в {full_path}")
except tarfile.TarError as e: except tarfile.TarError as e:
log.error(f"Ошибка при распаковке архива {archive_path}: {e}") log.error(f"Ошибка при распаковке архива {archive_path}: {e}")
return False return False
@ -129,9 +157,7 @@ def unpack(archive_path, extract_to=None):
return True return True
def check_hash_sum(check_file, check_sum): def check_hash_sum(check_file, check_sum):
if check_sum and isinstance(check_sum, str): if os.path.isfile(check_sum):
true_hash = check_sum
elif os.path.isfile(check_sum):
try: try:
with open(check_sum, "r", encoding="utf-8") as file: with open(check_sum, "r", encoding="utf-8") as file:
first_line = file.readline().strip() first_line = file.readline().strip()
@ -144,6 +170,8 @@ def check_hash_sum(check_file, check_sum):
log.error(f"Файл {check_sum} не найден.") log.error(f"Файл {check_sum} не найден.")
except Exception as e: except Exception as e:
log.error(f"Ошибка при чтении файла: {e}") log.error(f"Ошибка при чтении файла: {e}")
elif check_sum and isinstance(check_sum, str):
true_hash = check_sum
else: else:
log.error(f"Verification sha256sum was failed: {check_file}") log.error(f"Verification sha256sum was failed: {check_file}")

@ -6,24 +6,38 @@ from .log import *
from .env_var import * from .env_var import *
from .files_worker import * from .files_worker import *
from .config_parser import * from .config_parser import *
from .downloader import *
def init_wine(dist_path): def init_wine(wine_version=None):
used_wine_upper = var("used_wine").upper() if wine_version is None:
used_wine = var("used_wine")
else:
used_wine = wine_version
# TODO: будем переименовывать все каталоги wine в верхний регистр? # TODO: будем переименовывать все каталоги wine в верхний регистр?
if used_wine_upper != "SYSTEM": if used_wine.upper() != "SYSTEM":
if used_wine_upper == "WINE_LG": if used_wine.upper() == "WINE_LG":
used_wine = var("default_wine") used_wine = var("default_wine")
elif used_wine_upper == "PROTON_LG": elif used_wine.upper() == "PROTON_LG":
used_wine = var("default_proton") used_wine = var("default_proton")
wine_path = dist_path + "/" + used_wine wine_path = dist_path + "/" + used_wine
if not os.path.exists(wine_path + "/bin/wine"): if not os.path.exists(wine_path + "/bin/wine"):
# TODO: если нет wine то качаем и распаковываем
log.warning(f"{used_wine} not found. Try download...") log.warning(f"{used_wine} not found. Try download...")
# TODO: использовать зеркало при необходимости
# url_github_lg="https://github.com/Castro-Fidel/wine_builds/releases/download/" + used_wine + "/" + used_wine
url_cloud_lg="https://cloud.linux-gaming.ru/portproton/" + used_wine
if try_download(url_cloud_lg + ".tar.xz") and try_download(url_cloud_lg + ".sha256sum"):
if check_hash_sum(tmp_path + "/" + used_wine + ".tar.xz", tmp_path + "/" + used_wine + ".sha256sum"):
unpack(tmp_path + "/" + used_wine + ".tar.xz", dist_path)
for f in [".tar.xz", ".sha256sum"]:
try_remove_file(tmp_path + "/" + used_wine + f)
if not os.path.exists(wine_path + "/bin/wine"): if not os.path.exists(wine_path + "/bin/wine"):
log.critical(f"{used_wine} not found. Interrupt!") log.critical(f"{used_wine} not found. Interrupt!")
@ -41,12 +55,15 @@ def init_wine(dist_path):
set_env_var_force("MEDIACONV_BLANK_VIDEO_FILE", wine_share + "/media/blank.mkv") set_env_var_force("MEDIACONV_BLANK_VIDEO_FILE", wine_share + "/media/blank.mkv")
set_env_var_force("MEDIACONV_BLANK_AUDIO_FILE", wine_share + "/media/blank.ptna") set_env_var_force("MEDIACONV_BLANK_AUDIO_FILE", wine_share + "/media/blank.ptna")
# TODO: mono, gecko for wine_utils in ["mono", "gecko"]:
if not os.path.islink(wine_share + "/wine/" + wine_utils):
if os.path.isdir(wine_share + "/wine/" + wine_utils):
try_move_dir(wine_share + "/wine/" + wine_utils, data_path + "/" + wine_utils)
try_force_link_dir(data_path + "/" + wine_utils, wine_share + "/wine/" + wine_utils)
else: else:
try: try:
result = subprocess.run(['wine', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, result = subprocess.run(['wine', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
text=True)
if result.returncode == 0: if result.returncode == 0:
log.info(f"Используется системная версия WINE: {result.stdout.strip()}") log.info(f"Используется системная версия WINE: {result.stdout.strip()}")
wine_path = "/usr" wine_path = "/usr"

@ -6,7 +6,6 @@ from modules.files_worker import *
count_wines = 25 # Количество элементов для записи в .tmp файл count_wines = 25 # Количество элементов для записи в .tmp файл
repos = { # Список репозиториев для обработки и их короткие имена repos = { # Список репозиториев для обработки и их короткие имена
"GloriousEggroll/proton-ge-custom": "proton-ge-custom", "GloriousEggroll/proton-ge-custom": "proton-ge-custom",
"GloriousEggroll/wine-ge-custom": "wine-ge-custom", "GloriousEggroll/wine-ge-custom": "wine-ge-custom",
@ -19,13 +18,13 @@ mirrors = {
"https://cloud.linux-gaming.ru": "LG_mirror" "https://cloud.linux-gaming.ru": "LG_mirror"
} }
def source_list_checker(tmp_path): def source_list_checker():
for repo, short_name in repos.items(): for repo, short_name in repos.items():
output_file = os.path.join(tmp_path, f"{short_name}.tmp") output_file = os.path.join(tmp_path, f"{short_name}.tmp")
if not os.path.exists(output_file) or os.path.getsize(output_file) == 0 or \ if not os.path.exists(output_file) or os.path.getsize(output_file) == 0 or \
(time.time() - get_last_modified_time(output_file, fallback=0)) >= 10800: (time.time() - get_last_modified_time(output_file, fallback=0)) >= 10800:
source_list_downloader(repo, tmp_path, short_name, output_file) source_list_downloader(repo, short_name, output_file)
else: else:
log.info(f"Файл {output_file} существует и был обновлён менее 3 часов назад. Используем кэшированные данные.") log.info(f"Файл {output_file} существует и был обновлён менее 3 часов назад. Используем кэшированные данные.")
@ -34,11 +33,11 @@ def source_list_checker(tmp_path):
if not os.path.exists(output_file) or os.path.getsize(output_file) == 0 or \ if not os.path.exists(output_file) or os.path.getsize(output_file) == 0 or \
(time.time() - get_last_modified_time(output_file, fallback=0)) >= 10800: (time.time() - get_last_modified_time(output_file, fallback=0)) >= 10800:
source_list_downloader(mirror_url, tmp_path, short_name, output_file, use_github=False) source_list_downloader(mirror_url, short_name, output_file, use_github=False)
else: else:
log.info(f"Файл {output_file} существует и был обновлён менее 3 часов назад. Используем кэшированные данные.") log.info(f"Файл {output_file} существует и был обновлён менее 3 часов назад. Используем кэшированные данные.")
def source_list_downloader(source, tmp_path, short_name, output_file, use_github=True): def source_list_downloader(source, short_name, output_file, use_github=True):
if use_github: if use_github:
url = f"https://api.github.com/repos/{source}/releases?per_page={count_wines}" url = f"https://api.github.com/repos/{source}/releases?per_page={count_wines}"
else: else:
@ -87,9 +86,9 @@ def source_list_downloader(source, tmp_path, short_name, output_file, use_github
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
log.error(f"Ошибка при получении данных из {source}: {str(e)}") log.error(f"Ошибка при получении данных из {source}: {str(e)}")
def get_sources(args, tmp_path, dist_path, mirror): def get_sources(args, mirror):
os.makedirs(tmp_path, exist_ok=True) os.makedirs(tmp_path, exist_ok=True)
source_list_checker(tmp_path) source_list_checker()
if not args: if not args:
log.critical("Аргументы не предоставлены. Завершение работы.") log.critical("Аргументы не предоставлены. Завершение работы.")

@ -1,43 +1,25 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys import sys
import tempfile
from modules.config_parser import *
from modules.log import * from modules.log import *
from modules.env_var import *
from modules.files_worker import * from modules.files_worker import *
from modules.downloader import * from modules.downloader import *
from modules.init_wine import * from modules.init_wine import *
from modules.source_fetcher import * from modules.source_fetcher import *
tmp_path = tempfile.gettempdir() + "/portproton" mirror = True # перенести в функцию как (arg, mirror=True)
mirror = True
work_path = get_env_var("USER_WORK_PATH")
data_path = work_path + "/data"
dist_path = data_path + "/dist"
img_path = data_path + "/img"
vulkan_path = data_path + "/vulkan"
plugins_path = data_path + "/plugins_v" + var("plugins_ver")
libs_path = data_path + "/libs_v" + var("libs_ver")
create_new_dir(dist_path, tmp_path, img_path, vulkan_path)
log.info(f"рабочий каталог: {work_path}")
log.info(f"принятые аргументы: {sys.argv[1:]}") log.info(f"принятые аргументы: {sys.argv[1:]}")
if __name__ == "__main__": if __name__ == "__main__":
# TODO: реализовать все функции get_* в модуль downloader.py: create_new_dir(dist_path, tmp_path, img_path, vulkan_path)
if len(sys.argv) > 1: # Проверяем, что есть хотя бы один аргумент (кроме имени скрипта) if len(sys.argv) > 1: # Проверяем, что есть хотя бы один аргумент (кроме имени скрипта)
match sys.argv[1]: # Игнорируем первый аргумент (имя скрипта) match sys.argv[1]: # Игнорируем первый аргумент (имя скрипта)
case "--get-wine": case "--get-wine":
# без аргументов сохраняем список доступных в tmp_path/get_wine.tmp и выводим в терминал # без аргументов сохраняем список доступных в tmp_path/get_wine.tmp и выводим в терминал
# если есть аргумент (например WINE_LG_10-1) то обновляем и парсим tmp_path/get_wine.tmp с последующим скачиванием # если есть аргумент (например WINE_LG_10-1) то обновляем и парсим tmp_path/get_wine.tmp с последующим скачиванием
get_sources(sys.argv[2:], tmp_path, dist_path, mirror) get_sources(sys.argv[2:], mirror)
case "--get-dxvk": case "--get-dxvk":
# без аргументов сохраняем список доступных в tmp_path/get_dxvk.tmp и выводим в терминал # без аргументов сохраняем список доступных в tmp_path/get_dxvk.tmp и выводим в терминал
# если есть аргумент (например 2.5.3-31) то обновляем и парсим tmp_path/get_dxvk.tmp с последующим скачиванием # если есть аргумент (например 2.5.3-31) то обновляем и парсим tmp_path/get_dxvk.tmp с последующим скачиванием
@ -53,4 +35,4 @@ if __name__ == "__main__":
# версия контейнера будет захардкожена, парсить ничего не надо # версия контейнера будет захардкожена, парсить ничего не надо
get_libs(libs_ver) get_libs(libs_ver)
init_wine(dist_path) init_wine("WINE_LG")