Skip to content
main.py 7.74 KiB
Newer Older
from flask import Flask, render_template, request, flash, Response, make_response
app = Flask(__name__)
app.secret_key = 'some_secret'  #TODO set secret

state = {
"host": "",
"username": "",
"password": "",
"roottype": "",
"results": [],
"results_export":[]
}

@app.route("/server_settings")
def server_settings():
    return render_template("server_settings.html", state=state)

@app.route("/")
def step1():
    from xsa.datatypereader import get_root_types, get_fields
    root_types = get_root_types()
    roottypefields = ()
Franziska Koehn's avatar
Franziska Koehn committed
    roottypefieldsjson = {}
    if state["roottype"]:
        roottypefields = get_fields(state["roottype"])
        import json
        roottypefieldsjson = json.dumps(roottypefields, indent=2)
    return render_template("step1.html", state=state, roottypes=root_types,
    roottypefields=roottypefields, roottypefieldsjson=roottypefieldsjson)

Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed
@app.route("/set_chart_field", methods=["GET"])
def set_chart_field():
    from xsa.chart import count_substrings
    from xsa.datatypereader import get_field_key_by_label
    import json

    field_label = request.args.get("f")
    field_key = get_field_key_by_label(state["roottype"], field_label)

    strings = []
    for r in state["results"]:
        strings.append(r[field_key])

    substrings = request.args.get("s").split(',')

    data_dict=[]
    for c in count_substrings(substrings, strings):
        new_dict = {}
        new_dict['count'] = c[1]
        new_dict['label'] = c[0]
        data_dict.append(new_dict)
    data_json = json.dumps(data_dict)

    width=request.args.get("w")

    return render_template("chart.html", chart_data=data_json, chart_max=len(state["results"]), chart_width=width)


Franziska Koehn's avatar
Franziska Koehn committed
@app.route("/set_root_type", methods=["GET"])
def set_root_type():
    state["roottype"] = request.args.get("t")
    from xsa.datatypereader import get_root_types, get_fields
    root_types = get_root_types()
    roottypefields = ()
    roottypefieldsjson = {}
    if state["roottype"]:
        roottypefields = get_fields(state["roottype"])
        import json
        roottypefieldsjson = json.dumps(roottypefields, indent=2)
    return render_template("step1_1.html", state=state, roottypes=root_types,
    roottypefields=roottypefields, roottypefieldsjson=roottypefieldsjson)

#TODO Funktionen zusammenführen

#MODEL:  [{"operator":"AND","children":[{"name":"Type","predicate":"LIKE","value":"%t1%","idx":"0","field":"xnat:mrScanData/TYPE"}]}]

@app.route("/results")
def results(res):
    from xsa.datatypereader import get_field_label_by_key
    from xsa.queries import prepare_rest
    from xsa.datatypereader import get_rest
    from xsa.datatypereader import get_comparison_extra_source
    from urllib.parse import quote
    import json
    if state["roottype"] and res is not None:
        roottypefields=[]
        for h in res.headers():
            roottypefields.append({'key': h, 'label':get_field_label_by_key(state["roottype"], h)})

        rest_downl = ""
        try:
            rest_downl = get_rest(state["roottype"])
            for r in res:
                r['rest'] = quote(prepare_rest(r, rest_downl, state["host"]))
        except:
            pass

        rest_adddata = ""
        try:
            rest_adddata = get_comparison_extra_source(state["roottype"])
        except:
            pass

        return render_template("results.html", state=state, results=res, resultcount=len(res), roottypefields=roottypefields, rest_downl=rest_downl, rest_adddata= rest_adddata)
    else:
        flash("No root-type was chosen and/or no search-results are available.")

@app.route("/download", methods=["GET"])
def download():
    from xsa.queries import download_file_iter
    url = request.args.get("url")
    creds = state["username"], state["password"]
    response = Response(download_file_iter(url, creds), mimetype='application/zip')
    response.headers["Content-Disposition"] = "attachment; filename=test.zip"#TODO rename file
    return response

def adjust_constraints(list, parent):
    for item in list:
        if isinstance(item, dict):
            for key in item:
                if key=='operator':
                    child = []
                    child.append(item['operator'])
                    adjust_constraints(item['children'], child)
                    parent.append(child)
                elif key=='field':
                    parent.append((item['field'], item['predicate'], item['value']))
                else:
                    pass
        else:
            pass

@app.route("/send_query", methods=["POST", "GET"])
def send_query():
    import json
    from xsa.queries import search_for
    #TODO show message: sending query...

    constraints=[]
    adjust_constraints(json.loads(request.form.get("model")), constraints)

    search_fields = json.loads(request.form.get("fields"))
    state["host"] = json.loads(request.form.get("host"))
    state["username"] = json.loads(request.form.get("user"))
    state["password"] = json.loads(request.form.get("passw"))

    res = search_for(state["host"], state["roottype"], constraints, search_fields, state["username"], state["password"])

    if res is None:
        flash("Something went wrong. Check the connection to your server and your query.")
        return step1()
    else:
        state["results"] = res
        state["results_export"] = res
        return results(res)

@app.route("/get_adddata", methods=["POST", "GET"])
def get_adddata():
    from xsa.queries import query_for_additional_data
    from xsa.datatypereader import get_comparison_extra_source
    rest = get_comparison_extra_source(state["roottype"])

    new_data_sets = []
    for result in state["results"]:
        new_data_sets.append(query_for_additional_data(rest, result, state["host"], (state["username"], state["password"])))

    keys = []
    for data_set in new_data_sets:
        for key in data_set.keys():
            keys.append(key)

    new_result = []
    for data_set in new_data_sets:
        dic = {}
        for key in keys:
            try:
                dic[key] = data_set[key]
            except:
                dic[key] = "N/A"
        new_result.append(dic)

    from xsa.jsonutil import JsonTable
    state["results"] = JsonTable(new_result)
    state["results_export"] = JsonTable(new_result)

    print("FINISHED")

    return results(state["results"])

@app.route("/downl_query", methods=["POST", "GET"])
def downl_query():
    from datetime import datetime
    from xsa.datatypereader import get_field_label_by_field
    import json

    root = state["roottype"]

    from urllib.parse import unquote

    constraints = []
    adjust_constraints(json.loads(unquote(request.form.get("model"))), constraints)

    labels = []
    for f in json.loads(unquote(request.form.get("fields"))):
        labels.append(get_field_label_by_field(root, f))

    # auslagern (selber code steht in xsagtk.main_controller):

    root_key = 'root'
    query_key = 'query'
    labels_key = 'labels'

    data = {}
    data.update({root_key: root})
    data.update({query_key: constraints})
    data.update({labels_key: labels})

    response = Response(json.dumps(data), mimetype='application/json')
    filename= "query_%s" %  str(datetime.now())
    response.headers["Content-Disposition"] = "attachment; filename="+filename
    return response


@app.route("/downl_csv", methods=["POST", "GET"])
def download_csv():
    from datetime import datetime
    response = Response(state['results_export'].dumps_csv(","), mimetype='text/csv')
    filename= "search_export_%s.csv" % str(datetime.now())
    response.headers["Content-Disposition"] = "attachment; filename="+filename #TODO rename file
    return response

def start_web_gui(args):
    if args.host:
        state["host"] = args.host
    if args.user:
        state["username"], _, state["password"] = args.user.partition(":")

    app.debug=True
    app.run()