Formatted with python-black

pull/729/head
Callum Leslie 3 years ago
parent dba11ea1e3
commit 69f4f59bb6

@ -37,8 +37,6 @@ def main():
load_dotenv() load_dotenv()
cleanup() cleanup()
reddit_object = get_subreddit_threads() reddit_object = get_subreddit_threads()
length, number_of_comments = save_text_to_mp3(reddit_object) length, number_of_comments = save_text_to_mp3(reddit_object)
download_screenshots_of_reddit_posts(reddit_object, number_of_comments) download_screenshots_of_reddit_posts(reddit_object, number_of_comments)

@ -105,13 +105,13 @@ def get_subreddit_threads():
continue # # see https://github.com/JasonLovesDoggo/RedditVideoMakerBot/issues/78 continue # # see https://github.com/JasonLovesDoggo/RedditVideoMakerBot/issues/78
if not top_level_comment.stickied: if not top_level_comment.stickied:
if len(top_level_comment.body) <= int(try_env("MAX_COMMENT_LENGTH", 500)): if len(top_level_comment.body) <= int(try_env("MAX_COMMENT_LENGTH", 500)):
if not top_level_comment.author == None: if not top_level_comment.author == None:
content["comments"].append( content["comments"].append(
{ {
"comment_body": top_level_comment.body, "comment_body": top_level_comment.body,
"comment_url": top_level_comment.permalink, "comment_url": top_level_comment.permalink,
"comment_id": top_level_comment.id, "comment_id": top_level_comment.id,
} }
) )
print_substep("Received subreddit threads Successfully.", style="bold green") print_substep("Received subreddit threads Successfully.", style="bold green")
return content return content

