From 8ddd4a73e90b8b0c9035c3ae1e9d19a721e60df9 Mon Sep 17 00:00:00 2001 From: Thisal Dilmith <93121062+Thisal-D@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:27:10 +0530 Subject: [PATCH] v4.1.0 v4.1.0 --- VERSION | 2 +- app.py | 8 +- data/info.json | 4 +- main.py | 3 +- services/history_manager.py | 73 ++++++++++-- widgets/history_widgets/history_panel.py | 126 +++++++++++++-------- widgets/play_list/downloading_play_list.py | 2 +- 7 files changed, 149 insertions(+), 69 deletions(-) diff --git a/VERSION b/VERSION index dc9d742..fcb4da1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -VERSION = '4.0.1' +VERSION = '4.1.0' diff --git a/app.py b/app.py index 1e2fef2..75a1b91 100644 --- a/app.py +++ b/app.py @@ -1720,15 +1720,15 @@ def run_accessibility_check(self): self.update_check_thread = threading.Thread(target=self.check_accessibility, daemon=True) self.update_check_thread.start() - def manage_history_videos(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date): + def manage_history_videos(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date, is_playlist_duplicated): """ Manage the history videos. """ - self.history_content_frame.add_hisory_video(no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date) + self.history_content_frame.add_hisory_video(no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date, is_playlist_duplicated) - def manage_history_playlists(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date): + def manage_history_playlists(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date, is_playlist_duplicated): """ Manage the history playlists. """ - self.history_content_frame.add_hisory_playlist(no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date) + self.history_content_frame.add_hisory_playlist(no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date, is_playlist_duplicated) \ No newline at end of file diff --git a/data/info.json b/data/info.json index 1fe7dd2..8ae84cf 100644 --- a/data/info.json +++ b/data/info.json @@ -2,5 +2,5 @@ "contributors": {}, "name": "PyTube Downloader", "site": "https://github.com/Thisal-D/PyTube-Downloader", - "version": "4.0.1" -} + "version": "4.1.0" +} \ No newline at end of file diff --git a/main.py b/main.py index 4796507..c4b49d8 100644 --- a/main.py +++ b/main.py @@ -81,5 +81,4 @@ # just run the app app.run() -# Codes under here will only execute when the app is closed - \ No newline at end of file +# Codes under here will only execute when the app is closed \ No newline at end of file diff --git a/services/history_manager.py b/services/history_manager.py index 3a0f3a4..9a17a40 100644 --- a/services/history_manager.py +++ b/services/history_manager.py @@ -5,7 +5,7 @@ FileUtility ) import os -from typing import Callable +from typing import Callable, Literal # from widgets.video import DownloadedVideo # from widgets.play_list import DownloadedPlayList @@ -23,6 +23,8 @@ class HistoryManager: max_history = 40 video_history_change_callback = None playlist_history_change_callback = None + video_no = 0 + playlist_no = 0 @staticmethod def initialize( @@ -49,6 +51,7 @@ def initialize( HistoryManager.cursor = HistoryManager.connection.cursor() HistoryManager.initialize_history() + HistoryManager.configure_video_and_playlist_no() @staticmethod def initialize_history(): @@ -68,7 +71,43 @@ def initialize_history(): HistoryManager.videos_history_data = HistoryManager.videos_history_data[::-1] HistoryManager.playlists_history_data = HistoryManager.playlists_history_data[::-1] - + + @staticmethod + def configure_video_and_playlist_no(): + sql_videos = "SELECT no FROM videos ORDER BY rowid DESC LIMIT 1" + sql_playlists = "SELECT no FROM playlists ORDER BY rowid DESC LIMIT 1" + + HistoryManager.cursor.execute(sql_videos) + data = HistoryManager.cursor.fetchone() + if data is not None: + HistoryManager.video_no = data[0] + else: + HistoryManager.video_no = 0 + + HistoryManager.cursor.execute(sql_playlists) + data = HistoryManager.cursor.fetchone() + if data is not None: + HistoryManager.playlist_no = data[0] + else: + HistoryManager.playlist_no = 0 + + + @staticmethod + def remove_from_history(url: str, table: Literal["videos", "playlists"]) -> None: + sql = f"DELETE FROM {table} WHERE url = ?" + HistoryManager.cursor.execute(sql, (url,)) + HistoryManager.connection.commit() + + @staticmethod + def is_already_exists(video_url: str, table: Literal["videos", "playlists"]) -> bool: + sql = f"SELECT COUNT(*) FROM {table} WHERE url = ?" + HistoryManager.cursor.execute(sql, (video_url,)) + data = HistoryManager.cursor.fetchone() + if data is not None and data[0] > 0: + return True + else: + return False + @staticmethod def save_video_to_history(video):#: DownloadedVideo): channel = video.channel @@ -79,18 +118,24 @@ def save_video_to_history(video):#: DownloadedVideo): video_length = video.length download_date = DateTimeUtility.get_current_date_time() + if HistoryManager.is_already_exists(url, "videos"): + HistoryManager.remove_from_history(url, "videos") + is_duplicated = True + else: + is_duplicated = False + """ HistoryManager.videos_history_data.insert(0, (None, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date)) if len(HistoryManager.videos_history_data) > HistoryManager.max_history: HistoryManager.videos_history_data = HistoryManager.videos_history_data[0:HistoryManager.max_history] """ - - sql = "Insert into videos (channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date) values (?, ?, ?, ?, ?, ?, ?)" - HistoryManager.cursor.execute(sql, (channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date)) + HistoryManager.video_no += 1 + sql = "Insert into videos (no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date) values (?, ?, ?, ?, ?, ?, ?, ?)" + HistoryManager.cursor.execute(sql, (HistoryManager.video_no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date)) HistoryManager.connection.commit() - HistoryManager.video_history_change_callback(0, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date) - + HistoryManager.video_history_change_callback(HistoryManager.video_no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date, is_duplicated) + @staticmethod def save_playlist_to_history(playlist):#: DownloadedPlayList): channel = playlist.channel @@ -101,17 +146,23 @@ def save_playlist_to_history(playlist):#: DownloadedPlayList): video_count = playlist.playlist_original_video_count download_date = DateTimeUtility.get_current_date_time() + if HistoryManager.is_already_exists(url, "playlists"): + HistoryManager.remove_from_history(url, "playlists") + is_duplicated = True + else: + is_duplicated = False + """ HistoryManager.playlists_history_data.insert(0, (None, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date)) if len(HistoryManager.playlists_history_data) > HistoryManager.max_history: HistoryManager.playlists_history_data = HistoryManager.playlists_history_data[0:HistoryManager.max_history] """ - - sql = "Insert into playlists (channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date) values (?, ?, ?, ?, ?, ?, ?)" - HistoryManager.cursor.execute(sql, (channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date)) + HistoryManager.playlist_no += 1 + sql = "Insert into playlists (no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date) values (?, ?, ?, ?, ?, ?, ?, ?)" + HistoryManager.cursor.execute(sql, (HistoryManager.playlist_no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date)) HistoryManager.connection.commit() - HistoryManager.playlist_history_change_callback(0, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date) + HistoryManager.playlist_history_change_callback(HistoryManager.playlist_no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date, is_duplicated) @staticmethod def maintain_history(table: str) -> None: diff --git a/widgets/history_widgets/history_panel.py b/widgets/history_widgets/history_panel.py index 9328541..36b34b9 100644 --- a/widgets/history_widgets/history_panel.py +++ b/widgets/history_widgets/history_panel.py @@ -5,6 +5,7 @@ LanguageManager, HistoryManager ) +import threading from typing import Literal import tkinter as tk from .history_video import HistoryVideo @@ -74,39 +75,50 @@ def __init__( self.set_widgets_accent_color() self.set_widgets_texts() self.bind_widgets_events() - - self.configure_video_count_per_row() - self.configure_playlist_count_per_row() - - self.configure_old_history_videos() - self.configure_old_history_playlists() + + threading.Thread(target=self.configure_old_history_videos, daemon=True).start() + threading.Thread(target=self.configure_old_history_playlists, daemon=True).start() ThemeManager.register_widget(self) LanguageManager.register_widget(self) self.place_nav_frame(self.videos_scrollable_frame, "videos") - - def add_hisory_video(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date) -> None: - if len(self.histoy_videos_widgets) == HistoryManager.max_history: - self.histoy_videos_widgets.pop().destroy() - self.histoy_videos_widgets.insert( - 0, - ( - HistoryVideo( - master=self.videos_scrollable_frame, - no=no, - width=self.history_video_width, - channel=channel, - title=title, - url=url, - thumbnail_path_normal=thumbnail_normal_path, - thumbnail_path_hover=thumbnail_hover_path, - download_date=download_date, - length=video_length, - add_to_download_callback=self.video_add_to_download_callback + + def bring_video_to_top(self, url): + for index, history_video in enumerate(self.histoy_videos_widgets): + if history_video.url == url: + if index != 0: + history_video_temp = history_video + self.histoy_videos_widgets.remove(history_video) + self.histoy_videos_widgets.insert(0, history_video_temp) + self.place_history_videos() + break + + def add_hisory_video(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_length, download_date, is_duplicated) -> None: + if is_duplicated: + self.bring_video_to_top(url) + else: + if len(self.histoy_videos_widgets) == HistoryManager.max_history: + self.histoy_videos_widgets.pop().destroy() + self.histoy_videos_widgets.insert( + 0, + ( + HistoryVideo( + master=self.videos_scrollable_frame, + no=no, + width=self.history_video_width, + channel=channel, + title=title, + url=url, + thumbnail_path_normal=thumbnail_normal_path, + thumbnail_path_hover=thumbnail_hover_path, + download_date=download_date, + length=video_length, + add_to_download_callback=self.video_add_to_download_callback + ) ) ) - ) + self.place_history_videos() def place_history_videos(self) -> None: @@ -146,11 +158,14 @@ def configure_old_history_videos(self) -> None: add_to_download_callback=self.video_add_to_download_callback ) ) + self.configure_video_count_per_row() self.place_history_videos() def configure_history_videos(self) -> None: + previous_video_count_per_row = self.videos_per_row self.configure_video_count_per_row() - self.place_history_videos() + if previous_video_count_per_row != self.videos_per_row: + self.place_history_videos() def configure_video_count_per_row(self) -> None: total_required_width_for_video = self.history_video_width + self.history_video_grid_pad_x @@ -158,29 +173,41 @@ def configure_video_count_per_row(self) -> None: # ------------------------------------------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------------------------------------------ + def bring_playlist_to_top(self, url): + for index, history_playlist in enumerate(self.histoy_playlists_widgets): + if history_playlist.url == url: + if index != 0: + history_playlist_temp = history_playlist + self.histoy_playlists_widgets.remove(history_playlist) + self.histoy_playlists_widgets.insert(0, history_playlist_temp) + self.place_history_playlists() + break - def add_hisory_playlist(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date) -> None: - if len(self.histoy_playlists_widgets) == HistoryManager.max_history: - self.histoy_playlists_widgets.pop().destroy() - self.histoy_playlists_widgets.insert( - 0, - ( - HistoryPlaylist( - master=self.playlists_scrollable_frame, - no=no, - width=self.history_video_width, - channel=channel, - title=title, - url=url, - thumbnail_path_normal=thumbnail_normal_path, - thumbnail_path_hover=thumbnail_hover_path, - download_date=download_date, - add_to_download_callback=self.playlist_add_to_download_callback, - videos_count=video_count + def add_hisory_playlist(self, no, channel, title, url, thumbnail_normal_path, thumbnail_hover_path, video_count, download_date, is_duplicated) -> None: + if is_duplicated: + self.bring_playlist_to_top(url) + else: + if len(self.histoy_playlists_widgets) == HistoryManager.max_history: + self.histoy_playlists_widgets.pop().destroy() + self.histoy_playlists_widgets.insert( + 0, + ( + HistoryPlaylist( + master=self.playlists_scrollable_frame, + no=no, + width=self.history_video_width, + channel=channel, + title=title, + url=url, + thumbnail_path_normal=thumbnail_normal_path, + thumbnail_path_hover=thumbnail_hover_path, + download_date=download_date, + add_to_download_callback=self.playlist_add_to_download_callback, + videos_count=video_count + ) ) ) - ) - self.place_history_playlists() + self.place_history_playlists() def place_history_playlists(self) -> None: @@ -220,11 +247,14 @@ def configure_old_history_playlists(self) -> None: add_to_download_callback=self.playlist_add_to_download_callback ) ) + self.configure_playlist_count_per_row() self.place_history_playlists() def configure_history_playlists(self) -> None: + previous_playlist_count_per_row = self.playlists_per_row self.configure_playlist_count_per_row() - self.place_history_playlists() + if previous_playlist_count_per_row != self.playlists_per_row: + self.place_history_playlists() def configure_playlist_count_per_row(self) -> None: total_required_width_for_playlist = self.history_playlist_width + self.history_playlist_grid_pad_x diff --git a/widgets/play_list/downloading_play_list.py b/widgets/play_list/downloading_play_list.py index 7e5657e..0447f91 100644 --- a/widgets/play_list/downloading_play_list.py +++ b/widgets/play_list/downloading_play_list.py @@ -449,4 +449,4 @@ def kill(self): video.kill() super().kill() - + \ No newline at end of file