diff --git a/package/database/database.py b/package/database/database.py index 1dd3345..85a7340 100644 --- a/package/database/database.py +++ b/package/database/database.py @@ -38,7 +38,7 @@ class Data(Base): name = Column(String, nullable=False) date_shorts = Column(String, nullable=False) date_videos = Column(String, nullable=False) - date_videos_chat = Column(String, nullable=False) + date_videos_chats = Column(String, nullable=False) class YoutubeInfo(Base): __tablename__ = "youtube_info" @@ -171,6 +171,9 @@ class Database: def update_date_shorts(self, date: str): self.__update_date("date_shorts", date) + def update_date_chats(self, date: str): + self.__update_date("date_videos_chat", date) + def get_data(self) -> list[Data]: stmt = select(Data) return self.session.scalars(stmt).all() diff --git a/package/process_uploads.py b/package/process_uploads.py index b86ce4c..6b2b123 100644 --- a/package/process_uploads.py +++ b/package/process_uploads.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import os +from pathlib import Path from datetime import datetime, timedelta import package.utils as utils @@ -13,7 +14,112 @@ from package.youtube.uploader import CategoryId as CategoryId from package.database import TwitchVideo, YoutubeInfo, Data +def process_videos(video_type: bool = True): + videos = DB.get_unuploaded_chats() if video_type else DB.get_unuploaded_shorts() + file_type = "download/clips" if video_type else "download/video" + meta_data: Data = DB.get_data()[0] + + current_time = datetime.now(TZ) + release_time = datetime.strptime(meta_data.date_shorts, "%Y-%m-%d %H:%M:%S%z") + + if current_time > release_time: + release_time = release_time.replace(hour=12, minute=0, second=0, microsecond=0) + # if noon today is already past, push to tomorrow + if release_time <= current_time: + release_time += timedelta(days=1) + + for video in videos: + base_path = Path(f"{file_type}/{video.id}/{video.id}") + original_path = base_path.with_suffix(".mp4") + + if not original_path.exists(): + print(f"❌ Error: no video at {original_path}") + continue + + # Build candidate edited files + if video_type: + primary_edited = base_path.parent / f"{base_path.name}_SS_with_chat.mp4" + fallback_edited = base_path.parent / f"{base_path.name}_over_with_chat.mp4" + else: + primary_edited = base_path.parent / f"{base_path.name}_gaussian_9_16.mp4" + fallback_edited = base_path.parent / f"{base_path.name}_black_9_16.mp4" + + file_path = primary_edited if primary_edited.exists() else fallback_edited + if not file_path.exists(): + continue + + file_csv = base_path.parent / f"{base_path.name}_{meta_data.name}.csv" + srt_path = base_path.with_suffix(".srt") + + created_at = datetime.strptime(video.created_at, "%Y-%m-%d %H:%M:%S%z").astimezone(TZ) + category_id = CategoryId.GAMING + + if video_type: + origin_clipped = "Originally Streamed on" + hashs = "#Twitch" + else: + origin_clipped = f"Clipped By: {video.creator_name}, on" + hashs = "#Shorts #Clips #Twitch" + + description = f"Game: {video.game_name}, {origin_clipped} {created_at.strftime("%Y-%m-%d %H:%M:%S %Z (%:z)")}, {hashs} Every Friday and Sunday @7:30 ET https://twitch.tv/teampgp" + privatcyStatus = 'private' + tags = ['gaming', 'TeamPGP', f'{video.game_name}', f'{video.creator_name}', 'Level1Techs', 'twitch'] + if not video_type: + tags.extend(['shorts', 'twitch_clips', 'clips']) + + if srt_path.exists(): + try: + tags.extend(get_top_nouns(str(srt_path))) + except Exception as e: + print(f"⚠️ Could not get nouns from {srt_path}: {e}") + + youtube_info = DB.get_youtube_info(video.id) or YoutubeInfo(id=video.id) + + if youtube_info.yt_id: + main_video_id = youtube_info.yt_id + else: + main_video_id = upload_video(str(original_path), video.title, category_id, description, 'unlisted', tags) + if not main_video_id: + print(f"❌ Error: main video upload failed for {original_path}") + continue + youtube_info.yt_id = main_video_id + youtube_info.yt_date = datetime.now(TZ) + + # Upload secondary + secondary_desc = f"{description} Original Full size @ https://youtu.be/{main_video_id}" + secondary_video_id = upload_video(str(file_path), video.title, category_id, secondary_desc, 'private', tags, release_time) + + if not secondary_video_id: + print(f"❌ Error: secondary upload failed for {file_path}") + DB.insert(youtube_info) # save main id at least + continue + + # Success - write CSV and DB + data_csv = [main_video_id, secondary_video_id, release_time.isoformat()] + utils.write_csv([data_csv], str(file_csv)) + + if video_type: + DB.mark_as_uploaded_chats(video.id) + youtube_info.yt_chat_SS_id = secondary_video_id + youtube_info.yt_chat_SS_date = datetime.now(TZ) + else: + DB.mark_as_uploaded_shorts(video.id) + youtube_info.yt_short_id = secondary_video_id + youtube_info.yt_short_date = datetime.now(TZ) + + DB.insert(youtube_info) + release_time += timedelta(days=1) + + # Update global release pointer once at end + if video_type: + DB.update_date_chats(release_time) + else: + DB.update_date_shorts(release_time) + def process_shorts(): + process_videos(False) + return + shorts = DB.get_unuploaded_shorts() data = DB.get_data() meta_data: Data = data[0] @@ -37,7 +143,7 @@ def process_shorts(): if not os.path.exists(file_path): continue - short.title = short.title + #short.title = short.title created_at = datetime.strptime(short.created_at, "%Y-%m-%d %H:%M:%S%z") created_at = created_at.astimezone(TZ) categoryId = CategoryId.GAMING @@ -54,7 +160,7 @@ def process_shorts(): if os.path.exists(original_path): yt_video_id = None - if (youtube_info.id == short.id and youtube_info.yt_short_id is not None) or (yt_video_id := upload_video(original_path, short.title, categoryId, description, 'unlisted', tags)): + if (youtube_info.id == short.id and youtube_info.yt_id is not None) or (yt_video_id := upload_video(original_path, short.title, categoryId, description, 'unlisted', tags)): if youtube_info.id == short.id: yt_video_id = youtube_info.yt_short_id @@ -74,6 +180,8 @@ def process_shorts(): youtube_info.yt_short_id = yt_video_id youtube_info.yt_short_date = datetime.now(TZ) + else: + print(f"Why is this short allreay update") DB.insert(youtube_info) else: @@ -82,7 +190,78 @@ def process_shorts(): DB.update_date_shorts(release_time) def process_chats(): - pass + process_videos(True) + return + chats = DB.get_unuploaded_chats() + data = DB.get_data() + meta_data: Data = data[0] + + release_time = meta_data.date_shorts + + current_time = datetime.now(TZ) + release_time = datetime.strptime(release_time, "%Y-%m-%d %H:%M:%S%z") + + if current_time > release_time: + release_time = current_time + release_time = release_time.replace(hour=12, minute=0, second=0, microsecond=0) + + for chat in chats: + original_path = f"download/videos/{chat.id}/{chat.id}.mp4" + file_path = f"download/videos/{chat.id}/{chat.id}_SS_with_chat.mp4" + file_csv = f"download/videos/{chat.id}/{chat.id}_{meta_data.name}.csv" + + if not os.path.exists(file_path): + file_path = f"download/videos/{chat.id}/{chat.id}_over_with_chat.mp4" + if not os.path.exists(file_path): + continue + + #chat.title = chat.title + created_at = datetime.strptime(chat.created_at, "%Y-%m-%d %H:%M:%S%z") + created_at = created_at.astimezone(TZ) + categoryId = CategoryId.GAMING + description = f"Game: {chat.game_name}, Originally Streamed on {created_at.strftime("%Y-%m-%d %H:%M:%S %Z (%:z)")}, #Twitch Every Friday and Sunday @7:30 ET https://twitch.tv/teampgp" + privatcyStatus = 'private' + tags = ['gaming', 'TeamPGP', f'{chat.game_name}', f'{chat.creator_name}', 'Level1Techs', 'twitch'] + + tags.extend(get_top_nouns(f"download/video/{chat.id}/{chat.id}.srt")) + + youtube_info = DB.get_youtube_info(chat.id) + + if not youtube_info: + youtube_info = YoutubeInfo() + + if os.path.exists(original_path): + yt_video_id = None + if (youtube_info.id == chat.id and youtube_info.yt_id is not None) or (yt_video_id := upload_video(original_path, chat.title, categoryId, description, 'unlisted', tags)): + if youtube_info.id == chat.id: + yt_video_id = youtube_info.yt_short_id + + data_csv = [yt_video_id, current_time] + release_time += timedelta(days=1) + + # Assign / Update values on the object + youtube_info.id = chat.id + youtube_info.yt_id = yt_video_id + youtube_info.yt_date = datetime.now(TZ) + + if yt_video_id := upload_video(file_path, chat.title, categoryId, f"{description} Original no chat @ https://youtu.be/{yt_video_id}", privatcyStatus, tags, release_time): + data_csv.extend([yt_video_id, release_time]) + DB.mark_as_uploaded_yt(chat.id) + DB.mark_as_uploaded_shorts(chat.id) + utils.write_csv([data_csv], file_csv) + + youtube_info.yt_short_id = yt_video_id + youtube_info.yt_short_date = datetime.now(TZ) + else: + print(f"Why is this short allreay update") + + DB.insert(youtube_info) + else: + break + + DB.update_date_shorts(release_time) + + def process_uploads(): process_shorts()