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.

slideshow.js 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. var fs = require("fs");
  2. var pathlib = require("path");
  3. var sendfile = require("./sendfile");
  4. var error = require("./error");
  5. module.exports = Slideshow;
  6. // The individual slide
  7. function Slide(dir) {
  8. var self = {};
  9. self.dir = dir;
  10. self.name = pathlib.parse(dir).name;
  11. self.serveSlide = function(parts, res) {
  12. sendfile(res, pathlib.join(dir, "index.html"));
  13. }
  14. self.serveFiles = function(parts, res) {
  15. // Redirect to / if /{name} is requested
  16. if (parts.pathname.replace(/\//g, "") === self.name) {
  17. res.writeHead(302, { location: "/" });
  18. return res.end();
  19. }
  20. var name = parts.pathname.substring(1).replace(self.name, "");
  21. sendfile(res, pathlib.join(dir, name));
  22. }
  23. self.indexExists = function() {
  24. try {
  25. fs.accessSync(pathlib.join(dir, "index.html"));
  26. return true;
  27. } catch (err) {
  28. return false;
  29. }
  30. }
  31. try {
  32. self.meta = JSON.parse(
  33. fs.readFileSync(pathlib.join(dir, "meta.json")));
  34. } catch (err) {
  35. if (err.code !== "ENOENT")
  36. error(err);
  37. self.meta = {};
  38. }
  39. return self;
  40. }
  41. // The slideshow, whose job it is to manage all slides
  42. // and tell the client whether it has to update or not
  43. function Slideshow(dir, changeInterval) {
  44. var self = {};
  45. var currentSlide = null;
  46. var awaiters = [];
  47. var slides = [];
  48. var slideIndex = 0;
  49. var nextTimeout;
  50. self.sendEvent = function(evt, args) {
  51. var str = JSON.stringify({ evt: evt, args: args });
  52. awaiters.forEach(res => res.end(str));
  53. awaiters = [];
  54. }
  55. // Get the current slide's interval
  56. function currentInterval() {
  57. var itv = currentSlide.meta.interval;
  58. if (itv === undefined)
  59. itv = changeInterval;
  60. return itv;
  61. }
  62. // Return if the current slide is enabled and valid
  63. function currentEnabled() {
  64. return currentSlide.indexExists() && !currentSlide.disabled;
  65. }
  66. self.getSlideName = getSlideName;
  67. function getSlideName() {
  68. return currentSlide ? currentSlide.name : ""
  69. }
  70. self.pushAwaiter = pushAwaiter;
  71. function pushAwaiter(res) {
  72. awaiters.push(res);
  73. }
  74. self.serveCurrentSlide = serveCurrentSlide;
  75. function serveCurrentSlide(parts, res) {
  76. if (currentSlide)
  77. currentSlide.serveSlide(parts, res);
  78. else
  79. error("Current slide requested while no current slide exists", res);
  80. }
  81. self.getSlides = getSlides;
  82. function getSlides() {
  83. return slides;
  84. }
  85. self.next = next;
  86. function next() {
  87. slideIndex += 1;
  88. // Go to the next slide, or restart
  89. if (slideIndex >= slides.length) {
  90. clearTimeout(nextTimeout);
  91. init();
  92. } else {
  93. currentSlide = slides[slideIndex];
  94. nextTimeout = setTimeout(next, currentInterval());
  95. }
  96. // End all awaiting connections to notify slide change,
  97. if (currentEnabled()) {
  98. self.sendEvent("next", { name: currentSlide.name });
  99. // Or go to the next slide if the current one doesn't have an index.html
  100. // or if the slide is disabled
  101. } else {
  102. clearTimeout(nextTimeout);
  103. setTimeout(next, 0);
  104. }
  105. }
  106. // This function starts the slideshow and goes through the slides
  107. // one by one. When done, it starts again by calling this function again.
  108. function init() {
  109. slides = fs.readdirSync(dir)
  110. .sort()
  111. .map(file => Slide(pathlib.join(dir, file)));
  112. slideIndex = 0;
  113. currentSlide = slides[slideIndex];
  114. nextTimeout = setTimeout(next, currentInterval());
  115. }
  116. init();
  117. return self;
  118. }