Skip to content

HTTPS clone URL

Subversion checkout URL

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