#! /usr/bin/python3 from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.floatlayout import FloatLayout from kivy.uix.textinput import TextInput from kivy.uix.popup import Popup from kivy.uix.label import Label import threading from pathlib import Path import os from model.youload_playlist import YouLoadPlayList from view.file_chooser import YouloadFileChooser from view.download_type_chooser import YouloadDownloadTypeChooser class YouloadApp(App): def build(self): layout = BoxLayout(orientation='vertical') # Data members self.url = "https://youtube.com/playlist?list=PLXbRgJ9vx_KuA5CljV3BpiV58qx6znmRk&si=JFaVyspkeoMWUDNL" self.is_downloading = False self.should_stop_download = False # File chooser. self.file_chooser = YouloadFileChooser() self.file_chooser.set_app(self) # Download type chooser. self.download_type_chooser = YouloadDownloadTypeChooser() self.download_type_chooser.set_app(self) # Url input. url_input = TextInput(text=self.url, multiline=False, size_hint=(0.8, 1.0)) url_input.bind(text=self.uid_url_input) # Submit button. self.submit = Button(text="Download", size_hint=(0.2, 1.0)) self.submit.bind(on_press=self.submit_cb) # Url and submit layout. url_and_submit = BoxLayout(size_hint=(1.0, 0.1)) url_and_submit.add_widget(url_input) url_and_submit.add_widget(self.submit) # Download status. self.download_status = Label(text="Nothing downloading", size_hint=(0.3, 1.0)) # Download type chooser button. self.download_type_button = Button(text=self.download_type_chooser.current_type, size_hint=(0.1, 1.0)) self.download_type_button.bind(on_press=self.download_type_chooser.open) # Folder display. self.folder_display = Label(text=os.getcwd(), size_hint=(0.4, 1.0)) # choose folder button. self.choose_folder_button = Button(text="Folder", size_hint=(0.2, 1.0)) self.choose_folder_button.bind(on_press=self.choose_folder_cb) # Info line. info_line = BoxLayout(size_hint=(1.0, 0.1)) info_line.add_widget(self.download_status) info_line.add_widget(self.download_type_button) info_line.add_widget(self.folder_display) info_line.add_widget(self.choose_folder_button) # Info display. self.downloads_display = Label(text="", size_hint=(1.0, 0.8)) # Everything else (: layout.add_widget(url_and_submit) layout.add_widget(info_line) layout.add_widget(self.downloads_display) return layout def uid_url_input(self, instance, value): self.url = value # Download the videos in a different thread so the ui still works. def download_playlist_thread(self): try: self.download_status.text = "Fetching playlist" self.submit.text = "Stop" self.is_downloading = True # Get playlist. playlist = YouLoadPlayList(self.url) # Set directory and other stuff. playlist.set_download_directory(self.folder_display.text) playlist.download_type = self.download_type_chooser.current_type playlist.prepare_for_download() self.downloads_display.text = f"Downloading to {playlist.folder_name}\n" # Download each video for i in range(playlist.video_count): # Stop this mother fucker if self.should_stop_download: break self.download_status.text = f"Downloading {i+1}/{playlist.video_count}" self.downloads_display.text += playlist.download_video(i) + "\n" # Complete download. self.download_status.text = "Download complete" except FileExistsError: self.download_status.text = "Folder already exists" except KeyError: self.download_status.text = "Error getting playlist" except AttributeError: self.download_status.text = "Download type not supported" self.submit.text = "Download" self.is_downloading = False def stop_download(self): self.download_status.text = "Stopping download" self.should_stop_download = True def submit_cb(self, instance): # Is already downloading something. if self.is_downloading: self.stop_download() return # Start download thread. download_thread = threading.Thread(target=self.download_playlist_thread) self.should_stop_download = False download_thread.start() def choose_folder_cb(self, instance): self.file_chooser.open() def on_stop(self): self.stop_download()