/* global __dirname */ /* jshint strict:false */ "use strict"; var express = require('express'); var bodyParser = require('body-parser'); var slug = require('slug'); var beautify = require("json-beautify"); var _ = require('lodash'); var fs = require('fs'); var path = require('path'); var Promise = require('bluebird'); var Mustache = require('mustache'); var app = express(); var ExampleStore = require('./lib/ExampleStore'); var indexTpml = fs.readFileSync(__dirname + '/html/index.mustache.html').toString(); var sandboxTpml = fs.readFileSync(__dirname + '/html/template.mustache.html').toString(); Promise.promisifyAll(fs); var exStore = new ExampleStore(__dirname + '/exemples'); exStore.init() .then(() => console.log(exStore.getMenu())); // Initialize Express app: root folder as static, body parsers app.use(express.static(__dirname)); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); function addExample(slug, title) { examples.push({ slug: slug, title: title }); return fs.writeFileAsync(examplesJSON, beautify(examples, null, 2, 100)); } function readConfigJson(exampleSlug) { console.log(exampleSlug); return require('./exemples/jquery/' + exampleSlug + '/config.json'); } function readFileAsync(file) { return fs.readFileAsync(file) .then(buf => (buf.toString())); } function readFilesAsync(fullPath, files) { // console.log('reading files', files, 'from path', path); return Promise.reduce(files, (carry, f) => readFileAsync(fullPath + '/' + f) .then(content => (carry.concat([{ type: path.extname(f).substr(1), name: f, content }])) ), [] ); } function readExampleFiles(repoSlug, exampleSlug, config) { const exampleDir = __dirname + '/exemples/' + repoSlug + '/' + exampleSlug; const libsCssDir = __dirname + '/css/vendor'; const libsJsDir = __dirname + '/js/vendor'; const { html, js, css } = config; // libsCss, libsJs const files = [].concat(html, js, css); return readFilesAsync(exampleDir, files); } /** * Index page: render with only repo list in menu */ app.get('/', function(req, res) { const menuRepo = exStore.getRepoMenu(); // const title = 'Home'; console.log(menuRepo); res.send(Mustache.render(indexTpml, { title, menuRepo })); }); /** * Repo page: render with repo list and selected repo's example list in menu */ app.get('/:repoSlug', function(req, res) { const repo = exStore.getRepo(req.params.repoSlug); if(! repo) { return res.status(404).send('Repo ' + req.params.repoSlug + ' not found'); } const menuRepo = exStore.getRepoMenu(); const menuExample = exStore.getExampleMenu(repo.path); // const title = 'Home'; console.log(menuExample); res.send(Mustache.render(indexTpml, { // title, menuRepo, menuExample })); }); /** * Example page: render with repo list and selected repo's example list in menu, * and the editor with the selected example */ app.get('/:repoSlug/:exampleSlug', function(req, res) { const repo = exStore.getRepo(req.params.repoSlug); if(! repo) { return res.status(404).send('Repo ' + req.params.repoSlug + ' not found'); } const menuRepo = exStore.getRepoMenu(); const menuExample = exStore.getExampleMenu(repo.path); const example = _.find(repo.examples, { slug: req.params.exampleSlug }); if(! example) { return res.status(404).send('Example ' + req.params.repoSlug + '/' + req.params.exampleSlug + ' not found'); } // const title = 'Home'; console.log(menuExample); const { repoSlug, exampleSlug } = req.params; readExampleFiles(repoSlug, exampleSlug, example) .then(files => { // console.log('example files', html, js, css); res.send(Mustache.render(indexTpml, { // title, menuRepo, menuExample, files, filesJSON: JSON.stringify(files) })); }); }); app.post('/examples', function(req, res) { var title = req.body.title; if(! req.body.title) { res.status(400).send('Le titre ne peut pas être vide !'); } var existingTitle = _.find(examples, { title: title }); if(existingTitle) { res.status(400).send("L'exemple '" + title + "' existe déjà !"); } var exampleSlug = slug(req.body.title.toLowerCase()); var targetDir = __dirname + '/exemples/' + exampleSlug; fs.mkdirAsync(targetDir) .then(() => Promise.map( ['contenu.html', 'script.js'], f => fs.writeFileAsync(targetDir + '/' + f, '') )) .then(files => addExample(exampleSlug, title)) .then(() => res.json({ slug: exampleSlug, title: title })); }); app.get('/examples/:slug', function(req, res) { const { slug } = req.params; const config = readConfigJson(slug); const { title, html, js, css, libsCss, libsJs } = config; readFileAsync(__dirname + '/exemples/' + slug + '/example.html') .then(body => Mustache.render(sandboxTpml, { body, slug, title, js, css, libsCss, libsJs }) ) .then(html => res.send(html)); }); app.get('/menu', (rea, res) => { res.send(exStore.getMenu()); }); app.get('/list/:repoPath', function(req, res) { const { repoPath } = req.params; const repo = exStore.getList(repoPath); if(! repo) { return res.status(404).send('Repo ' + repoPath + ' not found'); } console.log('found repo', repo); const data = repo.examples.map(e => ( { slug: e.slug, title: e.title } )); res.json(data); }); app.put('/examples/:slug', function(req, res) { var slug = req.params.slug; var existing = _.find(examples, { slug: slug }); if(! existing) { res.status(404).send("L'exemple avec l'identifiant '" + slug + "' est introuvable !"); } var targetDir = __dirname + '/exemples/' + slug; if(req.body.html) { fs.writeFileSync(targetDir + '/contenu.html', req.body.html); } if(req.body.javascript) { fs.writeFileSync(targetDir + '/script.js', req.body.javascript); } var theDate = new Date(); console.log(theDate.getHours() + ':' + theDate.getMinutes() + " - Sauvegarde de l'exemple '" + existing.title + " effectuée'"); res.json({ success: true }); }); module.exports = app;