diff --git a/README.md b/README.md
index 36c5583..e923816 100644
--- a/README.md
+++ b/README.md
@@ -9,20 +9,22 @@ It provides a way to do:
You will need to set the `requireSession` and `editOnly` values to `true` in etherpad's `settings.json` file.
-It's recommended to also add in a `sessionKey`. This can be any random value, but should be the same across the cluster.
-
To get it working, change the `dbType` to `cassandra` and enter the following `dbSettings`:
```javascript
"dbSettings" : {
"hosts": ["127.0.0.1:9160"],
"keyspace": "oae",
- "cfName": "Etherpad",
+ "columnFamily": "Etherpad",
"user": "",
"pass": "",
"timeout": 3000,
"replication": 1,
- "strategyClass": "SimpleStrategy"
+ "strategyClass": "SimpleStrategy",
+ "clientOptions": {
+ "keyspace": "oae",
+ "contactPoints": ["127.0.0.1"]
+ }
}
```
@@ -46,7 +48,7 @@ You should have the following structure (assuming you have etherpad at `/opt/eth
* index.json
* ep.json
-Copy or symlink the `static/css/padd.css` file in this plugin to `your-etherpad-directory/src/static/custom/pad.css`. This file will skin the etherpad chrome. In order to have custom titles for headers, copy or symlink the `static/templates/editbarButtons.ejs` file in this plugin to `your-etherpad-directory/node_modules/ep_headings/templates/editbarButtons.ejs`.
+Copy or symlink the `static/css/padd.css` file in this plugin to `your-etherpad-directory/src/static/custom/pad.css`. This file will skin the etherpad chrome.
In order to use the OAE toolbar, the etherpad `settings.json` file needs to be updated to reflect the following changes:
diff --git a/locales/de.json b/locales/de.json
new file mode 100644
index 0000000..c1fc9ab
--- /dev/null
+++ b/locales/de.json
@@ -0,0 +1,13 @@
+{
+ "ep_headings.code" : "Code",
+ "ep_headings.h1" : "Titel 1",
+ "ep_headings.h2" : "Titel 2",
+ "ep_headings.h3" : "Titel 3",
+ "ep_headings.h4" : "Titel 4",
+ "ep_headings.h5" : "Titel 5",
+ "ep_headings.h6" : "Titel 6",
+ "ep_headings.normal" : "Normal",
+ "ep_headings.style" : "Stil",
+ "ep_oae.download": "Download",
+ "ep_oae.togglecolors": "Schaltet die Urheber Farben"
+}
diff --git a/locales/en.json b/locales/en.json
new file mode 100644
index 0000000..cb62c1a
--- /dev/null
+++ b/locales/en.json
@@ -0,0 +1,13 @@
+{
+ "ep_headings.code": "Code",
+ "ep_headings.normal": "Normal",
+ "ep_headings.style": "Style",
+ "ep_headings.h1": "Title 1",
+ "ep_headings.h2": "Title 2",
+ "ep_headings.h3": "Title 3",
+ "ep_headings.h4": "Title 4",
+ "ep_headings.h5": "Title 5",
+ "ep_headings.h6": "Title 6",
+ "ep_oae.download": "Download",
+ "ep_oae.togglecolors": "Toggle authorship colors"
+}
diff --git a/package.json b/package.json
index 10feb7b..8b1c598 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,13 @@
"dependencies": {
"amqp": "git://github.com/oaeproject/node-amqp#0.1.8.x"
},
+ "devDependencies": {
+ "crowdin": "latest",
+ "mv": "latest",
+ "optimist": "latest",
+ "temp": "latest",
+ "underscore": "latest"
+ },
"engines": {
"node": ">= 0.8.0"
}
diff --git a/static/js/index.js b/static/js/index.js
index 44764d9..5df6820 100755
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -16,8 +16,8 @@ exports.postAceInit = function (hook_name, args, cb) {
$('.buttonicon-showusers').removeClass('buttonicon-showusers').addClass('buttonicon-oae buttonicon-user');
// Add extra buttons to the toolbar *after* the style select
- $('ul.menu_left').append('
');
- $('ul.menu_left').append('
');
+ $('ul.menu_left').append('
');
+ $('ul.menu_left').append('
');
// Show the toolbar
$('.toolbar').animate({
diff --git a/static/templates/editbarButtons.ejs b/static/templates/editbarButtons.ejs
deleted file mode 100644
index 702ccba..0000000
--- a/static/templates/editbarButtons.ejs
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/tools/sync-translations.js b/tools/sync-translations.js
new file mode 100644
index 0000000..4c2e874
--- /dev/null
+++ b/tools/sync-translations.js
@@ -0,0 +1,111 @@
+/*!
+ * Copyright 2013 Apereo Foundation (AF) Licensed under the
+ * Educational Community License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may
+ * obtain a copy of the License at
+ *
+ * http://www.osedu.org/licenses/ECL-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+var argv = require('optimist')
+ .usage('Usage: $0 -a ')
+
+ .demand('a')
+ .alias('a', 'apiKey')
+ .describe('a', 'Crowdin API key')
+ .argv;
+
+var _ = require('underscore');
+var Crowdin = require('crowdin');
+var fs = require('fs');
+var temp = require('temp');
+
+// Automatically track and cleanup files at exit
+temp.track();
+
+var config = {
+ endpointUrl: 'https://crowdin.com/api/project/apereo-oae'
+};
+
+config.apiKey = argv.apiKey;
+
+var crowdin = new Crowdin(config);
+
+/**
+ * Make a POST request to crowdin
+ *
+ * @param {String} path The path to the crowdin api endpoint
+ * @param {Object} data The post data to be passed to request
+ * @param {Function} callback A function to call on completion
+ */
+var crowdinPost = function(path, data, callback) {
+ data.key = config.apiKey;
+ crowdin.requestData({
+ uri: config.endpointUrl + path,
+ method: 'POST',
+ formData: data,
+ qs: {
+ json: 'json'
+ }
+ }).then(callback);
+};
+
+/**
+ * Update the local translation files with data from crowdin
+ */
+var downloadCrowdinTranslations = function() {
+ console.log('Downloading translations');
+ temp.mkdir('crowdin', function(err, dirPath) {
+ // Download all the OAE translations
+ crowdin.downloadToPath(dirPath).then(function(){
+ // Copy the non-empty ep_oae bundles
+ fs.readdir(dirPath + '/locales', function(err, files) {
+ _.each(files, function(file) {
+ fs.readFile(dirPath + '/locales/' + file, function(err, data) {
+ var translations = JSON.parse(data);
+ var notEmpty = _.values(translations).some(function(translation){
+ return translation !== '';
+ });
+ if (notEmpty){
+ fs.createReadStream(dirPath + '/locales/' + file).pipe(fs.createWriteStream(__dirname + '/../locales/' + file));
+ }
+ });
+ });
+ });
+ });
+ });
+};
+
+// Upload keys
+var keysPostData = {
+ 'files[/ep_oae/locales/en.json]': fs.createReadStream(__dirname + '/../locales/en.json')
+};
+console.log('Uploading keys');
+crowdinPost('/update-file', keysPostData, function() {
+ console.log('Uploading translations');
+ // Upload existing translations
+ fs.readdir(__dirname + '/../locales', function(err, files) {
+ // After all the translations are uploaded, download any changes
+ var done = _.after(files.length, downloadCrowdinTranslations);
+
+ _.each(files, function(file) {
+ // We don't upload translations for the source language, that's covered by the key upload
+ if (file !== 'en.json') {
+ var translationPostData = {
+ key: config.apiKey,
+ 'files[/ep_oae/locales/en.json]': fs.createReadStream(__dirname + '/../locales/' + file),
+ language: file.substring(0, 2)
+ };
+ crowdinPost('/upload-translation', translationPostData, done);
+ } else {
+ done();
+ }
+ });
+ });
+});