From 45a296db802840be708b8679bc5ceb309b117249 Mon Sep 17 00:00:00 2001 From: CordlessCoder Date: Mon, 6 Jun 2022 20:42:46 +0300 Subject: [PATCH] setup.py heavily refactored, all files formatted with python-BLACK and added shebang lines --- build.sh | 3 +- main.py | 3 +- reddit/subreddit.py | 7 +- run.sh | 3 +- setup.py | 247 ++++++++++++++++-------- utils/console.py | 1 + utils/loader.py | 9 +- video_creation/background.py | 2 + video_creation/final_video.py | 18 +- video_creation/screenshot_downloader.py | 6 +- video_creation/voices.py | 1 + 11 files changed, 200 insertions(+), 100 deletions(-) mode change 100644 => 100755 setup.py diff --git a/build.sh b/build.sh index 7d4dfc6..45ebd33 100755 --- a/build.sh +++ b/build.sh @@ -1 +1,2 @@ -docker build -t rvmt . \ No newline at end of file +#!/bin/sh +docker build -t rvmt . diff --git a/main.py b/main.py index 9aabe78..92cc886 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Main from utils.console import print_markdown from utils.console import print_step @@ -54,7 +55,7 @@ if not os.path.exists(".env"): console.log("[red] Your .env file is invalid, or was never created. Standby.") for val in REQUIRED_VALUES: - #print(os.getenv(val)) + # print(os.getenv(val)) if val not in os.environ or not os.getenv(val): console.log(f'[bold red]Missing Variable: "{val}"') configured = False diff --git a/reddit/subreddit.py b/reddit/subreddit.py index c560293..a52a214 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from rich.console import Console from utils.console import print_markdown, print_step, print_substep from dotenv import load_dotenv @@ -48,7 +49,11 @@ def get_subreddit_threads(): # ! Prompt the user to enter a subreddit 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? "), + ) ) except ValueError: subreddit = reddit.subreddit("askreddit") diff --git a/run.sh b/run.sh index 4dcb69a..3ee26db 100755 --- a/run.sh +++ b/run.sh @@ -1 +1,2 @@ -docker run -v $(pwd)/out/:/app/assets -v $(pwd)/.env:/app/.env -it rvmt \ No newline at end of file +#!/bin/sh +docker run -v "$(pwd)/out/:/app/assets" -v "$(pwd)/.env:/app/.env -it rvmt" diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index feaa344..0154ce9 --- a/setup.py +++ b/setup.py @@ -1,55 +1,98 @@ -""" - -Setup Script for RedditVideoMakerBot +#!/usr/bin/env python3 +# Setup Script for RedditVideoMakerBot -""" # Imports import os -import time +import subprocess +import re from utils.console import print_markdown from utils.console import print_step -from utils.console import print_substep from rich.console import Console from utils.loader import Loader -from os.path import exists + console = Console() -setup_done = exists(".setup-done-before") -if setup_done == True: - console.log("[red]Setup was already completed! Please make sure you have to run this script again. If you have to, please delete the file .setup-done-before") - exit() +def handle_input( + message: str = "", + check_type=False, + match: str = "", + err_message: str = "", + nmin=None, + nmax=None, + oob_error="", +): + match = re.compile(match) + while True: + user_input = input(message + "\n> ").strip() + if re.match(match, user_input) is not None: + if check_type is not False: + try: + user_input = check_type(user_input) + if nmin is not None and user_input < nmin: + console.log("[red]" + oob_error) # Input too low failstate + continue + if nmax is not None and user_input > nmax: + console.log("[red]" + oob_error) # Input too high + continue + break # Successful type conversion and number in bounds + except ValueError: + console.log("[red]" + err_message) # Type conversion failed + continue + if ( + nmin is not None and len(user_input) < nmin + ): # Check if string is long enough + console.log("[red]" + oob_error) + continue + if ( + nmax is not None and len(user_input) > nmax + ): # Check if string is not too long + console.log("[red]" + oob_error) + continue + break + console.log("[red]" + err_message) + + return user_input + + +if os.path.isfile(".setup-done-before"): + console.log( + "[red]Setup was already completed! Please make sure you have to run this script again. If that is such, delete the file .setup-done-before" + ) + exit() # These lines ensure the user: # - knows they are in setup mode # - knows that they are about to erase any other setup files/data. print_step("Setup Assistant") - print_markdown( - "### You're in the setup wizard. Ensure you're supposed to be here, then type yes to continue. If you're not sure, type no to quit." + "### You're in the setup wizard. Ensure you're supposed to be here, then type yes to continue. If you're not sure, type no to quit." ) + # This Input is used to ensure the user is sure they want to continue. -ensureSetupIsRequired = input("Are you sure you want to continue? > ").casefold() -if ensureSetupIsRequired != "yes": - console.print("[red]Exiting...") - time.sleep(0.5) - exit() -else: - # Again, let them know they are about to erase all other setup data. - console.print("[bold red] This will overwrite your current settings. Are you sure you want to continue? [bold green]yes/no") - overwriteSettings = input("Are you sure you want to continue? > ").casefold() - if overwriteSettings != "yes": - console.print("[red]Abort mission! Exiting...") - time.sleep(0.5) - exit() - else: - # Once they confirm, move on with the script. - console.print("[bold green]Alright! Let's get started!") - time.sleep(1) +if input("Are you sure you want to continue? > ").strip().casefold() != "yes": + console.print("[red]Exiting...") + exit() +# This code is inaccessible if the prior check fails, and thus an else statement is unnecessary + +# Again, let them know they are about to erase all other setup data. +console.print( + "[bold red] This will overwrite your current settings. Are you sure you want to continue? [bold green]yes/no" +) + + +if input("Are you sure you want to continue? > ").strip().casefold() != "yes": + console.print("[red]Abort mission! Exiting...") + exit() +# This is once again inaccessible if the prior checks fail +# Once they confirm, move on with the script. +console.print("[bold green]Alright! Let's get started!") + +print("\n") console.log("Ensure you have the following ready to enter:") console.log("[bold green]Reddit Client ID") console.log("[bold green]Reddit Client Secret") @@ -59,64 +102,108 @@ console.log("[bold green]Reddit 2FA (yes or no)") console.log("[bold green]Opacity (range of 0-1, decimals are OK)") console.log("[bold green]Subreddit (without r/ or /r/)") console.log("[bold green]Theme (light or dark)") -time.sleep(0.5) -console.print("[green]If you don't have these, please follow the instructions in the README.md file to set them up.") -console.print("[green]If you do have these, type yes to continue. If you dont, go ahead and grab those quickly and come back.") -confirmUserHasCredentials = input("Are you sure you have the credentials? > ").casefold() -if confirmUserHasCredentials != "yes": - console.print("[red]I don't understand that.") - console.print("[red]Exiting...") - exit() -else: - console.print("[bold green]Alright! Let's get started!") - time.sleep(1) +console.print( + "[green]If you don't have these, please follow the instructions in the README.md file to set them up." +) +console.print( + "[green]If you do have these, type yes to continue. If you dont, go ahead and grab those quickly and come back." +) +print() -""" -Begin the setup process. +if input("Are you sure you have the credentials? > ").strip().casefold() != "yes": + console.print("[red]I don't understand that.") + console.print("[red]Exiting...") + exit() -""" + +console.print("[bold green]Alright! Let's get started!") + +# Begin the setup process. console.log("Enter your credentials now.") -cliID = input("Client ID > ") -cliSec = input("Client Secret > ") -user = input("Username > ") -passw = input("Password > ") -twofactor = input("2fa Enabled? (yes/no) > ") -opacity = input("Opacity? (range of 0-1) > ") -subreddit = input("Subreddit (without r/) > ") -theme = input("Theme? (light or dark) > ") -console.log("Attempting to save your credentials...") -loader = Loader("Saving Credentials...", "Done!").start() - # you can also put a while loop here, e.g. while VideoIsBeingMade == True: ... -time.sleep(0.5) -console.log("Removing old .env file...") -os.remove(".env") -time.sleep(0.5) -console.log("Creating new .env file...") -with open('.env', 'a') as f: - f.write(f'REDDIT_CLIENT_ID="{cliID}"\n') - time.sleep(0.5) - f.write(f'REDDIT_CLIENT_SECRET="{cliSec}"\n') - time.sleep(0.5) - f.write(f'REDDIT_USERNAME="{user}"\n') - time.sleep(0.5) - f.write(f'REDDIT_PASSWORD="{passw}"\n') - time.sleep(0.5) - f.write(f'REDDIT_2FA="{twofactor}"\n') - time.sleep(0.5) - f.write(f'THEME="{theme}"\n') - time.sleep(0.5) - f.write(f'SUBREDDIT="{subreddit}"\n') - time.sleep(0.5) - f.write(f'OPACITY="{opacity}"\n') - -with open('.setup-done-before', 'a') as f: - f.write("This file blocks the setup assistant from running again. Delete this file to run setup again.") +client_id = handle_input( + "Client ID > ", + False, + "[-a-zA-Z0-9._~+/]+=*", + "That is somehow not a correct ID, try again.", + 20, + 40, + "The ID should be over 20 and under 40 characters, double check your input.", +) +client_sec = handle_input( + "Client Secret > ", + False, + "[-a-zA-Z0-9._~+/]+=*", + "That is somehow not a correct secret, try again.", + 20, + 40, + "The secret should be over 20 and under 40 characters, double check your input.", +) +user = handle_input( + "Username > ", + False, + r"[_0-9a-zA-Z]+", + "That is not a valid user", + 3, + 20, + "A username HAS to be between 3 and 20 characters", +) +passw = handle_input("Password > ", False, "", "", 8, None, "Password too short") +twofactor = handle_input( + "2fa Enabled? (yes/no) > ", + False, + r"(yes)|(no)", + "You need to input either yes or no", +) +opacity = handle_input( + "Opacity? (range of 0-1) > ", + float, + "", + "You need to input a number between 0 and 1", + 0, + 1, + "Your number is not between 0 and 1", +) +subreddit = handle_input( + "Subreddit (without r/) > ", + False, + r"[_0-9a-zA-Z]+", + "This subreddit cannot exist, make sure you typed it in correctly and removed the r/ (or /r/).", + 3, + 20, + "A subreddit name HAS to be between 3 and 20 characters", +) +theme = handle_input( + "Theme? (light or dark) > ", + False, + r"(light)|(dark)", + "You need to input 'light' or 'dark'", +) +loader = Loader("Attempting to save your credentials...", "Done!").start() +# you can also put a while loop here, e.g. while VideoIsBeingMade == True: ... +console.log("Writing to the .env file...") +with open(".env", "w") as f: + f.write( + f"""REDDIT_CLIENT_ID="{client_id}" +REDDIT_CLIENT_SECRET="{client_sec}" +REDDIT_USERNAME="{user}" +REDDIT_PASSWORD="{passw}" +REDDIT_2FA="{twofactor}" +THEME="{theme}" +SUBREDDIT="{subreddit}" +OPACITY={opacity} +""" + ) + +with open(".setup-done-before", "w") as f: + f.write( + "This file blocks the setup assistant from running again. Delete this file to run setup again." + ) loader.stop() console.log("[bold green]Setup Complete! Returning...") # Post-Setup: send message and try to run main.py again. -os.system("python3 main.py") +subprocess.call("python3 main.py", shell=True) diff --git a/utils/console.py b/utils/console.py index d024dc0..11ee429 100644 --- a/utils/console.py +++ b/utils/console.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from rich.console import Console from rich.markdown import Markdown from rich.padding import Padding diff --git a/utils/loader.py b/utils/loader.py index 58fd662..46c40fe 100644 --- a/utils/loader.py +++ b/utils/loader.py @@ -1,9 +1,8 @@ -""" -Okay, have to admit. This code is from StackOverflow. It's so efficient, that it's probably the best way to do it. -Although, it is edited to use less threads. +# Okay, have to admit. This code is from StackOverflow. It's so efficient, that it's probably the best way to do it. +# Although, it is edited to use less threads. + -""" from itertools import cycle from shutil import get_terminal_size from threading import Thread @@ -50,4 +49,4 @@ class Loader: def __exit__(self, exc_type, exc_value, tb): # handle exceptions with those variables ^ - self.stop() \ No newline at end of file + self.stop() diff --git a/video_creation/background.py b/video_creation/background.py index dce46bd..fe7b5ec 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from random import randrange from yt_dlp import YoutubeDL @@ -13,6 +14,7 @@ def get_start_and_end_times(video_length, length_of_clip): random_time = randrange(180, int(length_of_clip) - int(video_length)) return random_time, random_time + video_length + def download_background(): """Downloads the background video from youtube. diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 93bac6f..8a635d6 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from moviepy.editor import ( VideoFileClip, AudioFileClip, @@ -7,7 +8,7 @@ from moviepy.editor import ( CompositeAudioClip, CompositeVideoClip, ) -import reddit.subreddit +import reddit.subreddit import re from utils.console import print_step from dotenv import load_dotenv @@ -16,13 +17,12 @@ import os W, H = 1080, 1920 - def make_final_video(number_of_clips): - + # Calls opacity from the .env load_dotenv() - opacity = os.getenv('OPACITY') - + opacity = os.getenv("OPACITY") + print_step("Creating the final video...") VideoFileClip.reW = lambda clip: clip.resize(width=W) @@ -65,7 +65,7 @@ def make_final_video(number_of_clips): .set_position("center") .resize(width=W - 100) .set_opacity(float(opacity)), - ) + ) else: image_clips.insert( 0, @@ -74,13 +74,15 @@ def make_final_video(number_of_clips): .set_position("center") .resize(width=W - 100) .set_opacity(float(opacity)), - ) + ) image_concat = concatenate_videoclips(image_clips).set_position( ("center", "center") ) image_concat.audio = audio_composite final = CompositeVideoClip([background_clip, image_concat]) - filename = (re.sub('[?\"%*:|<>]', '', ("assets/" + reddit.subreddit.submission.title + ".mp4"))) + filename = re.sub( + '[?"%*:|<>]', "", ("assets/" + reddit.subreddit.submission.title + ".mp4") + ) final.write_videofile(filename, fps=30, audio_codec="aac", audio_bitrate="192k") for i in range(0, number_of_clips): pass diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index d3d32ef..2925daa 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from playwright.sync_api import sync_playwright, ViewportSize from pathlib import Path from rich.progress import track @@ -24,7 +25,7 @@ def download_screenshots_of_reddit_posts(reddit_object, screenshot_num, theme): context = browser.new_context() if theme.casefold() == "dark": - cookie_file = open('video_creation/cookies.json') + cookie_file = open("video_creation/cookies.json") cookies = json.load(cookie_file) context.add_cookies(cookies) @@ -58,5 +59,4 @@ def download_screenshots_of_reddit_posts(reddit_object, screenshot_num, theme): path=f"assets/png/comment_{idx}.png" ) - print_substep("Screenshots downloaded Successfully.", - style="bold green") + print_substep("Screenshots downloaded Successfully.", style="bold green") diff --git a/video_creation/voices.py b/video_creation/voices.py index c0df8b7..5a64f7b 100644 --- a/video_creation/voices.py +++ b/video_creation/voices.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from gtts import gTTS from pathlib import Path from mutagen.mp3 import MP3