mirror of
https://github.com/Escartem/AnimeWwise.git
synced 2026-06-05 07:50:23 +08:00
184 lines
5.6 KiB
Python
184 lines
5.6 KiB
Python
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
import mapper
|
|
import extract
|
|
from PyQt5 import uic
|
|
from PyQt5.QtGui import QTextCursor, QStandardItemModel, QStandardItem
|
|
from PyQt5.QtWidgets import QMessageBox, QMainWindow, QApplication, QFileDialog, QHeaderView
|
|
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QThread, QMetaType, Qt
|
|
|
|
QMetaType.type('QTextCursor')
|
|
|
|
class TextEditStream(QObject):
|
|
append_text = pyqtSignal(str)
|
|
|
|
def __init__(self, text_edit):
|
|
super().__init__()
|
|
self.text_edit = text_edit
|
|
self.append_text.connect(self._append_text)
|
|
|
|
def write(self, text):
|
|
self.append_text.emit(text)
|
|
|
|
def flush(self):
|
|
pass
|
|
|
|
def _append_text(self, text):
|
|
self.text_edit.moveCursor(QTextCursor.End)
|
|
self.text_edit.insertPlainText(text)
|
|
self.text_edit.moveCursor(QTextCursor.End)
|
|
|
|
class BackgroundWorker(QObject):
|
|
finished = pyqtSignal(dict)
|
|
progress = pyqtSignal(list)
|
|
|
|
def __init__(self, action, folders, _map, _format):
|
|
super().__init__()
|
|
self.action = action
|
|
# TODO: dynamic args depending on action
|
|
self.folders = folders
|
|
self.map = _map
|
|
self.format = _format
|
|
|
|
def run(self):
|
|
if self.action == "load":
|
|
print("Loading files and mapping if necessary...")
|
|
fileStructure = extract.WwiseExtract(self.map, "mp3", *self.folders, progress=self.progress.emit).load_folder()
|
|
print("Done !")
|
|
self.finished.emit({"action": "load", "content": fileStructure})
|
|
|
|
class AnimeWwise(QMainWindow):
|
|
def __init__(self):
|
|
super(AnimeWwise, self).__init__()
|
|
uic.loadUi("gui.ui", self)
|
|
self.maps = self.getMaps()
|
|
self.folders = {
|
|
"input": "",
|
|
"output": "",
|
|
"diff": ""
|
|
}
|
|
self.setupActions()
|
|
sys.stdout = TextEditStream(self.console)
|
|
|
|
# utils
|
|
self.selectFolder = lambda: QFileDialog.getExistingDirectory(self, "Select Folder")
|
|
|
|
def setFolder(self, elem, folder):
|
|
path = self.selectFolder()
|
|
self.folders[folder] = path
|
|
elem.setText(path)
|
|
|
|
def setupActions(self):
|
|
self.changeInput.clicked.connect(lambda: self.setFolder(self.inputPath, "input"))
|
|
self.changeAltInput.clicked.connect(lambda: self.setFolder(self.altInputPath, "diff"))
|
|
self.changeOutput.clicked.connect(lambda: self.setFolder(self.outputPath, "output"))
|
|
|
|
self.outputFormat.addItems(["mp3", "ogg"])
|
|
self.assetMap.addItems(["No map", *[f'{e["game"]} - v{e["version"]}' for e in self.maps["maps"]]])
|
|
|
|
self.tabs.setTabEnabled(1, False)
|
|
self.tabs.setTabEnabled(2, False)
|
|
|
|
self.loadFilesButton.clicked.connect(lambda: self.start())
|
|
|
|
self.actionClearTreeView.triggered.connect(lambda: self.resetTreeView())
|
|
self.actionExit.triggered.connect(lambda: self.close())
|
|
|
|
def getMaps(self):
|
|
with open("maps/index.json", "r") as f:
|
|
maps = json.loads(f.read())
|
|
f.close()
|
|
|
|
return maps
|
|
|
|
@pyqtSlot(list)
|
|
def progressBarSlot(self, progress):
|
|
if progress[0] == "total":
|
|
self.progress.setValue(progress[1])
|
|
elif progress[0] == "task":
|
|
self.taskProgress.setValue(progress[1])
|
|
|
|
def start(self):
|
|
if "" in [self.folders["input"], self.folders["output"]]:
|
|
QMessageBox.warning(None, "Warning", "Missing input/output folder !", QMessageBox.Ok)
|
|
return
|
|
|
|
_map = self.assetMap.currentIndex()
|
|
if _map != 0:
|
|
_map = self.maps["maps"][_map-1]["name"]
|
|
else:
|
|
_map = None
|
|
|
|
self.tabs.setTabEnabled(0, False)
|
|
self.resetTreeView()
|
|
|
|
self.extractThread = QThread()
|
|
self.extractWorker = BackgroundWorker("load", self.folders, _map, self.outputFormat.currentText())
|
|
self.extractWorker.moveToThread(self.extractThread)
|
|
self.extractThread.started.connect(self.extractWorker.run)
|
|
self.extractWorker.finished.connect(self.handleFinished)
|
|
self.extractWorker.finished.connect(self.extractThread.quit)
|
|
self.extractWorker.finished.connect(self.extractWorker.deleteLater)
|
|
self.extractThread.finished.connect(self.extractThread.deleteLater)
|
|
|
|
self.extractWorker.progress.connect(self.progressBarSlot)
|
|
self.extractThread.start()
|
|
|
|
@pyqtSlot(dict)
|
|
def handleFinished(self, data):
|
|
if data["action"] == "load":
|
|
self.fileStructure = data["content"]
|
|
self.updateTreeView()
|
|
self.tabs.setTabEnabled(0, True)
|
|
self.tabs.setTabEnabled(1, True)
|
|
self.tabs.setCurrentIndex(1)
|
|
|
|
def _appendText(self, text):
|
|
cursor = self.console.textCursor()
|
|
cursor.movePosition(cursor.End)
|
|
cursor.insertText(text)
|
|
self.console.setTextCursor(cursor)
|
|
self.console.ensureCursorVisible()
|
|
|
|
def resetTreeView(self):
|
|
model = QStandardItemModel()
|
|
self.treeView.setModel(model)
|
|
self.tabs.setTabEnabled(1, False)
|
|
|
|
def updateTreeView(self):
|
|
model = QStandardItemModel()
|
|
model.setHorizontalHeaderLabels(["Name", "Offset", "Size"])
|
|
# TODO: non swappable columns
|
|
|
|
root_item = model.invisibleRootItem()
|
|
self.addItems(root_item, self.fileStructure)
|
|
|
|
self.treeView.setModel(model)
|
|
self.treeView.expandAll()
|
|
|
|
self.treeView.header().setSectionResizeMode(0, QHeaderView.Stretch)
|
|
self.treeView.header().setSectionResizeMode(1, QHeaderView.ResizeToContents)
|
|
self.treeView.header().setSectionResizeMode(2, QHeaderView.ResizeToContents)
|
|
|
|
def addItems(self, parent, element):
|
|
for folder_name in sorted(element.get("folders", {}).keys()):
|
|
folder_content = element["folders"][folder_name]
|
|
folder_item = QStandardItem(folder_name)
|
|
folder_item.setCheckable(True)
|
|
# folder_item.setTristate(True)
|
|
parent.appendRow([folder_item, QStandardItem(""), QStandardItem("")])
|
|
self.addItems(folder_item, folder_content)
|
|
|
|
for file in sorted(element.get("files", [])):
|
|
file_item = QStandardItem(str(file[0]))
|
|
file_item.setCheckable(True)
|
|
parent.appendRow([file_item, QStandardItem(str(file[1])), QStandardItem(str(file[2]))])
|
|
|
|
if __name__ == "__main__":
|
|
app = QApplication(sys.argv)
|
|
window = AnimeWwise()
|
|
window.show()
|
|
sys.exit(app.exec_())
|