Skip to content

Commit

Permalink
Translations
Browse files Browse the repository at this point in the history
  • Loading branch information
entonio committed Apr 27, 2024
1 parent e500b2a commit 31f6b9b
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
release/
source/config/*/NOTICE
source/packaging/*/NOTICE
source/config/*/translations.csv
/*.syso
/*.sh
/*.txt
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ Radio predefined
# delete the sequence "[onAir:<any characters>]" from song titles
Trim \[onAir:.+\]
# language (pt, en)
Language en
# store the clicked titles at $HOME/Musicas.sqlite
SQLite $HOME/Musicas.sqlite
Expand Down
17 changes: 16 additions & 1 deletion source/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

"main/libx/taboleta"
"main/libx/translate"

"github.com/getlantern/systray"
)
Expand All @@ -31,6 +32,7 @@ type Settings struct {
Playback string
Radio string
Trim *regexp.Regexp
Language string
SQLite string
Restart []string
Predefined Radio
Expand All @@ -52,14 +54,17 @@ var SETTINGS Settings
var RADIOS []Radio
var LARGEST_TITLE_LENGTH = 20

var musicas = NewMusicas()
var MUSICAS = NewMusicas()

var TRANSLATOR translate.Translator

func Start() {
CONFIG_DIR = findConfigDir()
SETTINGS = readSettings(CONFIG_DIR)
log.Printf("SETTINGS: %+v\n", SETTINGS)
radios := readRadios(CONFIG_DIR)
log.Printf("RADIOS: %+v\n", radios)
TRANSLATOR = translate.NewTranslator(filepath.Join(CONFIG_DIR, "translations.csv"), "pt")

checkAddresses := false
if checkAddresses {
Expand Down Expand Up @@ -187,6 +192,8 @@ func readSettings(configDir string) (settings Settings) {
settings.Radio = value
case "Trim":
settings.Trim, _ = regexp.Compile(value)
case "Language":
settings.Language = value
case "SQLite":
settings.SQLite = value
case "Restart":
Expand Down Expand Up @@ -226,6 +233,14 @@ func readRadios(configDir string) (radios []Radio) {
return
}

func t(key string) string {
return TRANSLATOR.Translate(SETTINGS.Language, key)
}

func tf(key string, parameters ...any) string {
return TRANSLATOR.TranslateFormatted(SETTINGS.Language, key, parameters...)
}

func AsInt(s string, onError int) int {
i, err := strconv.Atoi(s)
if err != nil {
Expand Down
32 changes: 16 additions & 16 deletions source/app/systray.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ func buildUI() {
//systray.SetTemplateIcon(icon, icon)
systray.SetIcon(icon)
//systray.SetTooltip("RádioTaboleta")
setMenuTitle("RádioTaboleta", false)
setMenuTitle(t("RádioTaboleta"), false)

mLower = systray.AddMenuItem("Volume -", "Diminuir o volume")
mLower = systray.AddMenuItem(t("Volume -"), t("Diminuir o volume"))
mLower.Hide()

mSetVol = systray.AddMenuItem("Volume %", "Definir o volume")
mSetVol = systray.AddMenuItem(t("Volume %"), t("Definir o volume"))
mSetVol.Hide()
mSetVolClickedCh := make(chan int)
mSetVolListen := func(mSetVolAtIndex *systray.MenuItem, vol int) {
Expand All @@ -83,7 +83,7 @@ func buildUI() {
}
}

mLouder = systray.AddMenuItem("Volume +", "Aumentar o volume")
mLouder = systray.AddMenuItem(t("Volume +"), t("Aumentar o volume"))
mLouder.Hide()

systray.AddSeparator()
Expand All @@ -93,7 +93,7 @@ func buildUI() {
mServer.Disable()
}

mStatus = systray.AddMenuItem("A iniciar...", "")
mStatus = systray.AddMenuItem(t("A iniciar..."), "")
mStatus.Disable()

mName = systray.AddMenuItem("", "")
Expand All @@ -105,22 +105,22 @@ func buildUI() {

systray.AddSeparator()

mZapOn = systray.AddMenuItem("Zapping", "Percorrer as estações")
mZapOn = systray.AddMenuItem(t("Zapping"), t("Percorrer as estações"))
mZapOn.Hide()

mZapOff = systray.AddMenuItem("Zapping", "Parar de percorrer as estações")
mZapOff = systray.AddMenuItem(t("Zapping"), t("Parar de percorrer as estações"))
mZapOff.Check()
mZapOff.Hide()

mResume = systray.AddMenuItem("Retomar", "Iniciar o rádio")
mResume = systray.AddMenuItem(t("Retomar"), t("Iniciar o rádio"))
mResume.Hide()

mPause = systray.AddMenuItem("Pausa", "Parar o rádio")
mPause = systray.AddMenuItem(t("Pausa"), t("Parar o rádio"))
mPause.Hide()

systray.AddSeparator()

mClose := systray.AddMenuItem("Sair", "Fechar")
mClose := systray.AddMenuItem(t("Sair"), t("Fechar"))
systray.AddSeparator()

mRadioClickedCh := make(chan int)
Expand Down Expand Up @@ -149,7 +149,7 @@ func buildUI() {
latest = item
}
}
mRadioAtIndex := systray.AddMenuItem(radio.Name, "Mudar para "+radio.Name)
mRadioAtIndex := systray.AddMenuItem(radio.Name, tf("Mudar para %s", radio.Name))
latest = item
mRadioListen(mRadioAtIndex, i)
mRadios = append(mRadios, mRadioAtIndex)
Expand Down Expand Up @@ -179,7 +179,7 @@ func buildUI() {
clipboard.WriteAll(displayedTitle)
split := strings.SplitN(displayedTitle, " - ", 2)
if len(split) == 2 {
musicas.Add(split[0], split[1])
MUSICAS.Add(split[0], split[1])
}
}

Expand Down Expand Up @@ -307,17 +307,17 @@ func updateUI() {
mZapOn.Hide()
mZapOff.Show()
}
mStatus.SetTitle(fmt.Sprintf("Vol %d%%, %d kbps", currentVolume, status.BitRate))
mStatus.SetTitle(tf("Vol %d%%, %d kbps", currentVolume, status.BitRate))
} else {
mResume.Show()
mPause.Hide()
mZapOn.Hide()
mZapOff.Hide()
mStatus.SetTitle(fmt.Sprintf("Vol %d%%, em pausa", currentVolume))
mStatus.SetTitle(tf("Vol %d%%, em pausa", currentVolume))
if len(displayedName) > 0 {
setMenuTitle(displayedName, false)
} else {
setMenuTitle("Em pausa", false)
setMenuTitle(t("Em pausa"), false)
}
}
mSetVol.Show()
Expand Down Expand Up @@ -378,7 +378,7 @@ func updateUI() {
mVols2[v2].Check()
*/
} else {
mStatus.SetTitle(fmt.Sprintf("Não contactável"))
mStatus.SetTitle(t("Não contactável"))
if len(status.ErrorAddress) > 0 {
for i, mRadio := range mRadios {
if status.ErrorAddress == RADIOS[i].Address {
Expand Down
4 changes: 4 additions & 0 deletions source/build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/sh

current=5
cp -va ../NOTICE config/win/
cp -va resources/$current.ico config/win/systray.ico
Expand All @@ -8,3 +9,6 @@ cp -va ../NOTICE config/mac/
cp -va resources/$current.icns config/mac/menubar.icns
cp -va ../NOTICE packaging/mac/Resources/
cp -va resources/$current.icns packaging/mac/Resources/app.icns

cp -va resources/translations.csv config/win/
cp -va resources/translations.csv config/mac/
3 changes: 1 addition & 2 deletions source/config/mac/Settings.taboleta
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
Mpd localhost:32123
Volume 9
Zapping 10
Playback let
Radio let
Trim \[onAir:.+\]
Language pt
SQLite $HOME/Dropbox/Musicas.sqlite
Restart killall -9 mpd
107 changes: 107 additions & 0 deletions source/libx/translate/translate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package translate

import (
"encoding/csv"
"fmt"
"log"
"os"
"strings"
)

type Translator struct {
Languages []string
keyLanguage string
translations map[string]map[string]string
}

func NewTranslator(file string, keyLanguage string) Translator {
keyLanguage = languageCode(keyLanguage)
languages, translations, _ := read(file, keyLanguage)
return Translator{Languages: languages, keyLanguage: keyLanguage, translations: translations}
}

func (self Translator) TranslateFormatted(language string, key string, parameters ...any) string {
return fmt.Sprintf(self.Translate(language, key), parameters...)
}

func (self Translator) Translate(language string, key string) string {
if len(language) > 0 && language != self.keyLanguage {
if self.translations != nil {
translations := self.translations[language]
if translations != nil {
return translations[key]
}
}
}
return key
}

func languageCode(s string) string {
return strings.ToLower(strings.TrimSpace(s))
}

func read(path string, keyLanguage string) (languages []string, translations map[string]map[string]string, err error) {
file, err := os.Open(path)
if err != nil {
log.Printf("Error reading %s: %s\n", path, err)
return
}
defer file.Close()

reader := csv.NewReader(file)
reader.Comma = ';'
records, err := reader.ReadAll()
if err != nil {
log.Printf("Error reading %s: %s\n", path, err)
return
}
if len(records) < 2 {
log.Printf("Transalations file %s is empty\n", path)
return
}
if len(records[0]) > 0 {
bom := string([]byte{239, 187, 191})
records[0][0] = strings.TrimPrefix(records[0][0], bom)
}

keyIndex := -1
languages = records[0]
for i, language := range languages {
language = languageCode(language)
fmt.Printf("[%+v][%+v][%+v][%+v][%+v]\n", keyLanguage, language, []byte(language), len(language),
language == keyLanguage)
if language == keyLanguage {
keyIndex = i
}
languages[i] = language
}

if keyIndex < 0 {
log.Printf("Transalations file %s doesn't contain the key language (%s)\n", path, keyLanguage)
return
}

translations = make(map[string]map[string]string)
for _, row := range records[1:] {
if len(row) < keyIndex {
continue
}
key := row[keyIndex]
for i, translation := range row {
if i == keyIndex {
continue
}
if i > len(languages) {
continue
}
language := languages[i]
lt := translations[language]
if lt == nil {
lt = make(map[string]string)
}
lt[key] = translation
translations[language] = lt
}
}
return
}
21 changes: 21 additions & 0 deletions source/resources/translations.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
PT;EN
Volume -;Volume -
Diminuir o volume;Turn volume down
Volume %;Volume %
Definir o volume;Set volume
Volume +;Volume +
Aumentar o volume;Turn volume up
A iniciar...;Starting...
Vol %d%%, %d kbps;Vol %d%%, %d kbps
Vol %d%%, em pausa;Vol %d%%, paused
Iniciar o rádio;Start radio
Pausa;Pause
Em pausa;Paused
Retomar;Resume
Mudar para %s;Switch to %s
Zapping;Zapping
Percorrer as estações;Loop through stations
Parar de percorrer as estações;Stop looping through stations
Parar o rádio;Stop radio
Sair;Exit
Fechar;Close

0 comments on commit 31f6b9b

Please sign in to comment.