Пример #1
0
def device_counters(data, session):

    device_counters = get_device_counters(
        zone=session.client_device.get_zone())
    return JsonResponse({
        "device_counters": device_counters,
    })
Пример #2
0
def start_video_download(request):
    youtube_ids = OrderedSet(
        simplejson.loads(request.raw_post_data or "{}").get("youtube_ids", []))

    video_files_to_create = [
        id for id in youtube_ids
        if not get_object_or_None(VideoFile, youtube_id=id)
    ]
    video_files_to_update = youtube_ids - OrderedSet(video_files_to_create)

    VideoFile.objects.bulk_create([
        VideoFile(youtube_id=id, flagged_for_download=True)
        for id in video_files_to_create
    ])

    for chunk in break_into_chunks(youtube_ids):
        video_files_needing_model_update = VideoFile.objects.filter(
            download_in_progress=False,
            youtube_id__in=chunk).exclude(percent_complete=100)
        video_files_needing_model_update.update(percent_complete=0,
                                                cancel_download=False,
                                                flagged_for_download=True)

    force_job("videodownload", "Download Videos")
    return JsonResponse({})
Пример #3
0
def retry_video_download(request):
    """Clear any video still accidentally marked as in-progress, and restart the download job.
    """
    VideoFile.objects.filter(download_in_progress=True).update(
        download_in_progress=False, percent_complete=0)
    force_job("videodownload", "Download Videos")
    return JsonResponse({})
Пример #4
0
 def wrapper_fn(*args, **kwargs):
     try:
         return handler(*args, **kwargs)
     except PermissionDenied as pe:
         raise pe  # handled upstream
     except Exception as e:
         return JsonResponse({"error": "Unexpected exception: %s" % e}, status=500)
Пример #5
0
def get_exercise_logs(request):
    """
    Given a list of exercise_ids, retrieve a list of video logs for this user.
    """

    data = simplejson.loads(request.raw_post_data or "[]")
    if not isinstance(data, list):
        return JsonResponse({"error": "Could not load ExerciseLog objects: Unrecognized input data format." % e}, status=500)

    user = request.session["facility_user"]
    responses = []
    for exercise_id in data:
        response = _get_exercise_log_dict(request, user, exercise_id)
        if response:
            responses.append(response)
    return JsonResponse(responses)
Пример #6
0
def get_download_urls(request):
    base_url = "%s://%s" % ("https" if request.is_secure() else "http",
                            get_central_server_host(request))

    # TODO: once Dylan makes all subtitle languages available,
    #   don't hard-code this.
    download_sizes = {
        "en": 19.8,
    }

    downloads = {}
    for locale, size in download_sizes.iteritems():
        urlargs = {
            "version": version.VERSION,
            "platform": "all",
            "locale": locale
        }
        downloads[locale] = {
            "display_name":
            "",  # Will fill in when language list from subtitles is available.
            "size":
            size,
            "url":
            "%s%s" %
            (base_url, reverse("download_kalite_public", kwargs=urlargs)),
        }

    return JsonResponse(downloads)
Пример #7
0
def start_video_download(request):
    """
    API endpoint for launching the videodownload job.
    """
    youtube_ids = OrderedSet(
        simplejson.loads(request.raw_post_data or "{}").get("youtube_ids", []))

    # One query per video (slow)
    video_files_to_create = [
        id for id in youtube_ids
        if not get_object_or_None(VideoFile, youtube_id=id)
    ]
    video_files_to_update = youtube_ids - OrderedSet(video_files_to_create)

    # OK to do bulk_create; cache invalidation triggered via save download
    VideoFile.objects.bulk_create([
        VideoFile(youtube_id=id, flagged_for_download=True)
        for id in video_files_to_create
    ])

    # One query per chunk
    for chunk in break_into_chunks(youtube_ids):
        video_files_needing_model_update = VideoFile.objects.filter(
            download_in_progress=False,
            youtube_id__in=chunk).exclude(percent_complete=100)
        video_files_needing_model_update.update(percent_complete=0,
                                                cancel_download=False,
                                                flagged_for_download=True)

    force_job("videodownload", _("Download Videos"))
    return JsonResponse({})
