summaryrefslogtreecommitdiff
path: root/coip/apps/opensocial
diff options
context:
space:
mode:
authorLeif Johansson <leifj@sunet.se>2011-06-19 23:39:34 +0200
committerLeif Johansson <leifj@sunet.se>2011-06-19 23:39:34 +0200
commita987b0cbf7874c4c547536270b80e432561ddfd8 (patch)
tree416546b83a5c591d65f55b72a49024122ae55a33 /coip/apps/opensocial
parent3cb58a9e9c9aae32ae1b22c3d8e83528df766764 (diff)
initial opensocial people service
Diffstat (limited to 'coip/apps/opensocial')
-rw-r--r--coip/apps/opensocial/__init__.py6
-rw-r--r--coip/apps/opensocial/people.py77
-rw-r--r--coip/apps/opensocial/serializer.py90
3 files changed, 173 insertions, 0 deletions
diff --git a/coip/apps/opensocial/__init__.py b/coip/apps/opensocial/__init__.py
new file mode 100644
index 0000000..289f68c
--- /dev/null
+++ b/coip/apps/opensocial/__init__.py
@@ -0,0 +1,6 @@
+from tastypie.api import Api
+from coip.apps.opensocial.people import PersonResource, MembershipResource
+
+opensocial_v1 = Api(api_name = "1.0")
+opensocial_v1.register(PersonResource())
+opensocial_v1.register(MembershipResource()) \ No newline at end of file
diff --git a/coip/apps/opensocial/people.py b/coip/apps/opensocial/people.py
new file mode 100644
index 0000000..128b2c7
--- /dev/null
+++ b/coip/apps/opensocial/people.py
@@ -0,0 +1,77 @@
+'''
+Created on Jun 19, 2011
+
+@author: leifj
+'''
+from tastypie.resources import ModelResource
+from coip.apps.userprofile.models import UserProfile, last_used_profile
+from django.contrib.auth.models import User
+from coip.apps.opensocial.serializer import OpenSocialSerializer
+from django.conf.urls.defaults import url
+from coip.apps.membership.models import Membership
+from tastypie.fields import ToManyField, ToOneField
+from tastypie.utils.urls import trailing_slash
+from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
+from tastypie.http import HttpGone, HttpMultipleChoices
+import logging
+from tastypie.serializers import Serializer
+from pprint import pformat
+
+class MembershipResource(ModelResource):
+
+ user = ToOneField("coip.apps.opensocial.people.PersonResource",'user',full=True)
+
+ class Meta:
+ queryset = Membership.objects.all()
+ serializer = OpenSocialSerializer()
+ resource_name = 'membership'
+ fields = ['user']
+
+ def dehydrate(self,bundle):
+ bundle = super(MembershipResource,self).dehydrate(bundle)
+ del bundle.data['resource_uri']
+ return bundle
+
+class PersonResource(ModelResource):
+
+ #memberships = ToManyField(MembershipResource,'memberships',full=True)
+
+ class Meta:
+ queryset = User.objects.all()
+ fields = ['username']
+ resource_name = 'people'
+ serializer = OpenSocialSerializer()
+
+ def override_urls(self):
+ return [
+ url(r"^(?P<resource_name>%s)/(?P<username>[\@\w\d_.-:]+)/(?P<pk>[\d]+)%s?" % (self._meta.resource_name,trailing_slash()),
+ self.wrap_view('list_memberships'), name="api_list_memberships"),
+ url(r"^(?P<resource_name>%s)/(?P<username>[\@\w\d_.-:]+)(?:/\@self)?%s" % (self._meta.resource_name,trailing_slash()),
+ self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
+ ]
+
+ def list_memberships(self, request, **kwargs):
+ logging.debug(pformat(kwargs))
+ try:
+ obj = self.cached_obj_get(request=request, username=kwargs['username'])
+ logging.debug(pformat(obj))
+ except ObjectDoesNotExist:
+ return HttpGone()
+ except MultipleObjectsReturned:
+ return HttpMultipleChoices("More than one resource is found at this URI.")
+
+ membership_resource = MembershipResource()
+ return membership_resource.get_list(request, group__owner_id=obj.pk)
+
+ def dispatch(self, request_type, request, **kwargs):
+ if kwargs.has_key('username') and kwargs['username'] == '@me':
+ kwargs['username'] = request.user.username
+ return super(PersonResource, self).dispatch(request_type, request, **kwargs)
+
+ def dehydrate(self,bundle):
+ bundle = super(PersonResource,self).dehydrate(bundle)
+ bundle.data['id'] = bundle.data['username']
+ bundle.data['displayName'] = last_used_profile(bundle.obj).display_name
+ del bundle.data['resource_uri']
+ del bundle.data['username']
+ return bundle \ No newline at end of file
diff --git a/coip/apps/opensocial/serializer.py b/coip/apps/opensocial/serializer.py
new file mode 100644
index 0000000..14ac2df
--- /dev/null
+++ b/coip/apps/opensocial/serializer.py
@@ -0,0 +1,90 @@
+'''
+Created on Jun 19, 2011
+
+@author: leifj
+'''
+from tastypie.serializers import Serializer, get_type_string
+from lxml.etree import Element
+from tastypie.bundle import Bundle
+from tastypie.fields import ApiField, ToOneField, ToManyField
+from django.utils.encoding import force_unicode
+import logging
+from pprint import pformat
+
+class OpenSocialSerializer(Serializer):
+
+ def __init__(self, formats=None, content_types=None, datetime_formatting=None):
+ super(OpenSocialSerializer,self).__init__(formats,content_types,datetime_formatting)
+
+ def to_etree(self, data, options=None, name=None, depth=0):
+
+ #logging.debug("--------")
+ #logging.debug(name)
+ #logging.debug(depth)
+ #logging.debug(pformat(data))
+ """
+ Given some data, converts that data to an ``etree.Element`` suitable
+ for use in the XML output.
+ """
+
+ if isinstance(data, (list, tuple)):
+ element = Element(name or 'objects')
+ if name:
+ element = Element(name)
+ #element.set('type', 'list')
+ else:
+ element = Element('objects')
+ for item in data:
+ element.append(self.to_etree(item, options, depth=depth+1))
+ elif isinstance(data, dict):
+ if depth == 0:
+ element = Element(name or 'response',attrib={'xmlns': "http://ns.opensocial.org/2008/opensocial"} )
+ else:
+ element = Element(name or 'object')
+ element.set('type', 'hash')
+
+ if data.has_key('objects'):
+ if len(data['objects']) == 1:
+ return self.to_etree(data['objects'][0], options, name=None, depth=depth)
+ else:
+ for v in data['objects']:
+ element.append(self.to_etree(v, options, name='entry', depth=depth+1))
+ else:
+ for (key, value) in data.iteritems():
+ keyname = key
+ if keyname == 'user':
+ keyname = 'person'
+ element.append(self.to_etree(value, options, name=keyname, depth=depth+1))
+ elif isinstance(data, Bundle):
+ element = Element(name or 'object')
+ for field_name, field_object in data.data.items():
+ keyname = field_name
+ if keyname == 'user':
+ keyname = 'person'
+ element.append(self.to_etree(field_object, options, name=keyname, depth=depth+1))
+ elif isinstance(data, ApiField):
+ if isinstance(data, ToOneField):
+ if data.full:
+ return self.to_etree(data.fk_resource, options, name, depth+1)
+ else:
+ return self.to_etree(data.value, options, name, depth+1)
+ elif isinstance(data, ToManyField):
+ if data.full:
+ element = Element(name or 'objects')
+ for bundle in data.m2m_bundles:
+ element.append(self.to_etree(bundle, options, bundle.resource_name, depth+1))
+ else:
+ element = Element(name or 'objects')
+ for value in data.value:
+ element.append(self.to_etree(value, options, name, depth=depth+1))
+ else:
+ return self.to_etree(data.value, options, name)
+ else:
+ element = Element(name or 'value')
+ simple_data = self.to_simple(data, options)
+ data_type = get_type_string(simple_data)
+ if data_type != 'string':
+ element.set('type', get_type_string(simple_data))
+ if data_type != 'null':
+ element.text = force_unicode(simple_data)
+ return element \ No newline at end of file