add proper pre-loading mechanism
Port language provider to new mechanism.
This commit is contained in:
@@ -16,6 +16,7 @@ from gi.repository import Adw, Gio, GLib, Gtk
|
||||
|
||||
# local, import order is important
|
||||
from .global_state import global_state
|
||||
from .preload_manager import preload_manager
|
||||
from .window import OsInstallerWindow
|
||||
|
||||
APP_ID = 'com.github.p3732.OS-Installer'
|
||||
@@ -42,6 +43,7 @@ class Application(Adw.Application):
|
||||
|
||||
global_state.set_config('version', version)
|
||||
global_state.send_notification = self._send_notification
|
||||
preload_manager.start()
|
||||
|
||||
def _setup_actions(self):
|
||||
actions = [
|
||||
|
||||
@@ -28,6 +28,7 @@ os_installer_sources = [
|
||||
'provider/internet_provider.py',
|
||||
'provider/keyboard_layout_provider.py',
|
||||
'provider/language_provider.py',
|
||||
'provider/preload_manager.py',
|
||||
'provider/timezone_provider.py',
|
||||
'ui/page.py',
|
||||
'ui/pages/choices.py',
|
||||
@@ -49,6 +50,7 @@ os_installer_sources = [
|
||||
'ui/widgets.py',
|
||||
'ui/window.py',
|
||||
'util/installation_scripting.py',
|
||||
'util/preloadable.py',
|
||||
'util/system_calls.py',
|
||||
'util/util.py',
|
||||
]
|
||||
|
||||
@@ -6,6 +6,7 @@ import os
|
||||
from gi.repository import GObject, GnomeDesktop
|
||||
|
||||
from .global_state import global_state
|
||||
from .preloadable import Preloadable
|
||||
|
||||
|
||||
# generated via language_codes_to_x_generator.py
|
||||
@@ -61,23 +62,9 @@ class LanguageInfo(GObject.GObject):
|
||||
self.locale = locale
|
||||
|
||||
|
||||
class LanguageProvider:
|
||||
languages_loaded = False
|
||||
languages_loading_lock = Lock()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
# async load all languages from existing translations
|
||||
localedir = global_state.get_config('localedir')
|
||||
self.languages = global_state.thread_pool.submit(
|
||||
self._get_languages, localedir=localedir)
|
||||
|
||||
|
||||
def _assert_languages_loaded(self):
|
||||
with self.languages_loading_lock:
|
||||
if not self.languages_loaded:
|
||||
self.all_languages, self.suggested, self.other = self.languages.result()
|
||||
self.languages = None
|
||||
self.languages_loaded = True
|
||||
class LanguageProvider(Preloadable) :
|
||||
def __init__(self):
|
||||
Preloadable.__init__(self, self._get_languages)
|
||||
|
||||
def _get_default_locale(self, language):
|
||||
if language in language_to_default_locale:
|
||||
@@ -106,45 +93,44 @@ class LanguageProvider:
|
||||
elif lang := GnomeDesktop.get_language_from_code(lang_code.split('_')[0], localization):
|
||||
return f'{lang} ({lang_code})'
|
||||
|
||||
def _get_languages(self, localedir):
|
||||
def _get_languages(self):
|
||||
localedir = global_state.get_config('localedir')
|
||||
translations = self._get_existing_translations(localedir)
|
||||
|
||||
all_languages = []
|
||||
self.all_languages = []
|
||||
unavailable_languages = []
|
||||
for language_code in translations:
|
||||
locale = self._get_default_locale(language_code)
|
||||
|
||||
if name := self._get_language_name_localized(locale, locale, language_code):
|
||||
language_info = LanguageInfo(name, language_code, locale)
|
||||
all_languages.append(language_info)
|
||||
self.all_languages.append(language_info)
|
||||
else:
|
||||
unavailable_languages.append(language_code)
|
||||
|
||||
if unavailable_languages:
|
||||
print('The following locales are not available on the current system: ',
|
||||
sorted(unavailable_languages))
|
||||
all_languages.sort(key=lambda k: k.name)
|
||||
self.all_languages.sort(key=lambda k: k.name)
|
||||
|
||||
suggested = []
|
||||
other = []
|
||||
self.suggested = []
|
||||
self.other = []
|
||||
suggested_codes = global_state.get_config('suggested_languages')
|
||||
if suggested_codes and len(suggested_codes) > 0:
|
||||
for language_info in all_languages:
|
||||
for language_info in self.all_languages:
|
||||
if language_info.language_code in suggested_codes:
|
||||
suggested.append(language_info)
|
||||
self.suggested.append(language_info)
|
||||
else:
|
||||
other.append(language_info)
|
||||
|
||||
return (all_languages, suggested, other)
|
||||
self.other.append(language_info)
|
||||
|
||||
### public methods ###
|
||||
|
||||
def get_all_languages(self):
|
||||
self._assert_languages_loaded()
|
||||
self.assert_preloaded()
|
||||
return self.all_languages
|
||||
|
||||
def get_fixed_language(self, fixed_language):
|
||||
self._assert_languages_loaded()
|
||||
self.assert_preloaded()
|
||||
|
||||
fixed = [info for info in self.all_languages
|
||||
if info.language_code == fixed_language]
|
||||
@@ -157,11 +143,11 @@ class LanguageProvider:
|
||||
return None
|
||||
|
||||
def get_suggested_languages(self):
|
||||
self._assert_languages_loaded()
|
||||
self.assert_preloaded()
|
||||
return self.suggested
|
||||
|
||||
def get_other_languages(self):
|
||||
self._assert_languages_loaded()
|
||||
self.assert_preloaded()
|
||||
return self.other
|
||||
|
||||
language_provider = LanguageProvider()
|
||||
|
||||
22
src/provider/preload_manager.py
Normal file
22
src/provider/preload_manager.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from threading import Thread
|
||||
|
||||
from .language_provider import language_provider
|
||||
|
||||
|
||||
class PreloadManager:
|
||||
def __init__(self):
|
||||
self.thread = Thread(target=self._preload)
|
||||
|
||||
def _preload(self):
|
||||
language_provider.preload()
|
||||
language_provider.assert_preloaded()
|
||||
|
||||
### public methods ###
|
||||
|
||||
def start(self):
|
||||
self.thread.start()
|
||||
|
||||
|
||||
preload_manager = PreloadManager()
|
||||
39
src/util/preloadable.py
Normal file
39
src/util/preloadable.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from threading import Lock
|
||||
|
||||
from .global_state import global_state
|
||||
|
||||
|
||||
class Preloadable:
|
||||
def __init__(self, preload_func):
|
||||
self.preload_func = preload_func
|
||||
self.preload_started = False
|
||||
self.preloaded = False
|
||||
self.preloading_lock = Lock()
|
||||
|
||||
### public methods ###
|
||||
|
||||
def assert_preloaded(self):
|
||||
if self.preloaded:
|
||||
return
|
||||
|
||||
with self.preloading_lock:
|
||||
if self.preloaded:
|
||||
return
|
||||
|
||||
if not self.preload_started:
|
||||
print('Preloading for preloadable was never started')
|
||||
self.preload()
|
||||
|
||||
# await result
|
||||
self.future.result()
|
||||
self.preloaded = True
|
||||
|
||||
def preload(self):
|
||||
with self.preloading_lock:
|
||||
if self.preload_started:
|
||||
return
|
||||
|
||||
self.future = global_state.thread_pool.submit(self.preload_func)
|
||||
self.preload_started = True
|
||||
Reference in New Issue
Block a user