diff --git a/main.py b/main.py index 9998f44..5f01e5f 100755 --- a/main.py +++ b/main.py @@ -37,11 +37,9 @@ def main(): load_dotenv() cleanup() - def get_obj(): - reddit_obj = get_subreddit_threads() - return reddit_obj - reddit_object = get_obj() + + reddit_object = get_subreddit_threads() length, number_of_comments = save_text_to_mp3(reddit_object) download_screenshots_of_reddit_posts(reddit_object, number_of_comments) download_background() diff --git a/utils/checker.py b/utils/checker.py index 07b1e15..668b40f 100755 --- a/utils/checker.py +++ b/utils/checker.py @@ -11,6 +11,11 @@ console = Console() def check_env() -> bool: + """Checks to see what's been put in .env + + Returns: + bool: Whether or not everything was put in properly + """ if not os.path.exists(".env.template"): console.print("[red]Couldn't find .env.template. Unable to check variables.") return True diff --git a/utils/cleanup.py b/utils/cleanup.py index 9490b6d..858cfe9 100644 --- a/utils/cleanup.py +++ b/utils/cleanup.py @@ -3,6 +3,11 @@ from os.path import exists def cleanup() -> int: + """Deletes all temporary assets in assets/temp + + Returns: + int: How many files were deleted + """ if exists("./assets/temp"): count = 0 files = [f for f in os.listdir(".") if f.endswith(".mp4") and "temp" in f.lower()] diff --git a/utils/subreddit.py b/utils/subreddit.py index e05c136..3c5cb22 100644 --- a/utils/subreddit.py +++ b/utils/subreddit.py @@ -4,7 +4,16 @@ from os import getenv from utils.console import print_substep -def get_subreddit_undone(submissions: List, subreddit): +def get_subreddit_undone(submissions: list, subreddit): + """_summary_ + + Args: + submissions (list): List of posts that are going to potentially be generated into a video + subreddit (praw.Reddit.SubredditHelper): Chosen subreddit + + Returns: + Any: The submission that has not been done + """ """ recursively checks if the top submission in the list was already done. """ @@ -27,7 +36,16 @@ def get_subreddit_undone(submissions: List, subreddit): ) # all of the videos in hot have already been done -def already_done(done_videos: list, submission): +def already_done(done_videos: list, submission)->bool: + """Checks to see if the given submission is in the list of videos + + Args: + done_videos (list): Finished videos + submission (Any): The submission + + Returns: + Boolean: Whether the video was found in the list + """ for video in done_videos: if video["id"] == str(submission): diff --git a/utils/videos.py b/utils/videos.py index 51a2704..e6510fe 100755 --- a/utils/videos.py +++ b/utils/videos.py @@ -5,10 +5,17 @@ from utils.console import print_step def check_done( - redditobj, -): # don't set this to be run anyplace that isn't subreddit.py bc of inspect stack - """params: - reddit_object: The Reddit Object you received in askreddit.py""" + redditobj:dict[str], +)->dict[str]|None: # don't set this to be run anyplace that isn't subreddit.py bc of inspect stack + """Checks if the chosen post has already been generated + + Args: + redditobj (dict[str]): Reddit object gotten from reddit/subreddit.py + + Returns: + dict[str]|None: Reddit object in args + """ + with open("./video_creation/data/videos.json", "r") as done_vids_raw: done_videos = json.load(done_vids_raw) for video in done_videos: diff --git a/utils/voice.py b/utils/voice.py index 63e8eff..e78ddad 100644 --- a/utils/voice.py +++ b/utils/voice.py @@ -1,12 +1,17 @@ import re -def sanitize_text(text): - """ - Sanitizes the text for tts. - What gets removed: - - following characters`^_~@!&;#:-%“”‘"%*/{}[]()\|<>?=+` - - any http or https links +def sanitize_text(text: str) -> str: + """Sanitizes the text for tts. + What gets removed: + - following characters`^_~@!&;#:-%“”‘"%*/{}[]()\|<>?=+` + - any http or https links + + Args: + text (str): Text to be sanitized + + Returns: + str: Sanitized text """ # remove any urls from the text diff --git a/video_creation/background.py b/video_creation/background.py index d1a7948..ebf369d 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -8,7 +8,16 @@ from moviepy.editor import VideoFileClip from utils.console import print_step, print_substep -def get_start_and_end_times(video_length, length_of_clip): +def get_start_and_end_times(video_length:int, length_of_clip:int)->tuple[int,int]: + """Generates a random interval of time to be used as the beckground of the video. + + Args: + video_length (int): Length of the video + length_of_clip (int): Length of the video to be used as the background + + Returns: + tuple[int,int]: Start and end time of the randomized interval + """ random_time = randrange(180, int(length_of_clip) - int(video_length)) return random_time, random_time + video_length @@ -45,7 +54,12 @@ def download_background(): ) -def chop_background_video(video_length): +def chop_background_video(video_length:int): + """Generates the background footage to be used in the video and writes it to assets/temp/background.mp4 + + Args: + video_length (int): Length of the clip where the background footage is to be taken out of + """ print_step("Finding a spot in the backgrounds video to chop...✂️") choice = random.choice(listdir("assets/backgrounds")) environ["background_credit"] = choice.split("-")[0] @@ -60,4 +74,3 @@ def chop_background_video(video_length): targetname="assets/temp/background.mp4", ) print_substep("Background video chopped successfully!", style="bold green") - return True diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 7ca1d10..5b2eee6 100755 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -25,7 +25,13 @@ console = Console() W, H = 1080, 1920 -def make_final_video(number_of_clips, length): +def make_final_video(number_of_clips:int, length:int): + """Gathers audio clips, gathers all screenshots, stitches them together and saves the final video to assets/temp + + Args: + number_of_clips (int): Index to end at when going through the screenshots + length (int): Length of the video + """ print_step("Creating the final video 🎥") VideoFileClip.reW = lambda clip: clip.resize(width=W) VideoFileClip.reH = lambda clip: clip.resize(width=H) @@ -110,32 +116,12 @@ def make_final_video(number_of_clips, length): image_concat.audio = audio_composite final = CompositeVideoClip([background_clip, image_concat]) - def get_video_title() -> str: - title = os.getenv("VIDEO_TITLE") or "final_video" - if len(title) <= 35: - return title - else: - return title[0:30] + "..." filename = f"{get_video_title()}.mp4" - def save_data(): - with open("./video_creation/data/videos.json", "r+") as raw_vids: - done_vids = json.load(raw_vids) - if str(subreddit.submission.id) in [video["id"] for video in done_vids]: - return # video already done but was specified to continue anyway in the .env file - payload = { - "id": str(os.getenv("VIDEO_ID")), - "time": str(int(time.time())), - "background_credit": str(os.getenv("background_credit")), - "reddit_title": str(os.getenv("VIDEO_TITLE")), - "filename": filename, - } - done_vids.append(payload) - raw_vids.seek(0) - json.dump(done_vids, raw_vids, ensure_ascii=False, indent=4) - - save_data() + + save_data(filename) + if not exists("./results"): print_substep("the results folder didn't exist so I made it") os.mkdir("./results") @@ -160,3 +146,36 @@ def make_final_video(number_of_clips, length): print_step( f"Reddit title: {os.getenv('VIDEO_TITLE')} \n Background Credit: {os.getenv('background_credit')}" ) + +def save_data(filename:str): + """Saves the videos that have already been generated to a JSON file in video_creation/data/videos.json + + Args: + filename (str): The finished video title name + """ + with open("./video_creation/data/videos.json", "r+") as raw_vids: + done_vids = json.load(raw_vids) + if str(subreddit.submission.id) in [video["id"] for video in done_vids]: + return # video already done but was specified to continue anyway in the .env file + payload = { + "id": str(os.getenv("VIDEO_ID")), + "time": str(int(time.time())), + "background_credit": str(os.getenv("background_credit")), + "reddit_title": str(os.getenv("VIDEO_TITLE")), + "filename": filename, + } + done_vids.append(payload) + raw_vids.seek(0) + json.dump(done_vids, raw_vids, ensure_ascii=False, indent=4) + +def get_video_title() -> str: + """Gets video title from env variable or gives it the name "final_video" + + Returns: + str: Video title + """ + title = os.getenv("VIDEO_TITLE") or "final_video" + if len(title) <= 35: + return title + else: + return title[0:30] + "..." \ No newline at end of file diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 469daf4..4620677 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -18,12 +18,14 @@ console = Console() storymode = False -def download_screenshots_of_reddit_posts(reddit_object, screenshot_num): - """Downloads screenshots of reddit posts as they are seen on the web. +def download_screenshots_of_reddit_posts(reddit_object:dict[str], screenshot_num:int): + """Downloads screenshots of reddit posts as seen on the web. Downloads to assets/temp/png + Args: - reddit_object: The Reddit Object you received in askreddit.py - screenshot_num: The number of screenshots you want to download. - """ + reddit_object (dict[str]): Reddit object received from reddit/subreddit.py + screenshot_num (int): Number of screenshots to downlaod + """ + print_step("Downloading screenshots of reddit posts...") # ! Make sure the reddit screenshots folder exists diff --git a/video_creation/voices.py b/video_creation/voices.py index 3bbd16c..f5ead42 100644 --- a/video_creation/voices.py +++ b/video_creation/voices.py @@ -25,11 +25,16 @@ TTSProviders = { VIDEO_LENGTH: int = 40 # secs -def save_text_to_mp3(reddit_obj): - """Saves Text to MP3 files. +def save_text_to_mp3(reddit_obj:dict[str])->tuple[int,int]: + """Saves text to MP3 files. Goes through the reddit_obj and generates the title MP3 file and a certain number of comments until the total amount of time exceeds VIDEO_LENGTH seconds. + Args: - reddit_obj : The reddit object you received from the reddit API in the askreddit.py file. + reddit_obj (dict[str]): Reddit object received from reddit API in reddit/subreddit.py + + Returns: + tuple[int,int]: (total length of the audio, the number of comments audio was generated for) """ + env = os.getenv("TTSCHOICE", "") if env.casefold() in map(lambda _: _.casefold(), TTSProviders): text_to_mp3 = TTSEngine(