Updated to sqlalchemy 2.x, as well as newer python version.

New syntax to query execution, as well as some string literal comparison stuff
master
Marek 3 days ago
parent c3f1bba1d7
commit 43006ce150

@ -7,7 +7,7 @@ from functools import wraps
from sqlalchemy.sql import select from sqlalchemy.sql import select
from sqlalchemy.sql import text from sqlalchemy.sql import text
from flask import Flask from flask import Flask
from flask import render_template, send_from_directory, request, Response, send_file, session from flask import render_template, send_from_directory, request, Response, send_file, session, jsonify
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
from io import BytesIO from io import BytesIO
from os import listdir from os import listdir
@ -30,20 +30,22 @@ with open('taglines.txt', 'r') as infile:
def getContainers(): def getContainers():
query = "select id, name from containers order by UPPER(name);" query = "select id, name from containers order by UPPER(name);"
r = db_engine.execute(text(query)) # r = db_engine.execute(text(query))
containers = [] # containers = []
for row in r: # for row in r:
containers.append(dict(row)) # containers.append(dict(row))
r.close() # r.close()
with db_engine.connect() as conn:
r = conn.execute(text(query))
containers = r.mappings().all()
return containers return containers
def check_auth(username, password): def check_auth(username, password):
query = "select id, password from users where username=:usrnm;" query = "select id, password from users where username=:usrnm;"
r = db_engine.execute(text(query), usrnm=username) #r = db_engine.execute(text(query), usrnm=username) #SQLalchemy 1.x
results = [] with db_engine.connect() as conn:
for row in r: r = conn.execute(text(query))
results.append(dict(row)) results = r.mappings().all()
r.close()
if len(results)!=1: if len(results)!=1:
return False; return False;
@ -79,99 +81,151 @@ def index():
@app.route(baseURL+'/getlocationsInContainer/<containerID>') @app.route(baseURL+'/getlocationsInContainer/<containerID>')
def get_locations_in_container(containerID): def get_locations_in_container(containerID):
s = 'select id, name from locations where container_id = :id order by name;' s = 'select id, name from locations where container_id = :id order by name;'
r = db_engine.execute(text(s), id=containerID) # r = db_engine.execute(text(s), id=containerID)
l={} # l={}
for row in r: # for row in r:
l[str(row[0])]= row[1]; # l[str(row[0])]= row[1];
r.close() # r.close()
return json.dumps(l) # return json.dumps(l)
with db_engine.connect() as conn:
r = conn.execute(text(s), {"id": containerID})
l = {str(row.id): row.name for row in r}
return jsonify(l)
@app.route(baseURL+'/getlocationURL/<locationID>') @app.route(baseURL+'/getlocationURL/<locationID>')
def get_locationURL(locationID): def get_locationURL(locationID):
s = 'select map from locations where id = :id;' s = 'select map from locations where id = :id;'
r = db_engine.execute(text(s), id=locationID) # r = db_engine.execute(text(s), id=locationID)
l=[]; # l=[];
for row in r: # for row in r:
l.append(row); # l.append(row);
r.close() # r.close()
return l[0][0] # return l[0][0]
with db_engine.connect() as conn:
result = conn.execute(text(s), {"id": locationID}).fetchone()
if result is None:
return ""
return result[0]
@app.route(baseURL+'/locationEditor') @app.route(baseURL+'/locationEditor')
def locationEditor(): def locationEditor():
query = 'select c.name as container, l.name as name, l.id, c.id as container_id from locations as l inner join containers as c on l.container_id = c.id order by container, name;' query = 'select c.name as container, l.name as name, l.id, c.id as container_id from locations as l inner join containers as c on l.container_id = c.id order by container, name;'
r = db_engine.execute(text(query)) # r = db_engine.execute(text(query))
locations = [] # locations = []
for row in r: # for row in r:
locations.append(dict(row)) # locations.append(dict(row))
r.close() # r.close()
return render_template('locationEditor.html', locations=locations, containers=getContainers(),baseURL=baseURL) # return render_template('locationEditor.html', locations=locations, containers=getContainers(),baseURL=baseURL)
with db_engine.connect() as conn:
result = conn.execute(text(query))
locations = [dict(row._mapping) for row in result]
return render_template(
'locationEditor.html',
locations=locations,
containers=getContainers(),
baseURL=baseURL
)
@app.route(baseURL+'/userEditor') @app.route(baseURL+'/userEditor')
def userEditor(): def userEditor():
query = 'select c.name as container, l.name as name, l.id, c.id as container_id from locations as l inner join containers as c on l.container_id = c.id order by container, name;'
query = 'select id, username from users;' query = 'select id, username from users;'
r = db_engine.execute(text(query)) # r = db_engine.execute(text(query))
users = [] # users = []
for row in r: # for row in r:
users.append(dict(row)) # users.append(dict(row))
r.close() # r.close()
with db_engine.connect() as conn:
result = conn.execute(text(query))
users = [dict(row._mapping) for row in result]
return render_template('userEditor.html', users=users, containers=getContainers(),baseURL=baseURL) return render_template('userEditor.html', users=users, containers=getContainers(),baseURL=baseURL)
@app.route(baseURL+'/alterLocation/<locationID>', methods=['POST']) @app.route(baseURL + '/alterLocation/<locationID>', methods=['POST'])
@requires_auth @requires_auth
def alterLocation(locationID): def alterLocation(locationID):
locationID = int(locationID) locationID = int(locationID)
s = ''
if locationID < 0: if locationID < 0:
# New entry # New entry
s = 'insert into locations (name, container_id) ' query = text("""
s += 'values (:name, :container);' insert into locations (name, container_id)
s = text(s) values (:name, :container)
r = db_engine.execute(s,name=request.form['name'],container=request.form['container']); """)
r.close()
return '{"status":"ok"}' with db_engine.begin() as conn:
conn.execute(query, {
"name": request.form['name'],
"container": request.form['container']
})
return jsonify(status="ok")
else: else:
# Modify entry # Modify entry
s = 'update locations ' query = text("""
s += 'set name=:name, container_id=:container ' update locations
s += 'where id=:locationID;' set name=:name,
s = text(s) container_id=:container
r = db_engine.execute(s, name=request.form['name'],container=request.form['container'],locationID=locationID); where id=:locationID
r.close() """)
return '{"status":"ok"}'
@app.route(baseURL+'/alterUser/<userID>', methods=['POST']) with db_engine.begin() as conn:
conn.execute(query, {
"name": request.form['name'],
"container": request.form['container'],
"locationID": locationID
})
return jsonify(status="ok")
@app.route(baseURL + '/alterUser/<userID>', methods=['POST'])
@requires_auth @requires_auth
def alterUser(userID): def alterUser(userID):
userID = int(userID) userID = int(userID)
s = ''
if userID < 0: if userID < 0:
# New entry # New entry
s = 'insert into users (username, password) ' query = text("""
s += 'values (:name, :password);' insert into users (username, password)
s = text(s) values (:name, :password)
r = db_engine.execute(s,name=request.form['name'],password=request.form['password']); """)
r.close()
return '{"status":"ok"}' with db_engine.begin() as conn:
conn.execute(query, {
"name": request.form['name'],
"password": request.form['password']
})
return jsonify(status="ok")
else: else:
# Modify entry # Modify entry
s = 'update users ' query = text("""
s += 'set username=:name, password=:password ' update users
s += 'where id=:userID;' set username=:name, password=:password
s = text(s) where id=:userID
r = db_engine.execute(s, name=request.form['name'],password=request.form['password'],userID=userID); """)
r.close()
return '{"status":"ok"}' with db_engine.begin() as conn:
conn.execute(query, {
"name": request.form['name'],
"password": request.form['password'],
"userID": userID
})
return jsonify(status="ok")
@app.route(baseURL+'/getpartinfo/<partID>') @app.route(baseURL+'/getpartinfo/<partID>')
def get_part_info(partID): def get_part_info(partID):
s = 'select p.id,partno,description,notes, c.name || l.name as location_descriptor, location_id, container_id, datasheet from parts as p inner join locations as l on p.location_id = l.id inner join containers as c on l.container_id = c.id where p.id = :id;' s = 'select p.id,partno,description,notes, c.name || l.name as location_descriptor, location_id, container_id, datasheet from parts as p inner join locations as l on p.location_id = l.id inner join containers as c on l.container_id = c.id where p.id = :id;'
r = db_engine.execute(text(s), id=partID) with db_engine.connect() as conn:
l = [] result = conn.execute(text(s), {"id": partID})
for row in r: row = result.mappings().first()
l.append(dict(row))
r.close()
return json.dumps(l[0])
return jsonify(dict(row) if row else {})
@app.route(baseURL+'/query/<filter_dummy>/<query>') # TODO: maybe change AND to OR or maybe not @app.route(baseURL+'/query/<filter_dummy>/<query>') # TODO: maybe change AND to OR or maybe not
def query(filter_dummy, query): def query(filter_dummy, query):
filter = request.args.to_dict() filter = request.args.to_dict()
@ -203,24 +257,24 @@ def query(filter_dummy, query):
s = s[:-5] s = s[:-5]
s += ') OR ' s += ') OR '
s = s[:-4] + ';' s = s[:-4] + ';'
s = text(s) # s = text(s)
r = db_engine.execute(s, kw_dict) # r = db_engine.execute(s, kw_dict)
l = [] # l = []
for row in r: # for row in r:
l.append(dict(row)) # l.append(dict(row))
r.close() # r.close()
with db_engine.connect() as conn:
l = [dict(row) for row in conn.execute(text(s), kw_dict).mappings()]
return json.dumps(l) return json.dumps(l)
@app.route(baseURL+'/map/<containerID>') @app.route(baseURL+'/map/<containerID>')
@app.route(baseURL+'/map/<containerID>/<annotate>') @app.route(baseURL+'/map/<containerID>/<annotate>')
def getMap(containerID, annotate=None): def getMap(containerID, annotate=None):
s = 'select map, overlay from containers where id = :id;' s = 'select map, overlay from containers where id = :id;'
r = db_engine.execute(text(s), id=containerID) with db_engine.connect() as conn:
l = [] row = conn.execute(text(s), {"id": containerID}).mappings().first()
for row in r: mapFile = row['map']
l.append(dict(row)) overlayFile = row['overlay']
mapFile = l[0]['map']
overlayFile = l[0]['overlay']
try: try:
mapImage = Image.open('maps/' + mapFile).convert("RGBA") mapImage = Image.open('maps/' + mapFile).convert("RGBA")
overlayImage = Image.open('maps/overlays/' + overlayFile).convert("RGBA") overlayImage = Image.open('maps/overlays/' + overlayFile).convert("RGBA")
@ -246,109 +300,134 @@ def getMap(containerID, annotate=None):
@app.route(baseURL+'/getfile/<filename>') @app.route(baseURL+'/getfile/<filename>')
def getfile(filename): def getfile(filename):
if(re.match('^[\w\-_]+.[p|P][d|D][f|F]$', filename) == None): # if(re.match('^[\w\-_]+.[p|P][d|D][f|F]$', filename) == None):
if(re.match(r'^[\w-]+\.pdf$', filename, re.IGNORECASE) == None):
return 'No injections pls.' return 'No injections pls.'
return send_from_directory('/srv/datasheets/', filename) return send_from_directory('/srv/datasheets/', filename)
@app.route(baseURL+'/alter/<partID>', methods=['POST']) @app.route(baseURL + '/alter/<partID>', methods=['POST'])
@requires_auth @requires_auth
def alter(partID): def alter(partID):
partID = int(partID) partID = int(partID)
s = ''
r = {} # -------------------------
# HANDLE FILE UPLOAD
# -------------------------
if len(request.files) != 0:
datasheet_file = request.files['datasheet-file']
datasheet_filename = secure_filename(datasheet_file.filename)
i = 1
while os.path.isfile('/srv/datasheets/' + datasheet_filename):
datasheet_filename = datasheet_filename[:-4] + str(i) + '.pdf'
i += 1
datasheet_file.save('/srv/datasheets/' + datasheet_filename)
datasheet_filename = 'http://elab.kth.se/parts/getfile/' + datasheet_filename
else:
try:
datasheet_filename = request.form['datasheet-url']
except:
datasheet_filename = None
# -------------------------
# INSERT
# -------------------------
if partID < 0: if partID < 0:
# New entry query = text("""
s = 'insert into parts (partno, description, datasheet, location_id, whoadded, notes) ' insert into parts
s += 'values (:partno, :description, :datasheet, :location_id, :user_id, :notes) returning id;' (partno, description, datasheet, location_id, whoadded, notes)
s = text(s) values
if len(request.files) != 0: (:partno, :description, :datasheet, :location_id, :user_id, :notes)
datasheet_file = request.files['datasheet-file'] returning id
datasheet_filename = secure_filename(datasheet_file.filename) """)
i = 1
while os.path.isfile('/srv/datasheets/' + datasheet_filename): with db_engine.begin() as conn:
datasheet_filename = datasheet_filename[:-4] + str(i) + '.pdf' result = conn.execute(query, {
i += 1 "partno": request.form['partno'],
datasheet_file.save('/srv/datasheets/' + datasheet_filename) "description": request.form['description'],
datasheet_filename = 'http://elab.kth.se/parts/getfile/' + datasheet_filename "datasheet": datasheet_filename,
# elif request.form.has_key('datasheet-url'): "location_id": request.form['location_id'],
# datasheet_filename = request.form['datasheet-url'] "notes": request.form['notes'],
else: "user_id": session['uid']
try: })
datasheet_filename = request.form['datasheet-url']
except: new_id = result.mappings().first()["id"]
datasheet_filename = None
r = db_engine.execute(s, partno=request.form['partno'], return jsonify(status="ok", part_id=new_id)
description=request.form['description'],
datasheet=datasheet_filename, # -------------------------
location_id=request.form['location_id'], # UPDATE
notes=request.form['notes'], # -------------------------
user_id=session['uid'])
else: else:
# Modify entry query = text("""
r = db_engine.execute(text('select * from parts where id=:id;'), id=partID) update parts
l = [] set partno=:partno,
for row in r: description=:description,
l.append(dict(row)) datasheet=:datasheet,
r.close() location_id=:location_id,
s = 'update parts ' notes=:notes
s += 'set partno=:partno, description=:description, datasheet=:datasheet, location_id=:location_id, notes=:notes ' where id=:id
if len(request.files) != 0: returning id
datasheet_file = request.files['datasheet-file'] """)
datasheet_filename = secure_filename(datasheet_file.filename)
i = 1 with db_engine.begin() as conn:
while os.path.isfile('/srv/datasheets/' + datasheet_filename): result = conn.execute(query, {
datasheet_filename = datasheet_filename[:-4] + str(i) + '.pdf' "partno": request.form['partno'],
i += 1 "description": request.form['description'],
datasheet_file.save('/srv/datasheets/' + datasheet_filename) "datasheet": datasheet_filename,
datasheet_filename = 'http://elab.kth.se/parts/getfile/' + datasheet_filename "location_id": request.form['location_id'],
if l[0]['datasheet'] != None: "notes": request.form['notes'],
whole_url = l[0]['datasheet'] "id": partID
actual_filename = whole_url[whole_url.rfind('/') + 1:] })
os.remove('/srv/datasheets/' + actual_filename)
else: new_id = result.mappings().first()["id"]
try:
datasheet_filename = request.form['datasheet-url'] return jsonify(status="ok", part_id=new_id)
except: @app.route(baseURL + '/delete/<partID>')
datasheet_filename = l[0]['datasheet']
s += 'where id=:id returning id;'
s = text(s)
r = db_engine.execute(s, partno=request.form['partno'],
description=request.form['description'],
datasheet=datasheet_filename,
location_id=request.form['location_id'],
id=partID,
notes=request.form['notes'])
new_id = r.fetchone()[0]
r.close()
return '{"status":"ok", "part_id" : ' + str(new_id) + '}'
@app.route(baseURL+'/delete/<partID>')
@requires_auth @requires_auth
def delete(partID): def delete(partID):
if int(partID) < 0: partID = int(partID)
if partID < 0:
abort(400) abort(400)
s = text('delete from parts where id=:id;')
r = db_engine.execute(s, id=partID)
return '{"status":"ok"}'
@app.route(baseURL+'/deleteLocation/<locationID>') query = text('delete from parts where id=:id')
with db_engine.begin() as conn:
conn.execute(query, {"id": partID})
return jsonify(status="ok")
@app.route(baseURL + '/deleteLocation/<locationID>')
@requires_auth @requires_auth
def deleteLocation(locationID): def deleteLocation(locationID):
if int(locationID) < 0: locationID = int(locationID)
if locationID < 0:
abort(400) abort(400)
s = text('delete from locations where id=:id;')
r = db_engine.execute(s, id=locationID) query = text('delete from locations where id=:id')
return '{"status":"ok"}'
@app.route(baseURL+'/deleteUser/<userID>') with db_engine.begin() as conn:
conn.execute(query, {"id": locationID})
return jsonify(status="ok")
@app.route(baseURL + '/deleteUser/<userID>')
@requires_auth @requires_auth
def deleteUser(userID): def deleteUser(userID):
if int(userID) < 0: userID = int(userID)
if userID < 0:
abort(400) abort(400)
s = text('delete from users where id=:id;')
r = db_engine.execute(s, id=userID) query = text('delete from users where id=:id')
return '{"status":"ok"}'
with db_engine.begin() as conn:
conn.execute(query, {"id": userID})
return jsonify(status="ok")
@app.route(baseURL+'/fetchOctopartSnippet/<searchTerm>') @app.route(baseURL+'/fetchOctopartSnippet/<searchTerm>')
def fetchOctopartSnippet(searchTerm): def fetchOctopartSnippet(searchTerm):
@ -380,8 +459,8 @@ def connect(user, password, db, host='localhost', port=5432):
con = sqlalchemy.create_engine(url, client_encoding='utf8') con = sqlalchemy.create_engine(url, client_encoding='utf8')
# We then bind the connection to MetaData() # We then bind the connection to MetaData()
meta = sqlalchemy.MetaData(bind=con) meta = sqlalchemy.MetaData()
meta.reflect(bind=con) meta.reflect(con)
return con, meta return con, meta
@ -395,7 +474,7 @@ if __name__ == '__main__':
try: try:
with open('octopartAPIkey.json') as f: with open('octopartAPIkey.json') as f:
j = json.load(f); j = json.load(f);
if j['key'] is not '': if j['key'] != '':
octopartURL = j['URL'] + j['key'] octopartURL = j['URL'] + j['key']
print ("Octopart credentials loaded.") print ("Octopart credentials loaded.")
else: else:
@ -404,6 +483,7 @@ if __name__ == '__main__':
print ("NO OCTOPART KEY FOUND. ABANDONING THAT PART") print ("NO OCTOPART KEY FOUND. ABANDONING THAT PART")
# Example query # Example query
'''s = select([parts]).where(parts.c.notes != '') '''s = select([parts]).where(parts.c.notes != '')
for row in db_engine.execute(s): with db_engine.connect() as conn:
print row''' r = conn.execute(text(query))
app.run(host='127.0.0.1', port='5000', debug=False) '''
app.run(host='127.0.0.1', port='5000', debug=False)

Loading…
Cancel
Save