def __init__(self, facility, *args, **kwargs): super(FacilityUserForm, self).__init__(*args, **kwargs) self.fields["default_language"].choices = [ (lang_code, get_language_name(lang_code)) for lang_code in get_installed_language_packs() ] # Select the initial default language, # but only if we're not in the process of updating it to something else. if not self.fields[ "default_language"].initial and "default_language" not in self.changed_data: self.fields["default_language"].initial = ( self.instance and self.instance.default_language) or get_default_language() # Passwords only required on new, not on edit self.fields["password_first"].required = self.instance.pk == "" self.fields["password_recheck"].required = self.instance.pk == "" # Across POST and GET requests self.fields["zone_fallback"].initial = facility.get_zone() self.fields["facility"].initial = facility self.fields["facility"].queryset = Facility.objects.by_zone( facility.get_zone()) self.fields["group"].queryset = FacilityGroup.objects.filter( facility=facility)
def delete_language_pack(request): """ API endpoint for deleting language pack which fetches the language code (in delete_id) which has to be deleted. That particular language folders are deleted and that language gets removed. """ lang_code = simplejson.loads(request.body or "{}").get("lang") delete_language(lang_code) return JsonResponse({ "success": _("Successfully deleted language pack for %(lang_name)s.") % { "lang_name": get_language_name(lang_code) } })
def start_languagepack_download(request): if not request.method == 'POST': raise Exception(_("Must call API endpoint with POST verb.")) data = json.loads( request.raw_post_data ) # Django has some weird post processing into request.POST, so use .body lang_code = lcode_to_ietf(data['lang']) call_command_async('retrievecontentpack', 'download', lang_code) return JsonResponseMessageSuccess( _("Successfully started language pack download for %(lang_name)s.") % {"lang_name": get_language_name(lang_code)})
def __init__(self, facility, *args, **kwargs): super(FacilityUserForm, self).__init__(*args, **kwargs) self.fields["default_language"].choices = [(lang_code, get_language_name(lang_code)) for lang_code in get_installed_language_packs()] # Select the initial default language, # but only if we're not in the process of updating it to something else. if not self.fields["default_language"].initial and "default_language" not in self.changed_data: self.fields["default_language"].initial = (self.instance and self.instance.default_language) or get_default_language() # Passwords only required on new, not on edit self.fields["password_first"].required = self.instance.pk == "" self.fields["password_recheck"].required = self.instance.pk == "" # Across POST and GET requests self.fields["zone_fallback"].initial = facility.get_zone() self.fields["facility"].initial = facility self.fields["facility"].queryset = Facility.objects.by_zone(facility.get_zone()) self.fields["group"].queryset = FacilityGroup.objects.filter(facility=facility)
def delete_language_pack(request): """ API endpoint for deleting language pack which fetches the language code (in delete_id) which has to be deleted. That particular language folders are deleted and that language gets removed. """ lang_code = simplejson.loads(request.body or "{}").get("lang") delete_language(lang_code) return JsonResponse({"success": _("Successfully deleted language pack for %(lang_name)s.") % {"lang_name": get_language_name(lang_code)}})
def start_languagepack_download(request): if not request.method == 'POST': raise Exception(_("Must call API endpoint with POST verb.")) data = json.loads(request.raw_post_data) # Django has some weird post processing into request.POST, so use .body lang_code = lcode_to_ietf(data['lang']) call_command_async('retrievecontentpack', 'download', lang_code) return JsonResponseMessageSuccess(_("Successfully started language pack download for %(lang_name)s.") % {"lang_name": get_language_name(lang_code)})
def update_content_availability(content_list, language="en", channel="khan"): # Loop through all content items and put thumbnail urls, content urls, # and subtitle urls on the content dictionary, and list all languages # that the content is available in. # turn this whole function into a generator try: contents_folder = os.listdir(django_settings.CONTENT_ROOT) except OSError: contents_folder = [] subtitle_langs = {} if os.path.exists(get_subtitle_file_path()): for (dirpath, dirnames, filenames) in os.walk(get_subtitle_file_path()): # Only both looking at files that are inside a 'subtitles' directory if os.path.basename(dirpath) == "subtitles": lc = os.path.basename(os.path.dirname(dirpath)) for filename in filenames: if filename in subtitle_langs: subtitle_langs[filename].append(lc) else: subtitle_langs[filename] = [lc] subtitle_language_dir = language.replace("-", "_") for content in content_list: # Some nodes are duplicated, but they require the same information # regardless of where they appear in the topic tree update = {} if content.get("kind") == "Exercise": # Databases have been pre-filtered to only contain existing exercises. # Exercises have been pre-marked as available as well. # Assume if the assessment items have been downloaded, then everything is hunky dory. continue elif content.get("kind") == "Topic": # Ignore topics, as we only want to update their availability after we have updated the rest. continue else: file_id = content.get("youtube_id") default_thumbnail = create_thumbnail_url(content.get("id")) format = content.get("format", "") filename = file_id + "." + format if file_id else None # Get list of subtitle language codes currently available subtitle_lang_codes = subtitle_langs.get("{id}.vtt".format(id=content.get("id")), []) if filename and filename in contents_folder: update["files_complete"] = 1 # File for this language is available and downloaded, so let's stamp the file size on it! update["size_on_disk"] = get_local_video_size(content.get("youtube_id")) else: # The video file for this content item does not exist. Set the files_complete and size_on_disk to 0 if content.get("files_complete"): update["files_complete"] = 0 if content.get("size_on_disk"): update["size_on_disk"] = 0 # Set file_id to None as a flag that this file should not be used in any later processing. file_id = None if not file_id and subtitle_language_dir in subtitle_lang_codes and (content.get("id") + "." + format in contents_folder): # The file is not available in this language, but it is available in English and can be subtitled file_id = content.get("id") filename = file_id + "." + format if file_id: # We have a valid file_id (i.e. some file that we can use is available locally) update["available"] = True thumbnail = create_thumbnail_url(file_id) or default_thumbnail update["content_urls"] = { "stream": django_settings.CONTENT_URL + filename, "stream_type": "{kind}/{format}".format(kind=content.get("kind").lower(), format=format), "thumbnail": thumbnail, } elif django_settings.BACKUP_VIDEO_SOURCE: # If the file is not available locally, but we are running the demo server, we want to serve the files # from the Internet. file_id = content.get("youtube_id", content.get("id")) update["available"] = True update["content_urls"] = { "stream": django_settings.BACKUP_VIDEO_SOURCE.format(youtube_id=file_id, video_format=format), "stream_type": "{kind}/{format}".format(kind=content.get("kind").lower(), format=format), "thumbnail": django_settings.BACKUP_VIDEO_SOURCE.format(youtube_id=file_id, video_format="png"), } if update.get("available"): # Don't bother doing this work if the video is not available at all # Generate subtitle URLs for any subtitles that do exist for this content item subtitle_urls = [{ "code": lc, "url": django_settings.STATIC_URL + "srt/{code}/subtitles/{id}.vtt".format(code=lc, id=content.get("id")), "name": get_language_name(lc) } for lc in subtitle_lang_codes] # Sort all subtitle URLs by language code update["subtitle_urls"] = sorted(subtitle_urls, key=lambda x: x.get("code", "")) # Content is currently flagged as available, but is not. Flag as unavailable. if content.get("available") and "available" not in update: update["available"] = False yield content.get("path"), update
def update_content_availability(content_list, language="en", channel="khan"): # Loop through all content items and put thumbnail urls, content urls, # and subtitle urls on the content dictionary, and list all languages # that the content is available in. # turn this whole function into a generator try: contents_folder = os.listdir(django_settings.CONTENT_ROOT) except OSError: contents_folder = [] subtitle_langs = {} if os.path.exists(get_subtitle_file_path()): for (dirpath, dirnames, filenames) in os.walk(get_subtitle_file_path()): # Only both looking at files that are inside a 'subtitles' directory if os.path.basename(dirpath) == "subtitles": lc = os.path.basename(os.path.dirname(dirpath)) for filename in filenames: if filename in subtitle_langs: subtitle_langs[filename].append(lc) else: subtitle_langs[filename] = [lc] subtitle_language_dir = language.replace("-", "_") for content in content_list: # Some nodes are duplicated, but they require the same information # regardless of where they appear in the topic tree update = {} if content.get("kind") == "Exercise": # Databases have been pre-filtered to only contain existing exercises. # Exercises have been pre-marked as available as well. # Assume if the assessment items have been downloaded, then everything is hunky dory. continue elif content.get("kind") == "Topic": # Ignore topics, as we only want to update their availability after we have updated the rest. continue else: file_id = content.get("youtube_id") default_thumbnail = create_thumbnail_url(content.get("id")) format = content.get("format", "") filename = file_id + "." + format if file_id else None # Get list of subtitle language codes currently available subtitle_lang_codes = subtitle_langs.get( "{id}.vtt".format(id=content.get("id")), []) if filename and filename in contents_folder: update["files_complete"] = 1 # File for this language is available and downloaded, so let's stamp the file size on it! update["size_on_disk"] = get_local_video_size( content.get("youtube_id")) else: # The video file for this content item does not exist. Set the files_complete and size_on_disk to 0 if content.get("files_complete"): update["files_complete"] = 0 if content.get("size_on_disk"): update["size_on_disk"] = 0 # Set file_id to None as a flag that this file should not be used in any later processing. file_id = None if not file_id and subtitle_language_dir in subtitle_lang_codes and ( content.get("id") + "." + format in contents_folder): # The file is not available in this language, but it is available in English and can be subtitled file_id = content.get("id") filename = file_id + "." + format if file_id: # We have a valid file_id (i.e. some file that we can use is available locally) update["available"] = True thumbnail = create_thumbnail_url(file_id) or default_thumbnail update["content_urls"] = { "stream": django_settings.CONTENT_URL + filename, "stream_type": "{kind}/{format}".format(kind=content.get("kind").lower(), format=format), "thumbnail": thumbnail, } elif django_settings.BACKUP_VIDEO_SOURCE: # If the file is not available locally, but we are running the demo server, we want to serve the files # from the Internet. file_id = content.get("youtube_id", content.get("id")) update["available"] = True update["content_urls"] = { "stream": django_settings.BACKUP_VIDEO_SOURCE.format( youtube_id=file_id, video_format=format), "stream_type": "{kind}/{format}".format(kind=content.get("kind").lower(), format=format), "thumbnail": django_settings.BACKUP_VIDEO_SOURCE.format( youtube_id=file_id, video_format="png"), } if update.get("available"): # Don't bother doing this work if the video is not available at all # Generate subtitle URLs for any subtitles that do exist for this content item subtitle_urls = [{ "code": lc, "url": django_settings.STATIC_URL + "srt/{code}/subtitles/{id}.vtt".format( code=lc, id=content.get("id")), "name": get_language_name(lc) } for lc in subtitle_lang_codes] # Sort all subtitle URLs by language code update["subtitle_urls"] = sorted( subtitle_urls, key=lambda x: x.get("code", "")) # Content is currently flagged as available, but is not. Flag as unavailable. if content.get("available") and "available" not in update: update["available"] = False yield content.get("path"), update