Skip to content

Commit

Permalink
Import EK channels from USB if present
Browse files Browse the repository at this point in the history
This is a first step to import the content from USB if present instead
of from network, without importing the content, just the metadata.

The list of channels is getted from the network right now, waiting for
the metadata.json definition that could be present in the
KOLIBRI_DATA/content folder:
learningequality/kolibri#9460

https://phabricator.endlessm.com/T33526
  • Loading branch information
danigm committed May 31, 2022
1 parent ff0cc56 commit fe757c6
Showing 1 changed file with 57 additions and 10 deletions.
67 changes: 57 additions & 10 deletions kolibri_explore_plugin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import os

import requests
from django.core.management import call_command
from django.http import FileResponse
from django.http import Http404
from django.http import HttpResponse
Expand All @@ -17,6 +18,9 @@
from django.views.generic.base import View
from kolibri.core.content.api import cache_forever
from kolibri.core.content.api import RemoteChannelViewSet
from kolibri.core.content.models import ContentNode
from kolibri.core.content.models import LocalFile
from kolibri.core.content.utils import paths
from kolibri.core.content.zip_wsgi import add_security_headers
from kolibri.core.content.zip_wsgi import get_embedded_file
from kolibri.core.decorators import cache_no_user_data
Expand Down Expand Up @@ -109,6 +113,31 @@ def get(self, request, app):
return HttpResponse(json_file, content_type="application/json")


def _import_channel_from_usb(channel_id, directory):
"""
Imports the specified channel from the content directory
and then make all the content available.
This function doesn't import the actual content, just the channel
metadata, the content should exists and be present in the
KOLIBRI_CONTENT_FALLBACK_DIRS configuration, in other case the
imported content with this method won't work correctly.
Function to be called as a background call adding it to a task queue
"""
call_command(
"importchannel",
"disk",
channel_id,
directory,
)
# Enable the content after import
nodes = ContentNode.objects.filter(channel_id=channel_id)
files = LocalFile.objects.filter(files__contentnode__channel_id=channel_id)
nodes.update(available=True)
files.update(available=True)


@method_decorator(csrf_exempt, name="dispatch")
class EndlessLearningCollection(View):
COLLECTION_TOKEN = "totoj-jupak"
Expand Down Expand Up @@ -144,10 +173,37 @@ def get(self, request):
json.dumps(jobs_response), content_type="application/json"
)

def import_job(self, task):
content_fallback = paths.get_content_fallback_paths()
if content_fallback:
task.update({"type": "DISKIMPORT"})
# Just getting the first one
directory = os.path.dirname(content_fallback[0])
job_id = queue.enqueue(
_import_channel_from_usb,
task["channel_id"],
directory,
extra_metadata=task,
track_progress=True,
)
else:
task.update({"type": "REMOTEIMPORT"})
job_id = queue.enqueue(
_remoteimport,
task["channel_id"],
task["baseurl"],
extra_metadata=task,
track_progress=True,
cancellable=True,
)

return job_id

def post(self, request):
token = self.COLLECTION_TOKEN

channel_viewset = RemoteChannelViewSet()
# TODO: get the list of channels from USB if exists
channels = channel_viewset._make_channel_endpoint_request(
identifier=token
)
Expand All @@ -161,18 +217,9 @@ def post(self, request):
"channel_name": channel["name"],
"baseurl": self.BASE_URL,
"started_by_username": "endless",
"type": "REMOTEIMPORT",
"PID": pid,
}

job_id = queue.enqueue(
_remoteimport,
task["channel_id"],
task["baseurl"],
extra_metadata=task,
track_progress=True,
cancellable=True,
)
job_id = self.import_job(task)
job_ids.append(job_id)

request.session["job_ids"] = job_ids
Expand Down

0 comments on commit fe757c6

Please sign in to comment.