Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 107 lines (86 sloc) 3.05 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 suppor...
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 suppor...
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
980372a @rnewson tidy up python script
authored
59 # Drop name of external hook.
60 del path[1]
c11d33e @rnewson handle databases with embedded slashes
authored
61 # URL-escape each part
62 for index, item in enumerate(path):
63 path[index] = urllib.quote(path[index], "")
980372a @rnewson tidy up python script
authored
64
8203af6 @rnewson support _optimize and _expunge calls.
authored
65 if len(path) == 3:
66 if req["query"] == {}:
67 path = '/'.join(['', 'info', key] + path)
68 else:
69 path = '/'.join(['', 'search', key] + path)
a84ba74 @rnewson convert unicode to utf-8 before urlencode call
authored
70 params = urllib.urlencode(dict([k, v.encode('utf-8')] for k, v in req["query"].items()))
71 path = '?'.join([path, params])
8203af6 @rnewson support _optimize and _expunge calls.
authored
72 elif len(path) == 4:
73 path = '/'.join(['', 'admin', key] + path)
24d6818 @rnewson call 'info' for calls without query argument
authored
74 else:
8203af6 @rnewson support _optimize and _expunge calls.
authored
75 return mkresp(400, "Invalid path\n" + str(len(req)), {"Content-Type":"text/plain"})
24c528e @rnewson allow -u/--url= override for couchdb-lucene location.
authored
76
989c04a @rnewson make Python external hook script work for cache hits too.
authored
77 req_headers = {}
416a059 @davisp Refactored the external hook a bit.
davisp authored
78 for h in req.get("headers", []):
79 if h.lower() in ["accept", "if-none-match"]:
989c04a @rnewson make Python external hook script work for cache hits too.
authored
80 req_headers[h] = req["headers"][h]
416a059 @davisp Refactored the external hook a bit.
davisp authored
81
f4799dc @rnewson handle older Python versions in hook script.
authored
82 # verb renamed to method in 0.11 onwards.
83 if "method" in req:
84 method = req["method"]
85 else:
86 method = req["verb"]
87
ddfd64d @rnewson allow either 'verb' or 'method' in req object.
authored
88 res.request(method, path, headers=req_headers)
416a059 @davisp Refactored the external hook a bit.
davisp authored
89 resp = res.getresponse()
989c04a @rnewson make Python external hook script work for cache hits too.
authored
90
91 resp_headers = {}
92 for h, v in resp.getheaders():
082b7da @rnewson httplib lower-cases HTTP responses headers -- so fix that ourselves.
authored
93 if h.lower() in httpdict:
94 resp_headers[httpdict[h]] = resp.getheader(h, [])
989c04a @rnewson make Python external hook script work for cache hits too.
authored
95
96 return mkresp(resp.status, resp.read(), resp_headers)
416a059 @davisp Refactored the external hook a bit.
davisp authored
97
98 def mkresp(code, body, headers=None):
99 ret = {"code": code, "body": body}
100 if headers is not None:
101 ret["headers"] = headers
102 return ret
ef0440b @rnewson Python variant of couchdb external hook.
authored
103
104 if __name__ == "__main__":
105 main()
416a059 @davisp Refactored the external hook a bit.
davisp authored
106
Something went wrong with that request. Please try again.