Skip to content

Commit

Permalink
Support i18n with gettext and add the Arabic language
Browse files Browse the repository at this point in the history
  • Loading branch information
zefr0x committed Sep 16, 2023
1 parent 9f9011f commit c0e519b
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 8 deletions.
84 changes: 84 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ strip = true

[dependencies]
gcd = "2.3.0"
gettext-rs = "0.7.0"
notify-rust = { version = "4.8.0", default-features = false, features = ["d"] }
serde = { version = "1.0.183", features = ["derive"] }
single-instance = "0.3.3"
Expand Down
10 changes: 10 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ _default:
lint_all:
pre-commit run --all-files

pot:
# Generate .pot file from sorce code using `xtr` (https://github.com/woboq/tr).
xtr --output po/io.github.zefr0x.ianny.pot --package-name Ianny src/main.rs
sed -i 1,2d po/io.github.zefr0x.ianny.pot

update_po:
for lang in `cat ./po/LINGUAS`; do \
msgmerge --update ./po/${lang}.po ./po/io.github.zefr0x.ianny.pot; \
done

todo:
rg "(.(TODO|FIXME|FIX|HACK|WARN|PREF|NOTE): )|(todo!)" --glob !{{ file_name(justfile()) }}

Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ summary({

# Other meson.build files
subdir('src/')
subdir('po/')


# Install .desktop files
Expand Down
1 change: 1 addition & 0 deletions po/LINGUAS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ar
36 changes: 36 additions & 0 deletions po/ar.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This file is distributed under the same license as the Ianny package.
# zefr0x, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: Ianny VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-15 23:35+0000\n"
"PO-Revision-Date: 2023-09-16 02:48+0300\n"
"Last-Translator: zefr0x\n"
"Language-Team: \n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
"X-Generator: Poedit 3.3.2\n"

#: src/main.rs:198
msgid "Break Time!"
msgstr "وَقتُ اِستِراحَة!"

#: src/main.rs:200
msgid "Take a break for <b>{} minute</b>"
msgid_plural "Take a break for <b>{} minutes</b>"
msgstr[0] "خُذ اِستِراحَة <b>({}د)</b>"
msgstr[1] "خُذ اِستِراحَةً لِمُدَّةِ <b>دَقِيقَةٍ وَاحِدَة ({}د)</b>"
msgstr[2] "خُذ اِستِراحَةً لِمُدَّةِ <b>دَقِيقَتانِ اِثنَتان ({}د)</b>"
msgstr[3] "خُذ اِستِراحَةً لِمُدَّةِ <b>{} دَقِائِق</b>"
msgstr[4] "خُذ اِستِراحَةً لِمُدَّةِ <b>{} دَقِيقَة</b>"
msgstr[5] "خُذ اِستِراحَةً لِمُدَّةِ <b>{} دَقِيقَة</b>"

#: src/main.rs:206
msgid "Ianny"
msgstr "عَيْنِي"
30 changes: 30 additions & 0 deletions po/io.github.zefr0x.ianny.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file is distributed under the same license as the Ianny package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Ianny VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-15 23:35+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: src/main.rs:198
msgid "Break Time!"
msgstr ""

#: src/main.rs:200
msgid "Take a break for <b>{} minute</b>"
msgid_plural "Take a break for <b>{} minutes</b>"
msgstr[0] ""
msgstr[1] ""

#: src/main.rs:206
msgid "Ianny"
msgstr ""
3 changes: 3 additions & 0 deletions po/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
i18n = import('i18n')

i18n.gettext(application_id)
37 changes: 29 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
extern crate gcd;
extern crate gettextrs;
extern crate notify_rust;
extern crate single_instance;
extern crate wayland_client;
extern crate wayland_protocols;
extern crate wayland_protocols_plasma;

mod config;

use gettextrs::{gettext, ngettext};
use single_instance::SingleInstance;
use std::env;
use std::time::Duration;
use std::{
ops::AddAssign,
Expand All @@ -19,6 +20,8 @@ use wayland_protocols::ext::idle_notify::v1::client::{
};
use wayland_protocols_plasma::idle::client::{org_kde_kwin_idle, org_kde_kwin_idle_timeout};

mod config;

const APP_ID: &str = "io.github.zefr0x.ianny";

struct State {
Expand All @@ -45,6 +48,7 @@ impl wayland_client::Dispatch<wl_registry::WlRegistry, ()> for State {
"wl_seat" => {
registry.bind::<wl_seat::WlSeat, _, _>(name, 1, queue_handle, ());
}
// TODO: Only bind to this if both are supported by the compositor.
"ext_idle_notifier_v1" => {
state.idle_notifier = Some(
registry.bind::<ext_idle_notifier_v1::ExtIdleNotifierV1, _, _>(
Expand Down Expand Up @@ -190,14 +194,15 @@ fn show_break_notification(break_time: Duration, notification_sound_hint: notify
use notify_rust::{Hint, Notification, Timeout, Urgency};

let mut handle = Notification::new()
// TODO: Localize messages and adapt words with number.
.summary("Break Time!")
.body(&format!(
"Take a break for <b>{} minutes</b>.",
break_time.as_secs() / 60
.summary(&gettext("Break Time!"))
.body(&ngettext!(
"Take a break for <b>{} minute</b>",
"Take a break for <b>{} minutes</b>",
(break_time.as_secs() / 60) as u32,
(break_time.as_secs() / 60)
))
.icon(APP_ID)
.appname("Ianny")
.appname(&gettext("Ianny"))
.hint(notification_sound_hint)
.hint(Hint::Urgency(Urgency::Critical))
.hint(Hint::Resident(true))
Expand All @@ -224,6 +229,22 @@ fn main() {
std::process::exit(1);
}

// Find and load locale
let app_lang = gettextrs::setlocale(
gettextrs::LocaleCategory::LcAll,
env::var("LC_ALL").unwrap_or_else(|_| {
env::var("LC_CTYPE")
.unwrap_or_else(|_| env::var("LANG").unwrap_or_else(|_| "en_US.UTF-8".to_owned()))
}),
)
.expect("Failed to set locale, please use a valid system locale and make sure it's enabled.");
gettextrs::textdomain(APP_ID).unwrap();
// FIX: Also support /usr/local/share/locale/
gettextrs::bindtextdomain(APP_ID, "/usr/share/locale").unwrap();
gettextrs::bind_textdomain_codeset(APP_ID, "UTF-8").unwrap();

eprintln!("Application locale: {}", String::from_utf8_lossy(&app_lang));

// Load config file
let user_config = config::load_config(config::get_config_file());

Expand Down

0 comments on commit c0e519b

Please sign in to comment.