#! /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 import traceback 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 = "" 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. self.url_input = TextInput(text=self.url, multiline=False, size_hint=(0.6, 1.0)) self.url_input.bind(text=self.uid_url_input) # Clear button. clear_button = Button(text="Clear", size_hint=(0.2, 1.0)) clear_button.bind(on_press=self.clear_cb) # 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(self.url_input) url_and_submit.add_widget(clear_button) 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.INTERNET, Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE]) def uid_url_input(self, instance, value): self.url = value def clear_cb(self, instance): self.url_input.text = "" 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 as e: self.download_status.text = "Folder already exists" self.downloads_display.text = repr(e) + "\n" + traceback.format_exc() print(self.downloads_display.text) except KeyError as e: self.download_status.text = "Error getting playlist" self.downloads_display.text = repr(e) + "\n" + traceback.format_exc() print(self.downloads_display.text) except AttributeError as e: self.download_status.text = "Download type not supported" self.downloads_display.text = repr(e) + "\n" + traceback.format_exc() print(self.downloads_display.text) except Exception as e: self.downloads_display.text = repr(e) + "\n" + traceback.format_exc() print(self.downloads_display.text) 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()