From d4db0b04a4c42db25cb2d7831c71f4dd504c60ef Mon Sep 17 00:00:00 2001 From: SumGuyV5 Date: Sat, 19 Sep 2026 00:05:54 +0000 Subject: [PATCH] update uploading functions --- help.sqlite3-query | 4 ++ main.py | 2 +- package/__init__.py | 3 +- package/database/__init__.py | 5 ++- package/database/database.py | 36 ++++++++++++---- package/process_uploads.py | 83 +++++++++++++++++++----------------- package/twitch/__init__.py | 2 +- package/youtube/__init__.py | 3 +- package/youtube/uploader.py | 2 + 9 files changed, 85 insertions(+), 55 deletions(-) create mode 100644 help.sqlite3-query diff --git a/help.sqlite3-query b/help.sqlite3-query new file mode 100644 index 0000000..03f1e61 --- /dev/null +++ b/help.sqlite3-query @@ -0,0 +1,4 @@ +-- database: ./database.db + +SELECT * FROM twitch_videos WHERE clip_is == "1" and uploaded_yt_shorts == "1"; +UPDATE twitch_videos SET uploaded_yt_shorts = 0 WHERE uploaded_yt_shorts == "1"; \ No newline at end of file diff --git a/main.py b/main.py index 0e826dd..c4f451b 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ import package.build_videos as build_videos import package.process_uploads as process_uploads if __name__ == "__main__": - upload = False + upload = True if upload is False: # Get Twitch Video Info diff --git a/package/__init__.py b/package/__init__.py index 1cb2d20..12013af 100644 --- a/package/__init__.py +++ b/package/__init__.py @@ -17,7 +17,6 @@ os.makedirs(CACHE_DIR, exist_ok=True) from .build_shorts import fit_to_9_16_letterbox from .build_videos import build_videos from .config import CHANNEL_NAME, TZ, DB -from .database import Database from .hash_tags import get_top_nouns from .process_uploads import process_uploads from .transcribe_video import transcribe_to_srt @@ -26,6 +25,7 @@ from .utils import write_csv, run_command # 4. Expose Subpackages from . import twitch from . import youtube +from . import database # (Optional) Defines what is exposed during 'from package import *' __all__ = [ @@ -34,7 +34,6 @@ __all__ = [ "CHANNEL_NAME", "TZ", "DB", - "Database", "get_top_nouns", "process_uploads", "transcribe_to_srt", diff --git a/package/database/__init__.py b/package/database/__init__.py index 1d39528..2d52fcb 100644 --- a/package/database/__init__.py +++ b/package/database/__init__.py @@ -1,11 +1,12 @@ # package/database/__init__.py # Expose components from individual modules using relative imports -from .database import TwitchVideo, Data, Database +from .database import TwitchVideo, Data, YoutubeInfo, Database # Explicitly define what is exposed when importing the subpackage __all__ = [ "TwitchVideo", "Data", + "YoutubeInfo", "Database", -] +] \ No newline at end of file diff --git a/package/database/database.py b/package/database/database.py index 491564e..a2a1702 100644 --- a/package/database/database.py +++ b/package/database/database.py @@ -1,5 +1,5 @@ -from sqlalchemy import create_engine, Column, String, Integer, Boolean, select -from sqlalchemy.orm import declarative_base, sessionmaker +from sqlalchemy import create_engine, Column, String, Integer, Boolean, ForeignKey, select +from sqlalchemy.orm import declarative_base, relationship, sessionmaker from typing import Any # 1. Define the base class for declarative models @@ -26,6 +26,8 @@ class TwitchVideo(Base): uploaded_yt_chats = Column(Boolean, nullable=False, default=False) uploaded_yt_shorts = Column(Boolean, nullable=False, default=False) + # Relationship back to YoutubeInfo (uselist=False enforces a 1-to-1 structure) + youtube_info = relationship("YoutubeInfo", back_populates="twitch_video", uselist=False) # 3. Define the data table class Data(Base): @@ -38,6 +40,23 @@ class Data(Base): date_videos = Column(String, nullable=False) date_videos_chat = Column(String, nullable=False) +class YoutubeInfo(Base): + __tablename__ = "youtube_info" + + id = Column(String, ForeignKey("twitch_videos.id"), primary_key=True) + yt_id = Column(String, nullable=True) + yt_date = Column(String, nullable=True) + yt_short_id = Column(String, nullable=True) + yt_short_date = Column(String, nullable=True) + yt_chat_SS_id = Column(String, nullable=True) + yt_chat_SS_date = Column(String, nullable=True) + yt_chat_over_id = Column(String, nullable=True) + yt_chat_over_date = Column(String, nullable=True) + + # Relationship linking back to the twitch video record + twitch_video = relationship("TwitchVideo", back_populates="youtube_info") + + class Database: def __init__(self, db_path: str = "database.db"): # 4. Connect to the SQLite file and generate the tables @@ -152,7 +171,10 @@ class Database: stmt = select(Data) return self.session.scalars(stmt).all() - def insert(self, data: TwitchVideo | Data): + def get_youtube_info(self, record_id) -> YoutubeInfo | None: + return self.session.get(YoutubeInfo, record_id) + + def insert(self, data: TwitchVideo | Data | YoutubeInfo): # SQLAlchemy 2.0 context manager handles commit/rollback automatically try: if isinstance(data, TwitchVideo): @@ -170,11 +192,9 @@ class Database: # 3. Add new instance if it doesn't exist self.session.add(data) print("➕ New TwitchVideo record inserted successfully!") - else: - # Handle standard insertion for the Data model - self.session.add(data) - print("➕ Data record inserted successfully!") - + else: + self.session.merge(data) + print(f"➕ {type(data).__name__} record inserted successfully!") # 4. Flush changes and commit the transaction self.session.commit() diff --git a/package/process_uploads.py b/package/process_uploads.py index 1754621..a6e788c 100644 --- a/package/process_uploads.py +++ b/package/process_uploads.py @@ -11,73 +11,76 @@ 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_shorts(): shorts = DB.get_unuploaded_shorts() data = DB.get_data() - ( data_id, name, release_time, _, _) = data[0] + 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: - pass - else: release_time = current_time release_time = release_time.replace(hour=12, minute=0, second=0, microsecond=0) for short in shorts: - ( - id, - title, - created_at, - view_count, - duration, - url, - thumbnail_url, - game_id, - game_name, - stream_id, - creator_name, - clip_is, - downloaded, - uploaded_yt, - uploaded_yt_chats, - uploaded_yt_shorts, - ) = short - - original_path = f"download/clips/{id}/{id}.mp4" - file_path = f"download/clips/{id}/{id}_gaussian_9_16.mp4" - file_csv = f"download/clips/{id}/{id}_{name}.csv" + 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/{id}/{id}_black_9_16.mp4" + file_path = f"download/clips/{short.id}/{short.id}_black_9_16.mp4" if not os.path.exists(file_path): continue - title = title - created_at = datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S%z") + 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: {game_name}, Clipped By: {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" + 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'{game_name}', f'{creator_name}', 'twitch_clips', 'clips', 'Level1Techs', 'twitch'] + 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/{id}/{id}.srt")) + tags.extend(get_top_nouns(f"download/clips/{short.id}/{short.id}.srt")) - data_csv = [] + youtube_info = DB.get_youtube_info(short.id) + + if not youtube_info: + youtube_info = YoutubeInfo() if os.path.exists(original_path): - if video_id := upload_video(original_path, title, categoryId, description, 'unlisted', tags): - data_csv.extend(video_id, current_time) - release_time += timedelta(days=1) - if video_id := upload_video(file_path, title, categoryId, f"{description} Original Full size @ https://youtu.be/{video_id}", privatcyStatus, tags, release_time): - data_csv.extend(video_id, release_time) - DB.mark_as_uploaded_shorts(id) - utils.write_csv(data_csv, file_csv) + if yt_video_id := upload_video(original_path, short.title, categoryId, description, 'unlisted', tags): + data_csv = [yt_video_id, current_time] + release_time += timedelta(days=1) - DB.update_date_shorts(data_id, release_time) + # 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_shorts(short.id) + DB.mark_as_uploaded_yt(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) + + DB.insert(youtube_info) + + DB.update_date_shorts(meta_data.id, release_time) + +def process_chats(): + pass def process_uploads(): process_shorts() + process_chats() if __name__ == "__main__": pass \ No newline at end of file diff --git a/package/twitch/__init__.py b/package/twitch/__init__.py index 3bdcb8f..aa87e0e 100644 --- a/package/twitch/__init__.py +++ b/package/twitch/__init__.py @@ -12,4 +12,4 @@ __all__ = [ "download_thumbnails", "download_videos", "video_info", -] +] \ No newline at end of file diff --git a/package/youtube/__init__.py b/package/youtube/__init__.py index 5749796..9b599ab 100644 --- a/package/youtube/__init__.py +++ b/package/youtube/__init__.py @@ -9,4 +9,5 @@ __all__ = [ "find_tags", "get_top_nouns", "upload_video", -] + "CategoryId", +] \ No newline at end of file diff --git a/package/youtube/uploader.py b/package/youtube/uploader.py index 174861c..da96528 100755 --- a/package/youtube/uploader.py +++ b/package/youtube/uploader.py @@ -43,6 +43,8 @@ def upload_video(file_path: str, title: str, category: CategoryId, description: release_time (datetime): Optional timezone-aware UTC datetime object for timed release schedule_date = datetime.now(timezone.utc) + timedelta(days=2) + Returns: + a String(str) of with the youtube video id or None if somthing fails """ if tags is None: tags = []