Commit b85aa245 authored by Wolfgang Knopki's avatar Wolfgang Knopki
Browse files

Merge branch 'mnt' into 'master'

Mnt

See merge request !2
parents 2fc14e1e fff0340f
node_modules
javascripts/maps
javascripts/spacedeck.js
public/stylesheets/*.css
database.sqlite
*.swp
*~
FROM spacedeck/docker-baseimage:latest
ENV NODE_ENV production
FROM node:10-alpine3.11
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
WORKDIR /app
COPY package.json /usr/src/app/
RUN npm install
RUN npm install gulp-rev-replace gulp-clean gulp-fingerprint gulp-rev gulp-rev-all gulp-rev-replace
RUN npm install -g --save-dev gulp
# build audiowaveform from source
RUN apk add git make cmake gcc g++ libmad-dev libid3tag-dev libsndfile-dev gd-dev boost-dev libgd libpng-dev zlib-dev
RUN apk add zlib-static libpng-static boost-static
RUN apk add autoconf automake libtool gettext
RUN wget https://github.com/xiph/flac/archive/1.3.3.tar.gz
RUN tar xzf 1.3.3.tar.gz
RUN cd flac-1.3.3/ && ./autogen.sh
RUN cd flac-1.3.3/ && ./configure --enable-shared=no
RUN cd flac-1.3.3/ && make
RUN cd flac-1.3.3/ && make install
RUN git clone https://github.com/bbc/audiowaveform.git
RUN mkdir audiowaveform/build/
RUN cd audiowaveform/build/ && cmake -D ENABLE_TESTS=0 -D BUILD_STATIC=1 ..
RUN cd audiowaveform/build/ && make
RUN cd audiowaveform/build/ && make install
COPY app.js Dockerfile Gulpfile.js LICENSE /usr/src/app/
COPY config /usr/src/app/config
COPY helpers /usr/src/app/helpers
COPY locales /usr/src/app/locales
COPY middlewares /usr/src/app/middlewares
COPY models /usr/src/app/models
COPY public /usr/src/app/public
COPY routes /usr/src/app/routes
COPY styles /usr/src/app/styles
COPY views /usr/src/app/views
# install other requirements
RUN gulp all
RUN npm cache clean
RUN apk add graphicsmagick ffmpeg ffmpeg-dev ghostscript
# install node package
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "node", "app.js" ]
# start app
EXPOSE 9666
CMD ["node", "spacedeck.js"]
var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
const gulp = require('gulp')
const sass = require('gulp-sass')
const concat = require('gulp-concat')
gulp.task('styles', function() {
gulp.task('styles', function(done) {
gulp.src('styles/**/*.scss')
.pipe(sass({
errLogToConsole: true
}))
.pipe(gulp.dest('./public/stylesheets/'))
.pipe(concat('style.css'));
});
.pipe(concat('style.css'))
done()
})
# Spacedeck Open
![Spacedeck 6.0 Screenshot](/public/images/sd6-screenshot.png)
This is the free and open source version of Spacedeck, a web based, real time, collaborative whiteboard application with rich media support. Spacedeck was developed in 6 major releases during Autumn 2011 until the end of 2016 and was originally a commercial SaaS. The developers were Lukas F. Hartmann (mntmn) and Martin Güther (magegu).
The spacedeck.com online service was shut down on May 1st 2018. We decided to open-source Spacedeck to allow educational and other organizations who currently rely on Spacedeck to migrate to a self-hosted or local version.
[MNT Research GmbH](https://mntre.com) has restarted development of Spacedeck Open in 2020.
We appreciate filed issues, pull requests and general discussion.
# Features
......@@ -13,9 +17,9 @@ We appreciate filed issues, pull requests and general discussion.
- Write and format text with full control over fonts, colors and style
- Draw, annotate and highlight with included graphical shapes
- Turn your Space into a zooming presentation
- Collaborate and chat in realtime with teammates, students or friends
- Collaborate in realtime with teammates, students or friends
- Share Spaces on the web or via email
- Export your work as printable PDF or ZIP
- Export your work as printable PDF or ZIP (currently being fixed, stay tuned)
# Use Cases
......@@ -23,23 +27,15 @@ We appreciate filed issues, pull requests and general discussion.
- Creative: Mood boards, Brainstorming, Design Thinking
- Visual note taking and planning
# Data Import from Spacedeck.com
Spacedeck Open has a data import feature that you can use to migrate your ZIP export from Spacedeck.com.
1. Just copy your downloaded ZIP file into the spacedeck root folder. Don't extract it.
2. Start your local Spacedeck.
3. Navigate to *Account / Profile* (person icon in the top right corner).
4. Click the *Import* button next to the ZIP file name. It is on the bottom of the page.
5. Wait until console output has finished and you're done.
# Requirements, Installation
Spacedeck requires:
- Node.js 9.x: Web Server / API. Download: https://nodejs.org
- Node.js 10.x: Web Server / API. Download: https://nodejs.org
- Graphicsmagick. On non-Linux, Download: http://www.graphicsmagick.org/ On Linux, install via package manager.
- Optionally ffmpeg, audiowaveform and ghostscript. See "Optional Dependencies" below.
To run Spacedeck, you only need Node.JS 9.x.
To run Spacedeck, you only need Node.JS 10.x.
To install all node dependencies, run (do this once):
......@@ -47,7 +43,7 @@ To install all node dependencies, run (do this once):
# Configuration
See [config/default.json](config/default.json)
See [config/default.json](config/default.json). Set `storage_local_path` for a local sqlite database or `storage_region`, `storage_bucket`, `storage_cdn` and `storage_endpoint` for AWS S3. `mail_provider` may be one of `console` or `smtp`. Also, omit a trailing `/` for the `endpoint`.
# Run (web server)
......@@ -55,10 +51,6 @@ See [config/default.json](config/default.json)
Then open http://localhost:9666 in a web browser.
# Run (desktop app with integrated web server)
electron .
# Optional Dependencies
For advanced media conversion:
......@@ -72,6 +64,16 @@ For advanced media conversion:
By default, media files are uploaded to the ```storage``` folder.
The database is stored in ```database.sqlite``` by default.
# Run with Docker
- configure `config/default.json`
- configure `volumes` section inside `docker-compose.yml`
- point to `database.sqlite` on the host system
- `touch database.sqlite` if it not exists
- point to `storage/` on the host system
- `mkdir storage/` if it not exists
- start the container with `sudo docker-compose up -f docker-compose.yml -d --build`
# Hacking
To rebuild the frontend CSS styles:
......
const spacedeck = require('./spacedeck')
const electron = require('electron')
const electronApp = electron.app
const BrowserWindow = electron.BrowserWindow
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({width: 1200, height: 700})
mainWindow.loadURL("http://localhost:9666")
mainWindow.on('closed', function () {
mainWindow = null
})
}
electronApp.on('ready', createWindow)
// Quit when all windows are closed.
electronApp.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
electronApp.quit()
}
})
electronApp.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
#!/usr/bin/env node
var app = require('../app');
var http = require('http');
var server = http.createServer(app);
......@@ -2,16 +2,17 @@
"team_name": "My Open Spacedeck",
"contact_email": "support@example.org",
"host": "::",
"port": 9666,
"endpoint": "http://localhost:9666",
"invite_code": "top-sekrit",
"storage_region": "eu-central-1",
//"storage_bucket": "sdeck-development",
//"storage_cdn": "http://localhost:9123/sdeck-development",
//"storage_endpoint": "http://storage:9000",
"storage_bucket": "my_spacedeck_bucket",
"storage_cdn": "/storage",
"storage_local_path": "./storage",
"storage_local_db": "./database.sqlite",
"redis_mock": true,
"mongodb_host": "localhost",
......@@ -22,12 +23,15 @@
"admin_pass": "very_secret_admin_password",
"phantom_api_secret": "very_secret_phantom_password",
// Choose "console" or "smtp"
"mail_provider": "smtp",
"mail_smtp_host": "your.smtp.host",
"mail_smtp_port": 465,
"mail_smtp_secure": true,
"mail_smtp_require_tls": true,
"mail_smtp_user": "your.smtp.user",
"mail_smtp_pass": "your.secret.smtp.password"
"mail_smtp_pass": "your.secret.smtp.password",
"path" : "http://localhost:9666/saml/SSO",
"entryPoint" : "https://m4lab.hft-stuttgart.de/idp/saml2/idp/SSOService.php",
"issuer" : "spacedeck.m4lab.hft-stuttgart.de"
}
version: "2.0"
services:
spacedeck:
build: .
container_name: spacedeck
ports:
- "9666:9666"
volumes:
- /absolute/path/to/storage:/app/storage
- /absolute/path/to/database.sqlite:/app/database.sqlite
To add fonts to Spacedeck Open, follow these steps:
1. Find the googleapis link for the font and add it to [./styles/type.scss](https://github.com/spacedeck/spacedeck-open/blob/docs/styles/type.scss#L4) after the `Inter` font that is already there. Here is a good reference to using [Google Font API](https://www.webfx.com/blog/web-design/google-font-api-guide/).
2. Add the name of the font to the file [./public/javascripts/spacedeck_sections.js](https://github.com/spacedeck/spacedeck-open/blob/docs/public/javascripts/spacedeck_sections.js#L150) in the `fonts` section found around line 150. The order of the list here is the order in which fonts will be displayed in the user interface.
3. From the root of your install, do `gulp styles` to recompile the SCSS.
4. Restart your server.
## Adding a new language to Spacedeck Open
To add a new language to Spacedeck Open, follow these steps:
*The steps are illustrated with Spanish (locale 'es') as the new language*
- Include the new locale ('es') in the locale list (./spacedeck.js):
```
locales: ["en",..., "es"],
```
- Create the new translation file (/locales/**es.js**, a copy of /locales/en.js) and translate the entries.
- Include the javascript for the new translation at the end of /views/spacedeck.ejs:
```
...
window.locales.es = {};
...
window.locales.es.translation = <%- include "./../locales/es.js" %>;
</script>
```
- Include a radio button for users to select the new language (/views/partials/account.html)
```
<label class="radio" v-bind:class="{checked: user.prefs_language=='es'}" v-on:click="save_user_language('es')">
<input type="radio" id="user-preferences_language" name="language" value="es"><span>Español</span>
</label>
```
# Windows Electron Build
sqlite3 needs to be manually built for the iojs version that electron ships. The following code assumes electron v1.8.4.
````
npm -g install windows-build-tools
cd node_modules\sqlite3
node-gyp configure --module_name=node_sqlite3 --module_path=../lib/binding/electron-v1.8-win32-x64
node-gyp rebuild --target=1.8.4 --target_platform=win32 --dist-url=https://atom.io/download/atom-shell --module_name=node_sqlite3 --module_path=../lib/binding/electron-v1.8-win32-x64 --msvs_version=2015
cd ..\..
````
......@@ -2,8 +2,6 @@
const config = require('config');
const nodemailer = require('nodemailer');
const swig = require('swig');
//var AWS = require('aws-sdk');
module.exports = {
sendMail: (to_email, subject, body, options) => {
......@@ -24,18 +22,14 @@ module.exports = {
plaintext+="\n"+options.action.link+"\n\n";
}
const htmlText = swig.renderFile('./views/emails/action.html', {
text: body.replace(/(?:\n)/g, '<br />'),
options: options
});
if (config.get('mail_provider') === 'console') {
console.log("Email: to " + to_email + " in production.\nreply_to: " + reply_to + "\nsubject: " + subject + "\nbody: \n" + htmlText + "\n\n plaintext:\n" + plaintext);
console.log("Email: to " + to_email + " in production.\nreply_to: " + reply_to + "\nsubject: " + subject + "\nbody: \n" + plaintext + "\n\n plaintext:\n" + plaintext);
} else if (config.get('mail_provider') === 'smtp') {
const transporter = nodemailer.createTransport({
let transporter;
if (config.has('mail_smtp_user')) {
transporter = nodemailer.createTransport({
host: config.get('mail_smtp_host'),
port: config.get('mail_smtp_port'),
secure: config.get('mail_smtp_secure'),
......@@ -45,14 +39,21 @@ module.exports = {
pass: config.get('mail_smtp_pass'),
}
});
} else {
transporter = nodemailer.createTransport({
host: config.get('mail_smtp_host'),
port: config.get('mail_smtp_port'),
secure: config.get('mail_smtp_secure'),
requireTLS: config.get('mail_smtp_require_tls'),
});
}
transporter.sendMail({
from: from,
replyTo: reply_to,
to: to_email,
subject: subject,
text: plaintext,
html: htmlText,
text: plaintext
}, function(err, info) {
if (err) {
console.error("Error sending email:", err);
......@@ -61,33 +62,6 @@ module.exports = {
}
});
} else if (config.get('mail_provider') === 'aws') {
/*
AWS.config.update({region: 'eu-west-1'});
var ses = new AWS.SES();
ses.sendEmail( {
Source: from,
Destination: { ToAddresses: [to_email] },
ReplyToAddresses: reply_to,
Message: {
Subject: {
Data: subject
},
Body: {
Text: {
Data: plaintext,
},
Html: {
Data: htmlText
}
}
}
}, function(err, data) {
if (err) console.error("Error sending email:", err);
else console.log("Email sent.");
});
*/
}
}
};
<?php
/*
Plugin Name: Spacedeck
Plugin URI: https://spacedeck.com
description: Embed Spacedeck Whiteboards in Wordpress Posts
Version: 1.0
Author: MNT Research GmbH
Author URI: https://mntre.com
License: GPLv3+
*/
add_option("spacedeck_settings");
function spacedeck_apicall($method, $path, $data) {
$spacedeck_api_base_uri = get_option("spacedeck_settings")[spacedeck_api_base_uri];
$spacedeck_api_key = get_option("spacedeck_settings")[spacedeck_api_key];
$data_string = json_encode($data);
$url = $spacedeck_api_base_uri . $path;
$headers = array(
'Content-Type' => 'application/json',
'X-Spacedeck-API-Token' => $spacedeck_api_key
);
$payload = array(
'method' => $method,
'timeout' => 10,
'blocking' => true,
'headers' => $headers,
'body' => $data_string
);
// echo("<p>payload:</p><pre>");
// print_r($payload);
// echo("</pre>");
$result = wp_remote_post($url, $payload);
if (is_wp_error($result)) {
return $result;
}
$result = json_decode($result[body], true);
// echo("<p>decoded:</p><pre>");
// print_r($result);
// echo("</pre>");
return $result;
}
function spacedeck_embed_space($slug, $width = '90%', $height = '800', $parent_space_id = null) {
$spacedeck_frontend_base_uri = get_option("spacedeck_settings")[spacedeck_frontend_base_uri];
// try to find the space identified by slug
$space = spacedeck_apicall("GET", "/spaces/" . $slug, array());
if (is_wp_error($space)) {
$error = $response->get_error_message();
return("<p><b>Spacedeck: WP Error looking up Space: $error</b></p>");
} else if ($space[error] && $space[error]!="space_not_found") {
return("<p><b>Spacedeck: Error looking up Space: $space[error]</b></p>");
}
// if it doesn't exist, create it:
if ($space[error]=="space_not_found") {
$data = array(
"name" => $slug,
"edit_slug" => $slug
);
if ($parent_space_id) {
$data[parent_space_id] = $parent_space_id;
}
$space = spacedeck_apicall("POST", "/spaces", $data);
if (is_wp_error($space)) {
$error = $response->get_error_message();
return("<p><b>Spacedeck: WP Error creating Space: $error</b></p>");
} else if ($space[error]) {
return("<p><b>Spacedeck: Error creating Space: $space[error]</b></p>");
}
}
if (is_wp_error($space)) {
$error = $response->get_error_message();
return("<p><b>Spacedeck: WP Error embedding Space: $error</b></p>");
} else if (!$space || $space[error]) {
return("<p><b>Spacedeck: Error embedding Space. Is your API key set up correctly?</b></p>");
}
$space_auth = $space[edit_hash];
// return a piece of html (iframe) embedding the space
$uri = $spacedeck_frontend_base_uri . '/spaces/' . $slug . '?embedded=1&spaceAuth=' . $space_auth;
$html = "<iframe src='$uri' class='spacedeck' width='$width' height='$height' style='max-width:100%' frameborder='0' allowFullScreen='true'></iframe>";
return $html;
}
function spacedeck_shortcode($attrs) {
extract(shortcode_atts(array(
'id' => 'none',
'parent_space_id' => null,
'width' => '100%',
'height' => '800'
), $attrs));
$w = $attrs[width];
$h = $attrs[height];
if (!$w) $w = '100%';
if (!$h) $h = 800;
return spacedeck_embed_space($attrs[id],$w,$h,$attrs[parent_space_id]);
}
add_shortcode('spacedeck_space', 'spacedeck_shortcode');
add_action('admin_menu', 'spacedeck_add_admin_menu');
add_action('admin_init', 'spacedeck_settings_init');
function spacedeck_add_admin_menu() {
add_options_page('spacedeck', 'Spacedeck', 'manage_options', 'spacedeck', 'spacedeck_options_page');
}
function spacedeck_settings_init() {
register_setting('pluginPage', 'spacedeck_settings');
add_settings_section(
'spacedeck_pluginPage_section',
'Spacedeck Settings',
'spacedeck_settings_section_callback',
'pluginPage'
);
add_settings_field(
'spacedeck_text_field_0',
'API key',
'spacedeck_text_field_0_render',
'pluginPage',
'spacedeck_pluginPage_section'
);
add_settings_field(
'spacedeck_text_field_1',
'API base URL',
'spacedeck_text_field_1_render',
'pluginPage',
'spacedeck_pluginPage_section'
);
add_settings_field(
'spacedeck_text_field_2',
'Frontend base URL',
'spacedeck_text_field_2_render',
'pluginPage',
'spacedeck_pluginPage_section'
);
}
function spacedeck_text_field_0_render() {
$opts = get_option('spacedeck_settings');
?>
<input type='text' name='spacedeck_settings[spacedeck_api_key]' value='<?php echo $opts[spacedeck_api_key]; ?>'>
<?php
}
function spacedeck_text_field_1_render() {
$opts = get_option('spacedeck_settings');
?>
<input type='text' name='spacedeck_settings[spacedeck_api_base_uri]' value='<?php echo $opts[spacedeck_api_base_uri]; ?>'>
<?php
}
function spacedeck_text_field_2_render() {
$opts = get_option('spacedeck_settings');
?>
<input type='text' name='spacedeck_settings[spacedeck_frontend_base_uri]' value='<?php echo $opts[spacedeck_frontend_base_uri]; ?>'>
<?php
}
function spacedeck_settings_section_callback() {
echo '';
}
function spacedeck_options_page() {
?>
<form action='options.php' method='post'>
<?php
settings_fields('pluginPage');
do_settings_sections('pluginPage');
submit_button();
?>
</form>
<?php
}
?>
{
"ok": "OK",
"cancel": "Cancelar",
"close": "Cerrar",
"open": "Abrir",
"folder": "Directorio",
"save": "Salvar",
"saved": "Salvado",
"created": "creado",
"duplicate": "Duplicar",
"delete": "Borrar",
"remove": "Eliminar",
"set": "ajustar",
"reset": "reiniciar",
"thanks": "Gracias",
"share": "Compartir",
"signup": "Regístrate",
"login": "Iniciar sesión",
"logout": "Cerrar sesión",
"email": "Correo Electrónico",
"password": "Contraseña",
"width": "Anchura",
"height": "Altura",
"nick": "Nombre",
"role": "Rol",
"members": "Miembros",
"actions": "Acciones",
"or": "o",
"you": "",
"via": "via",
"by": "por",
"zero": "Cero",
"page": "Página",
"new": "Nuevo",
"copy": "Copiar",
"home": "Inicio",
"owner": "Propietario",
"space": "Espacio",
"second": "Segundo",
"not_found": "No encontrado.",
"untitled_space": "Espacio sin título",
"untitled_folder": "Directorio sin título",
"untitled": "sin título",
"sure": "Está seguro?",
"specify": "Por favor, Especifica",
"confirm": "Por favor, Confirma",
"error_unknown_email": "Esta combinación correo electrónico/contraseña no es conocida.",
"error_password_confirmation": "La contraseña introducida no coincide.",
"error_domain_blocked": "Tu dominio está bloqueado.",
"error_user_email_already_used": "Esta dirección de correo electrónico ya se está usando.",
"support": "Soporte para Spacedeck",
"offline": "Offline. Clica para más.",
"error": "Lo siento, pero algo salió mal. Por favor, contacta con support@spacedeck.com",
"welcome": "Bienvenido",
"claim": "Tu Pizarra digital.",
"trynow": "Inténtalo ahora.",
"about": "Sobre nosotros.",
"terms": "Términos",
"contact": "Contacto",
"privacy": "Privacidad",
"business_adress": "Dirección de Negocios",
"post_adress": "Dirección postal",
"phone": "Teléfono",
"ceo": "Director gerente",
"name": "Nombre",
"confirm_subject": "Correo electrónico de confirmación de Spacedeck",
"confirm_body": "Gracias por iniciar sesión en Spacedeck.\nPor favor, clica en el siguiente enlace para confirmar tu dirección de correo electrónico.\n",
"confirm_action": "Confirmar Ahora",
"team_invite_membership_subject": "Inivitación de equipo para %s",
"team_invite_membership_body": "Has sido invitado a %s en Spacedeck. Por favor, clica en el siguiente enlace para aceptar la invitación.",
"team_invite_user_body": "Has sido invitado a %s en Spacedeck.\nTu contraseña temporal es \"%s\".\nPor favor, clica en el siguiente enlace para aceptar la invitación.",
"team_invite_admin_body": "%s fue invitado tu equipo: %s. La contraseña temporal es \"%s\".",
"team_invite_membership_acction": "Aceptar",
"team_new_member_subject": "Un nuevo Miembro para el Equipo %s se ha registrado",
"team_new_member_body": "%s se acaba de unir al Equipo %s en Spacedeck.",
"space_invite_membership_subject": "%s te invitó al Espacio %s ",
"space_invite_membership_body": "Has sido invitado por %s para unirte al Espacio %s en Spacedeck. Por favor, clica en el siguiente enlace para aceptar la invitación.",
"space_invite_membership_action": "Aceptar",
"folder_invite_membership_subject": "Espacio",
"folder_invite_membership_body": "Has sido invitado a un Equipo en Spacedeck. Por favor, clica en el siguiente enlace para aceptar la invitación.",
"folder_invite_membership_acction": "Aceptar",
"login_google": "Iniciar sesión con Google",
"save_changes": "Salvar Cambios",
"upgrade": "Mejorar",
"upgrade_now": "Mejorar ahora",
"create_space": "Crear Espacio",
"create_folder": "Crear Directorio",
"email_unconfirmed": "Correo electrónico no confirmado",
"confirmation_sent": "Correo electrónico enviado",
"folder_filter": "Filtro",
"sort_by": "Ordenar por",
"last_modified": "Última Modificación",
"last_opened": "Última Apertura",
"title": "Título",
"edit_team": "Editar Equipo",
"edit_account": "Edit Cuenta",
"log_out": "Cerrar Sesión",
"no_spaces_yet": "¡Bienvenido! Puedes crear Espacios y Directorios aquí utilizando los botones que se encuentran en la esquina superior izquierda.",
"new_folder_title": "Nuevo título para el directorio",
"folder_settings": "Ajustes de Directorio",
"upload_cover_image": "Cargar imagen de cubierta",
"spacedeck_pro_ad_folders": "Con Spacedeck Pro, puedes organizar un ilimitado número de Espacios y Directorios, y gestionar el control de acceso para cada Directorio. ¿Te gustaría aprender más sobre las características Pro?",
"spacedeck_pro_ad_versions": "Con Spacedeck Pro, puedes organizar un ilimitado número de versiones para cada Espacio así como realizar un seguimiento de su progreso o mantener instantáneas ('snapshots') seguras. ¿Te gustaría aprender más sobre las características Pro?",
"spacedeck_pro_ad_pdf": "Con Spacedeck Pro, puedes exportar tus Espacios como PDFs para su archivo, envío por correo, o impresión. ¿Te gustaría aprender más sobre las características Pro?",
"spacedeck_pro_ad_zip": "Con Spacedeck Pro, puedes exportar los contenidos de un Espacio empaquetado como un fichero ZIP. ¿Te gustaría aprender más sobre las características Pro?",
"spacedeck_pro_ad_colors": "Con Spacedeck Pro, puedes puedes usar tus propios colores usando un selector de color profesional.",
"profile_caption": "Perfil",
"upload_avatar": "Cardar Avatar",
"uploading_avatar": "Cargando Avatar…",
"avatar_dimensions": "Dimensiones recomendadas: 200×200 pixels.",
"profile_name": "Nombre",
"profile_email": "Dirección de correo electrónico",
"send_again": "Enviar de nuevo",
"confirmation_sent_long": "Correo electrónico con enlace de confirmación enviado. Por favor, revisa tu bandeja de entrada de Correo.",
"confirmation_sent_another": "Otro enlace de confirmación enviado.",
"confirmation_sent_dialog_text": "Te hemos enviado un correo explicando como confirmar tu dirección de correo electrónico.",
"payment_caption": "Pago",
"language_caption": "Idioma",
"notifications_caption": "Notificaciones",
"notifications_option_chat": "Infórmame via correo electrónico sobre nuevos cometarios",
"notifications_option_spaces": "Envíame un resumen diario de lo que sucedió en mis Espacios y Directorios.",
"password_caption": "Contraseña",
"current_password": "Contraseña Actual",
"new_password": "Nueva Contraseña",
"verify_password": "Verificar Contraseña",
"change_password": "Cambiar Contraseña",
"reset_password": "Reiniciar Contraseña",
"terminate_caption": "Borrar Cuenta",
"terminate_warning": "Si borras tu cuenta, todos los Espacios, Directorios y Mensajes (incluyendo todo el contenido que tú y otras personas crearon en tus Espacios) serán destruidos.",
"terminate_warning2": "Esta acción no puede deshacerse.",
"terminate_reason": "Mensaje",
"terminate_reason_caption": "Ayúdannos a mejorar compartiendo las razones por las que cancelas la cuenta.",
"terminate_terminate": "Terminar",
"space_blank1": "¡Bienvenido a un nuevo Espacio en blanco!",
"space_blank2": "Suelta ficheros, pega enlaces",
"space_blank3": "o utilizar las herramientas que aparecen abajo",
"space_blank4": "para rellenar este Espacio con contenido.",
"draft": "Borrador",
"publish": "Publicar",
"published": "Publicado",
"save_version": "Salvar Versión",
"version_saved": "Versión Salvada",
"post": "Publicar mensaje",
"chat_invite_cta1": "¡La Collaboración es divertida!",
"chat_invite_cta2": "¿Por qué no ",
"chat_invite_cta3": "invitar a algunas personas",
"chat_invite_cta4": "a trabajar contigo?",
"chat_message_placeholder": "Escribe tu mensaje…",
"view": "Ver",
"edit": "Editar",
"present": "Presentar",
"chat": "Chatear",
"meta": "Metadatos",
"tool_search": "Buscar",
"tool_upload": "Cargar",
"tool_text": "Texto",
"tool_shape": "Dar forma",
"tool_zones": "Zonas",
"tool_canvas": "Fondo pizarra",
"search_media": "Buscar multimedia…",
"type_here": "Escriba aquí",
"text_formats": "Formatos",
"format_p": "Párrafos",
"format_bullets": "Lista con 'Bullets'",
"format_numbers": "Lista Numérica",
"format_h1": "Titular 1",
"format_h2": "Titular 2",
"format_h3": "Titular 3",
"font_size": "Tamaño de Fuente",
"line_height": "Altura de la Línea",
"tool_align": "Alinear",
"tool_styles": "Estilos",
"tool_bullets": "'Bullets'",
"tool_numbers": "Números",
"color_fill": "Rellenar",
"color_stroke": "Trazo",
"color_text": "Texto",
"tool_type": "Tipo",
"tool_box": "Caja",
"tool_link": "Enlace",
"tool_layout": "Disposición",
"tool_options": "Opciones",
"tool_stroke": "Trazar",
"tool_delete": "Borrar",
"tool_lock": "Bloquear",
"tool_copy": "Copiar",
"stack": "Apilar",
"tool_circle": "Círculo",
"tool_hexagon": "Hexágono",
"tool_square": "Cuadrado",
"tool_diamond": "Diamante",
"tool_bubble": "Burbuja",
"tool_cloud": "Nube",
"tool_burst": "Ráfaga",
"tool_star": "Estrella",
"tool_heart": "Corazón",
"tool_scribble": "Garabatear",
"tool_line": "Líneas",
"tool_arrow": "Flecha",
"search_media_placeholder": "Buscar multimedia en web…",
"add_zone": "Nueva Zona",
"palette": "Paleta",
"picker": "Selector",
"background_image_caption": "Imagen",
"background_color_caption": "Color",
"upload_background_caption": "Clica para cargar una imagen de fondo",
"upload_background": "Cargar Fundo",
"access_caption": "Acceso",
"versions_caption": "Versiones",
"info_caption": "Información",
"mode_private": "Privado: Solo miembros pueden visualizar o editar",
"mode_public": "Público: Cualquiera con el enlace puede visualizar",
"invite_collaborators": "Invitar Colaboradores",
"revoke_access": "Anular Acceso",
"invite": "Enviar Invitaciones",
"invitee_email_address": "Dirección de correo electrónico del nuevo miembro",
"optional_message": "Mensaje optional",
"role_viewer": "Visualizador",
"role_editor": "Editor",
"role_admin": "Administrador",
"new_space_title": "Nuevo título para el Espacio",
"team": "Equipo",
"search": "Buscar",
"search_no_results": "Búsqueda sin resultados",
"search_clear": "Limpiar búsqueda",
"rename": "Renombrar",
"mobile": "teléfono móvl",
"image": "imagen",
"tool_filter": "fíltro",
"canel": "canel",
"invite_membership_action": "Acción afiliación de miembros",
"viewer": "visualizador",
"editor": "editor",
"admin": "administrador",
"logging_in": "iniciando sesión",
"password_confirmation": "Confirmación de Contraseña",
"confirm_again": "Te hemos enviado un correo electrónico explicando cómo puedes confirmar tu dirección de correo electrónico.",
"confirmed": "Tú Cuenta ha sido confirmada satisfactoriamente. Gracias.",
"signing_up": "Registrándote",
"password_check_inbox": "Por favor, comprueba tu bandeja de entrada de correo electrónico",
"new_space": "Nuevo Espacio",
"tool_more": "Más",
"what_is_your_name": "¡Bienvenido a %s! Por favor, elige un nombre de usuario.",
"lang": "es",
"landing_title": "Tu Pizarra en la Web.",
"landing_claim": "Spacedeck te permite combinar fácilmente todo tipo de multimedia en pizarras virtuales: notas de texto, fotos, enlaces web, incluso videos y grabaciones de audio. ",
"landing_example": "Las personas usan Spacedeck para organizar en equipo sus ideas y así poder ver proyectos completos de un vistazo, o bien en escuelas y universidades para obtener experiencias de aprendizaje más enriquecedoras y conectadas.",
"spaces": "Mis Espacios",
"access_editor_link": "Enlace de Edición Instantanea",
"access_editor_link_desc": "Proporciona este enlace a cualquier persona que deba poder editar instantáneamente este Espacio, no se requiere una cuenta: ",
"access_editor_link_desc_slug": "Este enlace también contiene el nombre del Espacio. ",
"access_anonymous_edit_blocking": "Los editores anónimos únicamente pueden cambiar sus propios elementos",
"access_current_members": "Miembros Actuales",
"access_new_members": "Invita Nuevos Miembros",
"access_no_members": "Los Miembros de este Espacio se mostrarán aquí.",
"comments": "comentarios",
"landing_customers": "Confiado por multitudes.",
"landing_features_title": "Sencillo de usar.",
"landing_features_text": "El nuevo Spacedeck 6 tiene un hermoso y optimizado interfaz de usuario que hace que tu trabajo sea más fácil y divertido que nunca, al tiempo que te brinda funciones aún más poderosas:",
"landing_features_1": "<b>Arrastra & suelta</b> imágenes, vídeos y áudios desde tu computadora o desde la web",
"landing_features_2": "<b>Escribe texto y formatéalo</b> con pleno control sobre fuente, color y estilo",
"landing_features_3": "<b>Dibuja, anota y resalta</b> incluyendo contornos gráficos",
"landing_features_4": "Convierte tu tablero en un <b>área de presentación con zoom</b>",
"landing_features_5": "<b>Colabora y chatea</b> en tiempo real con compañeros de equipo, alumnos y amigos.",
"landing_features_6": "<b>Comparte Espacios</b> en la web o via correo electrónico",
"landing_features_7": "<b>Exporta tu trabajo</b> como fichero imprimible PDF o como ZIP",
"landing_pricing": "Increiblemente asequible.",
"landing_pricing_lite": "Uso Libre/Personal",
"landing_pricing_lite_text": "La versión sencilla y completa para recopilar imágenes y tomar notas.",
"landing_pricing_pro_features_list": "<ul><li>Espacios ilimitados</li><li>Estructura de Directorios</li><li>Exportación a ficheros PDF y ZIP</li><li>Sin Marcas de Agua</li><li>Personaliza tu fondo</li><li>Historial de Actividad</li><li>20 GB de Almacenamiento</li><ul>",
"landing_pricing_pro": "€4,90/Usuario/Mes <br><small>o 49,90/Usuario/Año</small>",
"landing_pricing_pro_text": "Con todo la potencia que esperas.",
"landing_pricing_pro_features": "Con toda la potencia que esperas.",
"welcome_subject": "Bienvenido a Spacedeck",
"welcome_body": "¡Hola!\nGracias por registrárte en Spacedeck.<br>Esperamos que disfrutes trabajando con Espacios.<br>Recuerda, tu cuenta incluye colaboradores ilimitados. Siénte libre de compartir tus Espacios con amigos y colegas de todo el mundo.",
"invite_emails": "Dirección/ones de correo electrónico separadas por coma (,)",
"history_recently_updated": "Recientemente Actualizado",
"history_recently_empty": "Aún no ha pasado nada.",
"parent_folder": "Directorio padre",
"created_by": "Creado por",
"last_updated": "Última actualización",
"feedback_sent": "¡Muchas gracias por tu comentarios!",
"role_member": "Miembro",
"team_invite_membership_action": "Aceptar invitación",
"space_message_subject": "Nuevo Mensaje en el Espacio %s",
"space_message_body": "%s escribió en %s: \n",
"pro_ad_history_headline": "Cuando actualices a Spacedeck Pro, verás el historial de actualizaciones recientes en todos tus Espacios (compartidos) aquí.",
"password_reset_subject": "Restablecer contraseña para Spacedeck",
"password_reset_body": "Has solicitado el restablecimiento de tu contraseña en Spacedeck.\nPor favor, clica en el siguiente enlace para establecer una nueva contraseña.",
"password_reset_action": "Restablecer Ahora",
"was_offline": "La conexión con Spacedeck se ha interrupido. Si tienes trabajo sin salvar, mantén abierta, por favor, esta pestaña del navegadorhasta que la conexión esté restablecida, entonces toca los objetos no salvados.",
"subscription_failed_user_subject": "Problemas con el pago en tu Spacedeck",
"subscription_failed_user_body": "Desafortunadamente, no pudimos procesar su método de pago. Puede crear fácilmente un nuevo método de pago que incluya PayPal en la configuración de su cuenta.",
"subscription_failed_team_subject": "Problemas con el pago en tu Spacedeck",
"subscription_failed_team_body": "Desafortunadamente, no pudimos procesar su método de pago para tu Cuenta de Equipo. Corrija su método de pago lo antes posible.",
"team_name": "Nombre del Equipo",
"subdomain": "Subdominio",
"team_adresses": "Direcciones de correo electrónico del Equipo",
"add": "Añadir",
"invited": "invitado",
"duplicate_destination": "¿En qué directorio quieres duplicar este Espacio??",
"duplicate_confirm": "Duplicar %s en la directorio %s?",
"duplicate_success": "%s fue duplicado en %s.",
"goto_space": "Ve al Espacio %s",
"goto_folder": "Ve al Directorio %s",
"stay_here": "Permanece aquí",
"sharing": "Compartiendo",
"list": "Lista para Exportar",
"link": "Enlace",
"download_space": "Espacio de Descarga",
"type": "Tipo",
"download": "Descarga",
"Previous Zone": "Zona Previa",
"Next Zone": "Zona Siguiente",
"promote": "Promover",
"demote": "Degradar",
"more": "Más",
"lock": "Bloquear",
"unlock": "Desbloquear",
"follow_present": "Seguir",
"mute_present": "Dejar de Seguir",
"follow_present_help": "Si alguien más está presentando este espacio, los otros miembros siguen automáticamente la presentación. Active o desactive el seguimiento con este botón.",
"export": "exportar"
}
{
"ok": "D'acòrdi",
"cancel": "Anullar",
"close": "Tampar",
"open": "Dobrir",
"folder": "Repertòri",
"save": "Enregistrar",
"saved": "Enregistrat",
"created": "creat",
"duplicate": "Duplicar",
"delete": "Suprimir",
"remove": "Suprimir",
"set": "definir",
"reset": "reïnicializar",
"thanks": "Mercés",
"share": "Partejar",
"signup": "S’inscriure",
"login": "Connexion",
"logout": "Se desconnectar",
"email": "Adreça electronica",
"password": "Senhal",
"width": "Largor",
"height": "Nautor",
"nick": "Escais",
"role": "Ròtle",
"members": "Membres",
"actions": "Accions",
"or": "o",
"you": "vos",
"via": "via",
"by": "per",
"zero": "Zéro",
"page": "Pagina",
"new": "Nòu",
"copy": "Copiar",
"home": "Acuèlh",
"owner": "Proprietari",
"space": "Espaci",
"second": "Segond",
"not_found": "Pas trobat.",
"untitled_space": "Espaci sens nom",
"untitled_folder": "Repertòri sens nom",
"untitled": "sens títol",
"sure": "O volètz vertadièrament ?",
"specify": "Mercés d’especificar",
"confirm": "Mercés de confirmar",
"error_unknown_email": "Aquesta combinason d’adreça electronica/senhal es desconeguda.",
"error_password_confirmation": "Los senhals picats correspondon pas.",
"error_domain_blocked": "Lo domeni es blocat.",
"error_user_email_already_used": "Aquesta adreça es ja utilizada.",
"support": "Assisténcia Spacedeck",
"offline": "Fòra linha. Clicatz per mai d’opcions.",
"error": "O planhèm, quicòm a trucat. Mercés de contactar support@spacedeck.com",
"welcome": "La benvenguda",
"claim": "Vòstre tablèu numeric.",
"trynow": "Ensajatz ara.",
"about": "A prepaus de nosautre",
"terms": "Tèrmes",
"contact": "Contacte",
"privacy": "Confidencialitat",
"business_adress": "Adreça professionala",
"post_adress": "Adreça postala",
"phone": "Telefòn",
"ceo": "Gestionari",
"name": "Nom",
"confirm_subject": "Corrièl de confirmacion de Spacedeck",
"confirm_body": "Mercés de vòstra inscripcion a Spacedeck.\nMercés de clicar lo ligam seguent per confirmar vòstra adreça electronica.\n",
"confirm_action": "Confirmar",
"team_invite_membership_subject": "Invitacion d’equipa per %s",
"team_invite_membership_body": "Qualqu’un vos a convidat a %s sus Spacedeck. Mercés de clicar sul ligam seguent per acceptar l’invitacion.",
"team_invite_user_body": "Qualqu’un vos a convidat a %s sus Spacedeck.\nVòstre senhal temporari es « %s ».\nMercés de clicar sul ligam seguent per acceptar l’invitacion.",
"team_invite_admin_body": "%s es estat convidat a vòstra equipa : %s. Lo senhal temporari es « %s ».",
"team_invite_membership_acction": "Acceptar",
"team_new_member_subject": "Membre novèl",
"team_new_member_body": "%s a rejonch l’equipa %s sus Spacedeck",
"space_invite_membership_subject": "Invitacion Espaci per %s : %s",
"space_invite_membership_body": "%s vos a convit a l’Espaci « %s »",
"space_invite_membership_action": "Acceptar l’invitacion",
"folder_invite_membership_subject": "Espaci",
"folder_invite_membership_body": "Qualqu’un vos a convidat a Team sus Spacedeck. Clicatz lo ligam seguent per acceptar l’invitacion.",
"folder_invite_membership_acction": "Acceptar",
"login_google": "S’identificar amb Google",
"save_changes": "Enregistrar las modificacions",
"upgrade": "Metre a jorn",
"upgrade_now": "Metre a nivèl ara",
"create_space": "Crear un espaci",
"create_folder": "Crear un repertòri",
"email_unconfirmed": "Adreça pas confirmada",
"confirmation_sent": "Messatge enviat",
"folder_filter": "Filtre",
"sort_by": "Triar per",
"last_modified": "Darrièra modificacion",
"last_opened": "Darrièra dobertura",
"title": "Títol",
"edit_team": "Modificar equipa",
"edit_account": "Modificar compte",
"log_out": "Se desconnectar",
"no_spaces_yet": "Avètz pas encara creat cap d’espacis.",
"new_folder_title": "Novèl títol pel repertòri",
"folder_settings": "Paramètres repertòri",
"upload_cover_image": "Enviar imatge cobèrta",
"spacedeck_pro_ad_folders": "Avec Spacedeck Pro, vous pouvez organiser un nombre illimité de espaces dans les dossiers et gérer les contrôles d'accès pour chaque dossier. Voulez-vous en savoir plus sur les fonctionnalités Pro ?",
"spacedeck_pro_ad_versions": "Avec Spacedeck Pro, vous pouvez enregistrer des versions illimitées de chaque espace pour suivre vos progrès ou de conserver des instantanés sécurité. Voulez-vous en savoir plus sur les fonctionnalités Pro ?",
"spacedeck_pro_ad_pdf": "Avec Spacedeck Pro, vous pouvez exporter vos espaces et même des dossiers entiers belles PDF pour l'archivage, de diffusion, ou autour de l'impression. Voulez-vous en savoir plus sur les fonctionnalités Pro ?",
"spacedeck_pro_ad_zip": "Avec Spacedeck Pro, vous pouvez exporter le contenu d'un espace comme un paquet ZIP. Voulez-vous en savoir plus sur les fonctionnalités Pro ?",
"spacedeck_pro_ad_colors": "Avec Spacedeck Pro, vous pouvez mélanger vos propres couleurs en utilisant un sélecteur de couleur professionnelle.",
"profile_caption": "Perfil",
"upload_avatar": "Enviar avatar",
"uploading_avatar": "Mandadís avatar…",
"avatar_dimensions": "Dimensions recomandadas : 200x200 pixèls.",
"profile_name": "Nom",
"profile_email": "Adreça electronica",
"send_again": "Tornar enviar",
"confirmation_sent_long": "Ligam de confirmacion enviat. Mercés de verificar vòstres corrièrs.",
"confirmation_sent_another": "Un autre ligam de confirmacion enviat.",
"confirmation_sent_dialog_text": "Avèm enviat un corrièl qu’explica cossí confirmar vòstra adreça electronica.",
"payment_caption": "Pagament",
"language_caption": "Lenga",
"notifications_caption": "Notificacions",
"notifications_option_chat": "Enviatz-me de comentaris novèls per corrièl",
"notifications_option_spaces": "Enviatz-me un resumit jornadièr de las modificacions dels espacis",
"password_caption": "Senhal",
"current_password": "Senhal actual",
"new_password": "Senhal novèl",
"verify_password": "Verificar lo senhal novèl",
"change_password": "Modificar senhal",
"reset_password": "Reïnicializar senhal",
"terminate_caption": "Suprimir lo compte",
"terminate_warning": "En escafant vòstre compte, vòstres messatges, espacis, repertòris e lor contengut seràn suprimits. Aquesta accion pòt pas èsser anullada.",
"terminate_warning2": "Aquò pòt pas èsser anullat.",
"terminate_reason": "Messatge",
"terminate_reason_caption": "Ajudatz-nos a melhorar lo logicial en nos diguent las rasons de la supression de vòstre compte",
"terminate_terminate": "Suprimir vòstre compte per totjorn ?",
"space_blank1": "Aquò es vòstre novèl espaci",
"space_blank2": "Lisatz de fichièrs, pegatz de ligams",
"space_blank3": "o utilizatz las aisinas",
"space_blank4": "Siatz creatius !",
"draft": "Borrolhon",
"publish": "Publicar",
"published": "Publicat",
"save_version": "Enregistrar version",
"version_saved": "Version enregistrada",
"post": "Publicar messatge",
"chat_invite_cta1": "Collaboratz amb amusament !",
"chat_invite_cta2": "Perqué pas ",
"chat_invite_cta3": "convidar de monde",
"chat_invite_cta4": "per trabalhar amb vos ?",
"chat_message_placeholder": "Escrivètz vòstre messatge…",
"view": "Afichatge",
"edit": "Edicion",
"present": "Present",
"chat": "Messatjariá",
"meta": "Mèta",
"tool_search": "Recercar",
"tool_upload": "Enviar",
"tool_text": "Tèxte",
"tool_shape": "Forma",
"tool_zones": "Zònas",
"tool_canvas": "Canvas",
"search_media": "Cercar de mèdias…",
"type_here": "Picatz aquí",
"text_formats": "Formats",
"format_p": "Paragraph",
"format_bullets": "Lista a piuses",
"format_numbers": "Lista numeratada",
"format_h1": "Títol 1",
"format_h2": "Títol 2",
"format_h3": "Títol 3",
"font_size": "Font Size",
"line_height": "Nnautor de linha",
"tool_align": "Alinhar",
"tool_styles": "Estils",
"tool_bullets": "Bullets",
"tool_numbers": "Nombres",
"color_fill": "Fill",
"color_stroke": "Traçat",
"color_text": "Tèxte",
"tool_type": "Tipe",
"tool_box": "Bóstia",
"tool_link": "Ligam",
"tool_layout": "Agençament",
"tool_options": "Opcions",
"tool_stroke": "Traçat",
"tool_delete": "Suprimir",
"tool_lock": "Verrolhar",
"tool_copy": "Copiar",
"stack": "Pila",
"tool_circle": "Cercle",
"tool_hexagon": "Exagòn",
"tool_square": "Carrat",
"tool_diamond": "Diamond",
"tool_bubble": "Bulla",
"tool_cloud": "Nívol",
"tool_burst": "Burst",
"tool_star": "Star",
"tool_heart": "Còr",
"tool_scribble": "Barbolhatge",
"tool_line": "Linha",
"tool_arrow": "Sageta",
"search_media_placeholder": "Cercar de mèdias web…",
"add_zone": "Zòna novèla",
"palette": "Paleta",
"picker": "Pipeta",
"background_image_caption": "Imatge",
"background_color_caption": "Color",
"upload_background_caption": "Clicar per enviar un imatge de rèireplan",
"upload_background": "Enviar rèireplan",
"access_caption": "Accès",
"versions_caption": "Versions",
"info_caption": "Info",
"mode_private": "Privat : sonque los membres pòdon veire o modificar",
"mode_public": "Public : qual que siá amb lo ligam pòt veire",
"invite_collaborators": "Convidar collaborators",
"revoke_access": "Revocar l’accès",
"invite": "Enviar invitacions",
"invitee_email_address": "Adreça electronica del novèl membre",
"optional_message": "Messatge opcional",
"role_viewer": "Visualizaira",
"role_editor": "Editor",
"role_admin": "Admin",
"new_space_title": "Títol novèl per l’Espaci",
"team": "Equipa",
"search": "Recercar",
"search_no_results": "search_no_results",
"search_clear": "search_clear",
"rename": "Renomenar",
"mobile": "mobil",
"image": "imatge",
"tool_filter": "filtre",
"canel": "canel",
"invite_membership_action": "invite_membership_action",
"viewer": "visualizaira",
"editor": "editor",
"admin": "admin",
"logging_in": "connexion",
"password_confirmation": "Confirmacion del senhla",
"confirm_again": "Mercés de consultar vòstra bóstia de recepcion per confirmar vòstra adreça.",
"confirmed": "Vòstre compte es estat corrèctament confirmat. Mercés.",
"signing_up": "Inscripcion",
"password_check_inbox": "Verificatz vòstra bóstia de recepcion",
"new_space": "Espaci novèl",
"tool_more": "Mai",
"what_is_your_name": "La benvenguda a %s ! Mercés de causir un escais-nom.",
"lang": "en",
"landing_title": "Vòstre tablèu blanc sul Web.",
"landing_claim": "Spacedeck vos permet de facilament combinar quin que siá tipe de mèdias sus un tablèu virtual : tèxte, nòtas, ligams web, amai vidèos e enregistraments àudio. ",
"landing_example": "Lo monde utiliza Spacedeck per organizar lors idèas, en equipa per veire totes los projèctes en una ulhada, a l’escòla e a l’universitat pels mai rics, experiéncia d’aprendissatge connectat.",
"spaces": "Mos espacis",
"access_editor_link": "Ligam de modificacion dirècta",
"access_editor_link_desc": "Donatz aqueste ligam a qualqu’un que deu poder modificar dirèctament aqueste Espaci, cap de compte pas requerit : ",
"access_editor_link_desc_slug": "Aqueste ligam conten lo nom de l’espaci, tanben. ",
"access_anonymous_edit_blocking": "Los convidats pòdon pas modificar los elements qu’an creats.",
"access_current_members": "Membres actuals",
"access_new_members": "Convidar de novèls membres",
"access_no_members": "Los membres d’aqueste Espacii apreissaràn aquí.",
"comments": "comentaris",
"landing_customers": "La fisança de milièr de personas.",
"landing_features_title": "Un jòc d'enfants d’utilizar.",
"landing_features_text": "Le tout nouveau Spacedeck 5 vous permet de travailler bien plus facilement grâce à sa magnifique interface simplifiée.",
"landing_features_1": "Glissez & déposez images, vidéos et audios de votre ordinateur ou du web",
"landing_features_2": "Ecrivez directement sur l'espace et choisissez les polices de caractère, couleurs et styles",
"landing_features_3": "Dessinez, annotez et surlignez grâce aux formes graphiques intégrées",
"landing_features_4": "Transformez votre espace en une présentation dynamique",
"landing_features_5": "Collaborez et discutez en temps réel avec vos collègues, élèves et amis",
"landing_features_6": "Partagez vos espaces sur le web ou par email",
"landing_features_7": "Exportez votre espace en PDF pour l'imprimer",
"landing_pricing": "Incroyablement abordable.",
"landing_pricing_lite": "Usage personnel",
"landing_pricing_lite_text": "La version de base, bien arrondi pour recueillir des images et de garder des notes.",
"landing_pricing_pro_features_list": "<ul><li>Unlimited Spaces</li><li>Exporter PDF, ZIP</li><li>No Watermarks</li><li>Image de fonds</li><li>Activity History</li><li>20 Go de stockage</li><ul>",
"landing_pricing_pro": "€4,90/User/Mo. <br><small> €49,90/User/Year</small>",
"landing_pricing_pro_text": "Avec toute la puissance que vous attendez.",
"landing_pricing_pro_features": "€4,90/User/Mo. <br><small> €49,90/User/Year</small>",
"welcome_subject": "La benvenguda a Spacedeck",
"welcome_body": "Mercés per vòstra inscripcion a Spacedeck.\nEsperam qu’auretz plaser a trabalhar dins los Espacis. <br> Oblidetz pas que vòstre compte conten un nombre illimitat de collaborators. <br> Esitetz pas a partejar vòstres espacis amb los amics e collègas del monde entièr.",
"invite_emails": "Picatz las adreças mails (separadas per de vergulas)",
"history_recently_updated": "Novèlas",
"history_recently_empty": "Pas res",
"parent_folder": "Repertòri parent",
"created_by": "Creat per",
"last_updated": "Darrièra mesa a jorn",
"feedback_sent": "Comentari enviat",
"role_member": "Membre",
"team_invite_membership_action": "Acceptar",
"space_message_subject": "A publicat sus %s",
"space_message_body": "%s a comentat dins %s :\n",
"pro_ad_history_headline": "Aprèp una mesa a nivèl podètz obténer un apercebut de totas las activitats actualas dels espacis aquí.",
"password_reset_subject": "Reïnicializar lo senhal per Spacedeck",
"password_reset_body": "Òu !<br><br>Avètz demandat la reïnicializacion del senhal.<br>Mercés de clicar sul ligam seguent per ne causir un novèl.<br>",
"password_reset_action": "Reïnicializar ara",
"was_offline": "La connexion a Spacedeck es estada copada. S’avètz de trabalh pas enregistratz, gardatz aqueste onglet de navigador dobèrt fins que la connexion siá restablida puèi tocatz de nòu los elements pas enregistrats.",
"subscription_failed_user_subject": "Problèma amb lo pagament Spacedeck",
"subscription_failed_user_body": "Unfortunately, we could not process your Payment-method. You can easly create a new payment method including PayPal in your account settings.",
"subscription_failed_team_subject": "Problem with your Spacedeck Payment",
"subscription_failed_team_body": "Unfortunately, we could not process your Payment-method for your Team-Account. Please fix your payment method asap.",
"team_name": "Nom de l’equipa",
"subdomain": "jos-domeni",
"team_adresses": "Adreças equipa",
"add": "Ajustar",
"invited": "convidat",
"duplicate_destination": "Seleccionatz lo repertòri de destinacion",
"duplicate_confirm": "Duplicar %s dins %s ?",
"duplicate_success": "%s es estat duplicat dins %s.",
"goto_space": "anar a l’espaci",
"goto_folder": "anar al repertòri",
"stay_here": "Demorar aquí",
"sharing": "partatge",
"list": "lista",
"link": "Ligam",
"download_space": "Telecargar espaci",
"type": "Tipe",
"download": "Telecargar",
"Previous Zone": "Zòna precedenta",
"Next Zone": "Zòna seguenta",
"promote": "Promòure",
"demote": "Retrogradar",
"more": "Mai",
"lock": "Verrolhar",
"unlock": "Desverrolhar",
"follow_present": "Seguir",
"mute_present": "Quitar de seguir",
"follow_present_help": "follow_present_help",
"export": "exportar"
}
......@@ -4,27 +4,6 @@ require('../models/db');
var config = require('config');
const redis = require('../helpers/redis');
// FIXME TODO object.toJSON()
var saveAction = (actionKey, object) => {
if (object.constructor.modelName == "Space")
return;
let attr = {
action: actionKey,
space: object.space_id || object.space,
user: object.user_id || object.user,
editor_name: object.editor_name,
object: object
};
/*let action = new Action(attr);
action.save(function(err) {
if (err)
console.error("saved create action err:", err);
});*/
};
module.exports = (req, res, next) => {
res.header("Cache-Control", "no-cache");
......@@ -36,21 +15,18 @@ module.exports = (req, res, next) => {
if (!object) return;
redis.sendMessage("create", model, object, req.channelId);
this.status(201).json(object);
saveAction("create", object);
};
res['distributeUpdate'] = function(model, object) {
if (!object) return;
redis.sendMessage("update", model, object, req.channelId);
this.status(200).json(object);
saveAction("update", object);
};
res['distributeDelete'] = function(model, object) {
if (!object) return;
redis.sendMessage("delete", model, object, req.channelId);
this.sendStatus(204);
saveAction("delete", object);
};
next();
......
......@@ -4,6 +4,25 @@ const db = require('../models/db');
var config = require('config');
module.exports = (req, res, next) => {
// authentication via API token
const api_token = req.headers["x-spacedeck-api-token"];
if (api_token && api_token.length>7) {
db.User.findOne({where: {api_token: api_token}}).then(user => {
req.user = user;
next();
}).error(err => {
res.status(403).json({
"error": "invalid_api-token"
});
next();
});
return;
}
// authentication via session/cookie
const token = req.cookies["sdsession"];
if (token && token != "null" && token != null) {
......@@ -44,4 +63,3 @@ module.exports = (req, res, next) => {
next();
}
}
'use strict';
const db = require('../models/db');
const { Op } = require("sequelize");
var config = require('config');
module.exports = (req, res, next) => {
......@@ -53,15 +54,14 @@ module.exports = (req, res, next) => {
'email': 1
};
// find space by id or slug
db.Space.findOne({where: {
"_id": spaceId
[Op.or]: [
{"_id": spaceId},
{"edit_slug": spaceId}
]
}}).then(function(space) {
//.populate("creator", userMapping)
//if (err) {
// res.status(400).json(err);
//} else {
if (space) {
if (space.access_mode == "public") {
if (space.password) {
......
const Umzug = require('umzug');
const config = require('config')
function sequel_log(a,b,c) {
console.log(a);
......@@ -17,7 +18,7 @@ const sequelize = new Sequelize('database', 'username', 'password', {
},
// SQLite only
storage: 'database.sqlite',
storage: config.get('storage_local_db'),
logging: sequel_log,
// http://docs.sequelizejs.com/manual/tutorial/querying.html#operators
......@@ -42,6 +43,7 @@ module.exports = {
avatar_thumb_uri: Sequelize.STRING,
confirmation_token: Sequelize.STRING,
password_reset_token: Sequelize.STRING,
api_token: Sequelize.STRING,
home_folder_id: Sequelize.STRING,
prefs_language: Sequelize.STRING,
prefs_email_notifications: Sequelize.STRING,
......@@ -50,6 +52,17 @@ module.exports = {
updated_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW}
}),
CreatorSafeInclude: function(db) {
return {
model: this.User,
as: 'creator',
attributes: ['_id','email','nickname',
'avatar_original_uri',
'avatar_thumb_uri',
'created_at','updated_at']
};
},
Session: sequelize.define('session', {
token: {type: Sequelize.STRING, primaryKey: true},
user_id: Sequelize.STRING,
......@@ -91,7 +104,8 @@ module.exports = {
user_id: Sequelize.STRING,
role: Sequelize.STRING,
code: Sequelize.STRING,
state: {type: Sequelize.STRING, defaultValue: "pending"},
state: {type: Sequelize.STRING, defaultValue: "pending"}, // valid: "pending", "active"
email_invited: Sequelize.STRING,
created_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW},
updated_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW}
}),
......@@ -278,21 +292,20 @@ module.exports = {
getUserRoleInSpace: (originalSpace, user, cb) => {
originalSpace.path = [];
console.log("getUserRoleInSpace",originalSpace._id,user._id,user.home_folder_id);
if (originalSpace._id == user.home_folder_id || (originalSpace.creator_id && originalSpace.creator_id == user._id)) {
cb("admin");
} else {
var findMembershipsForSpace = function(space, allMemberships, prevRole) {
Membership.findAll({ where: {
"space": space._id
"space_id": space._id
}}).then(function(parentMemberships) {
var currentMemberships = parentMemberships.concat(allMemberships);
if (space.parent_space_id) {
Space.findOne({ where: {
"_id": space.parent_space_id
}}, function(err, parentSpace) {
}}).then(function(parentSpace) {
findMembershipsForSpace(parentSpace, currentMemberships, prevRole);
});
} else {
......
Supports Markdown
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