Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pipeline {
// URL for the Kolibri wheel to include.
// FIXME: It would be nice to cache this somehow.
// FIXME: Go back to use an official release once that happens on GitHub for 0.16.
KOLIBRI_WHL_URL = 'https://github.com/endlessm/kolibri-explore-plugin/releases/download/v5.8.0/kolibri-0.16.0.dev0+git.20220928203123-py2.py3-none-any.whl'
KOLIBRI_WHL_URL = 'https://github.com/learningequality/kolibri/releases/download/v0.16.0-alpha12/kolibri-0.16.0a12-py2.py3-none-any.whl'

// Both p4a and gradle cache outputs in the home directory.
// Point it inside the workspace.
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ src/kolibri: clean
sed -i 's/if name.endswith(".py"):/if name.endswith(".py") or name.endswith(".pyc"):/g' src/kolibri/dist/django/db/migrations/loader.py
# Apply kolibri patches
patch -d src/ -p1 < patches/0001-Add-track-progress-information-to-channelimport.patch
patch -d src/ -p1 < patches/0001-Break-up-DynamicWhiteNoise-code.patch

src/evil_kolibri: src/kolibri
mkdir -p src/evil_kolibri/utils
touch src/evil_kolibri/__init__.py
touch src/evil_kolibri/utils/__init__.py
cp src/kolibri/utils/kolibri_whitenoise.py src/evil_kolibri/utils/kolibri_whitenoise.py

.PHONY: apps-bundle.zip
apps-bundle.zip:
Expand Down Expand Up @@ -157,6 +164,7 @@ dist/version.json: needs-version
DIST_DEPS = \
p4a_android_distro \
src/kolibri \
src/evil_kolibri \
src/apps-bundle \
src/collections \
assets/welcomeScreen \
Expand Down
130 changes: 130 additions & 0 deletions patches/0001-Break-up-DynamicWhiteNoise-code.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
From 585771ca61fd6da449cce31425c2ffab322b0dd8 Mon Sep 17 00:00:00 2001
From: Dylan McCall <dylan@endlessos.org>
Date: Thu, 4 May 2023 17:52:48 -0700
Subject: [PATCH] Break up DynamicWhiteNoise code

Instead of generating everything in the initializer, we will use some
more specific functions. This makes it easier to create a subclass of
DynamicWhiteNoise, for example to support platforms that require special
libraries for file access.
---
kolibri/utils/kolibri_whitenoise.py | 61 ++++++++++++++++++++++-------
1 file changed, 46 insertions(+), 15 deletions(-)

diff --git a/kolibri/utils/kolibri_whitenoise.py b/kolibri/utils/kolibri_whitenoise.py
index 828324cf17..4acf1dab21 100644
--- a/kolibri/utils/kolibri_whitenoise.py
+++ b/kolibri/utils/kolibri_whitenoise.py
@@ -8,6 +8,7 @@ from wsgiref.headers import Headers
from django.contrib.staticfiles import finders
from django.core.files.storage import FileSystemStorage
from django.utils._os import safe_join
+from django.utils.functional import cached_property
from six.moves.urllib.parse import parse_qs
from six.moves.urllib.parse import urljoin
from whitenoise import WhiteNoise
@@ -206,33 +207,57 @@ class DynamicWhiteNoise(WhiteNoise):
}
kwargs.update(whitenoise_settings)
super(DynamicWhiteNoise, self).__init__(application, **kwargs)
- self.dynamic_finder = FileFinder(dynamic_locations or [])
+ self._dynamic_locations = dynamic_locations
+ self._writable_locations = writable_locations
+ self._app_paths = app_paths
+
+ if static_prefix is not None and not static_prefix.endswith("/"):
+ raise ValueError("Static prefix must end in '/'")
+ self.static_prefix = static_prefix
+
+ @cached_property
+ def app_path_check(self):
+ # Generate a regex to check if a path patches one of our app paths
+ return (
+ re.compile("^({})".format("|".join(self._app_paths)))
+ if self._app_paths
+ else None
+ )
+
+ @cached_property
+ def dynamic_finder(self):
+ return FileFinder(self._dynamic_locations or [])
+
+ @cached_property
+ def dynamic_check(self):
# Generate a regex to check if a path matches one of our dynamic
# location prefixes
- self.dynamic_check = (
+ return (
re.compile("^({})".format("|".join(self.dynamic_finder.prefixes)))
if self.dynamic_finder.prefixes
else None
)
- self.writable_locations = {}
- if dynamic_locations:
- for index in writable_locations:
+
+ @cached_property
+ def writable_locations(self):
+ result = {}
+ if self._dynamic_locations:
+ for index in self._writable_locations:
try:
prefix, root = self.dynamic_finder.locations[index]
- self.writable_locations[prefix] = root
+ result[prefix] = root
except IndexError:
pass
- self.writable_check = (
+ return result
+
+ @cached_property
+ def writable_check(self):
+ # Generate a regex to check if a path matches a writable location
+ return (
re.compile("^({})".format("|".join(self.writable_locations.keys())))
if self.writable_locations
else None
)
- self.app_path_check = (
- re.compile("^({})".format("|".join(app_paths))) if app_paths else None
- )
- if static_prefix is not None and not static_prefix.endswith("/"):
- raise ValueError("Static prefix must end in '/'")
- self.static_prefix = static_prefix

def __call__(self, environ, start_response):
path = decode_path_info(environ.get("PATH_INFO", ""))
@@ -308,13 +333,16 @@ class DynamicWhiteNoise(WhiteNoise):
headers["Access-Control-Allow-Origin"] = "*"
if self.add_headers_function:
self.add_headers_function(headers, path, url)
- return EndRangeStaticFile(
+ return self._create_end_range_static_file(
path,
headers.items(),
stat_cache=stat_cache,
encodings={"gzip": path + ".gz", "br": path + ".br"},
)

+ def _create_end_range_static_file(self, path, headers, **kwargs):
+ return EndRangeStaticFile(path, headers, **kwargs)
+
def get_streaming_static_file(self, url, remote_baseurl):
"""
Vendor this function from source to substitute in our
@@ -334,8 +362,11 @@ class DynamicWhiteNoise(WhiteNoise):
if self.add_headers_function:
self.add_headers_function(headers, path, url)
headers["Content-Encoding"] = ""
- return StreamingStaticFile(
+ return self._create_streaming_range_static_file(
os.path.join(local_dir, path),
headers,
urljoin(remote_baseurl, url.lstrip("/")),
)
+
+ def _create_streaming_range_static_file(self, path, headers, remote_url, **kwargs):
+ return StreamingStaticFile(path, headers, remote_url, **kwargs)
--
2.40.1

Loading