-
Notifications
You must be signed in to change notification settings - Fork 4
/
gui.py
271 lines (234 loc) · 13.5 KB
/
gui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
from logging.handlers import DEFAULT_TCP_LOGGING_PORT
import os
import sys
import glob
try:
from PyQt6 import QtWidgets, uic
from PyQt6.QtWidgets import QMessageBox, QApplication
from PyQt6.QtCore import QT_VERSION_STR
except ModuleNotFoundError:
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import QT_VERSION_STR
# Imports from this project
from release import year, lstupdt, spath, curb, ver, settingsPath, audioDirDefault, videoDirDefault
from gui.Audio import Audio, aud_playlist_bar_toggle
from gui.Video import Video, vid_quality, vid_playlist_bar_toggle, vid_quality_bar_toggle
from gui.Subs import Subs, sub_lang, sub_playlist_bar_toggle
from gui.ReEncode import Reencode, ree_settings, ree_settings_save, ree_choose
from gui.Update import Update, upd_auto_toggle
from gui.Settings import set_save, set_load, set_makeScript, WriteDefaultJson
from shared.ReEncode import reencode_shared_settings
from shared.Config import Settings
# changing python working directory to script location to fix most path issues
os.chdir(os.path.dirname(__file__))
try:
if (sys.platform.startswith("win")): # win, linux, darwin, freebsd
import ctypes
myappid = 'HorseArmored.yt-dl.gui.'+ver # Program Sting
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
except Exception as e:
print(e)
class MainWindow(QtWidgets.QMainWindow):
# region ===== drag & drop =====
def dragEnterEvent(self, e):
if e.mimeData().hasText():
e.accept()
else:
e.ignore()
def dropEvent(self, e): # this thing is absolutely awful, I have no clue how could it work before
drag = "" # fixes a crash
if "file:///" in e.mimeData().text():
drag = e.mimeData().text().replace("file:///", "")
self.ree_location_bar.setText(drag) # dropping anywhere on the main window drops into ree_location_bar
# endregion
def closeEvent(self, e): # when closing the app it's size and position gets saved, there alsoe has to be "e" even if it's not used or it throws an error
self.settings.Window.windowWidth = self.geometry().width()
self.settings.Window.windowHeight = self.geometry().height()
self.settings.Window.windowPosX = self.pos().x()
self.settings.Window.windowPosY = self.pos().y()
self.settings.toJson(settingsPath)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
uic.loadUi(f"gui{os.path.sep}gui.ui", self)
self.show()
self.setAcceptDrops(True)
# region ===== startup =====
pffmpeg = glob.glob(f"{spath}ffmpeg*")
pffprobe = glob.glob(f"{spath}ffprobe*")
if (not pffmpeg and not pffprobe):
self.floc = False
else: # THis code is absolutely terrible :)
directorySplit = pffmpeg[0]
directorySplit = directorySplit.split("\\")
directorySplit = directorySplit[:-1]
directorySplit = "\\".join(directorySplit)
self.floc = directorySplit
# this code is probably Windows only, and it's ugly af
pytonLoc = os.path.dirname(sys.executable)+os.path.sep
pythonw = sys.executable.replace("python.exe", "pythonw.exe")
youtubedl = glob.glob(f"{pytonLoc}Scripts{os.path.sep}yt-dlp*")
if (not youtubedl):
self.ytex = False
else:
self.ytex = [f"{pythonw}", f"{pytonLoc}Scripts{os.path.sep}yt-dlp.exe"]
if (os.path.exists(settingsPath)):
try:
self.settings = Settings.fromJson(settingsPath)
except KeyError as e:
print(e)
if QT_VERSION_STR[0] == '6':
self.messagePopup("Settings error", QMessageBox.Icon.Critical, "Your config file is not up to date,\nPress OK to load default config.", self.SaveDefaultConfig)
else:
self.messagePopup("Settings error", QMessageBox.Critical, "Your config file is not up to date,\nPress OK to load default config.", self.SaveDefaultConfig)
else:
if QT_VERSION_STR[0] == '6':
self.messagePopup("Settings error", QMessageBox.Icon.Critical, "You are missing a config file,\nPress OK to load default config.", self.SaveDefaultConfig)
else:
self.messagePopup("Settings error", QMessageBox.Critical, "You are missing a config file,\nPress OK to load default config.", self.SaveDefaultConfig)
self.setWindowTitle(f"yt-dl {ver}")
# changing size and position of the window
if self.settings.Window.windowWidth != 0 or self.settings.Window.windowHeight != 0:
self.resize(self.settings.Window.windowWidth, self.settings.Window.windowHeight)
if self.settings.Window.windowPosX != 0 or self.settings.Window.windowPosY != 0:
self.move(self.settings.Window.windowPosX, self.settings.Window.windowPosY)
self.tabWidget.setCurrentIndex(self.settings.defaultTab) # the code will not get here if settings is undefined.
self.running = False
self.status("Ready.")
self.process = ""
# endregion
# region =====aud_controls=====
self.aud_folder_button.clicked.connect(lambda: self.openFolder(self.settings.Youtubedl.audioDir))
self.aud_download_button.clicked.connect(lambda: Audio(self))
self.aud_playlist_checkbox.clicked.connect(lambda: aud_playlist_bar_toggle(self))
self.aud_cookie_checkbox.setChecked(self.settings.Youtubedl.cookie)
self.aud_output_console.setHtml("#yt-dl# Welcome to yt-dl-gui (Audio) paste a link and hit download.")
# endregion
# region =====vid_controls=====
self.vid_folder_button.clicked.connect(lambda: self.openFolder(self.settings.Youtubedl.videoDir))
self.vid_download_button.clicked.connect(lambda: Video(self))
self.vid_quality_button.clicked.connect(lambda: vid_quality(self))
self.vid_playlist_checkbox.clicked.connect(lambda: vid_playlist_bar_toggle(self))
self.vid_custom_radio.toggled.connect(lambda: vid_quality_bar_toggle(self))
self.vid_cookie_checkbox.setChecked(self.settings.Youtubedl.cookie)
self.vid_output_console.setHtml("#yt-dl# Welcome to yt-dl-gui (Video) paste a link and hit download.")
# endregion
# region =====sub_controls=====
self.sub_folder_button.clicked.connect(lambda: self.openFolder(self.settings.Youtubedl.videoDir))
self.sub_download_button.clicked.connect(lambda: Subs(self))
self.sub_lang_button.clicked.connect(lambda: sub_lang(self))
self.sub_playlist_checkbox.toggled.connect(lambda: sub_playlist_bar_toggle(self))
self.sub_cookie_checkbox.setChecked(self.settings.Youtubedl.cookie)
self.sub_output_console.setHtml("#yt-dl# Welcome to yt-dl-gui (Subtitles) paste a link and hit download.")
# endregion
# region =====ree_controls=====
for i in range(0, int(reencode_shared_settings(self, "len"))):
setting = reencode_shared_settings(self, i)
if setting:
self.ree_settings_combobox.addItem(setting[5]) # writes name of the setting
ree_settings(self) # load option on startup
self.ree_choose_button.clicked.connect(lambda: ree_choose(self))
self.ree_reencode_button.clicked.connect(lambda: Reencode(self))
self.ree_folder_button.clicked.connect(lambda: self.openFolder(self.ree_location_bar.text()))
self.ree_settings_combobox.activated.connect(lambda: ree_settings(self))
self.ree_settings_button.clicked.connect(lambda: ree_settings_save(self))
self.ree_output_console.setHtml("#yt-dl# Welcome to yt-dl-gui (Re-encode) paste a link and hit download.")
self.ree_location_bar.setAcceptDrops(True)
# endregion
# region ======upd_controls======
self.upd_update_combobox.addItem("All") # setting up items in combo list
self.upd_update_combobox.addItem("yt-dl")
self.upd_update_combobox.addItem("Dependencies")
self.upd_update_combobox.addItem("List versions")
if (sys.platform.startswith("haiku")):
self.upd_update_combobox.setCurrentIndex(1)
QtWidgets.QApplication.processEvents()
if self.settings.autoUpdate:
self.tabWidget.setCurrentIndex(4)
Update(self)
self.upd_update_button.clicked.connect(lambda: Update(self))
self.upd_auto_button.setText(f"Autoupdate=\"{self.settings.autoUpdate}\"")
self.upd_auto_button.clicked.connect(lambda: upd_auto_toggle(self))
self.upd_output_console.append("#yt-dl# Welcome to yt-dl-gui (Update) pick and option and click Update.")
# endregion
# region =====set_controls=====
self.set_loaddef_button.clicked.connect(lambda: WriteDefaultJson(self))
self.set_loadcur_button.clicked.connect(lambda: set_load(self, self.settings.Youtubedl.audioDir, self.settings.Youtubedl.videoDir, self.settings.Python.python, self.settings.Python.pip, self.settings.Youtubedl.fromPip, self.settings.autoUpdate, self.settings.Ffmpeg.audioCodec, self.settings.Ffmpeg.videoCodec, self.settings.Ffmpeg.audioBitrate, self.settings.Ffmpeg.videoQuality, self.settings.Ffmpeg.append, self.settings.defaultTab, self.settings.autoClose))
self.set_folder_button.clicked.connect(lambda: self.openFolder(spath))
self.set_launch_button.clicked.connect(lambda: set_makeScript(self))
self.set_save_button.clicked.connect(lambda: set_save(self))
self.set_Tab_combobox.addItem("Audio") # setting up items in combo list
self.set_Tab_combobox.addItem("Video")
self.set_Tab_combobox.addItem("Subs")
self.set_Tab_combobox.addItem("Re-encode")
self.set_Tab_combobox.addItem("Update")
self.set_Tab_combobox.addItem("Settings")
self.set_Tab_combobox.addItem("About")
set_load(self, self.settings.Youtubedl.audioDir, self.settings.Youtubedl.videoDir, self.settings.Python.python, self.settings.Python.pip, self.settings.Youtubedl.fromPip, self.settings.autoUpdate, self.settings.Ffmpeg.audioCodec, self.settings.Ffmpeg.videoCodec, self.settings.Ffmpeg.audioBitrate, self.settings.Ffmpeg.videoQuality, self.settings.Ffmpeg.append, self.settings.defaultTab, self.settings.autoClose)
# endregion
# region ==========🎓ABOUT🎓==========
self.about_box.setHtml(f"<p style=\"font-size: 18px; white-space: pre\">HorseArmored Inc. (C){year}<br>" +
f"Version: {ver} ({curb} branch)<br>" +
f"Last updated on: {lstupdt}<br>" +
f"My webpage: <a href=\"https://tiny.cc/koleq\">https://tiny.cc/koleq</a><br>" +
f"Project page: <a href=\"https://github.com/KoleckOLP/yt-dl\">https://github.com/KoleckOLP/yt-dl</a><br>" +
f"need help? ask here: <a href=\"https://discord.gg/W88375j\">https://discord.gg/W88375j</a><br>" +
f"yt-dlp (C)2021-{year} yt-dlp contributors<br>"
f"ffmpeg (C)2000-{year} FFmpeg team<br>" +
f"Thanks to <a href=\"https://github.com/kangalioo\">kangalioo</a> who always helps a ton!<br>" +
f"You can read the changelog: <a href=\"https://github.com/KoleckOLP/yt-dl/blob/testing/changelog.md\">here</a></pre></p>")
# endregion
# region ===== startup =====
def messagePopup(self, title, icon, text, callf=None):
msg = QMessageBox() # Pylance is being stupid, I had to disable Type checking.
msg.setWindowTitle(title)
msg.setIcon(icon)
msg.setText(text)
if callf is not None:
if QT_VERSION_STR[0] == '6':
msg.setStandardButtons(QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
else:
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msg.buttonClicked.connect(callf)
button = msg.exec()
if QT_VERSION_STR[0] == '6':
if button == QMessageBox.StandardButton.Ok:
self.SaveDefaultConfig("ok")
else:
exit()
def SaveDefaultConfig(self, i): # only exists for pyqt5 support, not needed in pyqt6
if QT_VERSION_STR[0] == '6':
text = i
else:
text: str = i.text().lower()
if "ok" in text:
WriteDefaultJson(self)
else:
exit()
enabledColor = "#383838"
disabledColor = "#242424"
# endregion
# region ===== used by most =====
def status(self, s=""): # shows status message and changes color of the status bar.
self.statusBar().showMessage(s)
if s == "Ready.":
self.statusBar().setStyleSheet("background-color: #00BB00")
elif s == "Busy.":
self.statusBar().setStyleSheet("background-color: #FF6600")
else:
self.statusBar().setStyleSheet("background-color: #A9A9A9")
@staticmethod
def openFolder(loc: str):
loc = os.path.dirname(loc)
if not os.path.exists(loc):
loc = "." + os.path.sep # if path does not exist open installation folder
if (sys.platform.startswith("win")):
os.startfile(loc) # does not work on macOS
elif (sys.platform.startswith("darwin")):
os.system(f"open {loc}")
else: # linux haiku and others
print("sorry this platform is not supported yet")
# endregion
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
app.exec()