Merge this project into kolibri-installer-mac
dylanmccall opened this issue · comments
This project is derived from kolibri-installer-mac, although it has several changes to make it work nicely on a GNOME desktop. For the most part, these changes are completely platform neutral and would be valuable contributions to the original codebase. We should merge as much of this project as possible back into kolibri-installer-mac. We will need to keep some existing code here, for example related to data files and very Linux-specific stuff. Ideally we should be able to remove most of the code in this repository and include kolibri-installer-mac as a dependency.
Some notable changes:
- Kolibri backend service is managed in a separate Python process using multiprocessing, along with some simple IPC stuff to get Kolibri's app key and detect when the process has stopped: https://github.com/learningequality/kolibri-installer-gnome/blob/master/src/kolibri_gnome/kolibri_service/kolibri_service.py
- Improvements for Kolibri startup detection, again using a separate Python process. This allows us to better handle when Kolibri fails to start: https://github.com/learningequality/kolibri-installer-gnome/blob/master/src/kolibri_gnome/desktop_launcher/application.py#L121-L143
- Added a mechanism for content extensions. These are discovered from a special location on disk and available to Kolibri using
KOLIBRI_CONTENT_FALLBACK_DIRS
: https://github.com/learningequality/kolibri-installer-gnome/blob/master/src/kolibri_gnome/kolibri_service/content_extensions.py - App lifecycle changes. The pyeverywhere GTK front-end is designed to check for uniqueness, making sure only one instance of an application is running. The startup code was tweaked to support that by implementing an
init_ui
method in pyeverywhere, as well as implementing ahandle_open_file_uris
method which is currently only used in the GTK front-end. Finally, the application does not shut itself down when windows are closed. Instead, we expect this to be managed by the UI toolkit: https://github.com/learningequality/kolibri-installer-gnome/blob/master/src/kolibri_gnome/desktop_launcher/application.py#L275-L289 - Additional WebKit functionality. This app connects to the "decide-policy" and "create" signals in WebKitGTK to support opening new windows in response to certain events: https://github.com/learningequality/kolibri-installer-gnome/blob/master/src/kolibri_gnome/desktop_launcher/application.py#L221-L253
- Added a more thorough check for whether URLs should open in the app, or in an external browser, which takes into account file downloads and special URLs: https://github.com/learningequality/kolibri-installer-gnome/blob/master/src/kolibri_gnome/desktop_launcher/application.py#L309-L320
I just merged in the Windows app work to the kolibri-installer-mac
repo, and would like to start merging in Android as well, so this is a good time to start looking at this!
I think pretty much all these changes would be candidates to merge into the kolibri-installer-mac
codebase. The content fallback dirs is the only thing that maybe feels a bit specific to the Endless version of the app, but if it's a no-op when it's not set, then it's also not harming anything either, so I think it'd be best to have things in one place. Download support is something we definitely want everywhere, and we've had to do the multiple app instance check on Windows as well already.
The main thing that would need changed before merging is that we'd want to refactor the Kolibri service handling to allow for us to use threads when multiprocessing
support is not available, e.g. on Android. We could either have two separate implementations, or, my preference would be to have some KolibriManager
class with various functions like start and stop as methods, then have the Thread
or Process
wrapper init the class and call those methods. Thoughts?
Yeah, that class sounds logical to me. We already have kolibri_service.py, so the threads / processes are abstracted from the rest of the application - so shouldn't be too much trouble to make those share some code that decides whether they're threads or processes, and there's definitely some common functionality that can be deduplicated.
With that said, if I remember correctly I think the only real reason I ended up using multiprocessing
as opposed to threading
here was because of code that imports stuff from (or runs) Kolibri before the main Kolibri backend process we really care about. We end up with various globals being set, and since it's all in the same Python process, that causes a problem when it's time to really run Kolibri. So that would need to be solved for real, and then we probably don't need multiprocessing anyway :)