diff options
author | Leif Johansson <leifj@sunet.se> | 2011-06-19 23:39:34 +0200 |
---|---|---|
committer | Leif Johansson <leifj@sunet.se> | 2011-06-19 23:39:34 +0200 |
commit | a987b0cbf7874c4c547536270b80e432561ddfd8 (patch) | |
tree | 416546b83a5c591d65f55b72a49024122ae55a33 /coip/apps/opensocial | |
parent | 3cb58a9e9c9aae32ae1b22c3d8e83528df766764 (diff) |
initial opensocial people service
Diffstat (limited to 'coip/apps/opensocial')
-rw-r--r-- | coip/apps/opensocial/__init__.py | 6 | ||||
-rw-r--r-- | coip/apps/opensocial/people.py | 77 | ||||
-rw-r--r-- | coip/apps/opensocial/serializer.py | 90 |
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 |