old_contents: # coding=utf-8
  """
  """
  from __future__ import absolute_import
  
  import hashlib
  
  from flask import Blueprint, make_response, request, g, Response
  from werkzeug.exceptions import NotFound
  
  from abilian.core.models.subjects import User
  
  
  bp = Blueprint('users', __name__, url_prefix='/users')
  
  
  @bp.url_value_preprocessor
  def get_user(endpoint, values):
    try:
      user_id = values.pop('user_id')
      user = User.query.get(user_id)
      if user:
        values['user'] = user
      else:
        raise NotFound()
    except KeyError:
      # this endpoint is not looking for a specific user
      pass
  
  
  @bp.route('/<int:user_id>/photo')
  def photo(user):
    if not user.photo:
      raise NotFound()
  
    data = user.photo
    self_photo = (user.id == g.user.id)
  
    if self_photo:
      # special case: for its own photo user has an etag, so that on change photo
      # is immediatly reloaded from server.
      #
      # FIXME: there should be a photo_digest field on user object
      acc = hashlib.md5(data)
      etag = acc.hexdigest()
  
      if request.if_none_match and etag in request.if_none_match:
        return Response(status=304)
  
    r = make_response(data)
    r.headers['content-type'] = 'image/jpeg'
  
    if not self_photo:
      r.headers.add('Cache-Control', 'public, max-age=600')
    else:
      # user always checks its own mugshot is up-to-date, in order to avoid seeing
      # old one immediatly after having uploaded of a new picture.
      r.headers.add('Cache-Control', 'private, must-revalidate')
      r.set_etag(etag)
  
    return r
  
new_contents: # coding=utf-8
  """
  """
  from __future__ import absolute_import
  
  import hashlib
  
  from sqlalchemy.sql.expression import or_, func
  from flask import Blueprint, make_response, request, g, Response
  from werkzeug.exceptions import NotFound
  
  from abilian.core.models.subjects import User
  from abilian.web import url_for
  from abilian.web.views import JSONModelSearch
  
  
  bp = Blueprint('users', __name__, url_prefix='/users')
  
  
  @bp.url_value_preprocessor
  def get_user(endpoint, values):
    try:
      user_id = values.pop('user_id')
      user = User.query.get(user_id)
      if user:
        values['user'] = user
      else:
        raise NotFound()
    except KeyError:
      # this endpoint is not looking for a specific user
      pass
  
  
  @bp.route('/<int:user_id>/photo')
  def photo(user):
    if not user.photo:
      raise NotFound()
  
    data = user.photo
    self_photo = (user.id == g.user.id)
  
    if self_photo:
      # special case: for its own photo user has an etag, so that on change photo
      # is immediatly reloaded from server.
      #
      # FIXME: there should be a photo_digest field on user object
      acc = hashlib.md5(data)
      etag = acc.hexdigest()
  
      if request.if_none_match and etag in request.if_none_match:
        return Response(status=304)
  
    r = make_response(data)
    r.headers['content-type'] = 'image/jpeg'
  
    if not self_photo:
      r.headers.add('Cache-Control', 'public, max-age=600')
    else:
      # user always checks its own mugshot is up-to-date, in order to avoid seeing
      # old one immediatly after having uploaded of a new picture.
      r.headers.add('Cache-Control', 'private, must-revalidate')
      r.set_etag(etag)
  
    return r
  
  
  # JSON search
  class UserJsonListing(JSONModelSearch):
    """
    """
    Model = User
    minimum_input_length = 0
  
    def filter(self, query, q, **kwargs):
      if q:
        query = query.filter(
          or_(func.lower(User.first_name).like(q + "%"),
              func.lower(User.last_name).like(q + "%"))
        )
      return query
  
    def order_by(self, query):
      return query.order_by(func.lower(User.last_name),
                            func.lower(User.first_name))
  
    def get_item(self, obj):
      d = super(UserJsonListing, self).get_item(obj)
      d['email'] = obj.email
      d['can_login'] = obj.can_login
      d['photo'] = url_for('users.photo', user_id=obj.id)
      return d
  
  bp.route('/json/')(UserJsonListing.as_view('json_list'))
  
subject: add coreview: user.json_list