Пример #8
0
def launch_mplayer(request):
    """
    Launch an mplayer instance in a new thread, to play the video requested via the API.
    """

    if not settings.USE_MPLAYER:
        raise PermissionDenied(
            "You can only initiate mplayer if USE_MPLAYER is set to True.")

    if "youtube_id" not in request.REQUEST:
        return JsonResponseMessageError(_("No youtube_id specified"))

    youtube_id = request.REQUEST["youtube_id"]
    video_id = request.REQUEST["video_id"]
    facility_user = request.session.get("facility_user")

    callback = partial(
        _update_video_log_with_points,
        video_id=video_id,
        youtube_id=youtube_id,
        facility_user=facility_user,
        language=request.language,
    )

    play_video_in_new_thread(youtube_id,
                             content_root=settings.CONTENT_ROOT,
                             callback=callback)

    return JsonResponse({})
Пример #9
0
def save_video_log(request):
    """
    Receives a video_id and relevant data,
    saves it to the currently authorized user.
    """

    # Form does all the data validation, including the video_id
    form = VideoLogForm(data=simplejson.loads(request.raw_post_data))
    if not form.is_valid():
        raise ValidationError(form.errors)
    data = form.data
    user = request.session["facility_user"]
    try:
        videolog = VideoLog.update_video_log(
            facility_user=user,
            video_id=data["video_id"],
            youtube_id=data["youtube_id"],
            total_seconds_watched=data[
                "total_seconds_watched"],  # don't set incrementally, to avoid concurrency issues
            points=data["points"],
            language=data.get("language") or request.language,
        )

    except ValidationError as e:
        return JsonResponseMessageError(_("Could not save VideoLog: %s") % e)

    if "points" in request.session:
        del request.session["points"]  # will be recomputed when needed

    return JsonResponse({
        "points": videolog.points,
        "complete": videolog.complete,
        "messages": {},
    })
Пример #10
0
def get_subtitle_counts(request):
    """
    Sort and return a dict in the following format that gives the count of srt files available by language:
        {"gu": {"count": 45, "name": "Gujarati"}, etc.. }
    """

    # Get the subtitles file
    subtitledata_path = settings.SUBTITLES_DATA_ROOT
    if not os.path.exists(subtitledata_path):
        # could call-command, but return 404 for now.
        raise Http404
    subtitle_counts = json.loads(open(subtitledata_path + "subtitle_counts.json").read())


    # Return an appropriate response
    # TODO(dylan): Use jsonp decorator once it becomes available
    if request.GET.get("callback",None):
        # JSONP response
        response = HttpResponse("%s(%s);" % (request.GET["callback"], json.dumps(subtitle_counts, sort_keys=True)))
        response["Access-Control-Allow-Headers"] = "*"
        response["Content-Type"] = "text/javascript"
        return response

    else:
        # Regular request
        response = JsonResponse(json.dumps(subtitle_counts, sort_keys=True), status=200)
        return response
Пример #11
0
def start_video_download(request):
    """
    API endpoint for launching the videodownload job.
    """
    youtube_ids = OrderedSet(
        simplejson.loads(request.raw_post_data or "{}").get("youtube_ids", []))

    # One query per video (slow)
    video_files_to_create = [
        id for id in youtube_ids
        if not get_object_or_None(VideoFile, youtube_id=id)
    ]

    # OK to do bulk_create; cache invalidation triggered via save download
    for lang_code, lang_youtube_ids in divide_videos_by_language(
            video_files_to_create).iteritems():
        VideoFile.objects.bulk_create([
            VideoFile(youtube_id=id,
                      flagged_for_download=True,
                      language=lang_code) for id in lang_youtube_ids
        ])

    # OK to update all, since we're not setting all props above.
    # One query per chunk
    for chunk in break_into_chunks(youtube_ids):
        video_files_needing_model_update = VideoFile.objects.filter(
            download_in_progress=False,
            youtube_id__in=chunk).exclude(percent_complete=100)
        video_files_needing_model_update.update(percent_complete=0,
                                                cancel_download=False,
                                                flagged_for_download=True)

    force_job("videodownload", _("Download Videos"), locale=request.language)

    return JsonResponse({})
