diff options
author | nathansmithsmith <nathansmith7@mailfence.com> | 2023-11-09 03:51:34 +0000 |
---|---|---|
committer | nathansmithsmith <nathansmith7@mailfence.com> | 2023-11-09 03:51:34 +0000 |
commit | b0edf6f418fbc860f3dd864fb5ee71ee0a108c1d (patch) | |
tree | 71854481f84b285c1d999aa760f802cb6b5e29db | |
download | youload-b0edf6f418fbc860f3dd864fb5ee71ee0a108c1d.tar.gz youload-b0edf6f418fbc860f3dd864fb5ee71ee0a108c1d.tar.bz2 youload-b0edf6f418fbc860f3dd864fb5ee71ee0a108c1d.zip |
first commit
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | src/main.py | 6 | ||||
-rw-r--r-- | src/youload_app.py | 68 | ||||
-rw-r--r-- | src/youload_playlist.py | 31 |
5 files changed, 110 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3bbe7b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +*.pyc +*.pyo diff --git a/README.md b/README.md new file mode 100644 index 0000000..263acbe --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Youload +A simple youtube playlist downloader diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..ab747b0 --- /dev/null +++ b/src/main.py @@ -0,0 +1,6 @@ +from youload_app import YouloadApp + +if __name__ == "__main__": + app = YouloadApp() + run = app.run() + print(run) diff --git a/src/youload_app.py b/src/youload_app.py new file mode 100644 index 0000000..9079923 --- /dev/null +++ b/src/youload_app.py @@ -0,0 +1,68 @@ +#! /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 + +import threading + +from youload_playlist import YouLoadPlayList + +class YouloadApp(App): + def build(self): + layout = BoxLayout(padding=10, orientation='vertical') + + # Data members + self.url = "https://youtube.com/playlist?list=PLuZUmvZz4WI78uqT5S71yBHNBMJ97HzhY&si=SI2qN9MgxmmK2rbf" + self.is_downloading = False + self.download_thread = threading.Thread(target=self.download_playlist_thread) + self.stop_download = False + + # Url input. + url_input = TextInput(text=self.url, multiline=False) + url_input.bind(text=self.uid_url_input) + + # Submit button. + submit = Button(text="Download") + submit.bind(on_press=self.submit_cb) + + # Info display. + self.info_display = Label(text="") + + # Everything else (: + layout.add_widget(url_input) + layout.add_widget(self.info_display) + layout.add_widget(submit) + + 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): + playlist = YouLoadPlayList(self.url) + playlist.prepare_for_download() + + self.info_display.text = f"Downloading {self.url}\n" + self.is_downloading = True + + # Download each video + for i in range(playlist.video_count): + self.info_display.text += playlist.download_video(i) + "\n" + + # Stop this mother fucker + if self.stop_download: + return + + self.is_downloading = False + + def submit_cb(self, instance): + self.stop_download = False + self.download_thread.start() + + def on_stop(self): + self.stop_download = True + diff --git a/src/youload_playlist.py b/src/youload_playlist.py new file mode 100644 index 0000000..4121d85 --- /dev/null +++ b/src/youload_playlist.py @@ -0,0 +1,31 @@ +from pytube import Playlist +import os + +def make_alpha_numeric(string: str) -> str: + return "".join(char for char in string if char.isalnum()) + +class YouLoadPlayList: + """A class for download and handling youtube playlists""" + + def __init__(self, link: str): + self.yt_playlist = Playlist(link) + self.video_count = len(self.yt_playlist.videos) + self.folder_name = make_alpha_numeric(self.yt_playlist.title) + + def generate_video_info(self, video_num: int) -> str: + """Returns information on video in playlist at 'video_num'""" + + video = self.yt_playlist.videos[video_num] + video_size = video.streams.get_highest_resolution().filesize // 1048576 + return f"Title: {video.title}, Size: {video_size} MB" + + def prepare_for_download(self) -> None: + os.mkdir(self.folder_name) + + def download_video(self, video_num: int) -> str: + video = self.yt_playlist.videos[video_num] + video_size = video.streams.get_highest_resolution().filesize + video.streams.get_highest_resolution().download(output_path=self.folder_name) + + return f"Title: {video.title}, Size: {video_size // (1024 ** 2)} MB" + |