Compare commits

...

6 Commits

1755 changed files with 1743 additions and 289 deletions

View File

@ -3,6 +3,7 @@ certifi==2022.12.7
charset-normalizer==3.0.1 charset-normalizer==3.0.1
click==7.1.2 click==7.1.2
dnspython==1.16.0 dnspython==1.16.0
ecdsa==0.18.0
email-validator==1.1.2 email-validator==1.1.2
eventlet==0.30.1 eventlet==0.30.1
Flask==1.1.2 Flask==1.1.2
@ -26,6 +27,7 @@ pyasn1-modules==0.2.8
pycairo==1.23.0 pycairo==1.23.0
PyGObject==3.42.2 PyGObject==3.42.2
pyparsing==2.4.7 pyparsing==2.4.7
pywebpush==1.14.0
pyxdg==0.28 pyxdg==0.28
requests==2.28.2 requests==2.28.2
rsa==4.7 rsa==4.7

View File

@ -4,6 +4,7 @@ import builtins
import threading import threading
import re import re
import secrets import secrets
import subprocess
# Lib imports # Lib imports
from flask import session from flask import session
@ -11,8 +12,12 @@ from flask import session
# Application imports # Application imports
from core import app from core import app
from core.utils import Logger from core.utils import Logger
from core.utils import MessageHandler # Get simple message processor
class BuiltinsException(Exception):
...
# NOTE: Threads WILL NOT die with parent's destruction. # NOTE: Threads WILL NOT die with parent's destruction.
def threaded_wrapper(fn): def threaded_wrapper(fn):
@ -41,22 +46,76 @@ def _get_file_size(file):
# NOTE: Just reminding myself we can add to builtins two different ways... # NOTE: Just reminding myself we can add to builtins two different ways...
# __builtins__.update({"event_system": Builtins()}) # __builtins__.update({"event_system": Builtins()})
builtins.app_name = "WebFM" builtins.app_name = "WebFM"
builtins.threaded = threaded_wrapper builtins.threaded = threaded_wrapper
builtins.daemon_threaded = daemon_threaded_wrapper builtins.daemon_threaded = daemon_threaded_wrapper
builtins.sizeof_fmt = sizeof_fmt_def builtins.sizeof_fmt = sizeof_fmt_def
builtins.get_file_size = _get_file_size builtins.get_file_size = _get_file_size
builtins.ROOT_FILE_PTH = os.path.dirname(os.path.realpath(__file__)) builtins.ROOT_FILE_PTH = os.path.dirname(os.path.realpath(__file__))
builtins.BG_IMGS_PATH = ROOT_FILE_PTH + "/static/imgs/backgrounds/" builtins.BG_IMGS_PATH = ROOT_FILE_PTH + "/static/imgs/backgrounds/"
builtins.BG_FILE_TYPE = (".webm", ".mp4", ".gif", ".jpg", ".png", ".webp") builtins.BG_FILE_TYPE = (".webm", ".mp4", ".gif", ".jpg", ".png", ".webp")
builtins.valid_fname_pat = re.compile(r"[a-z0-9A-Z-_\[\]\(\)\| ]{4,20}") builtins.valid_fname_pat = re.compile(r"[a-z0-9A-Z-_\[\]\(\)\| ]{4,20}")
builtins.logger = Logger().get_logger() builtins.logger = Logger().get_logger()
builtins.json_message = MessageHandler()
# NOTE: Need threads defined before instantiating
def _start_rtsp_and_ntfy_server():
PATH = f"{ROOT_FILE_PTH}/utils"
RTSP_PATH = f"{PATH}/rtsp-server"
NTFY_PATH = f"{PATH}/ntfy"
RAMFS = "/dev/shm/webfm"
SYMLINK = app.config['REMUX_FOLDER']
if not os.path.exists(RTSP_PATH) or not os.path.exists(f"{RTSP_PATH}/rtsp-simple-server"):
msg = f"\n\nAlert: Reference --> https://github.com/aler9/rtsp-simple-server/releases" + \
f"\nPlease insure {RTSP_PATH} exists and rtsp-simple-server binary is there.\n\n"
raise BuiltinsException(msg)
if not os.path.exists(NTFY_PATH) or not os.path.exists(f"{NTFY_PATH}/ntfy"):
msg = f"\n\nAlert: Reference --> https://ntfy.sh/" + \
f"\nPlease insure {NTFY_PATH} exists and ntfy binary is there.\n\n"
raise BuiltinsException(msg)
if not os.path.exists(RAMFS):
os.mkdir(RAMFS)
if not os.path.exists(SYMLINK):
os.symlink(RAMFS, SYMLINK)
@daemon_threaded
def _start_rtsp_server_threaded():
os.chdir(RTSP_PATH)
command = ["./rtsp-simple-server", "./rtsp-simple-server.yml"]
process = subprocess.Popen(command)
process.wait()
@daemon_threaded
def _start_ntfy_server_threaded():
os.chdir(NTFY_PATH)
command = ["./ntfy", "serve", "--behind-proxy", "--listen-http", ":7777"]
process = subprocess.Popen(command)
process.wait()
_start_ntfy_server_threaded()
_start_rtsp_server_threaded()
_start_rtsp_and_ntfy_server()
# NOTE: Need threads defined befor instantiating
from core.utils.shellfm.windows.controller import WindowController # Get file manager controller from core.utils.shellfm.windows.controller import WindowController # Get file manager controller
window_controllers = {} window_controllers = {}
processes = {}
def _get_sse_id():
return session["win_controller_id"]
def _get_view(): def _get_view():
controller = None controller = None
try: try:
@ -84,11 +143,59 @@ def _get_view():
view.logger = logger view.logger = logger
session['win_controller_id'] = id session['win_controller_id'] = id
window_controllers.update( {id: controller } ) window_controllers.update( {id: controller} )
controller = window_controllers[ session["win_controller_id"] ].get_window_by_index(0).get_tab_by_index(0) controller = window_controllers[ session["win_controller_id"] ].get_window_by_index(0).get_tab_by_index(0)
return controller return controller
def _get_stream(video_path=None, stream_target=None):
process = None
try:
window = window_controllers[ session["win_controller_id"] ].get_window_by_index(0)
tab = window.get_tab_by_index(0)
id = f"{window.get_id()}{tab.get_id()}"
process = processes[id]
except Exception as e:
if video_path and stream_target:
# NOTE: Yes, technically we should check if cuda is supported.
# Yes, the process probably should give us info we can process when failure occures.
command = [
"ffmpeg", "-nostdin", "-fflags", "+genpts", "-hwaccel", "cuda",
"-stream_loop", "-1", "-i", video_path, "-strict", "experimental",
"-vcodec", "copy", "-acodec", "copy", "-f", "rtsp",
"-rtsp_transport", "tcp", stream_target
]
builtins.get_view = _get_view proc = subprocess.Popen(command, shell=False, stdin=None, stdout=None, stderr=None)
window = window_controllers[ session["win_controller_id"] ].get_window_by_index(0)
tab = window.get_tab_by_index(0)
id = f"{window.get_id()}{tab.get_id()}"
processes.update( {id: proc} )
process = processes[id]
return process
def _kill_stream(process):
try:
if process.poll() == None:
process.terminate()
while process.poll() == None:
...
window = window_controllers[ session["win_controller_id"] ].get_window_by_index(0)
tab = window.get_tab_by_index(0)
id = f"{window.get_id()}{tab.get_id()}"
del processes[id]
except Exception as e:
return False
return True
builtins.get_view = _get_view
builtins.get_sse_id = _get_sse_id
builtins.get_stream = _get_stream
builtins.kill_stream = _kill_stream