Пример #12
0
def move_to_group(request):
    users = simplejson.loads(request.raw_post_data or "{}").get("users", [])
    group = simplejson.loads(request.raw_post_data or "{}").get("group", "")
    group_update = FacilityGroup.objects.get(pk=group)
    users_to_move = FacilityUser.objects.filter(username__in=users)
    users_to_move.update(group=group_update)
    return JsonResponse({})
Пример #13
0
 def wrapper_fn(request, *args, **kwargs):
     # TODO(bcipolli): send user info in the post data,
     #   allowing cross-checking of user information
     #   and better error reporting
     if "facility_user" not in request.session:
         return JsonResponse({"warning": self.logged_out_message + "  " + _("You must be logged in as a student or teacher to view/save progress.")}, status=500)
     else:
         return handler(request)
Пример #14
0
def check_video_download(request):
    youtube_ids = simplejson.loads(request.raw_post_data or "{}").get("youtube_ids", [])
    percentages = {}
    percentages["downloading"] = job_status("videodownload")
    for id in youtube_ids:
        videofile = get_object_or_None(VideoFile, youtube_id=id) or VideoFile(youtube_id=id)
        percentages[id] = videofile.percent_complete
    return JsonResponse(percentages)
Пример #15
0
def cancel_update_progress(request, process_log):
    """
    API endpoint for getting progress data on downloads.
    """
    process_log.cancel_requested = True
    process_log.save()

    return JsonResponse({})
Пример #16
0
def server_restart(request):
    try:
        server_restart_util(request)
        return JsonResponse({})
    except Exception as e:
        return JsonResponseMessageError(
            _("Unable to restart the server; please restart manually.  Error: %(error_info)s"
              ) % {"error_info": e})
Пример #17
0
def handler_403(request, *args, **kwargs):
    context = RequestContext(request)
    #message = None  # Need to retrieve, but can't figure it out yet.

    if request.is_ajax():
        return JsonResponse({ "error": "You must be logged in with an account authorized to view this page." }, status=403)
    else:
        messages.error(request, mark_safe(_("You must be logged in with an account authorized to view this page.")))
        return HttpResponseRedirect(reverse("login") + "?next=" + request.path)
Пример #18
0
def device_download(data, session):
    """This device is having its own devices downloaded"""
    zone = session.client_device.get_zone()
    devicezones = list(DeviceZone.objects.filter(zone=zone, device__in=data["devices"]))
    devices = [devicezone.device for devicezone in devicezones]
    session.models_downloaded += len(devices) + len(devicezones)

    # Return the objects serialized to the version of the other device.
    return JsonResponse({"devices": serializers.serialize("versioned-json", devices + devicezones, dest_version=session.client_version, ensure_ascii=False)})
Пример #19
0
 def wrapper_fn(request):
     if request.raw_post_data:
         data = simplejson.loads(request.raw_post_data)
     else:
         data = request.GET
     try:
         if "client_nonce" not in data:
             return JsonResponse({"error": "Client nonce must be specified."}, status=500)
         session = SyncSession.objects.get(client_nonce=data["client_nonce"])
         if not session.verified:
             return JsonResponse({"error": "Session has not yet been verified."}, status=500)
         if session.closed:
             return JsonResponse({"error": "Session is already closed."}, status=500)
     except SyncSession.DoesNotExist:
         return JsonResponse({"error": "Session with specified client nonce could not be found."}, status=500)
     response = handler(data, session)
     session.save()
     return response
Пример #20
0
def remove_from_group(request):
    """
    API endpoint for removing users from group
    (from user management page)
    """
    users = simplejson.loads(request.raw_post_data or "{}").get("users", "")
    users_to_remove = FacilityUser.objects.filter(username__in=users)
    users_to_remove.update(group=None)
    return JsonResponse({})
