node_modules/
doc/
client/assets/kiwi.js
-client/assets/kiwi.min.js\r
+client/assets/kiwi.min.js
+client/assets/locales/*.json
+!client/assets/locales/translations.json
client/index.html
kiwi.log
kiwiirc.pid
--- /dev/null
+\r
+#: client/assets/src/applets/chanlist.js\r
+msgid "Channel Name"\r
+#msgstr ""\r
+\r
+msgid "Users"\r
+#msgstr ""\r
+\r
+msgid "Topic"\r
+#msgstr ""\r
+\r
+msgid "Channel List"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/applets/scripteditor.js\r
+msgid "Save"\r
+#msgstr ""\r
+\r
+msgid "Script error. %s"\r
+#msgstr ""\r
+\r
+msgid "Your script has been saved and is now active"\r
+#msgstr ""\r
+\r
+msgid "Script Editor"\r
+#msgstr\r
+\r
+\r
+\r
+#: client/assets/src/applets/settings.js\r
+msgid "Tabs"\r
+#msgstr ""\r
+\r
+msgid "List"\r
+#msgstr ""\r
+\r
+msgid "for large amouts of channels"\r
+#msgstr ""\r
+\r
+msgid "Join/part channel notifications"\r
+#msgstr ""\r
+\r
+msgid "Timestamps"\r
+#msgstr ""\r
+\r
+msgid "Mute sound notifications"\r
+#msgstr ""\r
+\r
+msgid "messages in scroll history"\r
+#msgstr ""\r
+\r
+msgid "Default IRC client"\r
+#msgstr ""\r
+\r
+msgid "Make Kiwi my default IRC client"\r
+#msgstr ""\r
+\r
+msgid "Note: Chrome or Chromium browser users may need to check their settings via %s if nothing happens"\r
+#msgstr ""\r
+\r
+msgid "Settings"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/models/applet.js\r
+msgid "Unknown Applet"\r
+#msgstr ""\r
+\r
+msgid "Loading.."\r
+#msgstr ""\r
+\r
+msgid "Not found"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/models/application.js\r
+msgid "You have been disconnected. Attempting to reconnect for you"\r
+#msgstr ""\r
+\r
+msgid "You have been disconnected. Attempting to reconnect again in %d seconds"\r
+#msgstr ""\r
+\r
+msgid "It's OK, you're connected again"\r
+#msgstr ""\r
+\r
+msgid "Settings have been saved"\r
+#msgstr ""\r
+\r
+msgid "Ignored nicks"\r
+#msgstr ""\r
+\r
+msgid "Not ignoring anybody"\r
+#msgstr ""\r
+\r
+msgid "Ignoring %s"\r
+#msgstr ""\r
+\r
+msgid "Specifiy which nick you wish to stop ignoring"\r
+#msgstr ""\r
+\r
+msgid "Stopped ignoring %s"\r
+#msgstr ""\r
+\r
+msgid "Applet "%s" does not exist"\r
+#msgstr ""\r
+\r
+msgid "Encoding modified to %s"\r
+#msgstr ""\r
+\r
+msgid "%s is not a valid encoding"\r
+#msgstr ""\r
+\r
+msgid "Encoding not specified"\r
+#msgstr ""\r
+\r
+msgid "Usage: /encoding [NEW-ENCODING]"\r
+#msgstr ""\r
+\r
+msgid "New Connection"\r
+#msgstr ""\r
+\r
+msgid "Connecting to %s:%s..."\r
+#msgstr ""\r
+\r
+msgid "Error connecting to %s:%s (%s)"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/models/channel.js\r
+msgid "%s has joined"\r
+#msgstr ""\r
+\r
+msgid "%s has quit %s"\r
+#msgstr ""\r
+\r
+msgid "%s was kicked by %s %s"\r
+#msgstr ""\r
+\r
+msgid "You have been kicked by %s %s"\r
+#msgstr ""\r
+\r
+msgid "%s has left %s"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/models/network.js\r
+msgid "%s is not a valid channel name"\r
+#msgstr ""\r
+\r
+msgid "Disconnected from the IRC network"\r
+#msgstr ""\r
+\r
+msgid "%s is now known as %s"\r
+#msgstr ""\r
+\r
+msgid "Topic set by %s at %s"\r
+#msgstr ""\r
+\r
+msgid "%s sets mode %s"\r
+#msgstr ""\r
+\r
+msgid "%s set mode %s"\r
+#msgstr ""\r
+\r
+msgid "Channels: %s"\r
+#msgstr ""\r
+\r
+msgid "Connected to server: %s %s"\r
+#msgstr ""\r
+\r
+msgid "Idle for %s, signed on %s"\r
+#msgstr ""\r
+\r
+msgid "Away: %s"\r
+#msgstr ""\r
+\r
+msgid "Idle for %s"\r
+#msgstr ""\r
+\r
+msgid "No such nick"\r
+#msgstr ""\r
+\r
+msgid "You are banned from %s. %s"\r
+#msgstr ""\r
+\r
+msgid "Bad channel key for %s"\r
+#msgstr ""\r
+\r
+msgid "%s is invite only."\r
+#msgstr ""\r
+\r
+msgid "%s is full."\r
+#msgstr ""\r
+\r
+msgid "The nickname "%s" is already in use. Please select a new nickname"\r
+#msgstr ""\r
+\r
+msgid "Incorrect password given"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/views/application.js\r
+msgid "This will close all KiwiIRC conversations. Are you sure you want to close this window?"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/views/channel.js\r
+msgid "Joining channel.."\r
+#msgstr ""\r
+\r
+msgid "Topic for %s is: %s"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/views/mediamessage.js\r
+msgid "Close media"\r
+#msgstr ""\r
+\r
+msgid "Not found"\r
+#msgstr ""\r
+\r
+msgid "Loading tweet"\r
+#msgstr ""\r
+\r
+msgid "Loading image"\r
+#msgstr ""\r
+\r
+msgid "Loading Reddit thread"\r
+#msgstr ""\r
+\r
+msgid "Loading gist"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/views/nickchangegbox.js\r
+msgid "New nick"\r
+#msgstr ""\r
+\r
+msgid "Change"\r
+#msgstr ""\r
+\r
+msgid "Cancel"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/views/panel.js\r
+msgid "People are talking!"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/views/serverselect.js\r
+msgid "Think of a nickname..."\r
+#msgstr ""\r
+\r
+msgid "Nickname"\r
+#msgstr ""\r
+\r
+msgid "I have a password"\r
+#msgstr ""\r
+\r
+msgid "Password"\r
+#msgstr ""\r
+\r
+msgid "Channel"\r
+#msgstr ""\r
+\r
+msgid "Channel Key"\r
+#msgstr ""\r
+\r
+msgid "Channel requires a key"\r
+#msgstr ""\r
+\r
+msgid "Key"\r
+#msgstr ""\r
+\r
+msgid "Start..."\r
+#msgstr ""\r
+\r
+msgid "Server and network"\r
+#msgstr ""\r
+\r
+msgid "Server"\r
+#msgstr ""\r
+\r
+msgid "Port"\r
+#msgstr ""\r
+\r
+msgid "Powered by Kiwi IRC"\r
+#msgstr ""\r
+\r
+msgid "Select a nickname first!"\r
+#msgstr ""\r
+\r
+msgid "Connected"\r
+#msgstr ""\r
+\r
+msgid "Connecting.."\r
+#msgstr ""\r
+\r
+msgid "Nickname already taken"\r
+#msgstr ""\r
+\r
+msgid "Erroneus nickname"\r
+#msgstr ""\r
+\r
+msgid "Incorrect Password"\r
+#msgstr ""\r
+\r
+msgid "Error Connecting"\r
+#msgstr ""\r
+\r
+msgid "Server not found"\r
+#msgstr ""\r
+\r
+msgid "Connection refused"\r
+#msgstr ""\r
+\r
+\r
+\r
+#: client/assets/src/views/userbox.js\r
+msgid "Op"\r
+#msgstr ""\r
+\r
+msgid "De-op"\r
+#msgstr ""\r
+\r
+msgid "Voice"\r
+#msgstr ""\r
+\r
+msgid "De-voice"\r
+#msgstr ""\r
+\r
+msgid "Kick"\r
+#msgstr ""\r
+\r
+msgid "Ban"\r
+#msgstr ""\r
+\r
+msgid "Message"\r
+#msgstr ""\r
+\r
+msgid "Info"\r
+#msgstr ""\r
+\r
+msgid "Slap!"\r
+#msgstr ""\r
--- /dev/null
+{\r
+ "en-gb": "English (British)"\r
+}
\ No newline at end of file
\r
// Entry point to start the kiwi application\r
start: function (opts) {\r
+ var continueStart, locale;\r
opts = opts || {};\r
\r
// Load the plugin manager\r
_kiwi.global.settings = _kiwi.model.DataStore.instance('kiwi.settings');\r
_kiwi.global.settings.load();\r
\r
- _kiwi.global.i18n = new Jed();\r
-\r
- _kiwi.app = new _kiwi.model.Application(opts);\r
-\r
- if (opts.kiwi_server) {\r
- _kiwi.app.kiwi_server = opts.kiwi_server;\r
- }\r
-\r
- // Start the client up\r
- _kiwi.app.start();\r
-\r
- return true;\r
+ continueStart = function (locale, s, xhr) {\r
+ if (locale) {\r
+ _kiwi.global.i18n = new Jed({locale_data: locale, domain: xhr.getResponseHeader('Content-Language')});\r
+ } else {\r
+ _kiwi.global.i18n = new Jed();\r
+ }\r
+\r
+ _kiwi.app = new _kiwi.model.Application(opts);\r
+\r
+ if (opts.kiwi_server) {\r
+ _kiwi.app.kiwi_server = opts.kiwi_server;\r
+ }\r
+\r
+ // Start the client up\r
+ _kiwi.app.start();\r
+ };\r
+\r
+ locale = _kiwi.global.settings.get('locale')\r
+ if (!locale) {\r
+ $.getJSON(opts.base_path + '/assets/locales/magic.json', continueStart);\r
+ } else {\r
+ if (locale === 'en-gb') {\r
+ continueStart();\r
+ } else {\r
+ $.getJSON(opts.base_path + '/assets/locales/' + locale + '.json', continueStart);\r
+ }\r
+ }\r
}\r
};\r
\r
timestamps: _kiwi.global.i18n.translate('Timestamps').fetch(),\r
mute: _kiwi.global.i18n.translate('Mute sound notifications').fetch(),\r
scroll_history: _kiwi.global.i18n.translate('messages in scroll history').fetch(),\r
+ languages: _kiwi.app.translations,\r
default_client: _kiwi.global.i18n.translate('Default IRC client').fetch(),\r
make_default: _kiwi.global.i18n.translate('Make Kiwi my default IRC client').fetch(),\r
default_note: _kiwi.global.i18n.translate('Note: Chrome or Chromium browser users may need to check their settings via %s if nothing happens').fetch('<a href="chrome://settings/handlers">chrome://settings/handlers</a>')\r
case 'text':\r
$el.val(value);\r
break;\r
+ case 'select-one':\r
+ $('[value="' + value + '"]', that.$el).prop('selected', true);\r
+ break;\r
default:\r
$('[data-setting="' + key + '"][data-value="' + value + '"]', that.$el).addClass('active');\r
break;\r
saveSettings: function (event) {\r
var value,\r
settings = _kiwi.global.settings,\r
- $setting = $(event.currentTarget, this.$el)\r
+ $setting = $(event.currentTarget, this.$el);\r
\r
switch (event.currentTarget.type) {\r
case 'checkbox':\r
case 'text':\r
value = $setting.val();\r
break;\r
+ case 'select-one':\r
+ value = $(event.currentTarget[$setting.prop('selectedIndex')]).val();\r
+ break;\r
default:\r
value = $setting.data('value');\r
break;\r
var fs = require('fs'),\r
uglifyJS = require('uglify-js'),\r
_ = require('lodash'),\r
+ po2json = require('po2json'),\r
config = require('./../../../server/configuration.js');\r
\r
var FILE_ENCODING = 'utf-8',\r
\r
\r
\r
+/**\r
+* Convert translations from .po to .json\r
+*/\r
+var translations = [];\r
+var translation_files = fs.readdirSync(__dirname + '/../locales');\r
+translation_files.forEach(function (file) {\r
+ var locale = file.slice(0, -3),\r
+ json = '',\r
+ languages = JSON.parse(fs.readFileSync(__dirname + '/../locales/translations.json'));\r
+ if ((file.slice(-3) === '.po') && (locale !== 'template')) {\r
+ json = po2json.parseSync(__dirname + '/../locales/' + file);\r
+ fs.writeFileSync(__dirname + '/../locales/' + locale + '.json', JSON.stringify(json));\r
+ translations.push({tag: locale, language: languages[locale]});\r
+ console.log('Built translation file %s', locale + '.json');\r
+ }\r
+});\r
+\r
+\r
\r
\r
\r
vars.client_plugins = config.get().client_plugins;\r
}\r
\r
+// Translations\r
+vars.translations = translations;\r
+\r
_.each(vars, function(value, key) {\r
if (typeof value === 'object') value = JSON.stringify(value);\r
index_src = index_src.replace(new RegExp('<%' + key + '%>', 'g'), value);\r
fs.writeFileSync(__dirname + '/../../index.html', index_src, FILE_ENCODING);\r
\r
\r
-console.log('index.html built');
\ No newline at end of file
+console.log('index.html built');\r
</div>\r
</section>\r
\r
+ <section>\r
+ <h6>Language</h6>\r
+ <div class="control-group">\r
+ <select data-setting="locale">\r
+ <option value="en-gb">English (British)</option>\r
+ <% _.forEach(languages, function(lang) { %>\r
+ <option value="<%= lang.tag %>"><%= lang.language %></li>\r
+ <% }); %>\r
+ </select>\r
+ </div>\r
+ </section>\r
+\r
<section class="protocol_handler">\r
<h6><%= default_client %></h6>\r
<div class="control-group">\r
//kiwi_server: 'http://kiwiirc.com:80',\r
\r
server_settings: <%server_settings%>,\r
- client_plugins: <%client_plugins%>\r
+ client_plugins: <%client_plugins%>,\r
+ translations: <%translations%>\r
};\r
\r
// Start the app\r
\r
// Any options sent down from the server\r
this.server_settings = options[0].server_settings || {};\r
+ this.translations = options[0].translations || {};\r
\r
// Best guess at where the kiwi server is\r
this.detectKiwiServer();\r
"eventemitter2": "0.4.11",\r
"ipaddr.js": "0.1.1",\r
"socksjs": "0.3.3",\r
- "iconv-lite" : "0.2.10"\r
+ "iconv-lite" : "0.2.10",\r
+ "po2json": "0.0.6"\r
}\r
}\r
var url = require('url'),
- node_static = require ('node-static');
+ fs = require('fs'),
+ node_static = require('node-static'),
+ _ = require('lodash');
if (base_path.substr(base_path.length - 1) === '/') {
base_path = base_path.substr(0, base_path.length - 1);
}
-
+
// Build the regex to match the base_path
base_path_regex = base_path.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
request.url = '/';
}
+ // If the 'magic' translation is requested, figure out the best language to use from
+ // the Accept-Language HTTP header. If nothing is suitible, serve an empty response,
+ // Kiwi will just use the default en-gb strings baked in to it.
+ if (request.url === '/assets/locales/magic.json') {
+ return serveMagicLocale.call(this, request, response);
+ }
this.file_server.serve(request, response, function (err) {
if (err) {
response.end();
}
});
-};
\ No newline at end of file
+};
+
+var serveMagicLocale = function (request, response) {
+ var langs = [],
+ available = [],
+ i = 0;
+ if (request.headers['accept-language']) {
+ // Example: en-gb,en;q=0.5
+ langs = request.headers['accept-language'].split(',');
+ available = (function () {
+ var files = [],
+ l = [];
+ files = fs.readdirSync('client/assets/locales');
+ files.forEach(function (file) {
+ if (file.slice(-5) === '.json') {
+ l.push(file.slice(0, -5));
+ }
+ });
+ return l;
+ })();
+ for (i = 0; i < langs.length; i++) {
+ langs[i] = langs[i].split(';q=');
+ langs[i][1] = (typeof langs[i][1] === 'string') ? parseFloat(langs[i][1]) : 1.0;
+ }
+ langs.sort(function (a, b) {
+ return b[1] - a[1];
+ });
+
+ for (i = 0; i < langs.length; i++) {
+ if (langs[i][0] === '*') {
+ break;
+ } else if (_.contains(available, langs[i][0])) {
+ return this.file_server.serveFile('/assets/locales/' + langs[i][0] + '.json', 200, {Vary: 'Accept-Language', 'Content-Language': langs[i][0]}, request, response);
+ }
+ }
+ }
+
+ response.writeHead(200, {
+ 'Vary': 'Accept-Language',
+ 'Content-Type': 'application/json',
+ 'Content-Language': 'en-gb'
+ });
+ response.end('{"en-gb": {}}');
+};