def device(request, username, device_uid, version=None): d = get_device(request.user, device_uid, request.META.get("HTTP_USER_AGENT", "")) try: data = parse_request_body(request) except (UnicodeDecodeError, ValueError) as e: msg = ("Could not decode device update POST data for " + "user %s: %s") % ( username, request.body.decode("ascii", errors="replace"), ) logger.warning(msg, exc_info=True) return HttpResponseBadRequest(msg) if "caption" in data: if not data["caption"]: return HttpResponseBadRequest("caption must not be empty") d.name = data["caption"] if "type" in data: if not valid_devicetype(data["type"]): return HttpResponseBadRequest("invalid device type %s" % data["type"]) d.type = data["type"] d.save() return HttpResponse()
def device(request, username, device_uid, version=None): d = get_device(request.user, device_uid, request.META.get('HTTP_USER_AGENT', '')) try: data = parse_request_body(request) except (UnicodeDecodeError, ValueError) as e: msg = ('Could not decode device update POST data for ' + 'user %s: %s') % ( username, request.body.decode('ascii', errors='replace'), ) logger.warn(msg, exc_info=True) return HttpResponseBadRequest(msg) if 'caption' in data: if not data['caption']: return HttpResponseBadRequest('caption must not be empty') d.name = data['caption'] if 'type' in data: if not valid_devicetype(data['type']): return HttpResponseBadRequest('invalid device type %s' % data['type']) d.type = data['type'] d.save() return HttpResponse()
def device(request, username, device_uid): d = get_device(request.user, device_uid, request.META.get('HTTP_USER_AGENT', '')) try: data = parse_request_body(request) except (JSONDecodeError, UnicodeDecodeError, ValueError) as e: msg = ('Could not decode device update POST data for ' + 'user %s: %s') % (username, request.body.decode('ascii', errors='replace')) logger.warn(msg, exc_info=True) return HttpResponseBadRequest(msg) if 'caption' in data: if not data['caption']: return HttpResponseBadRequest('caption must not be empty') d.name = data['caption'] if 'type' in data: if not valid_devicetype(data['type']): return HttpResponseBadRequest('invalid device type %s' % data['type']) d.type = data['type'] set_device(request.user, d) return HttpResponse()
def main(request, username): """ API Endpoint for Device Synchronisation """ if request.method == 'GET': return JsonResponse(get_sync_status(request.user)) else: try: actions = parse_request_body(request) except JSONDecodeError as e: return HttpResponseBadRequest(str(e)) synclist = actions.get('synchronize', []) stopsync = actions.get('stop-synchronize', []) try: update_sync_status(request.user, synclist, stopsync) except ValueError as e: return HttpResponseBadRequest(str(e)) except DeviceDoesNotExist as e: return HttpResponseNotFound(str(e)) # reload user to get current sync status user = User.get(request.user._id) return JsonResponse(get_sync_status(user))
def main(request, username, scope): db = get_main_database() udb = get_userdata_database() def user_settings(user): return user, user, db def device_settings(user, uid): device = user.get_device_by_uid(uid) # get it from the user directly so that changes # to settings_obj are reflected in user (bug 1344) settings_obj = user.get_device_by_uid(uid) return user, settings_obj, db def podcast_settings(user, url): podcast = podcast_for_url(url) if not podcast: raise Http404 obj = podcast_state_for_user_podcast(user, podcast) return obj, obj, udb def episode_settings(user, url, podcast_url): episode = episode_for_podcast_url(podcast_url, url) if episode is None: raise Http404 episode_state = episode_state_for_user_episode(user, episode) return episode_state, episode_state, udb models = dict( account = lambda: user_settings(request.user), device = lambda: device_settings(request.user, request.GET.get('device', '')), podcast = lambda: podcast_settings(request.user, request.GET.get('podcast', '')), episode = lambda: episode_settings(request.user, request.GET.get('episode', ''), request.GET.get('podcast', '')) ) if scope not in models.keys(): return HttpResponseBadRequest('undefined scope %s' % scope) try: base_obj, settings_obj, db = models[scope]() except DeviceDoesNotExist as e: return HttpResponseNotFound(str(e)) if request.method == 'GET': return JsonResponse( settings_obj.settings ) elif request.method == 'POST': actions = parse_request_body(request) ret = update_settings(settings_obj, actions) db.save_doc(base_obj) return JsonResponse(ret)
def subscriptions(request, username, device_uid): now = datetime.now() now_ = get_timestamp(now) if request.method == 'GET': try: device = request.user.get_device_by_uid(device_uid) except DeviceDoesNotExist as e: return HttpResponseNotFound(str(e)) since_ = request.GET.get('since', None) if since_ is None: return HttpResponseBadRequest('parameter since missing') try: since = datetime.fromtimestamp(float(since_)) except ValueError: return HttpResponseBadRequest('since-value is not a valid timestamp') changes = get_subscription_changes(request.user, device, since, now) return JsonResponse(changes) elif request.method == 'POST': d = get_device(request.user, device_uid, request.META.get('HTTP_USER_AGENT', '')) if not request.body: return HttpResponseBadRequest('POST data must not be empty') try: actions = parse_request_body(request) except (JSONDecodeError, UnicodeDecodeError, ValueError) as e: msg = (u'Could not decode subscription update POST data for ' + 'user %s: %s') % (username, request.body.decode('ascii', errors='replace')) logger.warn(msg, exc_info=True) return HttpResponseBadRequest(msg) add = actions['add'] if 'add' in actions else [] rem = actions['remove'] if 'remove' in actions else [] add = filter(None, add) rem = filter(None, rem) try: update_urls = update_subscriptions(request.user, d, add, rem) except ValueError, e: return HttpResponseBadRequest(e) return JsonResponse({ 'timestamp': now_, 'update_urls': update_urls, })
def parsed_body(self, request): """ Returns the object parsed from the JSON request body """ if not request.body: raise RequestException('POST data must not be empty') try: # TODO: implementation of parse_request_body can be moved here # after all views using it have been refactored return parse_request_body(request) except (JSONDecodeError, UnicodeDecodeError, ValueError) as e: msg = u'Could not decode request body for user {}: {}'.format( username, request.body.decode('ascii', errors='replace')) logger.warn(msg, exc_info=True) raise RequestException(msg)
def parsed_body(self, request): """ Returns the object parsed from the JSON request body """ if not request.body: raise RequestException("POST data must not be empty") try: # TODO: implementation of parse_request_body can be moved here # after all views using it have been refactored return parse_request_body(request) except (UnicodeDecodeError, ValueError): msg = "Could not decode request body for user {}: {}".format( request.user.username, request.body.decode("ascii", errors="replace")) logger.warning(msg, exc_info=True) raise RequestException(msg)
def main(request, username): """ API Endpoint for Device Synchronisation """ if request.method == "GET": return JsonResponse(get_sync_status(request.user)) else: try: actions = parse_request_body(request) except ValueError as e: return HttpResponseBadRequest(str(e)) synclist = actions.get("synchronize", []) stopsync = actions.get("stop-synchronize", []) try: update_sync_status(request.user, synclist, stopsync) except ValueError as e: return HttpResponseBadRequest(str(e)) except Client.DoesNotExist as e: return HttpResponseNotFound(str(e)) return JsonResponse(get_sync_status(user))
def main(request, username): """ API Endpoint for Device Synchronisation """ if request.method == "GET": return JsonResponse(get_sync_status(request.user)) else: try: actions = parse_request_body(request) except ValueError as e: return HttpResponseBadRequest(str(e)) synclist = actions.get("synchronize", []) stopsync = actions.get("stop-synchronize", []) try: update_sync_status(request.user, synclist, stopsync) except ValueError as e: return HttpResponseBadRequest(str(e)) except Client.DoesNotExist as e: return HttpResponseNotFound(str(e)) return JsonResponse(get_sync_status(request.user))
def episodes(request, username, version=1): version = int(version) now = datetime.utcnow() now_ = get_timestamp(now) ua_string = request.META.get("HTTP_USER_AGENT", "") if request.method == "POST": try: actions = parse_request_body(request) except (UnicodeDecodeError, ValueError) as e: msg = ("Could not decode episode update POST data for " + "user %s: %s") % ( username, request.body.decode("ascii", errors="replace"), ) logger.warning(msg, exc_info=True) return HttpResponseBadRequest(msg) logger.info("start: user %s: %d actions from %s" % (request.user, len(actions), ua_string)) # handle in background if (dsettings.API_ACTIONS_MAX_NONBG is not None and len(actions) > dsettings.API_ACTIONS_MAX_NONBG): bg_handler = dsettings.API_ACTIONS_BG_HANDLER if bg_handler is not None: modname, funname = bg_handler.rsplit(".", 1) mod = import_module(modname) fun = getattr(mod, funname) fun(request.user, actions, now, ua_string) # TODO: return 202 Accepted return JsonResponse({"timestamp": now_, "update_urls": []}) try: update_urls = update_episodes(request.user, actions, now, ua_string) except ValidationError as e: logger.warning( "Validation Error while uploading episode actions " "for user %s: %s", username, str(e), ) return HttpResponseBadRequest(str(e)) except InvalidEpisodeActionAttributes as e: msg = ( "invalid episode action attributes while uploading episode actions for user %s" % (username, )) logger.warning(msg, exc_info=True) return HttpResponseBadRequest(str(e)) logger.info("done: user %s: %d actions from %s" % (request.user, len(actions), ua_string)) return JsonResponse({"timestamp": now_, "update_urls": update_urls}) elif request.method == "GET": podcast_url = request.GET.get("podcast", None) device_uid = request.GET.get("device", None) since_ = request.GET.get("since", None) aggregated = parse_bool(request.GET.get("aggregated", False)) try: since = int(since_) if since_ else None if since is not None: since = datetime.utcfromtimestamp(since) except ValueError: return HttpResponseBadRequest( "since-value is not a valid timestamp") if podcast_url: podcast = get_object_or_404(Podcast, urls__url=podcast_url) else: podcast = None if device_uid: try: user = request.user device = user.client_set.get(uid=device_uid) except Client.DoesNotExist as e: return HttpResponseNotFound(str(e)) else: device = None changes = get_episode_changes(request.user, podcast, device, since, now, aggregated, version) return JsonResponse(changes)
def episodes(request, username, version=1): version = int(version) now = datetime.now() now_ = get_timestamp(now) ua_string = request.META.get('HTTP_USER_AGENT', '') if request.method == 'POST': try: actions = parse_request_body(request) except (JSONDecodeError, UnicodeDecodeError, ValueError) as e: msg = ('Could not decode episode update POST data for ' + 'user %s: %s') % (username, request.body.decode('ascii', errors='replace')) logger.warn(msg, exc_info=True) return HttpResponseBadRequest(msg) logger.info('start: user %s: %d actions from %s' % (request.user._id, len(actions), ua_string)) # handle in background if len(actions) > dsettings.API_ACTIONS_MAX_NONBG: bg_handler = dsettings.API_ACTIONS_BG_HANDLER if bg_handler is not None: modname, funname = bg_handler.rsplit('.', 1) mod = import_module(modname) fun = getattr(mod, funname) fun(request.user, actions, now, ua_string) # TODO: return 202 Accepted return JsonResponse({'timestamp': now_, 'update_urls': []}) try: update_urls = update_episodes(request.user, actions, now, ua_string) except DeviceUIDException as e: logger.warn('invalid device UID while uploading episode actions for user %s', username) return HttpResponseBadRequest(str(e)) except InvalidEpisodeActionAttributes as e: msg = 'invalid episode action attributes while uploading episode actions for user %s' % (username,) logger.warn(msg, exc_info=True) return HttpResponseBadRequest(str(e)) logger.info('done: user %s: %d actions from %s' % (request.user._id, len(actions), ua_string)) return JsonResponse({'timestamp': now_, 'update_urls': update_urls}) elif request.method == 'GET': podcast_url= request.GET.get('podcast', None) device_uid = request.GET.get('device', None) since_ = request.GET.get('since', None) aggregated = parse_bool(request.GET.get('aggregated', False)) try: since = int(since_) if since_ else None except ValueError: return HttpResponseBadRequest('since-value is not a valid timestamp') if podcast_url: podcast = podcast_for_url(podcast_url) if not podcast: raise Http404 else: podcast = None if device_uid: try: device = request.user.get_device_by_uid(device_uid) except DeviceDoesNotExist as e: return HttpResponseNotFound(str(e)) else: device = None changes = get_episode_changes(request.user, podcast, device, since, now_, aggregated, version) return JsonResponse(changes)
def episodes(request, username, version=1): version = int(version) now = datetime.utcnow() now_ = get_timestamp(now) ua_string = request.META.get('HTTP_USER_AGENT', '') if request.method == 'POST': try: actions = parse_request_body(request) except (UnicodeDecodeError, ValueError) as e: msg = ('Could not decode episode update POST data for ' + 'user %s: %s') % (username, request.body.decode('ascii', errors='replace')) logger.warn(msg, exc_info=True) return HttpResponseBadRequest(msg) logger.info('start: user %s: %d actions from %s' % (request.user, len(actions), ua_string)) # handle in background if len(actions) > dsettings.API_ACTIONS_MAX_NONBG: bg_handler = dsettings.API_ACTIONS_BG_HANDLER if bg_handler is not None: modname, funname = bg_handler.rsplit('.', 1) mod = import_module(modname) fun = getattr(mod, funname) fun(request.user, actions, now, ua_string) # TODO: return 202 Accepted return JsonResponse({'timestamp': now_, 'update_urls': []}) try: update_urls = update_episodes(request.user, actions, now, ua_string) except ValidationError as e: logger.warning( 'Validation Error while uploading episode actions ' 'for user %s: %s', username, str(e)) return HttpResponseBadRequest(str(e)) except InvalidEpisodeActionAttributes as e: msg = 'invalid episode action attributes while uploading episode actions for user %s' % ( username, ) logger.warn(msg, exc_info=True) return HttpResponseBadRequest(str(e)) logger.info('done: user %s: %d actions from %s' % (request.user, len(actions), ua_string)) return JsonResponse({'timestamp': now_, 'update_urls': update_urls}) elif request.method == 'GET': podcast_url = request.GET.get('podcast', None) device_uid = request.GET.get('device', None) since_ = request.GET.get('since', None) aggregated = parse_bool(request.GET.get('aggregated', False)) try: since = int(since_) if since_ else None if since is not None: since = datetime.utcfromtimestamp(since) except ValueError: return HttpResponseBadRequest( 'since-value is not a valid timestamp') if podcast_url: podcast = get_object_or_404(Podcast, urls__url=podcast_url) else: podcast = None if device_uid: try: user = request.user device = user.client_set.get(uid=device_uid) except Client.DoesNotExist as e: return HttpResponseNotFound(str(e)) else: device = None changes = get_episode_changes(request.user, podcast, device, since, now, aggregated, version) return JsonResponse(changes)