Lightweight node app to use in place of plex to self host your video and movie collections. Running on just under 50MB of ram this is ideal for people looking to host videos on minimal hardware.
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.

252 lines
7.5 KiB

  1. /** express app for routing */
  2. const express = require("express");
  3. /**session data for login and storing preferences*/
  4. const session = require('express-session');
  5. const fileIO = require('./fileIO');
  6. const userUtils = require('./user.js');
  7. const configLoader = require('./configManager.js');
  8. // const recursive = require('./recursiveTraversal');
  9. //
  10. // const filepreview = require('filepreview');
  11. const fs = require('fs');
  12. const app = express();
  13. /**Initializes sessions for login */
  14. app.use(session({ secret: configLoader.getConfiguration().sessionSecret, cookie: { maxAge: 6000000 }}));
  15. app.use(express.urlencoded());
  16. app.use(express.json()); // if needed
  17. const routes = require('./routes');
  18. app.use('/', routes);
  19. // const CONFIG_FILE_NAME = "conf.json";
  20. // const config = fileIO.getFileAsJSON(CONFIG_FILE_NAME);
  21. // /** Template engine */
  22. // const whiskers = require('whiskers');
  23. // var rootDir = '/home/jeff/work/aaSchool/Algo/online Lectures/';
  24. // var serverURL = "http://localhost:5000";
  25. // function fetchInTemplate(templateContext, templateKey, filename)
  26. // {
  27. // templateContext[templateKey] = fileIO.getFile(filename);
  28. // }
  29. // function renderHTML(request, result, templateFile, templateDependencyFunction)
  30. // {
  31. // var templateContext = Object();
  32. // var prom = [];
  33. //
  34. // prom.push(fileIO.getFile("./html/mainTemplate.html"));
  35. // prom.push(fetchInTemplate(templateContext, "header", "./html/header.html"));
  36. // prom.push(fetchInTemplate(templateContext, "footer", "./html/footer.html"));
  37. // if(checkPrivilege(request) >= PRIVILEGE.MEMBER)
  38. // {
  39. // templateContext.loggedIn = true;
  40. // if(checkPrivilege(request) === PRIVILEGE.ADMIN)
  41. // templateContext.admin = true;
  42. // if(templateDependencyFunction !== null)
  43. // prom.push(templateDependencyFunction(templateContext, request));
  44. // prom.push(fetchInTemplate(templateContext, "main","./html/" + templateFile));
  45. // }
  46. // else
  47. // {
  48. // prom.push(fetchInTemplate(templateContext, "login","./html/login.html"));
  49. // }
  50. //
  51. // Promise.all(prom).then(function(content)
  52. // {
  53. // result.write(whiskers.render(content[0], templateContext));
  54. // result.end();
  55. // });
  56. // }
  57. // function getUserInformation(templateContext, request)
  58. // {
  59. // templateContext.users = configLoader.getConfiguration().users;
  60. // templateContext.apiKey = request.session.API;
  61. // templateContext.id = request.session.userID;
  62. // templateContext.username = request.session.username;
  63. // }
  64. // function getHomePageInformation(templateContext, request)
  65. // {
  66. // templateContext.username = request.session.username;
  67. // }
  68. // app.get('/', (req, res) => renderHTML(req, res, "home.html", getHomePageInformation));
  69. // app.get('/users', (req, res) => renderHTML(req, res, "users.html", getUserInformation));
  70. app.use(express.static('css'));
  71. app.use(express.static('js'));
  72. app.use(express.static('img'));
  73. // var videos = null;
  74. //
  75. // function getVideosTemplateInformation(templateContext, request)
  76. // {
  77. // if(videos === null)
  78. // {
  79. // videos = [];
  80. // return new Promise(function(resolve, reject)
  81. // {
  82. // recursive(rootDir, function (err, files)
  83. // {
  84. // console.log(files);
  85. // files.forEach(file =>
  86. // {
  87. // var splitArray = file.split('/');
  88. // var name = splitArray[splitArray.length -1];
  89. // const icon = 'img/private/' + name + ".png";
  90. // if (!fs.existsSync(icon))
  91. // {
  92. // filepreview.generate(file, icon, function(error) {
  93. // if (error) {
  94. // return console.log(error);
  95. // }
  96. // console.log('File preview is located ' + icon);
  97. // });
  98. // }
  99. // videos.push({name: file.replace(rootDir, ''), length: "n/a"});
  100. // });
  101. // templateContext.videos = videos;
  102. // resolve();
  103. // });
  104. // })
  105. // }
  106. // else
  107. // {
  108. // templateContext.videos = videos;
  109. // }
  110. // }
  111. // function getVideoTemplateInfo(templateContext, request)
  112. // {
  113. // templateContext.api = request.session.API;
  114. // templateContext.serverURL = serverURL;
  115. // templateContext.videoURL = request.query.v.split(" ").join("%20");
  116. // }
  117. // app.get('/videos', (req, res) => renderHTML(req, res, "videos.html", getVideosTemplateInformation));
  118. // app.get('/watch', (req, res) => renderHTML(req, res, "watch.html", getVideoTemplateInfo));
  119. // function isPublicVideo(videoURL)
  120. // {
  121. // return false;
  122. // }
  123. //
  124. // app.get('/icon/', function(request, result)
  125. // {
  126. // try
  127. // {
  128. // const videoID = request.query.v;
  129. //
  130. // const splitArray = videoID.split('/');
  131. // const name = splitArray[splitArray.length -1] + ".png";
  132. //
  133. // var file="";
  134. //
  135. // if(!isPublicVideo(videoID))
  136. // {
  137. // if(checkPrivilege(request) >= PRIVILEGE.MEMBER)
  138. // {
  139. // file = fs.readFileSync("img/private/" + name);
  140. // }
  141. // else
  142. // {
  143. // throw "Not logged in";
  144. // }
  145. // }
  146. // else
  147. // {
  148. // file = fs.readFileSync("img/public/" + name);
  149. // }
  150. //
  151. // result.writeHead(200, {'Content-Type': 'image/png',
  152. // 'Vary': 'Accept-Encoding'});
  153. // result.write(file);
  154. // result.end();
  155. // }
  156. // catch(error)
  157. // {
  158. // result.writeHead(404, {'Content-Type': 'text/html',
  159. // 'Vary': 'Accept-Encoding'});
  160. // result.write("Nada");
  161. // result.end();
  162. // }
  163. // });
  164. // app.get('/video/', function(request, result)
  165. // {
  166. // if(checkPrivilege(request) >= PRIVILEGE.MEMBER || userUtils.isValidAPI(request.query.api, config))
  167. // {
  168. // var videoID = request.query.v;
  169. // const path = rootDir + videoID;
  170. // const stat = fs.statSync(path);
  171. // const fileSize = stat.size;
  172. // const range = request.headers.range;
  173. //
  174. // if (range)
  175. // {
  176. // const parts = range.replace(/bytes=/, "").split("-");
  177. // const start = parseInt(parts[0], 10);
  178. // const end = parts[1]
  179. // ? parseInt(parts[1], 10)
  180. // : fileSize-1;
  181. //
  182. // const chunksize = (end-start)+1;
  183. // const file = fs.createReadStream(path, {start, end});
  184. // const head =
  185. // {
  186. // 'Content-Range': `bytes ${start}-${end}/${fileSize}`,
  187. // 'Accept-Ranges': 'bytes',
  188. // 'Content-Length': chunksize,
  189. // 'Content-Type': 'video/mp4',
  190. // };
  191. // result.writeHead(206, head);
  192. // file.pipe(result);
  193. // }
  194. // else
  195. // {
  196. // const head =
  197. // {
  198. // 'Content-Length': fileSize,
  199. // 'Content-Type': 'video/mp4',
  200. // };
  201. //
  202. // result.writeHead(200, head);
  203. // fs.createReadStream(path).pipe(result);
  204. // }
  205. // }
  206. // else
  207. // {
  208. // console.log("invalid attempt to view video");
  209. // result.status(401);
  210. // result.send('None shall pass');
  211. // }
  212. // });
  213. app.listen(configLoader.getConfiguration().port, () => console.log(`App listening on port ${configLoader.getConfiguration().port}!`));