Refactor the api
|
@ -6,8 +6,6 @@ ffmpeg \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /python-docker
|
|
||||||
|
|
||||||
COPY requirements.txt requirements.txt
|
COPY requirements.txt requirements.txt
|
||||||
RUN pip3 install -r requirements.txt
|
RUN pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
@ -15,9 +13,18 @@ COPY requirements-pydantic-pin.txt requirements-pydantic-pin.txt
|
||||||
RUN pip3 install -r requirements-pydantic-pin.txt
|
RUN pip3 install -r requirements-pydantic-pin.txt
|
||||||
RUN pip3 install https://github.com/datarhei/core-client-python/archive/refs/tags/1.1.0.tar.gz
|
RUN pip3 install https://github.com/datarhei/core-client-python/archive/refs/tags/1.1.0.tar.gz
|
||||||
|
|
||||||
COPY . .
|
COPY ./scripts/entrypoint.sh /entrypoint.sh
|
||||||
RUN chmod +x start.sh
|
RUN chmod +x /entrypoint.sh
|
||||||
|
|
||||||
|
COPY ./scripts/run.sh /run.sh
|
||||||
|
RUN chmod +x /run.sh
|
||||||
|
|
||||||
|
COPY ./app /app
|
||||||
|
WORKDIR /app/
|
||||||
|
|
||||||
|
ENV PYTHONPATH=/app
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
ENTRYPOINT [ "start.sh" ]
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
CMD ["/run.sh"]
|
|
@ -11,7 +11,7 @@ from flask.helpers import send_file, send_from_directory
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
from core_client import Client
|
from core_client import Client
|
||||||
|
|
||||||
app = Flask(__name__)
|
api = Flask(__name__)
|
||||||
scheduler = BackgroundScheduler()
|
scheduler = BackgroundScheduler()
|
||||||
|
|
||||||
# Log handlers
|
# Log handlers
|
||||||
|
@ -238,7 +238,7 @@ def client_address(req):
|
||||||
return req.environ['HTTP_X_FORWARDED_FOR']
|
return req.environ['HTTP_X_FORWARDED_FOR']
|
||||||
|
|
||||||
# Frontend
|
# Frontend
|
||||||
@app.route('/', methods=['GET'])
|
@api.route('/', methods=['GET'])
|
||||||
def root_route():
|
def root_route():
|
||||||
# Get a list of video files and thumbnails
|
# Get a list of video files and thumbnails
|
||||||
video_files = [file for file in os.listdir(f'{rec_path}/vod/') if file.endswith(('.mp4', '.mkv', '.avi'))]
|
video_files = [file for file in os.listdir(f'{rec_path}/vod/') if file.endswith(('.mp4', '.mkv', '.avi'))]
|
||||||
|
@ -254,18 +254,18 @@ def root_route():
|
||||||
return render_template('index.html', now=datetime.utcnow(), video_files=video_files, thumbnails=sorted_thumbnails)
|
return render_template('index.html', now=datetime.utcnow(), video_files=video_files, thumbnails=sorted_thumbnails)
|
||||||
|
|
||||||
# JSON Data
|
# JSON Data
|
||||||
@app.route('/playhead', methods=['GET'])
|
@api.route('/playhead', methods=['GET'])
|
||||||
def playhead_route():
|
def playhead_route():
|
||||||
global playhead
|
global playhead
|
||||||
return jsonify(playhead)
|
return jsonify(playhead)
|
||||||
|
|
||||||
@app.route('/database', methods=['GET'])
|
@api.route('/database', methods=['GET'])
|
||||||
def database_route():
|
def database_route():
|
||||||
global database
|
global database
|
||||||
return jsonify(database)
|
return jsonify(database)
|
||||||
|
|
||||||
# Images
|
# Images
|
||||||
@app.route("/thumb/<thumb_file>", methods=['GET'])
|
@api.route("/thumb/<thumb_file>", methods=['GET'])
|
||||||
def thumb_route(thumb_file):
|
def thumb_route(thumb_file):
|
||||||
thumb_path = f'{rec_path}/thumb/{thumb_file}'
|
thumb_path = f'{rec_path}/thumb/{thumb_file}'
|
||||||
if not os.path.exists(thumb_path):
|
if not os.path.exists(thumb_path):
|
||||||
|
@ -273,7 +273,7 @@ def thumb_route(thumb_file):
|
||||||
return send_file(thumb_path, mimetype='image/png')
|
return send_file(thumb_path, mimetype='image/png')
|
||||||
|
|
||||||
# Video
|
# Video
|
||||||
@app.route("/video/<video_file>", methods=['GET'])
|
@api.route("/video/<video_file>", methods=['GET'])
|
||||||
def video_route(video_file):
|
def video_route(video_file):
|
||||||
video_path = f'{rec_path}/vod/{video_file}'
|
video_path = f'{rec_path}/vod/{video_file}'
|
||||||
if not os.path.exists(video_path):
|
if not os.path.exists(video_path):
|
||||||
|
@ -281,7 +281,7 @@ def video_route(video_file):
|
||||||
logger_content.warning('[' + client_address(request) + '] stream' + str(video_path))
|
logger_content.warning('[' + client_address(request) + '] stream' + str(video_path))
|
||||||
return send_file(video_path, mimetype='video/mp4')
|
return send_file(video_path, mimetype='video/mp4')
|
||||||
|
|
||||||
@app.route("/video/download/<video_file>", methods=['GET'])
|
@api.route("/video/download/<video_file>", methods=['GET'])
|
||||||
def video_download_route(video_file):
|
def video_download_route(video_file):
|
||||||
video_path = f'{rec_path}/vod/{video_file}'
|
video_path = f'{rec_path}/vod/{video_file}'
|
||||||
if not os.path.exists(video_path):
|
if not os.path.exists(video_path):
|
||||||
|
@ -289,7 +289,7 @@ def video_download_route(video_file):
|
||||||
logger_content.warning('[' + client_address(request) + '] download' + str(video_path))
|
logger_content.warning('[' + client_address(request) + '] download' + str(video_path))
|
||||||
return send_file(video_path, as_attachment=True, download_name=video_file)
|
return send_file(video_path, as_attachment=True, download_name=video_file)
|
||||||
|
|
||||||
@app.route("/video/watch/<video_file_no_extension>", methods=['GET'])
|
@api.route("/video/watch/<video_file_no_extension>", methods=['GET'])
|
||||||
def video_watch_route(video_file_no_extension):
|
def video_watch_route(video_file_no_extension):
|
||||||
video_file = f'{video_file_no_extension}.mp4'
|
video_file = f'{video_file_no_extension}.mp4'
|
||||||
thumb_file = f'{video_file_no_extension}.png'
|
thumb_file = f'{video_file_no_extension}.png'
|
||||||
|
@ -302,5 +302,5 @@ def video_watch_route(video_file_no_extension):
|
||||||
logger_content.warning('[' + client_address(request) + '] player' + str(video_path))
|
logger_content.warning('[' + client_address(request) + '] player' + str(video_path))
|
||||||
return render_template('watch.html', video_file=video_file, thumb_file=thumb_file)
|
return render_template('watch.html', video_file=video_file, thumb_file=thumb_file)
|
||||||
|
|
||||||
def create_app():
|
def create_api():
|
||||||
return app
|
return api
|
3
src/api/app/prestart.sh
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Scheduler API"
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 956 B After Width: | Height: | Size: 956 B |
Before Width: | Height: | Size: 574 B After Width: | Height: | Size: 574 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 702 KiB After Width: | Height: | Size: 702 KiB |
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 3.1 MiB |
12
src/api/scripts/entrypoint.sh
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -f /app/app.py ]; then
|
||||||
|
DEFAULT_MODULE_NAME=api
|
||||||
|
fi
|
||||||
|
MODULE_NAME=${MODULE_NAME:-$DEFAULT_MODULE_NAME}
|
||||||
|
VARIABLE_NAME=${VARIABLE_NAME:-api}
|
||||||
|
export APP_MODULE=${APP_MODULE:-"$MODULE_NAME:$VARIABLE_NAME"}
|
||||||
|
|
||||||
|
exec "$@"
|
100
src/api/scripts/run.sh
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# If there's a prestart.sh script in the /app directory, run it before starting
|
||||||
|
PRE_START_PATH=/app/prestart.sh
|
||||||
|
echo "Checking for script in $PRE_START_PATH"
|
||||||
|
if [ -f $PRE_START_PATH ] ; then
|
||||||
|
echo "Running script $PRE_START_PATH"
|
||||||
|
. "$PRE_START_PATH"
|
||||||
|
else
|
||||||
|
echo "There is no script $PRE_START_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#waitress-serve --trusted-proxy='*' \
|
||||||
|
#--trusted-proxy-headers="x-forwarded-for","x-forwarded-host","x-forwarded-proto","x-forwarded-port" \
|
||||||
|
#--log-untrusted-proxy-headers --threads=16 --call api:create_app
|
||||||
|
|
||||||
|
params=""
|
||||||
|
|
||||||
|
if [[ -v WAITRESS_LISTEN ]]; then
|
||||||
|
listeners=$(echo "$WAITRESS_LISTEN" | tr "," "\n")
|
||||||
|
for listener in $listeners
|
||||||
|
do
|
||||||
|
if [[ -z $params ]]; then
|
||||||
|
params="--listen=$listener"
|
||||||
|
else
|
||||||
|
params=" $params --listen=$listener"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
if [[ -v WAITRESS_HOST ]]; then
|
||||||
|
if [[ -z $params ]]; then
|
||||||
|
params="--host=$WAITRESS_HOST"
|
||||||
|
else
|
||||||
|
params=" $params --host=$WAITRESS_HOST"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_PORT ]]; then
|
||||||
|
if [[ -z $params ]]; then
|
||||||
|
params="--port=$WAITRESS_PORT"
|
||||||
|
else
|
||||||
|
params=" $params --port=$WAITRESS_PORT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $params ]]; then
|
||||||
|
params="--listen=*:8080"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v WAITRESS_CALL ]]; then
|
||||||
|
params=" $params --call"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_NO_IPV6 ]]; then
|
||||||
|
params=" $params --no-ipv6"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_NO_IPV4 ]]; then
|
||||||
|
params=" $params --no-ipv4"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_EXPOSE_TRACEBACKS ]]; then
|
||||||
|
params=" $params --expose-tracebacks"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_NO_EXPOSE_TRACEBACKS ]]; then
|
||||||
|
params=" $params --no-expose-tracebacks"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_THREADS ]]; then
|
||||||
|
params=" $params --threads=$WAITRESS_THREADS"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_IDENT ]]; then
|
||||||
|
params=" $params --ident=$WAITRESS_IDENT"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_OUTBUF_OVERFLOW ]]; then
|
||||||
|
params=" $params --outbuf_overflow=$WAITRESS_OUTBUF_OVERFLOW"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_OUTBUF_HIGH_WATERMARK ]]; then
|
||||||
|
params=" $params --outbuf_high_watermark=$WAITRESS_OUTBUF_HIGH_WATERMARK"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_INBUF_OVERFLOW ]]; then
|
||||||
|
params=" $params --inbuf_overflow=$WAITRESS_INBUF_OVERFLOW"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_CONNECTION_LIMIT ]]; then
|
||||||
|
params=" $params --connection_limit=$WAITRESS_CONNECTION_LIMIT"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_MAX_REQUEST_HEADER_SIZE ]]; then
|
||||||
|
params=" $params --max_request_header_size=$WAITRESS_MAX_REQUEST_HEADER_SIZE"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_MAX_REQUEST_BODY_SIZE ]]; then
|
||||||
|
params=" $params --max_request_body_size=$WAITRESS_MAX_REQUEST_BODY_SIZE"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_ASYNCORE_LOOP_TIMEOUT ]]; then
|
||||||
|
params=" $params --asyncore_loop_timeout=$WAITRESS_ASYNCORE_LOOP_TIMEOUT"
|
||||||
|
fi
|
||||||
|
if [[ -v WAITRESS_ASYNCORE_USE_POLL ]]; then
|
||||||
|
params=" $params --asyncore_use_poll=$WAITRESS_ASYNCORE_USE_POLL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start Waitress
|
||||||
|
echo "waitress-serve $params $APP_MODULE"
|
||||||
|
exec waitress-serve $params $APP_MODULE
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
waitress-serve --port=8080 --trusted-proxy='*' \
|
|
||||||
--trusted-proxy-headers="x-forwarded-for","x-forwarded-host","x-forwarded-proto","x-forwarded-port" \
|
|
||||||
--log-untrusted-proxy-headers --threads=16 --call api:create_app
|
|