YouTubeDownloader v1.1.2
YouTube content downloader
Loading...
Searching...
No Matches
main_window.py
Go to the documentation of this file.
1"""!
2********************************************************************************
3@file main_window.py
4@brief View controller for the main window
5********************************************************************************
6"""
7
8import os
9import logging
10from typing import Any
11import subprocess
12from tkinter import Menu, Event
13from customtkinter import CTk, CTkFont
14from customtkinter.windows.widgets.ctk_entry import CTkEntry
15from pytubefix import YouTube
16import clipboard
17
18from Source.Util.app_data import ICON_APP
19from Source.version import __title__
20from Source.Model.model import Model
21from Source.Worker.downloader import DownloadThread
22
23from Source.Views.mainwindow_tk_ui import Ui_MainWindow # pylint: disable=wrong-import-position
24
25from Source import version
26
27log = logging.getLogger(__title__)
28
29S_DOWNLOAD_FOLDER = "Download"
30FONT_NAME = "Comic Sans MS"
31FONT_SIZE = 14
32
33
34def copy_selected_text_to_clipboard(url_input: CTkEntry) -> None:
35 """!
36 @brief Copy selected text to clipboard
37 @param url_input : url
38 """
39 s_text = url_input.selection_get()
40 clipboard.copy(s_text)
41
42
43def delete_selected_text(url_input: CTkEntry) -> None:
44 """!
45 @brief Delete selected text
46 @param url_input : url
47 """
48 try:
49 s_select_text = url_input.selection_get()
50 except BaseException: # pylint: disable=bare-except
51 pass
52 else:
53 s_entry_text = url_input.get()
54 i_selected_text_length = len(s_select_text)
55 i_curser_pos = url_input.index('insert')
56 i_curser_pos_end = i_curser_pos + i_selected_text_length
57 s_text_to_check = s_entry_text[i_curser_pos: i_curser_pos_end]
58 if s_text_to_check == s_select_text:
59 url_input.delete(i_curser_pos, i_curser_pos_end)
60 else:
61 url_input.delete(i_curser_pos - i_selected_text_length, i_curser_pos)
62
63
65 """!
66 @brief Class for YouTube download GUI
67 """
68
69 def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=keyword-arg-before-vararg
70 log.debug("Initializing Main Window")
71 super().__init__(*args, **kwargs)
72 self.setupUi(self)
73 self.title(__title__)
74 self.wm_iconbitmap(ICON_APP) # set icon
75 self.geometry("350x360") # set window
76 self.resizable(0, 0) # Don't allow resizing
77 self.columnconfigure(0, weight=1) # set all content in center.
78 # init widgets
79 self.init_widgets()
80 self.model = Model(self)
81 self.model.c_monitor.update_darkmode_status(self.model.c_monitor.e_style)
82
83 def init_widgets(self) -> None:
84 """!
85 @brief Initialize widgets
86 """
87 # right click content menu
88 d_context = {
89 "Ausschneiden": self.cut,
90 "Kopieren": self.copy,
91 "Einfügen": self.paste
92 }
93 self.menu = Menu(self, tearoff=0)
94 for text, callback in d_context.items():
95 self.menu.add_command(label=text, command=callback)
96 self.url_inputurl_input.bind("<Button-3>", self.do_popupdo_popup) # event for right mouse click (button 3)
97 self.url_inputurl_input.configure(placeholder_text="Gebe die YouTube URL ein:")
98 # Entry Box
99 s_clipboard_text = clipboard.paste() # get content of clip board
100 s_compare_string = "https://"
101 b_valid_url = False
102 if s_clipboard_text[0:len(s_compare_string)] == s_compare_string:
103 try:
104 YouTube(s_clipboard_text)
105 b_valid_url = True
106 except BaseException: # pylint: disable=bare-except
107 b_valid_url = False
108 if b_valid_url:
109 s_default_text = s_clipboard_text
110 s_default_status = "URL aus Zwischenablage wurde eingefügt!"
111 else:
112 s_default_text = "" # if no YouTube link or invalid set no text as default
113 s_default_status = "URL eingeben und Download starten!"
114 self.url_inputurl_input.insert(0, s_default_text) # set content of clipboard as default
115 self.insert_btn.configure(text="Einfügen", fg_color="green", text_color="white", command=self.input_link)
116 self.direct_btn.configure(text="Direkt Download", fg_color="darkorange", text_color="white", command=self.direct_clicked)
117 # Error Message
118 self.status_lbl.configure(text=s_default_status, text_color="grey", font=CTkFont(family=FONT_NAME, size=FONT_SIZE))
119 # Title Message
120 self.title_lbl.configure(text="Aktueller Song", text_color="orange", font=CTkFont(family=FONT_NAME, size=FONT_SIZE))
121 # format label
122 self.format_lbl.configure(text="Wähle ein Format:", font=CTkFont(size=FONT_SIZE))
123 # download button
124 self.download_btn.configure(text="Download", fg_color="red", text_color="white", command=self.start_download)
125 # folder button
126 self.open_folder_btn.configure(text="Öffne Speicherort", fg_color="grey", text_color="white")
127 # developer Label
128 self.copyright_lbl.configure(text=version.__copyright__, font=CTkFont(family=FONT_NAME, size=FONT_SIZE))
129
130 def copy(self) -> None:
131 """!
132 @brief Copy selected text to clipboard
133 """
135
136 def cut(self) -> None:
137 """!
138 @brief Copy selected text to clipboard and cut text out
139 """
142
143 def paste(self) -> None:
144 """!
145 @brief Paste text from clipboard to position
146 """
148 self.url_inputurl_input.insert(self.url_inputurl_input.index('insert'), clipboard.paste()) # paste at cursor position
149
150 def do_popup(self, event: Event) -> None:
151 """!
152 @brief Pop up content menu
153 @param event : arrived event
154 """
155 try:
156 self.url_inputurl_input.selection_get()
157 self.menu.entryconfig("Kopieren", state="normal")
158 self.menu.entryconfig("Ausschneiden", state="normal")
159 except BaseException: # pylint: disable=bare-except
160 self.menu.entryconfig("Kopieren", state="disabled")
161 self.menu.entryconfig("Ausschneiden", state="disabled")
162 try:
163 self.menu.tk_popup(event.x_root, event.y_root)
164 finally:
165 self.menu.grab_release()
166
167 def input_link(self) -> None:
168 """!
169 @brief Input text from clipboard to entry box
170 """
171 self.url_inputurl_input.delete(0, "end")
172 self.url_inputurl_input.insert(0, clipboard.paste()) # paste content of clipboard
173 self.status_lbl.configure(text="Text aus Zwischenablage wurde eingefügt!", text_color="grey")
174
175 def direct_clicked(self) -> None:
176 """!
177 @brief direct download clicked
178 """
179 self.input_link()
180 self.start_download()
181
182 def start_download(self) -> None:
183 """!
184 @brief Create and start thread for download
185 """
186 self.download_btn.configure(state="disabled")
187 self.direct_btn.configure(state="disabled")
188 c_download = DownloadThread(self)
189 c_download.start()
190
191 def open_download_folder(self) -> None:
192 """!
193 @brief Open download folder and create if not exist
194 """
195 if not os.path.isdir(S_DOWNLOAD_FOLDER):
196 os.makedirs(S_DOWNLOAD_FOLDER)
197 with subprocess.Popen('explorer ' + S_DOWNLOAD_FOLDER):
198 pass
Class for YouTube download GUI.
None input_link(self)
Input text from clipboard to entry box.
None __init__(self, *Any args, **Any kwargs)
None do_popup(self, Event event)
Pop up content menu.
None start_download(self)
Create and start thread for download.
None paste(self)
Paste text from clipboard to position.
None cut(self)
Copy selected text to clipboard and cut text out.
None copy(self)
Copy selected text to clipboard.
None direct_clicked(self)
direct download clicked
None init_widgets(self)
Initialize widgets.
None open_download_folder(self)
Open download folder and create if not exist.
Holds the data of the application.
Definition model.py:20
Thread class for download.
Definition downloader.py:35
None delete_selected_text(CTkEntry url_input)
Delete selected text.
None copy_selected_text_to_clipboard(CTkEntry url_input)
Copy selected text to clipboard.