Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 106 lines (85 sloc) 3.205 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
082b7da @rnewson httplib lower-cases HTTP responses headers -- so fix that ourselves.
authored
16 httpdict = {"etag":"ETag", "content-type":"Content-Type"}
17
416a059 @davisp Refactored the external hook a bit.
davisp authored
18 def options():
19 return [
cbfe065 @rnewson remove registry and indexkey, change output paths
authored
20 op.make_option('--remote-host', dest='remote_host',
21 default="localhost",
b9dc7a9 @rnewson fix external hook and external documentation.
authored
22 help="Hostname of the couchdb-lucene server. [%default]"),
cbfe065 @rnewson remove registry and indexkey, change output paths
authored
23 op.make_option('--remote-port', dest='remote_port', type='int',
416a059 @davisp Refactored the external hook a bit.
davisp authored
24 default=5985,
b9dc7a9 @rnewson fix external hook and external documentation.
authored
25 help="Port of the couchdb-lucene server. [%default]"),
cbfe065 @rnewson remove registry and indexkey, change output paths
authored
26 op.make_option('--local-host', dest='local_host',
27 default="localhost",
28 help="Hostname of this couchdb instance. [%default]"),
29 op.make_option('--local-port', dest='local_port', type='int',
30 default=5984,
31 help="Port of this couchdb instance. [%default]"),
416a059 @davisp Refactored the external hook a bit.
davisp authored
32 ]
33
34 def main():
35 parser = op.OptionParser(usage=__usage__, option_list=options())
36 opts, args = parser.parse_args()
37
38 if len(args):
39 parser.error("Unrecognized arguments: %s" % ' '.join(args))
cbfe065 @rnewson remove registry and indexkey, change output paths
authored
40 res = httplib.HTTPConnection(opts.remote_host, opts.remote_port)
416a059 @davisp Refactored the external hook a bit.
davisp authored
41 for req in requests():
42 try:
cbfe065 @rnewson remove registry and indexkey, change output paths
authored
43 resp = respond(res, req, opts.local_host, opts.local_port)
416a059 @davisp Refactored the external hook a bit.
davisp authored
44 except Exception, e:
45 body = traceback.format_exc()
46 resp = mkresp(500, body, {"Content-Type": "text/plain"})
cbfe065 @rnewson remove registry and indexkey, change output paths
authored
47 res = httplib.HTTPConnection(opts.remote_host, opts.remote_port)
416a059 @davisp Refactored the external hook a bit.
davisp authored
48
49 sys.stdout.write(json.dumps(resp))
50 sys.stdout.write("\n")
51 sys.stdout.flush()
52
ef0440b @rnewson Python variant of couchdb external hook.
authored
53 def requests():
54 line = sys.stdin.readline()
55 while line:
56 yield json.loads(line)
57 line = sys.stdin.readline()
58
cbfe065 @rnewson remove registry and indexkey, change output paths
authored
59 def respond(res, req, host, port):
416a059 @davisp Refactored the external hook a bit.
davisp authored
60 path = req.get("path", [])
989c04a @rnewson make Python external hook script work for cache hits too.
authored
61
416a059 @davisp Refactored the external hook a bit.
davisp authored
62 if len(path) != 4:
63 body = "\n".join([
64 "Invalid path: %s" % '/'.join([''] + path),
bfea51b @rnewson clarify error message
authored
65 "Paths should be: /db_name/_fti/ddocid/index_name?q=...",
66 "'ddocid' is from the '_design/ddocid' that defines index_name"
416a059 @davisp Refactored the external hook a bit.
davisp authored
67 ])
68 return mkresp(400, body, {"Content-Type": "text/plain"})
ef0440b @rnewson Python variant of couchdb external hook.
authored
69
980372a @rnewson tidy up python script
authored
70 # Drop name of external hook.
71 del path[1]
c11d33e @rnewson handle databases with embedded slashes
authored
72 # URL-escape each part
73 for index, item in enumerate(path):
74 path[index] = urllib.quote(path[index], "")
980372a @rnewson tidy up python script
authored
75
24d6818 @rnewson call 'info' for calls without query argument
authored
76 if req["query"] == {}:
c11d33e @rnewson handle databases with embedded slashes
authored
77 path = '/'.join(['', 'info', host, str(port)], path)
24d6818 @rnewson call 'info' for calls without query argument
authored
78 else:
980372a @rnewson tidy up python script
authored
79 path = '/'.join(['', 'search', host, str(port)] + path)
24d6818 @rnewson call 'info' for calls without query argument
authored
80 path = '?'.join([path, urllib.urlencode(req["query"])])
24c528e @rnewson allow -u/--url= override for couchdb-lucene location.
authored
81
989c04a @rnewson make Python external hook script work for cache hits too.
authored
82 req_headers = {}
416a059 @davisp Refactored the external hook a bit.
davisp authored
83 for h in req.get("headers", []):
84 if h.lower() in ["accept", "if-none-match"]:
989c04a @rnewson make Python external hook script work for cache hits too.
authored
85 req_headers[h] = req["headers"][h]
416a059 @davisp Refactored the external hook a bit.
davisp authored
86
989c04a @rnewson make Python external hook script work for cache hits too.
authored
87 res.request("GET", path, headers=req_headers)
416a059 @davisp Refactored the external hook a bit.
davisp authored
88 resp = res.getresponse()
989c04a @rnewson make Python external hook script work for cache hits too.
authored
89
90 resp_headers = {}
91 for h, v in resp.getheaders():
082b7da @rnewson httplib lower-cases HTTP responses headers -- so fix that ourselves.
authored
92 if h.lower() in httpdict:
93 resp_headers[httpdict[h]] = resp.getheader(h, [])
989c04a @rnewson make Python external hook script work for cache hits too.
authored
94
95 return mkresp(resp.status, resp.read(), resp_headers)
416a059 @davisp Refactored the external hook a bit.
davisp authored
96
97 def mkresp(code, body, headers=None):
98 ret = {"code": code, "body": body}
99 if headers is not None:
100 ret["headers"] = headers
101 return ret
ef0440b @rnewson Python variant of couchdb external hook.
authored
102
103 if __name__ == "__main__":
104 main()
416a059 @davisp Refactored the external hook a bit.
davisp authored
105
Something went wrong with that request. Please try again.