Beispiel #1
0
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
Beispiel #4
0
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)
Beispiel #5
0
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))
Beispiel #6
0
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)
Beispiel #7
0
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)