@ -15,7 +15,7 @@ def check_env() -> bool:
Returns: Returns:
bool: Whether or not everything was put in properly bool: Whether or not everything was put in properly
""" """
if not os.path.exists(".env.template"): if not os.path.exists(".env.template"):
console.print("[red]Couldn't find .env.template. Unable to check variables.") console.print("[red]Couldn't find .env.template. Unable to check variables.")
return True return True
@ -35,7 +35,11 @@ def check_env() -> bool:
req_envs = [] req_envs = []
var_optional = False var_optional = False
for line in template.readlines(): for line in template.readlines():
if line.startswith("#") is not True and "=" in line and var_optional is not True: if (
line.startswith("#") is not True
and "=" in line
and var_optional is not True
):
req_envs.append(line.split("=")[0]) req_envs.append(line.split("=")[0])
if "#" in line: if "#" in line:
examples[line.split("=")[0]] = "#".join(line.split("#")[1:]).strip() examples[line.split("=")[0]] = "#".join(line.split("#")[1:]).strip()
@ -56,7 +60,9 @@ def check_env() -> bool:
) )
var_optional = False var_optional = False
elif line.startswith("#MATCH_TYPE "): elif line.startswith("#MATCH_TYPE "):
types[req_envs[-1]] = eval(line.removeprefix("#MATCH_TYPE ")[:-1].split()[0]) types[req_envs[-1]] = eval(
line.removeprefix("#MATCH_TYPE ")[:-1].split()[0]
)
var_optional = False var_optional = False
elif line.startswith("#EXPLANATION "): elif line.startswith("#EXPLANATION "):
explanations[req_envs[-1]] = line.removeprefix("#EXPLANATION ")[:-1] explanations[req_envs[-1]] = line.removeprefix("#EXPLANATION ")[:-1]
@ -82,9 +88,9 @@ def check_env() -> bool:
try: try:
temp = types[env](value) temp = types[env](value)
if env in bounds.keys(): if env in bounds.keys():
(bounds[env][0] <= temp or incorrect.add(env)) and len(bounds[env]) > 1 and ( (bounds[env][0] <= temp or incorrect.add(env)) and len(
bounds[env][1] >= temp or incorrect.add(env) bounds[env]
) ) > 1 and (bounds[env][1] >= temp or incorrect.add(env))
except ValueError: except ValueError:
incorrect.add(env) incorrect.add(env)
@ -107,11 +113,17 @@ def check_env() -> bool:
for env in missing: for env in missing:
table.add_row( table.add_row(
env, env,
explanations[env] if env in explanations.keys() else "No explanation given", explanations[env]
if env in explanations.keys()
else "No explanation given",
examples[env] if env in examples.keys() else "", examples[env] if env in examples.keys() else "",
str(bounds[env][0]) if env in bounds.keys() and bounds[env][1] is not None else "", str(bounds[env][0])
if env in bounds.keys() and bounds[env][1] is not None
else "",
str(bounds[env][1]) str(bounds[env][1])
if env in bounds.keys() and len(bounds[env]) > 1 and bounds[env][1] is not None if env in bounds.keys()
and len(bounds[env]) > 1
and bounds[env][1] is not None
else "", else "",
) )
console.print(table) console.print(table)
@ -128,7 +140,9 @@ def check_env() -> bool:
title_style="#C0CAF5 bold", title_style="#C0CAF5 bold",
) )
table.add_column("Variable", justify="left", style="#7AA2F7 bold", no_wrap=True) table.add_column("Variable", justify="left", style="#7AA2F7 bold", no_wrap=True)
table.add_column("Current value", justify="left", style="#F7768E", no_wrap=False) table.add_column(
"Current value", justify="left", style="#F7768E", no_wrap=False
)
table.add_column("Explanation", justify="left", style="#BB9AF7", no_wrap=False) table.add_column("Explanation", justify="left", style="#BB9AF7", no_wrap=False)
table.add_column("Example", justify="center", style="#F7768E", no_wrap=True) table.add_column("Example", justify="center", style="#F7768E", no_wrap=True)
table.add_column("Min", justify="right", style="#F7768E", no_wrap=True) table.add_column("Min", justify="right", style="#F7768E", no_wrap=True)
@ -137,10 +151,14 @@ def check_env() -> bool:
table.add_row( table.add_row(
env, env,
os.getenv(env), os.getenv(env),
explanations[env] if env in explanations.keys() else "No explanation given", explanations[env]
if env in explanations.keys()
else "No explanation given",
str(types[env].__name__) if env in types.keys() else "str", str(types[env].__name__) if env in types.keys() else "str",
str(bounds[env][0]) if env in bounds.keys() else "None", str(bounds[env][0]) if env in bounds.keys() else "None",
str(bounds[env][1]) if env in bounds.keys() and len(bounds[env]) > 1 else "None", str(bounds[env][1])
if env in bounds.keys() and len(bounds[env]) > 1
else "None",
) )
missing.add(env) missing.add(env)
console.print(table) console.print(table)
@ -177,11 +195,17 @@ def check_env() -> bool:
if env in explanations.keys() if env in explanations.keys()
else "Incorrect input. Try again.", else "Incorrect input. Try again.",
bounds[env][0] if env in bounds.keys() else None, bounds[env][0] if env in bounds.keys() else None,
bounds[env][1] if env in bounds.keys() and len(bounds[env]) > 1 else None, bounds[env][1]
oob_errors[env] if env in oob_errors.keys() else "Input too long/short.", if env in bounds.keys() and len(bounds[env]) > 1
else None,
oob_errors[env]
if env in oob_errors.keys()
else "Input too long/short.",
extra_info="[#C0CAF5 bold]⮶ " extra_info="[#C0CAF5 bold]⮶ "
+ ( + (
explanations[env] if env in explanations.keys() else "No info available" explanations[env]
if env in explanations.keys()
else "No info available"
), ),
) )
) )

