parent
1189f84bd8
commit
2da3d95959
@ -1,32 +1,128 @@
|
|||||||
# Import the server module
|
import json
|
||||||
import http.server
|
import re
|
||||||
import webbrowser
|
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
|
# Set the hostname
|
||||||
HOST = "localhost"
|
HOST = "localhost"
|
||||||
# Set the port number
|
# Set the port number
|
||||||
PORT = 4000
|
PORT = 4000
|
||||||
|
|
||||||
# Define class to display the index page of the web server
|
# Configure application
|
||||||
class PythonServer(http.server.SimpleHTTPRequestHandler):
|
app = Flask(__name__, template_folder="GUI")
|
||||||
def do_GET(self):
|
|
||||||
if self.path == "/GUI":
|
# Configure secret key only to use 'flash'
|
||||||
self.path = "index.html"
|
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
|
||||||
return http.server.SimpleHTTPRequestHandler.do_GET(self)
|
|
||||||
|
|
||||||
|
# Ensure responses aren't cached
|
||||||
# Declare object of the class
|
@app.after_request
|
||||||
webServer = http.server.HTTPServer((HOST, PORT), PythonServer)
|
def after_request(response):
|
||||||
# Print the URL of the webserver, new =2 opens in a new tab
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
||||||
print(f"Server started at http://{HOST}:{PORT}/GUI/")
|
response.headers["Expires"] = 0
|
||||||
webbrowser.open(f"http://{HOST}:{PORT}/GUI/", new=2)
|
response.headers["Pragma"] = "no-cache"
|
||||||
print("Website opened in new tab")
|
return response
|
||||||
print("Press Ctrl+C to quit")
|
|
||||||
try:
|
|
||||||
# Run the web server
|
# Display index.html
|
||||||
webServer.serve_forever()
|
@app.route("/")
|
||||||
except KeyboardInterrupt:
|
def index():
|
||||||
# Stop the web server
|
return render_template("index.html")
|
||||||
webServer.server_close()
|
|
||||||
print("The server is stopped.")
|
|
||||||
exit()
|
# 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