orm mining works
This commit is contained in:
parent
74ef03ae4b
commit
69df560fff
|
|
@ -0,0 +1,7 @@
|
||||||
|
FROM python
|
||||||
|
COPY ./certs /certs
|
||||||
|
|
||||||
|
COPY ./ /app
|
||||||
|
RUN pip install -r /app/requirements.txt
|
||||||
|
|
||||||
|
CMD python /app/run.py
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
from flask import Flask, request, g, render_template
|
||||||
|
from flask_restful import Resource, reqparse
|
||||||
|
from flask_restful_swagger_3 import Api
|
||||||
|
from flask_cors import CORS
|
||||||
|
import os
|
||||||
|
from json import dumps
|
||||||
|
import application.endpoints as endpoints
|
||||||
|
import application.config as config
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
api = Api(app, version='1', contact={"name":""}, license={"name":"Online Dienst Dokumentation"}, api_spec_url='/api/swagger')
|
||||||
|
|
||||||
|
api.add_resource(endpoints.Recipe,'/api/v1/recipe/')
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def index():
|
||||||
|
"""serve the ui"""
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
debug = True
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
import sqlalchemy as db
|
||||||
|
from sqlalchemy import Column, String, Integer, Numeric, Table, DateTime, ARRAY, ForeignKey, create_engine, LargeBinary, Enum, Text
|
||||||
|
from sqlalchemy.orm import sessionmaker, relationship, column_property
|
||||||
|
from datetime import datetime
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
import enum
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
engine = db.create_engine('sqlite:///./test.sqlite', echo=False)
|
||||||
|
connection = engine.connect()
|
||||||
|
Base = declarative_base()
|
||||||
|
Session = sessionmaker(bind=engine)
|
||||||
|
|
||||||
|
# https://docs.sqlalchemy.org/en/13/orm/basic_relationships.html#association-object
|
||||||
|
class Link(Base):
|
||||||
|
__tablename__ = 'link'
|
||||||
|
recipe_id = Column(Integer, ForeignKey('recipe.recipe_id'), primary_key=True)
|
||||||
|
ingredient_id = Column(Integer, ForeignKey('ingredient.ingredient_id'), primary_key=True)
|
||||||
|
ingredient_amount = Column('ingredient_amount', Text)
|
||||||
|
ingredient_amount_mu = Column('ingredient_amount_mu', Text) # measurement unit
|
||||||
|
|
||||||
|
recipe = relationship("Recipe", back_populates="ingredient")
|
||||||
|
ingredient = relationship("Ingredient", back_populates="recipe")
|
||||||
|
|
||||||
|
def ingredients(self):
|
||||||
|
return self.ingredient.name
|
||||||
|
|
||||||
|
class Recipe(Base):
|
||||||
|
__tablename__ = "recipe"
|
||||||
|
recipe_id = Column('recipe_id', Integer, primary_key=True, autoincrement=True)
|
||||||
|
name = Column('name', Text)
|
||||||
|
instructions = Column('instructions', Text)
|
||||||
|
url = Column('url', Text)
|
||||||
|
img = Column('img', LargeBinary)
|
||||||
|
ingredient = relationship("Link", back_populates="recipe")
|
||||||
|
|
||||||
|
def ingredients(self):
|
||||||
|
l = []
|
||||||
|
for i in self.ingredient:
|
||||||
|
l.append(i.ingredients())
|
||||||
|
return l
|
||||||
|
|
||||||
|
def ingredientDict(self):
|
||||||
|
l = {}
|
||||||
|
for i in self.ingredient:
|
||||||
|
l[i.ingredients()] = [i.ingredient_amount, i.ingredient_amount_mu]
|
||||||
|
return l
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
ingredients = []
|
||||||
|
|
||||||
|
if self.img is not None:
|
||||||
|
img = self.img.decode('utf-8')
|
||||||
|
else:
|
||||||
|
img = None
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"recipe_id": self.recipe_id,
|
||||||
|
"name":self.name,
|
||||||
|
"instructions":self.instructions,
|
||||||
|
"url": self.url,
|
||||||
|
"img": img,
|
||||||
|
"ingredients": self.ingredient.ingredient
|
||||||
|
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
class Ingredient(Base):
|
||||||
|
__tablename__ = "ingredient"
|
||||||
|
ingredient_id = Column('ingredient_id', Integer, primary_key=True)
|
||||||
|
name = Column('name', Text)
|
||||||
|
recipe = relationship("Link", back_populates="ingredient")
|
||||||
|
|
||||||
|
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
from flask_restful import Resource, reqparse
|
||||||
|
import flask
|
||||||
|
import requests
|
||||||
|
import application.config as config
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
from application.db import Session, Recipe, Ingredient
|
||||||
|
|
||||||
|
class Recipe(Resource):
|
||||||
|
def get(self):
|
||||||
|
""" """
|
||||||
|
try:
|
||||||
|
parser = reqparse.RequestParser()
|
||||||
|
parser.add_argument('useFace', type=bool, required=False)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
session = Session()
|
||||||
|
|
||||||
|
return flask.make_response(flask.jsonify({'data': args}), 200)
|
||||||
|
except Exception as e:
|
||||||
|
print("error: -", e)
|
||||||
|
return flask.make_response(flask.jsonify({'error': str(e)}), 400)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
function getJSON(url, callback, fallback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', url, true);
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.onload = function () {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status < 400) {
|
||||||
|
callback(null, xhr.response);
|
||||||
|
} else {
|
||||||
|
fallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
};
|
||||||
|
|
||||||
|
function putJSON(url, data, callback, fallback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('PUT', url, true);
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
xhr.onload = function () {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status < 400) {
|
||||||
|
callback(null, xhr.response);
|
||||||
|
} else {
|
||||||
|
fallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
function postJSON(url, data, callback, fallback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, true);
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
xhr.onload = function () {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status < 400) {
|
||||||
|
callback(null, xhr.response);
|
||||||
|
} else {
|
||||||
|
fallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(data);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#list{
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top:0;
|
||||||
|
width: 20rem;
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#switch{
|
||||||
|
width: 25rem;
|
||||||
|
height: 5rem;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: -50%;
|
||||||
|
|
||||||
|
}
|
||||||
|
.navButton{
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
#main{
|
||||||
|
width: 65rem;
|
||||||
|
height: 38rem;
|
||||||
|
position: relative;
|
||||||
|
top: 10rem;
|
||||||
|
left: -50%;
|
||||||
|
display: block;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listIMG{
|
||||||
|
width: 5rem;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navi{
|
||||||
|
margin-left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.personalInfo{
|
||||||
|
float: right;
|
||||||
|
width: 9rem;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
.card{
|
||||||
|
margin-top:1rem;
|
||||||
|
}
|
||||||
|
.card-text{
|
||||||
|
padding: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#middle-left{
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
#middle-right{
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
.middle{
|
||||||
|
padding: 2rem ;
|
||||||
|
margin: 0 !important;
|
||||||
|
height: 100%;
|
||||||
|
width: 45%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#image-left{
|
||||||
|
width:100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
#image-right{
|
||||||
|
width:100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroInfo{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-controls{
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
|
||||||
|
rootKontext = ""
|
||||||
|
selected = null
|
||||||
|
var ml = document.getElementById('middle-left');
|
||||||
|
var mr = document.getElementById('middle-right');
|
||||||
|
personData = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves input data from a form and returns it as a JSON object.
|
||||||
|
* @param {HTMLFormControlsCollection} elements the form elements
|
||||||
|
* @return {Object} form data as an object literal
|
||||||
|
*/
|
||||||
|
const formToJSON = elements => [].reduce.call(elements, (data, element) => {
|
||||||
|
data[element.name] = element.value;
|
||||||
|
return data;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
function focusNav(id) {
|
||||||
|
focusedID = id;
|
||||||
|
$(id).addClass('btn-primary').siblings().removeClass('btn-primary')
|
||||||
|
//$(id).removeClass('active').siblings().removeClass('active')
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusPerson(id) {
|
||||||
|
selected = id;
|
||||||
|
$("#person" + id).removeClass('border-light').siblings().addClass('border-light')
|
||||||
|
$("#person" + id).addClass('border-success').siblings().removeClass('border-success')
|
||||||
|
renderPersonRight()
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadPersonList(data) {
|
||||||
|
console.log(data)
|
||||||
|
data = data["data"]
|
||||||
|
let el = document.getElementById('list');
|
||||||
|
data.forEach(function (item) {
|
||||||
|
string = `
|
||||||
|
<div class="card border-light" onclick="focusPerson(${item["person_id"]})" id="person${item["person_id"]}">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">${item["fname"]} ${item["lname"]}</h4>
|
||||||
|
<h6 class="card-subtitle mb-2 text-muted">${item["timestamp"]}</h6>
|
||||||
|
|
||||||
|
<p class="card-text">
|
||||||
|
<img class="listImg" src="${item["face"]}"></img>
|
||||||
|
<div class="personalInfo">
|
||||||
|
Gender: ${item["gender"]} <br>
|
||||||
|
YoB: ${item["yob"]} <br>
|
||||||
|
Available FP: ${item["fingerprints"].length} <br>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
el.innerHTML += string;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function snapShot(){
|
||||||
|
postJSON(rootKontext + "/api/v1/camera/", {},
|
||||||
|
function (error, data) {
|
||||||
|
document.getElementById('image-left').src = rootKontext + "/api/v1/camera/still";
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderPersonRight(data){
|
||||||
|
string = `
|
||||||
|
<img src="${data["face"]}" id="image-right"> </img>
|
||||||
|
|
||||||
|
<h4 class="heroInfo">
|
||||||
|
Gender: ${data["gender"]} <br>
|
||||||
|
YoB: ${data["yob"]} <br>
|
||||||
|
Available FP: ${data["fingerprints"].length} <br>
|
||||||
|
<h3>Score: ${data["matching_score"]} </h3>
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
`
|
||||||
|
mr.innerHTML = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function enrole(){
|
||||||
|
data = {}
|
||||||
|
data["fname"] = document.getElementById("personform")["fname"].value
|
||||||
|
data["lname"] = document.getElementById("personform")["lname"].value
|
||||||
|
data["gender"] = document.getElementById("personform")["gender"].value
|
||||||
|
data["yob"] = document.getElementById("personform")["yob"].value
|
||||||
|
data = {"person": data}
|
||||||
|
console.log(data)
|
||||||
|
postJSON(rootKontext + "/api/v1/person/", JSON.stringify(data),
|
||||||
|
function(){
|
||||||
|
location.reload()
|
||||||
|
},
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function identify(){
|
||||||
|
snapShot()
|
||||||
|
getJSON(rootKontext + "/api/v1/person/?useFace=True",
|
||||||
|
function (error, data) {
|
||||||
|
data = data["data"]
|
||||||
|
renderPersonRight(data)
|
||||||
|
$("#middle-right").removeClass("border-danger").addClass("boarder-success")
|
||||||
|
},
|
||||||
|
function(){
|
||||||
|
$("#middle-right").removeClass("border-success").addClass("border-danger")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate(){
|
||||||
|
snapShot()
|
||||||
|
getJSON(rootKontext + "/api/v1/person/" + selected + "?useFace=True",
|
||||||
|
function (error, data) {
|
||||||
|
data = data["data"]
|
||||||
|
renderPersonRight(data)
|
||||||
|
$("#middle-right").removeClass("border-danger").addClass("border-success")
|
||||||
|
},
|
||||||
|
function(){
|
||||||
|
mr.innerHTML="<p><h3>Please select a person<br> from the list, which you want to use for validation</h3></p>"
|
||||||
|
$("#middle-right").removeClass("border-success").addClass("border-danger")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadStream() {
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
`
|
||||||
|
ml.innerHTML += string;
|
||||||
|
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/still"}" id="image-right"> </img>
|
||||||
|
`
|
||||||
|
mr.innerHTML += string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadData() {
|
||||||
|
getJSON(rootKontext + "/api/v1/person/",
|
||||||
|
function (error, data) {
|
||||||
|
ml = document.getElementById('middle-left');
|
||||||
|
mr = document.getElementById('middle-right');
|
||||||
|
personData = data
|
||||||
|
loadPersonList(data)
|
||||||
|
renderIdentify()
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
function clearMiddle(){
|
||||||
|
ml.innerHTML = ""
|
||||||
|
mr.innerHTML = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderValidate(){
|
||||||
|
clearMiddle()
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
|
||||||
|
<button onclick="validate()" class="btn btn-primary float-right middle-controls">Verify</button>
|
||||||
|
<button onclick="renderValidate()" class="btn btn-warning float-right middle-controls">Retry</button>
|
||||||
|
`
|
||||||
|
ml.innerHTML = string;
|
||||||
|
$("#middle-right").removeClass("border-danger").removeClass("border-success")
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderChange(){
|
||||||
|
clearMiddle()
|
||||||
|
$("#middle-right").removeClass("border-danger").removeClass("border-success")
|
||||||
|
console.log("change")
|
||||||
|
|
||||||
|
}
|
||||||
|
function renderEnrole(){
|
||||||
|
clearMiddle()
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
|
||||||
|
<button onclick="snapShot()" class="btn btn-primary float-right middle-controls">Snap</button>
|
||||||
|
<button onclick="renderEnrole()" class="btn btn-warning float-right middle-controls">Retry</button>
|
||||||
|
`
|
||||||
|
ml.innerHTML = string;
|
||||||
|
|
||||||
|
string2 = `
|
||||||
|
<form id="personform">
|
||||||
|
<input type="text" class="form-control" name="fname" placeholder="First Name" ><br>
|
||||||
|
<input type="text" class="form-control" name="lname" placeholder="Last Name" ><br>
|
||||||
|
<select class="form-control" id="gender" name="gender">
|
||||||
|
<option>male</option>
|
||||||
|
<option>female</option>
|
||||||
|
<option>other</option>
|
||||||
|
</select><br>
|
||||||
|
<input type="text" class="form-control" name="yob" placeholder="YoB"><br>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<button type="button" class="btn btn-success float-right" onclick="enrole()">Enrole</button>
|
||||||
|
`
|
||||||
|
mr.innerHTML = string2;
|
||||||
|
$("#middle-right").removeClass("border-danger").removeClass("border-success")
|
||||||
|
}
|
||||||
|
function renderIdentify(){
|
||||||
|
clearMiddle()
|
||||||
|
string = `
|
||||||
|
<img src="${rootKontext + "/api/v1/camera/stream"}" id="image-left"> </img>
|
||||||
|
|
||||||
|
<button onclick="identify()" class="btn btn-primary float-right middle-controls">Identify</button>
|
||||||
|
<button onclick="renderIdentify()" class="btn btn-warning float-right middle-controls">Retry</button>
|
||||||
|
`
|
||||||
|
ml.innerHTML = string;
|
||||||
|
$("#middle-right").removeClass("border-danger").removeClass("border-success")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<!--Bootstrap-->
|
||||||
|
<!-- Latest compiled and minified CSS -->
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||||
|
<link href="https://bootswatch.com/4/superhero/bootstrap.css" rel="stylesheet" id="bootstrap-css3">
|
||||||
|
<link rel="stylesheet" title="default" href="/static/main.css">
|
||||||
|
|
||||||
|
<!-- jQuery library -->
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Popper JS -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Latest compiled JavaScript -->
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/static/coms.js"></script>
|
||||||
|
<script src="/static/render.js"></script>
|
||||||
|
<script src="/static/main.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div style="position: fixed; left: 50%; z-index: 9999;">
|
||||||
|
<div class="navbar navbar-expand-lg navbar-dark bg-dark" id="switch">
|
||||||
|
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||||
|
<button type="button" class="btn btn-primary navButton active" id="option1" onclick="focusNav('#option1'); renderIdentify()"> Identify
|
||||||
|
<button type="button" class="btn navButton" id="option2" onclick="focusNav('#option2'); renderValidate()"> Verify
|
||||||
|
<button type="button" class="btn navButton" id="option3" onclick="focusNav('#option3'); renderEnrole()"> Enrole
|
||||||
|
<button type="button" class="btn navButton" id="option4" onclick="focusNav('#option4'); renderChange()"> Change
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="position: fixed; left: 50%;">
|
||||||
|
<div class="container bg-dark" id="main">
|
||||||
|
<div class="middle card" id="middle-left">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="middle card" id="middle-right">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container bg-dark" id="list">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>loadData();</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
File diff suppressed because one or more lines are too long
26
mine.py
26
mine.py
|
|
@ -6,6 +6,9 @@ import json
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import random
|
import random
|
||||||
import traceback
|
import traceback
|
||||||
|
import cv2
|
||||||
|
import base64
|
||||||
|
from application.db import Session, Recipe, Ingredient, Link
|
||||||
|
|
||||||
header_values = {
|
header_values = {
|
||||||
'name': 'Michael Foord',
|
'name': 'Michael Foord',
|
||||||
|
|
@ -60,7 +63,7 @@ def getRecipe(links):
|
||||||
recs = dict()
|
recs = dict()
|
||||||
with requests.Session() as session:
|
with requests.Session() as session:
|
||||||
counter = 0
|
counter = 0
|
||||||
for link in links[:1]:
|
for link in links:
|
||||||
counter += 1
|
counter += 1
|
||||||
try:
|
try:
|
||||||
site = session.get(link, headers=header_values)
|
site = session.get(link, headers=header_values)
|
||||||
|
|
@ -69,15 +72,24 @@ def getRecipe(links):
|
||||||
namePath = "/html/body/main/article[1]/div/div[2]/h1/text()"
|
namePath = "/html/body/main/article[1]/div/div[2]/h1/text()"
|
||||||
ingredPath = "/html/body/main/article[2]/table/tbody/tr/td" # TODO: fix this
|
ingredPath = "/html/body/main/article[2]/table/tbody/tr/td" # TODO: fix this
|
||||||
recipPath = "/html/body/main/article[3]/div[1]/text()"
|
recipPath = "/html/body/main/article[3]/div[1]/text()"
|
||||||
|
imgPath = './data/images.jpeg'
|
||||||
|
|
||||||
name = tree.xpath(namePath)[0]
|
name = tree.xpath(namePath)[0]
|
||||||
ingred = tree.xpath(ingredPath)
|
ingred = tree.xpath(ingredPath)
|
||||||
resip = tree.xpath(recipPath)
|
resip = tree.xpath(recipPath)
|
||||||
|
|
||||||
|
image = cv2.imread(imgPath)
|
||||||
|
ret, jpeg = cv2.imencode(".jpeg", image)
|
||||||
|
img = base64.b64encode(jpeg)
|
||||||
|
|
||||||
resString = ""
|
resString = ""
|
||||||
for x in resip:
|
for x in resip:
|
||||||
resString += x + "\n"
|
resString += x
|
||||||
|
|
||||||
|
dbSession = Session()
|
||||||
|
|
||||||
|
r = Recipe(name=name, instructions=resString, url=link, img=img)
|
||||||
|
|
||||||
ingredDict = {}
|
ingredDict = {}
|
||||||
for i in range(0, len(ingred)-1, 2):
|
for i in range(0, len(ingred)-1, 2):
|
||||||
#print(ingred[i+1][0].text)
|
#print(ingred[i+1][0].text)
|
||||||
|
|
@ -95,13 +107,19 @@ def getRecipe(links):
|
||||||
except:
|
except:
|
||||||
amount = ""
|
amount = ""
|
||||||
#print(stuff, amount)
|
#print(stuff, amount)
|
||||||
|
a = Link(ingredient_amount=amount)
|
||||||
|
a.ingredient = Ingredient(name=stuff)
|
||||||
|
r.ingredient.append(a)
|
||||||
|
dbSession.add(r)
|
||||||
|
dbSession.commit()
|
||||||
|
|
||||||
ingredDict[stuff] = amount
|
ingredDict[stuff] = amount
|
||||||
recs[name] = [resString, ingredDict, link]
|
recs[name] = [resString, ingredDict, link, img.decode("utf-8")]
|
||||||
print("")
|
print("")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
|
|
||||||
print(format(counter/100, '.2f'), link)
|
print(format(counter/len(links), '.2f'), link)
|
||||||
sleep(random.randint(0, 5))
|
sleep(random.randint(0, 5))
|
||||||
return recs
|
return recs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
flask
|
||||||
|
flask_restful
|
||||||
|
sqlalchemy
|
||||||
|
requests
|
||||||
|
flask-restful-swagger-3
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
from application import app
|
||||||
|
|
||||||
|
app.run(host="localhost", port='5001', debug=True)
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue