Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 92 lines (73 sloc) 2.635 kb
ef0440b @rnewson Python variant of couchdb external hook.
authored
1 #!/usr/bin/python
2
416a059 @davisp Refactored the external hook a bit.
davisp authored
3 import httplib
4 import optparse as op
5 import sys
6 import traceback
9e37cdb @rnewson url escape query parameters.
authored
7 import urllib
7217c19 @rnewson simplify Python script.
authored
8
ef0440b @rnewson Python variant of couchdb external hook.
authored
9 try:
10 import json
11 except:
12 import simplejson as json
13
416a059 @davisp Refactored the external hook a bit.
davisp authored
14 __usage__ = "%prog [OPTIONS]"
15
16 def options():
17 return [
b9dc7a9 @rnewson fix external hook and external documentation.
authored
18 op.make_option('--host', dest='host',
416a059 @davisp Refactored the external hook a bit.
davisp authored
19 default="127.0.0.1",
b9dc7a9 @rnewson fix external hook and external documentation.
authored
20 help="Hostname of the couchdb-lucene server. [%default]"),
21 op.make_option('--port', dest='port', type='int',
416a059 @davisp Refactored the external hook a bit.
davisp authored
22 default=5985,
b9dc7a9 @rnewson fix external hook and external documentation.
authored
23 help="Port of the couchdb-lucene server. [%default]"),
24 op.make_option('--key', dest='key',
25 default="local",
26 help="Host key of this couchdb instance. [%default]")
416a059 @davisp Refactored the external hook a bit.
davisp authored
27 ]
28
29 def main():
30 parser = op.OptionParser(usage=__usage__, option_list=options())
31 opts, args = parser.parse_args()
32
33 if len(args):
34 parser.error("Unrecognized arguments: %s" % ' '.join(args))
b9dc7a9 @rnewson fix external hook and external documentation.
authored
35 res = httplib.HTTPConnection(opts.host, opts.port)
416a059 @davisp Refactored the external hook a bit.
davisp authored
36 for req in requests():
37 try:
b9dc7a9 @rnewson fix external hook and external documentation.
authored
38 resp = respond(res, req, opts.key)
416a059 @davisp Refactored the external hook a bit.
davisp authored
39 except Exception, e:
40 body = traceback.format_exc()
41 resp = mkresp(500, body, {"Content-Type": "text/plain"})
b9dc7a9 @rnewson fix external hook and external documentation.
authored
42 res = httplib.HTTPConnection(opts.host, opts.port)
416a059 @davisp Refactored the external hook a bit.
davisp authored
43
44 sys.stdout.write(json.dumps(resp))
45 sys.stdout.write("\n")
46 sys.stdout.flush()
47
ef0440b @rnewson Python variant of couchdb external hook.
authored
48 def requests():
49 line = sys.stdin.readline()
50 while line:
51 yield json.loads(line)
52 line = sys.stdin.readline()
53
b9dc7a9 @rnewson fix external hook and external documentation.
authored
54 def respond(res, req, host_key):
416a059 @davisp Refactored the external hook a bit.
davisp authored
55 path = req.get("path", [])
989c04a @rnewson make Python external hook script work for cache hits too.
authored
56
416a059 @davisp Refactored the external hook a bit.
davisp authored
57 if len(path) != 4:
58 body = "\n".join([
59 "Invalid path: %s" % '/'.join([''] + path),
b9dc7a9 @rnewson fix external hook and external documentation.
authored
60 "Paths should be: /host_key/db_name/_fti/docid/index_name?q=...",
416a059 @davisp Refactored the external hook a bit.
davisp authored
61 "'docid' is from the '_design/docid' that defines index_name"
62 ])
63 return mkresp(400, body, {"Content-Type": "text/plain"})
ef0440b @rnewson Python variant of couchdb external hook.
authored
64
b9dc7a9 @rnewson fix external hook and external documentation.
authored
65 path = '/'.join(['', 'search', host_key, path[0], path[2], path[3]])
416a059 @davisp Refactored the external hook a bit.
davisp authored
66 path = '?'.join([path, urllib.urlencode(req["query"])])
24c528e @rnewson allow -u/--url= override for couchdb-lucene location.
authored
67
989c04a @rnewson make Python external hook script work for cache hits too.
authored
68 req_headers = {}
416a059 @davisp Refactored the external hook a bit.
davisp authored
69 for h in req.get("headers", []):
70 if h.lower() in ["accept", "if-none-match"]:
989c04a @rnewson make Python external hook script work for cache hits too.
authored
71 req_headers[h] = req["headers"][h]
416a059 @davisp Refactored the external hook a bit.
davisp authored
72
989c04a @rnewson make Python external hook script work for cache hits too.
authored
73 res.request("GET", path, headers=req_headers)
416a059 @davisp Refactored the external hook a bit.
davisp authored
74 resp = res.getresponse()
989c04a @rnewson make Python external hook script work for cache hits too.
authored
75
76 resp_headers = {}
77 for h, v in resp.getheaders():
78 if h.lower() in ["content-type", "etag"]:
79 resp_headers[h] = resp.getheader(h, [])
80
81 return mkresp(resp.status, resp.read(), resp_headers)
416a059 @davisp Refactored the external hook a bit.
davisp authored
82
83 def mkresp(code, body, headers=None):
84 ret = {"code": code, "body": body}
85 if headers is not None:
86 ret["headers"] = headers
87 return ret
ef0440b @rnewson Python variant of couchdb external hook.
authored
88
89 if __name__ == "__main__":
90 main()
416a059 @davisp Refactored the external hook a bit.
davisp authored
91
Something went wrong with that request. Please try again.