pull/760/head
HallowedDust5 3 years ago
parent 34ce61e1ca
commit b8516577b9
No known key found for this signature in database
GPG Key ID: AAAAF940F1C8C004

@ -69,7 +69,8 @@ class TTSEngine:
else:
self.split_post(comment["comment_body"], idx)
print_substep("Saved Text to MP3 files successfully.", style="bold green")
print_substep("Saved Text to MP3 files successfully.",
style="bold green")
return self.length, idx
def split_post(self, text: str, idx: int) -> str:
@ -85,7 +86,8 @@ class TTSEngine:
for idy, text_cut in enumerate(split_text):
# print(f"{idx}-{idy}: {text_cut}\n")
self.call_tts(f"{idx}-{idy}.part", text_cut)
split_files.append(AudioFileClip(f"{self.path}/{idx}-{idy}.part.mp3"))
split_files.append(AudioFileClip(
f"{self.path}/{idx}-{idy}.part.mp3"))
CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile(
f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None
)

@ -12,7 +12,7 @@ def program_options():
"""
parser = argparse.ArgumentParser(
prog="RedditVideoMakerBot", # can be renamed, just a base
prog="RedditVideoMakerBot", # can be renamed, just a base
usage="RedditVideoMakerBot [OPTIONS]",
description=description
)
@ -21,7 +21,7 @@ def program_options():
help="Create a video (uses the defaults).",
action="store_true"
)
parser.add_argument( # only accepts the name of subreddit, not links.
parser.add_argument( # only accepts the name of subreddit, not links.
"-s", "--subreddit",
help="Specify a subreddit.",
action="store"
@ -65,7 +65,8 @@ def program_options():
args.number,
)
if not create:
try_again = input("Something went wrong! Try again? [y/N] > ").strip()
try_again = input(
"Something went wrong! Try again? [y/N] > ").strip()
if try_again in ["y", "Y"]:
continue

@ -32,29 +32,27 @@ print_markdown(
def main(
subreddit_=None,
background=None,
filename=None,
thread_link_=None,
number_of_comments=None
):
subreddit_=None,
background=None,
filename=None,
thread_link_=None,
number_of_comments=None
):
if check_env() is not True:
exit()
load_dotenv()
cleanup()
reddit_object = get_subreddit_threads(
subreddit_,
thread_link_,
number_of_comments
)
subreddit_,
thread_link_,
number_of_comments
)
length, number_of_comments = save_text_to_mp3(reddit_object)
download_screenshots_of_reddit_posts(reddit_object, number_of_comments)
download_background(background)
chop_background_video(length)
make_final_video(number_of_comments, length,filename)
make_final_video(number_of_comments, length, filename)
def run_many(times):

@ -1,3 +1,10 @@
from dotenv import load_dotenv
from prawcore.exceptions import (
OAuthException,
ResponseException,
RequestException,
BadRequest
)
import random
import os
import re
@ -10,7 +17,8 @@ from utils.subreddit import get_subreddit_undone
from utils.videos import check_done
from praw.models import MoreComments
TEXT_WHITELIST = set("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890")
TEXT_WHITELIST = set(
"abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890")
def textify(text):
@ -24,17 +32,6 @@ def try_env(param, backup):
return backup
from prawcore.exceptions import (
OAuthException,
ResponseException,
RequestException,
BadRequest
)
from dotenv import load_dotenv
from utils.console import print_step, print_substep
def get_subreddit_threads(subreddit_, thread_link_, number_of_comments):
"""
Takes subreddit_ as parameter which defaults to None, but in this
@ -67,11 +64,11 @@ def get_subreddit_threads(subreddit_, thread_link_, number_of_comments):
password=passkey.strip(),
)
except (
OAuthException,
ResponseException,
RequestException,
BadRequest
):
OAuthException,
ResponseException,
RequestException,
BadRequest
):
print_substep(
"[bold red]There is something wrong with the .env file, kindly check:[/bold red]\n"
+ "1. ClientID\n"
@ -80,7 +77,6 @@ def get_subreddit_threads(subreddit_, thread_link_, number_of_comments):
+ "4. Check if the type of Reddit app created is script (personal use script)."
)
# If the user specifies that he doesnt want a random thread, or if
# he doesn't insert the "RANDOM_THREAD" variable at all, ask the thread link
while True:
@ -136,7 +132,6 @@ def get_subreddit_threads(subreddit_, thread_link_, number_of_comments):
+ f"And has a {num_comments}[/blue].\n"
)
try:
content["thread_url"] = submission.url
content["thread_title"] = submission.title
@ -160,7 +155,8 @@ def get_subreddit_threads(subreddit_, thread_link_, number_of_comments):
except AttributeError:
pass
print_substep("AskReddit threads retrieved successfully.", style="bold green")
print_substep("AskReddit threads retrieved successfully.",
style="bold green")
content["thread_url"] = f"https://reddit.com{submission.permalink}"
content["thread_title"] = submission.title
@ -180,5 +176,6 @@ def get_subreddit_threads(subreddit_, thread_link_, number_of_comments):
"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