Пример #21
0
def time_set(request):
    """
    Receives a date-time string and sets the system date-time
    RPi only.
    """

    if not settings.ENABLE_CLOCK_SET:
        return JsonResponse(
            {"error": _("This can only be done on Raspberry Pi systems")},
            status=403)

    # Form does all the data validation - including ensuring that the data passed is a proper date time.
    # This is necessary to prevent arbitrary code being run on the system.
    form = DateTimeForm(data=simplejson.loads(request.raw_post_data))
    if not form.is_valid():
        return JsonResponse(
            {
                "error":
                _("Could not read date and time: Unrecognized input data format."
                  )
            },
            status=500)

    try:

        if os.system('sudo date +%%F%%T -s "%s"' % form.data["date_time"]):
            raise PermissionDenied

    except PermissionDenied as e:
        return JsonResponse(
            {
                "error":
                _("System permissions prevented time setting, please run with root permissions"
                  )
            },
            status=500)

    now = datetime.datetime.now().isoformat(" ").split(".")[0]

    return JsonResponse({
        "success":
        _("System time was reset successfully; current system time: %s" % now)
    })
Пример #22
0
def get_exercise_logs(request):
    """
    Given a list of exercise_ids, retrieve a list of video logs for this user.
    """
    data = simplejson.loads(request.raw_post_data or "[]")
    if not isinstance(data, list):
        return JsonResponse(
            {
                "error":
                "Could not load ExerciseLog objects: Unrecognized input data format."
                % e
            },
            status=500)

    user = request.session["facility_user"]
    logs = ExerciseLog.objects \
            .filter(user=user, exercise_id__in=data) \
            .values("exercise_id", "streak_progress", "complete", "points", "struggling", "attempts")
    return JsonResponse(list(logs))
Пример #23
0
def status(request):
    """In order to promote (efficient) caching on (low-powered)
    distributed devices, we do not include ANY user data in our
    templates.  Instead, an AJAX request is made to download user
    data, and javascript used to update the page.

    This view is the view providing the json blob of user information,
    for each page view on the distributed server.

    Besides basic user data, we also provide access to the
    Django message system through this API, again to promote
    caching by excluding any dynamic information from the server-generated
    templates.
    """
    # Build a list of messages to pass to the user.
    #   Iterating over the messages removes them from the
    #   session storage, thus they only appear once.
    message_dicts = []
    for message in get_messages(request):
        # Make sure to escape strings not marked as safe.
        # Note: this duplicates a bit of Django template logic.
        msg_txt = message.message
        if not (isinstance(msg_txt, SafeString)
                or isinstance(msg_txt, SafeUnicode)):
            msg_txt = cgi.escape(unicode(msg_txt))

        message_dicts.append({
            "tags": message.tags,
            "text": msg_txt,
        })

    # Default data
    data = {
        "is_logged_in": request.is_logged_in,
        "registered": request.session["registered"],
        "is_admin": request.is_admin,
        "is_django_user": request.is_django_user,
        "points": 0,
        "current_language": request.session[settings.LANGUAGE_COOKIE_NAME],
        "messages": message_dicts,
    }
    # Override properties using facility data
    if "facility_user" in request.session:  # Facility user
        user = request.session["facility_user"]
        data["is_logged_in"] = True
        data["username"] = user.get_name()
        if "points" not in request.session:
            request.session["points"] = compute_total_points(user)
        data["points"] = request.session["points"]
    # Override data using django data
    if request.user.is_authenticated():  # Django user
        data["is_logged_in"] = True
        data["username"] = request.user.username

    return JsonResponse(data)
