drop the separate i18n backend
This commit is contained in:
parent
874bc085fe
commit
ba17567617
@ -145,7 +145,7 @@ current_catalog: Optional[
|
||||
] = None
|
||||
|
||||
# the current Fluent translation instance
|
||||
current_i18n: Optional[anki.rsbackend.I18nBackend]
|
||||
current_i18n: Optional[anki.rsbackend.RustBackend]
|
||||
|
||||
# path to locale folder
|
||||
locale_folder = ""
|
||||
@ -175,9 +175,9 @@ def set_lang(lang: str, locale_dir: str) -> None:
|
||||
current_catalog = gettext.translation(
|
||||
"anki", gettext_dir, languages=[lang], fallback=True
|
||||
)
|
||||
current_i18n = anki.rsbackend.I18nBackend(
|
||||
preferred_langs=[lang], ftl_folder=ftl_dir
|
||||
)
|
||||
|
||||
current_i18n = anki.rsbackend.RustBackend(ftl_folder=ftl_dir, langs=[lang])
|
||||
|
||||
locale_folder = locale_dir
|
||||
|
||||
|
||||
|
@ -200,12 +200,20 @@ def _on_progress(progress_bytes: bytes) -> bool:
|
||||
|
||||
|
||||
class RustBackend:
|
||||
def __init__(self, server: bool = False) -> None:
|
||||
ftl_folder = os.path.join(anki.lang.locale_folder, "fluent")
|
||||
def __init__(
|
||||
self,
|
||||
ftl_folder: Optional[str] = None,
|
||||
langs: Optional[List[str]] = None,
|
||||
server: bool = False,
|
||||
) -> None:
|
||||
# pick up global defaults if not provided
|
||||
if ftl_folder is None:
|
||||
ftl_folder = os.path.join(anki.lang.locale_folder, "fluent")
|
||||
if langs is None:
|
||||
langs = [anki.lang.currentLang]
|
||||
|
||||
init_msg = pb.BackendInit(
|
||||
locale_folder_path=ftl_folder,
|
||||
preferred_langs=[anki.lang.currentLang],
|
||||
server=server,
|
||||
locale_folder_path=ftl_folder, preferred_langs=langs, server=server,
|
||||
)
|
||||
self._backend = ankirspy.open_backend(init_msg.SerializeToString())
|
||||
self._backend.set_progress_callback(_on_progress)
|
||||
@ -428,19 +436,6 @@ def translate_string_in(
|
||||
return pb.TranslateStringIn(key=key, args=args)
|
||||
|
||||
|
||||
class I18nBackend:
|
||||
def __init__(self, preferred_langs: List[str], ftl_folder: str) -> None:
|
||||
init_msg = pb.I18nBackendInit(
|
||||
locale_folder_path=ftl_folder, preferred_langs=preferred_langs
|
||||
)
|
||||
self._backend = ankirspy.open_i18n(init_msg.SerializeToString())
|
||||
|
||||
def translate(self, key: TR, **kwargs: Union[str, int, float]) -> str:
|
||||
return self._backend.translate(
|
||||
translate_string_in(key, **kwargs).SerializeToString()
|
||||
)
|
||||
|
||||
|
||||
# temporarily force logging of media handling
|
||||
if "RUST_LOG" not in os.environ:
|
||||
os.environ["RUST_LOG"] = "warn,anki::media=debug"
|
||||
|
@ -17,6 +17,7 @@ import anki.lang
|
||||
import aqt.buildinfo
|
||||
from anki import version as _version
|
||||
from anki.consts import HELP_SITE
|
||||
from anki.rsbackend import RustBackend
|
||||
from anki.utils import checksum, isLin, isMac
|
||||
from aqt.qt import *
|
||||
from aqt.utils import locale_dir
|
||||
@ -162,15 +163,15 @@ dialogs = DialogManager()
|
||||
# Qt requires its translator to be installed before any GUI widgets are
|
||||
# loaded, and we need the Qt language to match the gettext language or
|
||||
# translated shortcuts will not work.
|
||||
#
|
||||
# The Qt translator needs to be retained to work.
|
||||
|
||||
# A reference to the Qt translator needs to be held to prevent it from
|
||||
# being immediately deallocated.
|
||||
_qtrans: Optional[QTranslator] = None
|
||||
|
||||
|
||||
def setupLang(
|
||||
def setupLangAndBackend(
|
||||
pm: ProfileManager, app: QApplication, force: Optional[str] = None
|
||||
) -> None:
|
||||
) -> RustBackend:
|
||||
global _qtrans
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, "")
|
||||
@ -218,6 +219,8 @@ def setupLang(
|
||||
if _qtrans.load("qtbase_" + qt_lang, qt_dir):
|
||||
app.installTranslator(_qtrans)
|
||||
|
||||
return anki.lang.current_i18n
|
||||
|
||||
|
||||
# App initialisation
|
||||
##########################################################################
|
||||
@ -465,8 +468,8 @@ environment points to a valid, writable folder.""",
|
||||
if opts.profile:
|
||||
pm.openProfile(opts.profile)
|
||||
|
||||
# i18n
|
||||
setupLang(pm, app, opts.lang)
|
||||
# i18n & backend
|
||||
backend = setupLangAndBackend(pm, app, opts.lang)
|
||||
|
||||
if isLin and pm.glMode() == "auto":
|
||||
from aqt.utils import gfxDriverIsBroken
|
||||
@ -483,7 +486,7 @@ environment points to a valid, writable folder.""",
|
||||
# load the main window
|
||||
import aqt.main
|
||||
|
||||
mw = aqt.main.AnkiQt(app, pm, opts, args)
|
||||
mw = aqt.main.AnkiQt(app, pm, backend, opts, args)
|
||||
if exec:
|
||||
app.exec()
|
||||
else:
|
||||
|
@ -29,6 +29,7 @@ from anki import hooks
|
||||
from anki.collection import _Collection
|
||||
from anki.hooks import runHook
|
||||
from anki.lang import _, ngettext
|
||||
from anki.rsbackend import RustBackend
|
||||
from anki.sound import AVTag, SoundOrVideoTag
|
||||
from anki.storage import Collection
|
||||
from anki.utils import devMode, ids2str, intTime, isMac, isWin, splitFields
|
||||
@ -78,10 +79,12 @@ class AnkiQt(QMainWindow):
|
||||
self,
|
||||
app: QApplication,
|
||||
profileManager: ProfileManagerType,
|
||||
backend: RustBackend,
|
||||
opts: Namespace,
|
||||
args: List[Any],
|
||||
) -> None:
|
||||
QMainWindow.__init__(self)
|
||||
self.backend = backend
|
||||
self.state = "startup"
|
||||
self.opts = opts
|
||||
self.col: Optional[_Collection] = None
|
||||
|
@ -621,52 +621,3 @@ fn media_sync_progress(p: &MediaSyncProgress, i18n: &I18n) -> pb::MediaSyncProgr
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Standalone I18n backend
|
||||
/// This is a hack to allow translating strings in the GUI
|
||||
/// when a collection is not open, and in the future it should
|
||||
/// either be shared with or merged into the backend object.
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
pub struct I18nBackend {
|
||||
i18n: I18n,
|
||||
}
|
||||
|
||||
pub fn init_i18n_backend(init_msg: &[u8]) -> Result<I18nBackend> {
|
||||
let input: pb::I18nBackendInit = match pb::I18nBackendInit::decode(init_msg) {
|
||||
Ok(req) => req,
|
||||
Err(_) => return Err(AnkiError::invalid_input("couldn't decode init msg")),
|
||||
};
|
||||
|
||||
let log = log::terminal();
|
||||
|
||||
let i18n = I18n::new(&input.preferred_langs, input.locale_folder_path, log);
|
||||
|
||||
Ok(I18nBackend { i18n })
|
||||
}
|
||||
|
||||
impl I18nBackend {
|
||||
pub fn translate(&self, req: &[u8]) -> String {
|
||||
let req = match pb::TranslateStringIn::decode(req) {
|
||||
Ok(req) => req,
|
||||
Err(_e) => return "decoding error".into(),
|
||||
};
|
||||
|
||||
self.translate_string(req)
|
||||
}
|
||||
|
||||
fn translate_string(&self, input: pb::TranslateStringIn) -> String {
|
||||
let key = match pb::FluentString::from_i32(input.key) {
|
||||
Some(key) => key,
|
||||
None => return "invalid key".to_string(),
|
||||
};
|
||||
|
||||
let map = input
|
||||
.args
|
||||
.iter()
|
||||
.map(|(k, v)| (k.as_str(), translate_arg_to_fluent_val(&v)))
|
||||
.collect();
|
||||
|
||||
self.i18n.trn(key, map)
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use anki::backend::{
|
||||
init_backend, init_i18n_backend, Backend as RustBackend, I18nBackend as RustI18nBackend,
|
||||
};
|
||||
use anki::backend::{init_backend, Backend as RustBackend};
|
||||
use pyo3::exceptions::Exception;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyBytes;
|
||||
@ -87,30 +85,6 @@ impl Backend {
|
||||
}
|
||||
}
|
||||
|
||||
// I18n backend
|
||||
//////////////////////////////////
|
||||
|
||||
#[pyclass]
|
||||
struct I18nBackend {
|
||||
backend: RustI18nBackend,
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn open_i18n(init_msg: &PyBytes) -> PyResult<I18nBackend> {
|
||||
match init_i18n_backend(init_msg.as_bytes()) {
|
||||
Ok(backend) => Ok(I18nBackend { backend }),
|
||||
Err(e) => Err(exceptions::Exception::py_err(format!("{:?}", e))),
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl I18nBackend {
|
||||
fn translate(&self, input: &PyBytes) -> String {
|
||||
let in_bytes = input.as_bytes();
|
||||
self.backend.translate(in_bytes)
|
||||
}
|
||||
}
|
||||
|
||||
// Module definition
|
||||
//////////////////////////////////
|
||||
|
||||
@ -119,7 +93,6 @@ fn ankirspy(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
m.add_class::<Backend>()?;
|
||||
m.add_wrapped(wrap_pyfunction!(buildhash)).unwrap();
|
||||
m.add_wrapped(wrap_pyfunction!(open_backend)).unwrap();
|
||||
m.add_wrapped(wrap_pyfunction!(open_i18n)).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user