View File

@ -1,4 +1,5 @@
# Python imports # Python imports
import os
# Lib imports # Lib imports
from flask import Flask from flask import Flask
@ -6,7 +7,10 @@ from flask import Flask
from flask_oidc import OpenIDConnect from flask_oidc import OpenIDConnect
# Flask Login Path # Flask Login Path
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
from flask_login import current_user, login_user, logout_user, LoginManager from flask_login import current_user
from flask_login import login_user
from flask_login import logout_user
from flask_login import LoginManager
app = Flask(__name__) app = Flask(__name__)
app.config.from_object("core.config.ProductionConfig") app.config.from_object("core.config.ProductionConfig")
@ -36,10 +40,15 @@ app.jinja_env.globals['oidc_isAdmin'] = oidc_isAdmin
app.jinja_env.globals['TITLE'] = app.config["TITLE"] app.jinja_env.globals['TITLE'] = app.config["TITLE"]
from core.models import db, User, Favorites
from core.models import db
from core.models import User
from core.models import Favorites
db.init_app(app) db.init_app(app)
with app.app_context(): with app.app_context():
db.create_all() db.create_all()
from core.forms import RegisterForm, LoginForm from core.forms import RegisterForm
from core.forms import LoginForm
from core import routes from core import routes

View File

@ -1,14 +1,14 @@
# System import # System import
import os, secrets import os
import secrets
from datetime import timedelta from datetime import timedelta
# Lib imports # Lib imports
# Apoplication imports # Apoplication imports
# Configs # Configs
APP_NAME = 'WebFM' APP_NAME = 'WebFM'
ROOT_FILE_PTH = os.path.dirname(os.path.realpath(__file__)) ROOT_FILE_PTH = os.path.dirname(os.path.realpath(__file__))
@ -43,9 +43,9 @@ class Config(object):
# We are overiding some of the the shellmen view settings with these to make it all work with flask. # We are overiding some of the the shellmen view settings with these to make it all work with flask.
# These are passed along to the shellmen view from the Routes file upon the window controller creation. # These are passed along to the shellmen view from the Routes file upon the window controller creation.
ABS_THUMBS_PTH = f"{STATIC_FPTH}/imgs/thumbnails" # Used for thumbnail generation ABS_THUMBS_PTH = f"{STATIC_FPTH}/imgs/thumbnails" # Used for thumbnail generation
REMUX_FOLDER = f"{STATIC_FPTH}/remuxs" # Remuxed files folder REMUX_FOLDER = f"{STATIC_FPTH}/remuxs" # Remuxed files folder
FFMPG_THUMBNLR = f"{STATIC_FPTH}/ffmpegthumbnailer" # Thumbnail generator binary FFMPG_THUMBNLR = f"{STATIC_FPTH}/ffmpegthumbnailer" # Thumbnail generator binary

