|
|
|
import json
|
|
|
|
import re
|
|
|
|
import sqlalchemy
|
|
|
|
from sqlalchemy.sql import select
|
|
|
|
from sqlalchemy.sql import text
|
|
|
|
from flask import Flask
|
|
|
|
from flask import render_template, send_from_directory, request
|
|
|
|
from werkzeug.utils import secure_filename
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
db_engine = {}
|
|
|
|
db_metadata = {}
|
|
|
|
parts = {}
|
|
|
|
|
|
|
|
@app.route('/parts')
|
|
|
|
def index():
|
|
|
|
return render_template('partsearch.html')
|
|
|
|
|
|
|
|
@app.route('/parts/getpartinfo/<partID>')
|
|
|
|
def get_part_info(partID):
|
|
|
|
s = 'select * from parts where id = :id;'
|
|
|
|
r = db_engine.execute(text(s), id=partID)
|
|
|
|
l = []
|
|
|
|
for row in r:
|
|
|
|
l.append(dict(row))
|
|
|
|
r.close()
|
|
|
|
return json.dumps(l[0])
|
|
|
|
|
|
|
|
@app.route('/parts/query/<filter>/<query>')
|
|
|
|
def query(filter, query):
|
|
|
|
query = '%' + query + '%'
|
|
|
|
filter = int(filter)
|
|
|
|
s = 'select * from parts where '
|
|
|
|
if filter & (1 << 0) != 0:
|
|
|
|
s += 'LOWER(type) like LOWER(:name) or '
|
|
|
|
if filter & (1 << 1) != 0:
|
|
|
|
s += 'LOWER(partno) like LOWER(:name) or '
|
|
|
|
if filter & (1 << 2) != 0:
|
|
|
|
s += 'LOWER(partnoalt) like LOWER(:name) or '
|
|
|
|
if filter & (1 << 3) != 0:
|
|
|
|
s += 'LOWER(partnoalt2) like LOWER(:name) or '
|
|
|
|
if filter & (1 << 4) != 0:
|
|
|
|
s += 'LOWER(description) like LOWER(:name) or '
|
|
|
|
if filter & (1 << 5) != 0:
|
|
|
|
s += 'LOWER(notes) like LOWER(:name) or '
|
|
|
|
s = s[:-4] + ';'
|
|
|
|
s = text(s)
|
|
|
|
r = db_engine.execute(s, name=query)
|
|
|
|
l = []
|
|
|
|
for row in r:
|
|
|
|
l.append(dict(row))
|
|
|
|
r.close()
|
|
|
|
return json.dumps(l)
|
|
|
|
|
|
|
|
@app.route('/parts/getfile/<filename>')
|
|
|
|
def getfile(filename):
|
|
|
|
if(re.match('^[\w-_]+\.pdf$', filename) == None):
|
|
|
|
return 'No injections pls.'
|
|
|
|
|
|
|
|
return send_from_directory('/srv/datasheets/', 'filename')
|
|
|
|
|
|
|
|
@app.route('/parts/alter/<partID>', methods=['POST'])
|
|
|
|
def alter(partID):
|
|
|
|
partID = int(partID)
|
|
|
|
s = ''
|
|
|
|
if partID < 0:
|
|
|
|
# New entry
|
|
|
|
s = 'insert into parts (block, type, partno, partnoalt, partnoalt2, description, quantity, datasheet, notes) '
|
|
|
|
s += 'values (:block, :type, :partno, :partnoalt, :partnoalt2, :description, :quantity, :datasheet, :notes);'
|
|
|
|
s = text(s)
|
|
|
|
if len(request.files) != 0:
|
|
|
|
datasheet_file = request.files['datasheet-file']
|
|
|
|
datasheet_filename = secure_filename(datasheet_file.filename)
|
|
|
|
datasheet_file.save('/srv/datasheets/' + filename)
|
|
|
|
else:
|
|
|
|
datasheet_filename = ''
|
|
|
|
r = db_engine.execute(s, block=request.form['block'],
|
|
|
|
type=request.form['type'],
|
|
|
|
partno=request.form['partno'],
|
|
|
|
partnoalt=request.form['partnoalt'],
|
|
|
|
partnoalt2=request.form['partnoalt2'],
|
|
|
|
description=request.form['description'],
|
|
|
|
quantity=request.form['quantity'],
|
|
|
|
datasheet=datasheet_filename,
|
|
|
|
notes=request.form['notes'])
|
|
|
|
else:
|
|
|
|
# Modify entry
|
|
|
|
r = db_engine.execute(text('select * from parts where id=:id;'), id=partID)
|
|
|
|
l = []
|
|
|
|
for row in r:
|
|
|
|
l.append(dict(row))
|
|
|
|
r.close()
|
|
|
|
s = 'update parts '
|
|
|
|
s += 'set block=:block, type=:type, partno=:partno, partnoalt=:partnoalt, partnoalt2=:partnoalt2, description=:description, quantity=:quantity, datasheet=:datasheet, notes=:notes '
|
|
|
|
if len(request.files) != 0:
|
|
|
|
datasheet_file = request.files['datasheet-file']
|
|
|
|
datasheet_filename = secure_filename(datasheet_file.filename)
|
|
|
|
datasheet_file.save('/srv/datasheets/' + filename)
|
|
|
|
# TODO: Remove old datasheet
|
|
|
|
else:
|
|
|
|
datasheet_filename = l[0]['datasheet']
|
|
|
|
s += 'where id=:id;'
|
|
|
|
s = text(s)
|
|
|
|
r = db_engine.execute(s, block=request.form['block'],
|
|
|
|
type=request.form['type'],
|
|
|
|
partno=request.form['partno'],
|
|
|
|
partnoalt=request.form['partnoalt'],
|
|
|
|
partnoalt2=request.form['partnoalt2'],
|
|
|
|
description=request.form['description'],
|
|
|
|
quantity=request.form['quantity'],
|
|
|
|
datasheet=datasheet_filename,
|
|
|
|
notes=request.form['notes'],
|
|
|
|
id=partID)
|
|
|
|
|
|
|
|
|
|
|
|
return '{"status":"ok"}'
|
|
|
|
|
|
|
|
def connect(user, password, db, host='localhost', port=5432):
|
|
|
|
'''Returns a connection and a metadata object'''
|
|
|
|
# We connect with the help of the PostgreSQL URL
|
|
|
|
url = 'postgresql://{}:{}@{}:{}/{}'
|
|
|
|
url = url.format(user, password, host, port, db)
|
|
|
|
|
|
|
|
# The return value of create_engine() is our connection object
|
|
|
|
con = sqlalchemy.create_engine(url, client_encoding='utf8')
|
|
|
|
|
|
|
|
# We then bind the connection to MetaData()
|
|
|
|
meta = sqlalchemy.MetaData(bind=con, reflect=True)
|
|
|
|
|
|
|
|
return con, meta
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
with open('admin.json') as f:
|
|
|
|
postgres_credentials = json.load(f)
|
|
|
|
db_engine, db_metadata = connect(postgres_credentials['username'], postgres_credentials['password'], 'parts')
|
|
|
|
parts = sqlalchemy.Table('parts', db_metadata)
|
|
|
|
# Example query
|
|
|
|
'''s = select([parts]).where(parts.c.notes != '')
|
|
|
|
for row in db_engine.execute(s):
|
|
|
|
print row'''
|
|
|
|
app.run('0.0.0.0')
|