def form_validate(formclass, data, instance=None, commit=True): ''' Uses a form to validate data passed in as a dictionary. See http://docs.djangoproject.com/en/dev/ref/forms/validation/ Arguments: formclass The class of the form to use data A dictionary of data instance An existing instance to use to validate ''' qd = QueryDict({}).copy() qd.update(data) form = formclass(qd, instance=instance) if not form.is_valid(): raise exceptions.APIBadRequest(simplejson.dumps(form.errors)) return form.save(commit=commit)
def get_geofeatures(request): cache_key = _generate_cache_key(request) cache_val = cache.get(cache_key, cache_control.GEOFEATURES_CACHE_GROUP) if cache_val: return APIResponseOK(content=cache_val) bounds_param = get_param(request.GET, 'within') query = request.GET.copy() if bounds_param: pnts = bounds_param.split(',') bbox = (float(pnts[0]), float(pnts[1]), float(pnts[2]), float(pnts[3])) poly = Polygon.from_bbox(bbox) poly.set_srid(4326) del query['within'] base_query = Q() if bounds_param: base_query = base_query & Q(location__within=poly) # cast within bounds cast_base_query = models.Cast.get_privacy_q(request) & base_query q = qstranslate.QueryTranslator(models.Cast, CastAPI.ruleset, cast_base_query) try: casts = q.filter(query).select_related('author').prefetch_related('media_set').prefetch_related('tags') except qstranslate.InvalidParameterException, e: raise exceptions.APIBadRequest(e.message)
def check_collection(cast_id, coll_id): coll = get_object(models.Collection, id=coll_id) try: coll.related_casts.get(id=cast_id) except models.Cast.DoesNotExist: raise exceptions.APIBadRequest('Cast is not part of collection') return coll
def get(request, event_id=None): if event_id: event = get_object(Event, id=event_id) if not event.allowed_access(request.user): raise exceptions.APIForbidden event_dict = api_serialize(event, request) return APIResponseOK(content=event_dict, total=1) else: q = qstranslate.QueryTranslator(Event, EventAPI.ruleset) query = request.GET.copy() objs = total = pg = None try: objs = q.filter(query) objs, total, pg = paginate(objs, query) except qstranslate.InvalidParameterException, e: raise exceptions.APIBadRequest(e) event_arr = [] for m in objs: event_arr.append(api_serialize(m, request)) return APIResponseOK(content=event_arr, total=total, pg=pg)
def get(request, user_id=None): # Single user if user_id: u = get_object(TravelsUser, id=user_id) content = api_serialize(u) return APIResponseOK(content=content, total=1) # Multiple users else: q = qstranslate.QueryTranslator(TravelsUser, UserAPI.ruleset) query = request.GET.copy() objs = total = pg = None try: objs = q.filter(query) objs, total, pg = paginate(objs, request.GET) except qstranslate.InvalidParameterException, e: raise exceptions.APIBadRequest(e.message) user_arr = [] for m in objs: user_arr.append(api_serialize(m, request)) return APIResponseOK(content=user_arr, total=total, pg=pg)
def check_itinerary(cast_id, itin_id): itin = get_object(models.Itinerary, id=itin_id) try: itin.related_casts.get(id=cast_id) except models.Cast.DoesNotExist: raise exceptions.APIBadRequest('Cast is not part of itinerary') return itin
def check_cast_media(media_id, cast_id): cast = get_object(models.Cast, id=cast_id) try: cast.media_set.get(id=media_id) except models.Media.DoesNotExist: raise exceptions.APIBadRequest('Media object is not part of cast') return cast
def post_media_content(request, cast_id, media_id): get_object(models.Cast, cast_id) media = get_object(models.Media, media_id) if not media.author == request.user: raise exceptions.APIForbidden content_type = get_param(request.META, 'CONTENT_TYPE') mime_type = content_type.split(';')[0] # Form upload if mime_type == 'multipart/form-data': # multipart/form-data; boundary=----pluploadboundaryp15s131vjl18tdnlk1sj11min19p42 file = get_param(request.FILES, 'file') if not file: #TODO: perhaps if there is no file, and there is an error, delete the original? raise exceptions.APIBadRequest('Error uploading file!') media.content.file.save(file.name, file, save=True) else: media.content.create_file_from_data(request.body, mime_type) # media is the generic holder, media.content is the specific # content model (ImageMedia, VideoMedia etc.). media.content.content_state = models.Media.STATE_COMPLETE media.content.save() return APIResponseOK(content=api_serialize(media, request))
def post_media_content(request, cast_id, media_id): cast = get_object(models.Cast, cast_id) media = get_object(models.Media, media_id) if not media.author == request.user: raise exceptions.APIForbidden content_type = get_param(request.META, 'CONTENT_TYPE') mime_type = content_type.split(';')[0] # Form upload if mime_type == 'multipart/form-data': # multipart/form-data; boundary=----pluploadboundaryp15s131vjl18tdnlk1sj11min19p42 file = get_param(request.FILES, 'file') if not file: #TODO: perhaps if there is no file, and there is an error, delete the original? raise exceptions.APIBadRequest('Error uploading file!') media.content.file.save(file.name, file, save=True) mime_type = media.path_to_mimetype(file.name, media.content.MIME_TYPES) else: # create_file_from_data currently is only part of videocontent. # so this won't currently work with imagecontent. # see: locast.models.modelbases, line 332 media.content.create_file_from_data(request.raw_post_data, mime_type) if not mime_type: raise exceptions.APIBadRequest('Invalid file type!') # media is the generic holder, media.content is the specific # content model. media.content.mime_type = mime_type media.content.content_state = models.Media.STATE_COMPLETE media.content.save() # if not content_type: # raise exceptions.APIBadRequest('No content_type specified') #media.content.create_file_from_data(request.raw_post_data, 'video/3gpp') return APIResponseOK(content=api_serialize(media, request))
def get_json(raw_data): data = None try: data = simplejson.loads(raw_data) except ValueError: raise exceptions.APIBadRequest('Invalid JSON') return data
def post_favorite(request, cast_id): cast = get_object(models.Cast, id=cast_id) favorite = get_param(request.POST, 'favorite') if not favorite: raise exceptions.APIBadRequest('Incorrect data posted. Should be favorite=true or favorite=false.') favorite = (favorite in ['true','True']) if favorite: cast.favorite(request.user) else: cast.unfavorite(request.user) return APIResponseOK(content={'is_favorite':cast.is_favorited_by(request.user)})
def get_urgency_rank(request, itin_id=None): query = request.GET.copy() base_query = Q() cast_base_query = models.Cast.get_privacy_q(request) & base_query q = qstranslate.QueryTranslator(models.Cast, CastAPI.ruleset, cast_base_query) try: pre_query = q.filter(query).select_related('author').prefetch_related('media_set').prefetch_related('tags').prefetch_related('itinerary_set').annotate(urgency_score=Sum('tags__urgency_score')).filter(urgency_score__gt=0) if itin_id: pre_query = pre_query.filter(itinerary__id=itin_id) casts = pre_query.order_by('-urgency_score')[:10] except qstranslate.InvalidParameterException, e: raise exceptions.APIBadRequest(e.message)
def post(request, cast_id=None, coll_id=None): if cast_id: raise exceptions.APIBadRequest('Attempting to post with a cast id specified') coll = None if coll_id: coll = get_object(models.Collection, coll_id) cast = cast_from_post(request) if coll: coll.related_casts.add(cast) cast.save() models.UserActivity.objects.create_activity(request.user, cast, 'created') return APIResponseCreated(content=api_serialize(cast, request), location=cast.get_api_uri())
def post(request, cast_id=None, itin_id=None): if cast_id: raise exceptions.APIBadRequest('Attempting to post with a cast id specified') itin = None if itin_id: itin = get_object(models.Itinerary, itin_id) cast = cast_from_post(request) if itin: itin.related_casts.add(cast) cast.save() user = get_object(models.TravelsUser, request.user.id) models.UserActivity.objects.create_activity(user, cast, 'created') return APIResponseCreated(content=api_serialize(cast, request), location=cast.get_api_uri())
def post_media(request, cast_id): data = get_json(request.raw_post_data) cast = get_object(models.Cast, cast_id) if not cast.allowed_edit(request.user): raise exceptions.APIForbidden if 'content_type' in data: content_type = data['content_type'] del data['content_type'] else: raise exceptions.APIBadRequest('missing "content_type"') data['language'] = translation.get_language() data['author'] = request.user.id form_model = None if content_type == 'videomedia': form_model = forms.VideoMediaForm elif content_type == 'imagemedia': form_model = forms.ImageMediaForm elif content_type == 'linkedmedia': form_model = forms.LinkedMediaForm media = form_validate(form_model, data) cast.media_set.add(media) models.UserActivity.objects.create_activity(request.user, media, 'created') # this is needed as for some odd reason, it doesn't return an object with author, modified, etc. # TODO investigate why this is needed # amar: This can be fixed by using media.content media = get_object(models.Media, media.id) return APIResponseCreated(content=api_serialize(media, request), location=media.get_api_uri())
def get(request, itin_id=None): if itin_id: itinerary = get_object(Itinerary, id=itin_id) itinerary_dict = api_serialize(itinerary, request) return APIResponseOK(content=itinerary_dict, total=1) else: query = request.GET.copy() q = qstranslate.QueryTranslator(Itinerary, ItineraryAPI.ruleset) try: objs = q.filter(query) except qstranslate.InvalidParameterException, e: raise exceptions.APIBadRequest(e) objs, total, pg = paginate(objs, query) itinerary_arr = [] for i in objs: itinerary_arr.append(api_serialize(i, request)) return APIResponseOK(content=itinerary_arr, total=total, pg=pg)
def paginate(objs, request_dict): ''' Paginates a collection of objects based in a request object dictionary (request.GET or request.POST) Arguments: objs The collection of objects to paginate request_dict Dictionary of request parameters ''' pg = 1 total = len(objs) # Paginate the results. if 'pagesize' in request_dict: pgsize = None try: pgsize = int(request_dict['pagesize']) if 'page' in request_dict: pg = int(request_dict['page']) if pgsize < 1 or pg < 1: raise ValueError except ValueError, e: raise exceptions.InvalidParameterException('Invalid page number') p = Paginator(objs, pgsize) try: objs = p.page(pg).object_list except EmptyPage: raise exceptions.APIBadRequest('Empty Page')
def get(request, cast_id=None, coll_id=None, format='.json'): # single cast if cast_id: if coll_id: check_collection(cast_id, coll_id) cast = get_object(models.Cast, id=cast_id) if not cast.allowed_access(request.user): raise exceptions.APIForbidden if format == '.json': cast_dict = api_serialize(cast, request) return APIResponseOK(content=cast_dict, total=1) if format == '.html': is_flagged = cast.is_flagged_by(request.user) is_favorited = cast.is_favorited_by(request.user) allowed_edit = cast.allowed_edit(request.user) content = render_to_string('ajax/cast_frontpage.django.html', locals(), context_instance = RequestContext(request)) resp = HttpResponse(content=content) return resp else: raise exceptions.APIBadRequest('Invalid response format') # multiple casts else: base_query = models.Cast.get_privacy_q(request) if coll_id: get_object(models.Collection, id=coll_id) base_query = base_query & Q(collection=coll_id) q = qstranslate.QueryTranslator(models.Cast, ruleset, base_query) query = request.GET.copy() # Need to do some magic to order by popularity, so remove from # the query that will be sent to qstranslate popularity_order = False if 'orderby' in query and query['orderby'] == 'popularity': popularity_order = True del query['orderby'] objs = total = pg = None try: objs = q.filter(query) # popularity magic! if popularity_order: objs = objs.annotate(popularity=Count('favorited_by')).order_by('-popularity') objs, total, pg = paginate(objs, request.GET) except qstranslate.InvalidParameterException, e: raise exceptions.APIBadRequest(e.message) cast_arr = [] for c in objs: cast_arr.append(api_serialize(c, request)) return APIResponseOK(content=cast_arr, total=total, pg=pg)
def cast_from_post(request, cast = None): data = {} # this allows PUT operations to only send the data they # are interested in updating if cast: data = api_serialize(cast) data.update(get_json(request.body)) if not cast: data['author'] = request.user.id else: data['author'] = cast.author.id # Tags won't validate correctly, so store them to set later tags = None if 'tags' in data: tags = data['tags'] del data['tags'] # Location needs to be set manually location = None if 'location' in data: location = data['location'] # check to make sure its within boundary = models.Boundary.objects.get_default_boundary() if boundary and (not Point(location[0], location[1]).within(boundary.bounds)): raise exceptions.APIBadRequest('{"location":"outside default boundary"}') del data['location'] # Modified and created cannot be set if 'modified' in data: del data['modified'] if 'created' in data: del data['created'] if 'favorite' in data: if data['favorite'] == True: cast.favorite(request.user); else: cast.unfavorite(request.user); del data['favorite'] # Maps privacy names to values if 'privacy' in data: data['privacy'] = models.Cast.get_privacy_value(data['privacy']) cast = form_validate(forms.CastAPIForm, data, instance = cast) if not tags == None: # Clear all tags if tags == "": cast.tags.all().delete() cast.set_tags(tags) if location: cast.set_location(location[0], location[1]) cast.save() return cast
def cast_from_post(request, cast = None): data = {} # this allows PUT operations to only send the data they # are interested in updating if cast: data = api_serialize(cast) data.update(get_json(request.raw_post_data)) if not cast: data['author'] = request.user.id else: data['author'] = cast.author.id # Tags won't validate correctly, so store them to set later tags = None if 'tags' in data: tags = data['tags'] del data['tags'] # Location needs to be set manually location = None if 'location' in data: location = data['location'] # check to make sure its within boundry = models.Boundry.objects.get_default_boundry() if boundry and (not Point(location[0], location[1]).within(boundry.bounds)): raise exceptions.APIBadRequest('{"location":"outside default boundry"}') del data['location'] # Modified and created cannot be set if 'modified' in data: del data['modified'] if 'created' in data: del data['created'] # Maps privacy names to values if 'privacy' in data: data['privacy'] = models.Cast.get_privacy_value(data['privacy']) cast = form_validate(forms.CastAPIForm, data, instance = cast) # Necessary to do because of model_translation quirkyness. if 'title' in data and not cast.title: cast.title = data['title'] if 'description' in data and not cast.description: cast.description = data['description'] if not tags == None: # Clear all tags if tags == "": cast.tags.all().delete() if type(tags) == list: tags = [t.lower() for t in tags] else: tags = tags.lower() cast.set_tags(tags) if location: cast.set_location(location[0], location[1]) if 'itinerary_id' in data: print(data['itinerary_id']) cast.itinerary_set.clear() new_itinerary = Itinerary.objects.get(id=data['itinerary_id']) cast.itinerary_set.add(new_itinerary) cast.save() return cast
def get_all(request): try: tags = Tag.objects.order_by('name').all() except qstranslate.InvalidParameterException, e: raise exceptions.APIBadRequest(e.message)