Пример #24
0
def save_exercise_log(request):
    """
    Receives an exercise_id and relevant data,
    saves it to the currently authorized user.
    """

    # Form does all data validation, including of the exercise_id
    form = ExerciseLogForm(data=simplejson.loads(request.raw_post_data))
    if not form.is_valid():
        raise Exception(form.errors)
    data = form.data

    # More robust extraction of previous object
    user = request.session["facility_user"]
    (exerciselog, was_created) = ExerciseLog.get_or_initialize(
        user=user, exercise_id=data["exercise_id"])
    previously_complete = exerciselog.complete

    exerciselog.attempts = data[
        "attempts"]  # don't increment, because we fail to save some requests
    exerciselog.streak_progress = data["streak_progress"]
    exerciselog.points = data["points"]
    exerciselog.language = data.get("language") or request.language

    try:
        exerciselog.full_clean()
        exerciselog.save()
    except ValidationError as e:
        return JsonResponse(
            {"error": _("Could not save ExerciseLog") + u": %s" % e},
            status=500)

    if "points" in request.session:
        del request.session["points"]  # will be recomputed when needed

    # Special message if you've just completed.
    #   NOTE: it's important to check this AFTER calling save() above.
    if not previously_complete and exerciselog.complete:
        return JsonResponse({"success": _("You have mastered this exercise!")})

    # Return no message in release mode; "data saved" message in debug mode.
    return JsonResponse({})
Пример #25
0
def start_languagepack_download(request):
    if request.POST:
        data = json.loads(
            request.raw_post_data
        )  # Django has some weird post processing into request.POST, so use raw_post_data
        force_job('languagepackdownload',
                  _("Language pack download"),
                  lang_code=data['lang'],
                  locale=request.language)

        return JsonResponse({'success': True})
Пример #26
0
def model_download(data, session):
    """This device is having its own data downloaded"""
    if "device_counters" not in data:
        return JsonResponse(
            {
                "error": "Must provide device counters.",
                "count": 0
            }, status=500)
    try:
        # Return the objects serialized to the version of the other device.
        result = get_serialized_models(data["device_counters"],
                                       zone=session.client_device.get_zone(),
                                       include_count=True,
                                       dest_version=session.client_version)
    except Exception as e:
        result = {"error": e.message, "count": 0}

    session.models_downloaded += result["count"]
    session.errors += result.has_key("error")
    return JsonResponse(result)
Пример #27
0
def model_upload(data, session):
    """This device is getting data-related objects from another device."""
    if "models" not in data:
        return JsonResponse(
            {
                "error": "Must provide models.",
                "saved_model_count": 0
            },
            status=500)
    try:
        # Unserialize, knowing that the models were serialized by a client of its given version.
        #   dest_version assumed to be this device's version
        result = save_serialized_models(data["models"],
                                        src_version=session.client_version)
    except Exception as e:
        result = {"error": e.message, "saved_model_count": 0}

    session.models_uploaded += result["saved_model_count"]
    session.errors += result.has_key("error")
    return JsonResponse(result)
Пример #28
0
def get_video_logs(request):
    """
    Given a list of video_ids, retrieve a list of video logs for this user.
    """
    data = simplejson.loads(request.raw_post_data or "[]")
    if not isinstance(data, list):
        return JsonResponse(
            {
                "error":
                "Could not load VideoLog objects: Unrecognized input data format."
                % e
            },
            status=500)

    user = request.session["facility_user"]
    logs = VideoLog.objects \
        .filter(user=user, video_id__in=data) \
        .values("video_id", "complete", "total_seconds_watched", "points")

    return JsonResponse(list(logs))
Пример #29
0
def start_languagepack_download(request):
    if request.POST:
        data = json.loads(
            request.raw_post_data
        )  # Django has some weird post processing into request.POST, so use raw_post_data
        call_command_async(
            'languagepackdownload',
            manage_py_dir=settings.PROJECT_PATH,
            language=data['lang']
        )  # TODO: migrate to force_job once it can accept command_args
        return JsonResponse({'success': True})
Пример #30
0
def launch_mplayer(request):
    """Launch an mplayer instance in a new thread, to play the video requested via the API.
    """

    if not settings.USE_MPLAYER:
        raise PermissionDenied(
            "You can only initiate mplayer if USE_MPLAYER is set to True.")

    if "youtube_id" not in request.REQUEST:
        return JsonResponse({"error": "no youtube_id specified"}, status=500)

    youtube_id = request.REQUEST["youtube_id"]
    facility_user = request.session.get("facility_user")
    callback = partial(
        _update_video_log_with_points,
        youtube_id=youtube_id,
        facility_user=facility_user,
    )
    play_video_in_new_thread(youtube_id, callback=callback)

    return JsonResponse({})