Reorganised the webservers (temp for now) and docker-compose.yml now works
@@ -5,6 +5,7 @@ services:
|
|||||||
context: ./nginx
|
context: ./nginx
|
||||||
ports:
|
ports:
|
||||||
- "1935:1935" # RTMP
|
- "1935:1935" # RTMP
|
||||||
|
- "8080:8080"
|
||||||
depends_on:
|
depends_on:
|
||||||
- flask
|
- flask
|
||||||
networks:
|
networks:
|
||||||
@@ -12,7 +13,7 @@ services:
|
|||||||
|
|
||||||
flask:
|
flask:
|
||||||
build:
|
build:
|
||||||
context: ./core
|
context: ./web_server
|
||||||
ports:
|
ports:
|
||||||
- "5000:5000"
|
- "5000:5000"
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -1,26 +1,7 @@
|
|||||||
FROM ubuntu:22.04
|
FROM tiangolo/nginx-rtmp
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
build-essential \
|
|
||||||
libpcre3 libpcre3-dev \
|
|
||||||
libssl-dev \
|
|
||||||
zlib1g-dev \
|
|
||||||
wget git
|
|
||||||
|
|
||||||
# Download and build NGINX with RTMP
|
|
||||||
RUN wget http://nginx.org/download/nginx-1.25.2.tar.gz && \
|
|
||||||
tar -xzvf nginx-1.25.2.tar.gz && \
|
|
||||||
git clone https://github.com/arut/nginx-rtmp-module.git && \
|
|
||||||
cd nginx-1.25.2 && \
|
|
||||||
./configure --add-module=../nginx-rtmp-module --with-http_ssl_module && \
|
|
||||||
make && make install
|
|
||||||
|
|
||||||
# Copy custom NGINX configuration
|
|
||||||
COPY nginx.conf /etc/nginx/nginx.conf
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
EXPOSE 1935 8080
|
||||||
|
|
||||||
# Expose RTMP and HTTP ports
|
# Start the Nginx server
|
||||||
EXPOSE 1935
|
CMD [ "nginx", "-g", "daemon off;" ]
|
||||||
|
|
||||||
# Start NGINX
|
|
||||||
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
|
|
||||||
|
|||||||
@@ -1,12 +1,43 @@
|
|||||||
|
worker_processes 1;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
rtmp {
|
rtmp {
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 1935;
|
listen 1935; # RTMP listen port
|
||||||
chunk_size 4096;
|
|
||||||
|
|
||||||
application live {
|
application live {
|
||||||
live on;
|
live on;
|
||||||
record off;
|
|
||||||
|
# HLS Configuration (optional)
|
||||||
|
hls on; # Enable HLS conversion
|
||||||
|
hls_path /tmp/hls; # Path to store HLS files (use an absolute path)
|
||||||
|
hls_nested on;
|
||||||
|
hls_fragment 5s; # Duration of each HLS segment
|
||||||
|
hls_playlist_length 30s; # Length of HLS playlist (total duration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
# Enable HLS
|
||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
|
||||||
|
location /hls/ {
|
||||||
|
types {
|
||||||
|
application/vnd.apple.mpegurl m3u8;
|
||||||
|
video/mp2t ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
root /tmp;
|
||||||
|
add_header Cache-Control no-cache;
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
|
||||||
|
autoindex on; # Enable directory indexing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
2
web_server/.flaskenv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
FLASK_APP=blueprints.__init__
|
||||||
|
FLASK_DEBUG=True
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
FROM python:3.10
|
FROM python:3.10
|
||||||
|
|
||||||
# Set working directory
|
# Set the working directory
|
||||||
WORKDIR /core
|
WORKDIR /web_server
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
COPY requirements.txt requirements.txt
|
COPY requirements.txt requirements.txt
|
||||||
@@ -10,8 +10,12 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|||||||
# Copy application code
|
# Copy application code
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV FLASK_APP=blueprints.__init__
|
||||||
|
ENV FLASK_DEBUG=True
|
||||||
|
|
||||||
# Expose Flask's port
|
# Expose Flask's port
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
||||||
# Start the Flask app
|
# Start the Flask app
|
||||||
CMD ["python", "app.py"]
|
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
|
||||||
BIN
web_server/__pycache__/forms.cpython-311.pyc
Normal file
@@ -1,9 +1,9 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_session import Session
|
from flask_session import Session
|
||||||
from core.blueprints.utils import logged_in_user
|
from blueprints.utils import logged_in_user
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
app = Flask(__name__, template_folder="../../ui/templates/", static_folder="../../ui/static")
|
app = Flask(__name__, template_folder="../ui/templates/", static_folder="../ui/static/")
|
||||||
app.config["SECRET_KEY"] = ""
|
app.config["SECRET_KEY"] = ""
|
||||||
app.config["SESSION_PERMANENT"] = False
|
app.config["SESSION_PERMANENT"] = False
|
||||||
app.config["SESSION_TYPE"] = "filesystem"
|
app.config["SESSION_TYPE"] = "filesystem"
|
||||||
@@ -12,9 +12,9 @@ def create_app():
|
|||||||
app.before_request(logged_in_user)
|
app.before_request(logged_in_user)
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
from core.blueprints.authentication import auth_bp
|
from blueprints.authentication import auth_bp
|
||||||
from core.blueprints.main import main_bp
|
from blueprints.main import main_bp
|
||||||
from core.blueprints.stripe import stripe_bp
|
from blueprints.stripe import stripe_bp
|
||||||
|
|
||||||
app.register_blueprint(auth_bp)
|
app.register_blueprint(auth_bp)
|
||||||
app.register_blueprint(main_bp)
|
app.register_blueprint(main_bp)
|
||||||
BIN
web_server/blueprints/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
web_server/blueprints/__pycache__/authentication.cpython-311.pyc
Normal file
BIN
web_server/blueprints/__pycache__/main.cpython-311.pyc
Normal file
BIN
web_server/blueprints/__pycache__/stripe.cpython-311.pyc
Normal file
BIN
web_server/blueprints/__pycache__/utils.cpython-311.pyc
Normal file
@@ -1,8 +1,8 @@
|
|||||||
from flask import Blueprint, render_template, session, request, url_for, redirect, g
|
from flask import Blueprint, render_template, session, request, url_for, redirect, g
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from core.forms import SignupForm, LoginForm
|
from forms import SignupForm, LoginForm
|
||||||
from database.database import Database
|
from database.database import Database
|
||||||
from core.blueprints.utils import login_required
|
from blueprints.utils import login_required
|
||||||
|
|
||||||
auth_bp = Blueprint("auth", __name__)
|
auth_bp = Blueprint("auth", __name__)
|
||||||
|
|
||||||
@@ -1,38 +1,38 @@
|
|||||||
from flask import render_template, Blueprint, request, jsonify
|
from flask import render_template, Blueprint, request, jsonify
|
||||||
|
|
||||||
import stripe
|
import stripe
|
||||||
|
|
||||||
stripe_bp = Blueprint("stripe", __name__)
|
stripe_bp = Blueprint("stripe", __name__)
|
||||||
|
|
||||||
stripe.api_key = 'sk_test_51QikGlGk6yuk3uA8muEMPjMhUvbZWZiMCYQArZRXcFVn26hbt1kTz5yUVWkk3RQlltArbAXmVmkfEHU2z1Ch5Obv00Y03oT127'
|
stripe.api_key = 'sk_test_51QikGlGk6yuk3uA8muEMPjMhUvbZWZiMCYQArZRXcFVn26hbt1kTz5yUVWkk3RQlltArbAXmVmkfEHU2z1Ch5Obv00Y03oT127'
|
||||||
|
|
||||||
@stripe_bp.route('/create-checkout-session', methods=['POST'])
|
@stripe_bp.route('/create-checkout-session', methods=['POST'])
|
||||||
def create_checkout_session():
|
def create_checkout_session():
|
||||||
try:
|
try:
|
||||||
session = stripe.checkout.Session.create(
|
session = stripe.checkout.Session.create(
|
||||||
ui_mode = 'embedded',
|
ui_mode = 'embedded',
|
||||||
payment_method_types=['card'],
|
payment_method_types=['card'],
|
||||||
line_items=[
|
line_items=[
|
||||||
{
|
{
|
||||||
'price': 'price_1QikNCGk6yuk3uA86mZf3dmM', #Subscription ID
|
'price': 'price_1QikNCGk6yuk3uA86mZf3dmM', #Subscription ID
|
||||||
'quantity': 1,
|
'quantity': 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
mode='subscription',
|
mode='subscription',
|
||||||
redirect_on_completion = 'never'
|
redirect_on_completion = 'never'
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
return jsonify(clientSecret=session.client_secret)
|
return jsonify(clientSecret=session.client_secret)
|
||||||
|
|
||||||
@stripe_bp.route('/session-status', methods=['GET']) # check for payment status
|
@stripe_bp.route('/session-status', methods=['GET']) # check for payment status
|
||||||
def session_status():
|
def session_status():
|
||||||
session = stripe.checkout.Session.retrieve(request.args.get('session_id'))
|
session = stripe.checkout.Session.retrieve(request.args.get('session_id'))
|
||||||
|
|
||||||
return jsonify(status=session.status, customer_email=session.customer_details.email)
|
return jsonify(status=session.status, customer_email=session.customer_details.email)
|
||||||
|
|
||||||
@stripe_bp.route('/checkout', methods=['GET'])
|
@stripe_bp.route('/checkout', methods=['GET'])
|
||||||
def checkout():
|
def checkout():
|
||||||
return render_template("checkout.html")
|
return render_template("checkout.html")
|
||||||
BIN
web_server/database/__pycache__/database.cpython-311.pyc
Normal file
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -1,20 +1,20 @@
|
|||||||
blinker==1.9.0
|
blinker==1.9.0
|
||||||
cachelib==0.13.0
|
cachelib==0.13.0
|
||||||
certifi==2024.12.14
|
certifi==2024.12.14
|
||||||
charset-normalizer==3.4.1
|
charset-normalizer==3.4.1
|
||||||
click==8.1.8
|
click==8.1.8
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
Flask==3.1.0
|
Flask==3.1.0
|
||||||
Flask-Session==0.8.0
|
Flask-Session==0.8.0
|
||||||
Flask-WTF==1.2.2
|
Flask-WTF==1.2.2
|
||||||
idna==3.10
|
idna==3.10
|
||||||
itsdangerous==2.2.0
|
itsdangerous==2.2.0
|
||||||
Jinja2==3.1.5
|
Jinja2==3.1.5
|
||||||
MarkupSafe==3.0.2
|
MarkupSafe==3.0.2
|
||||||
msgspec==0.19.0
|
msgspec==0.19.0
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
stripe==11.4.1
|
stripe==11.4.1
|
||||||
typing_extensions==4.12.2
|
typing_extensions==4.12.2
|
||||||
urllib3==2.3.0
|
urllib3==2.3.0
|
||||||
Werkzeug==3.1.3
|
Werkzeug==3.1.3
|
||||||
WTForms==3.2.1
|
WTForms==3.2.1
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
const stripe = Stripe("pk_test_51QikGlGk6yuk3uA8MT3uQrPMpUqJlKzkxfbrfrd34yXolWSbJYEFWm674s2aUydZyjjS0W2oByEJTV0LXMs1pWTk002ioHxQl6");
|
const stripe = Stripe("pk_test_51QikGlGk6yuk3uA8MT3uQrPMpUqJlKzkxfbrfrd34yXolWSbJYEFWm674s2aUydZyjjS0W2oByEJTV0LXMs1pWTk002ioHxQl6");
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
// Create a Checkout Session
|
// Create a Checkout Session
|
||||||
async function initialize() {
|
async function initialize() {
|
||||||
const fetchClientSecret = async () => {
|
const fetchClientSecret = async () => {
|
||||||
const response = await fetch("/create-checkout-session", {
|
const response = await fetch("/create-checkout-session", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
const { clientSecret } = await response.json();
|
const { clientSecret } = await response.json();
|
||||||
return clientSecret;
|
return clientSecret;
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkout = await stripe.initEmbeddedCheckout({
|
const checkout = await stripe.initEmbeddedCheckout({
|
||||||
fetchClientSecret,
|
fetchClientSecret,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mount Checkout
|
// Mount Checkout
|
||||||
checkout.mount('#checkout');
|
checkout.mount('#checkout');
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block header_config %}
|
{% block header_config %}
|
||||||
<link rel="stylesheet" href="style.css" />
|
<link rel="stylesheet" href="style.css" />
|
||||||
<script src="https://js.stripe.com/v3/"></script>
|
<script src="https://js.stripe.com/v3/"></script>
|
||||||
<script src="{{ url_for('static', filename='checkout.js') }}" defer></script>
|
<script src="{{ url_for('static', filename='checkout.js') }}" defer></script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block main_content %}
|
{% block main_content %}
|
||||||
<!-- Display a payment form -->
|
<!-- Display a payment form -->
|
||||||
<div id="checkout">
|
<div id="checkout">
|
||||||
<!-- Checkout will insert the payment form here -->
|
<!-- Checkout will insert the payment form here -->
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||