-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
155 lines (129 loc) · 5.36 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import io
import json
import time
import logging
from base64 import b64encode
import redis
from mongoengine import connect
from flask import (Flask, render_template, request, send_file, redirect)
from schema import Image
from decoder import decode_redis
# Allows use to add to the database in mongoDB called covid-checkin
connect(db='imageRepo')
app = Flask("__main__")
# Setup logging config
logging.basicConfig(level=logging.INFO)
@app.route("/")
def displayAllImages():
"""
This route is used to display the images from the MongoDB database in the jinja2 frontend template.
"""
images = list()
# Gets documents from Image collection
mongoengineObjects = Image.objects()
for obj in mongoengineObjects:
imageObject = {
"title": obj.title,
"description": obj.description,
"image": obj.photo.read(), # Reads image as binary
"id": obj.id
}
# Allows only type bytes to be added to image list
if(type(imageObject['image']) is bytes):
# Converts bytes into base64 to be displayed in html
imageObject['image'] = b64encode(imageObject['image']).decode("utf-8")
# Pushes displayable images into list
images.append(imageObject)
else:
logging.error( "this image is not of type bytes", imageObject)
# Sends list of images to frontend for rendering
return render_template("allImages.html", images=images)
@app.route("/", methods=['POST'])
def search():
"""
This route is used to limit the results displayed in the frontend allowing user to filter through all the pictures in the database based on a specifc word search
"""
images = list()
if request.method == "POST":
searchValue = request.form["searchValue"]
mongoengineObjects = Image.objects.search_text(searchValue)
for obj in mongoengineObjects:
imageObject = {
"title": obj.title,
"description": obj.description,
"image": obj.photo.read(),
"id": obj.id
}
if(type(imageObject['image']) is bytes):
imageObject['image'] = b64encode(imageObject['image']).decode("utf-8")
images.append(imageObject)
else:
logging.error("this image is not of type bytes", imageObject)
return render_template("show.html", images=images)
@app.route("/addImage", methods=['GET','POST'])
def addImageToDB():
"""
Route for adding an image to the database
"""
if request.method == "POST":
searchValue = request.form["searchValue"]
description = request.form["description"]
file = request.files["file"].read()
# creates a document for image in collection Image
image = Image(title=searchValue)
image.description = description
image.photo.put(file, filename=(searchValue+".jpg"))
image.save()
return redirect("/")
return render_template("form.html")
@app.route("/image/<id>", methods=['GET'])
def displayIndividualImage(id):
"""
Route for displaying a single image based on id
id: string -- id of image to be displayed in database
"""
# redis configuration
r = redis.Redis(host='localhost', port=6379, db=0)
redisValue = r.hgetall(id)
# Checks if the image is in Redis first, if the image is not found in Redis, the image is searched for in mongoDB
if redisValue == {}:
mongoengineObject = Image.objects(id=id).first()
# If the image is not found in MongoDB, an error is logged and error page is rendered
if mongoengineObject is None:
logging.error("The user has tried to display image that is not available, image id doesn't correspond to an image Id: '", id "' was not found")
return render_template("error.html")
imageObject = {
"title": mongoengineObject.title,
"description": mongoengineObject.description,
"image": mongoengineObject.photo.read(),
"id": str(mongoengineObject.id)
}
imageObject['image'] = b64encode(imageObject['image']).decode("utf-8")
# Adds the image to Redis so that the next time it is retrived in this route it will be found in Redis which is a faster process than MongoDB
r.hmset(id, imageObject)
imgObjectToSendToHtml = imageObject
else:
# If the image was found in Redis it will be sent to frontend
image = decode_redis(redisValue)
imgObjectToSendToHtml = image
return render_template("anImage.html", image=imgObjectToSendToHtml)
@app.route("/delete/<id>", methods=['POST'])
def delete(id):
"""
Route for deleting images from the database based on the id passed through url of post request
id: string -- id of image to be deleted in database
"""
if request.method == 'POST':
# Image is deleted and the if statement verifies that it was successful
if(Image.objects(id=id).delete() != 1):
logging.error("User tried to delete an image unsuccessfully. Id: ", id)
return redirect("/")
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
"""
Route created to redirect to homepage of application if route is not already specified
path: string -- undefined url
"""
return redirect("/")
app.run(debug=True)