From 9ca1ae8476acb3232b267c50d485142fab78b460 Mon Sep 17 00:00:00 2001 From: Jo <42.jochang@gmail.com> Date: Fri, 1 Sep 2023 10:16:46 -0700 Subject: [PATCH 01/20] fix: Fixes #1812, random_voice True/False acceptance --- utils/.config.template.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index accf86d..211cc97 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -44,7 +44,7 @@ background_thumbnail_font_color = { optional = true, default = "255,255,255", ex [settings.tts] voice_choice = { optional = false, default = "tiktok", options = ["elevenlabs", "streamlabspolly", "tiktok", "googletranslate", "awspolly", "pyttsx", ], example = "tiktok", explanation = "The voice platform used for TTS generation. " } -random_voice = { optional = false, default = true, example = true, options = [true, false,], explanation = "Randomizes the voice used for each comment" } +random_voice = { optional = false, type = "bool", default = true, example = true, options = [true, false,], explanation = "Randomizes the voice used for each comment" } elevenlabs_voice_name = { optional = false, default = "Bella", example = "Bella", explanation = "The voice used for elevenlabs", options = ["Adam", "Antoni", "Arnold", "Bella", "Domi", "Elli", "Josh", "Rachel", "Sam", ] } elevenlabs_api_key = { optional = true, example = "21f13f91f54d741e2ae27d2ab1b99d59", explanation = "Elevenlabs API key" } aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" } From ed97ae4ebbb53b1a18fb68a2eb416549b2ae8b27 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 3 Sep 2023 17:22:55 -0400 Subject: [PATCH 02/20] fix: fixed the GUI chore: reformatted and optimized imports. Co-authored-by: Jan Tumpa --- GUI.py | 4 +- GUI/settings.html | 4 +- TTS/TikTok.py | 4 +- TTS/aws_polly.py | 4 +- TTS/elevenlabs.py | 8 ++- TTS/engine_wrapper.py | 25 ++++--- TTS/pyttsx.py | 4 +- TTS/streamlabs_polly.py | 4 +- main.py | 9 ++- reddit/subreddit.py | 33 ++++++--- utils/ai_methods.py | 22 ++++-- utils/cleanup.py | 2 +- utils/console.py | 17 ++++- utils/ffmpeg_install.py | 23 ++++--- utils/gui_utils.py | 22 ++++-- utils/imagenarator.py | 19 +++-- utils/playwright.py | 4 +- utils/settings.py | 35 ++++++++-- utils/subreddit.py | 21 ++++-- utils/thumbnail.py | 12 +++- utils/videos.py | 8 ++- utils/voice.py | 6 +- video_creation/background.py | 15 ++-- video_creation/final_video.py | 92 ++++++++++++++++++------- video_creation/screenshot_downloader.py | 42 +++++++---- video_creation/voices.py | 16 +++-- 26 files changed, 329 insertions(+), 126 deletions(-) diff --git a/GUI.py b/GUI.py index 4588083..47dfc25 100644 --- a/GUI.py +++ b/GUI.py @@ -82,7 +82,9 @@ def settings(): # Change settings config = gui.modify_settings(data, config_load, checks) - return render_template("settings.html", file="config.toml", data=config, checks=checks) + return render_template( + "settings.html", file="config.toml", data=config, checks=checks + ) # Make videos.json accessible diff --git a/GUI/settings.html b/GUI/settings.html index 1f0ef2e..f3f1751 100644 --- a/GUI/settings.html +++ b/GUI/settings.html @@ -205,7 +205,7 @@ @@ -618,4 +618,4 @@ }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/TTS/TikTok.py b/TTS/TikTok.py index 29542e2..3c83e9a 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -86,7 +86,9 @@ class TikTok: "Cookie": f"sessionid={settings.config['settings']['tts']['tiktok_sessionid']}", } - self.URI_BASE = "https://api16-normal-c-useast1a.tiktokv.com/media/api/text/speech/invoke/" + self.URI_BASE = ( + "https://api16-normal-c-useast1a.tiktokv.com/media/api/text/speech/invoke/" + ) self.max_chars = 200 self._session = requests.Session() diff --git a/TTS/aws_polly.py b/TTS/aws_polly.py index 4d55860..58323f9 100644 --- a/TTS/aws_polly.py +++ b/TTS/aws_polly.py @@ -41,7 +41,9 @@ class AWSPolly: raise ValueError( f"Please set the TOML variable AWS_VOICE to a valid voice. options are: {voices}" ) - voice = str(settings.config["settings"]["tts"]["aws_polly_voice"]).capitalize() + voice = str( + settings.config["settings"]["tts"]["aws_polly_voice"] + ).capitalize() try: # Request speech synthesis response = polly.synthesize_speech( diff --git a/TTS/elevenlabs.py b/TTS/elevenlabs.py index e18bba9..ab6dbb0 100644 --- a/TTS/elevenlabs.py +++ b/TTS/elevenlabs.py @@ -26,7 +26,9 @@ class elevenlabs: if random_voice: voice = self.randomvoice() else: - voice = str(settings.config["settings"]["tts"]["elevenlabs_voice_name"]).capitalize() + voice = str( + settings.config["settings"]["tts"]["elevenlabs_voice_name"] + ).capitalize() if settings.config["settings"]["tts"]["elevenlabs_api_key"]: api_key = settings.config["settings"]["tts"]["elevenlabs_api_key"] @@ -35,7 +37,9 @@ class elevenlabs: "You didn't set an Elevenlabs API key! Please set the config variable ELEVENLABS_API_KEY to a valid API key." ) - audio = generate(api_key=api_key, text=text, voice=voice, model="eleven_multilingual_v1") + audio = generate( + api_key=api_key, text=text, voice=voice, model="eleven_multilingual_v1" + ) save(audio=audio, filename=filepath) def randomvoice(self): diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index 7a73d61..a78aef7 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -14,10 +14,7 @@ from utils import settings from utils.console import print_step, print_substep from utils.voice import sanitize_text - -DEFAULT_MAX_LENGTH: int = ( - 50 # Video length variable, edit this on your own risk. It should work, but it's not supported -) +DEFAULT_MAX_LENGTH: int = 50 # Video length variable, edit this on your own risk. It should work, but it's not supported class TTSEngine: @@ -60,7 +57,9 @@ class TTSEngine: comment["comment_body"] = re.sub(regex_urls, " ", comment["comment_body"]) comment["comment_body"] = comment["comment_body"].replace("\n", ". ") comment["comment_body"] = re.sub(r"\bAI\b", "A.I", comment["comment_body"]) - comment["comment_body"] = re.sub(r"\bAGI\b", "A.G.I", comment["comment_body"]) + comment["comment_body"] = re.sub( + r"\bAGI\b", "A.G.I", comment["comment_body"] + ) if comment["comment_body"][-1] != ".": comment["comment_body"] += "." comment["comment_body"] = comment["comment_body"].replace(". . .", ".") @@ -82,13 +81,17 @@ class TTSEngine: if len(self.reddit_object["thread_post"]) > self.tts_module.max_chars: self.split_post(self.reddit_object["thread_post"], "postaudio") else: - self.call_tts("postaudio", process_text(self.reddit_object["thread_post"])) + self.call_tts( + "postaudio", process_text(self.reddit_object["thread_post"]) + ) elif settings.config["settings"]["storymodemethod"] == 1: for idx, text in track(enumerate(self.reddit_object["thread_post"])): self.call_tts(f"postaudio-{idx}", process_text(text)) else: - for idx, comment in track(enumerate(self.reddit_object["comments"]), "Saving..."): + for idx, comment in track( + enumerate(self.reddit_object["comments"]), "Saving..." + ): # ! Stop creating mp3 files if the length is greater than max length. if self.length > self.max_length and idx > 1: self.length -= self.last_clip_length @@ -171,7 +174,9 @@ class TTSEngine: fps=44100, ) silence = volumex(silence, 0) - silence.write_audiofile(f"{self.path}/silence.mp3", fps=44100, verbose=False, logger=None) + silence.write_audiofile( + f"{self.path}/silence.mp3", fps=44100, verbose=False, logger=None + ) def process_text(text: str, clean: bool = True): @@ -179,6 +184,8 @@ def process_text(text: str, clean: bool = True): new_text = sanitize_text(text) if clean else text if lang: print_substep("Translating Text...") - translated_text = translators.translate_text(text, translator="google", to_language=lang) + translated_text = translators.translate_text( + text, translator="google", to_language=lang + ) new_text = sanitize_text(translated_text) return new_text diff --git a/TTS/pyttsx.py b/TTS/pyttsx.py index bf47601..a80bf2d 100644 --- a/TTS/pyttsx.py +++ b/TTS/pyttsx.py @@ -21,7 +21,9 @@ class pyttsx: if voice_id == "" or voice_num == "": voice_id = 2 voice_num = 3 - raise ValueError("set pyttsx values to a valid value, switching to defaults") + raise ValueError( + "set pyttsx values to a valid value, switching to defaults" + ) else: voice_id = int(voice_id) voice_num = int(voice_num) diff --git a/TTS/streamlabs_polly.py b/TTS/streamlabs_polly.py index dc80dc9..721dd78 100644 --- a/TTS/streamlabs_polly.py +++ b/TTS/streamlabs_polly.py @@ -42,7 +42,9 @@ class StreamlabsPolly: raise ValueError( f"Please set the config variable STREAMLABS_POLLY_VOICE to a valid voice. options are: {voices}" ) - voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize() + voice = str( + settings.config["settings"]["tts"]["streamlabs_polly_voice"] + ).capitalize() body = {"voice": voice, "text": text, "service": "polly"} response = requests.post(self.url, data=body) if not check_ratelimit(response): diff --git a/main.py b/main.py index efaa51c..8eff308 100755 --- a/main.py +++ b/main.py @@ -7,11 +7,13 @@ from subprocess import Popen from typing import NoReturn from prawcore import ResponseException -from utils.console import print_substep + from reddit.subreddit import get_subreddit_threads from utils import settings from utils.cleanup import cleanup from utils.console import print_markdown, print_step +from utils.console import print_substep +from utils.ffmpeg_install import ffmpeg_install from utils.id import id from utils.version import checkversion from video_creation.background import ( @@ -23,7 +25,6 @@ from video_creation.background import ( from video_creation.final_video import make_final_video from video_creation.screenshot_downloader import get_screenshots_of_reddit_posts from video_creation.voices import save_text_to_mp3 -from utils.ffmpeg_install import ffmpeg_install __VERSION__ = "3.2.1" @@ -103,7 +104,9 @@ if __name__ == "__main__": sys.exit() try: if config["reddit"]["thread"]["post_id"]: - for index, post_id in enumerate(config["reddit"]["thread"]["post_id"].split("+")): + for index, post_id in enumerate( + config["reddit"]["thread"]["post_id"].split("+") + ): index += 1 print_step( f'on the {index}{("st" if index % 10 == 1 else ("nd" if index % 10 == 2 else ("rd" if index % 10 == 3 else "th")))} post of {len(config["reddit"]["thread"]["post_id"].split("+"))}' diff --git a/reddit/subreddit.py b/reddit/subreddit.py index e1def23..f2f8419 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -1,18 +1,16 @@ import re -from prawcore.exceptions import ResponseException - -from utils import settings import praw from praw.models import MoreComments from prawcore.exceptions import ResponseException +from utils import settings +from utils.ai_methods import sort_by_similarity from utils.console import print_step, print_substep +from utils.posttextparser import posttextparser from utils.subreddit import get_subreddit_undone from utils.videos import check_done from utils.voice import sanitize_text -from utils.posttextparser import posttextparser -from utils.ai_methods import sort_by_similarity def get_subreddit_threads(POST_ID: str): @@ -24,7 +22,9 @@ def get_subreddit_threads(POST_ID: str): content = {} if settings.config["reddit"]["creds"]["2fa"]: - print("\nEnter your two-factor authentication code from your authenticator app.\n") + print( + "\nEnter your two-factor authentication code from your authenticator app.\n" + ) code = input("> ") print() pw = settings.config["reddit"]["creds"]["password"] @@ -57,7 +57,9 @@ def get_subreddit_threads(POST_ID: str): ]: # note to user. you can have multiple subreddits via reddit.subreddit("redditdev+learnpython") try: subreddit = reddit.subreddit( - re.sub(r"r\/", "", input("What subreddit would you like to pull from? ")) + re.sub( + r"r\/", "", input("What subreddit would you like to pull from? ") + ) # removes the r/ from the input ) except ValueError: @@ -67,7 +69,9 @@ def get_subreddit_threads(POST_ID: str): sub = settings.config["reddit"]["thread"]["subreddit"] print_substep(f"Using subreddit: r/{sub} from TOML config") subreddit_choice = sub - if str(subreddit_choice).casefold().startswith("r/"): # removes the r/ from the input + if ( + str(subreddit_choice).casefold().startswith("r/") + ): # removes the r/ from the input subreddit_choice = subreddit_choice[2:] subreddit = reddit.subreddit(subreddit_choice) @@ -78,8 +82,12 @@ def get_subreddit_threads(POST_ID: str): settings.config["reddit"]["thread"]["post_id"] and len(str(settings.config["reddit"]["thread"]["post_id"]).split("+")) == 1 ): - submission = reddit.submission(id=settings.config["reddit"]["thread"]["post_id"]) - elif settings.config["ai"]["ai_similarity_enabled"]: # ai sorting based on comparison + submission = reddit.submission( + id=settings.config["reddit"]["thread"]["post_id"] + ) + elif settings.config["ai"][ + "ai_similarity_enabled" + ]: # ai sorting based on comparison threads = subreddit.hot(limit=50) keywords = settings.config["ai"]["ai_similarity_keywords"].split(",") keywords = [keyword.strip() for keyword in keywords] @@ -97,7 +105,10 @@ def get_subreddit_threads(POST_ID: str): if submission is None: return get_subreddit_threads(POST_ID) # submission already done. rerun - elif not submission.num_comments and settings.config["settings"]["storymode"] == "false": + elif ( + not submission.num_comments + and settings.config["settings"]["storymode"] == "false" + ): print_substep("No comments found. Skipping.") exit() diff --git a/utils/ai_methods.py b/utils/ai_methods.py index ed1d559..7f64570 100644 --- a/utils/ai_methods.py +++ b/utils/ai_methods.py @@ -1,12 +1,16 @@ import numpy as np -from transformers import AutoTokenizer, AutoModel import torch +from transformers import AutoTokenizer, AutoModel # Mean Pooling - Take attention mask into account for correct averaging def mean_pooling(model_output, attention_mask): - token_embeddings = model_output[0] # First element of model_output contains all token embeddings - input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float() + token_embeddings = model_output[ + 0 + ] # First element of model_output contains all token embeddings + input_mask_expanded = ( + attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float() + ) return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp( input_mask_expanded.sum(1), min=1e-9 ) @@ -32,13 +36,19 @@ def sort_by_similarity(thread_objects, keywords): ) with torch.no_grad(): threads_embeddings = model(**encoded_threads) - threads_embeddings = mean_pooling(threads_embeddings, encoded_threads["attention_mask"]) + threads_embeddings = mean_pooling( + threads_embeddings, encoded_threads["attention_mask"] + ) # Keywords inference - encoded_keywords = tokenizer(keywords, padding=True, truncation=True, return_tensors="pt") + encoded_keywords = tokenizer( + keywords, padding=True, truncation=True, return_tensors="pt" + ) with torch.no_grad(): keywords_embeddings = model(**encoded_keywords) - keywords_embeddings = mean_pooling(keywords_embeddings, encoded_keywords["attention_mask"]) + keywords_embeddings = mean_pooling( + keywords_embeddings, encoded_keywords["attention_mask"] + ) # Compare every keyword w/ every thread embedding threads_embeddings_tensor = torch.tensor(threads_embeddings) diff --git a/utils/cleanup.py b/utils/cleanup.py index 6e00d4c..8c73b15 100644 --- a/utils/cleanup.py +++ b/utils/cleanup.py @@ -1,6 +1,6 @@ import os -from os.path import exists import shutil +from os.path import exists def _listdir(d): # listdir with full path diff --git a/utils/console.py b/utils/console.py index 18c3248..7ac8a70 100644 --- a/utils/console.py +++ b/utils/console.py @@ -49,7 +49,10 @@ def handle_input( optional=False, ): if optional: - console.print(message + "\n[green]This is an optional value. Do you want to skip it? (y/n)") + console.print( + message + + "\n[green]This is an optional value. Do you want to skip it? (y/n)" + ) if input().casefold().startswith("y"): return default if default is not NotImplemented else "" if default is not NotImplemented: @@ -83,7 +86,11 @@ def handle_input( console.print("[red]" + err_message) continue elif match != "" and re.match(match, user_input) is None: - console.print("[red]" + err_message + "\nAre you absolutely sure it's correct?(y/n)") + console.print( + "[red]" + + err_message + + "\nAre you absolutely sure it's correct?(y/n)" + ) if input().casefold().startswith("y"): break continue @@ -116,5 +123,9 @@ def handle_input( if user_input in options: return user_input console.print( - "[red bold]" + err_message + "\nValid options are: " + ", ".join(map(str, options)) + "." + "[red bold]" + + err_message + + "\nValid options are: " + + ", ".join(map(str, options)) + + "." ) diff --git a/utils/ffmpeg_install.py b/utils/ffmpeg_install.py index 7d5b3ad..b29301f 100644 --- a/utils/ffmpeg_install.py +++ b/utils/ffmpeg_install.py @@ -1,14 +1,13 @@ -import zipfile -import requests import os import subprocess +import zipfile + +import requests def ffmpeg_install_windows(): try: - ffmpeg_url = ( - "https://github.com/GyanD/codexffmpeg/releases/download/6.0/ffmpeg-6.0-full_build.zip" - ) + ffmpeg_url = "https://github.com/GyanD/codexffmpeg/releases/download/6.0/ffmpeg-6.0-full_build.zip" ffmpeg_zip_filename = "ffmpeg.zip" ffmpeg_extracted_folder = "ffmpeg" @@ -39,7 +38,10 @@ def ffmpeg_install_windows(): # Rename and move files os.rename(f"{ffmpeg_extracted_folder}-6.0-full_build", ffmpeg_extracted_folder) for file in os.listdir(os.path.join(ffmpeg_extracted_folder, "bin")): - os.rename(os.path.join(ffmpeg_extracted_folder, "bin", file), os.path.join(".", file)) + os.rename( + os.path.join(ffmpeg_extracted_folder, "bin", file), + os.path.join(".", file), + ) os.rmdir(os.path.join(ffmpeg_extracted_folder, "bin")) for file in os.listdir(os.path.join(ffmpeg_extracted_folder, "doc")): os.remove(os.path.join(ffmpeg_extracted_folder, "doc", file)) @@ -101,7 +103,10 @@ def ffmpeg_install(): try: # Try to run the FFmpeg command subprocess.run( - ["ffmpeg", "-version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ["ffmpeg", "-version"], + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, ) except FileNotFoundError as e: # Check if there's ffmpeg.exe in the current directory @@ -122,7 +127,9 @@ def ffmpeg_install(): elif os.name == "mac": ffmpeg_install_mac() else: - print("Your OS is not supported. Please install FFmpeg manually and try again.") + print( + "Your OS is not supported. Please install FFmpeg manually and try again." + ) exit() else: print("Please install FFmpeg manually and try again.") diff --git a/utils/gui_utils.py b/utils/gui_utils.py index f683adf..9d644d8 100644 --- a/utils/gui_utils.py +++ b/utils/gui_utils.py @@ -67,7 +67,11 @@ def check(value, checks): and not hasattr(value, "__iter__") and ( ("nmin" in checks and checks["nmin"] is not None and value < checks["nmin"]) - or ("nmax" in checks and checks["nmax"] is not None and value > checks["nmax"]) + or ( + "nmax" in checks + and checks["nmax"] is not None + and value > checks["nmax"] + ) ) ): incorrect = True @@ -76,8 +80,16 @@ def check(value, checks): not incorrect and hasattr(value, "__iter__") and ( - ("nmin" in checks and checks["nmin"] is not None and len(value) < checks["nmin"]) - or ("nmax" in checks and checks["nmax"] is not None and len(value) > checks["nmax"]) + ( + "nmin" in checks + and checks["nmin"] is not None + and len(value) < checks["nmin"] + ) + or ( + "nmax" in checks + and checks["nmax"] is not None + and len(value) > checks["nmax"] + ) ) ): incorrect = True @@ -150,7 +162,9 @@ def delete_background(key): # Add background video def add_background(youtube_uri, filename, citation, position): # Validate YouTube URI - regex = re.compile(r"(?:\/|%3D|v=|vi=)([0-9A-z\-_]{11})(?:[%#?&]|$)").search(youtube_uri) + regex = re.compile(r"(?:\/|%3D|v=|vi=)([0-9A-z\-_]{11})(?:[%#?&]|$)").search( + youtube_uri + ) if not regex: flash("YouTube URI is invalid!", "error") diff --git a/utils/imagenarator.py b/utils/imagenarator.py index 9356540..06bbd69 100644 --- a/utils/imagenarator.py +++ b/utils/imagenarator.py @@ -1,9 +1,10 @@ +import os import re import textwrap -import os from PIL import Image, ImageDraw, ImageFont from rich.progress import track + from TTS.engine_wrapper import process_text @@ -17,7 +18,9 @@ def draw_multiple_line_text( Fontperm = font.getsize(text) image_width, image_height = image.size lines = textwrap.wrap(text, width=wrap) - y = (image_height / 2) - (((Fontperm[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2) + y = (image_height / 2) - ( + ((Fontperm[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2 + ) for line in lines: line_width, line_height = font.getsize(line) if transparent: @@ -63,19 +66,25 @@ def imagemaker(theme, reddit_obj: dict, txtclr, padding=5, transparent=False) -> font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100) tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100) else: - tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100) # for title + tfont = ImageFont.truetype( + os.path.join("fonts", "Roboto-Bold.ttf"), 100 + ) # for title font = ImageFont.truetype(os.path.join("fonts", "Roboto-Regular.ttf"), 100) size = (1920, 1080) image = Image.new("RGBA", size, theme) # for title - draw_multiple_line_text(image, title, tfont, txtclr, padding, wrap=30, transparent=transparent) + draw_multiple_line_text( + image, title, tfont, txtclr, padding, wrap=30, transparent=transparent + ) image.save(f"assets/temp/{id}/png/title.png") for idx, text in track(enumerate(texts), "Rendering Image"): image = Image.new("RGBA", size, theme) text = process_text(text, False) - draw_multiple_line_text(image, text, font, txtclr, padding, wrap=30, transparent=transparent) + draw_multiple_line_text( + image, text, font, txtclr, padding, wrap=30, transparent=transparent + ) image.save(f"assets/temp/{id}/png/img{idx}.png") diff --git a/utils/playwright.py b/utils/playwright.py index 9672f03..be046e6 100644 --- a/utils/playwright.py +++ b/utils/playwright.py @@ -1,5 +1,7 @@ def clear_cookie_by_name(context, cookie_cleared_name): cookies = context.cookies() - filtered_cookies = [cookie for cookie in cookies if cookie["name"] != cookie_cleared_name] + filtered_cookies = [ + cookie for cookie in cookies if cookie["name"] != cookie_cleared_name + ] context.clear_cookies() context.add_cookies(filtered_cookies) diff --git a/utils/settings.py b/utils/settings.py index 60efedb..e2db508 100755 --- a/utils/settings.py +++ b/utils/settings.py @@ -1,6 +1,7 @@ import re -from typing import Tuple, Dict from pathlib import Path +from typing import Tuple, Dict + import toml from rich.console import Console @@ -52,7 +53,11 @@ def check(value, checks, name): and not hasattr(value, "__iter__") and ( ("nmin" in checks and checks["nmin"] is not None and value < checks["nmin"]) - or ("nmax" in checks and checks["nmax"] is not None and value > checks["nmax"]) + or ( + "nmax" in checks + and checks["nmax"] is not None + and value > checks["nmax"] + ) ) ): incorrect = True @@ -60,8 +65,16 @@ def check(value, checks, name): not incorrect and hasattr(value, "__iter__") and ( - ("nmin" in checks and checks["nmin"] is not None and len(value) < checks["nmin"]) - or ("nmax" in checks and checks["nmax"] is not None and len(value) > checks["nmax"]) + ( + "nmin" in checks + and checks["nmin"] is not None + and len(value) < checks["nmin"] + ) + or ( + "nmax" in checks + and checks["nmax"] is not None + and len(value) > checks["nmax"] + ) ) ): incorrect = True @@ -69,9 +82,15 @@ def check(value, checks, name): if incorrect: value = handle_input( message=( - (("[blue]Example: " + str(checks["example"]) + "\n") if "example" in checks else "") + ( + ("[blue]Example: " + str(checks["example"]) + "\n") + if "example" in checks + else "" + ) + "[red]" - + ("Non-optional ", "Optional ")["optional" in checks and checks["optional"] is True] + + ("Non-optional ", "Optional ")[ + "optional" in checks and checks["optional"] is True + ] ) + "[#C0CAF5 bold]" + str(name) @@ -112,7 +131,9 @@ def check_toml(template_file, config_file) -> Tuple[bool, Dict]: try: template = toml.load(template_file) except Exception as error: - console.print(f"[red bold]Encountered error when trying to to load {template_file}: {error}") + console.print( + f"[red bold]Encountered error when trying to to load {template_file}: {error}" + ) return False try: config = toml.load(config_file) diff --git a/utils/subreddit.py b/utils/subreddit.py index f8e60ed..a3732f6 100644 --- a/utils/subreddit.py +++ b/utils/subreddit.py @@ -2,11 +2,13 @@ import json from os.path import exists from utils import settings -from utils.console import print_substep from utils.ai_methods import sort_by_similarity +from utils.console import print_substep -def get_subreddit_undone(submissions: list, subreddit, times_checked=0, similarity_scores=None): +def get_subreddit_undone( + submissions: list, subreddit, times_checked=0, similarity_scores=None +): """_summary_ Args: @@ -18,7 +20,9 @@ def get_subreddit_undone(submissions: list, subreddit, times_checked=0, similari """ # Second try of getting a valid Submission if times_checked and settings.config["ai"]["ai_similarity_enabled"]: - print("Sorting based on similarity for a different date filter and thread limit..") + print( + "Sorting based on similarity for a different date filter and thread limit.." + ) submissions = sort_by_similarity( submissions, keywords=settings.config["ai"]["ai_similarity_enabled"] ) @@ -27,7 +31,9 @@ def get_subreddit_undone(submissions: list, subreddit, times_checked=0, similari if not exists("./video_creation/data/videos.json"): with open("./video_creation/data/videos.json", "w+") as f: json.dump([], f) - with open("./video_creation/data/videos.json", "r", encoding="utf-8") as done_vids_raw: + with open( + "./video_creation/data/videos.json", "r", encoding="utf-8" + ) as done_vids_raw: done_videos = json.load(done_vids_raw) for i, submission in enumerate(submissions): if already_done(done_videos, submission): @@ -43,7 +49,8 @@ def get_subreddit_undone(submissions: list, subreddit, times_checked=0, similari print_substep("This post was pinned by moderators. Skipping...") continue if ( - submission.num_comments <= int(settings.config["reddit"]["thread"]["min_comments"]) + submission.num_comments + <= int(settings.config["reddit"]["thread"]["min_comments"]) and not settings.config["settings"]["storymode"] ): print_substep( @@ -52,7 +59,9 @@ def get_subreddit_undone(submissions: list, subreddit, times_checked=0, similari continue if settings.config["settings"]["storymode"]: if not submission.selftext: - print_substep("You are trying to use story mode on post with no post text") + print_substep( + "You are trying to use story mode on post with no post text" + ) continue else: # Check for the length of the post text diff --git a/utils/thumbnail.py b/utils/thumbnail.py index 172b454..aeb82b4 100644 --- a/utils/thumbnail.py +++ b/utils/thumbnail.py @@ -1,11 +1,15 @@ from PIL import ImageDraw, ImageFont -def create_thumbnail(thumbnail, font_family, font_size, font_color, width, height, title): +def create_thumbnail( + thumbnail, font_family, font_size, font_color, width, height, title +): font = ImageFont.truetype(font_family + ".ttf", font_size) Xaxis = width - (width * 0.2) # 20% of the width sizeLetterXaxis = font_size * 0.5 # 50% of the font size - XaxisLetterQty = round(Xaxis / sizeLetterXaxis) # Quantity of letters that can fit in the X axis + XaxisLetterQty = round( + Xaxis / sizeLetterXaxis + ) # Quantity of letters that can fit in the X axis MarginYaxis = height * 0.12 # 12% of the height MarginXaxis = width * 0.05 # 5% of the width # 1.1 rem @@ -30,6 +34,8 @@ def create_thumbnail(thumbnail, font_family, font_size, font_color, width, heigh # loop for put the title in the thumbnail for i in range(0, len(arrayTitle)): # 1.1 rem - draw.text((MarginXaxis, MarginYaxis + (LineHeight * i)), arrayTitle[i], rgb, font=font) + draw.text( + (MarginXaxis, MarginYaxis + (LineHeight * i)), arrayTitle[i], rgb, font=font + ) return thumbnail diff --git a/utils/videos.py b/utils/videos.py index 7c756fc..c30cb2c 100755 --- a/utils/videos.py +++ b/utils/videos.py @@ -19,7 +19,9 @@ def check_done( Returns: Submission|None: Reddit object in args """ - with open("./video_creation/data/videos.json", "r", encoding="utf-8") as done_vids_raw: + with open( + "./video_creation/data/videos.json", "r", encoding="utf-8" + ) as done_vids_raw: done_videos = json.load(done_vids_raw) for video in done_videos: if video["id"] == str(redditobj): @@ -33,7 +35,9 @@ def check_done( return redditobj -def save_data(subreddit: str, filename: str, reddit_title: str, reddit_id: str, credit: str): +def save_data( + subreddit: str, filename: str, reddit_title: str, reddit_id: str, credit: str +): """Saves the videos that have already been generated to a JSON file in video_creation/data/videos.json Args: diff --git a/utils/voice.py b/utils/voice.py index 37933ae..9bc09d8 100644 --- a/utils/voice.py +++ b/utils/voice.py @@ -4,10 +4,10 @@ import time as pytime from datetime import datetime from time import sleep +from cleantext import clean from requests import Response from utils import settings -from cleantext import clean if sys.version_info[0] >= 3: from datetime import timezone @@ -43,7 +43,9 @@ def sleep_until(time) -> None: if sys.version_info[0] >= 3 and time.tzinfo: end = time.astimezone(timezone.utc).timestamp() else: - zoneDiff = pytime.time() - (datetime.now() - datetime(1970, 1, 1)).total_seconds() + zoneDiff = ( + pytime.time() - (datetime.now() - datetime(1970, 1, 1)).total_seconds() + ) end = (time - datetime(1970, 1, 1)).total_seconds() + zoneDiff # Type check diff --git a/video_creation/background.py b/video_creation/background.py index 8c15b40..3683bb5 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -5,11 +5,12 @@ from pathlib import Path from random import randrange from typing import Any, Tuple, Dict +import yt_dlp from moviepy.editor import VideoFileClip, AudioFileClip from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip + from utils import settings from utils.console import print_step, print_substep -import yt_dlp def load_background_options(): @@ -59,7 +60,9 @@ def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int def get_background_config(mode: str): """Fetch the background/s configuration""" try: - choice = str(settings.config["settings"]["background"][f"background_{mode}"]).casefold() + choice = str( + settings.config["settings"]["background"][f"background_{mode}"] + ).casefold() except AttributeError: print_substep("No background selected. Picking random background'") choice = None @@ -119,7 +122,9 @@ def download_background_audio(background_config: Tuple[str, str, str]): print_substep("Background audio downloaded successfully! 🎉", style="bold green") -def chop_background(background_config: Dict[str, Tuple], video_length: int, reddit_object: dict): +def chop_background( + background_config: Dict[str, Tuple], video_length: int, reddit_object: dict +): """Generates the background audio and footage to be used in the video and writes it to assets/temp/background.mp3 and assets/temp/background.mp4 Args: @@ -132,7 +137,9 @@ def chop_background(background_config: Dict[str, Tuple], video_length: int, redd print_step("Volume was set to 0. Skipping background audio creation . . .") else: print_step("Finding a spot in the backgrounds audio to chop...✂️") - audio_choice = f"{background_config['audio'][2]}-{background_config['audio'][1]}" + audio_choice = ( + f"{background_config['audio'][2]}-{background_config['audio'][1]}" + ) background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") start_time_audio, end_time_audio = get_start_and_end_times( video_length, background_audio.duration diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 84ca249..0739df8 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -1,9 +1,12 @@ import multiprocessing import os import re +import tempfile +import threading +import time from os.path import exists # Needs to be imported specifically from typing import Final -from typing import Tuple, Any, Dict +from typing import Tuple, Dict import ffmpeg import translators @@ -11,15 +14,11 @@ from PIL import Image from rich.console import Console from rich.progress import track +from utils import settings from utils.cleanup import cleanup from utils.console import print_step, print_substep from utils.thumbnail import create_thumbnail from utils.videos import save_data -from utils import settings - -import tempfile -import threading -import time console = Console() @@ -76,7 +75,9 @@ def name_normalize(name: str) -> str: lang = settings.config["reddit"]["thread"]["post_lang"] if lang: print_substep("Translating filename...") - translated_name = translators.translate_text(name, translator="google", to_language=lang) + translated_name = translators.translate_text( + name, translator="google", to_language=lang + ) return translated_name else: return name @@ -113,7 +114,9 @@ def merge_background_audio(audio: ffmpeg, reddit_id: str): audio (ffmpeg): The TTS final audio but without background. reddit_id (str): The ID of subreddit """ - background_audio_volume = settings.config["settings"]["background"]["background_audio_volume"] + background_audio_volume = settings.config["settings"]["background"][ + "background_audio_volume" + ] if background_audio_volume == 0: return audio # Return the original audio else: @@ -167,27 +170,42 @@ def make_final_video( if settings.config["settings"]["storymode"]: if settings.config["settings"]["storymodemethod"] == 0: audio_clips = [ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")] - audio_clips.insert(1, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio.mp3")) + audio_clips.insert( + 1, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio.mp3") + ) elif settings.config["settings"]["storymodemethod"] == 1: audio_clips = [ ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3") - for i in track(range(number_of_clips + 1), "Collecting the audio files...") + for i in track( + range(number_of_clips + 1), "Collecting the audio files..." + ) ] - audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")) + audio_clips.insert( + 0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3") + ) else: audio_clips = [ - ffmpeg.input(f"assets/temp/{reddit_id}/mp3/{i}.mp3") for i in range(number_of_clips) + ffmpeg.input(f"assets/temp/{reddit_id}/mp3/{i}.mp3") + for i in range(number_of_clips) ] audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")) audio_clips_durations = [ - float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/{i}.mp3")["format"]["duration"]) + float( + ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/{i}.mp3")["format"][ + "duration" + ] + ) for i in range(number_of_clips) ] audio_clips_durations.insert( 0, - float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"]["duration"]), + float( + ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"][ + "duration" + ] + ), ) audio_concat = ffmpeg.concat(*audio_clips, a=1, v=0) ffmpeg.output( @@ -213,13 +231,19 @@ def make_final_video( if settings.config["settings"]["storymode"]: audio_clips_durations = [ float( - ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")["format"]["duration"] + ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")[ + "format" + ]["duration"] ) for i in range(number_of_clips) ] audio_clips_durations.insert( 0, - float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"]["duration"]), + float( + ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"][ + "duration" + ] + ), ) if settings.config["settings"]["storymodemethod"] == 0: image_clips.insert( @@ -236,7 +260,9 @@ def make_final_video( ) current_time += audio_clips_durations[0] elif settings.config["settings"]["storymodemethod"] == 1: - for i in track(range(0, number_of_clips + 1), "Collecting the image files..."): + for i in track( + range(0, number_of_clips + 1), "Collecting the image files..." + ): image_clips.append( ffmpeg.input(f"assets/temp/{reddit_id}/png/img{i}.png")["v"].filter( "scale", screenshot_width, -1 @@ -252,9 +278,9 @@ def make_final_video( else: for i in range(0, number_of_clips + 1): image_clips.append( - ffmpeg.input(f"assets/temp/{reddit_id}/png/comment_{i}.png")["v"].filter( - "scale", screenshot_width, -1 - ) + ffmpeg.input(f"assets/temp/{reddit_id}/png/comment_{i}.png")[ + "v" + ].filter("scale", screenshot_width, -1) ) image_overlay = image_clips[i].filter("colorchannelmixer", aa=opacity) background_clip = background_clip.overlay( @@ -273,11 +299,15 @@ def make_final_video( subreddit = settings.config["reddit"]["thread"]["subreddit"] if not exists(f"./results/{subreddit}"): - print_substep("The 'results' folder could not be found so it was automatically created.") + print_substep( + "The 'results' folder could not be found so it was automatically created." + ) os.makedirs(f"./results/{subreddit}") if not exists(f"./results/{subreddit}/OnlyTTS") and allowOnlyTTSFolder: - print_substep("The 'OnlyTTS' folder could not be found so it was automatically created.") + print_substep( + "The 'OnlyTTS' folder could not be found so it was automatically created." + ) os.makedirs(f"./results/{subreddit}/OnlyTTS") # create a thumbnail for the video @@ -291,7 +321,11 @@ def make_final_video( os.makedirs(f"./results/{subreddit}/thumbnails") # get the first file with the .png extension from assets/backgrounds and use it as a background for the thumbnail first_image = next( - (file for file in os.listdir("assets/backgrounds") if file.endswith(".png")), + ( + file + for file in os.listdir("assets/backgrounds") + if file.endswith(".png") + ), None, ) if first_image is None: @@ -313,7 +347,9 @@ def make_final_video( title_thumb, ) thumbnailSave.save(f"./assets/temp/{reddit_id}/thumbnail.png") - print_substep(f"Thumbnail - Building Thumbnail in assets/temp/{reddit_id}/thumbnail.png") + print_substep( + f"Thumbnail - Building Thumbnail in assets/temp/{reddit_id}/thumbnail.png" + ) text = f"Background by {background_config['video'][2]}" background_clip = ffmpeg.drawtext( @@ -354,7 +390,9 @@ def make_final_video( "b:a": "192k", "threads": multiprocessing.cpu_count(), }, - ).overwrite_output().global_args("-progress", progress.output_file.name).run( + ).overwrite_output().global_args( + "-progress", progress.output_file.name + ).run( quiet=True, overwrite_output=True, capture_stdout=False, @@ -384,7 +422,9 @@ def make_final_video( "b:a": "192k", "threads": multiprocessing.cpu_count(), }, - ).overwrite_output().global_args("-progress", progress.output_file.name).run( + ).overwrite_output().global_args( + "-progress", progress.output_file.name + ).run( quiet=True, overwrite_output=True, capture_stdout=False, diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index cdc8d61..6226adf 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -4,7 +4,6 @@ from pathlib import Path from typing import Dict, Final import translators -from playwright.async_api import async_playwright # pylint: disable=unused-import from playwright.sync_api import ViewportSize, sync_playwright from rich.progress import track @@ -12,7 +11,6 @@ from utils import settings from utils.console import print_step, print_substep from utils.imagenarator import imagemaker from utils.playwright import clear_cookie_by_name - from utils.videos import save_data __all__ = ["download_screenshots_of_reddit_posts"] @@ -38,7 +36,9 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): # set the theme and disable non-essential cookies if settings.config["settings"]["theme"] == "dark": - cookie_file = open("./video_creation/data/cookie-dark-mode.json", encoding="utf-8") + cookie_file = open( + "./video_creation/data/cookie-dark-mode.json", encoding="utf-8" + ) bgcolor = (33, 33, 36, 255) txtcolor = (240, 240, 240) transparent = False @@ -48,15 +48,21 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): bgcolor = (0, 0, 0, 0) txtcolor = (255, 255, 255) transparent = True - cookie_file = open("./video_creation/data/cookie-dark-mode.json", encoding="utf-8") + cookie_file = open( + "./video_creation/data/cookie-dark-mode.json", encoding="utf-8" + ) else: # Switch to dark theme - cookie_file = open("./video_creation/data/cookie-dark-mode.json", encoding="utf-8") + cookie_file = open( + "./video_creation/data/cookie-dark-mode.json", encoding="utf-8" + ) bgcolor = (33, 33, 36, 255) txtcolor = (240, 240, 240) transparent = False else: - cookie_file = open("./video_creation/data/cookie-light-mode.json", encoding="utf-8") + cookie_file = open( + "./video_creation/data/cookie-light-mode.json", encoding="utf-8" + ) bgcolor = (255, 255, 255, 255) txtcolor = (0, 0, 0) transparent = False @@ -100,8 +106,12 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): page.set_viewport_size(ViewportSize(width=1920, height=1080)) page.wait_for_load_state() - page.locator('[name="username"]').fill(settings.config["reddit"]["creds"]["username"]) - page.locator('[name="password"]').fill(settings.config["reddit"]["creds"]["password"]) + page.locator('[name="username"]').fill( + settings.config["reddit"]["creds"]["username"] + ) + page.locator('[name="password"]').fill( + settings.config["reddit"]["creds"]["password"] + ) page.locator("button[class$='m-full-width']").click() page.wait_for_timeout(5000) @@ -182,7 +192,9 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): location[i] = float("{:.2f}".format(location[i] * zoom)) page.screenshot(clip=location, path=postcontentpath) else: - page.locator('[data-test-id="post-content"]').screenshot(path=postcontentpath) + page.locator('[data-test-id="post-content"]').screenshot( + path=postcontentpath + ) except Exception as e: print_substep("Something went wrong!", style="red") resp = input( @@ -196,7 +208,9 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): "green", ) - resp = input("Do you want the error traceback for debugging purposes? (y/n)") + resp = input( + "Do you want the error traceback for debugging purposes? (y/n)" + ) if not resp.casefold().startswith("y"): exit() @@ -241,9 +255,13 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): # zoom the body of the page page.evaluate("document.body.style.zoom=" + str(zoom)) # scroll comment into view - page.locator(f"#t1_{comment['comment_id']}").scroll_into_view_if_needed() + page.locator( + f"#t1_{comment['comment_id']}" + ).scroll_into_view_if_needed() # as zooming the body doesn't change the properties of the divs, we need to adjust for the zoom - location = page.locator(f"#t1_{comment['comment_id']}").bounding_box() + location = page.locator( + f"#t1_{comment['comment_id']}" + ).bounding_box() for i in location: location[i] = float("{:.2f}".format(location[i] * zoom)) page.screenshot( diff --git a/video_creation/voices.py b/video_creation/voices.py index 4d8495b..4b29657 100644 --- a/video_creation/voices.py +++ b/video_creation/voices.py @@ -5,9 +5,9 @@ from rich.console import Console from TTS.GTTS import GTTS from TTS.TikTok import TikTok from TTS.aws_polly import AWSPolly +from TTS.elevenlabs import elevenlabs from TTS.engine_wrapper import TTSEngine from TTS.pyttsx import pyttsx -from TTS.elevenlabs import elevenlabs from TTS.streamlabs_polly import StreamlabsPolly from utils import settings from utils.console import print_table, print_step @@ -36,7 +36,9 @@ def save_text_to_mp3(reddit_obj) -> Tuple[int, int]: voice = settings.config["settings"]["tts"]["voice_choice"] if str(voice).casefold() in map(lambda _: _.casefold(), TTSProviders): - text_to_mp3 = TTSEngine(get_case_insensitive_key_value(TTSProviders, voice), reddit_obj) + text_to_mp3 = TTSEngine( + get_case_insensitive_key_value(TTSProviders, voice), reddit_obj + ) else: while True: print_step("Please choose one of the following TTS providers: ") @@ -45,12 +47,18 @@ def save_text_to_mp3(reddit_obj) -> Tuple[int, int]: if choice.casefold() in map(lambda _: _.casefold(), TTSProviders): break print("Unknown Choice") - text_to_mp3 = TTSEngine(get_case_insensitive_key_value(TTSProviders, choice), reddit_obj) + text_to_mp3 = TTSEngine( + get_case_insensitive_key_value(TTSProviders, choice), reddit_obj + ) return text_to_mp3.run() def get_case_insensitive_key_value(input_dict, key): return next( - (value for dict_key, value in input_dict.items() if dict_key.lower() == key.lower()), + ( + value + for dict_key, value in input_dict.items() + if dict_key.lower() == key.lower() + ), None, ) From 48abe251ec1af92f189232bacc949376f43825db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:02:55 +0000 Subject: [PATCH 03/20] Bump unidecode from 1.3.6 to 1.3.8 Bumps [unidecode](https://github.com/kmike/text-unidecode) from 1.3.6 to 1.3.8. - [Release notes](https://github.com/kmike/text-unidecode/releases) - [Commits](https://github.com/kmike/text-unidecode/commits) --- updated-dependencies: - dependency-name: unidecode dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c9abc85..aada5cc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ Pillow==9.5.0 tomlkit==0.11.8 Flask==2.3.3 clean-text==0.6.0 -unidecode==1.3.6 +unidecode==1.3.8 spacy==3.5.3 torch==2.0.1 transformers==4.29.2 From 6d19bd1f5c8bf1a334aa75e5f1727de224d8d56b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 01:42:08 +0000 Subject: [PATCH 04/20] Bump pillow from 9.5.0 to 10.2.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.5.0 to 10.2.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/9.5.0...10.2.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index aada5cc..fd8b51b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ rich==13.4.1 toml==0.10.2 translators==5.7.6 pyttsx3==2.90 -Pillow==9.5.0 +Pillow==10.2.0 tomlkit==0.11.8 Flask==2.3.3 clean-text==0.6.0 From 3f40fc9e1d3e2d35677849b5672d65b72ce08477 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:19:14 +0000 Subject: [PATCH 05/20] Bump transformers from 4.29.2 to 4.37.1 Bumps [transformers](https://github.com/huggingface/transformers) from 4.29.2 to 4.37.1. - [Release notes](https://github.com/huggingface/transformers/releases) - [Commits](https://github.com/huggingface/transformers/compare/v4.29.2...v4.37.1) --- updated-dependencies: - dependency-name: transformers dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index aada5cc..209020b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 torch==2.0.1 -transformers==4.29.2 +transformers==4.37.1 ffmpeg-python==0.2.0 elevenlabs==0.2.17 yt-dlp==2023.7.6 \ No newline at end of file From 425286fe90b233e55e28992fd7653ce7c7205943 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 14:00:12 +0000 Subject: [PATCH 06/20] fixup: Format Python code with Black --- GUI.py | 4 +- TTS/TikTok.py | 4 +- TTS/aws_polly.py | 4 +- TTS/elevenlabs.py | 8 +-- TTS/engine_wrapper.py | 25 +++----- TTS/pyttsx.py | 4 +- TTS/streamlabs_polly.py | 4 +- main.py | 4 +- reddit/subreddit.py | 25 ++------ utils/ai_methods.py | 20 ++---- utils/console.py | 17 +----- utils/ffmpeg_install.py | 8 +-- utils/gui_utils.py | 22 ++----- utils/imagenarator.py | 16 ++--- utils/playwright.py | 4 +- utils/settings.py | 32 ++-------- utils/subreddit.py | 19 ++---- utils/thumbnail.py | 12 +--- utils/videos.py | 8 +-- utils/voice.py | 4 +- video_creation/background.py | 12 +--- video_creation/final_video.py | 81 ++++++------------------- video_creation/screenshot_downloader.py | 40 +++--------- video_creation/voices.py | 14 +---- 24 files changed, 96 insertions(+), 295 deletions(-) diff --git a/GUI.py b/GUI.py index 47dfc25..4588083 100644 --- a/GUI.py +++ b/GUI.py @@ -82,9 +82,7 @@ def settings(): # Change settings config = gui.modify_settings(data, config_load, checks) - return render_template( - "settings.html", file="config.toml", data=config, checks=checks - ) + return render_template("settings.html", file="config.toml", data=config, checks=checks) # Make videos.json accessible diff --git a/TTS/TikTok.py b/TTS/TikTok.py index 3c83e9a..29542e2 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -86,9 +86,7 @@ class TikTok: "Cookie": f"sessionid={settings.config['settings']['tts']['tiktok_sessionid']}", } - self.URI_BASE = ( - "https://api16-normal-c-useast1a.tiktokv.com/media/api/text/speech/invoke/" - ) + self.URI_BASE = "https://api16-normal-c-useast1a.tiktokv.com/media/api/text/speech/invoke/" self.max_chars = 200 self._session = requests.Session() diff --git a/TTS/aws_polly.py b/TTS/aws_polly.py index 58323f9..4d55860 100644 --- a/TTS/aws_polly.py +++ b/TTS/aws_polly.py @@ -41,9 +41,7 @@ class AWSPolly: raise ValueError( f"Please set the TOML variable AWS_VOICE to a valid voice. options are: {voices}" ) - voice = str( - settings.config["settings"]["tts"]["aws_polly_voice"] - ).capitalize() + voice = str(settings.config["settings"]["tts"]["aws_polly_voice"]).capitalize() try: # Request speech synthesis response = polly.synthesize_speech( diff --git a/TTS/elevenlabs.py b/TTS/elevenlabs.py index ab6dbb0..e18bba9 100644 --- a/TTS/elevenlabs.py +++ b/TTS/elevenlabs.py @@ -26,9 +26,7 @@ class elevenlabs: if random_voice: voice = self.randomvoice() else: - voice = str( - settings.config["settings"]["tts"]["elevenlabs_voice_name"] - ).capitalize() + voice = str(settings.config["settings"]["tts"]["elevenlabs_voice_name"]).capitalize() if settings.config["settings"]["tts"]["elevenlabs_api_key"]: api_key = settings.config["settings"]["tts"]["elevenlabs_api_key"] @@ -37,9 +35,7 @@ class elevenlabs: "You didn't set an Elevenlabs API key! Please set the config variable ELEVENLABS_API_KEY to a valid API key." ) - audio = generate( - api_key=api_key, text=text, voice=voice, model="eleven_multilingual_v1" - ) + audio = generate(api_key=api_key, text=text, voice=voice, model="eleven_multilingual_v1") save(audio=audio, filename=filepath) def randomvoice(self): diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index a78aef7..6d498d2 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -14,11 +14,12 @@ from utils import settings from utils.console import print_step, print_substep from utils.voice import sanitize_text -DEFAULT_MAX_LENGTH: int = 50 # Video length variable, edit this on your own risk. It should work, but it's not supported +DEFAULT_MAX_LENGTH: int = ( + 50 # Video length variable, edit this on your own risk. It should work, but it's not supported +) class TTSEngine: - """Calls the given TTS engine to reduce code duplication and allow multiple TTS engines. Args: @@ -57,9 +58,7 @@ class TTSEngine: comment["comment_body"] = re.sub(regex_urls, " ", comment["comment_body"]) comment["comment_body"] = comment["comment_body"].replace("\n", ". ") comment["comment_body"] = re.sub(r"\bAI\b", "A.I", comment["comment_body"]) - comment["comment_body"] = re.sub( - r"\bAGI\b", "A.G.I", comment["comment_body"] - ) + comment["comment_body"] = re.sub(r"\bAGI\b", "A.G.I", comment["comment_body"]) if comment["comment_body"][-1] != ".": comment["comment_body"] += "." comment["comment_body"] = comment["comment_body"].replace(". . .", ".") @@ -81,17 +80,13 @@ class TTSEngine: if len(self.reddit_object["thread_post"]) > self.tts_module.max_chars: self.split_post(self.reddit_object["thread_post"], "postaudio") else: - self.call_tts( - "postaudio", process_text(self.reddit_object["thread_post"]) - ) + self.call_tts("postaudio", process_text(self.reddit_object["thread_post"])) elif settings.config["settings"]["storymodemethod"] == 1: for idx, text in track(enumerate(self.reddit_object["thread_post"])): self.call_tts(f"postaudio-{idx}", process_text(text)) else: - for idx, comment in track( - enumerate(self.reddit_object["comments"]), "Saving..." - ): + for idx, comment in track(enumerate(self.reddit_object["comments"]), "Saving..."): # ! Stop creating mp3 files if the length is greater than max length. if self.length > self.max_length and idx > 1: self.length -= self.last_clip_length @@ -174,9 +169,7 @@ class TTSEngine: fps=44100, ) silence = volumex(silence, 0) - silence.write_audiofile( - f"{self.path}/silence.mp3", fps=44100, verbose=False, logger=None - ) + silence.write_audiofile(f"{self.path}/silence.mp3", fps=44100, verbose=False, logger=None) def process_text(text: str, clean: bool = True): @@ -184,8 +177,6 @@ def process_text(text: str, clean: bool = True): new_text = sanitize_text(text) if clean else text if lang: print_substep("Translating Text...") - translated_text = translators.translate_text( - text, translator="google", to_language=lang - ) + translated_text = translators.translate_text(text, translator="google", to_language=lang) new_text = sanitize_text(translated_text) return new_text diff --git a/TTS/pyttsx.py b/TTS/pyttsx.py index a80bf2d..bf47601 100644 --- a/TTS/pyttsx.py +++ b/TTS/pyttsx.py @@ -21,9 +21,7 @@ class pyttsx: if voice_id == "" or voice_num == "": voice_id = 2 voice_num = 3 - raise ValueError( - "set pyttsx values to a valid value, switching to defaults" - ) + raise ValueError("set pyttsx values to a valid value, switching to defaults") else: voice_id = int(voice_id) voice_num = int(voice_num) diff --git a/TTS/streamlabs_polly.py b/TTS/streamlabs_polly.py index 721dd78..dc80dc9 100644 --- a/TTS/streamlabs_polly.py +++ b/TTS/streamlabs_polly.py @@ -42,9 +42,7 @@ class StreamlabsPolly: raise ValueError( f"Please set the config variable STREAMLABS_POLLY_VOICE to a valid voice. options are: {voices}" ) - voice = str( - settings.config["settings"]["tts"]["streamlabs_polly_voice"] - ).capitalize() + voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize() body = {"voice": voice, "text": text, "service": "polly"} response = requests.post(self.url, data=body) if not check_ratelimit(response): diff --git a/main.py b/main.py index 8eff308..0a401c3 100755 --- a/main.py +++ b/main.py @@ -104,9 +104,7 @@ if __name__ == "__main__": sys.exit() try: if config["reddit"]["thread"]["post_id"]: - for index, post_id in enumerate( - config["reddit"]["thread"]["post_id"].split("+") - ): + for index, post_id in enumerate(config["reddit"]["thread"]["post_id"].split("+")): index += 1 print_step( f'on the {index}{("st" if index % 10 == 1 else ("nd" if index % 10 == 2 else ("rd" if index % 10 == 3 else "th")))} post of {len(config["reddit"]["thread"]["post_id"].split("+"))}' diff --git a/reddit/subreddit.py b/reddit/subreddit.py index f2f8419..8646b48 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -22,9 +22,7 @@ def get_subreddit_threads(POST_ID: str): content = {} if settings.config["reddit"]["creds"]["2fa"]: - print( - "\nEnter your two-factor authentication code from your authenticator app.\n" - ) + print("\nEnter your two-factor authentication code from your authenticator app.\n") code = input("> ") print() pw = settings.config["reddit"]["creds"]["password"] @@ -57,9 +55,7 @@ def get_subreddit_threads(POST_ID: str): ]: # note to user. you can have multiple subreddits via reddit.subreddit("redditdev+learnpython") try: subreddit = reddit.subreddit( - re.sub( - r"r\/", "", input("What subreddit would you like to pull from? ") - ) + re.sub(r"r\/", "", input("What subreddit would you like to pull from? ")) # removes the r/ from the input ) except ValueError: @@ -69,9 +65,7 @@ def get_subreddit_threads(POST_ID: str): sub = settings.config["reddit"]["thread"]["subreddit"] print_substep(f"Using subreddit: r/{sub} from TOML config") subreddit_choice = sub - if ( - str(subreddit_choice).casefold().startswith("r/") - ): # removes the r/ from the input + if str(subreddit_choice).casefold().startswith("r/"): # removes the r/ from the input subreddit_choice = subreddit_choice[2:] subreddit = reddit.subreddit(subreddit_choice) @@ -82,12 +76,8 @@ def get_subreddit_threads(POST_ID: str): settings.config["reddit"]["thread"]["post_id"] and len(str(settings.config["reddit"]["thread"]["post_id"]).split("+")) == 1 ): - submission = reddit.submission( - id=settings.config["reddit"]["thread"]["post_id"] - ) - elif settings.config["ai"][ - "ai_similarity_enabled" - ]: # ai sorting based on comparison + submission = reddit.submission(id=settings.config["reddit"]["thread"]["post_id"]) + elif settings.config["ai"]["ai_similarity_enabled"]: # ai sorting based on comparison threads = subreddit.hot(limit=50) keywords = settings.config["ai"]["ai_similarity_keywords"].split(",") keywords = [keyword.strip() for keyword in keywords] @@ -105,10 +95,7 @@ def get_subreddit_threads(POST_ID: str): if submission is None: return get_subreddit_threads(POST_ID) # submission already done. rerun - elif ( - not submission.num_comments - and settings.config["settings"]["storymode"] == "false" - ): + elif not submission.num_comments and settings.config["settings"]["storymode"] == "false": print_substep("No comments found. Skipping.") exit() diff --git a/utils/ai_methods.py b/utils/ai_methods.py index 7f64570..eb6e73e 100644 --- a/utils/ai_methods.py +++ b/utils/ai_methods.py @@ -5,12 +5,8 @@ from transformers import AutoTokenizer, AutoModel # Mean Pooling - Take attention mask into account for correct averaging def mean_pooling(model_output, attention_mask): - token_embeddings = model_output[ - 0 - ] # First element of model_output contains all token embeddings - input_mask_expanded = ( - attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float() - ) + token_embeddings = model_output[0] # First element of model_output contains all token embeddings + input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float() return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp( input_mask_expanded.sum(1), min=1e-9 ) @@ -36,19 +32,13 @@ def sort_by_similarity(thread_objects, keywords): ) with torch.no_grad(): threads_embeddings = model(**encoded_threads) - threads_embeddings = mean_pooling( - threads_embeddings, encoded_threads["attention_mask"] - ) + threads_embeddings = mean_pooling(threads_embeddings, encoded_threads["attention_mask"]) # Keywords inference - encoded_keywords = tokenizer( - keywords, padding=True, truncation=True, return_tensors="pt" - ) + encoded_keywords = tokenizer(keywords, padding=True, truncation=True, return_tensors="pt") with torch.no_grad(): keywords_embeddings = model(**encoded_keywords) - keywords_embeddings = mean_pooling( - keywords_embeddings, encoded_keywords["attention_mask"] - ) + keywords_embeddings = mean_pooling(keywords_embeddings, encoded_keywords["attention_mask"]) # Compare every keyword w/ every thread embedding threads_embeddings_tensor = torch.tensor(threads_embeddings) diff --git a/utils/console.py b/utils/console.py index 7ac8a70..18c3248 100644 --- a/utils/console.py +++ b/utils/console.py @@ -49,10 +49,7 @@ def handle_input( optional=False, ): if optional: - console.print( - message - + "\n[green]This is an optional value. Do you want to skip it? (y/n)" - ) + console.print(message + "\n[green]This is an optional value. Do you want to skip it? (y/n)") if input().casefold().startswith("y"): return default if default is not NotImplemented else "" if default is not NotImplemented: @@ -86,11 +83,7 @@ def handle_input( console.print("[red]" + err_message) continue elif match != "" and re.match(match, user_input) is None: - console.print( - "[red]" - + err_message - + "\nAre you absolutely sure it's correct?(y/n)" - ) + console.print("[red]" + err_message + "\nAre you absolutely sure it's correct?(y/n)") if input().casefold().startswith("y"): break continue @@ -123,9 +116,5 @@ def handle_input( if user_input in options: return user_input console.print( - "[red bold]" - + err_message - + "\nValid options are: " - + ", ".join(map(str, options)) - + "." + "[red bold]" + err_message + "\nValid options are: " + ", ".join(map(str, options)) + "." ) diff --git a/utils/ffmpeg_install.py b/utils/ffmpeg_install.py index b29301f..b2c673d 100644 --- a/utils/ffmpeg_install.py +++ b/utils/ffmpeg_install.py @@ -7,7 +7,9 @@ import requests def ffmpeg_install_windows(): try: - ffmpeg_url = "https://github.com/GyanD/codexffmpeg/releases/download/6.0/ffmpeg-6.0-full_build.zip" + ffmpeg_url = ( + "https://github.com/GyanD/codexffmpeg/releases/download/6.0/ffmpeg-6.0-full_build.zip" + ) ffmpeg_zip_filename = "ffmpeg.zip" ffmpeg_extracted_folder = "ffmpeg" @@ -127,9 +129,7 @@ def ffmpeg_install(): elif os.name == "mac": ffmpeg_install_mac() else: - print( - "Your OS is not supported. Please install FFmpeg manually and try again." - ) + print("Your OS is not supported. Please install FFmpeg manually and try again.") exit() else: print("Please install FFmpeg manually and try again.") diff --git a/utils/gui_utils.py b/utils/gui_utils.py index 9d644d8..f683adf 100644 --- a/utils/gui_utils.py +++ b/utils/gui_utils.py @@ -67,11 +67,7 @@ def check(value, checks): and not hasattr(value, "__iter__") and ( ("nmin" in checks and checks["nmin"] is not None and value < checks["nmin"]) - or ( - "nmax" in checks - and checks["nmax"] is not None - and value > checks["nmax"] - ) + or ("nmax" in checks and checks["nmax"] is not None and value > checks["nmax"]) ) ): incorrect = True @@ -80,16 +76,8 @@ def check(value, checks): not incorrect and hasattr(value, "__iter__") and ( - ( - "nmin" in checks - and checks["nmin"] is not None - and len(value) < checks["nmin"] - ) - or ( - "nmax" in checks - and checks["nmax"] is not None - and len(value) > checks["nmax"] - ) + ("nmin" in checks and checks["nmin"] is not None and len(value) < checks["nmin"]) + or ("nmax" in checks and checks["nmax"] is not None and len(value) > checks["nmax"]) ) ): incorrect = True @@ -162,9 +150,7 @@ def delete_background(key): # Add background video def add_background(youtube_uri, filename, citation, position): # Validate YouTube URI - regex = re.compile(r"(?:\/|%3D|v=|vi=)([0-9A-z\-_]{11})(?:[%#?&]|$)").search( - youtube_uri - ) + regex = re.compile(r"(?:\/|%3D|v=|vi=)([0-9A-z\-_]{11})(?:[%#?&]|$)").search(youtube_uri) if not regex: flash("YouTube URI is invalid!", "error") diff --git a/utils/imagenarator.py b/utils/imagenarator.py index 06bbd69..151b0e6 100644 --- a/utils/imagenarator.py +++ b/utils/imagenarator.py @@ -18,9 +18,7 @@ def draw_multiple_line_text( Fontperm = font.getsize(text) image_width, image_height = image.size lines = textwrap.wrap(text, width=wrap) - y = (image_height / 2) - ( - ((Fontperm[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2 - ) + y = (image_height / 2) - (((Fontperm[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2) for line in lines: line_width, line_height = font.getsize(line) if transparent: @@ -66,25 +64,19 @@ def imagemaker(theme, reddit_obj: dict, txtclr, padding=5, transparent=False) -> font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100) tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100) else: - tfont = ImageFont.truetype( - os.path.join("fonts", "Roboto-Bold.ttf"), 100 - ) # for title + tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100) # for title font = ImageFont.truetype(os.path.join("fonts", "Roboto-Regular.ttf"), 100) size = (1920, 1080) image = Image.new("RGBA", size, theme) # for title - draw_multiple_line_text( - image, title, tfont, txtclr, padding, wrap=30, transparent=transparent - ) + draw_multiple_line_text(image, title, tfont, txtclr, padding, wrap=30, transparent=transparent) image.save(f"assets/temp/{id}/png/title.png") for idx, text in track(enumerate(texts), "Rendering Image"): image = Image.new("RGBA", size, theme) text = process_text(text, False) - draw_multiple_line_text( - image, text, font, txtclr, padding, wrap=30, transparent=transparent - ) + draw_multiple_line_text(image, text, font, txtclr, padding, wrap=30, transparent=transparent) image.save(f"assets/temp/{id}/png/img{idx}.png") diff --git a/utils/playwright.py b/utils/playwright.py index be046e6..9672f03 100644 --- a/utils/playwright.py +++ b/utils/playwright.py @@ -1,7 +1,5 @@ def clear_cookie_by_name(context, cookie_cleared_name): cookies = context.cookies() - filtered_cookies = [ - cookie for cookie in cookies if cookie["name"] != cookie_cleared_name - ] + filtered_cookies = [cookie for cookie in cookies if cookie["name"] != cookie_cleared_name] context.clear_cookies() context.add_cookies(filtered_cookies) diff --git a/utils/settings.py b/utils/settings.py index e2db508..8187e9a 100755 --- a/utils/settings.py +++ b/utils/settings.py @@ -53,11 +53,7 @@ def check(value, checks, name): and not hasattr(value, "__iter__") and ( ("nmin" in checks and checks["nmin"] is not None and value < checks["nmin"]) - or ( - "nmax" in checks - and checks["nmax"] is not None - and value > checks["nmax"] - ) + or ("nmax" in checks and checks["nmax"] is not None and value > checks["nmax"]) ) ): incorrect = True @@ -65,16 +61,8 @@ def check(value, checks, name): not incorrect and hasattr(value, "__iter__") and ( - ( - "nmin" in checks - and checks["nmin"] is not None - and len(value) < checks["nmin"] - ) - or ( - "nmax" in checks - and checks["nmax"] is not None - and len(value) > checks["nmax"] - ) + ("nmin" in checks and checks["nmin"] is not None and len(value) < checks["nmin"]) + or ("nmax" in checks and checks["nmax"] is not None and len(value) > checks["nmax"]) ) ): incorrect = True @@ -82,15 +70,9 @@ def check(value, checks, name): if incorrect: value = handle_input( message=( - ( - ("[blue]Example: " + str(checks["example"]) + "\n") - if "example" in checks - else "" - ) + (("[blue]Example: " + str(checks["example"]) + "\n") if "example" in checks else "") + "[red]" - + ("Non-optional ", "Optional ")[ - "optional" in checks and checks["optional"] is True - ] + + ("Non-optional ", "Optional ")["optional" in checks and checks["optional"] is True] ) + "[#C0CAF5 bold]" + str(name) @@ -131,9 +113,7 @@ def check_toml(template_file, config_file) -> Tuple[bool, Dict]: try: template = toml.load(template_file) except Exception as error: - console.print( - f"[red bold]Encountered error when trying to to load {template_file}: {error}" - ) + console.print(f"[red bold]Encountered error when trying to to load {template_file}: {error}") return False try: config = toml.load(config_file) diff --git a/utils/subreddit.py b/utils/subreddit.py index a3732f6..403b6d3 100644 --- a/utils/subreddit.py +++ b/utils/subreddit.py @@ -6,9 +6,7 @@ from utils.ai_methods import sort_by_similarity from utils.console import print_substep -def get_subreddit_undone( - submissions: list, subreddit, times_checked=0, similarity_scores=None -): +def get_subreddit_undone(submissions: list, subreddit, times_checked=0, similarity_scores=None): """_summary_ Args: @@ -20,9 +18,7 @@ def get_subreddit_undone( """ # Second try of getting a valid Submission if times_checked and settings.config["ai"]["ai_similarity_enabled"]: - print( - "Sorting based on similarity for a different date filter and thread limit.." - ) + print("Sorting based on similarity for a different date filter and thread limit..") submissions = sort_by_similarity( submissions, keywords=settings.config["ai"]["ai_similarity_enabled"] ) @@ -31,9 +27,7 @@ def get_subreddit_undone( if not exists("./video_creation/data/videos.json"): with open("./video_creation/data/videos.json", "w+") as f: json.dump([], f) - with open( - "./video_creation/data/videos.json", "r", encoding="utf-8" - ) as done_vids_raw: + with open("./video_creation/data/videos.json", "r", encoding="utf-8") as done_vids_raw: done_videos = json.load(done_vids_raw) for i, submission in enumerate(submissions): if already_done(done_videos, submission): @@ -49,8 +43,7 @@ def get_subreddit_undone( print_substep("This post was pinned by moderators. Skipping...") continue if ( - submission.num_comments - <= int(settings.config["reddit"]["thread"]["min_comments"]) + submission.num_comments <= int(settings.config["reddit"]["thread"]["min_comments"]) and not settings.config["settings"]["storymode"] ): print_substep( @@ -59,9 +52,7 @@ def get_subreddit_undone( continue if settings.config["settings"]["storymode"]: if not submission.selftext: - print_substep( - "You are trying to use story mode on post with no post text" - ) + print_substep("You are trying to use story mode on post with no post text") continue else: # Check for the length of the post text diff --git a/utils/thumbnail.py b/utils/thumbnail.py index aeb82b4..172b454 100644 --- a/utils/thumbnail.py +++ b/utils/thumbnail.py @@ -1,15 +1,11 @@ from PIL import ImageDraw, ImageFont -def create_thumbnail( - thumbnail, font_family, font_size, font_color, width, height, title -): +def create_thumbnail(thumbnail, font_family, font_size, font_color, width, height, title): font = ImageFont.truetype(font_family + ".ttf", font_size) Xaxis = width - (width * 0.2) # 20% of the width sizeLetterXaxis = font_size * 0.5 # 50% of the font size - XaxisLetterQty = round( - Xaxis / sizeLetterXaxis - ) # Quantity of letters that can fit in the X axis + XaxisLetterQty = round(Xaxis / sizeLetterXaxis) # Quantity of letters that can fit in the X axis MarginYaxis = height * 0.12 # 12% of the height MarginXaxis = width * 0.05 # 5% of the width # 1.1 rem @@ -34,8 +30,6 @@ def create_thumbnail( # loop for put the title in the thumbnail for i in range(0, len(arrayTitle)): # 1.1 rem - draw.text( - (MarginXaxis, MarginYaxis + (LineHeight * i)), arrayTitle[i], rgb, font=font - ) + draw.text((MarginXaxis, MarginYaxis + (LineHeight * i)), arrayTitle[i], rgb, font=font) return thumbnail diff --git a/utils/videos.py b/utils/videos.py index c30cb2c..7c756fc 100755 --- a/utils/videos.py +++ b/utils/videos.py @@ -19,9 +19,7 @@ def check_done( Returns: Submission|None: Reddit object in args """ - with open( - "./video_creation/data/videos.json", "r", encoding="utf-8" - ) as done_vids_raw: + with open("./video_creation/data/videos.json", "r", encoding="utf-8") as done_vids_raw: done_videos = json.load(done_vids_raw) for video in done_videos: if video["id"] == str(redditobj): @@ -35,9 +33,7 @@ def check_done( return redditobj -def save_data( - subreddit: str, filename: str, reddit_title: str, reddit_id: str, credit: str -): +def save_data(subreddit: str, filename: str, reddit_title: str, reddit_id: str, credit: str): """Saves the videos that have already been generated to a JSON file in video_creation/data/videos.json Args: diff --git a/utils/voice.py b/utils/voice.py index 9bc09d8..56595fc 100644 --- a/utils/voice.py +++ b/utils/voice.py @@ -43,9 +43,7 @@ def sleep_until(time) -> None: if sys.version_info[0] >= 3 and time.tzinfo: end = time.astimezone(timezone.utc).timestamp() else: - zoneDiff = ( - pytime.time() - (datetime.now() - datetime(1970, 1, 1)).total_seconds() - ) + zoneDiff = pytime.time() - (datetime.now() - datetime(1970, 1, 1)).total_seconds() end = (time - datetime(1970, 1, 1)).total_seconds() + zoneDiff # Type check diff --git a/video_creation/background.py b/video_creation/background.py index 3683bb5..2ec9812 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -60,9 +60,7 @@ def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int def get_background_config(mode: str): """Fetch the background/s configuration""" try: - choice = str( - settings.config["settings"]["background"][f"background_{mode}"] - ).casefold() + choice = str(settings.config["settings"]["background"][f"background_{mode}"]).casefold() except AttributeError: print_substep("No background selected. Picking random background'") choice = None @@ -122,9 +120,7 @@ def download_background_audio(background_config: Tuple[str, str, str]): print_substep("Background audio downloaded successfully! 🎉", style="bold green") -def chop_background( - background_config: Dict[str, Tuple], video_length: int, reddit_object: dict -): +def chop_background(background_config: Dict[str, Tuple], video_length: int, reddit_object: dict): """Generates the background audio and footage to be used in the video and writes it to assets/temp/background.mp3 and assets/temp/background.mp4 Args: @@ -137,9 +133,7 @@ def chop_background( print_step("Volume was set to 0. Skipping background audio creation . . .") else: print_step("Finding a spot in the backgrounds audio to chop...✂️") - audio_choice = ( - f"{background_config['audio'][2]}-{background_config['audio'][1]}" - ) + audio_choice = f"{background_config['audio'][2]}-{background_config['audio'][1]}" background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") start_time_audio, end_time_audio = get_start_and_end_times( video_length, background_audio.duration diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 0739df8..5069474 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -75,9 +75,7 @@ def name_normalize(name: str) -> str: lang = settings.config["reddit"]["thread"]["post_lang"] if lang: print_substep("Translating filename...") - translated_name = translators.translate_text( - name, translator="google", to_language=lang - ) + translated_name = translators.translate_text(name, translator="google", to_language=lang) return translated_name else: return name @@ -114,9 +112,7 @@ def merge_background_audio(audio: ffmpeg, reddit_id: str): audio (ffmpeg): The TTS final audio but without background. reddit_id (str): The ID of subreddit """ - background_audio_volume = settings.config["settings"]["background"][ - "background_audio_volume" - ] + background_audio_volume = settings.config["settings"]["background"]["background_audio_volume"] if background_audio_volume == 0: return audio # Return the original audio else: @@ -170,42 +166,27 @@ def make_final_video( if settings.config["settings"]["storymode"]: if settings.config["settings"]["storymodemethod"] == 0: audio_clips = [ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")] - audio_clips.insert( - 1, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio.mp3") - ) + audio_clips.insert(1, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio.mp3")) elif settings.config["settings"]["storymodemethod"] == 1: audio_clips = [ ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3") - for i in track( - range(number_of_clips + 1), "Collecting the audio files..." - ) + for i in track(range(number_of_clips + 1), "Collecting the audio files...") ] - audio_clips.insert( - 0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3") - ) + audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")) else: audio_clips = [ - ffmpeg.input(f"assets/temp/{reddit_id}/mp3/{i}.mp3") - for i in range(number_of_clips) + ffmpeg.input(f"assets/temp/{reddit_id}/mp3/{i}.mp3") for i in range(number_of_clips) ] audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")) audio_clips_durations = [ - float( - ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/{i}.mp3")["format"][ - "duration" - ] - ) + float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/{i}.mp3")["format"]["duration"]) for i in range(number_of_clips) ] audio_clips_durations.insert( 0, - float( - ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"][ - "duration" - ] - ), + float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"]["duration"]), ) audio_concat = ffmpeg.concat(*audio_clips, a=1, v=0) ffmpeg.output( @@ -231,19 +212,13 @@ def make_final_video( if settings.config["settings"]["storymode"]: audio_clips_durations = [ float( - ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")[ - "format" - ]["duration"] + ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")["format"]["duration"] ) for i in range(number_of_clips) ] audio_clips_durations.insert( 0, - float( - ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"][ - "duration" - ] - ), + float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"]["duration"]), ) if settings.config["settings"]["storymodemethod"] == 0: image_clips.insert( @@ -260,9 +235,7 @@ def make_final_video( ) current_time += audio_clips_durations[0] elif settings.config["settings"]["storymodemethod"] == 1: - for i in track( - range(0, number_of_clips + 1), "Collecting the image files..." - ): + for i in track(range(0, number_of_clips + 1), "Collecting the image files..."): image_clips.append( ffmpeg.input(f"assets/temp/{reddit_id}/png/img{i}.png")["v"].filter( "scale", screenshot_width, -1 @@ -278,9 +251,9 @@ def make_final_video( else: for i in range(0, number_of_clips + 1): image_clips.append( - ffmpeg.input(f"assets/temp/{reddit_id}/png/comment_{i}.png")[ - "v" - ].filter("scale", screenshot_width, -1) + ffmpeg.input(f"assets/temp/{reddit_id}/png/comment_{i}.png")["v"].filter( + "scale", screenshot_width, -1 + ) ) image_overlay = image_clips[i].filter("colorchannelmixer", aa=opacity) background_clip = background_clip.overlay( @@ -299,15 +272,11 @@ def make_final_video( subreddit = settings.config["reddit"]["thread"]["subreddit"] if not exists(f"./results/{subreddit}"): - print_substep( - "The 'results' folder could not be found so it was automatically created." - ) + print_substep("The 'results' folder could not be found so it was automatically created.") os.makedirs(f"./results/{subreddit}") if not exists(f"./results/{subreddit}/OnlyTTS") and allowOnlyTTSFolder: - print_substep( - "The 'OnlyTTS' folder could not be found so it was automatically created." - ) + print_substep("The 'OnlyTTS' folder could not be found so it was automatically created.") os.makedirs(f"./results/{subreddit}/OnlyTTS") # create a thumbnail for the video @@ -321,11 +290,7 @@ def make_final_video( os.makedirs(f"./results/{subreddit}/thumbnails") # get the first file with the .png extension from assets/backgrounds and use it as a background for the thumbnail first_image = next( - ( - file - for file in os.listdir("assets/backgrounds") - if file.endswith(".png") - ), + (file for file in os.listdir("assets/backgrounds") if file.endswith(".png")), None, ) if first_image is None: @@ -347,9 +312,7 @@ def make_final_video( title_thumb, ) thumbnailSave.save(f"./assets/temp/{reddit_id}/thumbnail.png") - print_substep( - f"Thumbnail - Building Thumbnail in assets/temp/{reddit_id}/thumbnail.png" - ) + print_substep(f"Thumbnail - Building Thumbnail in assets/temp/{reddit_id}/thumbnail.png") text = f"Background by {background_config['video'][2]}" background_clip = ffmpeg.drawtext( @@ -390,9 +353,7 @@ def make_final_video( "b:a": "192k", "threads": multiprocessing.cpu_count(), }, - ).overwrite_output().global_args( - "-progress", progress.output_file.name - ).run( + ).overwrite_output().global_args("-progress", progress.output_file.name).run( quiet=True, overwrite_output=True, capture_stdout=False, @@ -422,9 +383,7 @@ def make_final_video( "b:a": "192k", "threads": multiprocessing.cpu_count(), }, - ).overwrite_output().global_args( - "-progress", progress.output_file.name - ).run( + ).overwrite_output().global_args("-progress", progress.output_file.name).run( quiet=True, overwrite_output=True, capture_stdout=False, diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 6226adf..cdcf8ef 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -36,9 +36,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): # set the theme and disable non-essential cookies if settings.config["settings"]["theme"] == "dark": - cookie_file = open( - "./video_creation/data/cookie-dark-mode.json", encoding="utf-8" - ) + cookie_file = open("./video_creation/data/cookie-dark-mode.json", encoding="utf-8") bgcolor = (33, 33, 36, 255) txtcolor = (240, 240, 240) transparent = False @@ -48,21 +46,15 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): bgcolor = (0, 0, 0, 0) txtcolor = (255, 255, 255) transparent = True - cookie_file = open( - "./video_creation/data/cookie-dark-mode.json", encoding="utf-8" - ) + cookie_file = open("./video_creation/data/cookie-dark-mode.json", encoding="utf-8") else: # Switch to dark theme - cookie_file = open( - "./video_creation/data/cookie-dark-mode.json", encoding="utf-8" - ) + cookie_file = open("./video_creation/data/cookie-dark-mode.json", encoding="utf-8") bgcolor = (33, 33, 36, 255) txtcolor = (240, 240, 240) transparent = False else: - cookie_file = open( - "./video_creation/data/cookie-light-mode.json", encoding="utf-8" - ) + cookie_file = open("./video_creation/data/cookie-light-mode.json", encoding="utf-8") bgcolor = (255, 255, 255, 255) txtcolor = (0, 0, 0) transparent = False @@ -106,12 +98,8 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): page.set_viewport_size(ViewportSize(width=1920, height=1080)) page.wait_for_load_state() - page.locator('[name="username"]').fill( - settings.config["reddit"]["creds"]["username"] - ) - page.locator('[name="password"]').fill( - settings.config["reddit"]["creds"]["password"] - ) + page.locator('[name="username"]').fill(settings.config["reddit"]["creds"]["username"]) + page.locator('[name="password"]').fill(settings.config["reddit"]["creds"]["password"]) page.locator("button[class$='m-full-width']").click() page.wait_for_timeout(5000) @@ -192,9 +180,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): location[i] = float("{:.2f}".format(location[i] * zoom)) page.screenshot(clip=location, path=postcontentpath) else: - page.locator('[data-test-id="post-content"]').screenshot( - path=postcontentpath - ) + page.locator('[data-test-id="post-content"]').screenshot(path=postcontentpath) except Exception as e: print_substep("Something went wrong!", style="red") resp = input( @@ -208,9 +194,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): "green", ) - resp = input( - "Do you want the error traceback for debugging purposes? (y/n)" - ) + resp = input("Do you want the error traceback for debugging purposes? (y/n)") if not resp.casefold().startswith("y"): exit() @@ -255,13 +239,9 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): # zoom the body of the page page.evaluate("document.body.style.zoom=" + str(zoom)) # scroll comment into view - page.locator( - f"#t1_{comment['comment_id']}" - ).scroll_into_view_if_needed() + page.locator(f"#t1_{comment['comment_id']}").scroll_into_view_if_needed() # as zooming the body doesn't change the properties of the divs, we need to adjust for the zoom - location = page.locator( - f"#t1_{comment['comment_id']}" - ).bounding_box() + location = page.locator(f"#t1_{comment['comment_id']}").bounding_box() for i in location: location[i] = float("{:.2f}".format(location[i] * zoom)) page.screenshot( diff --git a/video_creation/voices.py b/video_creation/voices.py index 4b29657..8495f8d 100644 --- a/video_creation/voices.py +++ b/video_creation/voices.py @@ -36,9 +36,7 @@ def save_text_to_mp3(reddit_obj) -> Tuple[int, int]: voice = settings.config["settings"]["tts"]["voice_choice"] if str(voice).casefold() in map(lambda _: _.casefold(), TTSProviders): - text_to_mp3 = TTSEngine( - get_case_insensitive_key_value(TTSProviders, voice), reddit_obj - ) + text_to_mp3 = TTSEngine(get_case_insensitive_key_value(TTSProviders, voice), reddit_obj) else: while True: print_step("Please choose one of the following TTS providers: ") @@ -47,18 +45,12 @@ def save_text_to_mp3(reddit_obj) -> Tuple[int, int]: if choice.casefold() in map(lambda _: _.casefold(), TTSProviders): break print("Unknown Choice") - text_to_mp3 = TTSEngine( - get_case_insensitive_key_value(TTSProviders, choice), reddit_obj - ) + text_to_mp3 = TTSEngine(get_case_insensitive_key_value(TTSProviders, choice), reddit_obj) return text_to_mp3.run() def get_case_insensitive_key_value(input_dict, key): return next( - ( - value - for dict_key, value in input_dict.items() - if dict_key.lower() == key.lower() - ), + (value for dict_key, value in input_dict.items() if dict_key.lower() == key.lower()), None, ) From fb6457844e6339626056ad18f772328f1bc4c74c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 11:12:47 +0000 Subject: [PATCH 07/20] Bump gtts from 2.3.2 to 2.5.1 Bumps [gtts](https://github.com/pndurette/gTTS) from 2.3.2 to 2.5.1. - [Release notes](https://github.com/pndurette/gTTS/releases) - [Changelog](https://github.com/pndurette/gTTS/blob/main/CHANGELOG.md) - [Commits](https://github.com/pndurette/gTTS/compare/v2.3.2...v2.5.1) --- updated-dependencies: - dependency-name: gtts dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f2e1396..ef05d51 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ boto3==1.26.142 botocore==1.29.142 -gTTS==2.3.2 +gTTS==2.5.1 moviepy==1.0.3 playwright==1.34.0 praw==7.7.0 From e05bafd9854fa3c0436a32c8de1ff63461823c06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 10:12:08 +0000 Subject: [PATCH 08/20] Bump torch from 2.0.1 to 2.2.0 Bumps [torch](https://github.com/pytorch/pytorch) from 2.0.1 to 2.2.0. - [Release notes](https://github.com/pytorch/pytorch/releases) - [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md) - [Commits](https://github.com/pytorch/pytorch/compare/v2.0.1...v2.2.0) --- updated-dependencies: - dependency-name: torch dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f2e1396..0de5323 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ Flask==2.3.3 clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 -torch==2.0.1 +torch==2.2.0 transformers==4.37.1 ffmpeg-python==0.2.0 elevenlabs==0.2.17 From 49ddc36b447f9c191bf1b0cf4529a8199e605db3 Mon Sep 17 00:00:00 2001 From: dieperdev <140034404+dieperdev@users.noreply.github.com> Date: Wed, 31 Jan 2024 06:39:43 -0500 Subject: [PATCH 09/20] Update streamlabs_polly.py --- TTS/streamlabs_polly.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TTS/streamlabs_polly.py b/TTS/streamlabs_polly.py index dc80dc9..aca1fe3 100644 --- a/TTS/streamlabs_polly.py +++ b/TTS/streamlabs_polly.py @@ -43,8 +43,9 @@ class StreamlabsPolly: f"Please set the config variable STREAMLABS_POLLY_VOICE to a valid voice. options are: {voices}" ) voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize() + headers = {"referer": "https://streamlabs.com"} body = {"voice": voice, "text": text, "service": "polly"} - response = requests.post(self.url, data=body) + response = requests.post(self.url, headers=headers, data=body) if not check_ratelimit(response): self.run(text, filepath, random_voice) From f2a5291d1ae1223447f3a65b449f69f980ba3209 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 14:22:29 +0000 Subject: [PATCH 10/20] Bump transformers from 4.37.1 to 4.37.2 Bumps [transformers](https://github.com/huggingface/transformers) from 4.37.1 to 4.37.2. - [Release notes](https://github.com/huggingface/transformers/releases) - [Commits](https://github.com/huggingface/transformers/compare/v4.37.1...v4.37.2) --- updated-dependencies: - dependency-name: transformers dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 46591d1..f804029 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 torch==2.2.0 -transformers==4.37.1 +transformers==4.37.2 ffmpeg-python==0.2.0 elevenlabs==0.2.17 yt-dlp==2023.7.6 \ No newline at end of file From 005cfaa4fe315ab262a4df45ce6c2282d11cc529 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 10:39:44 +0000 Subject: [PATCH 11/20] Bump torch from 2.2.0 to 2.2.2 Bumps [torch](https://github.com/pytorch/pytorch) from 2.2.0 to 2.2.2. - [Release notes](https://github.com/pytorch/pytorch/releases) - [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md) - [Commits](https://github.com/pytorch/pytorch/compare/v2.2.0...v2.2.2) --- updated-dependencies: - dependency-name: torch dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f804029..c022e5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ Flask==2.3.3 clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 -torch==2.2.0 +torch==2.2.2 transformers==4.37.2 ffmpeg-python==0.2.0 elevenlabs==0.2.17 From 3e9b099c4606b380ac7231353d409881e2ffbfbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:42:06 +0000 Subject: [PATCH 12/20] Bump transformers from 4.37.2 to 4.39.2 Bumps [transformers](https://github.com/huggingface/transformers) from 4.37.2 to 4.39.2. - [Release notes](https://github.com/huggingface/transformers/releases) - [Commits](https://github.com/huggingface/transformers/compare/v4.37.2...v4.39.2) --- updated-dependencies: - dependency-name: transformers dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c022e5d..7a66deb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 torch==2.2.2 -transformers==4.37.2 +transformers==4.39.2 ffmpeg-python==0.2.0 elevenlabs==0.2.17 yt-dlp==2023.7.6 \ No newline at end of file From d52c443ff56133ec1fe4fb625b46e4c4ed8199b6 Mon Sep 17 00:00:00 2001 From: Jason Cameron Date: Mon, 1 Apr 2024 12:52:09 -0400 Subject: [PATCH 13/20] Update streamlabs_polly.py --- TTS/streamlabs_polly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TTS/streamlabs_polly.py b/TTS/streamlabs_polly.py index aca1fe3..9ecabf4 100644 --- a/TTS/streamlabs_polly.py +++ b/TTS/streamlabs_polly.py @@ -43,8 +43,8 @@ class StreamlabsPolly: f"Please set the config variable STREAMLABS_POLLY_VOICE to a valid voice. options are: {voices}" ) voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize() - headers = {"referer": "https://streamlabs.com"} body = {"voice": voice, "text": text, "service": "polly"} + headers = {"Referer" : "https://streamlabs.com/" } response = requests.post(self.url, headers=headers, data=body) if not check_ratelimit(response): self.run(text, filepath, random_voice) From a9ea4a077ff5731d1b5bfce2efe864dd45aa0bd1 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:52:25 +0000 Subject: [PATCH 14/20] fixup: Format Python code with Black --- TTS/streamlabs_polly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TTS/streamlabs_polly.py b/TTS/streamlabs_polly.py index 9ecabf4..3f0610d 100644 --- a/TTS/streamlabs_polly.py +++ b/TTS/streamlabs_polly.py @@ -44,7 +44,7 @@ class StreamlabsPolly: ) voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize() body = {"voice": voice, "text": text, "service": "polly"} - headers = {"Referer" : "https://streamlabs.com/" } + headers = {"Referer": "https://streamlabs.com/"} response = requests.post(self.url, headers=headers, data=body) if not check_ratelimit(response): self.run(text, filepath, random_voice) From 11156f13c94da7f91b2b9da33b8875e7c0a1a16b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:19:26 +0000 Subject: [PATCH 15/20] Bump pillow from 10.2.0 to 10.3.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.2.0 to 10.3.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/10.2.0...10.3.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7a66deb..2b8246e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ rich==13.4.1 toml==0.10.2 translators==5.7.6 pyttsx3==2.90 -Pillow==10.2.0 +Pillow==10.3.0 tomlkit==0.11.8 Flask==2.3.3 clean-text==0.6.0 From bdde04fa04f98ca771770c767879a1db56e51144 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:19:34 +0000 Subject: [PATCH 16/20] Bump transformers from 4.39.2 to 4.39.3 Bumps [transformers](https://github.com/huggingface/transformers) from 4.39.2 to 4.39.3. - [Release notes](https://github.com/huggingface/transformers/releases) - [Commits](https://github.com/huggingface/transformers/compare/v4.39.2...v4.39.3) --- updated-dependencies: - dependency-name: transformers dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7a66deb..d8cbd19 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 torch==2.2.2 -transformers==4.39.2 +transformers==4.39.3 ffmpeg-python==0.2.0 elevenlabs==0.2.17 yt-dlp==2023.7.6 \ No newline at end of file From 49b2321099a89bbc08afffef381e634bb4487b36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:30:26 +0000 Subject: [PATCH 17/20] Bump translators from 5.7.6 to 5.9.1 Bumps [translators](https://github.com/UlionTse/translators) from 5.7.6 to 5.9.1. - [Changelog](https://github.com/UlionTse/translators/blob/master/README_history.md) - [Commits](https://github.com/UlionTse/translators/commits) --- updated-dependencies: - dependency-name: translators dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7a66deb..6488a16 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ prawcore~=2.3.0 requests==2.31.0 rich==13.4.1 toml==0.10.2 -translators==5.7.6 +translators==5.9.1 pyttsx3==2.90 Pillow==10.2.0 tomlkit==0.11.8 From 2dfbb71a26c829c239b72187325170e25582fcb5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 10:17:22 +0000 Subject: [PATCH 18/20] Bump torch from 2.2.2 to 2.3.0 Bumps [torch](https://github.com/pytorch/pytorch) from 2.2.2 to 2.3.0. - [Release notes](https://github.com/pytorch/pytorch/releases) - [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md) - [Commits](https://github.com/pytorch/pytorch/compare/v2.2.2...v2.3.0) --- updated-dependencies: - dependency-name: torch dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c85f8fd..92bc26f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ Flask==2.3.3 clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 -torch==2.2.2 +torch==2.3.0 transformers==4.39.3 ffmpeg-python==0.2.0 elevenlabs==0.2.17 From 133e400686205f7eafa112d3749837b8b87c862c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 18:53:04 +0000 Subject: [PATCH 19/20] Bump transformers from 4.39.3 to 4.40.2 Bumps [transformers](https://github.com/huggingface/transformers) from 4.39.3 to 4.40.2. - [Release notes](https://github.com/huggingface/transformers/releases) - [Commits](https://github.com/huggingface/transformers/compare/v4.39.3...v4.40.2) --- updated-dependencies: - dependency-name: transformers dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 92bc26f..80208a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ clean-text==0.6.0 unidecode==1.3.8 spacy==3.5.3 torch==2.3.0 -transformers==4.39.3 +transformers==4.40.2 ffmpeg-python==0.2.0 elevenlabs==0.2.17 yt-dlp==2023.7.6 \ No newline at end of file From a34ee29697a9a23ed335040692830d6b1096e9f8 Mon Sep 17 00:00:00 2001 From: Morgan Barber Date: Fri, 10 May 2024 09:52:08 -0600 Subject: [PATCH 20/20] Fix weird github changes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 143100e..5fadd83 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ I have tried to simplify the code so anyone can read it and start contributing a Please read our [contributing guidelines](CONTRIBUTING.md) for more detailed information. -### For any questions or support join the [Discord](https://discord.gg/WBQT52RrHV) server +### For any questions or support join the [Discord](https://discord.gg/Vkanmh6C8V) server ## Developers and maintainers.