-
Florent Aide authoredFlorent Aide authored
views.py 5.62 KiB
from pyramid.view import view_config
import uuid
import json
from webob import Response, exc
from cornice import Service
import logging
from pytsprf.distance_getter_factory import DistanceGetterFactory
from pytsprf.route_solver_factory import RouteSolverFactory
from pytsprf.models import get_db_user_token, get_db_user
from pytsprf.models import create_db_user, delete_db_user, get_db_users
# ==================================================
# Service : Users authentication and autorization
# ==================================================
users = Service(name='users', path='/users', description="Users management")
_USERS = {}
def _create_token():
return uuid.uuid4().hex
class _401(exc.HTTPError):
def __init__(self, msg='Unauthorized'):
body = {'status': 401, 'message': msg}
Response.__init__(self, json.dumps(body))
self.status = 401
self.content_type = 'application/json'
def valid_token(request):
header = 'X-Messaging-Token'
htoken = request.headers.get(header)
if htoken is None:
raise _401()
try:
user, token = htoken.split('-', 1)
except ValueError:
raise _401()
dbtoken = get_db_user_token(user)
valid = (dbtoken is not None) and (dbtoken == token)
if not valid:
raise _401()
request.validated['user'] = user
def is_valid_username(request):
body_unicode = request.body.decode('utf-8')
username = json.loads(body_unicode)
request.validated['username'] = username
def is_new_user(request):
is_valid_username(request)
username = request.validated['username']
is_new_user = False
if (username is not None):
isfound, user = get_db_user(username)
is_new_user = not(isfound)
if isfound:
request.errors.add(
'/users',
'POST', 'Le Client possede deja une cle d''API active'
)
request.validated['is_new_user'] = is_new_user
def is_authorized(request):
request.validated['is_authorized'] = True
# Services - User Management
@users.get(validators=is_authorized)
def get_users(request):
"""Returns a list of all users."""
is_authorized = request.validated['is_authorized']
if (is_authorized):
success, users = get_db_users()
if success:
names = list()
for user in users:
names.append(user.name)
return {'authorized': is_authorized, 'users': names}
@users.post(validators=is_new_user)
def create_user(request):
"""Adds a new user."""
username = request.validated['username']
success = False
is_new_user = request.validated['is_new_user']
if is_new_user:
success, user = create_db_user(username)
if success:
user = {'name': username, 'token': get_db_user_token(username)}
request.validated['created'] = True
else:
request.errors.add(
'/users',
username,
'Request aborted due to a Database Access error'
)
if success:
response = {
'created': success,
'token': '%s-%s' % (
user.get('name'),
user.get('token')
)
}
else:
response = {'created': success}
return response
@users.delete(validators=valid_token)
def delete_user(request):
"""Removes the user."""
username = request.validated['user']
success = delete_db_user(username)
return {'deleted': success}
# ==================================================
# Service : Home
# ==================================================
@view_config(route_name='access', renderer='templates/service.pt')
def access_page(request):
return {'project': 'access'}
@view_config(route_name='credentials', renderer='templates/index.pt')
def home_page(request):
return {'project': 'pytsprf'}
# ==================================================
# Service : Route
# ==================================================
tsp = Service(
name='tsp',
path='/tsp',
description="Route in response to the requested TSP"
)
def activate_logging():
logname = "log.txt"
logging.basicConfig(
filename=logname,
filemode='a',
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
level=logging.DEBUG
)
def get_response(points, route, cost, distance_getter_name, solver_name):
return {
'waypoints': points,
'route': route,
'api-description': u'XCG Consulting API : TSP solution',
'distance-solver': distance_getter_name,
'route-solver': solver_name,
'origin': points[0],
'destination': points[0],
'cost': cost
}
def convert_to_points(pointsDict):
points = []
for pointDict in pointsDict:
points.append([pointDict.get('lat'), pointDict.get('lng')])
print(points)
return points
def get_route(points, is_test_mode=False):
dgetterFactory = DistanceGetterFactory(is_test_mode)
distance_getter = dgetterFactory.get_instance()
solverFactory = RouteSolverFactory(points, distance_getter)
solver = solverFactory.get_instance()
route = solver.get_route()
cost = solver.get_cost(route)
return route, cost, distance_getter.name, solver.name
@tsp.post(validators=valid_token)
def calc_route(request):
requestDataDict = request.json
points = convert_to_points(requestDataDict)
route, cost, distance_getter_name, solver_name = get_route(
points, is_test_mode=False
)
response = get_response(
requestDataDict, route, cost, distance_getter_name, solver_name
)
return json.dumps(response)