~didrocks/unity/altf10

« back to all changes in this revision

Viewing changes to grackle/service.py

  • Committer: Curtis Hovey
  • Date: 2012-03-17 21:02:32 UTC
  • Revision ID: curtis.hovey@canonical.com-20120317210232-0cw98mbpn9356que
No need to uppercase the reason.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
__metaclass__ = type
2
 
__all__ = [
3
 
    'ForkedFakeService',
4
 
    'GrackleService',
5
 
    ]
6
2
 
7
3
import httplib
8
4
import logging
10
6
from signal import SIGKILL
11
7
import simplejson
12
8
import sys
13
 
from wsgiref.headers import Headers
14
9
from wsgiref.simple_server import make_server
15
10
from wsgiref.util import shift_path_info
16
 
 
17
11
from grackle.store import (
18
12
    MemoryStore,
19
13
    )
20
14
 
21
15
 
22
16
class GrackleService:
23
 
    """A request handler that forwards to an archive store."""
 
17
    """A request handler that forwards to server.store."""
24
18
 
25
19
    def __init__(self, store):
26
20
        self.store = store
29
23
    def __call__(self, environ, start_response):
30
24
        self.environ = environ
31
25
        self.start_response = start_response
32
 
        self.headers = Headers([('content-type', 'application/json')])
33
26
        self.method = environ['REQUEST_METHOD']
34
 
        if '://' in environ['PATH_INFO']:
35
 
            # All the needed information is embedded in PATH_INFO.
36
 
            shift_path_info(environ)  # shift the host and or port.
37
 
            self.application = shift_path_info(environ)
38
 
            path = environ['PATH_INFO'].split('/')
39
 
            path.pop(0)  # Pop the scheme.
40
 
            self.path = path
41
 
        elif environ['SCRIPT_NAME'] == '':
42
 
            # Remove the application to set the path.
43
 
            self.application = shift_path_info(environ)
44
 
            self.path = environ['PATH_INFO'].split('/')
45
 
        else:
46
 
            self.application = environ['SCRIPT_NAME']
47
 
            self.path = environ['PATH_INFO'].split('/')
 
27
        self.host_port = shift_path_info(environ)
 
28
        self.application = shift_path_info(environ)
 
29
        self.path = environ['PATH_INFO'].split('/')[1:]
48
30
        self.query_string = environ['QUERY_STRING']
49
31
        return self.handle_request()
50
32
 
51
33
    def handle_request(self):
52
 
        """Select the method to handle the request and return a response."""
53
 
        if self.application != 'archive':
54
 
            return self.send_response(httplib.NOT_FOUND)
55
 
        elif self.method == 'PUT':
 
34
        if self.method == 'PUT':
56
35
            return self.do_PUT()
57
 
        elif self.method == 'POST':
 
36
        if self.method == 'POST':
58
37
            return self.do_POST()
59
 
        elif self.method == 'GET':
 
38
        if self.method == 'GET':
60
39
            return self.do_GET()
61
 
        return self.send_response(httplib.METHOD_NOT_ALLOWED)
62
40
 
63
 
    def send_response(self, code, response='', reason=None):
64
 
        """Set the status code and reason, then return the response."""
 
41
    def send_response(self, code, headers={}, reason=None):
65
42
        if reason is None:
66
43
            reason = httplib.responses[code]
67
 
        response_status = '%s %s' % (code, reason)
68
 
        self.start_response(response_status, self.headers.items())
69
 
        return [response]
 
44
        response_code = '%s %s' % (code, reason)
 
45
        response_headers = {'content-type': 'application/json'}
 
46
        response_headers.update(headers.items())
 
47
        self.start_response(response_code, response_headers.items())
70
48
 
71
49
    def do_PUT(self):
72
50
        """Create an archive or message on PUT."""
74
52
            # This expected path is /archive/archive_id.
75
53
            try:
76
54
                self.store.put_archive(self.path[0])
77
 
                return self.send_response(httplib.CREATED)
 
55
                self.send_response(httplib.CREATED)
 
56
                return ['']
78
57
            except Exception, error:
79
 
                return self.send_response(
 
58
                self.send_response(
80
59
                    httplib.BAD_REQUEST, reason=error.__doc__)
81
 
        elif len(self.path) == 2:
 
60
                return ['']
 
61
        if len(self.path) == 2:
82
62
            # This expected path is /archive/archive_id/message_id.
83
63
            try:
84
64
                put_input = self.environ['wsgi.input']
85
65
                message = put_input.read(int(self.environ['CONTENT_LENGTH']))
86
66
                self.store.put_message(self.path[0], self.path[1], message)
87
 
                return self.send_response(httplib.CREATED)
88
 
            except Exception, error:
89
 
                return self.send_response(
90
 
                    httplib.BAD_REQUEST, reason=error.__doc__)
 
67
                self.send_response(httplib.CREATED)
 
68
                return ['']
 
69
            except:
 
70
                self.send_response(httplib.BAD_REQUEST)
 
71
                return ['']
91
72
 
92
73
    def do_POST(self):
93
74
        """Change a message on POST."""
97
78
                # This expected path is /archive/archive_id/message_id.
98
79
                response = self.store.hide_message(
99
80
                    self.path[0], self.path[1], self.query_string)
100
 
                response = simplejson.dumps(response)
101
 
                return self.send_response(httplib.OK, response=response)
102
 
            except Exception, error:
103
 
                return self.send_response(
104
 
                    httplib.BAD_REQUEST, reason=error.__doc__)
 
81
                self.send_response(httplib.OK)
 
82
                return [simplejson.dumps(response)]
 
83
            except:
 
84
                self.send_response(httplib.BAD_REQUEST)
 
85
                return ['']
105
86
 
106
87
    def do_GET(self):
107
88
        """Retrieve a list of messages on GET."""
108
89
        try:
109
90
            response = self.store.get_messages(
110
91
                self.path[0], self.query_string)
111
 
            response = simplejson.dumps(response)
112
 
            return self.send_response(httplib.OK, response=response)
 
92
            self.send_response(httplib.OK)
 
93
            return [simplejson.dumps(response)]
113
94
        except Exception, error:
114
 
            return self.send_response(
115
 
                httplib.BAD_REQUEST, reason=error.__doc__)
 
95
            self.send_response(httplib.BAD_REQUEST, reason=error.__doc__)
 
96
            return ['']
116
97
 
117
98
    def log_message(self, format, *args):
118
99
        """Override log_message to use standard Python logging."""
183
164
        os.kill(self.pid, SIGKILL)
184
165
 
185
166
 
 
167
def application(environ, start_response):
 
168
    start_response('200 OK', [('Content-Type', 'text/plain')])
 
169
    return "Hello World"
 
170
 
 
171
 
186
172
if __name__ == '__main__':
187
173
    app = GrackleService(MemoryStore({}))
188
174
    service = make_server('', 8787, app)