Skip to content

Commit

Permalink
add web app (incomplete)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pei-Yun Sun committed Oct 19, 2020
1 parent f789a9c commit 11a92a9
Show file tree
Hide file tree
Showing 40 changed files with 17,852 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export HAP_DB_NAME=hap
export HAP_DB_HOST=localhost
export HAP_DB_PORT=27017
23 changes: 23 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from config import create_app, db
from views import public_route_bp
from controller import api_bp_new, api_bp_old


app = create_app()
"""
register blueprint
"""
app.register_blueprint(public_route_bp)
app.register_blueprint(api_bp_old)
app.register_blueprint(api_bp_new, url_prefix='/api')

app.app_context().push()


def main():
app.run(debug=True, host="0.0.0.0", port=5000) # RUNNING APP MAKE debug =FALSE for Production Env
# app.run(debug=True, host="localhost", port=8888)


if __name__ == "__main__":
main()
50 changes: 50 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from flask import Flask
from flask_mongoengine import MongoEngine
from deepface import DeepFaceLite
# import tensorflow as tf
# from tensorflow.python.keras.backend import set_session
import os

"""
initialize the ML engine
"""
db = MongoEngine()
# sess = tf.Session()
# graph = tf.get_default_graph()
# set_session(sess)
deepface = DeepFaceLite()

"""
database environment variable
"""
DB_NAME = os.environ.get('HAP_DB_NAME')
DB_HOST = os.environ.get('HAP_DB_HOST')
DB_PORT = os.environ.get('HAP_DB_PORT')
DB_USERNAME = os.environ.get('HAP_DB_USERNAME')
DB_PASSWORD = os.environ.get('HAP_DB_PASSWORD')


def create_app():
"""
return app instance
:return: app instance
"""
app = Flask(__name__)
if DB_USERNAME is not None and DB_PASSWORD is not None:
app.config['MONGODB_SETTINGS'] = {
'db': DB_NAME,
'host': DB_HOST,
'port': int(DB_PORT),
'username': DB_USERNAME,
'password': DB_PASSWORD
}
else:
app.config['MONGODB_SETTINGS'] = {
'db': DB_NAME,
'host': DB_HOST,
'port': int(DB_PORT)
}

db.init_app(app)

return app
24 changes: 24 additions & 0 deletions controller/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from flask_restplus import Api
from flask import Blueprint
from controller.prediction_controller import api as predict_apis
from controller.feedback_controller import api as feedback_apis
from controller.general_controller import api as general_apis


# old api, will be discard later
api_bp_old = Blueprint('api_old', __name__)

api = Api(api_bp_old)

api.add_namespace(predict_apis)
api.add_namespace(general_apis)

"""
new api with /api/ path
"""
api_bp_new = Blueprint('api_new', __name__)

api_new = Api(api_bp_new)
api_new.add_namespace(general_apis)
api_new.add_namespace(predict_apis)
api_new.add_namespace(feedback_apis)
32 changes: 32 additions & 0 deletions controller/feedback_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from flask import request
from extension.utilServices import send_json_response
from flask_restplus import Namespace, Resource
import datetime
api = Namespace('feedback', path='/feedback', description='prediction related operations')


@api.route('')
class Feedback(Resource):
@api.doc('feedback related api')
def post(self):
"""
store user feedbacks to the database
:return: operation results
"""
from models.feedback import Feedback, FeedbackContent

message = request.get_json(force=True)

try:
new_feedback = Feedback()
new_feedback_content = []
for each_content in message['data']:
feedback_content = FeedbackContent(**each_content)
new_feedback_content.append(feedback_content)

new_feedback.content = new_feedback_content
new_feedback.date = datetime.datetime.now()
new_feedback.save()
return send_json_response({}, 200)
except Exception as error:
return send_json_response({'msg': str(error)}, 500)
190 changes: 190 additions & 0 deletions controller/general_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
from extension.utilServices import (send_json_response)
from extension.constants import CONSTANTS
import csv
import re
from flask_restplus import Namespace, Resource
import datetime
import copy

api = Namespace('general', path='/', description='general information related to app')


# @api.route('/get-breed-info')
# class BreedList(Resource):
# @api.doc('get breed information from csv')
# def get(self):
# """
# return the breed information, which gets from wikipedia
# :return: list of breed information
# """
# breed_info = {}
# for animal_type in CONSTANTS['ANIMAL_TYPE']:
# with open('wikiFile/' + animal_type + '.csv') as csv_file:
# csv_reader = csv.reader(csv_file, delimiter=',')
# line_count = 0
# json_title = []
# animal_list = []
# for row in csv_reader:
# if line_count == 0:
# json_title = row
# line_count += 1
# else:
# info_obj = {
# json_title[0]: row[0],
# json_title[1]: row[1],
# json_title[2]: row[2],
# json_title[3]: row[3],
# json_title[4]: row[4],
# }
# animal_list.append(info_obj)
# line_count += 1
# csv_file.close()
# breed_info[animal_type] = animal_list

