how to display an image and its values onto an html page in flask - python

i want to display both an image and its information simultaneously on an html page.
Please see my code below. i want that the value of 'temp' will change each time global_temp is updated from function render(video).
(Please pay attention in the #comment of python, includes: #1 and #2)
index.html page:
{% extends 'base.html' %}{% block content %}
<h1 style="text-align: center;margin-top:15px;">{{temp}}</h1>
<img src="{{ url_for('video') }}"/>
{% endblock %}
main.py:
from flask import Flask, render_template, Response
from video import Video
from file import LoadFile
import cv2
import ssl
import datetime
import os
app = Flask(__name__)
global_temp = 1
#app.route('/')
def index():
global global_temp
return render_template('index.html',
temp=global_temp) #1. update temp for html (from render video)
def render(video):
print('file: ')
t = 0
file = LoadFile()
loadFileName = ''
while True:
t+=1
loadFile = file.get_files()
if(loadFile['success']):
try:
cap = cv2.VideoCapture(loadFile['file'])
length = int(cv2.VideoCapture.get(cap, int(cv2.CAP_PROP_FRAME_COUNT)))
j = 0
if(loadFileName != loadFile['file']):
loadFileName = loadFile['file']
while True and (length > 0 and j < length):
j+=1
try:
global global_temp
global_temp = j #2. update for html
frame = video.get_frame(cap)
yield(b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
except Exception as e:
print('Error frame: ', str(e))
break
except Exception as e:
print('Main: ',str(e))
#app.route('/video')
def video():
return Response(render(Video()),
mimetype='multipart/x-mixed-replace; boundary=frame')
app.run(debug=True)

Related

Flask: can't get redirection to work when using openCV

I am using opencv and pyzbar to make a barcode scanner that can work in a flask app.
There is a while True loop which constantly outputs the current camera frame to 127.0.0.1:5000/scanner, whilst simultaneously attempting to decode a barcode from the image. If it decodes a barcode, the loop breaks and the program redirects to 127.0.0.1:5000/output/, where the barcode number is displayed - except it doesn't for some reason. 127.0.0.1:5000/output/ displays correctly if it is entered manually.
Python:
from flask import Flask, render_template, Response, redirect, url_for
import io
import cv2
import sys
from pyzbar import pyzbar
app = Flask(__name__)
#app.route('/output/')
def output():
return str(output)
#app.route('/scanner')
def index():
return render_template('scanner.html')
def gen():
vc = cv2.VideoCapture(0)
while True:
read_return_code, frame = vc.read()
og = frame
cv2.rectangle(frame,(200,170),(450,330),(0,255,100),7)
frame = cv2.flip(frame, 1)
decode = pyzbar.decode(og)
if len(str(decode)) > 10:
global output
output = str(decode).split("'")
output = output[1]
vc.release()
return redirect('/output/') #THE PROBLEM
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
encode_return_code, image_buffer = cv2.imencode('.jpg', frame)
io_buf = io.BytesIO(image_buffer)
print("a", file=sys.stderr)
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + io_buf.read() + b'\r\n')
#app.route('/video_feed')
def video_feed():
return Response(
gen(),
mimetype='multipart/x-mixed-replace; boundary=frame'
)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, threaded=False)
HTML:
<html>
<head>
<style>
body{
font-family: Verdana, sans-serif;
}
</style>
<title>Scanner</title>
</head>
<body>
<h1>Scanner</h1>
<img src="{{ url_for('video_feed') }}">
</body>
</html>
you return redirect without parameters, this is equal to just requesting it via URL.
your 'output' route doesn't take any input params.
You should change your code to something like this, where 'data' is the output of your cv:
app.route('/output/<data>')
def output(data):
return str(data)
app.route('/scanner')
def index():
data='whatever'
return redirect(url_for('output', data=data))

How to send images from Flask to JavaScript in real time

I'm currently writing a program that uses webRTC, Flask, and openCV etc... to analyze a webcam video in real time.
I succeeded in sending the webcam video from JavaScript to the Flask server, but I cannot display the image after analysis from Flask to HTML.
For example, I tried to save the image file once.
#app.route("/img", methods=["POST"])
def img():
img = cv2.imdecode(np.fromstring(request.files['video'].read(), np.uint8), cv2.IMREAD_UNCHANGED)
   #Processing by openCV...
