forked from CastroFidel/winehelper
Compare commits
1 Commits
license_ag
...
download_p
Author | SHA1 | Date | |
---|---|---|---|
9611cc52fc |
@ -1,14 +0,0 @@
|
||||
Лицензионные соглашения использования сторонних компонентов:
|
||||
|
||||
Некоторые компоненты, установленные в префикс и необходимые для запуска приложений,
|
||||
могут быть защищены авторским правом или лицензионными соглашениями. Вы обязаны
|
||||
самостоятельно убедиться в законности использования этих компонентов в вашей
|
||||
юрисдикции.
|
||||
|
||||
Мы не несём ответственности за нарушение лицензионных соглашений, связанное с
|
||||
использованием подготовленного префикса, а так же за программное обеспечение,
|
||||
поставляемое из сторонних источников.
|
||||
|
||||
Подтверждая продолжение установки, вы соглашаетесь, что ознакомились с данным
|
||||
отказом от ответственности и принимаете все риски, связанные с использованием
|
||||
программного обеспечения.
|
24
winehelper
24
winehelper
@ -7,7 +7,7 @@ if [[ $(id -u) -eq 0 ]] ; then
|
||||
fi
|
||||
|
||||
##### DEFAULT PATH #####
|
||||
export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH LICENSE_FILE AGREEMENT
|
||||
export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH LICENSE_FILE
|
||||
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
|
||||
@ -18,7 +18,6 @@ if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
|
||||
CHANGELOG_FILE="$(realpath "/usr/share/doc/winehelper"-*/CHANGELOG)"
|
||||
WH_ICON_PATH="$DATA_PATH/image/gui/winehelper.svg"
|
||||
LICENSE_FILE="$(realpath "/usr/share/doc/winehelper"-*/LICENSE)"
|
||||
AGREEMENT="$(realpath "/usr/share/doc/winehelper"-*/LICENSE_AGREEMENT)"
|
||||
else
|
||||
# переменные для тестового запуска WineHelper из репозитория
|
||||
USER_WORK_PATH="$HOME/test-$SCRIPT_NAME"
|
||||
@ -27,7 +26,6 @@ else
|
||||
CHANGELOG_FILE="$DATA_PATH/CHANGELOG"
|
||||
WH_ICON_PATH="$DATA_PATH/image/gui/winehelper-devel.svg"
|
||||
LICENSE_FILE="$DATA_PATH/LICENSE"
|
||||
AGREEMENT="$DATA_PATH/LICENSE_AGREEMENT"
|
||||
|
||||
# минимальная проверка синтаксиса скриптов
|
||||
for self_check_script in "$RUN_SCRIPT" \
|
||||
@ -369,14 +367,20 @@ print_license_agreement () {
|
||||
then return 0
|
||||
fi
|
||||
|
||||
if [[ -f "$AGREEMENT" ]]; then
|
||||
echo
|
||||
print_warning "$(cat "$AGREEMENT")"
|
||||
else
|
||||
fatal "Файл лицензионного соглашения не найден: $AGREEMENT"
|
||||
fi
|
||||
|
||||
echo
|
||||
print_warning "Лицензионные соглашения использования сторонних компонентов:
|
||||
|
||||
Некоторые компоненты, установленные в префикс и необходимые для запуска приложений, могут
|
||||
быть защищены авторским правом или лицензионными соглашениями. Вы обязаны самостоятельно
|
||||
убедиться в законности использования этих компонентов в вашей юрисдикции.
|
||||
|
||||
Мы не несём ответственности за нарушение лицензионных соглашений, связанное с использованием
|
||||
подготовленного префикса, а так же за программное обеспечение поставляемого из сторонних источников.
|
||||
|
||||
Подтверждая продолжение установки, вы соглашаетесь что ознакомились с данным отказом от
|
||||
ответственности и принимаете все риски, связанные с использованием программного обеспечения.
|
||||
"
|
||||
|
||||
if print_confirmation "Подтвердите продолжение установки" ; then
|
||||
touch "$license_agreement_file"
|
||||
chmod 600 "$license_agreement_file"
|
||||
|
@ -2,9 +2,9 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import html
|
||||
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,QPushButton, QLabel, QTabWidget,
|
||||
QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea,
|
||||
QGridLayout, QFrame, QDialog, QTextBrowser)
|
||||
@ -21,7 +21,6 @@ class Var:
|
||||
CHANGELOG_FILE = os.environ.get("CHANGELOG_FILE")
|
||||
WH_ICON_PATH = os.environ.get("WH_ICON_PATH")
|
||||
LICENSE_FILE = os.environ.get("LICENSE_FILE")
|
||||
LICENSE_AGREEMENT_FILE = os.environ.get("AGREEMENT")
|
||||
|
||||
class WineHelperGUI(QMainWindow):
|
||||
def __init__(self):
|
||||
@ -91,6 +90,9 @@ class WineHelperGUI(QMainWindow):
|
||||
self.create_installed_tab()
|
||||
self.create_help_tab()
|
||||
|
||||
# Инициализируем состояние, которое будет использоваться для логов
|
||||
self._reset_log_state()
|
||||
|
||||
# Обновляем список установленных приложений
|
||||
self.update_installed_apps()
|
||||
|
||||
@ -606,6 +608,7 @@ class WineHelperGUI(QMainWindow):
|
||||
# Подвкладка "Лицензия"
|
||||
license_tab = QWidget()
|
||||
license_layout = QVBoxLayout(license_tab)
|
||||
import html
|
||||
license_text = QTextBrowser()
|
||||
license_text.setOpenExternalLinks(True)
|
||||
|
||||
@ -1256,32 +1259,38 @@ class WineHelperGUI(QMainWindow):
|
||||
license_page = QWidget()
|
||||
license_layout = QVBoxLayout(license_page)
|
||||
|
||||
license_found = False
|
||||
license_text = QTextEdit()
|
||||
license_text.setReadOnly(True)
|
||||
|
||||
license_text = QTextBrowser()
|
||||
|
||||
# Получаем текст лицензионного соглашения из файла
|
||||
# Получаем текст лицензии из скрипта winehelper
|
||||
script_path = os.path.join(Var.DATA_PATH, "winehelper")
|
||||
license_content = ""
|
||||
try:
|
||||
license_file_path = Var.LICENSE_AGREEMENT_FILE
|
||||
if not license_file_path or not os.path.exists(license_file_path):
|
||||
raise FileNotFoundError
|
||||
with open(script_path, 'r', encoding='utf-8') as f:
|
||||
capturing = False
|
||||
for line in f:
|
||||
if 'print_warning "Лицензионные соглашения использования сторонних компонентов:' in line:
|
||||
capturing = True
|
||||
continue
|
||||
|
||||
with open(license_file_path, 'r', encoding='utf-8') as f:
|
||||
license_content = f.read()
|
||||
|
||||
escaped_license_content = html.escape(license_content)
|
||||
if capturing:
|
||||
if 'Подтверждая продолжение установки' in line:
|
||||
break
|
||||
# Очищаем строку от лишних символов
|
||||
clean_line = line.strip()
|
||||
clean_line = clean_line.replace('print_warning "', '').replace('\\n', '\n')
|
||||
clean_line = clean_line.rstrip('"')
|
||||
license_content += clean_line + '\n'
|
||||
|
||||
license_text.setHtml(f"""
|
||||
<pre style="font-family: sans-serif; font-size: 10pt; white-space: pre-wrap; word-wrap: break-word;">{escaped_license_content}</pre>
|
||||
<h3>Лицензионные соглашения использования сторонних компонентов:</h3>
|
||||
<p>{license_content}</p>
|
||||
""")
|
||||
license_found = True
|
||||
except (FileNotFoundError, TypeError):
|
||||
license_text.setHtml(f'<h3>Лицензионные соглашения</h3><p>Не удалось загрузить файл лицензионного соглашения по пути:<br>{Var.LICENSE_AGREEMENT_FILE}</p>')
|
||||
except Exception as e:
|
||||
print(f"Ошибка чтения файла лицензии: {str(e)}")
|
||||
license_text.setHtml(f"""
|
||||
print(f"Ошибка чтения файла для извлечения лицензии: {str(e)}")
|
||||
license_text.setHtml("""
|
||||
<h3>Лицензионные соглашения</h3>
|
||||
<p>Произошла ошибка при чтении файла лицензии:<br>{str(e)}</p>
|
||||
<p>Не удалось загрузить текст лицензионного соглашения.</p>
|
||||
""")
|
||||
|
||||
license_layout.addWidget(license_text)
|
||||
@ -1328,15 +1337,18 @@ class WineHelperGUI(QMainWindow):
|
||||
lambda state: self.btn_continue.setEnabled(state == Qt.Checked)
|
||||
)
|
||||
|
||||
if not license_found:
|
||||
self.license_checkbox.setEnabled(False)
|
||||
|
||||
self.install_dialog.show()
|
||||
|
||||
def _reset_log_state(self):
|
||||
"""Сбрасывает состояние буфера и флага прогресса для лога установки."""
|
||||
self.output_buffer = ""
|
||||
self.last_line_was_progress = False
|
||||
|
||||
def _prepare_installation(self):
|
||||
"""Подготавливает и запускает процесс установки"""
|
||||
self.stacked_widget.setCurrentIndex(1)
|
||||
|
||||
self._reset_log_state() # Сбрасываем состояние для обработки лога
|
||||
|
||||
winehelper_path = self.winehelper_path
|
||||
script_path = os.path.join(Var.DATA_PATH,
|
||||
"autoinstall" if self.current_script in self.autoinstall_scripts else "manualinstall",
|
||||
@ -1383,34 +1395,99 @@ class WineHelperGUI(QMainWindow):
|
||||
self.install_process.start(winehelper_path, args)
|
||||
if not self.install_process.waitForStarted(3000):
|
||||
raise RuntimeError("Не удалось запустить процесс установки")
|
||||
self.append_log("Процесс установки запущен...")
|
||||
self.append_log("Процесс установки успешно запущен...")
|
||||
except Exception as e:
|
||||
self.append_log(f"\n=== ОШИБКА: {str(e)} ===", is_error=True)
|
||||
QMessageBox.critical(self.install_dialog, "Ошибка", f"Не удалось запустить установку:\n{str(e)}")
|
||||
self.cleanup_process()
|
||||
|
||||
def append_log(self, text, is_error=False):
|
||||
def append_log(self, text, is_error=False, add_newline=True):
|
||||
"""Добавляет сообщение в лог"""
|
||||
if not hasattr(self, 'log_output'): return
|
||||
cursor = self.log_output.textCursor()
|
||||
cursor.movePosition(QTextCursor.End)
|
||||
|
||||
if is_error:
|
||||
# Для ошибок всегда добавляем перенос строки для лучшей читаемости
|
||||
cursor.insertHtml(f'<font color="red">{text}</font><br>')
|
||||
else:
|
||||
cursor.insertText(f"{text}\n")
|
||||
# Вставляем текст. Добавляем перенос строки, если нужно.
|
||||
formatted_text = f"{text}\n" if add_newline else text
|
||||
cursor.insertText(formatted_text)
|
||||
|
||||
self.log_output.ensureCursorVisible()
|
||||
QApplication.processEvents()
|
||||
|
||||
def _process_log_line(self, line_with_delimiter):
|
||||
"""Обрабатывает одну строку лога, управляя заменой строк прогресса."""
|
||||
is_progress_line = '\r' in line_with_delimiter
|
||||
|
||||
# Фильтруем "мусорные" строки прогресса (например, '-=O=-' от wget),
|
||||
# обрабатывая только те, что содержат знак процента.
|
||||
if is_progress_line:
|
||||
if not re.search(r'\d\s*%', line_with_delimiter):
|
||||
return # Игнорируем строку прогресса без процентов
|
||||
|
||||
clean_line = line_with_delimiter.replace('\r', '').replace('\n', '').strip()
|
||||
|
||||
if not clean_line:
|
||||
return
|
||||
|
||||
cursor = self.log_output.textCursor()
|
||||
|
||||
# Если новая строка - это прогресс, и предыдущая тоже была прогрессом,
|
||||
# то мы удаляем старую, чтобы заменить ее новой.
|
||||
if is_progress_line and self.last_line_was_progress:
|
||||
cursor.movePosition(QTextCursor.End)
|
||||
cursor.select(QTextCursor.LineUnderCursor)
|
||||
cursor.removeSelectedText()
|
||||
elif not is_progress_line and self.last_line_was_progress:
|
||||
# Это переход от строки прогресса к финальной строке.
|
||||
# Вместо добавления переноса, мы заменяем предыдущую строку новой.
|
||||
cursor.movePosition(QTextCursor.End)
|
||||
cursor.select(QTextCursor.LineUnderCursor)
|
||||
cursor.removeSelectedText()
|
||||
|
||||
# Добавляем новую очищенную строку.
|
||||
# Для прогресса - без переноса строки, для обычных строк - с переносом.
|
||||
self.append_log(clean_line, add_newline=not is_progress_line)
|
||||
|
||||
self.last_line_was_progress = is_progress_line
|
||||
|
||||
def handle_process_output(self):
|
||||
"""Обрабатывает вывод процесса"""
|
||||
output = self.install_process.readAllStandardOutput().data().decode('utf-8', errors='ignore').strip()
|
||||
if output:
|
||||
self.append_log(output)
|
||||
"""Обрабатывает вывод процесса, корректно отображая однострочный прогресс."""
|
||||
new_data = self.install_process.readAllStandardOutput().data().decode('utf-8', errors='ignore')
|
||||
self.output_buffer += new_data
|
||||
|
||||
while True:
|
||||
# Ищем ближайший разделитель (\n или \r)
|
||||
idx_n = self.output_buffer.find('\n')
|
||||
idx_r = self.output_buffer.find('\r')
|
||||
|
||||
if idx_n == -1 and idx_r == -1:
|
||||
break # Нет полных строк для обработки
|
||||
|
||||
split_idx = min(idx for idx in [idx_n, idx_r] if idx != -1)
|
||||
|
||||
# Получаем строку, включая разделитель
|
||||
line = self.output_buffer[:split_idx + 1]
|
||||
self.output_buffer = self.output_buffer[split_idx + 1:]
|
||||
|
||||
self._process_log_line(line)
|
||||
|
||||
def handle_process_finished(self, exit_code, exit_status):
|
||||
"""Обрабатывает завершение процесса"""
|
||||
# Обрабатываем остаток в буфере, если он есть
|
||||
if self.output_buffer:
|
||||
self._process_log_line(self.output_buffer)
|
||||
|
||||
# Если последней строкой был прогресс, "завершаем" его переносом строки.
|
||||
if self.last_line_was_progress:
|
||||
cursor = self.log_output.textCursor()
|
||||
cursor.movePosition(QTextCursor.End)
|
||||
cursor.insertText("\n")
|
||||
|
||||
self._reset_log_state()
|
||||
if exit_code == 0 and exit_status == QProcess.NormalExit:
|
||||
self.append_log("\n=== Установка успешно завершена ===")
|
||||
# Создаем кастомный диалог, чтобы кнопка была на русском
|
||||
|
Reference in New Issue
Block a user