@ -7,10 +7,12 @@ def cleanup() -> int:
Returns: Returns:
int: How many files were deleted int: How many files were deleted
""" """
if exists("./assets/temp"): if exists("./assets/temp"):
count = 0 count = 0
files = [f for f in os.listdir(".") if f.endswith(".mp4") and "temp" in f.lower()] files = [
f for f in os.listdir(".") if f.endswith(".mp4") and "temp" in f.lower()
]
count += len(files) count += len(files)
for f in files: for f in files:
os.remove(f) os.remove(f)

@ -64,10 +64,14 @@ def handle_input(
except ValueError: except ValueError:
console.print("[red]" + err_message) # Type conversion failed console.print("[red]" + err_message) # Type conversion failed
continue continue
if nmin is not None and len(user_input) < nmin: # Check if string is long enough if (
nmin is not None and len(user_input) < nmin
): # Check if string is long enough
console.print("[red]" + oob_error) console.print("[red]" + oob_error)
continue continue
if nmax is not None and len(user_input) > nmax: # Check if string is not too long if (
nmax is not None and len(user_input) > nmax
): # Check if string is not too long
console.print("[red]" + oob_error) console.print("[red]" + oob_error)
continue continue
break break

@ -9,11 +9,11 @@ def get_subreddit_undone(submissions: list, subreddit):
Args: Args:
submissions (list): List of posts that are going to potentially be generated into a video submissions (list): List of posts that are going to potentially be generated into a video
subreddit (praw.Reddit.SubredditHelper): Chosen subreddit subreddit (praw.Reddit.SubredditHelper): Chosen subreddit
Returns: Returns:
Any: The submission that has not been done Any: The submission that has not been done
""" """
""" """
recursively checks if the top submission in the list was already done. recursively checks if the top submission in the list was already done.
""" """
@ -36,8 +36,8 @@ def get_subreddit_undone(submissions: list, subreddit):
) # all of the videos in hot have already been done ) # all of the videos in hot have already been done
def already_done(done_videos: list, submission)->bool: def already_done(done_videos: list, submission) -> bool:
"""Checks to see if the given submission is in the list of videos """Checks to see if the given submission is in the list of videos
Args: Args:
done_videos (list): Finished videos done_videos (list): Finished videos
@ -45,7 +45,7 @@ def already_done(done_videos: list, submission)->bool:
Returns: Returns:
Boolean: Whether the video was found in the list Boolean: Whether the video was found in the list
""" """
for video in done_videos: for video in done_videos:
if video["id"] == str(submission): if video["id"] == str(submission):

