Pictures!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.js 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. var fs = require("fs");
  2. var http = require("http");
  3. var crypto = require("crypto");
  4. var pathlib = require("path");
  5. var urllib = require("url");
  6. var index = fs.readFileSync("index.html");
  7. var conf = JSON.parse(fs.readFileSync("conf.json"));
  8. function error(res, err) {
  9. console.trace(err);
  10. res.end(err.toString());
  11. }
  12. // The individual slide
  13. function Slide(dir) {
  14. var self = {};
  15. self.dir = dir;
  16. function serve(parts, res) {
  17. if (parts.pathname === "/slide") {
  18. fs.createReadStream(pathlib.join(dir, "index.html"))
  19. .on("error", err => error(res, err))
  20. .pipe(res);
  21. } else {
  22. fs.createReadStream(pathlib.join(dir, parts.pathname))
  23. .on("error", err => error(res, err))
  24. .pipe(res);
  25. }
  26. }
  27. self.serve = function(parts, res) {
  28. try {
  29. serve(parts, res);
  30. } catch (err) {
  31. if (err.code && err.code === "ENOENT")
  32. res.writeHead(404);
  33. error(res, err);
  34. }
  35. }
  36. return self;
  37. }
  38. // The slideshow, whose job it is to manage all slides
  39. // and tell the client whether it has to update or not
  40. function Slideshow(dir, changeInterval) {
  41. var self = {};
  42. var currentSlide = null;
  43. var awaiters = [];
  44. self.serve = function(req, res) {
  45. var parts = urllib.parse(req.url);
  46. // /: Send the base site to the client
  47. if (parts.pathname === "/") {
  48. res.end(index);
  49. // /await: long polling, request won't end before a new slide comes
  50. } else if (parts.pathname === "/await") {
  51. awaiters.push(res);
  52. // There's a current slide: leave serving files up to the slide
  53. } else if (currentSlide) {
  54. currentSlide.serve(parts, res);
  55. // There's no current slide show
  56. } else {
  57. res.end("No current slideshow.");
  58. }
  59. }
  60. // This function starts the slideshow and goes through the slides
  61. // one by one. When done, it starts again by calling this function again.
  62. function init() {
  63. var slides = fs.readdirSync(dir)
  64. .sort()
  65. .map(file => Slide(pathlib.join(dir, file)));
  66. var slideIndex = 0;
  67. currentSlide = slides[slideIndex];
  68. var interval = setInterval(() => {
  69. slideIndex += 1;
  70. // Go to the next slide, or restart
  71. if (slideIndex >= slides.length) {
  72. clearInterval(interval);
  73. init();
  74. } else {
  75. currentSlide = slides[slideIndex];
  76. }
  77. // End all awaiting connections to notify slide change
  78. awaiters.forEach(res => res.end());
  79. }, changeInterval);
  80. }
  81. init();
  82. return self;
  83. }
  84. var slideshow = Slideshow(conf.slides, conf.interval);
  85. http.createServer((req, res) => {
  86. slideshow.serve(req, res);
  87. }).listen(conf.port);