@ -108,7 +108,8 @@ user = handle_input(
20,
"A username HAS to be between 3 and 20 characters",
)
passw = handle_input("Password > ", False, ".*", "", 8, None, "Password too short")
passw = handle_input("Password > ", False, ".*", "",
8, None, "Password too short")
twofactor = handle_input(
"2fa Enabled? (yes/no) > ",
False,

@ -15,9 +15,10 @@ def check_env() -> bool:
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.")
console.print(
"[red]Couldn't find .env.template. Unable to check variables.")
return True
if not os.path.exists(".env"):
console.print("[red]Couldn't find the .env file, creating one now.")
@ -38,14 +39,17 @@ def check_env() -> bool:
if line.startswith("#") is not True and "=" in line and var_optional is not True:
req_envs.append(line.split("=")[0])
if "#" in line:
examples[line.split("=")[0]] = "#".join(line.split("#")[1:]).strip()
examples[line.split("=")[0]] = "#".join(
line.split("#")[1:]).strip()
elif "#OPTIONAL" in line:
var_optional = True
elif line.startswith("#MATCH_REGEX "):
matching[req_envs[-1]] = line.removeprefix("#MATCH_REGEX ")[:-1]
matching[req_envs[-1]
] = line.removeprefix("#MATCH_REGEX ")[:-1]
var_optional = False
elif line.startswith("#OOB_ERROR "):
oob_errors[req_envs[-1]] = line.removeprefix("#OOB_ERROR ")[:-1]
oob_errors[req_envs[-1]
] = line.removeprefix("#OOB_ERROR ")[:-1]
var_optional = False
elif line.startswith("#RANGE "):
bounds[req_envs[-1]] = tuple(
@ -56,10 +60,12 @@ def check_env() -> bool:
)
var_optional = False
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
elif line.startswith("#EXPLANATION "):
explanations[req_envs[-1]] = line.removeprefix("#EXPLANATION ")[:-1]
explanations[req_envs[-1]
] = line.removeprefix("#EXPLANATION ")[:-1]
var_optional = False
else:
var_optional = False
@ -99,17 +105,22 @@ def check_env() -> bool:
title_justify="left",
title_style="#C0CAF5 bold",
)
table.add_column("Variable", justify="left", style="#7AA2F7 bold", no_wrap=True)
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("Variable", justify="left",
style="#7AA2F7 bold", no_wrap=True)
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("Min", justify="right", style="#F7768E", no_wrap=True)
table.add_column("Max", justify="left", style="#F7768E", no_wrap=True)
for env in missing:
table.add_row(
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 "",
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])
if env in bounds.keys() and len(bounds[env]) > 1 and bounds[env][1] is not None
else "",
@ -127,20 +138,26 @@ def check_env() -> bool:
title_justify="left",
title_style="#C0CAF5 bold",
)
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("Explanation", justify="left", style="#BB9AF7", no_wrap=False)
table.add_column("Example", justify="center", style="#F7768E", 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("Explanation", justify="left",
style="#BB9AF7", no_wrap=False)
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("Max", justify="left", style="#F7768E", no_wrap=True)
for env in incorrect:
table.add_row(
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(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)
console.print(table)
@ -157,11 +174,13 @@ def check_env() -> bool:
with open(".env", "r+") as env_file:
lines = []
for line in env_file.readlines():
line.split("=")[0].strip() not in incorrect and lines.append(line)
line.split("=")[0].strip(
) not in incorrect and lines.append(line)
env_file.seek(0)
env_file.write("\n".join(lines))
env_file.truncate()
console.print("[green]Successfully removed incorrectly set variables from .env")
console.print(
"[green]Successfully removed incorrectly set variables from .env")
with open(".env", "a") as env_file:
for env in missing:
env_file.write(
@ -177,11 +196,14 @@ def check_env() -> bool:
if env in explanations.keys()
else "Incorrect input. Try again.",
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,
oob_errors[env] if env in oob_errors.keys() else "Input too long/short.",
bounds[env][1] 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]⮶ "
+ (
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,11 @@ def cleanup() -> int:
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()]
files = [f for f in os.listdir(".") if f.endswith(
".mp4") and "temp" in f.lower()]
count += len(files)
for f in files:
os.remove(f)

@ -13,7 +13,7 @@ def get_subreddit_undone(submissions: list, subreddit):
Returns:
Any: The submission that has not been done
"""
"""
"""
recursively checks if the top submission in the list was already done.
"""
@ -28,7 +28,8 @@ def get_subreddit_undone(submissions: list, subreddit):
print_substep("NSFW Post Detected. Skipping...")
continue
except AttributeError:
print_substep("NSFW settings not defined. Skipping NSFW post...")
print_substep(
"NSFW settings not defined. Skipping NSFW post...")
return submission
print("all submissions have been done going by top submission order")
return get_subreddit_undone(
@ -36,7 +37,7 @@ def get_subreddit_undone(submissions: list, subreddit):
) # 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
Args:
@ -45,7 +46,7 @@ def already_done(done_videos: list, submission)->bool:
Returns:
Boolean: Whether the video was found in the list
"""
"""
for video in done_videos:
if video["id"] == str(submission):

@ -5,8 +5,8 @@ from utils.console import print_step
def check_done(
redditobj:dict[str],
)->dict[str]|None: # don't set this to be run anyplace that isn't subreddit.py bc of inspect stack
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:
@ -25,6 +25,7 @@ def check_done(
"You already have done this video but since it was declared specifically in the .env file the program will continue"
)
return redditobj
print_step("Getting new post as the current one has already been done")
print_step(
"Getting new post as the current one has already been done")
return None
return redditobj

@ -28,13 +28,13 @@ console = Console()
W, H = 1080, 1920
def make_final_video(number_of_clips:int, length:int,final_vid_path:str):
def make_final_video(number_of_clips: int, length: int, final_vid_path: str):
"""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)
@ -49,10 +49,10 @@ def make_final_video(number_of_clips:int, length:int,final_vid_path:str):
try:
opacity = float(os.getenv("OPACITY"))
except (
ValueError,
FloatingPointError,
TypeError
):
ValueError,
FloatingPointError,
TypeError
):
print_substep(
"Please ensure that OPACITY is between 0 and 1 in .env file", style_="bold red"
)
@ -66,16 +66,15 @@ def make_final_video(number_of_clips:int, length:int,final_vid_path:str):
try:
audio_clips.insert(1, AudioFileClip("assets/mp3/posttext.mp3"))
except (
OSError,
FileNotFoundError,
):
OSError,
FileNotFoundError,
):
print_substep("An error occured! Aborting.", style_="bold red")
raise SystemExit()
else:
audio_concat = concatenate_audioclips(audio_clips)
audio_composite = CompositeAudioClip([audio_concat])
# Get sum of all clip lengths
total_length = sum([clip.duration for clip in audio_clips])
# round total_length to an integer
@ -142,13 +141,12 @@ def make_final_video(number_of_clips:int, length:int,final_vid_path:str):
final = CompositeVideoClip([background_clip, image_concat])
if final_vid_path is None:
final_vid_path = re.sub(
final_vid_path = re.sub(
"[?\"%*:|<>]/", "", (f"assets/{subreddit.submission.title}.mp4")
)
final.write_videofile(final_vid_path, fps=30, audio_codec="aac", audio_bitrate="192k")
final.write_videofile(final_vid_path, fps=30,
audio_codec="aac", audio_bitrate="192k")
save_data(final_vid_path)
@ -177,12 +175,13 @@ def make_final_video(number_of_clips:int, length:int,final_vid_path:str):
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
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]:
@ -198,12 +197,13 @@ def save_data(filename:str):
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

@ -27,7 +27,7 @@ TTSProviders = {
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.
Args:
@ -36,7 +36,7 @@ def save_text_to_mp3(reddit_obj:dict[str])->tuple[int,int]:
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(

Loading…
Cancel
Save