@ -5,8 +5,10 @@ from utils.console import print_step
def check_done( def check_done(
redditobj:dict[str], redditobj: dict[str],
)->dict[str]|None: # don't set this to be run anyplace that isn't subreddit.py bc of inspect stack ) -> 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 """Checks if the chosen post has already been generated
Args: Args:

@ -10,7 +10,7 @@ from pytube import YouTube
from utils.console import print_step, print_substep from utils.console import print_step, print_substep
def get_start_and_end_times(video_length:int, length_of_clip:int)->tuple[int,int]: 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. """Generates a random interval of time to be used as the beckground of the video.
Args: Args:
@ -19,7 +19,7 @@ def get_start_and_end_times(video_length:int, length_of_clip:int)->tuple[int,int
Returns: Returns:
tuple[int,int]: Start and end time of the randomized interval tuple[int,int]: Start and end time of the randomized interval
""" """
random_time = randrange(180, int(length_of_clip) - int(video_length)) random_time = randrange(180, int(length_of_clip) - int(video_length))
return random_time, random_time + video_length return random_time, random_time + video_length
@ -37,7 +37,7 @@ def download_background():
] ]
# note: make sure the file name doesn't include an - in it # note: make sure the file name doesn't include an - in it
if not len(listdir("./assets/backgrounds")) >= len( if not len(listdir("./assets/backgrounds")) >= len(
background_options background_options
): # if there are any background videos not installed ): # if there are any background videos not installed
print_step( print_step(
"We need to download the backgrounds videos. they are fairly large but it's only done once. 😎" "We need to download the backgrounds videos. they are fairly large but it's only done once. 😎"
@ -56,12 +56,12 @@ def download_background():
) )
def chop_background_video(video_length:int): 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 """Generates the background footage to be used in the video and writes it to assets/temp/background.mp4
Args: Args:
video_length (int): Length of the clip where the background footage is to be taken out of 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...✂️") print_step("Finding a spot in the backgrounds video to chop...✂️")
choice = random.choice(listdir("assets/backgrounds")) choice = random.choice(listdir("assets/backgrounds"))
environ["background_credit"] = choice.split("-")[0] environ["background_credit"] = choice.split("-")[0]

@ -26,13 +26,13 @@ console = Console()
W, H = 1080, 1920 W, H = 1080, 1920
def make_final_video(number_of_clips:int, length:int): 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 """Gathers audio clips, gathers all screenshots, stitches them together and saves the final video to assets/temp
Args: Args:
number_of_clips (int): Index to end at when going through the screenshots number_of_clips (int): Index to end at when going through the screenshots
length (int): Length of the video length (int): Length of the video
""" """
print_step("Creating the final video 🎥") print_step("Creating the final video 🎥")
VideoFileClip.reW = lambda clip: clip.resize(width=W) VideoFileClip.reW = lambda clip: clip.resize(width=W)
VideoFileClip.reH = lambda clip: clip.resize(width=H) VideoFileClip.reH = lambda clip: clip.resize(width=H)
@ -117,10 +117,8 @@ def make_final_video(number_of_clips:int, length:int):
image_concat.audio = audio_composite image_concat.audio = audio_composite
final = CompositeVideoClip([background_clip, image_concat]) final = CompositeVideoClip([background_clip, image_concat])
filename = f"{get_video_title()}.mp4" filename = f"{get_video_title()}.mp4"
save_data(filename) save_data(filename)
if not exists("./results"): if not exists("./results"):
@ -149,12 +147,13 @@ def make_final_video(number_of_clips:int, length:int):
f"Reddit title: {os.getenv('VIDEO_TITLE')} \n Background Credit: {os.getenv('background_credit')}" f"Reddit title: {os.getenv('VIDEO_TITLE')} \n Background Credit: {os.getenv('background_credit')}"
) )
def save_data(filename:str):
def save_data(filename: str):
"""Saves the videos that have already been generated to a JSON file in video_creation/data/videos.json """Saves the videos that have already been generated to a JSON file in video_creation/data/videos.json
Args: Args:
filename (str): The finished video title name filename (str): The finished video title name
""" """
with open("./video_creation/data/videos.json", "r+") as raw_vids: with open("./video_creation/data/videos.json", "r+") as raw_vids:
done_vids = json.load(raw_vids) done_vids = json.load(raw_vids)
if str(subreddit.submission.id) in [video["id"] for video in done_vids]: if str(subreddit.submission.id) in [video["id"] for video in done_vids]:
@ -170,14 +169,15 @@ def save_data(filename:str):
raw_vids.seek(0) raw_vids.seek(0)
json.dump(done_vids, raw_vids, ensure_ascii=False, indent=4) json.dump(done_vids, raw_vids, ensure_ascii=False, indent=4)
def get_video_title() -> str: def get_video_title() -> str:
"""Gets video title from env variable or gives it the name "final_video" """Gets video title from env variable or gives it the name "final_video"
Returns: Returns:
str: Video title str: Video title
""" """
title = os.getenv("VIDEO_TITLE") or "final_video" title = os.getenv("VIDEO_TITLE") or "final_video"
if len(title) <= 35: if len(title) <= 35:
return title return title
else: else:
return title[0:30] + "..." return title[0:30] + "..."

@ -3,7 +3,7 @@ from os import getenv
import os import os
from pathlib import Path from pathlib import Path
from playwright.async_api import async_playwright # do not remove this line from playwright.async_api import async_playwright # do not remove this line
from playwright.sync_api import sync_playwright, ViewportSize from playwright.sync_api import sync_playwright, ViewportSize
from rich.progress import track from rich.progress import track
@ -18,14 +18,14 @@ console = Console()
storymode = False storymode = False
def download_screenshots_of_reddit_posts(reddit_object:dict[str], screenshot_num:int): 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 """Downloads screenshots of reddit posts as seen on the web. Downloads to assets/temp/png
Args: Args:
reddit_object (dict[str]): Reddit object received from reddit/subreddit.py reddit_object (dict[str]): Reddit object received from reddit/subreddit.py
screenshot_num (int): Number of screenshots to downlaod screenshot_num (int): Number of screenshots to downlaod
""" """
print_step("Downloading screenshots of reddit posts...") print_step("Downloading screenshots of reddit posts...")
# ! Make sure the reddit screenshots folder exists # ! Make sure the reddit screenshots folder exists
@ -60,10 +60,13 @@ def download_screenshots_of_reddit_posts(reddit_object:dict[str], screenshot_num
if getenv("POSTLANG"): if getenv("POSTLANG"):
print_substep("Translating post...") print_substep("Translating post...")
texts_in_tl = ts.google(reddit_object["thread_title"], to_language=os.getenv("POSTLANG")) texts_in_tl = ts.google(
reddit_object["thread_title"], to_language=os.getenv("POSTLANG")
)
page.evaluate( page.evaluate(
'tl_content => document.querySelector(\'[data-test-id="post-content"] > div:nth-child(3) > div > div\').textContent = tl_content', texts_in_tl "tl_content => document.querySelector('[data-test-id=\"post-content\"] > div:nth-child(3) > div > div').textContent = tl_content",
texts_in_tl,
) )
else: else:
print_substep("Skipping translation...") print_substep("Skipping translation...")
@ -92,9 +95,12 @@ def download_screenshots_of_reddit_posts(reddit_object:dict[str], screenshot_num
# translate code # translate code
if getenv("POSTLANG"): if getenv("POSTLANG"):
comment_tl = ts.google(comment["comment_body"], to_language=os.getenv("POSTLANG")) comment_tl = ts.google(
comment["comment_body"], to_language=os.getenv("POSTLANG")
)
page.evaluate( page.evaluate(
'([tl_content, tl_id]) => document.querySelector(`#t1_${tl_id} > div:nth-child(2) > div > div[data-testid="comment"] > div`).textContent = tl_content', [comment_tl, comment['comment_id']] '([tl_content, tl_id]) => document.querySelector(`#t1_${tl_id} > div:nth-child(2) > div > div[data-testid="comment"] > div`).textContent = tl_content',
[comment_tl, comment["comment_id"]],
) )
page.locator(f"#t1_{comment['comment_id']}").screenshot( page.locator(f"#t1_{comment['comment_id']}").screenshot(

@ -25,7 +25,7 @@ TTSProviders = {
VIDEO_LENGTH: int = 40 # secs VIDEO_LENGTH: int = 40 # secs
def save_text_to_mp3(reddit_obj:dict[str])->tuple[int,int]: 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. """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: Args:
@ -34,7 +34,7 @@ def save_text_to_mp3(reddit_obj:dict[str])->tuple[int,int]:
Returns: Returns:
tuple[int,int]: (total length of the audio, the number of comments audio was generated for) tuple[int,int]: (total length of the audio, the number of comments audio was generated for)
""" """
env = os.getenv("TTSCHOICE", "") env = os.getenv("TTSCHOICE", "")
if env.casefold() in map(lambda _: _.casefold(), TTSProviders): if env.casefold() in map(lambda _: _.casefold(), TTSProviders):
text_to_mp3 = TTSEngine( text_to_mp3 = TTSEngine(

Loading…
Cancel
Save