mirror of
https://github.com/relativemodder/aegnux.git
synced 2025-12-10 05:29:38 +05:00
private plugin installation
This commit is contained in:
@@ -9,6 +9,7 @@ from src.installationthread import InstallationThread
|
||||
from src.runaethread import RunAEThread
|
||||
from src.runexethread import RunExeThread
|
||||
from src.killaethread import KillAEThread
|
||||
from src.pluginthread import PluginThread
|
||||
from src.removeaethread import RemoveAEThread
|
||||
from src.utils import (
|
||||
check_aegnux_tip_marked, get_default_terminal, get_wine_bin_path_env,
|
||||
@@ -40,6 +41,11 @@ class MainWindow(MainWindowUI):
|
||||
self.remove_ae_thread = RemoveAEThread()
|
||||
self.remove_ae_thread.finished_signal.connect(self._finished)
|
||||
|
||||
self.plugin_thread = PluginThread()
|
||||
self.plugin_thread.log_signal.connect(self._log)
|
||||
self.plugin_thread.progress_signal.connect(self.progress_bar.setValue)
|
||||
self.plugin_thread.finished_signal.connect(self._finished)
|
||||
|
||||
self.alt_t_action = QAction(self)
|
||||
self.alt_t_action.setShortcut(QKeySequence("Alt+T"))
|
||||
self.alt_t_action.triggered.connect(self.run_command_alt_t)
|
||||
@@ -56,6 +62,7 @@ class MainWindow(MainWindowUI):
|
||||
self.ae_action.triggered.connect(self.run_ae_button_clicked)
|
||||
self.exe_action.triggered.connect(self.run_exe_button_clicked)
|
||||
self.reg_action.triggered.connect(self.reg_button_clicked)
|
||||
self.plugininst_action.triggered.connect(self.install_plugins_button_clicked)
|
||||
self.kill_action.triggered.connect(self.kill_ae_button_clicked)
|
||||
self.log_action.triggered.connect(self.toggle_logs)
|
||||
self.term_action.triggered.connect(self.run_command_alt_t)
|
||||
@@ -74,6 +81,7 @@ class MainWindow(MainWindowUI):
|
||||
self.runMenu.setEnabled(True)
|
||||
self.browseMenu.setEnabled(True)
|
||||
self.kill_action.setEnabled(True)
|
||||
self.plugininst_action.setEnabled(True)
|
||||
self.term_action.setEnabled(True)
|
||||
|
||||
else:
|
||||
@@ -85,11 +93,13 @@ class MainWindow(MainWindowUI):
|
||||
self.browseMenu.setEnabled(False)
|
||||
self.kill_action.setEnabled(False)
|
||||
self.term_action.setEnabled(False)
|
||||
self.plugininst_action.setEnabled(False)
|
||||
|
||||
def _construct_menubar(self):
|
||||
self.runMenu = self.menuBar().addMenu(gls('run_menu'))
|
||||
self.ae_action = self.runMenu.addAction(gls('ae_action'))
|
||||
self.exe_action = self.runMenu.addAction(gls('exe_action'))
|
||||
self.plugininst_action = self.runMenu.addAction(gls('plugininst_action'))
|
||||
self.reg_action = self.runMenu.addAction(gls('reg_action'))
|
||||
|
||||
self.browseMenu = self.menuBar().addMenu(gls('browse_menu'))
|
||||
@@ -108,6 +118,8 @@ class MainWindow(MainWindowUI):
|
||||
self.install_button.setEnabled(not lock)
|
||||
self.run_button.setEnabled(not lock)
|
||||
self.remove_aegnux_button.setEnabled(not lock)
|
||||
|
||||
self.runMenu.setEnabled(not lock)
|
||||
|
||||
@Slot()
|
||||
def toggle_logs(self):
|
||||
@@ -172,6 +184,29 @@ class MainWindow(MainWindowUI):
|
||||
self.progress_bar.show()
|
||||
self.install_thread.start()
|
||||
|
||||
@Slot()
|
||||
def install_plugins_button_clicked(self):
|
||||
QMessageBox.information(
|
||||
self,
|
||||
gls('plugin_note'),
|
||||
gls('plugin_note_text')
|
||||
)
|
||||
|
||||
filename, _ = QFileDialog.getOpenFileName(
|
||||
self,
|
||||
gls('offline_ae_zip_title'),
|
||||
"",
|
||||
"Zip Files (*.zip);;All Files (*)"
|
||||
)
|
||||
if filename == '':
|
||||
return
|
||||
|
||||
self.plugin_thread.set_plugin_zip_filename(filename)
|
||||
|
||||
self.lock_ui()
|
||||
self.progress_bar.show()
|
||||
self.plugin_thread.start()
|
||||
|
||||
@Slot()
|
||||
def run_ae_button_clicked(self):
|
||||
self.lock_ui()
|
||||
|
||||
162
src/pluginthread.py
Normal file
162
src/pluginthread.py
Normal file
@@ -0,0 +1,162 @@
|
||||
import os
|
||||
import shutil
|
||||
from src.processthread import ProcessThread
|
||||
from src.utils import get_private_plugins_unpack_path, get_ae_plugins_dir, get_wineprefix_dir
|
||||
|
||||
|
||||
class PluginThread(ProcessThread):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def set_plugin_zip_filename(self, filename: str):
|
||||
self.plugin_zip_filename = filename
|
||||
|
||||
def run(self):
|
||||
self.log_signal.emit('[DEBUG] Unpacking plugins from the archive...')
|
||||
self.progress_signal.emit(5)
|
||||
self.remove_ppu_dir()
|
||||
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
self.unpack_zip(self.plugin_zip_filename, ppu_dir.as_posix())
|
||||
self.progress_signal.emit(15)
|
||||
|
||||
self.install_aex_plugins()
|
||||
self.install_cep_extensions()
|
||||
self.install_presets()
|
||||
self.run_installers()
|
||||
|
||||
self.remove_ppu_dir()
|
||||
self.progress_signal.emit(95)
|
||||
self.log_signal.emit('[INFO] The plugins have been installed')
|
||||
|
||||
self.finished_signal.emit(True)
|
||||
self.progress_signal.emit(100)
|
||||
|
||||
def install_aex_plugins(self):
|
||||
self.log_signal.emit('[DEBUG] Installing aex plugins...')
|
||||
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
aex_src = ppu_dir.joinpath('aex')
|
||||
|
||||
for item in os.listdir(aex_src.as_posix()):
|
||||
if self._is_cancelled:
|
||||
self.cancelled.emit()
|
||||
return
|
||||
src_path = aex_src.joinpath(item)
|
||||
dst_path = get_ae_plugins_dir().joinpath(item)
|
||||
|
||||
if os.path.isdir(src_path):
|
||||
shutil.copytree(src_path, dst_path, dirs_exist_ok=True)
|
||||
else:
|
||||
shutil.copy2(src_path, dst_path)
|
||||
|
||||
self.log_signal.emit('[INFO] AEX plugins installed')
|
||||
self.progress_signal.emit(30)
|
||||
|
||||
def install_presets(self):
|
||||
self.log_signal.emit('[DEBUG] Installing presets...')
|
||||
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
preset_src = ppu_dir.joinpath('preset-backup')
|
||||
preset_dest = get_wineprefix_dir().joinpath('drive_c/users/relative/Documents/Adobe/After Effects 2024/User Presets')
|
||||
|
||||
os.makedirs(preset_dest, exist_ok=True)
|
||||
for item in os.listdir(preset_src):
|
||||
if self._is_cancelled:
|
||||
self.cancelled.emit()
|
||||
return
|
||||
src_path = preset_src.joinpath(item)
|
||||
dst_path = preset_dest.joinpath(item)
|
||||
if os.path.isdir(src_path):
|
||||
shutil.copytree(src_path, dst_path, dirs_exist_ok=True)
|
||||
else:
|
||||
shutil.copy2(src_path, dst_path)
|
||||
|
||||
self.log_signal.emit("[INFO] Presets installed")
|
||||
self.progress_signal.emit(55)
|
||||
|
||||
def run_installers(self):
|
||||
self.log_signal.emit('[DEBUG] Running installers...')
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
install_src = ppu_dir.joinpath('installer')
|
||||
|
||||
installers_counter = 0
|
||||
|
||||
for exe in os.listdir(install_src.as_posix()):
|
||||
if exe.endswith('.exe') and exe not in ['E3D.exe', 'saber.exe']:
|
||||
self.progress_signal.emit(55 + installers_counter * 3)
|
||||
|
||||
self.log_signal.emit(f"[INFO] Installing: {exe}")
|
||||
self.run_command(
|
||||
['wine', exe, '/verysilent', '/suppressmsgboxes'],
|
||||
install_src.as_posix(), True
|
||||
)
|
||||
|
||||
self.progress_signal.emit(70)
|
||||
|
||||
# Special handling for E3D and saber
|
||||
for exe in ['E3D.exe', 'saber.exe']:
|
||||
self.log_signal.emit(f"[INFO] Please manually install: {exe}")
|
||||
self.run_command(
|
||||
['wine', exe],
|
||||
install_src.as_posix(), True
|
||||
)
|
||||
|
||||
self.progress_signal.emit(85)
|
||||
self.copy_element_files()
|
||||
|
||||
def copy_element_files(self):
|
||||
self.log_signal.emit('[DEBUG] Copying Element files...')
|
||||
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
install_src = ppu_dir.joinpath('installer')
|
||||
|
||||
video_copilot_dir = get_ae_plugins_dir().joinpath("VideoCopilot")
|
||||
element_files = [
|
||||
("Element.aex", "Element.aex"),
|
||||
("Element.license", "Element.license")
|
||||
]
|
||||
|
||||
for src_name, dst_name in element_files:
|
||||
src_path = install_src.joinpath(src_name)
|
||||
if os.path.exists(src_path):
|
||||
shutil.copy2(src_path, os.path.join(video_copilot_dir, dst_name))
|
||||
self.log_signal.emit(f"[INFO] {src_name} copied successfully")
|
||||
|
||||
self.log_signal.emit("[INFO] Element installed")
|
||||
self.progress_signal.emit(90)
|
||||
|
||||
def install_cep_extensions(self):
|
||||
self.log_signal.emit('[DEBUG] Installing CEP extensions...')
|
||||
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
cep_dir = ppu_dir.joinpath('CEP')
|
||||
|
||||
cep_reg_file = cep_dir.joinpath("AddKeys.reg")
|
||||
self.run_command(['wine', "regedit", cep_reg_file.as_posix()], in_prefix=True)
|
||||
|
||||
self.install_flow()
|
||||
|
||||
self.log_signal.emit("[INFO] CEP extensions installed")
|
||||
self.progress_signal.emit(45)
|
||||
|
||||
def install_flow(self):
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
cep_dir = ppu_dir.joinpath('CEP')
|
||||
|
||||
self.log_signal.emit('[DEBUG] Installing Flow...')
|
||||
|
||||
flow_src = cep_dir.joinpath("flowv1.4.2")
|
||||
cep_dst = get_wineprefix_dir().joinpath("drive_c/Program Files (x86)/Common Files/Adobe/CEP/extensions")
|
||||
|
||||
os.makedirs(cep_dst, exist_ok=True)
|
||||
shutil.copytree(flow_src, os.path.join(cep_dst, "flowv1.4.2"), dirs_exist_ok=True)
|
||||
self.log_signal.emit("[INFO] Flow installed")
|
||||
|
||||
def remove_ppu_dir(self):
|
||||
ppu_dir = get_private_plugins_unpack_path()
|
||||
try:
|
||||
shutil.rmtree(ppu_dir.as_posix())
|
||||
self.log_signal.emit('[DEBUG] Temporary folder removed successfully.')
|
||||
except OSError as e:
|
||||
self.log_signal.emit(f'[WARNING] Failed to remove temporary folder {ppu_dir}: {e}')
|
||||
12
src/utils.py
12
src/utils.py
@@ -204,4 +204,14 @@ def check_aegnux_tip_marked():
|
||||
|
||||
def mark_aegnux_tip_as_shown():
|
||||
with open(get_aegnux_tip_marked_flag_path(), 'w') as f:
|
||||
f.write('Press ALT+T to open up a terminal')
|
||||
f.write('Press ALT+T to open up a terminal')
|
||||
|
||||
|
||||
def get_private_plugins_unpack_path():
|
||||
aegnux_dir = get_aegnux_installation_dir()
|
||||
ppu_dir = aegnux_dir.joinpath('private-plugins')
|
||||
|
||||
if not os.path.exists(ppu_dir):
|
||||
os.makedirs(ppu_dir)
|
||||
|
||||
return ppu_dir
|
||||
@@ -32,5 +32,11 @@ STRINGS = {
|
||||
'cep_action': 'CEP directory',
|
||||
'offline_note': 'Offline note',
|
||||
'offline_note_text': 'Note that the .zip archive should contain After Effects from Program Files (including AfterFX.exe).',
|
||||
'error': 'Error'
|
||||
'error': 'Error',
|
||||
'plugininst_action': 'Install private plugins from ZIP',
|
||||
'plugin_note': 'Private plugins note',
|
||||
'plugin_note_text': 'Those plugins are available at https://t.me/Aegnux',
|
||||
'done_title': 'Done!',
|
||||
'done_ae': 'AE has been installed.',
|
||||
'done_plugins': 'The plugins have been installed.'
|
||||
}
|
||||
@@ -32,5 +32,10 @@ STRINGS = {
|
||||
'cep_action': 'Папка с CEP',
|
||||
'offline_note': 'Внимание, оффлайн',
|
||||
'offline_note_text': 'Учтите, что .zip-архив должен содержать After Effects из Program Files (включая AfterFX.exe).',
|
||||
'error': 'Ошибка'
|
||||
'error': 'Ошибка',
|
||||
'plugininst_action': 'Установить приватные плагины из ZIP',
|
||||
'plugin_note': 'Замечание к приватным плагинам',
|
||||
'plugin_note_text': 'Эти плагины доступны здесь: https://t.me/Aegnux',
|
||||
'done_ae': 'AE был установлен.',
|
||||
'done_plugins': 'Плагины были установлены.'
|
||||
}
|
||||
@@ -32,5 +32,10 @@ STRINGS = {
|
||||
"cep_action": "Папка з CEP",
|
||||
'offline_note': 'Увага, офлайн',
|
||||
'offline_note_text': 'Зауважте, що .zip-архів повинен містити After Effects з Program Files (включаючи AfterFX.exe).',
|
||||
'error': 'Помилка'
|
||||
'error': 'Помилка',
|
||||
'plugininst_action': 'Встановити приватні плагіни з ZIP',
|
||||
'plugin_note': 'Примітка до приватних плагінів',
|
||||
'plugin_note_text': 'Ці плагіни доступні тут: https://t.me/Aegnux',
|
||||
'done_ae': 'AE було встановлено.',
|
||||
'done_plugins': 'Плагіни було встановлено.'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user