parent
1189f84bd8
commit
2da3d95959
@ -1,32 +1,128 @@
|
||||
# Import the server module
|
||||
import http.server
|
||||
import json
|
||||
import re
|
||||
import webbrowser
|
||||
from pathlib import Path
|
||||
|
||||
# Used "tomlkit" instead of "toml" because it doesn't change formatting on "dump"
|
||||
import tomlkit
|
||||
from flask import (
|
||||
Flask,
|
||||
flash,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
send_from_directory,
|
||||
url_for,
|
||||
)
|
||||
|
||||
# Set the hostname
|
||||
HOST = "localhost"
|
||||
# Set the port number
|
||||
PORT = 4000
|
||||
|
||||
# Define class to display the index page of the web server
|
||||
class PythonServer(http.server.SimpleHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
if self.path == "/GUI":
|
||||
self.path = "index.html"
|
||||
return http.server.SimpleHTTPRequestHandler.do_GET(self)
|
||||
|
||||
|
||||
# Declare object of the class
|
||||
webServer = http.server.HTTPServer((HOST, PORT), PythonServer)
|
||||
# Print the URL of the webserver, new =2 opens in a new tab
|
||||
print(f"Server started at http://{HOST}:{PORT}/GUI/")
|
||||
webbrowser.open(f"http://{HOST}:{PORT}/GUI/", new=2)
|
||||
print("Website opened in new tab")
|
||||
print("Press Ctrl+C to quit")
|
||||
try:
|
||||
# Run the web server
|
||||
webServer.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
# Stop the web server
|
||||
webServer.server_close()
|
||||
print("The server is stopped.")
|
||||
exit()
|
||||
# Configure application
|
||||
app = Flask(__name__, template_folder="GUI")
|
||||
|
||||
# Configure secret key only to use 'flash'
|
||||
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
|
||||
|
||||
|
||||
# Ensure responses aren't cached
|
||||
@app.after_request
|
||||
def after_request(response):
|
||||
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
||||
response.headers["Expires"] = 0
|
||||
response.headers["Pragma"] = "no-cache"
|
||||
return response
|
||||
|
||||
|
||||
# Display index.html
|
||||
@app.route("/")
|
||||
def index():
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
# Make videos.json accessible
|
||||
@app.route("/videos.json")
|
||||
def videos_json():
|
||||
return send_from_directory("video_creation/data", "videos.json")
|
||||
|
||||
|
||||
# Make videos in results folder accessible
|
||||
@app.route("/results/<path:name>")
|
||||
def results(name):
|
||||
return send_from_directory("results", name, as_attachment=True)
|
||||
|
||||
|
||||
@app.route("/add_background", methods=["POST"])
|
||||
def add_background():
|
||||
# Get form values
|
||||
youtube_uri = request.form.get("youtube_uri").strip()
|
||||
filename = request.form.get("filename").strip()
|
||||
citation = request.form.get("citation").strip()
|
||||
position = request.form.get("position").strip()
|
||||
|
||||
# Validate YouTube URI
|
||||
regex = re.compile(
|
||||
r"(?:https?:\/\/)?(?:www\.)?youtu\.?be(?:\.com)?\/?.*(?:watch|embed)?(?:.*v=|v\/|\/)([\w\-_]+)\&?"
|
||||
).search(youtube_uri)
|
||||
|
||||
if not regex:
|
||||
flash("YouTube URI is invalid!", "error")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
youtube_uri = f"https://www.youtube.com/watch?v={regex.group(1)}"
|
||||
|
||||
# Check if position is valid
|
||||
if position == "" or position == "center":
|
||||
position = "center"
|
||||
|
||||
elif position.isdecimal():
|
||||
position = int(position)
|
||||
|
||||
else:
|
||||
flash('Position is invalid! It can be "center" or decimal number.', "error")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
# Sanitize filename
|
||||
filename = filename.replace(" ", "-").split(".")[0]
|
||||
|
||||
# Check if background doesn't already exist
|
||||
with open("utils/backgrounds.json", "r", encoding="utf-8") as backgrounds:
|
||||
data = json.load(backgrounds)
|
||||
|
||||
# Check if key isn't already taken
|
||||
if filename in list(data.keys()):
|
||||
flash("Background video with this name already exist!", "error")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
# Check if the YouTube URI isn't already used under different name
|
||||
if youtube_uri in [data[i][0] for i in list(data.keys())]:
|
||||
flash("Background video with this YouTube URI is already added!", "error")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
# Add background video to json file
|
||||
with open("utils/backgrounds.json", "r+", encoding="utf-8") as backgrounds:
|
||||
data = json.load(backgrounds)
|
||||
|
||||
data[filename] = [youtube_uri, filename + ".mp4", citation, position]
|
||||
backgrounds.seek(0)
|
||||
json.dump(data, backgrounds, ensure_ascii=False, indent=4)
|
||||
|
||||
# Add background video to ".config.template.toml" to make it accessible
|
||||
config = tomlkit.loads(Path("utils/.config.template.toml").read_text())
|
||||
config["settings"]["background"]["background_choice"]["options"].append(filename)
|
||||
|
||||
with Path("utils/.config.template.toml").open("w") as toml_file:
|
||||
toml_file.write(tomlkit.dumps(config))
|
||||
|
||||
flash(f'Added "{citation}-{filename}.mp4" as a new background video!')
|
||||
|
||||
return redirect(url_for("index"))
|
||||
|
||||
|
||||
# Run browser and start the app
|
||||
if __name__ == "__main__":
|
||||
webbrowser.open(f"http://{HOST}:{PORT}", new=2)
|
||||
print("Website opened in new tab. Refresh if it didn't load.")
|
||||
app.run(port=PORT)
|
||||
|
@ -1,45 +0,0 @@
|
||||
# Supported Background. Can add/remove background video here....
|
||||
# <key>-<value> : key -> used as keyword for TOML file. value -> background configuration
|
||||
# Format (value):
|
||||
# 1. Youtube URI
|
||||
# 2. filename
|
||||
# 3. Citation (owner of the video)
|
||||
# 4. Position of image clips in the background. See moviepy reference for more information. (https://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.set_position)
|
||||
background_options = {
|
||||
"motor-gta": ( # Motor-GTA Racing
|
||||
"https://www.youtube.com/watch?v=vw5L4xCPy9Q",
|
||||
"bike-parkour-gta.mp4",
|
||||
"Achy Gaming",
|
||||
lambda t: ("center", 480 + t),
|
||||
),
|
||||
"rocket-league": ( # Rocket League
|
||||
"https://www.youtube.com/watch?v=2X9QGY__0II",
|
||||
"rocket_league.mp4",
|
||||
"Orbital Gameplay",
|
||||
lambda t: ("center", 200 + t),
|
||||
),
|
||||
"minecraft": ( # Minecraft parkour
|
||||
"https://www.youtube.com/watch?v=n_Dv4JMiwK8",
|
||||
"parkour.mp4",
|
||||
"bbswitzer",
|
||||
"center",
|
||||
),
|
||||
"gta": ( # GTA Stunt Race
|
||||
"https://www.youtube.com/watch?v=qGa9kWREOnE",
|
||||
"gta-stunt-race.mp4",
|
||||
"Achy Gaming",
|
||||
lambda t: ("center", 480 + t),
|
||||
),
|
||||
"csgo-surf": ( # CSGO Surf
|
||||
"https://www.youtube.com/watch?v=E-8JlyO59Io",
|
||||
"csgo-surf.mp4",
|
||||
"Aki",
|
||||
"center",
|
||||
),
|
||||
"cluster-truck": ( # Cluster Truck Gameplay
|
||||
"https://www.youtube.com/watch?v=uVKxtdMgJVU",
|
||||
"cluster_truck.mp4",
|
||||
"No Copyright Gameplay",
|
||||
lambda t: ("center", 480 + t),
|
||||
),
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
{
|
||||
"motor-gta": [
|
||||
"https://www.youtube.com/watch?v=vw5L4xCPy9Q",
|
||||
"bike-parkour-gta.mp4",
|
||||
"Achy Gaming",
|
||||
480
|
||||
],
|
||||
"rocket-league": [
|
||||
"https://www.youtube.com/watch?v=2X9QGY__0II",
|
||||
"rocket_league.mp4",
|
||||
"Orbital Gameplay",
|
||||
200
|
||||
],
|
||||
"minecraft": [
|
||||
"https://www.youtube.com/watch?v=n_Dv4JMiwK8",
|
||||
"parkour.mp4",
|
||||
"bbswitzer",
|
||||
"center"
|
||||
],
|
||||
"gta": [
|
||||
"https://www.youtube.com/watch?v=qGa9kWREOnE",
|
||||
"gta-stunt-race.mp4",
|
||||
"Achy Gaming",
|
||||
480
|
||||
],
|
||||
"csgo-surf": [
|
||||
"https://www.youtube.com/watch?v=E-8JlyO59Io",
|
||||
"csgo-surf.mp4",
|
||||
"Aki",
|
||||
"center"
|
||||
],
|
||||
"cluster-truck": [
|
||||
"https://www.youtube.com/watch?v=uVKxtdMgJVU",
|
||||
"cluster_truck.mp4",
|
||||
"No Copyright Gameplay",
|
||||
480
|
||||
]
|
||||
}
|
Loading…
Reference in new issue