Select Git revision
interface.py
-
Alexandros Asonitis authoredAlexandros Asonitis authored
main.py 6.39 KiB
"""
The main app. This handles both the backend and the frontend side.
render_template just renders the html from the "template" folder.
redirect_url redirects towards a certain url, but does NOT render a template if the pointed url also does not.
"""
from flask import Flask, render_template, url_for, request, redirect, flash, send_file, send_from_directory
from datetime import datetime
from werkzeug.utils import secure_filename
import os, time, sys
"""
The following are the import for the backend. Just write the name of the script without .py.
Then you can immediately use the function from the script directly in the app.
"""
sys.path.append(os.path.join(os.path.dirname(sys.path[0]),'Backend'))
import dqn, petrinet
import eventlog as elog
#define the app
app = Flask(__name__)
#the super secret key that allows browser based flashes :
app.secret_key = '54321'
#specifies where the upload directory is and the file type available for uploads
UPLOAD_FOLDER = r'upload'
ALLOWED_EXTENSIONS = {'.csv','.xes'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#specifies the static folder used for images and stuff
STATIC_FOLDER = r'static'
app.config['STATIC_FOLDER'] = STATIC_FOLDER
#specifices where the temporary folder for downloaded file would be:
DOWNLOAD_FOLDER = r'export'
app.config['DOWNLOAD_FOLDER'] = DOWNLOAD_FOLDER
IMAGES_FOLDER = r'images'
app.config['IMAGES_FOLDER'] = IMAGES_FOLDER
#home page route. The type inputs are just for the list selection.
@app.route('/')
def index():
types = ['csv','xes']
return render_template('index.html',fileTypes = types)
"""
The following is the upload functionality. It uploads directly into the "upload" directory.
Then it redirects towards the case ID input page.
"""
@app.route('/', methods=['POST'])
def upload_file():
uploaded_file = request.files['file']
if uploaded_file.filename != '':
#file is saved in the 'upload' directory.
uploaded_file.save(os.path.join(app.config['UPLOAD_FOLDER'],uploaded_file.filename))
if not elog.format_check(uploaded_file.filename):
flash('Event log does not match the expected business process!')
return redirect(url_for('index'))
elif uploaded_file.filename == '':
#if no file has been selected, flashes a warning
flash('No files selected! Please select a file!')
return redirect(url_for('index'))
return redirect(url_for('case_id', filename = uploaded_file.filename))
"""
The download usage. Currently just downloads fish.jpg.
os.path.join here is setup to point towards static folder and also point at fish.jpg.
Currently it just sends a preexisting file. Meaning the generated file will have to be saved somewhere to import.
"""
@app.route('/download/', methods=['GET'])
def download():
filetype = time = ''
filetype = request.args.get("selectType")
time = request.args.get("elogTime")
if time != None:
time = int(time)
elog.generate_event_log(time)
if filetype == 'csv':
path = os.path.join(app.config['DOWNLOAD_FOLDER'], 'elog.csv')
#flash the confirmation that file is succesfully downloaded
# flash('Generated a event log in csv. Please check your attachments!')
return send_file(path, as_attachment=True)
elif filetype == 'xes':
path = os.path.join(app.config['DOWNLOAD_FOLDER'], 'elog.xes')
#flash the confirmation that file is succesfully downloaded
# flash('Generated a event log in xes. Please check your attachments!')
return send_file(path, as_attachment=True)
else:
path = os.path.join(app.config['DOWNLOAD_FOLDER'], 'fish.jpg')
#flash the confirmation that file is succesfully downloaded
# flash('Else')
return send_file(path, as_attachment=True)
"""
Route for displaying possible case IDs. It is a dropdown menu that displays the list from the python script in the dropdown menu.
There is a preview functionality, when clicked will show a preview of a generated image. It is linked to the 'preview' button in the case id page.
The generated image currently displays static images and not instantly generated ones from the backend.
Currently it displays moyai.jpg by default and fish.jpg on case 1 and 2. Will change this later.
"""
@app.route('/case.html/<filename>', methods=['GET'])
def case_id(filename):
#temporary choice of cases until I figure out where the actual function from backend is.
#give the list here in selection using functions from
selection = elog.get_active_cases(filename)
previewid = request.args.get("selectpreview")
# preview = "../static/fish.jpg"
if previewid != None:
for file in os.listdir('static/'):
if file.startswith('preview_net'): # not to remove other images
os.remove('static/' + file)
result = int(previewid)
petrinet.decorate_petri_net(result, filename)
return render_template('case.html', selection=selection, filename=filename)
"""
Route for sending the case id towards recommendation. This is linked to the 'Optimize now' button in the case ID page.
I have decided to use a separate dropdown list to avoid cross sending the http requests by accident.
"""
@app.route('/case.html/<filename>', methods=['POST'])
def send_caseid(filename):
result = request.form.get("selectresult")
return redirect(url_for('recommendation', result=result, filename=filename))
"""
The result page.
It processes "id" (for now it uses the "foo" function from input.py) using backend functions
and prints out the result immediately in the page.
"""
@app.route('/result.html/<filename>/<result>', methods=['GET'])
def recommendation(result, filename):
result = int(result)
state = elog.get_state(result, filename)
rec = dqn.deploy(state)
rec = int(rec)
for file in os.listdir('static/'):
if file.startswith('net'): # not to remove other images
os.remove('static/' + file)
name = petrinet.decorate_petri_net_with_rec(result, rec, filename)
return render_template('result.html', name = name)
"""
Loading page. Has yet to be used.
"""
#loading page route
@app.route('/loading.html')
def loading():
return render_template('loading.html')
#about us page route
@app.route('/aboutus.html')
def aboutus():
return render_template('aboutus.html')
#the main app
if __name__ == "__main__":
port = int(os.environ.get('PORT', 5000))
app.run(debug=True, host='0.0.0.0', port=port)