-
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathkolibri_plugin.py
More file actions
116 lines (93 loc) · 3.67 KB
/
kolibri_plugin.py
File metadata and controls
116 lines (93 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import logging
from android_utils import is_active_network_metered
from android_utils import os_user
from android_utils import share_by_intent
from django.utils import timezone
from jnius import autoclass
from kolibri.core.content.hooks import ShareFileHook
from kolibri.core.device.hooks import CheckIsMeteredHook
from kolibri.core.device.hooks import GetOSUserHook
from kolibri.core.tasks.hooks import JobHook
from kolibri.core.tasks.job import Priority
from kolibri.plugins import KolibriPluginBase
from kolibri.plugins.hooks import register_hook
Locale = autoclass("java.util.Locale")
Task = autoclass("org.learningequality.Task")
TaskWorker = autoclass("org.learningequality.Kolibri.task.TaskWorkerImpl")
PROGRESS_LIMIT = 10000
logger = logging.getLogger(__name__)
class AndroidApp(KolibriPluginBase):
pass
@register_hook
class AndroidGetOSUserHook(GetOSUserHook):
def get_os_user(self, auth_token=None):
return os_user(auth_token)
@register_hook
class AndroidCheckIsMeteredHook(CheckIsMeteredHook):
def check_is_metered(self):
try:
return bool(is_active_network_metered())
except Exception:
return False
@register_hook
class AndroidShareFileHook(ShareFileHook):
def share_file(self, filename, message):
return share_by_intent(filename, message)
@register_hook
class AndroidJobHook(JobHook):
def schedule(
self,
job,
orm_job,
):
if orm_job.id:
delay = (
max(0, (orm_job.scheduled_time - timezone.now()).total_seconds())
if orm_job.scheduled_time
else 0
)
high_priority = orm_job.priority <= Priority.HIGH
# Android has no mechanism for scheduling a limited run of repeating tasks,
# so we just schedule it as a one-off task, and then re-schedule it when the task
# is completed.
# We could use WorkManager's PeriodicWorkRequest, but this gives us more control
# over execution, and also allows us to use the same mechanism for all tasks.
# Similarly, retry_intervals are handled by the schedule mechanism, so we don't
# leverage Android's retry mechanism either.
logger.info(
"Scheduling task {} for job {} with delay {} and high priority {}".format(
job.func, orm_job.id, delay, high_priority
)
)
request_id = Task.enqueueOnce(
orm_job.id,
delay,
high_priority,
job.func,
job.long_running,
)
job.update_worker_info(extra=request_id)
def update(self, job, orm_job, state=None, **kwargs):
currentLocale = Locale.getDefault().toLanguageTag()
status = job.status(currentLocale)
if status:
if job.total_progress:
progress = job.progress
total_progress = job.total_progress
else:
progress = -1
total_progress = -1
# avoid passing integers that are too large
# PROGRESS_LIMIT gives sufficient precision for a % progress calculation
if total_progress > PROGRESS_LIMIT:
progress = PROGRESS_LIMIT * progress // total_progress
total_progress = PROGRESS_LIMIT
TaskWorker.notifyLocalObservers(
status.title,
status.text,
progress,
total_progress,
)
def clear(self, job, orm_job):
logger.info("Clearing task {} for job {}".format(job.func, orm_job.id))
Task.clear(orm_job.id)