Browse Source

Merge pull request #7 from jrtechs/publicSection

Public section
pull/8/head
Jeffery Russell 5 years ago
committed by GitHub
parent
commit
ffe0290bad
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 305 additions and 91 deletions
  1. +6
    -0
      README.MD
  2. +5
    -0
      configManager.js
  3. +11
    -0
      html/error.html
  4. +18
    -13
      html/home.html
  5. +1
    -6
      html/mainTemplate.html
  6. +17
    -3
      html/videos.html
  7. +28
    -0
      package.json
  8. +7
    -9
      routes/icon.js
  9. +6
    -0
      routes/index.js
  10. +1
    -2
      routes/user/addUser.js
  11. +1
    -2
      routes/user/edituser.js
  12. +9
    -1
      routes/user/index.js
  13. +1
    -2
      routes/user/removeuser.js
  14. +4
    -0
      routes/user/revokeAPI.js
  15. +1
    -2
      routes/user/updateUser.js
  16. +8
    -5
      routes/video.js
  17. +10
    -37
      routes/videos.js
  18. +17
    -1
      routes/watch.js
  19. +6
    -5
      server.js
  20. +23
    -3
      utils.js
  21. +125
    -0
      videoManager.js

+ 6
- 0
README.MD View File

@ -23,6 +23,12 @@ npm install express-session --save
npm install whiskers --save npm install whiskers --save
``` ```
Dependencies
```bash
$apt-get install ffmpeg
```
Codacs which don't work Codacs which don't work
H.265 H.265

+ 5
- 0
configManager.js View File

@ -16,6 +16,11 @@ module.exports=
}, },
getRootDirectory: function() getRootDirectory: function()
{
return "/home/jeff/public/Shows/Rick And Morty/Season 1";
},
getPublicDirectory: function()
{ {
return "/home/jeff/work/aaSchool/Algo/online Lectures/"; return "/home/jeff/work/aaSchool/Algo/online Lectures/";
}, },

+ 11
- 0
html/error.html View File

@ -0,0 +1,11 @@
<div class="row">
<div class="col-md-6">
<center><h1 class="align-content-center">{errorMessage}</h1></center>
<br>
<img class="mx-auto d-block" src="/404.jpg" alt="Page not found" width="60%" />
<br><br>
</div>
<div class="col-md-6">
{>login}
</div>
</div>

+ 18
- 13
html/home.html View File

@ -1,19 +1,24 @@
<div class="row"> <div class="row">
<div class="col-4"> <div class="col-4">
<div class="card">
<div class="card-header">
<h3>Profile</h3>
</div>
<div class="card-body">
<p>Welcome {username}.</p>
<br>
<form action="/user/logout" method ="post" class="p-2">
<div class="text-center">
<button class="btn btn-lg btn-secondary">LogOut</button>
</div>
{if loggedIn}
<div class="card">
<div class="card-header">
<h3>Profile</h3>
</div>
<div class="card-body">
<p>Welcome {username}.</p>
<br> <br>
</form>
<form action="/user/logout" method ="post" class="p-2">
<div class="text-center">
<button class="btn btn-lg btn-secondary">LogOut</button>
</div>
<br>
</form>
</div>
</div> </div>
</div>
{else}
{>login}
{/if}
</div> </div>
</div> </div>

+ 1
- 6
html/mainTemplate.html View File

@ -1,12 +1,7 @@
{>header} {>header}
<div class="container"> <div class="container">
{if loggedIn}
{>main}
{else}
{>login}
{/if}
{>main}
</div> </div>
{>footer} {>footer}

+ 17
- 3
html/videos.html View File

@ -8,11 +8,25 @@
<br> <br>
<div class="row"> <div class="row">
{for video in videos}
<div class="col-md-4 videoElement">
{for video in private}
<div class="col-md-3 videoElement p-2">
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<h2>{video.name}</h2>
<h4>{video.name}</h4>
</div>
<div class="card-body">
<a href="/watch?v={video.name}" class="" role="button" aria-pressed="true">
<img src="/icon?v={video.name}" alt="Icon for {video.name}" width=100%/>
</a>
</div>
</div>
</div>
{/for}
{for video in public}
<div class="col-md-3 videoElement p-2">
<div class="card">
<div class="card-header">
<h4>{video.name}</h4>
</div> </div>
<div class="card-body"> <div class="card-body">
<a href="/watch?v={video.name}" class="" role="button" aria-pressed="true"> <a href="/watch?v={video.name}" class="" role="button" aria-pressed="true">

