Server: Splitting State / IrcConnection / IrcCommands better
[KiwiIRC.git] / server / httphandler.js
index 816cb37333d306f935c5e092ddf62733a31506d4..045dd2f806b049fd54707cb2cae4d00547c45d36 100644 (file)
@@ -1,5 +1,7 @@
 var url         = require('url'),
-    node_static = require ('node-static');
+    fs          = require('fs'),
+    node_static = require('node-static'),
+    _           = require('lodash');
 
 
 
@@ -21,7 +23,7 @@ HttpHandler.prototype.serve = function (request, response) {
     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, '\\$&');
 
@@ -33,6 +35,15 @@ HttpHandler.prototype.serve = function (request, response) {
         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, fallback to our en-gb default translation
+    if (request.url.substr(0, 16) === '/assets/locales/') {
+        if (request.url === '/assets/locales/magic.json') {
+            return serveMagicLocale.call(this, request, response);
+        } else {
+            response.setHeader('Content-Language', request.url.substr(16, request.url.indexOf('.') - 16));
+        }
+    }
 
     this.file_server.serve(request, response, function (err) {
         if (err) {
@@ -40,4 +51,53 @@ HttpHandler.prototype.serve = function (request, response) {
             response.end();
         }
     });
-};
\ No newline at end of file
+};
+
+var serveMagicLocale = function (request, response) {
+    var that = this;
+
+    if (request.headers['accept-language']) {
+        fs.readdir('client/assets/locales', function (err, files) {
+            var available = [],
+                i = 0,
+                langs = request.headers['accept-language'].split(','); // Example: en-gb,en;q=0.5
+
+            // Get a list of the available translations we have
+            files.forEach(function (file) {
+                if (file.substr(-5) === '.json') {
+                    available.push(file.slice(0, -5));
+                }
+            });
+
+            // Sanitise the browsers accepted languages and the qualities
+            for (i = 0; i < langs.length; i++) {
+                langs[i]= langs[i].split(';q=');
+                langs[i][0] = langs[i][0].toLowerCase();
+                langs[i][1] = (typeof langs[i][1] === 'string') ? parseFloat(langs[i][1]) : 1.0;
+            }
+
+            // Sort the accepted languages by quality
+            langs.sort(function (a, b) {
+                return b[1] - a[1];
+            });
+
+            // Serve the first language we have a translation for
+            for (i = 0; i < langs.length; i++) {
+                if (langs[i][0] === '*') {
+                    break;
+                } else if (_.contains(available, langs[i][0])) {
+                    return that.file_server.serveFile('/assets/locales/' + langs[i][0] + '.json', 200, {Vary: 'Accept-Language', 'Content-Language': langs[i][0]}, request, response);
+                }
+            }
+
+            serveFallbackLocale.call(that, request, response);
+        });
+    } else {
+        serveFallbackLocale.call(that, request, response);
+    }
+};
+
+var serveFallbackLocale = function (request, response) {
+    //en-gb is our default language, so we serve this as the last possible answer for everything
+    this.file_server.serveFile('/assets/locales/en-gb.json', 200, {Vary: 'Accept-Language', 'Content-Language': 'en-gb'}, request, response);
+};