Skip to content

Instantly share code, notes, and snippets.

@ialexi
Created December 22, 2009 00:07
Show Gist options
  • Select an option

  • Save ialexi/261381 to your computer and use it in GitHub Desktop.

Select an option

Save ialexi/261381 to your computer and use it in GitHub Desktop.
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