def get(self, request, username, device_uid): now = datetime.utcnow() now_ = get_timestamp(now) user = request.user try: device = user.client_set.get(uid=device_uid) except Client.DoesNotExist as e: return HttpResponseNotFound(str(e)) try: since = self.get_since(request) except ValueError as e: return HttpResponseBadRequest(str(e)) include_actions = parse_bool(request.GET.get('include_actions', False)) domain = RequestSite(request).domain add, rem, subscriptions = self.get_subscription_changes(user, device, since, now, domain) updates = self.get_episode_changes(user, subscriptions, domain, include_actions, since) return JsonResponse({ 'add': add, 'rem': rem, 'updates': updates, 'timestamp': get_timestamp(now), })
def get(self, request, username, device_uid): now = datetime.utcnow() now_ = get_timestamp(now) user = request.user try: device = user.client_set.get(uid=device_uid) except Client.DoesNotExist as e: return HttpResponseNotFound(str(e)) try: since = self.get_since(request) except ValueError as e: return HttpResponseBadRequest(str(e)) include_actions = parse_bool(request.GET.get("include_actions", False)) domain = RequestSite(request).domain add, rem, subscriptions = self.get_subscription_changes( user, device, since, now, domain) updates = self.get_episode_changes(user, subscriptions, domain, include_actions, since) return JsonResponse({ "add": add, "rem": rem, "updates": updates, "timestamp": get_timestamp(now), })
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 = json.loads(request.raw_post_data) except (JSONDecodeError, UnicodeDecodeError) as e: log('Advanced API: could not decode episode update POST data for user %s: %s' % (username, e)) return HttpResponseBadRequest() try: update_urls = update_episodes(request.user, actions, now, ua_string) except DeviceUIDException as e: import traceback log('could not update episodes for user %s: %s %s: %s' % (username, e, traceback.format_exc(), actions)) return HttpResponseBadRequest(str(e)) 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 = datetime.fromtimestamp(float(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 for_user_opml(request, username): User = get_user_model() user = get_object_or_404(User, username=username) subscriptions = get_subscribed_podcasts(user, only_public=True) if parse_bool(request.GET.get('symbian', False)): subscriptions = map(symbian_opml_changes, [p.podcast for p in subscriptions]) response = render(request, 'user_subscriptions.opml', { 'subscriptions': subscriptions, 'other_user': user }) response['Content-Disposition'] = 'attachment; filename=%s-subscriptions.opml' % username return response
def for_user_opml(request, username): user = User.get_user(username) if not user: raise Http404 subscriptions = user.get_subscribed_podcasts(public=True) if parse_bool(request.GET.get('symbian', False)): subscriptions = map(symbian_opml_changes, subscriptions) response = render(request, 'user_subscriptions.opml', { 'subscriptions': subscriptions, 'other_user': user }) response['Content-Disposition'] = 'attachment; filename=%s-subscriptions.opml' % username return response
def for_user_opml(request, username): User = get_user_model() user = get_object_or_404(User, username=username) subscriptions = get_subscribed_podcasts(user, only_public=True) if parse_bool(request.GET.get('symbian', False)): subscriptions = map(symbian_opml_changes, [p.podcast for p in subscriptions]) response = render(request, 'user_subscriptions.opml', { 'subscriptions': subscriptions, 'other_user': user }) response[ 'Content-Disposition'] = 'attachment; filename=%s-subscriptions.opml' % username return response
def for_user_opml(request, username): User = get_user_model() user = get_object_or_404(User, username=username) subscriptions = get_subscribed_podcasts(user, only_public=True) if parse_bool(request.GET.get("symbian", False)): subscriptions = map(symbian_opml_changes, [p.podcast for p in subscriptions]) response = render( request, "user_subscriptions.opml", {"subscriptions": subscriptions, "other_user": user}, ) response["Content-Disposition"] = ( "attachment; filename=%s-subscriptions.opml" % username ) return response
def updates(request, username, device_uid): now = datetime.now() now_ = get_timestamp(now) 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_ == None: return HttpResponseBadRequest('parameter since missing') try: since = datetime.fromtimestamp(float(since_)) except ValueError: return HttpResponseBadRequest('since-value is not a valid timestamp') include_actions = parse_bool(request.GET.get('include_actions', False)) ret = get_subscription_changes(request.user, device, since, now) domain = RequestSite(request).domain subscriptions = list(device.get_subscribed_podcasts()) podcasts = dict( (p.url, p) for p in subscriptions ) prepare_podcast_data = partial(get_podcast_data, podcasts, domain) ret['add'] = map(prepare_podcast_data, ret['add']) devices = dict( (dev.id, dev.uid) for dev in request.user.devices ) clean_action_data = partial(clean_episode_action_data, user=request.user, devices=devices) # index subscribed podcasts by their Id for fast access podcasts = dict( (p.get_id(), p) for p in subscriptions ) prepare_episode_data = partial(get_episode_data, podcasts, domain, clean_action_data, include_actions) episode_updates = get_episode_updates(request.user, subscriptions, since) ret['updates'] = map(prepare_episode_data, episode_updates) return JsonResponse(ret)
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)