diff --git a/app.py b/app.py index 17674ea..e476f68 100755 --- a/app.py +++ b/app.py @@ -24,6 +24,9 @@ import analytics as a with open("app_config.json", 'r') as file: app_config = json.load(file) + +with open('folder_permission_config.json') as file: + folder_config = json.load(file) cache_audio = diskcache.Cache('./filecache_audio', size_limit= app_config['filecache_size_limit_audio'] * 1024**3) cache_image = diskcache.Cache('./filecache_image', size_limit= app_config['filecache_size_limit_image'] * 1024**3) @@ -407,6 +410,52 @@ def get_transcript(subpath): content = f.read() return content, 200, {'Content-Type': 'text/markdown; charset=utf-8'} + +@app.route("/create_share/") +@auth.require_secret +def create_share(subpath): + scheme = request.scheme # current scheme (http or https) + if 'admin ' not in session and not session.get('admin'): + return "Unauthorized", 403 + + paths = {} + + for item in folder_config: + for folder in item['folders']: + paths[folder['foldername']] = folder['folderpath'] + + # use folder config file and ignore validity to get full path + root, *relative_parts = subpath.split('/') + base_path = paths[root] + full_path = os.path.join(base_path, *relative_parts) + foldername = relative_parts[-1] + validity_date = (datetime.now() + timedelta(days=90)).strftime('%d.%m.%Y') + data = { + "validity": validity_date, + "folders": [ + { + "foldername": foldername, + "folderpath": full_path + } + ] + } + + print (data) + + token = auth.generate_secret_key_compressed(data) + + content = f"""Ordner:\\ +{foldername}\\ +\\ +Gültig bis:\\ +{validity_date}\\ +\\ +Link:\\ +`{scheme}://{request.host}?token={token}`""" + + return content, 200, {'Content-Type': 'text/markdown; charset=utf-8'} + + def query_recent_connections(): global clients_connected, background_thread_running background_thread_running = True @@ -476,9 +525,13 @@ def handle_request_initial_data(): def index(path): title_short = app_config.get('TITLE_SHORT', 'Default Title') title_long = app_config.get('TITLE_LONG' , 'Default Title') + if 'admin' in session: + admin_enabled = session['admin'] + return render_template("app.html", title_short=title_short, - title_long=title_long + title_long=title_long, + admin_enabled=admin_enabled, ) if __name__ == '__main__': diff --git a/auth.py b/auth.py index 8daa476..d0ed94c 100644 --- a/auth.py +++ b/auth.py @@ -99,6 +99,15 @@ def require_secret(f): for folder_info in token_item['folders']: session['folders'][folder_info['foldername']] = folder_info['folderpath'] + args_admin = request.args.get('admin', None) + config_admin = app_config.get('ADMIN_KEY', None) + + if args_admin and config_admin: + if args_admin == config_admin: + session['admin'] = True + else: + session['admin'] = False + # 6) If we have folders, proceed; otherwise show index if session['folders']: # assume since visitor has a valid secret, they are ok with annonymous tracking diff --git a/static/app.css b/static/app.css index 9562e5b..8bfd07f 100644 --- a/static/app.css +++ b/static/app.css @@ -10,6 +10,7 @@ html, body { body { font-family: 'Helvetica Neue', Arial, sans-serif; padding-top: 70px; /* Adjust to your header height */ + overflow-x: hidden; /* Prevent horizontal scroll */ } /* Header styles */ .site-header { @@ -17,7 +18,7 @@ body { color: var(--header-text-color); position: fixed; top: 0; - width: 94%; + width: 100%; z-index: 1000; display: flex; align-items: center; @@ -138,6 +139,16 @@ a.show-transcript:hover { color: rgb(113, 146, 167); } +a.create-share { + text-decoration: none; + color: var(--main-text-color); + font-size: 20px; + margin-left: 10px; +} +a.create-share:hover { + color: rgb(113, 146, 167); +} + .currently-playing { background-color: var(--selected-background); } diff --git a/static/app.js b/static/app.js index d44dbe7..f42c754 100644 --- a/static/app.js +++ b/static/app.js @@ -74,19 +74,26 @@ function renderContent(data) { }); contentHTML += ''; } else { + share_link = ''; // Render directories normally if (data.directories.length > 0) { const areAllShort = data.directories.every(dir => dir.name.length <= 15) && data.files.length === 0; if (areAllShort && data.breadcrumbs.length !== 1) { contentHTML += '
'; data.directories.forEach(dir => { - contentHTML += ``; + if (admin_enabled && data.breadcrumbs.length != 1) { + share_link = `🌐`; + } + contentHTML += `
📁 ${dir.name}${share_link}
`; }); contentHTML += '
'; } else { contentHTML += '