From 433ad25335b94876710ea27fc0d0173f951a8440 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 00:16:29 +0100 Subject: sql name search many terms --- megapixels/app/models/sql_factory.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index a580f28e..82e59b22 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -101,10 +101,12 @@ class SqlDataset: def search_name(self, q): table = self.get_table('identity_meta') uuid_table = self.get_table('uuids') + identity_list = table.query.filter(table.fullname.like(q)).order_by(table.fullname.desc()).limit(10) + return identity_list - identity = table.query.filter(table.fullname.like(q)).order_by(table.fullname.desc()).limit(30) + def get_uuids_for_identities(self, identity_list): identities = [] - for row in identity: + for row in identity_list: uuid = uuid_table.query.filter(uuid_table.id == row.image_id).first() identities.append({ 'uuid': uuid.toJSON(), -- cgit v1.2.3-70-g09d2 From 4a9ce42814708a85919663c92be3938530d3742e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 00:58:13 +0100 Subject: rewriting sql scripts to correspond to data format --- megapixels/app/models/sql_factory.py | 120 ++++++++++++++++++----------------- megapixels/app/server/api.py | 8 +-- 2 files changed, 66 insertions(+), 62 deletions(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index 82e59b22..05984500 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -88,9 +88,9 @@ class SqlDataset: } def get_identity(self, id): - table = self.get_table('identity_meta') + table = self.get_table('identity') # id += 1 - identity = table.query.filter(table.image_id <= id).order_by(table.image_id.desc()).first().toJSON() + identity = table.query.filter(table.record_id <= id).order_by(table.record_id.desc()).first().toJSON() return { 'uuid': self.select('uuids', id), 'identity': identity, @@ -99,17 +99,17 @@ class SqlDataset: } def search_name(self, q): - table = self.get_table('identity_meta') - uuid_table = self.get_table('uuids') + table = self.get_table('identity') identity_list = table.query.filter(table.fullname.like(q)).order_by(table.fullname.desc()).limit(10) return identity_list - def get_uuids_for_identities(self, identity_list): + def get_file_records_for_identities(self, identity_list): identities = [] + file_record_table = self.get_table('file_record') for row in identity_list: - uuid = uuid_table.query.filter(uuid_table.id == row.image_id).first() + file_record = file_record_table.query.filter(file_record_table.id == row.record_id).first() identities.append({ - 'uuid': uuid.toJSON(), + 'file_record': file_record.toJSON(), 'identity': row.toJSON(), }) return identities @@ -120,7 +120,7 @@ class SqlDataset: return None session = Session() # for obj in session.query(table).filter_by(id=id): - # print(table) + # print(table) obj = session.query(table).filter(table.id == id).first() session.close() return obj.toJSON() @@ -128,43 +128,70 @@ class SqlDataset: def get_table(self, type): if type in self.tables: return self.tables[type] - elif type == 'uuids': - self.tables[type] = self.uuid_table() - elif type == 'roi': - self.tables[type] = self.roi_table() - elif type == 'identity_meta': + elif type == 'file_record': + self.tables[type] = self.file_record_table() + elif type == 'identity': self.tables[type] = self.identity_table() - elif type == 'pose': - self.tables[type] = self.pose_table() + elif type == 'face_roi': + self.tables[type] = self.face_roi_table() + elif type == 'face_pose': + self.tables[type] = self.face_pose_table() else: return None return self.tables[type] - # ==> uuids.csv <== - # index,uuid - # 0,f03fd921-2d56-4e83-8115-f658d6a72287 - def uuid_table(self): - class UUID(self.base_model): - __tablename__ = self.name + "_uuid" + # ==> file_record.csv <== + # index,ext,fn,identity_key,sha256,subdir,uuid,identity_index + def file_record_table(self): + class FileRecord(self.base_model): + __tablename__ = self.name + "_file_record" id = Column(Integer, primary_key=True) + ext = Column(String(3, convert_unicode=True), nullable=False) + fn = Column(String(36, convert_unicode=True), nullable=False) + identity_key = Column(String(36, convert_unicode=True), nullable=False) + sha256 = Column(String(36, convert_unicode=True), nullable=False) + subdir = Column(String(36, convert_unicode=True), nullable=False) uuid = Column(String(36, convert_unicode=True), nullable=False) + identity_index = Column(Integer) def toJSON(self): return { 'id': self.id, 'uuid': self.uuid, + 'identity_index': self.identity_index, } - return UUID + return FileRecord - # ==> roi.csv <== + # ==> identity.csv <== + # index,description,gender,images,fullname + # 0,A. J. Cook,Canadian actress,f,1,0 + def identity_table(self): + class Identity(self.base_model): + __tablename__ = self.name + "_identity" + id = Column(Integer, primary_key=True) + description = Column(String(36, convert_unicode=True), nullable=False) + gender = Column(String(1, convert_unicode=True), nullable=False) + images = Column(Integer, nullable=False) + fullname = Column(String(36, convert_unicode=True), nullable=False) + def toJSON(self): + return { + 'id': self.id, + 'fullname': self.fullname, + 'images': self.images, + 'gender': self.gender, + 'description': self.description, + } + return Identity + + # ==> face_roi.csv <== # index,h,image_height,image_index,image_width,w,x,y # 0,0.33000000000000007,250,0,250,0.32999999999999996,0.33666666666666667,0.35 - def roi_table(self): - class ROI(self.base_model): + def face_roi_table(self): + class FaceROI(self.base_model): __tablename__ = self.name + "_roi" id = Column(Integer, primary_key=True) h = Column(Float, nullable=False) image_height = Column(Integer, nullable=False) - image_index = Column(Integer, nullable=False) + record_index = Column(Integer, nullable=False) image_width = Column(Integer, nullable=False) w = Column(Float, nullable=False) x = Column(Float, nullable=False) @@ -172,7 +199,7 @@ class SqlDataset: def toJSON(self): return { 'id': self.id, - 'image_index': self.image_index, + 'record_index': self.record_index, 'image_height': self.image_height, 'image_width': self.image_width, 'w': self.w, @@ -180,48 +207,25 @@ class SqlDataset: 'x': self.x, 'y': self.y, } - return ROI - - # ==> identity.csv <== - # index,fullname,description,gender,images,image_index - # 0,A. J. Cook,Canadian actress,f,1,0 - def identity_table(self): - class Identity(self.base_model): - __tablename__ = self.name + "_identity" - id = Column(Integer, primary_key=True) - fullname = Column(String(36, convert_unicode=True), nullable=False) - description = Column(String(36, convert_unicode=True), nullable=False) - gender = Column(String(1, convert_unicode=True), nullable=False) - images = Column(Integer, nullable=False) - image_id = Column(Integer, nullable=False) - def toJSON(self): - return { - 'id': self.id, - 'image_id': self.image_id, - 'fullname': self.fullname, - 'images': self.images, - 'gender': self.gender, - 'description': self.description, - } - return Identity + return FaceROI - # ==> pose.csv <== - # index,image_index,pitch,roll,yaw + # ==> face_pose.csv <== + # index,record_index,pitch,roll,yaw # 0,0,11.16264458441435,10.415885631337728,22.99719032415318 - def pose_table(self): - class Pose(self.base_model): + def face_pose_table(self): + class FacePose(self.base_model): __tablename__ = self.name + "_pose" id = Column(Integer, primary_key=True) - image_id = Column(Integer, primary_key=True) + record_id = Column(Integer, nullable=False) pitch = Column(Float, nullable=False) roll = Column(Float, nullable=False) yaw = Column(Float, nullable=False) def toJSON(self): return { 'id': self.id, - 'image_id': self.image_id, + 'record_id': self.record_id, 'pitch': self.pitch, 'roll': self.roll, 'yaw': self.yaw, } - return Pose + return FacePose diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index cc791bb2..0af217e3 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -150,21 +150,21 @@ def name_lookup(dataset_name): } if len(terms) == 1: names = dataset.search_name('%' + term + '%') if term else [] - results = dataset.get_uuids_for_identities(names) + results = dataset.get_file_records_for_identities(names) else: lookup = {} results_lookup = {} for i, term in enumerate(terms): search_term = '%' + term + '%' - names = dataset.search_name() if term else [] + names = dataset.search_name(term) if term else [] for name in names: if name.id in lookup: lookup[name.id] += 1 else: lookup[name.id] = 1 results_lookup[name.id] = name - top_names = [results_lookup[item[0]] for item in sorted(lookup.items(), key=operator.itemgetter(1))][0:30] - results = dataset.get_uuids_for_identities(top_names) + top_names = [results_lookup[item[0]] for item in sorted(lookup.items(), key=operator.itemgetter(1))][0:20] + results = dataset.get_file_records_for_identities(top_names) # print(results) return jsonify({ -- cgit v1.2.3-70-g09d2 From 0fa4c5b7d1e16859f282bdda73bb6af4f4f78b6e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 01:33:16 +0100 Subject: commenting --- megapixels/app/models/sql_factory.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index 05984500..a89d89bf 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -62,7 +62,7 @@ def load_sql_dataset(path, replace=False, engine=None, base_model=None): df = pd.read_csv(fn) # fix columns that are named "index", a sql reserved word df.reindex_axis(sorted(df.columns), axis=1) - df.columns = sorted(table.__table__.columns).keys() + # df.columns = sorted(table.__table__.columns).keys() df.to_sql(name=table.__tablename__, con=engine, if_exists='replace', index=False) return dataset @@ -82,12 +82,18 @@ class SqlDataset: self.base_model = base_model def describe(self): + """ + List the available SQL tables for a given dataset. + """ return { 'name': self.name, 'tables': list(self.tables.keys()), } def get_identity(self, id): + """ + Get an identity given an ID. + """ table = self.get_table('identity') # id += 1 identity = table.query.filter(table.record_id <= id).order_by(table.record_id.desc()).first().toJSON() @@ -99,11 +105,17 @@ class SqlDataset: } def search_name(self, q): + """ + Find an identity by name. + """ table = self.get_table('identity') identity_list = table.query.filter(table.fullname.like(q)).order_by(table.fullname.desc()).limit(10) return identity_list def get_file_records_for_identities(self, identity_list): + """ + Given a list of identities, map these to file records. + """ identities = [] file_record_table = self.get_table('file_record') for row in identity_list: @@ -115,6 +127,9 @@ class SqlDataset: return identities def select(self, table, id): + """ + Perform a generic select. + """ table = self.get_table(table) if not table: return None @@ -126,6 +141,9 @@ class SqlDataset: return obj.toJSON() def get_table(self, type): + """ + Get one of these memoized, dynamically generated tables. + """ if type in self.tables: return self.tables[type] elif type == 'file_record': -- cgit v1.2.3-70-g09d2 From 59f692719bb6b4163594243e4c11262dc88466b4 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 17:38:56 +0100 Subject: fixing imports --- .eslintrc.js | 3 ++- client/nameSearch/nameSearch.query.js | 4 ++-- megapixels/app/models/sql_factory.py | 4 +++- megapixels/app/server/api.py | 10 ++++++---- 4 files changed, 13 insertions(+), 8 deletions(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/.eslintrc.js b/.eslintrc.js index 364bcad6..1d5aed90 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,7 +16,7 @@ module.exports = { } }, "rules": { - "react/prop-types": 1, + "react/prop-types": 0, "react/jsx-uses-vars": 2, "no-underscore-dangle": 0, "comma-dangle": ["error", "only-multiline"], @@ -37,6 +37,7 @@ module.exports = { "object-curly-newline": 0, "class-methods-use-this": 0, "quotes": "off", + "no-console": "off", }, "env": { "browser": true, diff --git a/client/nameSearch/nameSearch.query.js b/client/nameSearch/nameSearch.query.js index 629b7b1d..99c1da84 100644 --- a/client/nameSearch/nameSearch.query.js +++ b/client/nameSearch/nameSearch.query.js @@ -11,8 +11,8 @@ class NameSearchQuery extends Component { handleInput(value) { this.setState({ q: value }) - if (value.strip().length > 1) { - this.props.actions.search(this.props.payload, value.strip()) + if (value.trim().length > 1) { + this.props.actions.search(this.props.payload, value.trim()) } } diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index a89d89bf..5cdaa889 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -62,7 +62,9 @@ def load_sql_dataset(path, replace=False, engine=None, base_model=None): df = pd.read_csv(fn) # fix columns that are named "index", a sql reserved word df.reindex_axis(sorted(df.columns), axis=1) - # df.columns = sorted(table.__table__.columns).keys() + columns = [column.name for column in table.__table__.columns] + # print(columns) + df.columns = sorted(columns) df.to_sql(name=table.__tablename__, con=engine, if_exists='replace', index=False) return dataset diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index 0af217e3..5219a8da 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -148,13 +148,15 @@ def name_lookup(dataset_name): 'q': q, 'timing': time.time() - start, } - if len(terms) == 1: - names = dataset.search_name('%' + term + '%') if term else [] + if len(terms) == 0: + results = [] + elif len(terms) == 1: + names = dataset.search_name('%' + terms[0] + '%') if terms[0] else [] results = dataset.get_file_records_for_identities(names) else: lookup = {} results_lookup = {} - for i, term in enumerate(terms): + for i, term in enumerate(terms[0:5]): search_term = '%' + term + '%' names = dataset.search_name(term) if term else [] for name in names: @@ -163,7 +165,7 @@ def name_lookup(dataset_name): else: lookup[name.id] = 1 results_lookup[name.id] = name - top_names = [results_lookup[item[0]] for item in sorted(lookup.items(), key=operator.itemgetter(1))][0:20] + top_names = [results_lookup[item[0]] for item in sorted(lookup.items(), key=operator.itemgetter(1))][0:10] results = dataset.get_file_records_for_identities(top_names) # print(results) -- cgit v1.2.3-70-g09d2 From c3eec5ef62c6aacf4ca8c8056e1f9150dcd31506 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 17:58:51 +0100 Subject: returning results again --- client/nameSearch/nameSearch.result.js | 2 +- megapixels/app/models/sql_factory.py | 15 ++++++++------- megapixels/app/server/api.py | 6 ++++-- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/client/nameSearch/nameSearch.result.js b/client/nameSearch/nameSearch.result.js index 9e20228c..38c544cc 100644 --- a/client/nameSearch/nameSearch.result.js +++ b/client/nameSearch/nameSearch.result.js @@ -50,7 +50,7 @@ class NameSearchResult extends Component { ) } const els = results.map((result, i) => { - const { uuid } = result.uuid + const { uuid } = result.file_record const { fullname, gender, description, images } = result.identity return (
diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index 5cdaa889..eb91fb37 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -62,9 +62,10 @@ def load_sql_dataset(path, replace=False, engine=None, base_model=None): df = pd.read_csv(fn) # fix columns that are named "index", a sql reserved word df.reindex_axis(sorted(df.columns), axis=1) + print(df.columns) columns = [column.name for column in table.__table__.columns] - # print(columns) - df.columns = sorted(columns) + print(columns) + df.columns = columns df.to_sql(name=table.__tablename__, con=engine, if_exists='replace', index=False) return dataset @@ -121,7 +122,7 @@ class SqlDataset: identities = [] file_record_table = self.get_table('file_record') for row in identity_list: - file_record = file_record_table.query.filter(file_record_table.id == row.record_id).first() + file_record = file_record_table.query.filter(file_record_table.identity_id == row.id).first() identities.append({ 'file_record': file_record.toJSON(), 'identity': row.toJSON(), @@ -172,12 +173,12 @@ class SqlDataset: sha256 = Column(String(36, convert_unicode=True), nullable=False) subdir = Column(String(36, convert_unicode=True), nullable=False) uuid = Column(String(36, convert_unicode=True), nullable=False) - identity_index = Column(Integer) + identity_id = Column(Integer) def toJSON(self): return { 'id': self.id, 'uuid': self.uuid, - 'identity_index': self.identity_index, + 'identity_id': self.identity_id, } return FileRecord @@ -211,7 +212,7 @@ class SqlDataset: id = Column(Integer, primary_key=True) h = Column(Float, nullable=False) image_height = Column(Integer, nullable=False) - record_index = Column(Integer, nullable=False) + record_id = Column(Integer, nullable=False) image_width = Column(Integer, nullable=False) w = Column(Float, nullable=False) x = Column(Float, nullable=False) @@ -219,7 +220,7 @@ class SqlDataset: def toJSON(self): return { 'id': self.id, - 'record_index': self.record_index, + 'record_id': self.record_id, 'image_height': self.image_height, 'image_width': self.image_width, 'w': self.w, diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index 5219a8da..5f33e84b 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -111,7 +111,8 @@ def upload(dataset_name): dists.append(round(float(_d), 2)) ids.append(_i+1) - results = [ dataset.get_identity(int(_i)) for _i in ids ] + file_records = [ dataset.get_file_record(int(_i)) for _i in ids ] + identities = [ dataset.get_identity(rec.identity_id) for rec in file_records ] # print(distances) # print(ids) @@ -128,7 +129,7 @@ def upload(dataset_name): # print(results) return jsonify({ 'query': query, - 'results': results, + 'results': identities, 'distances': dists, }) @@ -148,6 +149,7 @@ def name_lookup(dataset_name): 'q': q, 'timing': time.time() - start, } + if len(terms) == 0: results = [] elif len(terms) == 1: -- cgit v1.2.3-70-g09d2 From 5fd0aab76caef8aaf7be77843b9c9260f22dfbb7 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 18:37:43 +0100 Subject: add prefix to name search --- megapixels/app/models/sql_factory.py | 21 +++++++---- megapixels/app/server/api.py | 70 ++++++++++++++++++++++++------------ megapixels/app/server/create.py | 15 ++++++++ old/server/run.py | 2 +- 4 files changed, 78 insertions(+), 30 deletions(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index eb91fb37..25c7e784 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -3,7 +3,7 @@ import glob import time import pandas as pd -from sqlalchemy import create_engine, Table, Column, String, Integer, DateTime, Float +from sqlalchemy import create_engine, Table, Column, String, Integer, DateTime, Float, func from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base @@ -112,7 +112,15 @@ class SqlDataset: Find an identity by name. """ table = self.get_table('identity') - identity_list = table.query.filter(table.fullname.like(q)).order_by(table.fullname.desc()).limit(10) + identity_list = table.query.filter(table.fullname.ilike(q)).order_by(table.fullname.desc()).limit(15) + return identity_list + + def search_description(self, q): + """ + Find an identity by description. + """ + table = self.get_table('identity') + identity_list = table.query.filter(table.description.ilike(q)).order_by(table.description.desc()).limit(15) return identity_list def get_file_records_for_identities(self, identity_list): @@ -123,10 +131,11 @@ class SqlDataset: file_record_table = self.get_table('file_record') for row in identity_list: file_record = file_record_table.query.filter(file_record_table.identity_id == row.id).first() - identities.append({ - 'file_record': file_record.toJSON(), - 'identity': row.toJSON(), - }) + if file_record: + identities.append({ + 'file_record': file_record.toJSON(), + 'identity': row.toJSON(), + }) return identities def select(self, table, id): diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index 5f33e84b..743e06f4 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -1,3 +1,5 @@ +import logging +import logging.handlers import os import re import time @@ -141,36 +143,58 @@ def name_lookup(dataset_name): dataset = get_dataset(dataset_name) q = request.args.get('q') - q = re.sub('[^a-zA-Z ]+', '*', q) + q = re.sub('[^a-zA-Z. ]+', '*', q) terms = q.split(' ') - # print(q) query = { 'q': q, 'timing': time.time() - start, } - - if len(terms) == 0: - results = [] - elif len(terms) == 1: - names = dataset.search_name('%' + terms[0] + '%') if terms[0] else [] - results = dataset.get_file_records_for_identities(names) - else: - lookup = {} - results_lookup = {} - for i, term in enumerate(terms[0:5]): - search_term = '%' + term + '%' - names = dataset.search_name(term) if term else [] - for name in names: - if name.id in lookup: - lookup[name.id] += 1 - else: - lookup[name.id] = 1 - results_lookup[name.id] = name - top_names = [results_lookup[item[0]] for item in sorted(lookup.items(), key=operator.itemgetter(1))][0:10] - results = dataset.get_file_records_for_identities(top_names) - # print(results) + print(terms) + + if len(terms) == 0: + return jsonify({ 'query': query, 'results': [] }) + + lookup = {} + results_lookup = {} + + names = dataset.search_name(q + '%') + for name in names: + if name.id in lookup: + print(name.fullname) + lookup[name.id] += 4 + else: + print(name.fullname) + lookup[name.id] = 4 + results_lookup[name.id] = name + + for i, term in enumerate(terms[0:5]): + search_term = '%' + term + '%' + names = dataset.search_name(search_term) if len(term) > 0 else [] + descriptions = dataset.search_description(search_term) if len(term) > 0 else [] + for name in names: + if name.id in lookup: + print(name.fullname) + lookup[name.id] += 2 + else: + print(name.fullname) + lookup[name.id] = 2 + results_lookup[name.id] = name + for name in descriptions: + if name.id in lookup: + print(name.fullname) + lookup[name.id] += 1 + else: + print(name.fullname) + lookup[name.id] = 1 + results_lookup[name.id] = name + + sorted_names = sorted(lookup.items(), key=operator.itemgetter(1), reverse=True)[0:10] + top_names = [results_lookup[item[0]] for item in sorted_names] + results = dataset.get_file_records_for_identities(top_names) + + print(results) return jsonify({ 'query': query, 'results': results, diff --git a/megapixels/app/server/create.py b/megapixels/app/server/create.py index f46bb2a0..a1ce56df 100644 --- a/megapixels/app/server/create.py +++ b/megapixels/app/server/create.py @@ -1,3 +1,18 @@ +import logging +import logging.handlers + +logger = logging.getLogger("") +logger.setLevel(logging.DEBUG) +handler = logging.handlers.RotatingFileHandler("flask.log", + maxBytes=3000000, backupCount=2) +formatter = logging.Formatter( + '[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s') +handler.setFormatter(formatter) +logger.addHandler(handler) +logging.getLogger().addHandler(logging.StreamHandler()) + +logging.debug("starting app") + from flask import Flask, Blueprint, jsonify, send_from_directory from flask_sqlalchemy import SQLAlchemy from app.models.sql_factory import connection_url, load_sql_datasets diff --git a/old/server/run.py b/old/server/run.py index c4c3e8d7..ff2d5009 100644 --- a/old/server/run.py +++ b/old/server/run.py @@ -8,5 +8,5 @@ import logging logging.basicConfig(filename='error.log',level=logging.DEBUG) if __name__ == '__main__': - app.run(host='0.0.0.0',debug=False,threaded=False,port=8000) + app.run(host='0.0.0.0', debug=True, threaded=False, port=8000) pass -- cgit v1.2.3-70-g09d2 From 521bc1e5251105f895dd88a38ddc889cbd0e4431 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 18:55:17 +0100 Subject: updating face search API --- megapixels/app/models/sql_factory.py | 26 ++++++++++++++++---------- megapixels/app/server/api.py | 7 ++----- 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index 25c7e784..a71eabb0 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -62,9 +62,7 @@ def load_sql_dataset(path, replace=False, engine=None, base_model=None): df = pd.read_csv(fn) # fix columns that are named "index", a sql reserved word df.reindex_axis(sorted(df.columns), axis=1) - print(df.columns) columns = [column.name for column in table.__table__.columns] - print(columns) df.columns = columns df.to_sql(name=table.__tablename__, con=engine, if_exists='replace', index=False) return dataset @@ -97,15 +95,23 @@ class SqlDataset: """ Get an identity given an ID. """ - table = self.get_table('identity') # id += 1 - identity = table.query.filter(table.record_id <= id).order_by(table.record_id.desc()).first().toJSON() - return { - 'uuid': self.select('uuids', id), - 'identity': identity, - 'roi': self.select('roi', id), - 'pose': self.select('pose', id), - } + print('fetching {}'.format(id)) + + file_record_table = self.get_table('file_record') + file_record = file_record_table.query.filter(file_record_table.id == id).first() + + identity_table = self.get_table('identity') + identity = identity_table.query.filter(identity_table.id == file_record.identity_id).first() + + if file_record and identity: + return { + 'file_record': file_record.toJSON(), + 'identity': identity.toJSON(), + 'face_roi': self.select('face_roi', id), + 'face_pose': self.select('face_pose', id), + } + return {} def search_name(self, q): """ diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index 743e06f4..af3db4d0 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -113,8 +113,7 @@ def upload(dataset_name): dists.append(round(float(_d), 2)) ids.append(_i+1) - file_records = [ dataset.get_file_record(int(_i)) for _i in ids ] - identities = [ dataset.get_identity(rec.identity_id) for rec in file_records ] + identities = [ dataset.get_identity(int(_i)) for _i in ids ] # print(distances) # print(ids) @@ -151,8 +150,6 @@ def name_lookup(dataset_name): 'timing': time.time() - start, } - print(terms) - if len(terms) == 0: return jsonify({ 'query': query, 'results': [] }) @@ -193,7 +190,7 @@ def name_lookup(dataset_name): sorted_names = sorted(lookup.items(), key=operator.itemgetter(1), reverse=True)[0:10] top_names = [results_lookup[item[0]] for item in sorted_names] results = dataset.get_file_records_for_identities(top_names) - + print(results) return jsonify({ 'query': query, -- cgit v1.2.3-70-g09d2 From 384be7d882d1402220b10bd5b2d0037226b41785 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 12 Jan 2019 19:02:19 +0100 Subject: returning face results again --- client/faceSearch/faceSearch.result.js | 4 ++-- megapixels/app/models/sql_factory.py | 22 ++++++++++++---------- megapixels/app/processors/faiss.py | 3 +++ megapixels/app/server/api.py | 1 + site/assets/css/applets.css | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) (limited to 'megapixels/app/models/sql_factory.py') diff --git a/client/faceSearch/faceSearch.result.js b/client/faceSearch/faceSearch.result.js index 95534830..c2509033 100644 --- a/client/faceSearch/faceSearch.result.js +++ b/client/faceSearch/faceSearch.result.js @@ -72,8 +72,8 @@ class FaceSearchResult extends Component { } const els = results.map((result, i) => { const distance = distances[i] - const { uuid } = result.uuid - const { x, y, w, h } = result.roi + const { uuid } = result.file_record + const { x, y, w, h } = result.face_roi const { fullname, gender, description, images } = result.identity const bbox = { left: (100 * x) + '%', diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index a71eabb0..5b3cb5a3 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -96,22 +96,24 @@ class SqlDataset: Get an identity given an ID. """ # id += 1 - print('fetching {}'.format(id)) - file_record_table = self.get_table('file_record') file_record = file_record_table.query.filter(file_record_table.id == id).first() + if not file_record: + return None + identity_table = self.get_table('identity') identity = identity_table.query.filter(identity_table.id == file_record.identity_id).first() - if file_record and identity: - return { - 'file_record': file_record.toJSON(), - 'identity': identity.toJSON(), - 'face_roi': self.select('face_roi', id), - 'face_pose': self.select('face_pose', id), - } - return {} + if not identity: + return None + + return { + 'file_record': file_record.toJSON(), + 'identity': identity.toJSON(), + 'face_roi': self.select('face_roi', id), + 'face_pose': self.select('face_pose', id), + } def search_name(self, q): """ diff --git a/megapixels/app/processors/faiss.py b/megapixels/app/processors/faiss.py index 5156ad71..ab067fd0 100644 --- a/megapixels/app/processors/faiss.py +++ b/megapixels/app/processors/faiss.py @@ -30,6 +30,9 @@ def build_faiss_database(name, recipe): vec_fn = os.path.join(cfg.DIR_FAISS_METADATA, name, "vecs.csv") index_fn = os.path.join(cfg.DIR_FAISS_INDEXES, name + ".index") + if not os.path.exists(vec_fn): + return + index = faiss.index_factory(recipe.dim, recipe.factory_type) keys, rows = load_csv_safe(vec_fn) diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index af3db4d0..5f80a0c4 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -114,6 +114,7 @@ def upload(dataset_name): ids.append(_i+1) identities = [ dataset.get_identity(int(_i)) for _i in ids ] + identities = list(filter(None, identities)) # print(distances) # print(ids) diff --git a/site/assets/css/applets.css b/site/assets/css/applets.css index b2b3c85e..b64da4b7 100644 --- a/site/assets/css/applets.css +++ b/site/assets/css/applets.css @@ -60,7 +60,7 @@ .img .bbox { position: absolute; color: rgba(255,255,255,1); - background: rgba(255,255,255,255.05); + background: rgba(255,255,255,0.05); border: 1px solid; } .cta { -- cgit v1.2.3-70-g09d2