+ 28
- 0
package.json View File

@ -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"
}
}

+ 7
- 9
routes/icon.js View File

@ -4,6 +4,8 @@ const utils = require("../utils");
const fs = require('fs'); const fs = require('fs');
const videoManager = require('../videoManager');
function isPublicVideo(videoURL) function isPublicVideo(videoURL)
{ {
return false; return false;
@ -18,24 +20,23 @@ routes.get('/', (request, result) =>
const splitArray = videoID.split('/'); const splitArray = videoID.split('/');
const name = splitArray[splitArray.length -1] + ".png"; const name = splitArray[splitArray.length -1] + ".png";
console.log(name);
var file=""; var file="";
if(!isPublicVideo(videoID))
if(!videoManager.isPublicVideo(videoID))
{ {
if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER) if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER)
{ {
file = fs.readFileSync("./img/private/" + name);
file = fs.readFileSync("./icon/private/" + name);
} }
else else
{ {
utils.printError(result, "You need to be logged in");
throw "Not logged in"; throw "Not logged in";
} }
} }
else else
{ {
file = fs.readFileSync("./img/public/" + name);
file = fs.readFileSync("./icon/public/" + name);
} }
result.writeHead(200, {'Content-Type': 'image/png', result.writeHead(200, {'Content-Type': 'image/png',
@ -45,10 +46,7 @@ routes.get('/', (request, result) =>
} }
catch(error) catch(error)
{ {
result.writeHead(404, {'Content-Type': 'text/html',
'Vary': 'Accept-Encoding'});
result.write("Nada");
result.end();
utils.printError(result, "Invalid Icon");
} }
}); });

+ 6
- 0
routes/index.js View File

@ -30,4 +30,10 @@ routes.get('/', (request, result) =>
utils.renderHTML(request, result, "home.html", getHomePageInformation) utils.renderHTML(request, result, "home.html", getHomePageInformation)
}); });
routes.get('*', (request, result) =>
{
utils.printError(result, "Page not found.");
});
module.exports = routes; module.exports = routes;

+ 1
- 2
routes/user/addUser.js View File

@ -17,8 +17,7 @@ routes.post('/', (request, result) =>
} }
else else
{ {
result.status(401);
result.send('None shall pass');
utils.printError(result, "You need to be logged in");
} }
}); });

+ 1
- 2
routes/user/edituser.js View File

@ -17,8 +17,7 @@ routes.post('/', (request, result) =>
} }
else else
{ {
result.status(401);
result.send('None shall pass');
utils.printError(result, "You need to be logged in");
} }
}); });

+ 9
- 1
routes/user/index.js View File

@ -40,7 +40,15 @@ function getUserInformation(templateContext, request)
routes.get('/', (request, result) => 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; module.exports = routes;

+ 1
- 2
routes/user/removeuser.js View File

@ -13,8 +13,7 @@ routes.post('/', (request, result) =>
} }
else else
{ {
result.status(401);
result.send('None shall pass');
utils.printError(result, "You need to be logged in");
} }
}); });

+ 4
- 0
routes/user/revokeAPI.js View File

@ -16,6 +16,10 @@ routes.post('/', (request, result) =>
userUtils.revokeAPI(request.session.username); userUtils.revokeAPI(request.session.username);
request.session.API = userUtils.getAPIKEY(request.session.username); request.session.API = userUtils.getAPIKEY(request.session.username);
} }
else
{
utils.printError(result, "You need to be logged in");
}
result.redirect('/user'); result.redirect('/user');
}); });

+ 1
- 2
routes/user/updateUser.js View File

@ -14,8 +14,7 @@ routes.post('/', (request, result) =>
} }
else else
{ {
result.status(401);
result.send('None shall pass');
utils.printError(result, "You need to be logged in");
} }
}); });

+ 8
- 5
routes/video.js View File

@ -8,14 +8,19 @@ const configManager = require("../configManager");
const fs = require('fs'); const fs = require('fs');
const videoManager = require("../videoManager");
routes.get('/', (request, result) => routes.get('/', (request, result) =>
{ {
var videoID = request.query.v;
if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER || if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER ||
userUtils.isValidAPI(request.query.api))
userUtils.isValidAPI(request.query.api) ||
videoManager.isPublicVideo(videoID))
{ {
const rootDir = configManager.getRootDirectory(); const rootDir = configManager.getRootDirectory();
var videoID = request.query.v;
const path = rootDir + videoID; const path = rootDir + videoID;
const stat = fs.statSync(path); const stat = fs.statSync(path);
const fileSize = stat.size; const fileSize = stat.size;
@ -55,9 +60,7 @@ routes.get('/', (request, result) =>
} }
else 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");
} }
}); });

