Convert controllers to classes

master
Dustin 2015-02-15 15:54:10 -06:00
parent 4cb2ece33b
commit 0c5237c1a9
2 changed files with 125 additions and 55 deletions

View File

@ -3,91 +3,161 @@ import json
import milla import milla
class BaseController(milla.controllers.Controller):
def __init__(self):
# allowed_methods must be set on the instance rather than the
# class because of how Milla does attribute copying to the
# partial the router creates.
try:
self.allowed_methods = self.__class__.allowed_methods
except AttributeError:
pass
def __before__(self, request):
super(BaseController, self).__before__(request)
self.session = model.Session()
def __after__(self, request):
self.session.rollback()
self.session.bind.dispose()
del self.session
def index(request): def index(request):
raise milla.HTTPMovedPermanently(location=request.create_href('/zones/')) raise milla.HTTPMovedPermanently(location=request.create_href('/zones/'))
@milla.allow('GET', 'HEAD', 'POST') class ZoneListController(BaseController):
def all_zones(request):
allowed_methods = ('GET', 'HEAD', 'POST')
def __call__(self, request):
return getattr(self, request.method)(request)
def GET(self, request):
response = request.ResponseClass() response = request.ResponseClass()
response.content_type = 'application/json' response.content_type = 'application/json'
zones = map(model.Zone.as_dict, self.session.query(model.Zone))
session = model.Session()
if request.method == 'GET':
zones = map(model.Zone.as_dict, session.query(model.Zone))
json.dump(list(zones), response.body_file) json.dump(list(zones), response.body_file)
session.rollback() return response
elif request.method == 'POST':
HEAD = GET
def POST(self, request):
response = request.ResponseClass()
response.content_type = None
data = json.loads(request.text) data = json.loads(request.text)
zone = model.Zone(**data) zone = model.Zone(**data)
session.add(zone) self.session.add(zone)
session.commit() self.session.commit()
response.status_int = 201 response.status_int = 201
response.location = request.create_href_full(
'/zones/{}'.format(zone.name)
)
return response return response
@milla.allow('GET', 'HEAD', 'POST', 'PUT', 'DELETE') class ZoneController(BaseController):
def zone(request, name):
response = request.ResponseClass()
response.content_type = 'application/json'
session = model.Session() allowed_methods = ('GET', 'HEAD', 'POST', 'PUT', 'DELETE')
zone = session.query(model.Zone).get(name)
def __call__(self, request, name):
return getattr(self, request.method)(request, name)
def get_zone(self, name):
zone = self.session.query(model.Zone).get(name)
if not zone: if not zone:
raise milla.HTTPNotFound raise milla.HTTPNotFound
return zone
if request.method == 'GET': def GET(self, request, name):
response = request.ResponseClass()
response.content_type = 'application/json'
zone = self.get_zone(name)
zone_d = zone.as_dict() zone_d = zone.as_dict()
zone_d['records'] = list(map(model.Record.as_dict, zone.records)) zone_d['records'] = list(map(model.Record.as_dict, zone.records))
json.dump(zone_d, response.body_file) json.dump(zone_d, response.body_file)
session.rollback() return response
elif request.method == 'PUT':
HEAD = GET
def PUT(self, request, name):
response = request.ResponseClass()
response.content_type = 'application/json'
data = json.loads(request.text) data = json.loads(request.text)
for k, v in data.items(): for k, v in data.items():
assert k != 'records' assert k != 'records'
assert hasattr(zone, k) assert hasattr(zone, k)
setattr(zone, k, v) setattr(zone, k, v)
session.commit() self.session.commit()
elif request.method == 'POST': return response
def POST(self, request, name):
response = request.ResponseClass()
response.content_type = None
zone = self.get_zone(name)
data = json.loads(request.text) data = json.loads(request.text)
zone_name = data.pop('zone', zone.name) zone_name = data.pop('zone', zone.name)
assert zone_name == zone.name assert zone_name == zone.name
record = model.Record(zone=zone_name, **data) record = model.Record(zone=zone_name, **data)
session.add(record) self.session.add(record)
session.commit() self.session.commit()
response.status_int = 201 response.status_int = 201
response.location = request.create_href_full( response.location = request.create_href_full(
'/records/{}'.format(record.id) '/records/{}'.format(record.id)
) )
elif request.method == 'DELETE':
session.delete(zone)
session.commit()
else:
session.rollback()
return response return response
@milla.allow('GET', 'HEAD', 'PUT', 'DELETE') def DELETE(self, request, name):
def record(request, id):
response = request.ResponseClass() response = request.ResponseClass()
response.content_type = 'application/json' response.content_type = None
zone = self.get_zone(name)
self.session.delete(zone)
self.session.commit()
response.status_int = 204
return response
session = model.Session()
record = session.query(model.Record).get(id) class RecordController(BaseController):
allowed_methods = ('GET', 'HEAD', 'PUT', 'DELETE')
def __call__(self, request, id):
return getattr(self, request.method)(request, id)
def get_record(self, id):
record = self.session.query(model.Record).get(id)
if not record: if not record:
raise milla.HTTPNotFound raise milla.HTTPNotFound
return record
if request.method == 'GET': def GET(self, request, id):
response = request.ResponseClass()
response.content_type = 'application/json'
record = self.get_record(id)
json.dump(record.as_dict(), response.body_file) json.dump(record.as_dict(), response.body_file)
session.rollback() return response
elif request.method == 'DELETE':
session.delete(record) HEAD = GET
session.commit()
elif request.method == 'PUT': def PUT(self, request, id):
data =json.loads(request.text) response = request.ResponseClass()
response.content_type = 'application/json'
record = self.get_record(id)
data = json.loads(request.text)
for k, v in data.items(): for k, v in data.items():
assert k != 'zone'
assert hasattr(record, k) assert hasattr(record, k)
setattr(record, k, v) setattr(record, k, v)
session.commit() self.session.commit()
else: return response
session.rollback()
def DELETE(self, request, id):
response = request.ResponseClass()
response.content_type = None
record = self.get_record(id)
self.session.delete(record)
self.session.commit()
response.status_int = 204
return response return response

View File

@ -4,6 +4,6 @@ from milla.dispatch import routing
router = routing.Router() router = routing.Router()
router.add_route('/', controllers.index) router.add_route('/', controllers.index)
router.add_route('/zones/', controllers.all_zones) router.add_route('/zones/', controllers.ZoneListController())
router.add_route('/zones/{name}', controllers.zone) router.add_route('/zones/{name}', controllers.ZoneController())
router.add_route('/records/{id}', controllers.record) router.add_route('/records/{id}', controllers.RecordController())