sandboxApp.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* global __dirname */
  2. /* jshint strict:false */
  3. "use strict";
  4. var express = require('express');
  5. var bodyParser = require('body-parser');
  6. var slug = require('slug');
  7. var beautify = require("json-beautify");
  8. var _ = require('lodash');
  9. var path = require('path');
  10. var Mustache = require('mustache');
  11. var app = express();
  12. var fs = require('fs');
  13. var Promise = require('bluebird'); Promise.promisifyAll(fs);
  14. var sandboxTpml = fs.readFileSync(__dirname + '/html/template.mustache.html').toString();
  15. var ExampleStore = require('./lib/ExampleStore');
  16. var examplesDir = __dirname + '/exemples';
  17. // var examplesDir = __dirname + '/test/integration/test-examples';
  18. var exStore = new ExampleStore(examplesDir);
  19. var {
  20. readFileAsync,
  21. readFilesAsync
  22. } = require('./lib/fsio');
  23. var {
  24. getAcceptLanguage,
  25. getIndexBare,
  26. getIndexRepo,
  27. getIndexExample
  28. } = require('./lib/indexHandlers')(exStore, examplesDir);
  29. /**
  30. * Initialize example store
  31. */
  32. exStore.init();
  33. // .then(() => console.log(exStore.getMenu()));
  34. /**
  35. * Initialize Express app:
  36. * - root folder as static
  37. * - body parsers
  38. * - browser language detection middleware
  39. */
  40. app.use(express.static(__dirname));
  41. app.use(bodyParser.json());
  42. app.use(bodyParser.urlencoded({ extended: true }));
  43. app.use(getAcceptLanguage);
  44. function addExample(slug, title) {
  45. return fs.writeFileAsync(examplesJSON, beautify(examples, null, 2, 100));
  46. }
  47. function readConfigJson(exampleSlug) {
  48. console.log(exampleSlug);
  49. return require('./exemples/jquery/' + exampleSlug + '/config.json');
  50. }
  51. /**
  52. * Index page: render with only repo list in menu
  53. */
  54. app.get('/', getIndexBare);
  55. /**
  56. * Repo page: render with repo list and selected repo's example list in menu
  57. */
  58. app.get('/:repoSlug', getIndexRepo);
  59. /**
  60. * Example page: render with repo list and selected repo's example list in menu,
  61. * and the editor with the selected example
  62. */
  63. app.get('/:repoSlug/:exampleSlug', getIndexExample);
  64. app.post('/:repoSlug/examples', function(req, res) {
  65. var title = req.body.title;
  66. var { repoSlug } = req.params;
  67. if(! req.body.title) {
  68. res.status(400).send('Le titre ne peut pas être vide !');
  69. }
  70. var repo = exStore.getRepo(repoSlug);
  71. if(! repo) {
  72. res.status(404).send("Repo " + repoSlug + "not found");
  73. }
  74. var existingTitle = _.find(repo.examples, { title: title });
  75. if(existingTitle) {
  76. res.status(400).send("L'exemple '" + title + "' existe déjà !");
  77. }
  78. var exampleSlug = slug(req.body.title.toLowerCase());
  79. var targetDir = __dirname + '/exemples/' + repoSlug + '/' + exampleSlug;
  80. fs.mkdirAsync(targetDir)
  81. .then(() => Promise.map(
  82. ['contenu.html', 'script.js'], f => fs.writeFileAsync(targetDir + '/' + f, '')
  83. ))
  84. .then(files => repo.examples.push({ slug: slug, title: title }))
  85. .then(() => res.json({ slug: exampleSlug, title: title }));
  86. });
  87. app.get('/examples/:slug', function(req, res) {
  88. const { slug } = req.params;
  89. const config = readConfigJson(slug);
  90. const { title, html, js, css, libsCss, libsJs } = config;
  91. readFileAsync(__dirname + '/exemples/' + slug + '/example.html')
  92. .then(body =>
  93. Mustache.render(sandboxTpml, { body, slug, title, js, css, libsCss, libsJs })
  94. )
  95. .then(html => res.send(html));
  96. });
  97. app.get('/menu', (rea, res) => {
  98. res.send(exStore.getMenu());
  99. });
  100. app.get('/list/:repoPath', function(req, res) {
  101. const { repoPath } = req.params;
  102. const repo = exStore.getList(repoPath);
  103. if(! repo) {
  104. return res.status(404).send('Repo ' + repoPath + ' not found');
  105. }
  106. console.log('found repo', repo);
  107. const data = repo.examples.map(e => (
  108. { slug: e.slug, title: e.title }
  109. ));
  110. res.json(data);
  111. });
  112. app.put('/examples/:slug', function(req, res) {
  113. var slug = req.params.slug;
  114. var existing = _.find(examples, { slug: slug });
  115. if(! existing) {
  116. res.status(404).send("L'exemple avec l'identifiant '" + slug + "' est introuvable !");
  117. }
  118. var targetDir = __dirname + '/exemples/' + slug;
  119. if(req.body.html) {
  120. fs.writeFileSync(targetDir + '/contenu.html', req.body.html);
  121. }
  122. if(req.body.javascript) {
  123. fs.writeFileSync(targetDir + '/script.js', req.body.javascript);
  124. }
  125. var theDate = new Date();
  126. console.log(theDate.getHours() + ':' + theDate.getMinutes() + " - Sauvegarde de l'exemple '" + existing.title + " effectuée'");
  127. res.json({ success: true });
  128. });
  129. module.exports = app;