cv2.imwrite("test.jpg", img)
return "success"
#app.route('/feed')
def feed():
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
def gen():
while True:
with open('test.jpg', 'rb') as f:
img = f.read()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + img + b'\r\n')
Next is the HTML code
<img id="cap-src" src="{{ url_for('feed') }}">
However, this code curiously didn't update the image displayed in HTML, so I gave up.
Then I tried the method of not saving the image.
#app.route("/img", methods=["POST"])
def img():
global img
img = cv2.imdecode(np.fromstring(request.files['video'].read(), np.uint8), cv2.IMREAD_UNCHANGED)
def generate_img():
  #Processing by openCV...
#app.route('/feed')
def feed():
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
def gen():
while True:
img = generate_img()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + img + b'\r\n')
The HTML code does not change.
However, this method did not update the image displayed in HTML.
Is there any good way?
And I want to use a method that doesn't save the image if possible.Thank you.
Finally, I put the summarized code.
This is the HTML code
<html>
<head>
</head>
<body>
<img id="img">
<video id="myvideo" width="720px" autoplay></video>
<button id="start"></button>
<canvas id="videocanvas"></canvas>
<img id="cap-src" src="">
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script>
$(function(){
const constraints = window.constraints = {
audio: false,
video: {
facingMode: "environment"
}
};
async function init() {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
const video = document.querySelector('#myvideo');
const videoTracks = stream.getVideoTracks();
window.stream = stream;
video.srcObject = stream;
e.target.disabled = true;
} catch{
$('#errorMsg').text('error');
}
}
$('#start').click(init);
var canvas = $('#videocanvas')[0];
$('#myvideo').on('loadedmetadata', function(){
var video = $('#myvideo')[0];
var width = canvas.width = video.videoWidth;
var height = canvas.height = video.videoHeight;
var ctx = canvas.getContext("2d");
var fd = new FormData();
fd.append('video', null);
setInterval(function(){
ctx.drawImage(video, 0, 0, width, height);
canvas.toBlob(function(blob){
fd.set('video', blob);
$.ajax({
url: "/img",
type : "POST",
processData: false,
contentType: false,
data : fd,
dataType: "text",
})
.done(function(data){
console.log(data);
})
.fail(function(data){
console.log(data);
});
}, 'image/jpeg');
},100);
});
});
document.getElementById("start").onclick = function() {
document.getElementById("cap-src").src = "{{ url_for('feed') }}";
}
</script>
</body>
</html>
And the python code.
from flask import Flask, render_template, Response, request, jsonify
import cv2
import numpy as np
from PIL import Image
#app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,POST') # Put any other methods you need here
return response
#app.route('/')
def index():
return render_template('index.html')
#app.route("/img", methods=["POST"])
def img():
img = cv2.imdecode(np.fromstring(request.files['video'].read(), np.uint8), cv2.IMREAD_UNCHANGED)
image = cv2.resize(img, (480, 300))
cv2.imwrite("test.jpg", image)
ret, jpeg = cv2.imencode('.jpg', image)
jpeg = jpeg.tobytes()
return "success"
#api.route('/feed')
def feed():
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
def gen():
while True:
with open('./templates/dst/test.jpg', 'rb') as f:
img = f.read()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + img + b'\r\n')
Since the issue you mentioned is about "displaying the image after analysis from Flask to HTML", so here is the solution to your problem, it can send video or camera output images to the html. For more details follow this tutorial
The main python app (which will run on the server) file is here:
app.py
from flask import Flask, render_template, request,Response
import cv2,imutils,time
import pyshine as ps
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
def changeBrightness(img,value):
""" This function will take an image (img) and the brightness
value. It will perform the brightness change using OpenCv
and after split, will merge the img and return it.
"""
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)
lim = 255 - value
v[v>lim] = 255
v[v<=lim] += value
final_hsv = cv2.merge((h,s,v))
img = cv2.cvtColor(final_hsv,cv2.COLOR_HSV2BGR)
return img
def changeBlur(img,value):
""" This function will take the img image and blur values as inputs.
After perform blur operation using opencv function, it returns
the image img.
"""
kernel_size = (value+1,value+1) # +1 is to avoid 0
img = cv2.blur(img,kernel_size)
return img
def pyshine_process(params):
print("Parameters:",params)
"""Video streaming generator function."""
CAMERA=True
if CAMERA:
cap = cv2.VideoCapture(0)
else:
cap = cv2.VideoCapture('videos/mario.mp4')
print('FUNCTION DONE')
# Read until video is completed
fps=0
st=0
frames_to_count=20
cnt=0
while(cap.isOpened()):
ret, img = cap.read()
brightness_value_now = int(params['brightness'])
blur_value_now = int(params['blur'])
img = changeBrightness(img,brightness_value_now)
img = changeBlur(img,blur_value_now)
if ret == True:
if cnt == frames_to_count:
try: # To avoid divide by 0 we put it in try except
fps = round(frames_to_count/(time.time()-st))
st = time.time()
cnt=0
except:
pass
cnt+=1
img = imutils.resize(img, width=640)
text = 'FPS: '+str(fps)
img = ps.putBText(img,text,text_offset_x=20,text_offset_y=30,background_RGB=(10,20,222))
text = str(time.strftime("%d %b %Y %H.%M.%S %p"))
img = ps.putBText(img,text,text_offset_x=190,text_offset_y=30,background_RGB=(228,20,222))
text = f"Brightness: {brightness_value_now}"
img = ps.putBText(img,text,text_offset_x=20,text_offset_y=300,background_RGB=(20,210,4))
text = f'Blur: {blur_value_now}'
img = ps.putBText(img,text,text_offset_x=490,text_offset_y=300,background_RGB=(210,20,4))
frame = cv2.imencode('.JPEG', img,[cv2.IMWRITE_JPEG_QUALITY,20])[1].tobytes()
time.sleep(0.016)
yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
else:
break
#app.route('/res',methods = ['POST','GET'])
def res():
global result
if request.method == 'POST':
result = request.form.to_dict()
return render_template("results.html",result = result)
#app.route('/results')
def video_feed():
global result
params= result
return Response(pyshine_process(params),mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == "__main__":
app.run(debug=True, host='192.168.1.104',port=9999,threaded=True)
Here are the files for the templates folder
index.html
<html>
<head>
<title>PyShine streaming video application </title>
</head>
<body>
<h1>Please input the parameters (0 to 100): </h1>
<form action = "http://192.168.1.104:9999/res" method = "POST">
<table>
<tr>
<td align="right">Brightness:</td>
<td align="left"><input type="text" name="brightness" value="1" /></td>
</tr>
<tr>
<td align="right">Blur:</td>
<td align="left"><input type="text" name="blur" value="0" /></td>
</tr>
<tr>
<td></td>
<td align="right"><input type = "submit" value = "submit" /></td>
</tr>
</table>
</form>
</body>
</html>
results.html
<!DOCTYPE html>
<html>
<head>
<title>PyShine Streaming Video Application </title>
</head>
<body>
<h1>PyShine streaming processed video... </h1>
<br>
<img src="">
<br>
<input type="button" value="Go back!" onclick="history.back()">
</body>
</html>
Important: change the host IP address according to your specifications.

Running a yolo model in the flask server itself. How to?

I am working on an application in which as soon as I run the flask server my webcam should start(which it does!) and show the yolo model on the webpage itself(the one that I have runs independently, which I don't want).
I'm not sure how do I tackle this. Maybe by looking at the code you would be able to help.
main.py
from flask import Flask, render_template, Response
from camera import VideoCamera
import tablib
import os
app = Flask(__name__)
dataset = tablib.Dataset()
with open(os.path.join(os.path.dirname(__file__), 'object.csv')) as f:
dataset.csv = f.read()
#app.route('/')
def index():
data = dataset.html
return render_template('index.html', data=data)
def gen(camera):
while True:
count = 0
frame = camera.get_frame()
yield (b'--frame+str("%d"%count)\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
#app.route('/video_feed')
def video_feed():
return Response(gen(VideoCamera()),
mimetype='multipart/x-mixed-replace; boundary=frame')
#app.route('/table')
def display_table():
#do something to create a pandas datatable
df = pd.DataFrame(data=[[person], [Timestamps]])
df_html = df.to_html() #using pandas to autogenerate html
return render_template('index.html', 'table_html=df_html')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
camera.py
import datetime
import cv2
import time
import numpy as np
from keras import backend as K
from keras.models import load_model
from yad2k.models.keras_yolo import yolo_head, yolo_eval
from yad2k.yolo_utils import read_classes, read_anchors, preprocess_webcam_image, draw_boxes, generate_colors
import pandas as pd
class VideoCamera(object):
def __init__(self):
# Using OpenCV to capture from device 0. If you have trouble capturing
# from a webcam, comment the line below out and use a video file
# instead.
self.video = cv2.VideoCapture(0)
self.class_names = read_classes("model_data/coco_classes.txt")
anchors = read_anchors("model_data/yolo_anchors.txt")
image_shape = (480., 640.)
self.yolo_model = load_model("model_data/yolo.h5")
#print(self.yolo_model.summary(), "fndkjcndkn")
yolo_outputs = yolo_head(self.yolo_model.output, anchors, len(self.class_names))
self.scores, self.boxes, self.classes = yolo_eval(yolo_outputs, image_shape)
def predict(self,sess,frame):
# Preprocess your image
image, image_data = preprocess_webcam_image(frame, model_image_size=(608, 608))
out_scores, out_boxes, out_classes = sess.run([self.scores, self.boxes, self.classes], feed_dict={self.yolo_model.input: image_data,
K.learning_phase(): 0})
# Print predictions info
#print('Found {} boxes'.format(len(out_boxes))) #here it prints object names!
# Generate colors for drawing bounding boxes.
colors = generate_colors(self.class_names)
# Draw bounding boxes on the image file
draw_boxes(image, out_scores, out_boxes, out_classes, self.class_names, colors)
return np.array(image), out_boxes
def __del__(self):
self.video.release()
cv2.destroyAllWindows()
def get_frame(self):
sess = K.get_session()
while True:
# Capture frame-by-frame
grabbed, frame = self.video.read()
if not grabbed:
break
#Run detection
start = time.time()
output_image,image = self.predict(sess,frame)
#df = pd.DataFrame({'Object': [image], 'Timestamp': [datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p")]}, index=[0])
#df.to_csv('objects3.csv', sep=';', header = 2, index=False, encoding='utf-8', mode = 'a', columns=['Object', 'Timestamp'])
#df.to_csv('object2.csv', header= 2, mode = 'a')
end = time.time()
cv2.imshow('', output_image)
if(cv2.waitKey(1) & 0xFF == ord('q')):
return 0
#dt = datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p")
#print (dt)
#print("Inference time: {:.2f}s".format(end - start))
success, image = self.video.read()
# We are using Motion JPEG, but OpenCV defaults to capture raw images,
# so we must encode it into JPEG in order to correctly display the
# video stream.
ret, jpeg = cv2.imencode('.jpg', image)
# Display the resulting frame
cv2.imshow('', output_image)
#
# When everything done, release the capture
stream.release()
cv2.destroyAllWindows()
index.html
<html>
<head>
<title>Video Streaming Demonstration</title>
<link rel=stylesheet type="text/css" href="{{ url_for('static', filename='css/style.css')}}"/>
</head>
<body>
<h1>Keep Looking...</h1>
<img id="bg" src="{{ url_for('video_feed') }}">
{{ table_html | safe }}
<table border="1" class="dataframe">
<thead>
<tr style="text-align: left;">
<th>Objects</th>
<th>Timestamps</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ output_image }} </td>
<td>{{ dt }}</td>
</tr>
</tbody>
</table>
<!-- new code -->
<div class="table">
{% block body %}
{{ data|safe }}
{% endblock %}
</div>
</body>
</html>
This example could work for you. He is not streaming from a camera but from a file. You could write this file in Yolo from one script and read it from Flask. You just need to remove the OpenCV camera code.
test.py
from flask import Flask, render_template, Response
import cv2
import socket
import io
app = Flask(__name__)
vc = cv2.VideoCapture(0)
#app.route('/')
def index():
"""Video streaming ."""
return render_template('index.html')
def gen():
"""Video streaming generator function."""
while True:
rval, frame = vc.read()
cv2.imwrite('pic.jpg', frame)
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + open('pic.jpg', 'rb').read() + b'\r\n')
#app.route('/video_feed')
def video_feed():
"""Video streaming route. Put this in the src attribute of an img tag."""
return Response(gen(),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(debug=True, threaded=True)
/templates/index.html
<html>
<head>
<title>Video Streaming </title>
</head>
<body>
<h1> Live Video Streaming </h1>
<img src="{{ url_for('video_feed') }}">
</body>
</html>

How do I display a newly saved image using opencv from Flask in the static folder?

I'm trying to take image input and do some processing on it before displaying the output on the webpage. However, when I try a different image, the older image is displayed instead of the new one.
Here are the code snippets:
from flask import Flask, render_template, request
import pro
app = Flask(__name__)
#app.route('/')
def index():
return render_template("index.html")
#app.route('/process', methods=['GET', 'POST'])
def process():
n = '/home/vivek/Desktop/CL3/d/booth/trial/uploads/up.jpg'
a = pro.pro(n)
return render_template("out.html")
if __name__ == '__main__':
app.run(debug=True)
The process code:
import cv2
def pro(p):
img = cv2.imread(p, 1)
# some process here
path = '/home/vivek/Desktop/CL3/d/booth/trial/static/'
cv2.imwrite(str(path) + 'out.jpg',img)
cv2.waitKey(0)
np = '/home/vivek/Desktop/CL3/d/booth/trial/static/out.jpg'
return np
And finally the HTML file:
<!DOCTYPE html>
<html>
<body>
<h2>OUTPUT</h2>
<img src="{{url_for('static', filename='out.jpg')}}" alt="OUTPUT" style="width:128px;height:128px;">
</body>
</html>
You need to disable cache
def process():
....
resp = make_response(render_template('out.html'))
resp.cache_control.no_cache = True
return resp
Updated
class MyFlask(Flask):
def get_send_file_max_age(self, name):
if name == 'out.jpg':
return 0
return Flask.get_send_file_max_age(self, name)
app = MyFlask(__name__)

upload an image and a label with Flask

I am toying around with an image uploader using Flask. I cloned it from this repository https://github.com/chokepoint/flaskgur . I have it running on my VPS here
http://107.170.119.38
What I'm trying to do is enable someone to write a custom label for an image they are about to upload. The final product should display an image and the custom label the user typed in. The image uploader works fine but I can't seem to store the label in the database on upload. Here is my code
from flask import Flask, request, g, redirect, url_for, abort, render_template,send_from_directory
from werkzeug import secure_filename
from hashlib import md5
from PIL import Image
import sqlite3
import os
import time
DEBUG = True
BASE_DIR = '/var/www/flaskgur/'
UPLOAD_DIR = BASE_DIR + 'pics'
DATABASE = BASE_DIR + 'flaskgur.db'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__)
app.config.from_object(__name__)
# Make sure extension is in the ALLOWD_EXTENSIONS set
def check_extension(extension):
return extension in ALLOWED_EXTENSIONS
def connect_db():
return sqlite3.connect(app.config['DATABASE'])
# Return a list of the last 25 uploaded images
def get_last_pics():
cur = g.db.execute('select * from pics order by id desc limit 25')
filenames = [dict(id=row[0], filename=row[1], label=row[2]) for row in cur.fetchall()]
#filenames = [row[0] for row in cur.fetchall()]
return filenames
# Insert filename into database
def add_pic(filename, label):
g.db.executemany('insert into pics (filename, label) values (?, ?)', [filename, label])
g.db.commit()
# Generate thumbnail image
def gen_thumbnail(filename):
height = width = 200
original = Image.open(os.path.join(app.config['UPLOAD_DIR'], filename))
thumbnail = original.resize((width, height), Image.ANTIALIAS)
thumbnail.save(os.path.join(app.config['UPLOAD_DIR'], 'thumb_'+filename))
def add_label(label):
label = request.form['label']
g.db.execute('INSERT INTO pics (label) VALUES (?)', [label])
g.db.commit()
# Taken from flask example app
#app.before_request
def before_request():
g.db = connect_db()
# Taken from flask example app
#app.teardown_request
def teardown_request(exception):
db = getattr(g, 'db', None)
if db is not None:
db.close()
#app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
#app.route('/', methods=['GET','POST'])
def upload_pic():
if request.method == 'POST':
file = request.files['file']
try:
extension = file.filename.rsplit('.', 1)[1].lower()
except IndexError, e:
abort(404)
if file and check_extension(extension):
# Salt and hash the file contents
filename = md5(file.read() + str(round(time.time() * 1000))).hexdigest() + '.' + extension
file.seek(0) # Move cursor back to beginning so we can write to disk
file.save(os.path.join(app.config['UPLOAD_DIR'], filename, label))
add_pic(filename)
add_label(label)
gen_thumbnail(filename)
return redirect(url_for('show_pic', filename=filename))
else: # Bad file extension
abort(404)
else:
return render_template('upload.html', pics=get_last_pics())
#app.route('/show')
def show_pic():
filename = request.args.get('filename','')
return render_template('upload.html', filename=filename, label=label)
def show_label():
g.db = connect_db()
cur = g.db.execute('SELECT label FROM pics WHERE id=(?)')
labels = cur.fetchone()
return render_template('upload.html', labels=labels)
#app.route('/pics/<filename>')
def return_pic(filename):
return send_from_directory(app.config['UPLOAD_DIR'], secure_filename(filename))
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0')
And my template (upload.html):
{% if filename is defined %}
<div id="image"><img class="new" src="{{ pic_path(filename) }}"></div>
<h2><p>The Label is: </p>{{ labels }}</h2>
{% else %}
<ul>
{% for pic in pics %}
<li class="thumb"><img class="thumb" src="{{ pic_path('thumb_'+pic) }}"></li>
{% endfor %}
base template (base.html):
<div id="upload">
<h1>Upload Picture</h1>
<form action="/" method=post enctype=multipart/form-data>
<p>
<input type=file name=file><br />
<p>Add a Label:</p>
<input type=text name=label value={{ request.form.label }}><br />
<input type=submit value=Upload>
</p>
</div>
I apologize if my code is atrocious. I am trying my best to learn
I figured it out. Rewrote the get_last_pics() function to this:
# Return a list of the last 25 uploaded images
def get_last_pics():
try:
cur = g.db.execute('select filename, label from pics order by id desc limit 25')
filenames = []
for row in cur.fetchall():
filenames.append({"filename": row[0], "label": row[1] or ''})
return filenames
except:
return []
rewrote add_pic() to this:
# Insert filename and label into database
def add_pic(filename, label):
g.db.execute('insert into pics (filename, label) values (?, ?)', [filename, label])
g.db.commit()
rewrote upload_pic() to this:
#app.route('/', methods=['GET', 'POST'])
def upload_pic():
if request.method == 'POST':
file = request.files['file']
label = request.form['label']
try:
extension = file.filename.rsplit('.', 1)[1].lower()
except IndexError, e:
abort(404)
if file and check_extension(extension):
# Salt and hash the file contents
filename = md5(file.read() + str(round(time.time() * 1000))).hexdigest() + '.' + extension
file.seek(0) # Move cursor back to beginning so we can write to disk
file.save(os.path.join(app.config['UPLOAD_DIR'], filename))
add_pic(filename, label)
gen_thumbnail(filename)
return redirect(url_for('show_pic', filename=filename))
else:
# Bad file extension
abort(404)
else:
return render_template('upload.html', pics=get_last_pics())
rewrote show_pic() to this:
#app.route('/show')
def show_pic():
filename = request.args.get('filename', '')
t = (filename,)
cur = g.db.execute('select label from pics where filename=?', t)
label = cur.fetchone()[0]
return render_template('upload.html', filename=filename, label=label)
Everything works now. Hope that helps someone in the future

Categories