Created
December 22, 2009 00:07
-
-
Save ialexi/261381 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from django.http import HttpResponse | |
| from django.http import Http404 | |
| from cornelius import dudley | |
| import datetime | |
| import random | |
| import re, string | |
| try: import simplejson as json | |
| except ImportError: import json | |
| class Roots(object): | |
| def __init__(self, root, allowed): | |
| """ | |
| Initializes a Roots server object with a set of allowed attach points. | |
| """ | |
| if not allowed: | |
| allowed = [] | |
| self.allowed = allowed | |
| self.root = root | |
| def __call__(self, request, rtype): | |
| """ The main responder """ | |
| if not rtype in self.allowed: | |
| raise Http404 | |
| if request.method == "GET": | |
| return self.get(request, rtype) | |
| elif request.method == "PUT": # delete is done with record containing "DELETE"==True | |
| return self.put(request, rtype) | |
| def get(self, request, rtype): | |
| # for now, we only support sending _All_ data to the client. | |
| # as such, the "client_i" parameter is useless (we send data from all "virtual servers" in our "logical server") | |
| did = None | |
| if "did" in request.GET: did = request.GET["did"] | |
| data = self.attach(rtype, did) # attach returns a dump of the data | |
| return HttpResponse(json.dumps(data), mimetype="application/json") | |
| def attach(self, rtype, did): | |
| # connect if we can | |
| if did: dudley.connect(did, (rtype, )) | |
| # now, get records and return that | |
| return self.fetch_records(rtype) | |
| def put(self, request, rtype): | |
| # we need a client id. andfrom that, we create a virtual server id | |
| if "id" not in request.session: # each session gets its own virtual server on our end. | |
| # we generate it with a combo of: time + random characters | |
| id = re.sub(r"\D", "", str(datetime.datetime.now())) | |
| for i in range(10): id += random.choice(string.letters + string.digits) | |
| request.session["id"] = id | |
| client_id = request.session["id"] | |
| records = json.loads(request.raw_post_data) | |
| result = self.receive_records(rtype, records, self.root + "/" + rtype + "/" + client_id) | |
| return HttpResponse(json.dumps(result), mimetype="application/json") | |
| def fetch_records(self, rtype): | |
| return [] | |
| def receive_records(self, rtype, records, server): | |
| return [] | |
| from pymongo import Connection | |
| class MongoRoots(Roots): | |
| def __init__(self, root, allowed, db): | |
| Roots.__init__(self, root, allowed) | |
| self.db = db | |
| def fetch_records(self, rtype): | |
| result = [] | |
| for i in self.db[rtype].find(): | |
| r = {} | |
| for key in i: | |
| value = i[key] | |
| # skip _id | |
| if key == "_id": continue | |
| if isinstance(value, datetime.datetime) or isinstance(value, datetime.time) or isinstance(value, datetime.date): | |
| value = value.isoformat() # it should usually be stored in string format anyway... | |
| r[key] = value | |
| result.append(r) | |
| return result | |
| def receive_records(self, rtype, records, server): | |
| """receive messages""" | |
| result = [] | |
| updates = [] | |
| for record in records: | |
| if not "id" in record: | |
| continue | |
| existing = None | |
| # get a valid full id | |
| id = record["id"] | |
| if not "@" in str(id): | |
| id = str(id) + "@" + server | |
| # update record's copy of id to full id. | |
| record["id"] = id | |
| # see if there is an existing. | |
| existing = self.db[rtype].find_one({"id": id}) | |
| # if so, grab the _id from the old one. | |
| if existing: record["_id"] = existing["_id"] | |
| # see if we are supposed to delete. | |
| if "DELETE" in record and record["DELETE"]: | |
| if existing: self.db[rtype].remove(record["_id"]) | |
| else: continue | |
| else: | |
| self.db[rtype].save(record) | |
| del record["_id"] | |
| result.append(record) | |
| updates.append( (rtype, record) ) | |
| dudley.updates(updates) # Delete, updates, and adds! So easy! | |
| return result | |
| records = MongoRoots("contacts", ["groups", "contacts"], db=Connection().contacts) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment