Beispiel #1
0
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()
Beispiel #2
0
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()
Beispiel #3
0
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()
Beispiel #4
0
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))
Beispiel #5
0
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)
Beispiel #6
0
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,
            })
Beispiel #7
0
    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)
Beispiel #8
0
    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)
Beispiel #9
0
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))
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
0
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)