Commit 482fa9b4 authored by Dietmar Maurer's avatar Dietmar Maurer

start i18n support

parent 7a10f3e6
...@@ -3,7 +3,7 @@ include defines.mk ...@@ -3,7 +3,7 @@ include defines.mk
DESTDIR= DESTDIR=
#SUBDIRS = bin lib www aplinfo #SUBDIRS = bin lib www aplinfo
SUBDIRS = aplinfo PVE bin www SUBDIRS = aplinfo PVE bin www po
DEB=${PACKAGE}_${VERSION}-${PACKAGERELEASE}_all.deb DEB=${PACKAGE}_${VERSION}-${PACKAGERELEASE}_all.deb
......
include ../defines.mk
# msginit -i messages.pot -l de
LINGUAS=de fr
all: $(patsubst %, pve-lang-%.js, $(LINGUAS))
.PHONY: update-po
update-po:
../xgettext.pl -f POTFILES
for i in $(LINGUAS); do echo -n "$$i: ";msgmerge -v $$i.po messages.pot >$$i.po.tmp; mv $$i.po.tmp $$i.po; done
pve-lang-%.js: %.po
./po2js.pl $< >$@.tmp
mv $@.tmp $@
.PHONY: install
install: $(patsubst %, pve-lang-%.js, $(LINGUAS))
install -m 0644 -o www-data -g www-data $^ ${WWWROOTDIR}
clean:
rm -rf *~ *.po.tmp *.js.tmp pve-lang-*.js
\ No newline at end of file
../www/manager/window/LoginWindow.js
../www/manager/qemu/Config.js
# German translations for pve-manager package.
# Copyright (C) 2011 Proxmox Server Solutions GmbH
# This file is distributed under the same license as the pve-manager package.
# Proxmox Support Team <support@proxmox.com>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: pve-manager 2\n"
"POT-Creation-Date: Mon Nov 21 12:40:32 2011\n"
"PO-Revision-Date: 2011-11-21 07:01+0100\n"
"Last-Translator: Proxmox Support Team <support@proxmox.com>\n"
"Language-Team: German\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../www/manager/window/LoginWindow.js:88
msgid "Enter your password"
msgstr "Bitte geben Sie Ihr Passwort ein"
#: ../www/manager/window/LoginWindow.js:65
msgid "Enter your user name"
msgstr "Bitte geben Sie Ihren Benutzernamen ein"
#: ../www/manager/window/LoginWindow.js:103
msgid "Language"
msgstr "Sprache"
#: ../www/manager/window/LoginWindow.js:118
msgid "Login"
msgstr "Anmelden"
#: ../www/manager/window/LoginWindow.js:86
msgid "Password"
msgstr "Passwort"
#: ../www/manager/window/LoginWindow.js:44
msgid "Proxmox VE Login"
msgstr "Proxmox VE Anmeldung"
#: ../www/manager/qemu/Config.js:71
msgid "Shutdown"
msgstr "Herunterfahren"
#: ../www/manager/window/LoginWindow.js:63
msgid "User name"
msgstr "Benutzername"
# French translations for pve-manager package.
# Copyright (C) 2011 Proxmox Server Solutions GmbH
# This file is distributed under the same license as the pve-manager package.
# Proxmox Support Team <support@proxmox.com>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: pve-manager 2\n"
"POT-Creation-Date: Mon Nov 21 12:40:32 2011\n"
"PO-Revision-Date: 2011-11-21 12:22+0100\n"
"Last-Translator: Proxmox Support Team <support@proxmox.com>\n"
"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: ../www/manager/window/LoginWindow.js:88
msgid "Enter your password"
msgstr ""
#: ../www/manager/window/LoginWindow.js:65
msgid "Enter your user name"
msgstr ""
#: ../www/manager/window/LoginWindow.js:103
msgid "Language"
msgstr ""
#: ../www/manager/window/LoginWindow.js:118
msgid "Login"
msgstr ""
#: ../www/manager/window/LoginWindow.js:86
msgid "Password"
msgstr ""
#: ../www/manager/window/LoginWindow.js:44
msgid "Proxmox VE Login"
msgstr ""
#: ../www/manager/qemu/Config.js:71
msgid "Shutdown"
msgstr ""
#: ../www/manager/window/LoginWindow.js:63
msgid "User name"
msgstr ""
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2011 Proxmox Server Solutions GmbH
# This file is distributed under the same license as the pve-manager package.
# Proxmox Support Team <support@proxmox.com>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: pve-manager 2\n"
"POT-Creation-Date: Mon Nov 21 12:40:32 2011\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <support@proxmox.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../www/manager/window/LoginWindow.js:88
msgid "Enter your password"
msgstr ""
#: ../www/manager/window/LoginWindow.js:65
msgid "Enter your user name"
msgstr ""
#: ../www/manager/window/LoginWindow.js:103
msgid "Language"
msgstr ""
#: ../www/manager/window/LoginWindow.js:118
msgid "Login"
msgstr ""
#: ../www/manager/window/LoginWindow.js:86
msgid "Password"
msgstr ""
#: ../www/manager/window/LoginWindow.js:44
msgid "Proxmox VE Login"
msgstr ""
#: ../www/manager/qemu/Config.js:71
msgid "Shutdown"
msgstr ""
#: ../www/manager/window/LoginWindow.js:63
msgid "User name"
msgstr ""
#!/usr/bin/perl -w
use strict;
use Locale::PO;
use JSON;
# current limits:
# - we do not support plural. forms
# - no message content support
my $filename = shift || die "no po file specified\n";
# like FNV32a, but we only return 31 bits (positive numbers)
sub fnv31a {
my ($string) = @_;
my $hval = 0x811c9dc5;
foreach my $c (unpack('C*', $string)) {
$hval ^= $c;
$hval += (
(($hval << 1) ) +
(($hval << 4) ) +
(($hval << 7) ) +
(($hval << 8) ) +
(($hval << 24) ) );
$hval = $hval & 0xffffffff;
}
return $hval & 0x7fffffff;
}
my $aref = Locale::PO->load_file_asarray($filename);
my $catalog;
foreach my $po (@$aref) {
my $qmsgid = $po->msgid;
my $msgid = $po->dequote($qmsgid);
next if !length($msgid); # skip header
my $qmsgstr = $po->msgstr;
my $msgstr = $po->dequote($qmsgstr);
my $digest = fnv31a($msgid);
die "duplicate digest" if $catalog->{$digest};
$catalog->{$digest} = [ $msgstr ];
# later, we can add plural forms to the array
}
my $json = encode_json($catalog);
print <<__EOD
// gettext catalog "$filename"
PVE = { i18n_msgcat: $json }
function fnv31a(text) {
var len = text.length;
var hval = 0x811c9dc5;
for (var i = 0; i < len; i++) {
var c = text.charCodeAt(i);
hval ^= c;
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
hval &= 0x7fffffff;
return hval;
}
function gettext(buf) {
var digest = fnv31a(buf);
var data = PVE.i18n_msgcat[digest];
if (!data) {
return buf;
}
return data[0];
}
__EOD
...@@ -23,6 +23,7 @@ install: ${EXTDATA} ...@@ -23,6 +23,7 @@ install: ${EXTDATA}
install -m 0644 extjs/resources/css/ext-all.css ${WWWEXT4DIR}/resources/css install -m 0644 extjs/resources/css/ext-all.css ${WWWEXT4DIR}/resources/css
install -d ${WWWEXT4DIR}/resources/themes/images install -d ${WWWEXT4DIR}/resources/themes/images
cp -a extjs/resources/themes/images/default ${WWWEXT4DIR}/resources/themes/images cp -a extjs/resources/themes/images/default ${WWWEXT4DIR}/resources/themes/images
cp -a extjs/locale ${WWWEXT4DIR}
chown -R www-data:www-data ${WWWEXT4DIR} chown -R www-data:www-data ${WWWEXT4DIR}
find ${WWWEXT4DIR} -type f -exec chmod -R 0644 '{}' ';' find ${WWWEXT4DIR} -type f -exec chmod -R 0644 '{}' ';'
......
...@@ -182,7 +182,8 @@ Ext.define('PVE.Utils', { statics: { ...@@ -182,7 +182,8 @@ Ext.define('PVE.Utils', { statics: {
language_map: { language_map: {
en: 'English', en: 'English',
de: 'German' de: 'German',
fr: 'French'
}, },
render_language: function (value) { render_language: function (value) {
......
...@@ -25,10 +25,19 @@ sub send_output { ...@@ -25,10 +25,19 @@ sub send_output {
# NOTE: Requests to this page are not authenticated # NOTE: Requests to this page are not authenticated
# so we must be very careful here # so we must be very careful here
my $lang = 'en';
my $r = Apache2::RequestUtil->request(); my $r = Apache2::RequestUtil->request();
my $username; my $username;
my $token = 'null'; my $token = 'null';
if (my $cookie = $r->headers_in->{Cookie}) { if (my $cookie = $r->headers_in->{Cookie}) {
if (my $newlang = ($cookie =~ /(?:^|\s)PVELangCookie=([^;]*)/)[0]) {
if ($newlang =~ m/^[a-f]{2,3}(_A-F{2,3})?$/) {
$lang = $newlang;
}
}
my $ticket = PVE::REST::extract_auth_cookie($cookie); my $ticket = PVE::REST::extract_auth_cookie($cookie);
if (($username = PVE::AccessControl::verify_ticket($ticket, 1))) { if (($username = PVE::AccessControl::verify_ticket($ticket, 1))) {
$token = PVE::AccessControl::assemble_csrf_prevention_token($username); $token = PVE::AccessControl::assemble_csrf_prevention_token($username);
...@@ -48,6 +57,20 @@ if (!PVE) PVE = {}; ...@@ -48,6 +57,20 @@ if (!PVE) PVE = {};
PVE.GUIVersion = '$version'; PVE.GUIVersion = '$version';
PVE.UserName = '$username'; PVE.UserName = '$username';
PVE.CSRFPreventionToken = '$token'; PVE.CSRFPreventionToken = '$token';
_EOJS
my $langfile = "/usr/share/pve-manager/ext4/locale/ext-lang-${lang}.js";
$jssrc .= PVE::Tools::file_get_contents($langfile) if -f $langfile;
my $i18nsrc;
$langfile = "/usr/share/pve-manager/root/pve-lang-${lang}.js";
if (-f $langfile) {
$i18nsrc = PVE::Tools::file_get_contents($langfile);
} else {
$i18nsrc = 'function gettext(buf) { return buf; }';
}
$jssrc .= <<_EOJS;
Ext.require(['*', '$workspace']); Ext.require(['*', '$workspace']);
...@@ -60,8 +83,6 @@ Ext.onReady(function() { Ext.create('$workspace');}); ...@@ -60,8 +83,6 @@ Ext.onReady(function() { Ext.create('$workspace');});
_EOJS _EOJS
$jssrc .= "";
my $page = <<_EOD; my $page = <<_EOD;
<html> <html>
<head> <head>
...@@ -72,9 +93,9 @@ my $page = <<_EOD; ...@@ -72,9 +93,9 @@ my $page = <<_EOD;
<link rel="stylesheet" type="text/css" href="/pve2/ext4/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="/pve2/ext4/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="/pve2/css/ext-pve.css" /> <link rel="stylesheet" type="text/css" href="/pve2/css/ext-pve.css" />
<script type="text/javascript">$i18nsrc</script>
<script type="text/javascript" src="/pve2/ext4/ext-all-debug.js"></script> <script type="text/javascript" src="/pve2/ext4/ext-all-debug.js"></script>
<script type="text/javascript" src="/pve2/ext4/pvemanagerlib.js"></script> <script type="text/javascript" src="/pve2/ext4/pvemanagerlib.js"></script>
<script type="text/javascript">$jssrc</script> <script type="text/javascript">$jssrc</script>
</head> </head>
......
Ext.onReady(function() {
// fixme: how do we implement i18n?
//alert("LOADED LANG DE");
});
\ No newline at end of file
...@@ -68,7 +68,7 @@ Ext.define('PVE.qemu.Config', { ...@@ -68,7 +68,7 @@ Ext.define('PVE.qemu.Config', {
}); });
var shutdownBtn = Ext.create('PVE.button.Button', { var shutdownBtn = Ext.create('PVE.button.Button', {
text: 'Shutdown', text: gettext('Shutdown'),
confirmMsg: "Do you really want to shutdown the VM?", confirmMsg: "Do you really want to shutdown the VM?",
handler: function() { handler: function() {
vm_command('shutdown', { timeout: 30 }); vm_command('shutdown', { timeout: 30 });
......
...@@ -41,7 +41,7 @@ Ext.define('PVE.window.LoginWindow', { ...@@ -41,7 +41,7 @@ Ext.define('PVE.window.LoginWindow', {
closable: false, closable: false,
resizable: false, resizable: false,
layout: 'auto', layout: 'auto',
title: 'Proxmox VE Login', title: gettext('Proxmox VE Login'),
items: [{ items: [{
xtype: 'form', xtype: 'form',
...@@ -49,7 +49,6 @@ Ext.define('PVE.window.LoginWindow', { ...@@ -49,7 +49,6 @@ Ext.define('PVE.window.LoginWindow', {
url: '/api2/extjs/access/ticket', url: '/api2/extjs/access/ticket',
fieldDefaults: { fieldDefaults: {
labelWidth: 70,
labelAlign: 'right' labelAlign: 'right'
}, },
...@@ -61,9 +60,9 @@ Ext.define('PVE.window.LoginWindow', { ...@@ -61,9 +60,9 @@ Ext.define('PVE.window.LoginWindow', {
items: [ items: [
{ {
xtype: 'textfield', xtype: 'textfield',
fieldLabel: 'User name', fieldLabel: gettext('User name'),
name: 'username', name: 'username',
blankText: "Enter your user name", blankText: gettext("Enter your user name"),
listeners: { listeners: {
afterrender: function(f) { afterrender: function(f) {
// Note: only works if we pass delay 1000 // Note: only works if we pass delay 1000
...@@ -84,9 +83,9 @@ Ext.define('PVE.window.LoginWindow', { ...@@ -84,9 +83,9 @@ Ext.define('PVE.window.LoginWindow', {
{ {
xtype: 'textfield', xtype: 'textfield',
inputType: 'password', inputType: 'password',
fieldLabel: 'Password', fieldLabel: gettext('Password'),
name: 'password', name: 'password',
blankText: "Enter your password", blankText: gettext("Enter your password"),
listeners: { listeners: {
specialkey: function(field, e) { specialkey: function(field, e) {
if (e.getKey() === e.ENTER) { if (e.getKey() === e.ENTER) {
...@@ -98,11 +97,25 @@ Ext.define('PVE.window.LoginWindow', { ...@@ -98,11 +97,25 @@ Ext.define('PVE.window.LoginWindow', {
{ {
xtype: 'pveRealmComboBox', xtype: 'pveRealmComboBox',
name: 'realm' name: 'realm'
},
{
xtype: 'pveLanguageSelector',
fieldLabel: gettext('Language'),
value: Ext.util.Cookies.get('PVELangCookie') || 'en',
name: 'lang',
submitValue: false,
listeners: {
change: function(t, value) {
var dt = Ext.Date.add(new Date(), Ext.Date.YEAR, 10);
Ext.util.Cookies.set('PVELangCookie', value, dt);
window.location.reload();
}
}
} }
], ],
buttons: [ buttons: [
{ {
text: 'Login', text: gettext('Login'),
handler: function(){ handler: function(){
me.onLogon(); me.onLogon();
} }
......
...@@ -57,21 +57,19 @@ my $ctime = scalar localtime; ...@@ -57,21 +57,19 @@ my $ctime = scalar localtime;
my $header = << '.'; my $header = << '.';
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) 2008 Proxmox Server Solutions GmbH # Copyright (C) 2011 Proxmox Server Solutions GmbH
# This file is distributed under the same license as the pve-manager package. # This file is distributed under the same license as the pve-manager package.
# Proxmox Support Team <support@proxmox.com>, 2008. # Proxmox Support Team <support@proxmox.com>, 2011.
# #
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: pve-manager 2\n"
. .
$header .= "\"Report-Msgid-Bugs-To: $opts{'msgid-bugs-address'}\\n\"\n" if $opts{'msgid-bugs-address'}; $header .= "\"Report-Msgid-Bugs-To: $opts{'msgid-bugs-address'}\\n\"\n" if $opts{'msgid-bugs-address'};
$header .= "\"POT-Creation-Date: $ctime\\n\"\n"; $header .= "\"POT-Creation-Date: $ctime\\n\"\n";
$header .= << '.'; $header .= << '.';
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <support@proxmox.com>\n" "Language-Team: LANGUAGE <support@proxmox.com>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment