mirror of
https://github.com/linuxserver/docker-ffmpeg.git
synced 2026-02-20 04:56:23 +08:00
171 lines
4.8 KiB
Python
171 lines
4.8 KiB
Python
from flask import Flask, send_from_directory, request
|
|
from flask_socketio import SocketIO
|
|
from pathlib import Path
|
|
import glob
|
|
import os
|
|
import pty
|
|
import re
|
|
import select
|
|
import subprocess
|
|
import time
|
|
import yaml
|
|
# Error logging only
|
|
#import logging
|
|
#log = logging.getLogger('werkzeug')
|
|
#log.setLevel(logging.ERROR)
|
|
|
|
# Websocket server
|
|
app = Flask(__name__,static_folder="public")
|
|
sio = SocketIO(app)
|
|
|
|
################################
|
|
# Job functions #
|
|
################################
|
|
|
|
# Build and return an array of stuff to process
|
|
def build_list(extension):
|
|
# Sanitize exenstion
|
|
extension_regex = re.sub(r'([A-Za-z])', lambda m: '[' + m.group(1).upper() + m.group(1).lower() + ']', extension)
|
|
# Build full glob
|
|
all_files = glob.glob('/in/**/*' + extension_regex, recursive=True)
|
|
# Check if anything in this array has a processed log or is not a file and pull it out
|
|
for file in all_files:
|
|
# Remove files from processing list if they have log files and no processing pid
|
|
if not os.path.isfile(file) or os.path.isfile(file + '.ffmpeg_log'):
|
|
if not os.path.isfile(file + '.ffmpeg_processing'):
|
|
all_files.remove(file)
|
|
return all_files
|
|
|
|
# run individual job
|
|
def run_job(file,job_command):
|
|
try:
|
|
# Create a processing file on disk
|
|
os.remove(file + '.ffmpeg_processing')
|
|
os.mknod(file + '.ffmpeg_processing')
|
|
# Create output structure
|
|
filename = os.path.basename(file)
|
|
outpath = Path('/out/' + os.path.dirname(os.path.abspath(file)).replace('/in/', '', 1))
|
|
outpath.mkdir(parents=True)
|
|
# Remove processing file on disk
|
|
time.sleep(5)
|
|
os.remove(file + '.ffmpeg_processing')
|
|
except OSError:
|
|
pass
|
|
|
|
# run jobs based on config
|
|
def run_jobs(config):
|
|
for command in config['commands']:
|
|
file_list = build_list(command['extension'])
|
|
for file in file_list:
|
|
run_job(file,command['command'])
|
|
|
|
# Background job thread loop for file processing
|
|
def processor():
|
|
while True:
|
|
with open("/config/config.yml", 'r') as stream:
|
|
try:
|
|
config = yaml.safe_load(stream)
|
|
if config['enabled'] is True:
|
|
run_jobs(config)
|
|
except yaml.YAMLError as e:
|
|
print(e)
|
|
# Loop every 5 seconds to check config file and run jobs
|
|
stream.close()
|
|
time.sleep(5)
|
|
sio.start_background_task(processor)
|
|
|
|
################################
|
|
# Web Server #
|
|
################################
|
|
|
|
# Default index root
|
|
static_file_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'public')
|
|
@app.route("/")
|
|
def index():
|
|
return send_from_directory(static_file_dir, 'index.html')
|
|
|
|
# Send the current config to the user to render
|
|
@sio.on('getconfig')
|
|
def config():
|
|
with open("/config/config.yml", 'r') as stream:
|
|
try:
|
|
config = yaml.safe_load(stream)
|
|
sio.emit('sendconfig', config, room=request.sid)
|
|
except yaml.YAMLError as e:
|
|
print(e)
|
|
|
|
# Send the current command examples from github to the user to render
|
|
@sio.on('getcommands')
|
|
def commands():
|
|
with open("./commands.yml", 'r') as stream:
|
|
try:
|
|
commands = yaml.safe_load(stream)
|
|
sio.emit('sendcommands', commands, room=request.sid)
|
|
except yaml.YAMLError as e:
|
|
print(e)
|
|
|
|
# Main page for rendering processing history and current
|
|
@sio.on('getmain')
|
|
def main():
|
|
with open("/config/config.yml", 'r') as stream:
|
|
try:
|
|
config = yaml.safe_load(stream)
|
|
sio.emit('sendmain', config, room=request.sid)
|
|
except yaml.YAMLError as e:
|
|
print(e)
|
|
|
|
# Save user set config
|
|
@sio.on('saveconfig')
|
|
def commands(data):
|
|
with open("/config/config.yml", 'w') as configfile:
|
|
try:
|
|
yaml.dump(data, configfile)
|
|
except yaml.YAMLError as e:
|
|
print(e)
|
|
|
|
|
|
################################
|
|
# User Terminal #
|
|
################################
|
|
|
|
# Globals
|
|
app.config['term'] = None
|
|
app.config['bash'] = None
|
|
|
|
# Send terminal data from forked process
|
|
def send_term():
|
|
while True:
|
|
# Sane delay on data sends
|
|
sio.sleep(0.01)
|
|
if app.config['term']:
|
|
timeout_sec = 0
|
|
(data_ready, _, _) = select.select([app.config['term']], [], [], timeout_sec)
|
|
if data_ready:
|
|
output = os.read(app.config['term'], 1024 * 20).decode()
|
|
sio.emit('sendterm', output)
|
|
|
|
# Write user input to terminal
|
|
@sio.on('termdata')
|
|
def termdata(data):
|
|
if app.config['term']:
|
|
os.write(app.config['term'], data.encode())
|
|
|
|
# The user requested a terminal
|
|
@sio.on('giveterm')
|
|
def giveterm():
|
|
if app.config['bash']:
|
|
return
|
|
(bash, term) = pty.fork()
|
|
if bash == 0:
|
|
subprocess.run('/bin/bash')
|
|
else:
|
|
app.config['term'] = term
|
|
app.config['bash'] = bash
|
|
sio.start_background_task(target=send_term)
|
|
|
|
################################
|
|
# App Run #
|
|
################################
|
|
|
|
if __name__ == '__main__':
|
|
sio.run(app, port=8787, host='0.0.0.0') |