From fa582405fa6ae8050703e0fc9c2a798115423359 Mon Sep 17 00:00:00 2001 From: jrtechs Date: Sat, 9 Feb 2019 12:27:22 -0500 Subject: [PATCH 1/3] Updated videos page to display public videos to un-registered users. --- configManager.js | 5 +++++ html/error.html | 4 ++++ html/home.html | 31 ++++++++++++++++++------------- html/mainTemplate.html | 7 +------ html/videos.html | 16 +++++++++++++++- routes/icon.js | 11 +++++------ routes/user/addUser.js | 3 +-- routes/user/edituser.js | 3 +-- routes/user/index.js | 10 +++++++++- routes/user/removeuser.js | 3 +-- routes/user/revokeAPI.js | 4 ++++ routes/user/updateUser.js | 3 +-- routes/video.js | 4 +--- routes/videos.js | 38 +++++++++++++++++++++++++++++++------- utils.js | 25 ++++++++++++++++++++++--- 15 files changed, 119 insertions(+), 48 deletions(-) create mode 100644 html/error.html diff --git a/configManager.js b/configManager.js index 4db79a3..1218f7e 100644 --- a/configManager.js +++ b/configManager.js @@ -20,6 +20,11 @@ module.exports= return "/home/jeff/work/aaSchool/Algo/online Lectures/"; }, + getPublicDirectory: function() + { + return "/home/jeff/work/aaSchool/Algo/online Lectures/"; + }, + getServerURL: function() { return "http://localhost:5000"; diff --git a/html/error.html b/html/error.html new file mode 100644 index 0000000..1549c1f --- /dev/null +++ b/html/error.html @@ -0,0 +1,4 @@ +

{errorMessage}

+

+Page not found +

\ No newline at end of file diff --git a/html/home.html b/html/home.html index 4f5e8fd..aa1beab 100644 --- a/html/home.html +++ b/html/home.html @@ -1,19 +1,24 @@
-
-
-

Profile

-
-
-

Welcome {username}.

-
-
-
- -
+ {if loggedIn} +
+ +
+

Profile

+
+
+

Welcome {username}.


- +
+
+ +
+
+
+
-
+ {else} + {>login} + {/if}
\ No newline at end of file diff --git a/html/mainTemplate.html b/html/mainTemplate.html index c26cb1f..a128c5f 100644 --- a/html/mainTemplate.html +++ b/html/mainTemplate.html @@ -1,12 +1,7 @@ {>header}
- {if loggedIn} - {>main} - {else} - {>login} - {/if} - + {>main}
{>footer} \ No newline at end of file diff --git a/html/videos.html b/html/videos.html index dac14f0..6786e57 100644 --- a/html/videos.html +++ b/html/videos.html @@ -8,7 +8,21 @@
- {for video in videos} + {for video in private} +
+
+
+

{video.name}

+
+
+ + Icon for {video.name} + +
+
+
+ {/for} + {for video in public}
diff --git a/routes/icon.js b/routes/icon.js index dc86d20..1cc0d2a 100644 --- a/routes/icon.js +++ b/routes/icon.js @@ -26,16 +26,17 @@ routes.get('/', (request, result) => { if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER) { - file = fs.readFileSync("./img/private/" + name); + file = fs.readFileSync("./icon/private/" + name); } else { + utils.printError(result, "You need to be logged in"); throw "Not logged in"; } } else { - file = fs.readFileSync("./img/public/" + name); + file = fs.readFileSync("./icon/public/" + name); } result.writeHead(200, {'Content-Type': 'image/png', @@ -45,10 +46,8 @@ routes.get('/', (request, result) => } catch(error) { - result.writeHead(404, {'Content-Type': 'text/html', - 'Vary': 'Accept-Encoding'}); - result.write("Nada"); - result.end(); + utils.printError(result, "Invalid Icon"); + console.log(error); } }); diff --git a/routes/user/addUser.js b/routes/user/addUser.js index 8f35a09..0f0e28a 100644 --- a/routes/user/addUser.js +++ b/routes/user/addUser.js @@ -17,8 +17,7 @@ routes.post('/', (request, result) => } else { - result.status(401); - result.send('None shall pass'); + utils.printError(result, "You need to be logged in"); } }); diff --git a/routes/user/edituser.js b/routes/user/edituser.js index 5ae4c28..3146ae9 100644 --- a/routes/user/edituser.js +++ b/routes/user/edituser.js @@ -17,8 +17,7 @@ routes.post('/', (request, result) => } else { - result.status(401); - result.send('None shall pass'); + utils.printError(result, "You need to be logged in"); } }); diff --git a/routes/user/index.js b/routes/user/index.js index 106801e..64b5ea4 100644 --- a/routes/user/index.js +++ b/routes/user/index.js @@ -40,7 +40,15 @@ function getUserInformation(templateContext, request) routes.get('/', (request, result) => { - utils.renderHTML(request, result, "users.html", getUserInformation); + if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER) + { + utils.renderHTML(request, result, "users.html", getUserInformation); + } + else + { + utils.printError(result, "You need to be logged in"); + } + }); module.exports = routes; \ No newline at end of file diff --git a/routes/user/removeuser.js b/routes/user/removeuser.js index c04a2ed..69cb961 100644 --- a/routes/user/removeuser.js +++ b/routes/user/removeuser.js @@ -13,8 +13,7 @@ routes.post('/', (request, result) => } else { - result.status(401); - result.send('None shall pass'); + utils.printError(result, "You need to be logged in"); } }); diff --git a/routes/user/revokeAPI.js b/routes/user/revokeAPI.js index 02b50e5..956d205 100644 --- a/routes/user/revokeAPI.js +++ b/routes/user/revokeAPI.js @@ -16,6 +16,10 @@ routes.post('/', (request, result) => userUtils.revokeAPI(request.session.username); request.session.API = userUtils.getAPIKEY(request.session.username); } + else + { + utils.printError(result, "You need to be logged in"); + } result.redirect('/user'); }); diff --git a/routes/user/updateUser.js b/routes/user/updateUser.js index fa177f4..19dc356 100644 --- a/routes/user/updateUser.js +++ b/routes/user/updateUser.js @@ -14,8 +14,7 @@ routes.post('/', (request, result) => } else { - result.status(401); - result.send('None shall pass'); + utils.printError(result, "You need to be logged in"); } }); diff --git a/routes/video.js b/routes/video.js index 45190b8..6140b50 100644 --- a/routes/video.js +++ b/routes/video.js @@ -55,9 +55,7 @@ routes.get('/', (request, result) => } else { - console.log("invalid attempt to view video"); - result.status(401); - result.send('None shall pass'); + utils.printError(result, "You need to be logged in"); } }); diff --git a/routes/videos.js b/routes/videos.js index 15094d4..764da4f 100644 --- a/routes/videos.js +++ b/routes/videos.js @@ -10,13 +10,14 @@ const filepreview = require('filepreview'); const fs = require('fs'); -var videos = null; +var privateVideos = null; -function getVideosTemplateInformation(templateContext, request) +var publicVideos = null; + +function getVideosForTemplate(templateContext, rootDir, templateKey, videos) { if(videos === null) { - const rootDir = configManager.getRootDirectory(); videos = []; return new Promise(function(resolve, reject) { @@ -27,7 +28,7 @@ function getVideosTemplateInformation(templateContext, request) { var splitArray = file.split('/'); var name = splitArray[splitArray.length -1]; - const icon = 'img/private/' + name + ".png"; + const icon = 'img/' + templateKey + '/' + name + ".png"; if (!fs.existsSync(icon)) { filepreview.generate(file, icon, function(error) { @@ -37,19 +38,42 @@ function getVideosTemplateInformation(templateContext, request) console.log('File preview is located ' + icon); }); } - videos.push({name: file.replace(rootDir, ''), length: "n/a"}); + videos.push({name: file.replace(rootDir, '')}); }); - templateContext.videos = videos; + templateContext[templateKey] = videos; resolve(); }); }) } else { - templateContext.videos = videos; + templateContext[templateKey] = videos; } } + +function getVideosTemplateInformation(templateContext, request) +{ + var promises = []; + + const rootDir = configManager.getRootDirectory(); + + const rootPublicDir = configManager.getPublicDirectory(); + + if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER) + { + promises.push(getVideosForTemplate(templateContext, rootDir, "private", privateVideos)); + } + else + { + templateContext["private"] = []; + } + + promises.push(getVideosForTemplate(templateContext, rootPublicDir, "public", publicVideos)); + + return Promise.all(promises); +} + routes.get('/', (request, result) => { utils.renderHTML(request, result, "videos.html", getVideosTemplateInformation) diff --git a/utils.js b/utils.js index 860a2bf..117ef2c 100644 --- a/utils.js +++ b/utils.js @@ -28,15 +28,16 @@ module.exports = templateContext.loggedIn = true; if(module.exports.checkPrivilege(request) === PRIVILEGE.ADMIN) templateContext.admin = true; - if(templateDependencyFunction !== null) - prom.push(templateDependencyFunction(templateContext, request)); - prom.push(fetchInTemplate(templateContext, "main","./html/" + templateFile)); } else { prom.push(fetchInTemplate(templateContext, "login","./html/login.html")); } + if(templateDependencyFunction !== null) + prom.push(templateDependencyFunction(templateContext, request)); + prom.push(fetchInTemplate(templateContext, "main","./html/" + templateFile)); + Promise.all(prom).then(function(content) { result.write(whiskers.render(content[0], templateContext)); @@ -59,5 +60,23 @@ module.exports = else if(request.session.admin === true) return module.exports.PRIVILEGE.ADMIN; return module.exports.RIVILEGE.MEMBER; + }, + + printError: function(result, errorMessage) + { + var templateContext = Object(); + var prom = []; + + prom.push(fileIO.getFile("./html/mainTemplate.html")); + prom.push(fetchInTemplate(templateContext, "header", "./html/header.html")); + prom.push(fetchInTemplate(templateContext, "footer", "./html/footer.html")); + prom.push(fetchInTemplate(templateContext, "main", "./html/error.html")); + templateContext.errorMessage = errorMessage; + + Promise.all(prom).then(function(content) + { + result.write(whiskers.render(content[0], templateContext)); + result.end(); + }); } }; \ No newline at end of file From d52f0696e56f47146b07b204e16e22284b556cdc Mon Sep 17 00:00:00 2001 From: jrtechs Date: Sat, 9 Feb 2019 15:02:52 -0500 Subject: [PATCH 2/3] Updated videos to work with public and private sets. --- configManager.js | 2 +- routes/icon.js | 4 +- routes/video.js | 9 +++- routes/videos.js | 57 ++------------------- videoManager.js | 125 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 videoManager.js diff --git a/configManager.js b/configManager.js index 1218f7e..df2500e 100644 --- a/configManager.js +++ b/configManager.js @@ -17,7 +17,7 @@ module.exports= getRootDirectory: function() { - return "/home/jeff/work/aaSchool/Algo/online Lectures/"; + return "/home/jeff/public/Shows/Rick And Morty/Season 1"; }, getPublicDirectory: function() diff --git a/routes/icon.js b/routes/icon.js index 1cc0d2a..2c438ba 100644 --- a/routes/icon.js +++ b/routes/icon.js @@ -4,6 +4,8 @@ const utils = require("../utils"); const fs = require('fs'); +const videoManager = require('../videoManager'); + function isPublicVideo(videoURL) { return false; @@ -22,7 +24,7 @@ routes.get('/', (request, result) => var file=""; - if(!isPublicVideo(videoID)) + if(!videoManager.isPublicVideo(videoID)) { if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER) { diff --git a/routes/video.js b/routes/video.js index 6140b50..fbb323b 100644 --- a/routes/video.js +++ b/routes/video.js @@ -8,14 +8,19 @@ const configManager = require("../configManager"); const fs = require('fs'); +const videoManager = require("../videoManager"); + routes.get('/', (request, result) => { + var videoID = request.query.v; + if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER || - userUtils.isValidAPI(request.query.api)) + userUtils.isValidAPI(request.query.api) || + videoManager.isPublicVideo(videoID)) { const rootDir = configManager.getRootDirectory(); - var videoID = request.query.v; + const path = rootDir + videoID; const stat = fs.statSync(path); const fileSize = stat.size; diff --git a/routes/videos.js b/routes/videos.js index 764da4f..f863e1b 100644 --- a/routes/videos.js +++ b/routes/videos.js @@ -2,74 +2,23 @@ const routes = require('express').Router(); const utils = require("../utils"); -const recursive = require('../recursiveTraversal'); - -const configManager = require("../configManager"); - -const filepreview = require('filepreview'); - -const fs = require('fs'); - -var privateVideos = null; - -var publicVideos = null; - -function getVideosForTemplate(templateContext, rootDir, templateKey, videos) -{ - if(videos === null) - { - videos = []; - return new Promise(function(resolve, reject) - { - recursive(rootDir, function (err, files) - { - console.log(files); - files.forEach(file => - { - var splitArray = file.split('/'); - var name = splitArray[splitArray.length -1]; - const icon = 'img/' + templateKey + '/' + name + ".png"; - if (!fs.existsSync(icon)) - { - filepreview.generate(file, icon, function(error) { - if (error) { - return console.log(error); - } - console.log('File preview is located ' + icon); - }); - } - videos.push({name: file.replace(rootDir, '')}); - }); - templateContext[templateKey] = videos; - resolve(); - }); - }) - } - else - { - templateContext[templateKey] = videos; - } -} +const videoManager = require("../videoManager"); function getVideosTemplateInformation(templateContext, request) { var promises = []; - const rootDir = configManager.getRootDirectory(); - - const rootPublicDir = configManager.getPublicDirectory(); - if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER) { - promises.push(getVideosForTemplate(templateContext, rootDir, "private", privateVideos)); + promises.push(videoManager.getVideosForTemplate(templateContext, "private")); } else { templateContext["private"] = []; } - promises.push(getVideosForTemplate(templateContext, rootPublicDir, "public", publicVideos)); + promises.push(videoManager.getVideosForTemplate(templateContext, "public")); return Promise.all(promises); } diff --git a/videoManager.js b/videoManager.js new file mode 100644 index 0000000..b98b49f --- /dev/null +++ b/videoManager.js @@ -0,0 +1,125 @@ +const configManager = require('./configManager'); + +const recursive = require('./recursiveTraversal'); + +const filepreview = require('filepreview'); + +const fs = require('fs'); + +var privateVideos = null; + +var publicVideos = null; + +module.exports = + { + indexVideos: function(rootDir, videos, templateKey) + { + return new Promise(function(resolve, reject) + { + recursive(rootDir, function (err, files) + { + console.log(files); + files.forEach(file => + { + var splitArray = file.split('/'); + var name = splitArray[splitArray.length -1]; + const icon = './icon/' + templateKey + '/' + name + ".png"; + if (!fs.existsSync(icon)) + { + var options = { + width: 200, + quality: 50 + }; + + filepreview.generate(file, icon, options,function(error) { + if (error) { + return console.log(error); + } + console.log('File preview is located ' + icon); + }); + } + videos.push({name: file.replace(rootDir, '')}); + }); + resolve(); + }); + }).catch(function(error) + { + console.log(error); + }) + }, + + getVideosForTemplate: function(templateContext, templateKey) + { + return new Promise(function(resolve, reject) + { + var videos, rootDir; + if(templateKey === "public") + { + videos = publicVideos; + rootDir = configManager.getPublicDirectory(); + } + else + { + videos = privateVideos; + rootDir = configManager.getRootDirectory(); + } + + if(videos === null) + { + videos = []; + module.exports.indexVideos(rootDir, videos, templateKey) + .then(function() + { + templateContext[templateKey] = videos; + if(templateKey === "public") + publicVideos = videos; + else + privateVideos = videos; + resolve(); + }) + } + else + { + templateContext[templateKey] = videos; + resolve(); + } + }) + }, + + isPublicVideo: function(videoName) + { + if(publicVideos == null) + { + publicVideos = []; + rootDir = configManager.getPublicDirectory(); + module.exports.indexVideos(rootDir, publicVideos, "public").then(function() + { + for(var i = 0; i < publicVideos.length; i++) + { + const splitArray = publicVideos[i].name.split('/'); + const name = splitArray[splitArray.length -1]; + + if(name === videoName) + { + return true; + } + } + return false; + }); + } + else + { + for(var i = 0; i < publicVideos.length; i++) + { + const splitArray = publicVideos[i].name.split('/'); + const name = splitArray[splitArray.length -1]; + + if(name === videoName) + { + return true; + } + } + return false; + } + } + }; \ No newline at end of file From 8984782b9675976159180371b3fe765818388983 Mon Sep 17 00:00:00 2001 From: jrtechs Date: Sat, 9 Feb 2019 16:59:58 -0500 Subject: [PATCH 3/3] Updated file preview to take the video preview 5 minutes into to movie to prevent blank icons. Minor bug fixes. --- README.MD | 6 ++++++ html/error.html | 15 +++++++++++---- html/videos.html | 8 ++++---- package.json | 28 ++++++++++++++++++++++++++++ routes/icon.js | 3 --- routes/index.js | 6 ++++++ routes/watch.js | 18 +++++++++++++++++- server.js | 11 ++++++----- utils.js | 1 + videoManager.js | 6 +++--- 10 files changed, 82 insertions(+), 20 deletions(-) create mode 100644 package.json diff --git a/README.MD b/README.MD index 945654e..76b6ed3 100644 --- a/README.MD +++ b/README.MD @@ -23,6 +23,12 @@ npm install express-session --save npm install whiskers --save ``` +Dependencies + +```bash +$apt-get install ffmpeg +``` + Codacs which don't work H.265 diff --git a/html/error.html b/html/error.html index 1549c1f..678c3ef 100644 --- a/html/error.html +++ b/html/error.html @@ -1,4 +1,11 @@ -

{errorMessage}

-

-Page not found -

\ No newline at end of file +
+
+

{errorMessage}

+
+ Page not found +

+
+
+ {>login} +
+
diff --git a/html/videos.html b/html/videos.html index 6786e57..6ef6dcf 100644 --- a/html/videos.html +++ b/html/videos.html @@ -9,10 +9,10 @@
{for video in private} -
+
-

{video.name}

+

{video.name}

{/for} {for video in public} -
+
-

{video.name}

+

{video.name}

diff --git a/package.json b/package.json new file mode 100644 index 0000000..d568e42 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "HomeBrewPlex", + "version": "0.1.0", + "description": "Light weight alternative for Plex", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jrtechs/HomeBrewPlex.git" + }, + "author": "Jeffery Russell", + "license": "MPL 2.0", + "bugs": { + "url": "https://github.com/jrtechs/HomeBrewPlex/issues" + }, + "homepage": "https://github.com/jrtechs/HomeBrewPlex#readme", + "dependencies": { + "download-file": "^0.1.5", + "express-session": "^1.15.6", + "fs": "0.0.2", + "path": "^0.12.7", + "url": "^0.11.0", + "whiskers": "^0.4.0" + } +} diff --git a/routes/icon.js b/routes/icon.js index 2c438ba..4053872 100644 --- a/routes/icon.js +++ b/routes/icon.js @@ -20,8 +20,6 @@ routes.get('/', (request, result) => const splitArray = videoID.split('/'); const name = splitArray[splitArray.length -1] + ".png"; - console.log(name); - var file=""; if(!videoManager.isPublicVideo(videoID)) @@ -49,7 +47,6 @@ routes.get('/', (request, result) => catch(error) { utils.printError(result, "Invalid Icon"); - console.log(error); } }); diff --git a/routes/index.js b/routes/index.js index a18abd0..4d37cb6 100644 --- a/routes/index.js +++ b/routes/index.js @@ -30,4 +30,10 @@ routes.get('/', (request, result) => utils.renderHTML(request, result, "home.html", getHomePageInformation) }); + +routes.get('*', (request, result) => +{ + utils.printError(result, "Page not found."); +}); + module.exports = routes; \ No newline at end of file diff --git a/routes/watch.js b/routes/watch.js index f88b15a..626adb8 100644 --- a/routes/watch.js +++ b/routes/watch.js @@ -4,16 +4,32 @@ const utils = require("../utils"); const configManager = require("../configManager"); +const videoManager = require("../videoManager"); + function getVideoTemplateInfo(templateContext, request) { templateContext.api = request.session.API; templateContext.serverURL = configManager.getServerURL(); templateContext.videoURL = request.query.v.split(" ").join("%20"); + + if(utils.checkPrivilege(request) === utils.PRIVILEGE.NOBODY + && !videoManager.isPublicVideo(request.query.v)) + { + throw "Video either doesn't exist or you need to log in."; + } } routes.get('/', (request, result) => { - utils.renderHTML(request, result, "watch.html", getVideoTemplateInfo) + try + { + utils.renderHTML(request, result, "watch.html", getVideoTemplateInfo) + } + catch(error) + { + utils.printError(result, error); + } + }); module.exports = routes; \ No newline at end of file diff --git a/server.js b/server.js index c72dfdb..58e1792 100644 --- a/server.js +++ b/server.js @@ -11,20 +11,21 @@ const app = express(); /**Initializes sessions for login */ app.use(session( { secret: configLoader.getConfiguration().sessionSecret, - cookie: { maxAge: 6000000 } - } + cookie: { maxAge: 6000000 }} )); app.use(express.urlencoded()); //for easy retrieval of post and get data app.use(express.json()); -const routes = require('./routes'); -app.use('/', routes); - app.use(express.static('css')); app.use(express.static('js')); app.use(express.static('img')); +const routes = require('./routes'); +app.use('/', routes); + + + app.listen(configLoader.getConfiguration().port, () => console.log(`App listening on port ${configLoader.getConfiguration().port}!`) ); \ No newline at end of file diff --git a/utils.js b/utils.js index 117ef2c..bd7866c 100644 --- a/utils.js +++ b/utils.js @@ -71,6 +71,7 @@ module.exports = prom.push(fetchInTemplate(templateContext, "header", "./html/header.html")); prom.push(fetchInTemplate(templateContext, "footer", "./html/footer.html")); prom.push(fetchInTemplate(templateContext, "main", "./html/error.html")); + prom.push(fetchInTemplate(templateContext, "login","./html/login.html")); templateContext.errorMessage = errorMessage; Promise.all(prom).then(function(content) diff --git a/videoManager.js b/videoManager.js index b98b49f..37cf0b3 100644 --- a/videoManager.js +++ b/videoManager.js @@ -18,7 +18,6 @@ module.exports = { recursive(rootDir, function (err, files) { - console.log(files); files.forEach(file => { var splitArray = file.split('/'); @@ -28,7 +27,8 @@ module.exports = { var options = { width: 200, - quality: 50 + quality: 50, + previewTime: '00:05:00.000' }; filepreview.generate(file, icon, options,function(error) { @@ -44,7 +44,7 @@ module.exports = }); }).catch(function(error) { - console.log(error); + //console.log(error); }) },