def upload_plant_snaps(request): plant_name = request.POST['name'] uploaded = 0 for name, value in request.POST.items(): if name == 'name': continue if value == u'': continue logger.debug('Saving snap %r for plant %s', value, plant_name) file_uuid, ext = _save_pic(value, request) doc = { 'user': request.user.id, 'timestamp': datetime.datetime.utcnow(), 'filename': file_uuid + ext, 'plant': plant_name, } res = request.db.index(doc, 'snaps', 'snaptype', file_uuid) if not res['ok']: logger.error("Error while saving index") logger.error(res) raise HTTPServerError() uploaded += 1 request.db.refresh() request.session.flash("Uploaded %d snaps" % uploaded) return HTTPFound(location='/plant/%s' % plant_name)
def user(self): """ Get the logged in user """ email = authenticated_userid(self) if email is not None: query = FieldQuery(FieldParameter('email', email)) res = self.db.search(query) if len(res) == 0: doc = { 'id': str(uuid4()), 'email': email, 'registered': datetime.datetime.utcnow(), } res = self.db.index(doc, 'users', 'usertype', doc['id']) if res['ok'] == False: logger.error("Signup failure") logger.error(res) raise HTTPServerError() self.db.refresh() res = [namedtuple('User', doc.keys())(**doc)] if len(res) > 0: return res[0] return None
def suggest_snaps(query_snap, other_snaps, pic_dir, cache=None, criterion='euclidean_distance', max_suggestions=10): """Order snaps by similarity with the reference query""" if cache is None: cache = {} if not query_snap.warped: raise ValueError("Cannot make suggestion on unwarped snapshot") query_features = cache.get(query_snap.filename) if query_features is None: query_warped_file_path = os.path.join( pic_dir, query_snap.warped_filename) query_features = compute_features(query_warped_file_path) cache[query_snap.filename] = query_features # filter out the query snap from the candidates other_snaps = [s for s in other_snaps if s.filename != query_snap.filename] snaps, features = compute_features_collection( other_snaps, pic_dir, cache=cache) # wrap query as a 2D array to use the pairwise distance API query_features = query_features.reshape((1, -1)) try: if criterion == 'euclidean_distance': minimize = True scores = pairwise_distances(query_features, features).ravel() else: raise NotImplementedError('criterion: ' + criterion) except ValueError as e: dump_folder = 'invalid_features' if not os.path.exists(dump_folder): os.makedirs(dump_folder) now = time.time() query_filename = os.path.join( dump_folder, "%f_query_%s.txt" % (now, criterion)) others_filename = os.path.join( dump_folder, "%f_others_%s.txt" % (now, criterion)) np.savetxt(query_filename, query_features) np.savetxt(others_filename, features) logger.error("%r, invalid features saved to %s and %s", e, query_filename, others_filename, exc_info=True) return [], [] if minimize: ordering = np.argsort(scores) else: ordering = np.argsort(scores)[::-1] best_snaps = np.array(snaps)[ordering][:max_suggestions] best_scores = scores[ordering][:max_suggestions] return best_snaps, best_scores
def snapshot(request): """Index page.""" filename = request.matchdict['file'] settings = dict(request.registry.settings) pic_dir = settings['thumbs.document_root'] file_path = os.path.join(pic_dir, filename) try: height, width = get_img_size(file_path) except IOError: logger.error("Failed to open file with path: %s", file_path, exc_info=True) raise HTTPNotFound("Could not load image for snap %s" % filename) # security loop elmts = filename.split(os.sep) for unsecure in ('.', '..'): if unsecure in elmts: return HTTPNotFound() file_uuid = os.path.splitext(filename)[0] if request.method == 'POST': base = _toint(request.POST['bottom_y']), _toint(request.POST['bottom_x']) top = _toint(request.POST['top_y']), _toint(request.POST['top_x']) warped_img_path, new_base, new_top = warp_img(file_path, base, top) # There should be only one snap_idx, snap_type = 'snaps', 'snaptype' snap = request.db.get(snap_idx, snap_type, file_uuid) warped_filename = os.path.basename(warped_img_path) if snap is not None: snap['warped_filename'] = warped_filename snap['warped'] = True snap['base_x'] = base[0] snap['base_y'] = base[1] snap['top_x'] = top[0] snap['top_y'] = top[1] logger.debug("Warping snap %s", file_uuid) request.db.index(snap, snap_idx, snap_type, file_uuid) request.db.refresh() # Precompute the cached features incrementally compute_features_collection([snap], pic_dir, cache=FEATURES_CACHE) else: logger.warning("Could not find snap for %s", file_uuid) return HTTPFound(location='/warped/%s' % warped_filename) data = {'snapshot': filename, 'width': width, 'height': height} return _basic(request, data)
def pick(request): plant_name = request.POST['plant'] leaf_uuid = request.POST['leaf'][:-len('_warped')] snap_idx, snap_type = 'snaps', 'snaptype' doc = request.db.get(snap_idx, snap_type, leaf_uuid) doc['plant'] = plant_name res = request.db.index(doc, snap_idx, snap_type, leaf_uuid) if not res['ok']: logger.error("Error while saving index") logger.error(res) raise HTTPServerError() request.db.refresh() request.session.flash("Picked %s!" % plant_name) base, ext = os.path.splitext(doc.filename) return HTTPFound(location='/warped/%s_warped%s' % (base, ext))
def upload_plant(request): index, type_, root = 'plants', 'planttype', 'plant' if request.user is None: raise Forbidden() if request.method == 'POST': pic = request.POST.get('picture') name = request.POST.get('name', '') if not name: name = str(uuid4()) if pic not in (None, ''): name, ext = _save_pic(pic, request, name) filename = name + ext else: filename = None # TODO: check if plant exist first # Add to Elastic Search doc = { 'user': request.user.id, 'timestamp': datetime.datetime.utcnow(), 'filename': filename, 'gravatar': gravatar_image_url(request.user.email), 'geo_longitude': request.POST.get('longitude'), 'geo_latitude': request.POST.get('latitude'), 'geo_accuracy': request.POST.get('accuracy'), 'name': name, } logger.debug("Indexing plant %s: %r", name, doc) res = request.db.index(doc, index, type_, name) if not res['ok']: logger.error("Error while creating plant %s", name) logger.error(res) raise HTTPServerError() request.db.refresh() request.session.flash('Plant registered') return HTTPFound(location='/%s/%s' % (root, name)) return _basic(request)
def _upload(request, index, type_, root): if request.user is None: raise Forbidden() if request.method == 'POST': pic = request.POST.get('picture') file_uuid = request.POST.get('name', str(uuid4())) if pic is not None: file_uuid, ext = _save_pic(pic, request, file_uuid) else: ext = '.bin' # Add to Elastic Search doc = { 'user': request.user.id, 'timestamp': datetime.datetime.utcnow(), 'filename': file_uuid + ext, 'gravatar': gravatar_image_url(request.user.email), 'geo_longitude': request.POST.get('longitude'), 'geo_latitude': request.POST.get('latitude'), 'geo_accuracy': request.POST.get('accuracy'), 'name': request.POST.get('name') } res = request.db.index(doc, index, type_, file_uuid) if not res['ok']: logger.error("Error while saving index %r for %r", index, file_uuid) logger.error(res) raise HTTPServerError() request.db.refresh() request.session.flash('Image uploaded') return HTTPFound(location='/%s/%s' % (root, file_uuid + ext)) return _basic(request)