+ 10
- 37
routes/videos.js View File

@ -2,52 +2,25 @@ const routes = require('express').Router();
const utils = require("../utils"); const utils = require("../utils");
const recursive = require('../recursiveTraversal');
const videoManager = require("../videoManager");
const configManager = require("../configManager");
const filepreview = require('filepreview');
const fs = require('fs');
var videos = null;
function getVideosTemplateInformation(templateContext, request) function getVideosTemplateInformation(templateContext, request)
{ {
if(videos === null)
var promises = [];
if(utils.checkPrivilege(request) >= utils.PRIVILEGE.MEMBER)
{ {
const rootDir = configManager.getRootDirectory();
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/private/' + 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, ''), length: "n/a"});
});
templateContext.videos = videos;
resolve();
});
})
promises.push(videoManager.getVideosForTemplate(templateContext, "private"));
} }
else else
{ {
templateContext.videos = videos;
templateContext["private"] = [];
} }
promises.push(videoManager.getVideosForTemplate(templateContext, "public"));
return Promise.all(promises);
} }
routes.get('/', (request, result) => routes.get('/', (request, result) =>

+ 17
- 1
routes/watch.js View File

@ -4,16 +4,32 @@ const utils = require("../utils");
const configManager = require("../configManager"); const configManager = require("../configManager");
const videoManager = require("../videoManager");
function getVideoTemplateInfo(templateContext, request) function getVideoTemplateInfo(templateContext, request)
{ {
templateContext.api = request.session.API; templateContext.api = request.session.API;
templateContext.serverURL = configManager.getServerURL(); templateContext.serverURL = configManager.getServerURL();
templateContext.videoURL = request.query.v.split(" ").join("%20"); 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) => 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; module.exports = routes;

+ 6
- 5
server.js View File

@ -11,20 +11,21 @@ const app = express();
/**Initializes sessions for login */ /**Initializes sessions for login */
app.use(session( app.use(session(
{ secret: configLoader.getConfiguration().sessionSecret, { 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.urlencoded()); //for easy retrieval of post and get data
app.use(express.json()); app.use(express.json());
const routes = require('./routes');
app.use('/', routes);
app.use(express.static('css')); app.use(express.static('css'));
app.use(express.static('js')); app.use(express.static('js'));
app.use(express.static('img')); app.use(express.static('img'));
const routes = require('./routes');
app.use('/', routes);
app.listen(configLoader.getConfiguration().port, () => app.listen(configLoader.getConfiguration().port, () =>
console.log(`App listening on port ${configLoader.getConfiguration().port}!`) console.log(`App listening on port ${configLoader.getConfiguration().port}!`)
); );

+ 23
- 3
utils.js View File

@ -28,15 +28,16 @@ module.exports =
templateContext.loggedIn = true; templateContext.loggedIn = true;
if(module.exports.checkPrivilege(request) === PRIVILEGE.ADMIN) if(module.exports.checkPrivilege(request) === PRIVILEGE.ADMIN)
templateContext.admin = true; templateContext.admin = true;
if(templateDependencyFunction !== null)
prom.push(templateDependencyFunction(templateContext, request));
prom.push(fetchInTemplate(templateContext, "main","./html/" + templateFile));
} }
else else
{ {
prom.push(fetchInTemplate(templateContext, "login","./html/login.html")); 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) Promise.all(prom).then(function(content)
{ {
result.write(whiskers.render(content[0], templateContext)); result.write(whiskers.render(content[0], templateContext));
@ -59,5 +60,24 @@ module.exports =
else if(request.session.admin === true) else if(request.session.admin === true)
return module.exports.PRIVILEGE.ADMIN; return module.exports.PRIVILEGE.ADMIN;
return module.exports.RIVILEGE.MEMBER; 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"));
prom.push(fetchInTemplate(templateContext, "login","./html/login.html"));
templateContext.errorMessage = errorMessage;
Promise.all(prom).then(function(content)
{
result.write(whiskers.render(content[0], templateContext));
result.end();
});
} }
}; };

+ 125
- 0
videoManager.js View File

@ -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)
{
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,
previewTime: '00:05:00.000'
};
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;
}
}
};

Loading…
Cancel
Save