import basura import os, uuid, cgi from simplejson import dumps as tojson, loads as fromjson from subprocess import Popen, PIPE from threading import Thread def request(environ, response): path = environ['PATH_INFO'].split('/',2) # if the database doesn't exist db = basura.dbexists(path[1]) if db == False: response('404 Not Found') return tojson({"error":{"id":"not_found","reason":"missing"}}) # only a db, no ID if len(path)<3 or not path[2]: doc = fromjson(environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))) if doc.has_key('_bulk_docs'): # TODO: make a first pass looking for conflicts, missing ids? for subdoc in doc['_bulk_docs']: subdoc['_rev'] = str(uuid.uuid1()) db[str(subdoc['_id'])] = subdoc response('201 Created') return tojson({"ok":True}) else: # POST w/out ID => PUT w/newly minted ID doc['_id'] = doc['_rev'] = str(uuid.uuid1()) db[doc['_id']] = doc response('201 Created') return tojson({"ok":True, "_id":doc["_id"], "_rev":doc["_rev"]}) # retrieve the input stream query = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) # builtin view: _all_docs if path[2] == '_temp_view': server = Popen(['js', 'main.js'], stdin=PIPE, stdout=PIPE, cwd='viewServer/javascript') # asyncronously feed in json documents def pump(): server.stdin.write('["reset"]\n') server.stdin.write('["add_map_fun", %s]\n' % tojson(query)) for doc in db.itervalues(): server.stdin.write('["map_doc", %s]\n' % doc) server.stdin.write('\n') # why? thread = Thread(target=pump) thread.start() # skip past the initialization responses dummy = server.stdout.readline() # why? reset = server.stdout.readline() amf = server.stdout.readline() # list comprehension of the results rows = [] for id, doc in db.iteritems(): for row in fromjson(server.stdout.readline()): if not row: continue if not isinstance(row,dict): row = {"value":row} if row.keys() == ['multi']: for mrow in row['multi']: rows.append((mrow.items(), doc['_id'], doc["_rev"])) else: rows.append((row.items(), doc['_id'], doc["_rev"])) rows.sort() args = dict(cgi.parse_qsl(environ['QUERY_STRING'])) if args.get('reverse','') == 'true': rows.reverse() rows = [dict(value+[("_id",id), ("_rev",rev)]) for value, id, rev in rows] # kill the pump and viewServer thread.join() os.kill(server.pid, 15) # produce the response response('200 OK') return tojson({"view":"_temp_view:" + query, "offset":0, "total_rows": len(rows), "rows": rows}) # not found response('404 Not Found') return tojson({"error":{"id":"not_found","reason":"missing"}})