View File

@ -1,9 +1,19 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError from wtforms import StringField
from wtforms import PasswordField
from wtforms import SubmitField
from wtforms.validators import DataRequired
from wtforms.validators import Length
from wtforms.validators import Email
from wtforms.validators import EqualTo
from wtforms.validators import ValidationError
from core import User from core import User
class RegisterForm(FlaskForm): class RegisterForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=4, max=24)]) username = StringField('Username', validators=[DataRequired(), Length(min=4, max=24)])
email = StringField('Email', validators=[DataRequired(), Email()]) email = StringField('Email', validators=[DataRequired(), Email()])

View File

@ -1,11 +1,12 @@
# System imports # System imports
# Lib imports # Lib imports
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
# App imports # App imports
from . import app, login_manager from . import app
from flask_login import UserMixin from . import login_manager
db = SQLAlchemy(app) db = SQLAlchemy(app)

View File

@ -9,7 +9,6 @@ from flask_uploads import ALL
from flask_uploads import configure_uploads from flask_uploads import configure_uploads
from flask_uploads import UploadSet from flask_uploads import UploadSet
# App imports # App imports
# Get from __init__ # Get from __init__
from core import app from core import app
@ -17,10 +16,6 @@ from core import db
from core import Favorites from core import Favorites
from core import oidc from core import oidc
from core.utils import MessageHandler # Get simple message processor
json_message = MessageHandler()
@app.route('/api/delete/<_hash>', methods=['GET', 'POST']) @app.route('/api/delete/<_hash>', methods=['GET', 'POST'])
@ -46,6 +41,8 @@ def delete_item(_hash = None):
msg = "[Error] Unable to delete the file/folder...." msg = "[Error] Unable to delete the file/folder...."
return json_message.create("danger", msg) return json_message.create("danger", msg)
msg = "Can't manage the request type..."
return json_message.create("danger", msg)
@app.route('/api/create/<_type>', methods=['GET', 'POST']) @app.route('/api/create/<_type>', methods=['GET', 'POST'])
@ -82,9 +79,9 @@ def create_item(_type = None):
msg = "[Success] created the file/dir..." msg = "[Success] created the file/dir..."
return json_message.create("success", msg) return json_message.create("success", msg)
else:
msg = "Can't manage the request type..." msg = "Can't manage the request type..."
return json_message.create("danger", msg) return json_message.create("danger", msg)
@app.route('/api/upload', methods=['GET', 'POST']) @app.route('/api/upload', methods=['GET', 'POST'])
@ -114,6 +111,6 @@ def upload():
msg = "[Success] Uploaded file(s)..." msg = "[Success] Uploaded file(s)..."
return json_message.create("success", msg) return json_message.create("success", msg)
else:
msg = "Can't manage the request type..." msg = "Can't manage the request type..."
return json_message.create("danger", msg) return json_message.create("danger", msg)

