7baea94247dccd57bea0422776dca0061d7b42ac
[cascardo/ipsilon.git] / ipsilon / rest / common.py
1 # Copyright (C) 2015  Ipsilon Contributors see COPYING for license
2
3 import cherrypy
4 import json
5 from functools import wraps
6 from ipsilon.util.endpoint import Endpoint
7
8
9 def jsonout(func):
10     """
11     JSON output decorator. Does not handle binary data.
12     """
13     @wraps(func)
14     def wrapper(*args, **kw):
15         value = func(*args, **kw)
16         cherrypy.response.headers["Content-Type"] = \
17             "application/json;charset=utf-8"
18         return json.dumps(value, sort_keys=True, indent=2)
19
20     return wrapper
21
22
23 def rest_error(status=500, message=''):
24     """
25     Create a REST error response.
26
27     The assumption is that the jsonout wrapper will handle converting
28     the response to JSON.
29     """
30     cherrypy.response.status = status
31     cherrypy.response.headers['Content-Type'] = 'application/json'
32     return {'status': status, 'message': message}
33
34
35 class RestPage(Endpoint):
36
37     def __init__(self, *args, **kwargs):
38         super(RestPage, self).__init__(*args, **kwargs)
39         self.auth_protect = True
40
41
42 class RestPlugins(RestPage):
43     def __init__(self, name, site, parent, facility, ordered=True):
44         super(RestPlugins, self).__init__(site)
45         self._master = parent
46         self.name = name
47         self.title = '%s plugins' % name
48         self.url = '%s/%s' % (parent.url, name)
49         self.facility = facility
50         self.template = None
51         self.order = None
52         parent.add_subtree(name, self)
53
54         for plugin in self._site[facility].available:
55             obj = self._site[facility].available[plugin]
56             if hasattr(obj, 'rest'):
57                 cherrypy.log.error('Rest plugin: %s' % plugin)
58                 obj.rest.mount(self)
59
60     def root_with_msg(self, message=None, message_type=None, changed=None):
61         return None
62
63     def root(self, *args, **kwargs):
64         return self.root_with_msg()
65
66
67 class Rest(RestPage):
68
69     def __init__(self, site, mount):
70         super(Rest, self).__init__(site)
71         self.title = None
72         self.mount = mount
73         self.url = '%s/%s' % (self.basepath, mount)
74         self.menu = [self]
75
76     @jsonout
77     def root(self, *args, **kwargs):
78         return rest_error(404, 'Not Found')
79
80     def add_subtree(self, name, page):
81         self.__dict__[name] = page
82
83     def del_subtree(self, name):
84         del self.__dict__[name]