from glob import glob from os.path import basename, join, exists, splitext, getsize from functools import wraps from collections import OrderedDict import toml from flask import render_template, send_from_directory, request, Response from app import app CONFIG_PATH = "pipeline.toml" PLOTS_PATH = "../plots" LOGS_PATH = "../logs" USERNAME = None PASSWORD = None app.config['FREEZER_DESTINATION'] = '../km3web' PLOTS = [['dom_activity', 'dom_rates'], 'pmt_rates_du*', 'pmt_hrv_du*', ['trigger_rates'], ['ztplot', 'triggermap']] AHRS_PLOTS = ['yaw_calib_du*', 'pitch_calib_du*', 'roll_calib_du*'] TRIGGER_PLOTS = [['trigger_rates'], ['trigger_rates_lin']] K40_PLOTS = [['intradom'], ['angular_k40rate_distribution']] RTTC_PLOTS = [['rttc']] RECO_PLOTS = [['track_reco', 'ztplot_roy'], ['time_residuals']] COMPACT_PLOTS = [['dom_activity', 'dom_rates', 'pmt_rates', 'pmt_hrv'], ['trigger_rates', 'trigger_rates_lin'], ['ztplot', 'ztplot_roy', 'triggermap']] SN_PLOTS = [['sn_bg_histogram', 'sn_pk_history']] RASP_PLOTS = [['dom_rates', 'ztplot', 'triggermap'], [ 'pmt_rates_du2', 'pmt_rates_du3', 'pmt_rates_du4', 'pmt_rates_du5' ], ['trigger_rates', 'trigger_rates_lin']] if exists(CONFIG_PATH): config = toml.load(CONFIG_PATH) if "WebServer" in config: print("Reading authentication information from '%s'" % CONFIG_PATH) USERNAME = config["WebServer"]["username"] PASSWORD = config["WebServer"]["password"] def expand_wildcards(plot_layout): """Replace wildcard entries with list of files""" plots = [] for row in plot_layout: if not isinstance(row, list) and '*' in row: plots.append( sorted([ splitext(basename(p))[0] for p in glob(join(app.root_path, PLOTS_PATH, row)) ])) else: plots.append(row) return plots def check_auth(username, password): """This function is called to check if a username / password combination is valid. """ if USERNAME is not None and PASSWORD is not None: return username == USERNAME and password == PASSWORD else: return True def authenticate(): """Sends a 401 response that enables basic auth""" return Response( 'Could not verify your access level for that URL.\n' 'You have to login with proper credentials', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) def requires_auth(f): @wraps(f) def decorated(*args, **kwargs): auth = request.authorization if not auth or not check_auth(auth.username, auth.password): return authenticate() return f(*args, **kwargs) return decorated @app.after_request def add_header(r): """ Disable caches. """ r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" r.headers["Pragma"] = "no-cache" r.headers["Expires"] = "0" r.headers["Cache-Control"] = "public, max-age=0" return r @app.route('/') @app.route('/index.html') @requires_auth def index(): return render_template('plots.html', plots=expand_wildcards(PLOTS)) @app.route('/ahrs.html') @requires_auth def ahrs(): return render_template('plots.html', plots=expand_wildcards(AHRS_PLOTS)) @app.route('/reco.html') @requires_auth def reco(): return render_template('plots.html', plots=expand_wildcards(RECO_PLOTS)) @app.route('/sn.html') @requires_auth def supernova(): return render_template('plots.html', plots=expand_wildcards(SN_PLOTS)) @app.route('/compact.html') @requires_auth def compact(): return render_template('plots.html', plots=expand_wildcards(COMPACT_PLOTS)) @app.route('/rttc.html') @requires_auth def rttc(): return render_template( 'plots.html', plots=expand_wildcards(RTTC_PLOTS), info= "Cable Round Trip Time calculated from realtime data provided by the " "Detector Manager. The red lines shows the median and the STD " "from the past 24 hours. " "RTTC = Cable_RTT - (TX_Slave + RX_Slave + TX_Master + RX_Master)") # @app.route('/k40.html') # @requires_auth # def k40(): # return render_template( # 'plots.html', # plots=expand_wildcards(K40_PLOTS), # info="The first plot shows the intra-DOM calibration. " # "y-axis: delta_t [ns], x-axis: cosine of angles. " # "The second plot the angular distribution of K40 rates. " # "y-axis: rate [Hz], x-axis: cosine of angles. " # "blue=before, red=after") @app.route('/trigger.html') @requires_auth def trigger(): return render_template('plots.html', plots=expand_wildcards(TRIGGER_PLOTS)) @app.route('/logs.html') @requires_auth def logs(): files = OrderedDict() for filename in sorted(glob(join(app.root_path, LOGS_PATH, "MSG*.log"))): files[basename(filename)] = getsize(filename) print(files) return render_template('logs.html', files=files) @app.route('/logs/<path:filename>') @requires_auth def custom_static_logfile(filename): filepath = join(app.root_path, LOGS_PATH) print("Serving: {}/{}".format(filepath, filename)) return send_from_directory(join(app.root_path, LOGS_PATH), filename) @app.route('/plots/<path:filename>') @requires_auth def custom_static(filename): filepath = join(app.root_path, PLOTS_PATH) print("Serving: {}/{}".format(filepath, filename)) return send_from_directory(join(app.root_path, PLOTS_PATH), filename) @app.route('/rasp.html') @requires_auth def rasp(): return render_template('plots.html', plots=expand_wildcards(RASP_PLOTS))