View File

@ -7,15 +7,11 @@ from flask import request
from core import app from core import app
from core import db from core import db
from core import Favorites # Get from __init__ from core import Favorites # Get from __init__
from core.utils import MessageHandler # Get simple message processor
json_message = MessageHandler()
@app.route('/api/list-favorites', methods=['GET', 'POST']) @app.route('/api/list-favorites', methods=['GET', 'POST'])
def listFavorites(): def list_favorites():
if request.method == 'POST': if request.method == 'POST':
list = db.session.query(Favorites).all() list = db.session.query(Favorites).all()
faves = [] faves = []
@ -23,12 +19,12 @@ def listFavorites():
faves.append([fave.link, fave.id]) faves.append([fave.link, fave.id])
return json_message.faves_list(faves) return json_message.faves_list(faves)
else:
msg = "Can't manage the request type..." msg = "Can't manage the request type..."
return json_message.create("danger", msg) return json_message.create("danger", msg)
@app.route('/api/load-favorite/<_id>', methods=['GET', 'POST']) @app.route('/api/load-favorite/<_id>', methods=['GET', 'POST'])
def loadFavorite(_id): def load_favorite(_id):
if request.method == 'POST': if request.method == 'POST':
try: try:
ID = int(_id) ID = int(_id)
@ -40,13 +36,13 @@ def loadFavorite(_id):
print(repr(e)) print(repr(e))
msg = "Incorrect Favorites ID..." msg = "Incorrect Favorites ID..."
return json_message.create("danger", msg) return json_message.create("danger", msg)
else:
msg = "Can't manage the request type..." msg = "Can't manage the request type..."
return json_message.create("danger", msg) return json_message.create("danger", msg)
@app.route('/api/manage-favorites/<_action>', methods=['GET', 'POST']) @app.route('/api/manage-favorites/<_action>', methods=['GET', 'POST'])
def manageFavorites(_action): def manage_favorites(_action):
if request.method == 'POST': if request.method == 'POST':
ACTION = _action.strip() ACTION = _action.strip()
view = get_view() view = get_view()
@ -66,6 +62,6 @@ def manageFavorites(_action):
db.session.commit() db.session.commit()
return json_message.create("success", msg) return json_message.create("success", msg)
else:
msg = "Can't manage the request type..." msg = "Can't manage the request type..."
return json_message.create("danger", msg) return json_message.create("danger", msg)

View File

@ -6,21 +6,19 @@ import shutil
# Lib imports # Lib imports
from flask import request from flask import request
# App imports # App imports
# Get from __init__ # Get from __init__
from core import app from core import app
from core.utils import MessageHandler # Get simple message processor
from core.utils.tmdbscraper import scraper # Get media art scraper from core.utils.tmdbscraper import scraper # Get media art scraper
json_message = MessageHandler()
tmdb = scraper.get_tmdb_scraper() tmdb = scraper.get_tmdb_scraper()
@app.route('/api/get-background-poster-trailer', methods=['GET', 'POST']) @app.route('/api/get-background-poster-trailer', methods=['GET', 'POST'])
def getPosterTrailer(): def get_poster_trailer():
if request.method == 'GET': if request.method == 'GET':
info = {} info = {}
view = get_view() view = get_view()
@ -71,6 +69,8 @@ def getPosterTrailer():
return info return info
msg = "Can't manage the request type..."
return json_message.create("danger", msg)
@app.route('/backgrounds', methods=['GET', 'POST']) @app.route('/backgrounds', methods=['GET', 'POST'])
def backgrounds(): def backgrounds():
@ -83,10 +83,10 @@ def backgrounds():
return json_message.backgrounds(files) return json_message.backgrounds(files)
@app.route('/api/get-thumbnails', methods=['GET', 'POST']) @app.route('/api/get-thumbnails', methods=['GET', 'POST'])
def getThumbnails(): def get_thumbnails():
if request.method == 'GET': if request.method == 'GET':
view = get_view() view = get_view()
return json_message.thumbnails( view.get_video_icons() ) return json_message.thumbnails( view.get_video_icons() )
else:
msg = "Can't manage the request type..." msg = "Can't manage the request type..."
return json_message.create("danger", msg) return json_message.create("danger", msg)