# return send_json_response(breed_info, 200)


@api.route('/get-app-info')
class AppInfo(Resource):
@api.doc('return the app developer information')
def get(self):
"""
return the footer information
:return: return the app related information
"""
app_info = {
'developedBy': 'This app was developed by the Melbourne eResearch Group (www.eresearch.unimelb.edu.au) within the School of Computing and Information Systems (https://cis.unimelb.edu.au) at The University of Melbourne (www.unimelb.edu.au). ',
'description': 'The app uses artificial intelligence (convolutional neural networks) that have been trained on dog/cat images to identify whether a dog/cat is in an image, and if so the species type (breed) and it\'s emotion.',
'contact': 'https://eresearch.unimelb.edu.au',
'developedByHTML': '<p>This app was developed by the Melbourne eResearch Group (<a href=\"www.eresearch.unimelb.edu.au\" target=\"_blank\">www.eresearch.unimelb.edu.au</a>) within the School of Computing and Information Systems (<a href=\"https://cis.unimelb.edu.au\" target=\"_blank\">https://cis.unimelb.edu.au</a>) at The University of Melbourne (<a href=\"www.unimelb.edu.au\" target=\"_blank\">www.unimelb.edu.au</a>).</p>',
'descriptionHTML': '<p>The app uses artificial intelligence (convolutional neural networks) that have been trained on dog/cat images to identify whether a dog/cat is in an image, and if so the species type (breed) and it\'s emotion.</p>',
'contactHTML': '<p>Please contact us at: <a href=\"eresearch.unimelb.edu.au\" target=\"_blank\">eresearch.unimelb.edu.au</a></p>'
}

return send_json_response(app_info, 200)


@api.route('/get-statistical-results')
class StatisticalData(Resource):
@api.doc('return statistical data')
def get(self):
"""
return the statistical information
query across feedback and prediction model
:return: return statistical information
"""
from models.prediction import Prediction
from models.feedback import Feedback

total_cat_breed = []
total_dog_breed = []
prediction_collection = Prediction._get_collection()
feedback_collection = Feedback._get_collection()
statistical_data = copy.deepcopy(CONSTANTS['STATISTICAL_DATA'])

# initial statistical_data based on breed and alpha order
f = open("model_data/pet_classes.txt", "r")
for each_line in f:
first_char = each_line[0]
if first_char.isupper():
total_cat_breed.append(re.sub(r"_", " ", each_line.rstrip(), flags=re.IGNORECASE).title())
else:
total_dog_breed.append(re.sub(r"_", " ", each_line.rstrip(), flags=re.IGNORECASE).title())
f.close()
total_cat_breed.sort()
total_dog_breed.sort()

for each_breed in total_cat_breed:
statistical_data['Cat']['prediction_data']['breed'][each_breed] = 0
statistical_data['Cat']['feedback_data']['breed']['wrong'][each_breed] = 0
statistical_data['Cat']['feedback_data']['breed']['correct'][each_breed] = 0

for each_breed in total_dog_breed:
statistical_data['Dog']['prediction_data']['breed'][each_breed] = 0
statistical_data['Dog']['feedback_data']['breed']['wrong'][each_breed] = 0
statistical_data['Dog']['feedback_data']['breed']['correct'][each_breed] = 0

# photo by date
today = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
total_number_of_photo_within_one_week = {
(today - datetime.timedelta(days=6)).strftime('%d/%m/%Y'): prediction_collection.count_documents(
{'date': {'$lt': today - datetime.timedelta(days=5), '$gte': today - datetime.timedelta(days=6)}}),
(today - datetime.timedelta(days=5)).strftime('%d/%m/%Y'): prediction_collection.count_documents(
{'date': {'$lt': today - datetime.timedelta(days=4), '$gte': today - datetime.timedelta(days=5)}}),
(today - datetime.timedelta(days=4)).strftime('%d/%m/%Y'): prediction_collection.count_documents(
{'date': {'$lt': today - datetime.timedelta(days=3), '$gte': today - datetime.timedelta(days=4)}}),
(today - datetime.timedelta(days=3)).strftime('%d/%m/%Y'): prediction_collection.count_documents(
{'date': {'$lt': today - datetime.timedelta(days=2), '$gte': today - datetime.timedelta(days=3)}}),
(today - datetime.timedelta(days=2)).strftime('%d/%m/%Y'): prediction_collection.count_documents(
{'date': {'$lt': today - datetime.timedelta(days=1), '$gte': today - datetime.timedelta(days=2)}}),
(today - datetime.timedelta(days=1)).strftime('%d/%m/%Y'): prediction_collection.count_documents(
{'date': {'$lt': today, '$gte': today - datetime.timedelta(days=1)}}),
today.strftime('%d/%m/%Y'): prediction_collection.count_documents(
{'date': {'$gte': today}}),
}

