#! /usr/bin/python3 from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.textinput import TextInput from kivy.uix.label import Label from kivy import platform import threading from model.youload_playlist import YouLoadPlayList from view.file_chooser import YouloadFileChooser from view.download_type_chooser import YouloadDownloadTypeChooser import util 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.75, 1.0)) # Download type chooser button. self.download_type_button = Button(text=self.download_type_chooser.current_type, size_hint=(0.25, 1.0)) self.download_type_button.bind(on_press=self.download_type_chooser.open) # Folder display. self.folder_display = Label(text=util.get_default_download_dir(), size_hint=(0.5, 1.0)) # Add numbers. self.do_add_numbers: bool = False self.add_numbers_button = Button(text="No numbers", size_hint=(0.25, 1.0)) self.add_numbers_button.bind(on_press=self.toggle_add_numbers_cb) # choose folder button. self.choose_folder_button = Button(text="Folder", size_hint=(0.25, 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_line2 = BoxLayout(size_hint=(1.0, 0.1)) info_line2.add_widget(self.folder_display) info_line2.add_widget(self.add_numbers_button) info_line2.add_widget(self.choose_folder_button) # Info display. self.downloads_display = Label(text="", size_hint=(1.0, 0.7)) # Everything else (: layout.add_widget(url_and_submit) layout.add_widget(info_line) layout.add_widget(info_line2) layout.add_widget(self.downloads_display) return layout def on_start(self, **kwargs): if platform == "android": from android.permissions import request_permissions, Permission request_permissions([Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE]) def uid_url_input(self, instance, value): self.url = value def toggle_add_numbers_cb(self, instance): self.do_add_numbers = not self.do_add_numbers self.add_numbers_button.text = "Numbers" if self.do_add_numbers else "No numbers" # 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, self.do_add_numbers) + "\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" except Exception as e: self.downloads_display.text = repr(e) 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()