View File

@ -1,42 +1,49 @@
# Python imports # Python imports
import os import os
import requests
import uuid
# Lib imports # Lib imports
from flask import make_response
from flask import redirect from flask import redirect
from flask import request from flask import request
from flask import render_template from flask import render_template
from flask import session
from flask import send_from_directory from flask import send_from_directory
# App imports # App imports
# Get from __init__ # Get from __init__
from core import app from core import app
from core import db from core import db
from core import Favorites from core import Favorites
from core import oidc from core import oidc
from core.utils import MessageHandler # Get simple message processor
json_message = MessageHandler()
@app.route('/', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST'])
def home(): def home():
if request.method == 'GET': if request.method == 'GET':
view = get_view() view = get_view()
sse_id = get_sse_id()
_dot_dots = view.get_dot_dots() _dot_dots = view.get_dot_dots()
_current_directory = view.get_current_directory() _current_directory = view.get_current_directory()
return render_template('pages/index.html', current_directory = _current_directory, dot_dots = _dot_dots)
response = make_response(
render_template(
'pages/index.html',
current_directory = _current_directory,
dot_dots = _dot_dots
)
)
response.set_cookie('sse_id', sse_id, secure=True, httponly = False)
return response
return render_template('error.html', title = 'Error!', return render_template('error.html', title = 'Error!',
message = 'Must use GET request type...') message = 'Must use GET request type...')
@app.route('/api/list-files/<_hash>', methods=['GET', 'POST']) @app.route('/api/list-files/<_hash>', methods=['GET', 'POST'])
def listFiles(_hash = None): def list_files(_hash = None):
if request.method == 'POST': if request.method == 'POST':
view = get_view() view = get_view()
dot_dots = view.get_dot_dots() dot_dots = view.get_dot_dots()
@ -70,14 +77,13 @@ def listFiles(_hash = None):
in_fave = "true" if fave else "false" in_fave = "true" if fave else "false"
files.update({'in_fave': in_fave}) files.update({'in_fave': in_fave})
return files return files
else:
msg = "Can't manage the request type..."
return json_message.create("danger", msg)
msg = "Can't manage the request type..."
return json_message.create("danger", msg)
@app.route('/api/file-manager-action/<_type>/<_hash>', methods=['GET', 'POST']) @app.route('/api/file-manager-action/<_type>/<_hash>', methods=['GET', 'POST'])
def fileManagerAction(_type, _hash = None): def file_manager_action(_type, _hash = None):
view = get_view() view = get_view()
if _type == "reset-path" and _hash == "None": if _type == "reset-path" and _hash == "None":
@ -93,19 +99,16 @@ def fileManagerAction(_type, _hash = None):
if _type == "files": if _type == "files":
logger.debug(f"Downloading:\n\tDirectory: {folder}\n\tFile: {file}") logger.debug(f"Downloading:\n\tDirectory: {folder}\n\tFile: {file}")
return send_from_directory(directory=folder, filename=file) return send_from_directory(directory=folder, filename=file)
if _type == "remux":
# NOTE: Need to actually implimint a websocket to communicate back to client that remux has completed.
# As is, the remux thread hangs until completion and client tries waiting until server reaches connection timeout.
# I.E....this is stupid but for now works better than nothing
good_result = view.remux_video(_hash, fpath)
if good_result:
return '{"path":"static/remuxs/' + _hash + '.mp4"}'
else:
msg = "Remuxing: Remux failed or took too long; please, refresh the page and try again..."
return json_message.create("success", msg)
if _type == "remux": if _type == "remux":
stream_target = view.remux_video(_hash, fpath) remux_video(get_sse_id(), _hash, fpath, view)
msg = "Remuxing: Remux process has started..."
return json_message.create("success", msg)
if _type == "stream":
setup_stream(get_sse_id(), _hash, fpath)
msg = "Streaming: Streaming process is being setup..."
return json_message.create("success", msg)
# NOTE: Positionally protecting actions further down that are privlidged # NOTE: Positionally protecting actions further down that are privlidged
@ -123,3 +126,63 @@ def fileManagerAction(_type, _hash = None):
msg = "Opened media..." msg = "Opened media..."
view.open_file_locally(fpath) view.open_file_locally(fpath)
return json_message.create("success", msg) return json_message.create("success", msg)
@daemon_threaded
def remux_video(sse_id, hash, path, view):
link = f"https://www.webfm.com/sse/{sse_id}"
body = '{"path":"static/remuxs/' + hash + '.mp4"}'
# good_result = view.remux_video(hash, path)
good_result = view.handbrake_remux_video(hash, path)
if not good_result:
body = json_message.create("warning", "Remuxing: Remux failed...")
requests.post(link, data=body, timeout=10)
def setup_stream(sse_id, hash, path):
link = f"https://www.webfm.com/sse/{sse_id}"
_sub_uuid = uuid.uuid4().hex
_video_path = path
_stub = f"{hash}{_sub_uuid}"
_rtsp_path = f"rtsp://127.0.0.1:8554/{_stub}"
_webrtc_path = f"http://www.{app_name.lower()}.com:8889/{_stub}/"
_stream_target = _rtsp_path
process = get_stream()
if process:
if not kill_stream(process):
msg = "Couldn't stop an existing stream!"
body = json_message.create("danger", msg)
requests.post(link, data=body, timeout=10)
return
stream = get_stream(_video_path, _stream_target)
if stream.poll():
msg = "Streaming: Setting up stream failed! Please try again..."
body = json_message.create("danger", msg)
requests.post(link, data=body, timeout=10)
return
_stream_target = _webrtc_path
body = '{"stream":"' + _stream_target + '"}'
requests.post(link, data=body, timeout=10)
@app.route('/api/stop-current-stream', methods=['GET', 'POST'])
def stop_current_stream():
type = "success"
msg = "Stopped found stream process..."
process = get_stream()
if process:
if not kill_stream(process):
type = "danger"
msg = "Couldn't stop an existing stream!"
else:
type = "warning"
msg = "No stream process found. Nothing to stop..."
return json_message.create(type, msg)

View File

@ -1,15 +1,24 @@
# Python imports # Python imports
# Lib imports # Lib imports
from flask import request, render_template, flash, redirect, url_for from flask import request
from flask_login import current_user, login_user, logout_user from flask import render_template
from flask import flash
from flask import redirect
from flask import url_for
from flask_login import current_user
from flask_login import login_user
from flask_login import logout_user
# App imports # App imports
from core import app, bcrypt, db, User, LoginForm from core import app
from core.utils import MessageHandler # Get simple message processor from core import bcrypt
from core import db
from core import User
from core import LoginForm
msgHandler = MessageHandler()
@app.route('/app-login', methods=['GET', 'POST']) @app.route('/app-login', methods=['GET', 'POST'])
def app_login(): def app_login():

View File

@ -1,16 +1,21 @@
# Python imports # Python imports
# Lib imports # Lib imports
from flask import request, render_template, url_for, redirect, flash from flask import render_template
from flask import url_for
from flask import redirect
from flask import flash
# App imports # App imports
from core import app, bcrypt, db, current_user, RegisterForm # Get from __init__ # Get from __init__
from core import app
from core import bcrypt
from core import db
from core import current_user
from core import RegisterForm
from core.models import User from core.models import User
from core.utils import MessageHandler # Get simple message processor
msgHandler = MessageHandler()
@app.route('/app-register', methods=['GET', 'POST']) @app.route('/app-register', methods=['GET', 'POST'])
def app_register(): def app_register():

View File

@ -1,17 +1,19 @@
# Python imports # Python imports
# Lib imports # Lib imports
from flask import request, redirect, flash from flask import request
from flask import redirect
from flask import flash
# App imports # App imports
from ... import app, oidc from ... import app
from ... import oidc
@app.route('/oidc-login', methods=['GET', 'POST']) @app.route('/oidc-login', methods=['GET', 'POST'])
@oidc.require_login @oidc.require_login
def oidc_login(): def oidc_login():
print(request)
return redirect("/") return redirect("/")

View File

@ -1,15 +1,19 @@
# Python imports # Python imports
# Lib imports # Lib imports
from flask import request, render_template, url_for, redirect, flash from flask import request
from flask import render_template
from flask import url_for
from flask import redirect
from flask import flash
# App imports # App imports
from ... import app, oidc, db # Get from __init__ # Get from __init__
from ...utils import MessageHandler # Get simple message processor from ... import app
from ... import oidc
from ... import db
msgHandler = MessageHandler()
@app.route('/oidc-register', methods=['GET', 'POST']) @app.route('/oidc-register', methods=['GET', 'POST'])
def oidc_register(): def oidc_register():

View File

Before

Width:  |  Height:  |  Size: 870 B

After

Width:  |  Height:  |  Size: 870 B

View File

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 367 B

View File

Before

Width:  |  Height:  |  Size: 626 B

After

Width:  |  Height:  |  Size: 626 B

View File

Before

Width:  |  Height:  |  Size: 711 B

After

Width:  |  Height:  |  Size: 711 B

View File

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 271 B

View File

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

View File

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View File

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 316 B

View File

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

View File

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 282 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 359 B

View File

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 401 B

View File

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 350 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 350 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 375 B

View File

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 375 B

View File

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 375 B

View File

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 376 B

View File

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 352 B

View File

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 359 B

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 370 B

View File

Before

Width:  |  Height:  |  Size: 377 B

After

Width:  |  Height:  |  Size: 377 B

View File

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 451 B

View File

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 286 B

View File

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 379 B

View File

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 453 B

View File

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 289 B

View File

Before

Width:  |  Height:  |  Size: 314 B

After

Width:  |  Height:  |  Size: 314 B

View File

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 359 B

View File

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 444 B

View File

Before

Width:  |  Height:  |  Size: 457 B

After

Width:  |  Height:  |  Size: 457 B

View File

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 309 B

View File

Before

Width:  |  Height:  |  Size: 320 B

After

Width:  |  Height:  |  Size: 320 B

View File

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 370 B

View File

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 453 B

View File

Before

Width:  |  Height:  |  Size: 314 B

After

Width:  |  Height:  |  Size: 314 B

View File

Before

Width:  |  Height:  |  Size: 362 B

After

Width:  |  Height:  |  Size: 362 B

View File

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 445 B

View File

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

View File

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 582 B

View File

Before

Width:  |  Height:  |  Size: 373 B

After

Width:  |  Height:  |  Size: 373 B

View File

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 372 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 372 B

View File

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 316 B

View File

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

View File

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 446 B

View File

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 312 B

View File

Before

Width:  |  Height:  |  Size: 769 B

After

Width:  |  Height:  |  Size: 769 B

View File

Before

Width:  |  Height:  |  Size: 977 B

After

Width:  |  Height:  |  Size: 977 B

View File

Before

Width:  |  Height:  |  Size: 320 B

After

Width:  |  Height:  |  Size: 320 B

View File

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

View File

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 372 B

View File

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 446 B

View File

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 284 B

View File

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 376 B

View File

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 449 B

View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

View File

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

View File

Before

Width:  |  Height:  |  Size: 358 B

After

Width:  |  Height:  |  Size: 358 B

View File

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

View File

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 309 B

View File

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 463 B

View File

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 462 B

View File

Before

Width:  |  Height:  |  Size: 499 B

After

Width:  |  Height:  |  Size: 499 B

View File

Before

Width:  |  Height:  |  Size: 498 B

After

Width:  |  Height:  |  Size: 498 B

View File

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 730 B

View File

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 706 B

View File

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 391 B

View File

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 484 B

View File

Before

Width:  |  Height:  |  Size: 358 B

After

Width:  |  Height:  |  Size: 358 B

Some files were not shown because too many files have changed in this diff Show More