# prediction
total_prediction = prediction_collection.find({})
for each_prediction in total_prediction:
prediction_results = each_prediction['predictionResults']
for each_result in prediction_results:
statistical_data[each_result['type']]['prediction_number'] = statistical_data[each_result['type']].get(
'prediction_number', 0) + 1
statistical_data[each_result['type']]['prediction_data']['breed'][each_result['breed']] = \
statistical_data[each_result['type']]['prediction_data']['breed'].get(each_result['breed'], 0) + 1
statistical_data[each_result['type']]['prediction_data']['emotion'][each_result['emotion']] = \
statistical_data[each_result['type']]['prediction_data']['emotion'].get(each_result['emotion'],
0) + 1
# feedback
total_feedback = feedback_collection.find({})

for each_feedback in total_feedback:
feedback_content = each_feedback['content']
for each_content in feedback_content:
statistical_data[each_content['type']]['feedback_number'] = statistical_data[each_content['type']].get(
'feedback_number', 0) + 1

if not each_content['breedCorrectness']:
statistical_data[each_content['type']]['feedback_data']['breed']['wrong'][
each_content['breedFeedback']] = \
statistical_data[each_content['type']]['feedback_data']['breed'][
'wrong'].get(each_content['breedFeedback'], 0) + 1
else:
statistical_data[each_content['type']]['feedback_data']['breed']['correct'][
each_content['breedFeedback']] = \
statistical_data[each_content['type']]['feedback_data']['breed']['correct'].get(
each_content['breedFeedback'], 0) + 1

if not each_content['emotionCorrectness']:
statistical_data[each_content['type']]['feedback_data']['emotion']['wrong'][
each_content['emotionFeedback']] = \
statistical_data[each_content['type']]['feedback_data']['emotion']['wrong'].get(
each_content['emotionFeedback'], 0) + 1
else:
statistical_data[each_content['type']]['feedback_data']['emotion']['correct'][
each_content['emotionFeedback']] = \
statistical_data[each_content['type']]['feedback_data']['emotion']['correct'].get(
each_content['emotionFeedback'], 0) + 1

result = {
'totalNumberOfPhotoUploaded': prediction_collection.count_documents({}),
'totalNumberOfCatPrediction': statistical_data['Cat']['prediction_number'],
'totalNumberOfDogPrediction': statistical_data['Dog']['prediction_number'],
'totalNumberOfCatFeedback': statistical_data['Cat']['feedback_number'],
'totalNumberOfDogFeedback': statistical_data['Dog']['feedback_number'],
'totalNumberOfDogBreedPrediction': statistical_data['Dog']['prediction_data']['breed'],
'totalNumberOfDogBreedCorrectFeedback': statistical_data['Dog']['feedback_data']['breed']['correct'],
'totalNumberOfDogBreedWrongFeedback': statistical_data['Dog']['feedback_data']['breed']['wrong'],
'totalNumberOfDogEmotionPrediction': statistical_data['Dog']['prediction_data']['emotion'],
'totalNumberOfDogEmotionCorrectFeedback': statistical_data['Dog']['feedback_data']['emotion']['correct'],
'totalNumberOfDogEmotionWrongFeedback': statistical_data['Dog']['feedback_data']['emotion']['wrong'],
'totalNumberOfCatBreedPrediction': statistical_data['Cat']['prediction_data']['breed'],
'totalNumberOfCatBreedCorrectFeedback': statistical_data['Cat']['feedback_data']['breed']['correct'],
'totalNumberOfCatBreedWrongFeedback': statistical_data['Cat']['feedback_data']['breed']['wrong'],
'totalNumberOfCatEmotionPrediction': statistical_data['Cat']['prediction_data']['emotion'],
'totalNumberOfCatEmotionCorrectFeedback': statistical_data['Cat']['feedback_data']['emotion']['correct'],
'totalNumberOfCatEmotionWrongFeedback': statistical_data['Cat']['feedback_data']['emotion']['wrong'],
'numberOfPhotoByDate': total_number_of_photo_within_one_week
}

return send_json_response(result, 200)
Loading

0 comments on commit 11a92a9

Please sign in to comment.