harvest-dev team mailing list archive
-
harvest-dev team
-
Mailing list archive
-
Message #00254
[Merge] lp:~dholbach/harvest/581730 into lp:harvest
Daniel Holbach has proposed merging lp:~dholbach/harvest/581730 into lp:harvest.
Requested reviews:
harvest-dev (harvest-dev)
Related bugs:
#581730 dump data to json
https://bugs.launchpad.net/bugs/581730
--
https://code.launchpad.net/~dholbach/harvest/581730/+merge/33387
Your team harvest-dev is requested to review the proposed merge of lp:~dholbach/harvest/581730 into lp:harvest.
=== added directory 'harvest/services'
=== added file 'harvest/services/__init__.py'
--- harvest/services/__init__.py 1970-01-01 00:00:00 +0000
+++ harvest/services/__init__.py 2010-08-23 14:17:40 +0000
@@ -0,0 +1,155 @@
+# Portions of this code comes from the Oct09 project
+# developed by the Moffitt Cancer Center.
+# License: http://bitbucket.org/oct09/main/src/tip/COPYING
+# Project: http://bitbucket.org/oct09/main/wiki/Home
+
+from django.db.models import Model
+from django.http import HttpResponse
+from django.forms.fields import EMPTY_VALUES
+from django.utils import simplejson
+import re
+import decimal
+
+CHUNK_SIZE = 500
+
+def parse_number_argument(arguments, which):
+ if not arguments.has_key(which):
+ return None
+ if arguments[which] in EMPTY_VALUES:
+ return None
+ try:
+ number = int(arguments[which])
+ except:
+ number = None
+ return number
+
+def model_service(model, request, url, include=None, exclude=None):
+ (instance_id, rem_url) = get_model_id(request, url)
+
+ try:
+ if instance_id is not None and instance_id != '':
+ return model_entity(model, request, url, include, exclude)
+ else:
+ return model_collection(model, request, url, include, exclude)
+ except Exception, e:
+ return HttpResponse(encode_error(e))
+
+def model_entity(model, request, url, include=None, exclude=None):
+ (entity_id, rem_url) = get_model_id(request, url)
+
+ try:
+ entity = model.objects.get(pk=entity_id)
+ except:
+ return HttpResponse(encode_error("Entity not found"))
+
+
+ # Otherwise process the entity request
+ if request.method == "GET":
+ return HttpResponse(encode(entity, include, exclude), mimetype=get_mimetype())
+
+ elif request.method == "PUT":
+ return HttpResponse(encode_error("Write operations are not supported"))
+
+ elif request.method == "DELETE":
+ return HttpResponse(encode_error("Write operations are not supported"))
+
+ return HttpResponse(encode_error("%s Not Implemented"%request.method))
+
+def model_collection(model, request, url, include=None, exclude=None):
+ if request.method == "GET":
+ results = do_search(model, request.GET, include, exclude)
+
+ collection = list(results)
+ return HttpResponse(encode(collection, include, exclude), mimetype=get_mimetype())
+
+ elif request.method == "POST":
+ return HttpResponse(encode_error("Write operations are not supported"))
+
+ return HttpResponse(encode_error("%s Not Implemented"%request.method))
+
+def do_search(model, request, include=None, exclude=None):
+ search_fields = include
+ if search_fields is None:
+ search_fields = [f.name for f in model._meta.local_fields+model._meta.many_to_many if not f.name.endswith("_ptr")]
+ if exclude is not None:
+ search_fields = [f for f in search_fields if f not in exclude]
+ search_values = dict([(str(key), value) for (key, value) in request.items()])
+
+ extra_arguments = {}
+ for key in search_values.keys():
+ if key.startswith('_'):
+ extra_arguments[key] = search_values.pop(key)
+ offset = parse_number_argument(extra_arguments, '_offset')
+ length = parse_number_argument(extra_arguments, '_length')
+ if not length or length > CHUNK_SIZE:
+ length = CHUNK_SIZE
+ results = model.objects.filter(**search_values)[offset:length]
+
+ if '_sortby' in request and request['_sortby'] not in EMPTY_VALUES:
+ results = results.order_by(request.get('_sortby'))
+ return results
+
+def get_model_id(request, url):
+ instance_id = None
+ rem_url = None
+ if url is not None and len(url) > 0:
+ m = re.match(r"^([^/]+)/?(.*)", url)
+
+ if m is not None:
+ instance_id = m.group(1)
+ rem_url = m.group(2)
+ return (instance_id, rem_url)
+
+def encode(entity, include=None, exclude=None):
+ json = JSONEncoder(include, exclude)
+ return json.encode(entity)
+
+def decode(klass, entity, request, url=None):
+ return request.raw_post_data
+
+def get_mimetype():
+ return "application/json"
+
+def encode_error(error):
+ json = JSONEncoder()
+ return json.encode({'error': unicode(error)})
+
+class JSONEncoder(simplejson.JSONEncoder):
+
+ def __init__(self, include=None, exclude=None):
+ self.include = include
+ self.exclude = exclude
+ super(JSONEncoder, self).__init__()
+
+ def get_field_value(self, o, field):
+ f = getattr(o, field)
+ try:
+ if isinstance(f, Model):
+ if hasattr(f, 'pk'):
+ return self.default(f.pk)
+ else:
+ return None
+ if isinstance(f, decimal.Decimal):
+ return o._meta.get_field_by_name(field)[0]._format(f)
+ else:
+ return self.default(f)
+ except Exception:
+ return None
+
+ def default(self, o=None):
+
+ if isinstance(o, Model):
+ model_fields = self.include
+ if model_fields is None:
+ model_fields = [f.name for f in o._meta.fields+o._meta.many_to_many if not f.name.endswith("_ptr")]
+ if self.exclude is not None:
+ model_fields = [f for f in model_fields if f not in self.exclude]
+ d = dict([(field, self.get_field_value(o, field)) for field in model_fields])
+ return d
+ elif o.__class__.__name__ == 'ManyRelatedManager' or o.__class__.__name__ == 'RelatedManager':
+ return [r.pk for r in o.all()]
+ elif isinstance(o, (int, long, float)):
+ return o
+ elif o is None:
+ return None
+ return str(o)
=== added file 'harvest/services/urls.py'
--- harvest/services/urls.py 1970-01-01 00:00:00 +0000
+++ harvest/services/urls.py 2010-08-23 14:17:40 +0000
@@ -0,0 +1,12 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+ url(r'^users/(.*)$', 'services.views.user_service', name='user_service'),
+ url(r'^packagesets/(.*)$', 'services.views.packageset_service', name='packageset_service'),
+ url(r'^sourcepackages/(.*)$', 'services.views.sourcepackage_service', name='sourcepackage_service'),
+ url(r'^opportunitylists/(.*)$', 'services.views.opportunitylist_service', name='opportunitylist_service'),
+ url(r'^opportunities/(.*)$', 'services.views.opportunity_service', name='opportunity_service'),
+ url(r'^notes/(.*)$', 'services.views.note_service', name='note_service'),
+ url(r'^actionlogentries/(.*)$', 'services.views.actionlogentry_service', name='actionlogentry_service'),
+)
+
=== added file 'harvest/services/views.py'
--- harvest/services/views.py 1970-01-01 00:00:00 +0000
+++ harvest/services/views.py 2010-08-23 14:17:40 +0000
@@ -0,0 +1,25 @@
+from opportunities.models import PackageSet, SourcePackage, OpportunityList, Opportunity, Note, ActionLogEntry
+from django.contrib.auth.models import User
+
+from services import model_service
+
+def user_service(request, url):
+ return model_service(User, request, url, include=['id', 'username', 'groups'])
+
+def packageset_service(request, url):
+ return model_service(PackageSet, request, url)
+
+def sourcepackage_service(request, url):
+ return model_service(SourcePackage, request, url)
+
+def opportunitylist_service(request, url):
+ return model_service(OpportunityList, request, url)
+
+def opportunity_service(request, url):
+ return model_service(Opportunity, request, url)
+
+def note_service(request, url):
+ return model_service(Note, request, url)
+
+def actionlogentry_service(request, url):
+ return model_service(ActionLogEntry, request, url)
=== modified file 'harvest/settings.py'
--- harvest/settings.py 2010-07-14 19:52:01 +0000
+++ harvest/settings.py 2010-08-23 14:17:40 +0000
@@ -111,6 +111,7 @@
'django_openid_auth',
'opportunities',
'filters',
+ 'services',
'common',
)
=== modified file 'harvest/urls.py'
--- harvest/urls.py 2009-08-26 14:57:36 +0000
+++ harvest/urls.py 2010-08-23 14:17:40 +0000
@@ -7,6 +7,7 @@
urlpatterns = patterns('',
url(r'^$', 'common.views.index', name='home'),
url(r'^opportunities/', include('opportunities.urls')),
+ url(r'^services/', include('services.urls')),
url(r'^openid/', include('django_openid_auth.urls')),
url(r'^logout$', 'common.views.site_logout'),
url(r'^admin/', include(admin.site.urls)),