#!/usr/bin/env python3 import os from pathlib import Path from datetime import datetime, timedelta import package.utils as utils from package.config import TZ as TZ from package.config import DB as DB from package.hash_tags import get_top_nouns as get_top_nouns from package.youtube.uploader import upload_video as upload_video from package.youtube.uploader import CategoryId as CategoryId from package.database import TwitchVideo, YoutubeInfo, Data def process_videos(video_type: bool = True, limit: int = 22): count = 0 # count how many videos we have upload and stop at var: limit videos = DB.get_unuploaded_chats() if video_type else DB.get_unuploaded_shorts() file_type = "download/video" if video_type else "download/clips" 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: #We reached limit stop uploading videos if count >= limit: break 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']) tags.extend([video.id]) 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, f"{description} \n\n({video.id})", 'unlisted', tags) count += 1 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} \n\n({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 count += 1 # 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] 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 short in shorts: original_path = f"download/clips/{short.id}/{short.id}.mp4" file_path = f"download/clips/{short.id}/{short.id}_gaussian_9_16.mp4" file_csv = f"download/clips/{short.id}/{short.id}_{meta_data.name}.csv" if not os.path.exists(file_path): file_path = f"download/clips/{short.id}/{short.id}_black_9_16.mp4" if not os.path.exists(file_path): continue #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 description = f"Game: {short.game_name}, Clipped By: {short.creator_name}, on {created_at.strftime("%Y-%m-%d %H:%M:%S %Z (%:z)")}, #Shorts #Clips #Twitch Every Friday and Sunday @7:30 ET https://twitch.tv/teampgp" privatcyStatus = 'private' tags = ['shorts', 'gaming', 'TeamPGP', f'{short.game_name}', f'{short.creator_name}', 'twitch_clips', 'clips', 'Level1Techs', 'twitch'] tags.extend(get_top_nouns(f"download/clips/{short.id}/{short.id}.srt")) youtube_info = DB.get_youtube_info(short.id) if not youtube_info: youtube_info = YoutubeInfo() if os.path.exists(original_path): yt_video_id = None 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 data_csv = [yt_video_id, current_time] release_time += timedelta(days=1) # Assign / Update values on the object youtube_info.id = short.id youtube_info.yt_id = yt_video_id youtube_info.yt_date = datetime.now(TZ) if yt_video_id := upload_video(file_path, short.title, categoryId, f"{description} Original Full size @ https://youtu.be/{yt_video_id}", privatcyStatus, tags, release_time): data_csv.extend([yt_video_id, release_time]) DB.mark_as_uploaded_yt(short.id) DB.mark_as_uploaded_shorts(short.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_chats(): 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() #process_chats() if __name__ == "__main__": pass