Merge branch 'dev' of Devowo/Mpoknimu into master
This commit is contained in:
commit
745f7cdd19
|
@ -0,0 +1,9 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = false
|
||||||
|
trim_trailing_whitespace = false
|
|
@ -0,0 +1,6 @@
|
||||||
|
client/dist/
|
||||||
|
client/node_modules/
|
||||||
|
client/build/
|
||||||
|
client/static/
|
||||||
|
node_modules/
|
||||||
|
public/assets/
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) <year> <copyright holders>
|
Copyright (c) 2018 Devowo
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
const path = require('path');
|
||||||
|
const express = require('express');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const ejs = require('ejs').__express;
|
||||||
|
const flash = require('connect-flash');
|
||||||
|
const session = require('express-session');
|
||||||
|
const cookieParser = require('cookie-parser');
|
||||||
|
const logger = require('morgan');
|
||||||
|
const passport = require('passport');
|
||||||
|
const cors = require('cors');
|
||||||
|
const methodOverride = require('method-override');
|
||||||
|
|
||||||
|
|
||||||
|
require('./config/passport');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
//const app = polka();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
require('express-helpers')(app);
|
||||||
|
// view engine setup
|
||||||
|
//app.disable('etag');
|
||||||
|
//app.set('views', path.join(__dirname, 'views'));
|
||||||
|
app.set("views", "./views");
|
||||||
|
|
||||||
|
//app.set("views", "./public/dist/");
|
||||||
|
|
||||||
|
app.set('view engine', 'ejs');
|
||||||
|
app.engine('.ejs', ejs); //
|
||||||
|
app.locals.rmWhitespace = true;
|
||||||
|
// Routes
|
||||||
|
const episodes = require('./routes/episodes');
|
||||||
|
const series = require('./routes/series');
|
||||||
|
|
||||||
|
app.locals.moment = require('moment');
|
||||||
|
const moment = require('moment');
|
||||||
|
moment.locale('es');
|
||||||
|
|
||||||
|
//app.use(express.logger('dev'));
|
||||||
|
//app.use(logger('dev'));
|
||||||
|
|
||||||
|
app.use(cors());
|
||||||
|
app.use(bodyParser.json({limit: '50mb'}));
|
||||||
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
// Angular DIST output folder
|
||||||
|
//app.use(express.static(path.join(__dirname, 'dist')));
|
||||||
|
// Original no angular
|
||||||
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
app.use(logger('dev'));
|
||||||
|
app.use(methodOverride('_method'));
|
||||||
|
|
||||||
|
//login system
|
||||||
|
app.use(cookieParser());
|
||||||
|
app.use(session({
|
||||||
|
cookie: { maxAge: 365 * 24 * 60 * 60 * 1000 },
|
||||||
|
secret: 'kontol',
|
||||||
|
saveUninitialized: false,
|
||||||
|
resave: false
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use(passport.initialize());
|
||||||
|
app.use(passport.session());
|
||||||
|
|
||||||
|
// Middlewares
|
||||||
|
app.use(flash());
|
||||||
|
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
res.locals.success_messages = req.flash('success');
|
||||||
|
res.locals.error_messages = req.flash('error');
|
||||||
|
res.locals.isAuthenticated = req.user ? true : false;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
app.use('/series', series);
|
||||||
|
app.use('/', episodes);
|
||||||
|
app.use('/episodes', episodes);
|
||||||
|
app.use('/show', episodes);
|
||||||
|
app.use('/anime', series);
|
||||||
|
app.use('/episodes', series);
|
||||||
|
|
||||||
|
|
||||||
|
app.use('/users', require('./routes/users'));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Catach 404 Errors and forward them to error handler
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
var err = new Error('404: Not Found ' + req.originalUrl); //here
|
||||||
|
err.status = 404;
|
||||||
|
next(err);// or null
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
|
@ -0,0 +1,39 @@
|
||||||
|
const passport = require('passport');
|
||||||
|
const LocalStrategy = require('passport-local').Strategy;
|
||||||
|
const User = require('../models/user');
|
||||||
|
|
||||||
|
passport.serializeUser((user, done) => {
|
||||||
|
done(null, user.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
passport.deserializeUser(async (id, done) => {
|
||||||
|
try{
|
||||||
|
const user = await User.findById(id);
|
||||||
|
done(null, user.id);
|
||||||
|
}catch(error){
|
||||||
|
done(error, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
passport.use('local', new LocalStrategy({
|
||||||
|
usernameField: 'email',
|
||||||
|
passwordField: 'password',
|
||||||
|
passReqToCallback: false
|
||||||
|
}, async (email, password, done)=>{
|
||||||
|
try{
|
||||||
|
// 1) Check if the email already exists
|
||||||
|
const user = await User.findOne({ 'email': email});
|
||||||
|
if (!user){
|
||||||
|
return done(null,false,{ message: 'Unknown User' })
|
||||||
|
}
|
||||||
|
// 2) Check if the password is correct
|
||||||
|
const isValit = User.comparePasswords(password,user.password);
|
||||||
|
if(isValit){
|
||||||
|
return done(null, user);
|
||||||
|
}else{
|
||||||
|
return done(null, false,{ message: 'Unknown Password'});
|
||||||
|
}
|
||||||
|
}catch(error){
|
||||||
|
return done(error, false);
|
||||||
|
}
|
||||||
|
}));
|
|
@ -0,0 +1,107 @@
|
||||||
|
const Episode = require("../models/episodes");
|
||||||
|
const Serie = require("../models/series");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
index: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
// Get all the episodes
|
||||||
|
const episode = await Episode.find({})
|
||||||
|
.lean()
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
.limit(9); // the correct order is -1
|
||||||
|
//res.render("index", { episode: episode });
|
||||||
|
//res.render('index', { name: 'John' });
|
||||||
|
res.json(episode);
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
newEpisode: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
// 1. Find the actual anime
|
||||||
|
const anime = await Serie.findById(req.body.anime);
|
||||||
|
// 2. Create a new episode
|
||||||
|
const newEpisode = req.body;
|
||||||
|
delete newEpisode.anime;
|
||||||
|
const episode = new Episode(newEpisode);
|
||||||
|
episode.anime = anime;
|
||||||
|
//anime.markModified('episode.anime');
|
||||||
|
await episode.save();
|
||||||
|
// 3. Add newly created episode to the actual anime
|
||||||
|
anime.episodes.push(episode);
|
||||||
|
//episode.markModified('anime.episodes');
|
||||||
|
//anime.markModified('anime.serie');
|
||||||
|
await anime.save();
|
||||||
|
// We're done!
|
||||||
|
res.json(episode);
|
||||||
|
// res.redirect("/");
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getEpisode: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const episode = await Episode.findOne({ slug: req.params.slug });
|
||||||
|
if (!episode) return next();
|
||||||
|
res.json(episode)
|
||||||
|
//res.render("show", { episode: episode });
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/* getEpisode: async (req, res, next) => {
|
||||||
|
const episode = await Episode.findById(req.params.episodeId);
|
||||||
|
res.render('show', { episode: episode });
|
||||||
|
//res.json(episode);
|
||||||
|
}, */
|
||||||
|
|
||||||
|
replaceEpisode: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const { episodeId } = req.params;
|
||||||
|
const newEpisode = req.body;
|
||||||
|
const result = await Episode.findByIdAndUpdate(episodeId, newEpisode);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateEpisode: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const { episodeId } = req.params;
|
||||||
|
const newEpisode = req.body;
|
||||||
|
const result = await Episode.findByIdAndUpdate(episodeId, newEpisode);
|
||||||
|
//res.json({ success: true });
|
||||||
|
res.redirect("/");
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteEpisode: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const { episodeId } = req.params;
|
||||||
|
// Get a episode
|
||||||
|
const episode = await Episode.findById(episodeId);
|
||||||
|
if (!episode) {
|
||||||
|
return res.status(404).json({ error: "Episode no existe" });
|
||||||
|
}
|
||||||
|
const animeId = episode.anime;
|
||||||
|
// Get a anime
|
||||||
|
const anime = await Serie.findById(animeId);
|
||||||
|
// Remove the episode
|
||||||
|
await episode.remove();
|
||||||
|
// Remove episode from the anime's selling list
|
||||||
|
console.log("anime", anime);
|
||||||
|
anime.episodes.pull(episode);
|
||||||
|
console.log("anime", anime);
|
||||||
|
await anime.save();
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,159 @@
|
||||||
|
const Serie = require("../models/series");
|
||||||
|
const Episode = require("../models/episodes");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/* original code without page (you have to modify the routes leave it alone in /)
|
||||||
|
index: async (req, res, next) => {
|
||||||
|
const serie = await Serie.find({})
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
.limit(9);
|
||||||
|
res.render("series", {serie: serie});
|
||||||
|
}, */
|
||||||
|
|
||||||
|
|
||||||
|
index: async (req, res, next) => {
|
||||||
|
const serie = await Serie.find({})
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
res.json(serie);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
Uncomment this code to use the page with ejs
|
||||||
|
index: async (req, res, next) => {
|
||||||
|
var perPage = 4;
|
||||||
|
var page = req.params.page || 1;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const serie = await Serie.find({})
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
.skip(perPage * page - perPage)
|
||||||
|
.limit(perPage)
|
||||||
|
.lean()
|
||||||
|
.exec(function(err, serie) {
|
||||||
|
Serie.count().exec(function(err, count) {
|
||||||
|
if (err) return next(err);
|
||||||
|
res.render("series", {
|
||||||
|
serie: serie,
|
||||||
|
current: page,
|
||||||
|
pages: Math.ceil(count / perPage)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
}, */
|
||||||
|
|
||||||
|
newSerie: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const newSerie = new Serie(req.body);
|
||||||
|
const serie = await newSerie.save();
|
||||||
|
//res.render("addserie",{serie: serie})
|
||||||
|
res.json(serie);
|
||||||
|
//res.redirect("/users/dashboard");
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//.lean(true) high performance .populate('episodes', 'slug -_id', null, {sort: { createdAt: -1 } });
|
||||||
|
getSerie: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const serie = await Serie.findOne({ slug: req.params.slug }).populate({
|
||||||
|
path: "episodes",
|
||||||
|
select: "slug -_id",
|
||||||
|
//, match: { x: 1 },
|
||||||
|
options: { sort: { createdAt: -1 }, limit: 9 }
|
||||||
|
});
|
||||||
|
if (!serie) return next();
|
||||||
|
//res.render("anime", { serie: serie });
|
||||||
|
res.json(serie);
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* getSerie: async (req, res, next) => {
|
||||||
|
const { serieId } = req.params;
|
||||||
|
const serie = await Serie.findById(serieId);
|
||||||
|
res.render('anime', { serie: serie });
|
||||||
|
//res.json(serie);
|
||||||
|
}, */
|
||||||
|
|
||||||
|
replaceSerie: async (req, res, next) => {
|
||||||
|
// enforce that req.body must contain all the fields
|
||||||
|
try {
|
||||||
|
const { serieId } = req.params;
|
||||||
|
const newSerie = req.body;
|
||||||
|
const result = await Serie.findByIdAndUpdate(serieId, newSerie);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateSerie: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
// req.body may contain any number of fields
|
||||||
|
const { serieId } = req.params;
|
||||||
|
const newSerie = req.body;
|
||||||
|
const result = await Serie.findByIdAndUpdate(serieId, newSerie);
|
||||||
|
//res.json({ success: true });
|
||||||
|
res.redirect("/");
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//the same as getseries
|
||||||
|
getSerieEpisodes: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const { serieId } = req.params;
|
||||||
|
const serie = await Serie.findById(serieId).populate("episodes");
|
||||||
|
//res.render('episodes', { serie : serie });
|
||||||
|
res.json(serie.episodes);
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
newSerieEpisode: async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const { serieId } = req.params;
|
||||||
|
// Create a new episode
|
||||||
|
const newEpisode = new Episode(req.body);
|
||||||
|
// Get series
|
||||||
|
const serie = await Serie.findById(serieId);
|
||||||
|
// Assing serie as episode's anime
|
||||||
|
newEpisode.anime = serie;
|
||||||
|
// Save the episode
|
||||||
|
await newEpisode.save();
|
||||||
|
// Add episode to the serie's selling array 'episodes'
|
||||||
|
serie.episodes.push(newEpisode);
|
||||||
|
// Save the series
|
||||||
|
await serie.save();
|
||||||
|
res.json(newEpisode);
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
We can interact with mongoose in 3 different ways:
|
||||||
|
1) Callbacks
|
||||||
|
2) Promises
|
||||||
|
3) [X] Async/Await (Promises) - this use for the code
|
||||||
|
*/
|
||||||
|
|
||||||
|
//let is used to isolate a code even if they have the same name are two different variables
|
||||||
|
//const their values after declaring they can be changed as long as the parent object is called
|
||||||
|
|
||||||
|
/* Example promises:
|
||||||
|
index: (req, res, next) => {
|
||||||
|
Serie.find({})
|
||||||
|
.then(series => {
|
||||||
|
res.status(200).json // res.render(series)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
next(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
*/
|
|
@ -0,0 +1,42 @@
|
||||||
|
let gulp = require('gulp');
|
||||||
|
let cleanCSS = require('gulp-clean-css');
|
||||||
|
var pump = require('pump');
|
||||||
|
var htmlmin = require('gulp-htmlmin');
|
||||||
|
var concat = require('gulp-concat');
|
||||||
|
var uglifyes = require('uglify-es');
|
||||||
|
var composer = require('gulp-uglify/composer');
|
||||||
|
var minify = composer(uglifyes);
|
||||||
|
|
||||||
|
gulp.task('default', () =>
|
||||||
|
console.log('See you in another video')
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('minify-css', () => {
|
||||||
|
return gulp.src('public/css/*.css')
|
||||||
|
.pipe(cleanCSS(
|
||||||
|
{level: {1: {specialComments: 0}}}))
|
||||||
|
.pipe(concat('cssbundle.css'))
|
||||||
|
.pipe(gulp.dest('public/dist/css'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('compress', () => {
|
||||||
|
pump([
|
||||||
|
gulp.src(['./*.js','controllers/*.js','models/*.js','routes/*.js','helpers/*.js']),
|
||||||
|
minify(),
|
||||||
|
concat('jsbundle.js'),
|
||||||
|
gulp.dest('public/dist/js')
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('minify-html', () => {
|
||||||
|
return gulp.src(['views/*.ejs','views/layouts/*.ejs'])
|
||||||
|
.pipe(htmlmin({collapseWhitespace: true,
|
||||||
|
collapseInlineTagWhitespace:true,
|
||||||
|
removeComments: true,
|
||||||
|
removeRedundantAttributes:true,
|
||||||
|
useShortDoctype:true,
|
||||||
|
html5: true }))
|
||||||
|
.pipe(concat('htmlbundle.ejs'))
|
||||||
|
.pipe(gulp.dest('public/dist/html'));
|
||||||
|
});
|
|
@ -0,0 +1,50 @@
|
||||||
|
const Joi = require('joi');
|
||||||
|
// validation does not work well prevents parameters from being entered into the database
|
||||||
|
module.exports = {
|
||||||
|
validateParam: (schema, name) => {
|
||||||
|
return (req, res, next) => {
|
||||||
|
const result = Joi.validate({ param: req['params'][name] }, schema);
|
||||||
|
if (result.error){
|
||||||
|
return res.status(400).json(result.error);
|
||||||
|
} else {
|
||||||
|
if (!req.value)
|
||||||
|
req.value = {};
|
||||||
|
|
||||||
|
if (!req.value['params'])
|
||||||
|
req.value['params'] = {};
|
||||||
|
|
||||||
|
req.value['params'][name] = result.value.param;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Work but for any rasons not implements
|
||||||
|
validateBody: (schema) => {
|
||||||
|
return (req, res, next) => {
|
||||||
|
const result = Joi.validate(req.body, schema);
|
||||||
|
if (result.error) {
|
||||||
|
return res.status(400).json(result.error);
|
||||||
|
} else {
|
||||||
|
if (!req.value)
|
||||||
|
req.value = {};
|
||||||
|
|
||||||
|
if (!req.value['body'])
|
||||||
|
req.value['body'] = {};
|
||||||
|
|
||||||
|
req.value['body'] = result.value;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
schemas: {
|
||||||
|
serieSchema: Joi.object().keys({
|
||||||
|
title: Joi.string().optional(),
|
||||||
|
synopsis: Joi.string().optional()
|
||||||
|
}),
|
||||||
|
|
||||||
|
idSchema: Joi.object().keys({
|
||||||
|
param: Joi.string().regex(/^[0-9a-fA-F]{24}$/).required()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
const slug = require('slugs');
|
||||||
|
|
||||||
|
|
||||||
|
const episodeSchema= new Schema({
|
||||||
|
|
||||||
|
title: {
|
||||||
|
type: String,index: true
|
||||||
|
},
|
||||||
|
slug: String,
|
||||||
|
serieTitle: String,
|
||||||
|
chapterTitle: String,
|
||||||
|
chapter: Number,
|
||||||
|
server: String,
|
||||||
|
serverTwo: String,
|
||||||
|
imageCap: String,
|
||||||
|
download: String,
|
||||||
|
anime: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: 'serie'
|
||||||
|
}
|
||||||
|
}, { timestamps: {} }
|
||||||
|
//{
|
||||||
|
//toJSON: { virtuals: true },
|
||||||
|
//toObject: { virtuals: true },
|
||||||
|
//},
|
||||||
|
//{ runSettersOnQuery: true }
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Da error
|
||||||
|
/* // Define our indexes
|
||||||
|
episodeSchema.index({
|
||||||
|
title: 'text',
|
||||||
|
});
|
||||||
|
|
||||||
|
episodeSchema.index({
|
||||||
|
location: 'indexloco'
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
episodeSchema.pre('save', async function (next) {
|
||||||
|
if (!this.isModified('title')) {
|
||||||
|
next(); // skip it
|
||||||
|
return; // stop this function from running
|
||||||
|
}
|
||||||
|
this.slug = slug(this.title);
|
||||||
|
// find other stores that have a slug of wes, wes-1, wes-2
|
||||||
|
const slugRegEx = new RegExp(`^(${this.slug})((-[0-9]*$)?)$`, 'i');
|
||||||
|
const storesWithSlug = await this.constructor.find({
|
||||||
|
slug: slugRegEx
|
||||||
|
});
|
||||||
|
if (storesWithSlug.length) {
|
||||||
|
this.slug = `${this.slug}-${storesWithSlug.length + 1}`; //`` blackstring generacion de cadenas
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
// TODO make more resiliant so slugs are unique
|
||||||
|
});
|
||||||
|
|
||||||
|
const Episode = mongoose.model('episode', episodeSchema);
|
||||||
|
module.exports = Episode;
|
|
@ -0,0 +1,66 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
const slug = require('slugs');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const serieSchema = new Schema({
|
||||||
|
|
||||||
|
title: {
|
||||||
|
type: String, index: true
|
||||||
|
},
|
||||||
|
slug: String,
|
||||||
|
cover: String,
|
||||||
|
backgroundimage: String,
|
||||||
|
frontimage: String,
|
||||||
|
synopsis: String,
|
||||||
|
estate: String,
|
||||||
|
type: String,
|
||||||
|
tags: [String],
|
||||||
|
episodes: [{
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: 'episode'
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
timestamps: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
serieSchema.pre('save', async function (next) {
|
||||||
|
if (!this.isModified('title')) {
|
||||||
|
next(); // skip it
|
||||||
|
return; // stop this function from running
|
||||||
|
}
|
||||||
|
this.slug = slug(this.title);
|
||||||
|
// find other stores that have a slug of wes, wes-1, wes-2
|
||||||
|
const slugRegEx = new RegExp(`^(${this.slug})((-[0-9]*$)?)$`, 'i');
|
||||||
|
const storesWithSlug = await this.constructor.find({
|
||||||
|
slug: slugRegEx
|
||||||
|
});
|
||||||
|
if (storesWithSlug.length) {
|
||||||
|
this.slug = `${this.slug}-${storesWithSlug.length + 1}`; //`` blackstring generacion de cadenas
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
// TODO make more resiliant so slugs are unique
|
||||||
|
});
|
||||||
|
|
||||||
|
serieSchema.statics.getTagsList = function() {
|
||||||
|
return this.aggregate([
|
||||||
|
{ $unwind: '$tags' },
|
||||||
|
{ $group: { _id: '$tags', count: { $sum: 1 } } },
|
||||||
|
{ $sort: { count: -1 } }
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* function autopopulate(next) {
|
||||||
|
this.populate('episodes', 'slug');
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
serieSchema.pre('find', autopopulate);
|
||||||
|
serieSchema.pre('findOne', autopopulate);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
const Serie = mongoose.model('serie', serieSchema);
|
||||||
|
module.exports = Serie;
|
|
@ -0,0 +1,34 @@
|
||||||
|
const mongoose = require("mongoose");
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
|
||||||
|
const userSchema = new Schema(
|
||||||
|
{
|
||||||
|
email: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
username: String,
|
||||||
|
password: String
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: {}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const User = mongoose.model("user", userSchema);
|
||||||
|
module.exports = User;
|
||||||
|
module.exports.hashPassword = async password => {
|
||||||
|
try {
|
||||||
|
const salt = await bcrypt.genSalt(10);
|
||||||
|
return await bcrypt.hash(password, salt);
|
||||||
|
} catch (error) {
|
||||||
|
throw new error("Hashing failed", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
module.exports.comparePasswords = async (inputPassword, hashedPassword) => {
|
||||||
|
try {
|
||||||
|
return await bcrypt.compare(inputPassword, hashedPassword);
|
||||||
|
} catch (error) {
|
||||||
|
throw new error("Comparing failed", error);
|
||||||
|
}
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"name": "MPOKNIMU",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "app.js",
|
||||||
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 9.3.0"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"prod": "NODE_ENV=production node ./start.js",
|
||||||
|
"watch": "nodemon ./start.js",
|
||||||
|
"start": "concurrently \"npm run watch\" --names \"💻,📦\" --prefix name"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bcryptjs": "^2.4.3",
|
||||||
|
"body-parser": "^1.17.2",
|
||||||
|
"chalk": "^2.0.1",
|
||||||
|
"connect-flash": "^0.1.1",
|
||||||
|
"cookie-parser": "^1.4.3",
|
||||||
|
"cors": "^2.8.4",
|
||||||
|
"dotenv": "^4.0.0",
|
||||||
|
"ejs": "^2.5.6",
|
||||||
|
"express": "^4.16.2",
|
||||||
|
"express-helpers": "^1.3.2",
|
||||||
|
"express-messages": "^1.0.1",
|
||||||
|
"express-session": "^1.15.6",
|
||||||
|
"joi": "^10.6.0",
|
||||||
|
"method-override": "^2.3.10",
|
||||||
|
"moment": "^2.20.1",
|
||||||
|
"mongoose": "^5.0.1",
|
||||||
|
"morgan": "^1.9.0",
|
||||||
|
"passport": "^0.4.0",
|
||||||
|
"passport-local": "^1.0.0",
|
||||||
|
"pump": "^2.0.0",
|
||||||
|
"slugs": "^0.1.3"
|
||||||
|
},
|
||||||
|
"browserslist": "last 2 versions",
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^7.2.5",
|
||||||
|
"babel-core": "^6.26.0",
|
||||||
|
"babel-preset-env": "^1.6.1",
|
||||||
|
"concurrently": "^3.5.1",
|
||||||
|
"gulp": "^3.9.1",
|
||||||
|
"gulp-clean-css": "^3.9.2",
|
||||||
|
"gulp-concat": "^2.6.1",
|
||||||
|
"gulp-htmlmin": "^4.0.0",
|
||||||
|
"gulp-uglify": "^3.0.0",
|
||||||
|
"node-sass": "^4.7.2",
|
||||||
|
"nodemon": "^1.14.11",
|
||||||
|
"uglify-es": "^3.3.7"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,281 @@
|
||||||
|
/*!
|
||||||
|
STYLE GUIDE
|
||||||
|
1. NAV-BAR
|
||||||
|
2. Series
|
||||||
|
3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
a{
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caps{
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
width:auto;
|
||||||
|
margin:auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image{
|
||||||
|
max-width: 220px;
|
||||||
|
max-height: 300px;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* videoplayer */
|
||||||
|
.container{
|
||||||
|
width: 880px;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.elementoVideo{
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
display:flex;
|
||||||
|
flex-flow:row wrap;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.elemento{
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
margin: 10px;
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
display:flex;
|
||||||
|
flex-flow:row wrap;
|
||||||
|
justify-content:flex-start;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
align-items: baseline;
|
||||||
|
align-content: flex-start;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.elementoAnime{
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
margin: 10px;
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
display:flex;
|
||||||
|
/* height: auto;
|
||||||
|
flex-basis: auto;*/
|
||||||
|
flex-flow:column wrap;
|
||||||
|
justify-content:flex-start;
|
||||||
|
/* that all encompass 100%
|
||||||
|
flex-grow:1;*/
|
||||||
|
/* align-content: center; */
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.elementoDash{
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
margin: 10px;
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
display:flex;
|
||||||
|
/* height: auto;
|
||||||
|
flex-basis: auto;*/
|
||||||
|
flex-flow:column wrap;
|
||||||
|
justify-content:flex-start;
|
||||||
|
/* that all encompass 100%
|
||||||
|
flex-grow:1;*/
|
||||||
|
/* align-content: center; */
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sada1 {
|
||||||
|
margin-right: 30px;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
.contenedor {
|
||||||
|
background:#212121;
|
||||||
|
width:auto;
|
||||||
|
height:auto;
|
||||||
|
margin:auto;
|
||||||
|
/* Flexbox */
|
||||||
|
display:flex;
|
||||||
|
flex-flow:row wrap;
|
||||||
|
min-height: 100vh;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background:#263238;
|
||||||
|
width:100%;
|
||||||
|
padding:20px;
|
||||||
|
/* Flexbox */
|
||||||
|
display: flex;
|
||||||
|
justify-content:space-between;
|
||||||
|
align-items:center;
|
||||||
|
|
||||||
|
flex-direction:row;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header .logo {
|
||||||
|
color:#FFFFFF;
|
||||||
|
font-size:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .logo img {
|
||||||
|
width:50px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .logo a {
|
||||||
|
color:#FFFFFF;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height:50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav {
|
||||||
|
width:50%;
|
||||||
|
/* Flexbox */
|
||||||
|
|
||||||
|
display:flex;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
align-items:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav a {
|
||||||
|
background:#455A64;
|
||||||
|
color:#FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
padding:10px;
|
||||||
|
|
||||||
|
/* Flexbox */
|
||||||
|
flex-grow:1;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav a:hover {
|
||||||
|
background:#78909C;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
background:#263238;
|
||||||
|
width: 100%;
|
||||||
|
padding:20px;
|
||||||
|
/* Flexbox */
|
||||||
|
display: flex;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
justify-content:space-between;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
footer .links {
|
||||||
|
background:#455A64;
|
||||||
|
display:flex;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer .links a {
|
||||||
|
flex-grow:1;
|
||||||
|
|
||||||
|
color:#FFFFFF;
|
||||||
|
padding:10px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer .links a:hover {
|
||||||
|
background:#78909C;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer .social {
|
||||||
|
background:#455A64;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer .social a {
|
||||||
|
color:#FFFFFF;
|
||||||
|
text-decoration: none;
|
||||||
|
padding:10px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
.contenedor {
|
||||||
|
flex-direction:column;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
flex-direction:column;
|
||||||
|
padding:0;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .logo {
|
||||||
|
margin:20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination{
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.pagination a {
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 8px 16px;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination a.active {
|
||||||
|
background-color: #455a64;
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination a:hover:not(.active) {
|
||||||
|
background-color: #78909C;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px) {
|
||||||
|
.sada1 {
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
|
||||||
|
footer {
|
||||||
|
justify-content:space-around;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Series */
|
||||||
|
|
||||||
|
#dash{
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
body{background-color:#ff0!important}
|
|
@ -0,0 +1 @@
|
||||||
|
<% include ./layouts/header %> <body><h1>Anime View</h1><h4 class="card-title"> <%- serie.title %> </h4><br> <%- serie.synopsis.substring(0,48) %>...<br><br><h6>Type:</h6><ul> <%- link_to(serie.type) %> </ul><h6>Genre:</h6><ul> <% for(var i=0; i<serie.tags.length; i++) {%> <li> <%- link_to(serie.tags[i], '/'+serie.tags[i]) %> </li> <% } %> </ul><h6>Episode:</h6><ul> <% for(var i=0; i<serie.episodes.length; i++) {%> <li> <%- link_to(serie.episodes[i].slug, '/'+serie.episodes[i].slug) %> </li> <% } %> </ul></body>
|
|
@ -0,0 +1 @@
|
||||||
|
<% include ./layouts/header %> <body><h4>Episodes</h4> <%- serie.serieTitle %> </body>
|
|
@ -0,0 +1 @@
|
||||||
|
<!-- FOOT -->
|
|
@ -0,0 +1 @@
|
||||||
|
<!DOCTYPE html><html lang="en"><head><title>MPOKNIMU</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><link href="/dist/pure-min.css" rel="stylesheet"><link href="/dist/app.css" rel="stylesheet"><nav class="navbar navbar-expand-lg navbar-light bg-light"><a class="navbar-brand" href="#">Anime</a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarNav"><ul class="navbar-nav"><li class="nav-item active"><a class="nav-link" href="http://localhost:9000/">Home</a></li><li class="nav-item"><a class="nav-link" href="/series">Series</a></li><li class="nav-item"><a class="nav-link" href="#">Login</a></li></ul></div></nav><div class="hola" id="hola">Hello</div></head></html>
|
|
@ -0,0 +1,21 @@
|
||||||
|
<% include ./layouts/header %> <body><h1>View Anime</h1><h4 class="card-title"> <%- serie.title %> </h4><br> <%- serie.synopsis.substring(0,48) %>...<br><br><h6>Type:</h6><ul> <%- link_to(serie.type) %> </ul><h6>Genre:</h6><ul> <% for(var i=0; i<serie.tags.length; i++) {%> <li> <%- link_to(serie.tags[i], '/'+serie.tags[i]) %> </li> <% } %> </ul><h6>Chapters:</h6><ul> <% for(var i=0; i<serie.episodes.length; i++) {%> <li> <%- link_to(serie.episodes[i].slug, '/'+serie.episodes[i].slug) %> </li> <% } %> </ul></body>
|
||||||
|
<% include ./layouts/header %> <body><h4>Episodes</h4> <%- serie.serieTitle %> </body>
|
||||||
|
<% include ./layouts/header %> <body> <% episode.forEach(function(episode) { %> <div class="container" style="width: 720px;margin-top: 15px;"><div class="row"> <% const episodeUrl = '/episodes/' + episode.slug; %> <div class="col"><div class="card-group" style="margin-right: 190px;"><div class="card"><a href="<%- episode.slug %>" class="card-link"><img class="card-img-top img-fluid" src="<%- episode.imageCap %> " alt="Card image cap"></a><div class="card-block"><h4 class="card-title"><a href="<%- episode.slug %>" class="card-link"> <%- episode.serieTitle %> </a></h4><h7 class="card-title"> <%- episode.serieTitle %> </h7><p class="card-text"><small class="text-muted"><%- episode.createdAt %></small></p></div></div></div></div> <% }); %> </div></div></body>
|
||||||
|
<% include ./layouts/header %> <body><div class="container" style="width: 720px;margin-top: 15px;"><div class="row"> <% serie.forEach(function(serie) { %> <div class="col"> <% const serieUrl = '/series/' + serie.slug; %> <div class="card-group"><div class="card" style="width: 20rem; margin-bottom: 15px;"><a href="anime/<%- serie.slug %>" class="card-link"><img class="card-img-top" id="image-home" src="<%- serie.cover %>" alt="Card image cap"></a><div class="card-block"><h4 class="card-title"> <%- serie.title.substring(0,18) %>...</h4><p class="card-text"> <%- serie.synopsis.substring(0,48) %>...</p></div><ul class="list-group list-group-flush"><li class="list-group-item"> <%- serie.type %> <%- serie.episodes %> </li></ul><div class="card-block"><a href="#" class="card-link">Watch Anime</a></div></div></div></div> <% }); %> </div></div><nav aria-label="Page navigation example"><ul class="pagination justify-content-center"><li class="page-item"><a class="page-link" href="#">Previous</a></li><li class="page-item"><a class="page-link" href="#">1</a></li><li class="page-item"><a class="page-link" href="#">2</a></li><li class="page-item"><a class="page-link" href="#">3</a></li><li class="page-item"><a class="page-link" href="#">Next</a></li></ul></nav></body>
|
||||||
|
<% include ./layouts/header %> <script src="https://content.jwplatform.com/libraries/bfIbW5Pe.js"></script><body><div class="container" style="width: 720px;margin-top: 15px;"><div class="row"><h1> <%- episode.serieTitle %> <%- episode.chapter %> </h1><br> <%- episode.server %> <br><div id="myElement"></div><script type="text/javascript">var playerInstance = jwplayer("myElement");
|
||||||
|
playerInstance.setup({
|
||||||
|
file: "<%- episode.server %>",
|
||||||
|
height: "440",
|
||||||
|
width: "720",
|
||||||
|
autostart: false,
|
||||||
|
playbackRateControls: [0.25, 0.75, 1, 1.25, 2, 3],
|
||||||
|
title: "<%- episode.serieTitle %> <%- episode.chapter %>",
|
||||||
|
image: "<%- episode.imageCap %>",
|
||||||
|
abouttext: "<%- episode.serieTitle %> <%- episode.chapter %>",
|
||||||
|
displaytitle: true,
|
||||||
|
timeSliderAbove: true,
|
||||||
|
primary: "html5",
|
||||||
|
preload: "metadata"
|
||||||
|
});</script></div></div></body>
|
||||||
|
|
||||||
|
<!DOCTYPE html><html lang="en"><head><title>MPOKNIMU</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><link href="/dist/pure-min.css" rel="stylesheet"><link href="/dist/app.css" rel="stylesheet"><nav class="navbar navbar-expand-lg navbar-light bg-light"><a class="navbar-brand" href="#">Anime</a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarNav"><ul class="navbar-nav"><li class="nav-item active"><a class="nav-link" href="http://localhost:9000/">Home</a></li><li class="nav-item"><a class="nav-link" href="/series">Series</a></li><li class="nav-item"><a class="nav-link" href="#">Login</a></li></ul></div></nav><div class="hola" id="hola">Hallo</div></head></html>
|
|
@ -0,0 +1 @@
|
||||||
|
<% include ./layouts/header %> <body> <% episode.forEach(function(episode) { %> <div class="container" style="width: 720px;margin-top: 15px;"><div class="row"> <% const episodeUrl = '/episodes/' + episode.slug; %> <div class="col"><div class="card-group" style="margin-right: 190px;"><div class="card"><a href="<%- episode.slug %>" class="card-link"><img class="card-img-top img-fluid" src="<%- episode.imageCap %> " alt="Card image cap"></a><div class="card-block"><h4 class="card-title"><a href="<%- episode.slug %>" class="card-link"> <%- episode.serieTitle %> </a></h4><h7 class="card-title"> <%- episode.serieTitle %> </h7><p class="card-text"><small class="text-muted"><%- episode.createdAt %></small></p></div></div></div></div> <% }); %> </div></div></body>
|
|
@ -0,0 +1 @@
|
||||||
|
<% include ./layouts/header %> <body><div class="container" style="width: 720px;margin-top: 15px;"><div class="row"> <% serie.forEach(function(serie) { %> <div class="col"> <% const serieUrl = '/series/' + serie.slug; %> <div class="card-group"><div class="card" style="width: 20rem; margin-bottom: 15px;"><a href="anime/<%- serie.slug %>" class="card-link"><img class="card-img-top" id="image-home" src="<%- serie.cover %>" alt="Card image cap"></a><div class="card-block"><h4 class="card-title"> <%- serie.title.substring(0,18) %>...</h4><p class="card-text"> <%- serie.synopsis.substring(0,48) %>...</p></div><ul class="list-group list-group-flush"><li class="list-group-item"> <%- serie.type %> <%- serie.episodes %> </li></ul><div class="card-block"><a href="#" class="card-link">Watch Anime</a></div></div></div></div> <% }); %> </div></div><nav aria-label="Page navigation example"><ul class="pagination justify-content-center"><li class="page-item"><a class="page-link" href="#">Previous</a></li><li class="page-item"><a class="page-link" href="#">1</a></li><li class="page-item"><a class="page-link" href="#">2</a></li><li class="page-item"><a class="page-link" href="#">3</a></li><li class="page-item"><a class="page-link" href="#">Next</a></li></ul></nav></body>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<% include ./layouts/header %> <script src="https://content.jwplatform.com/libraries/bfIbW5Pe.js"></script><body><div class="container" style="width: 720px;margin-top: 15px;"><div class="row"><h1> <%- episode.serieTitle %> <%- episode.chapter %> </h1><br> <%- episode.server %> <br><div id="myElement"></div><script type="text/javascript">var playerInstance = jwplayer("myElement");
|
||||||
|
playerInstance.setup({
|
||||||
|
file: "<%- episode.server %>",
|
||||||
|
height: "440",
|
||||||
|
width: "720",
|
||||||
|
autostart: false,
|
||||||
|
playbackRateControls: [0.25, 0.75, 1, 1.25, 2, 3],
|
||||||
|
title: "<%- episode.serieTitle %> <%- episode.chapter %>",
|
||||||
|
image: "<%- episode.imageCap %>",
|
||||||
|
abouttext: "<%- episode.serieTitle %> <%- episode.chapter %>",
|
||||||
|
displaytitle: true,
|
||||||
|
timeSliderAbove: true,
|
||||||
|
primary: "html5",
|
||||||
|
preload: "metadata"
|
||||||
|
});</script></div></div></body>
|
|
@ -0,0 +1 @@
|
||||||
|
const path=require("path"),express=require("express"),bodyParser=require("body-parser"),ejs=require("ejs").__express,chalk=require("chalk"),log=console.log,error=chalk.bold.red,app=express();require("express-helpers")(app),app.set("views","./views"),app.set("view engine","ejs"),app.engine(".ejs",ejs),app.locals.rmWhitespace=!0;const episodes=require("./routes/episodes"),series=require("./routes/series");app.use(bodyParser.json({limit:"50mb"})),app.use(bodyParser.urlencoded({extended:!1})),app.use(express.static(path.join(__dirname,"public"))),app.use("/series",series),app.use("/",episodes),app.use("/episodes",episodes),app.use("/show",episodes),app.use("/anime",series),app.use("/episodes",series),app.use(function(e,s,p){var r=new Error("404: Not Found "+e.originalUrl);r.status=404,p(r)}),module.exports=app;
|
|
@ -0,0 +1 @@
|
||||||
|
let gulp=require("gulp"),cleanCSS=require("gulp-clean-css");var pump=require("pump"),htmlmin=require("gulp-htmlmin"),uglifyes=require("uglify-es"),composer=require("gulp-uglify/composer"),minify=composer(uglifyes);gulp.task("default",()=>console.log("See you in another video kids")),gulp.task("minify-css",()=>gulp.src("public/css/*.css").pipe(cleanCSS({level:{1:{specialComments:0}}})).pipe(gulp.dest("public/dist/css"))),gulp.task("compress",()=>{pump([gulp.src("./*.js"),minify(),gulp.dest("public/dist/js")])}),gulp.task("minify-html",function(){return gulp.src("views/*.ejs").pipe(htmlmin({collapseWhitespace:!0,collapseInlineTagWhitespace:!0,removeComments:!0,removeRedundantAttributes:!0,useShortDoctype:!0,html5:!0})).pipe(gulp.dest("public/dist/html"))});
|
|
@ -0,0 +1,10 @@
|
||||||
|
const path=require("path"),express=require("express"),bodyParser=require("body-parser"),ejs=require("ejs").__express,app=express();require("express-helpers")(app),app.set("views","./views"),app.set("view engine","ejs"),app.engine(".ejs",ejs),app.locals.rmWhitespace=!0;const episodes=require("./routes/episodes"),series=require("./routes/series");app.use(bodyParser.json({limit:"50mb"})),app.use(bodyParser.urlencoded({extended:!1})),app.use(express.static(path.join(__dirname,"public"))),app.use("/series",series),app.use("/",episodes),app.use("/episodes",episodes),app.use("/show",episodes),app.use("/anime",series),app.use("/episodes",series),app.use(function(e,s,p){var r=new Error("404: Not Found "+e.originalUrl);r.status=404,p(r)}),module.exports=app;
|
||||||
|
let gulp=require("gulp"),cleanCSS=require("gulp-clean-css");var pump=require("pump"),htmlmin=require("gulp-htmlmin"),concat=require("gulp-concat"),uglifyes=require("uglify-es"),composer=require("gulp-uglify/composer"),minify=composer(uglifyes);gulp.task("default",()=>console.log("See you in another vineyard")),gulp.task("minify-css",()=>gulp.src("public/css/*.css").pipe(cleanCSS({level:{1:{specialComments:0}}})).pipe(concat("bundle-css.css")).pipe(gulp.dest("public/dist/css"))),gulp.task("compress",()=>{pump([gulp.src(["./*.js","controllers/*.js","models/*.js","routes/*.js","helpers/*.js"]),minify(),concat("jsbundle.js"),gulp.dest("public/dist/js")])}),gulp.task("minify-html",()=>gulp.src(["views/*.ejs","views/layouts/*.ejs"]).pipe(htmlmin({collapseWhitespace:!0,collapseInlineTagWhitespace:!0,removeComments:!0,removeRedundantAttributes:!0,useShortDoctype:!0,html5:!0})).pipe(concat("bundle-html.html")).pipe(gulp.dest("public/dist/html")));
|
||||||
|
const mongoose=require("mongoose"),chalk=require("chalk"),log=console.log,error=chalk.bold.red;require("dotenv").config({path:"variables.env"}),mongoose.Promise=global.Promise;let mongodbUri=mongoose.connect("mongodb://YOUR MONGODB URL",{useMongoClient:!0,poolSize:3,reconnectTries:240,reconnectInterval:900,autoReconnect:!0,noDelay:!0,loggerLevel:"error"});const db=mongoose.connection;db.on("error",console.error.bind(console,"MongoDB connection error:")),db.once("open",function(){log(chalk.hex("#FFEB3B")("Te conectaste a la base de datos sin errores 👠"),chalk.greenBright("ðŸ˜"))}),process.on("unhandledRejection",(e,o)=>{console.log("Unhandled Rejection at: Promise",o,"reason:",e)});const appp=require("./app");appp.set("port",process.env.PORT||9e3);const server=appp.listen(appp.get("port"),()=>{log(chalk.underline.hex("#DEADED")("Server is listening music on port:"),chalk.hex("#4CAF50")(`🌠PORT → ${server.address().port} 🎶`))});
|
||||||
|
const Episode=require("../models/episodes"),Serie=require("../models/series");module.exports={index:async(e,s,i)=>{const d=await Episode.find({}).sort({createdAt:-1}).limit(9);s.render("index",{episode:d})},newEpisode:async(e,s,i)=>{const d=await Serie.findById(e.body.anime),o=e.body;delete o.anime;const a=new Episode(o);a.anime=d,await a.save(),d.episodes.push(a),await d.save(),s.json(a)},getEpisode:async(e,s,i)=>{const d=await Episode.findOne({slug:e.params.slug});if(!d)return i();s.render("show",{episode:d})},replaceEpisode:async(e,s,i)=>{const{episodeId:d}=e.params,o=e.body;await Episode.findByIdAndUpdate(d,o);s.json({success:!0})},updateEpisode:async(e,s,i)=>{const{episodeId:d}=e.params,o=e.body;await Episode.findByIdAndUpdate(d,o);s.json({success:!0})},deleteEpisode:async(e,s,i)=>{const{episodeId:d}=e.params,o=await Episode.findById(d);if(!o)return s.status(404).json({error:"Episode no existe"});const a=o.anime,n=await Serie.findById(a);await o.remove(),console.log("anime",n),n.episodes.pull(o),console.log("anime",n),await n.save(),s.json({success:!0})}};
|
||||||
|
const Serie=require("../models/series"),Episode=require("../models/episodes");module.exports={index:async(e,s,i)=>{const a=await Serie.find({}).sort({createdAt:-1}).limit(9);s.render("series",{serie:a})},newSerie:async(e,s,i)=>{const a=new Serie(e.body),r=await a.save();s.json(r)},getSerie:async(e,s,i)=>{const a=await Serie.findOne({slug:e.params.slug}).populate({path:"episodes",select:"slug -_id",options:{sort:{createdAt:-1},limit:9}});if(!a)return i();s.render("anime",{serie:a})},replaceSerie:async(e,s,i)=>{const{serieId:a}=e.params,r=e.body;await Serie.findByIdAndUpdate(a,r);s.json({success:!0})},updateSerie:async(e,s,i)=>{const{serieId:a}=e.params,r=e.body;await Serie.findByIdAndUpdate(a,r);s.json({success:!0})},getSerieEpisodes:async(e,s,i)=>{const{serieId:a}=e.params,r=await Serie.findById(a).populate("episodes");s.json(r.episodes)},newSerieEpisode:async(e,s,i)=>{const{serieId:a}=e.params,r=new Episode(e.body),d=await Serie.findById(a);r.anime=d,await r.save(),d.episodes.push(r),await d.save(),s.json(r)}};
|
||||||
|
const mongoose=require("mongoose"),Schema=mongoose.Schema,slug=require("slugs"),episodeSchema=new Schema({title:{type:String},slug:String,serieTitle:String,chapterTitle:String,chapter:Number,server:String,serverTwo:String,imageCap:String,anime:{type:Schema.Types.ObjectId,ref:"serie"}},{timestamps:{}});episodeSchema.pre("save",async function(e){if(!this.isModified("title"))return void e();this.slug=slug(this.title);const s=new RegExp(`^(${this.slug})((-[0-9]*$)?)$`,"i"),i=await this.constructor.find({slug:s});i.length&&(this.slug=`${this.slug}-${i.length+1}`),e()});const Episode=mongoose.model("episode",episodeSchema);module.exports=Episode;
|
||||||
|
const mongoose=require("mongoose"),Schema=mongoose.Schema,slug=require("slugs"),serieSchema=new Schema({title:{type:String},slug:String,cover:String,backgroundimage:String,frontimage:String,synopsis:String,estate:String,type:String,tags:[String],episodes:[{type:Schema.Types.ObjectId,ref:"episode"}]},{timestamps:{}});serieSchema.pre("save",async function(e){if(!this.isModified("title"))return void e();this.slug=slug(this.title);const t=new RegExp(`^(${this.slug})((-[0-9]*$)?)$`,"i"),s=await this.constructor.find({slug:t});s.length&&(this.slug=`${this.slug}-${s.length+1}`),e()}),serieSchema.statics.getTagsList=function(){return this.aggregate([{$unwind:"$tags"},{$group:{_id:"$tags",count:{$sum:1}}},{$sort:{count:-1}}])};const Serie=mongoose.model("serie",serieSchema);module.exports=Serie;
|
||||||
|
const router=require("express-promise-router")(),EpisodesController=require("../controllers/episodes");router.route("/").get(EpisodesController.index).post(EpisodesController.newEpisode),router.route("/:slug").get(EpisodesController.getEpisode).put(EpisodesController.replaceEpisode).patch(EpisodesController.updateEpisode).delete(EpisodesController.deleteEpisode),module.exports=router;
|
||||||
|
const express=require("express"),router=require("express-promise-router")(),SeriesController=require("../controllers/series");router.route("/").get(SeriesController.index).post(SeriesController.newSerie),router.route("/:slug").get(SeriesController.getSerie).put(SeriesController.replaceSerie).patch(SeriesController.updateSerie),router.route("/:serieId/episodes").get(SeriesController.getSerieEpisodes).post(SeriesController.newSerieEpisode),module.exports=router;
|
||||||
|
const Joi=require("joi");module.exports={validateParam:(a,e)=>(r,o,i)=>{const s=Joi.validate({param:r.params[e]},a);if(s.error)return o.status(400).json(s.error);r.value||(r.value={}),r.value.params||(r.value.params={}),r.value.params[e]=s.value.param,i()},validateBody:a=>(e,r,o)=>{const i=Joi.validate(e.body,a);if(i.error)return r.status(400).json(i.error);e.value||(e.value={}),e.value.body||(e.value.body={}),e.value.body=i.value,o()},schemas:{serieSchema:Joi.object().keys({title:Joi.string().optional(),synopsis:Joi.string().optional()}),idSchema:Joi.object().keys({param:Joi.string().regex(/^[0-9a-fA-F]{24}$/).required()})}};
|
|
@ -0,0 +1 @@
|
||||||
|
const mongoose=require("mongoose"),chalk=require("chalk"),log=console.log,error=chalk.bold.red;require("dotenv").config({path:"variables.env"}),mongoose.Promise=global.Promise;let mongodbUri=mongoose.connect("mongodb://YOUR MONGODB URL",{useMongoClient:!0,poolSize:3,reconnectTries:240,reconnectInterval:900,autoReconnect:!0,noDelay:!0,loggerLevel:"error"});const db=mongoose.connection;db.on("error",console.error.bind(console,"MongoDB connection error:")),db.once("open",function(){log(chalk.hex("#FFEB3B")("Did you connect to the database without errors"),chalk.greenBright("ðŸ˜"))}),process.on("unhandledRejection",(e,o)=>{console.log("Unhandled Rejection at: Promise",o,"reason:",e)});const app=require("./app");app.set("port",process.env.PORT||9e3);const server=app.listen(app.get("port"),()=>{log(chalk.underline.hex("#DEADED")("Server is listening music on port:"),chalk.hex("#4CAF50")(`🌠PORT → ${server.address().port} 🎶`))});
|
|
@ -0,0 +1,23 @@
|
||||||
|
const express = require("express");
|
||||||
|
const router = express.Router();
|
||||||
|
//const router = require("express-promise-router")();
|
||||||
|
const EpisodesController = require("../controllers/episodes");
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/")
|
||||||
|
.get(EpisodesController.index)
|
||||||
|
.post(EpisodesController.newEpisode);
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/:slug")
|
||||||
|
.get(EpisodesController.getEpisode)
|
||||||
|
/* .put(EpisodesController.replaceEpisode)
|
||||||
|
.patch(EpisodesController.updateEpisode) */
|
||||||
|
.delete(EpisodesController.deleteEpisode);
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/:episodeId")
|
||||||
|
.put(EpisodesController.replaceEpisode)
|
||||||
|
.patch(EpisodesController.updateEpisode);
|
||||||
|
|
||||||
|
module.exports = router;
|
|
@ -0,0 +1,35 @@
|
||||||
|
const express = require("express");
|
||||||
|
const router = express.Router();
|
||||||
|
//const router = require("express-promise-router")(); // Elimina la necesidad de usar try catch
|
||||||
|
|
||||||
|
const SeriesController = require("../controllers/series");
|
||||||
|
//const { validateParam, validateBody, schemas } = require('../helpers/routeHelper');
|
||||||
|
|
||||||
|
|
||||||
|
/* router
|
||||||
|
.route("/")
|
||||||
|
.post(SeriesController.newSerie);
|
||||||
|
*/
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/:page")
|
||||||
|
.get(SeriesController.index)
|
||||||
|
.post(SeriesController.newSerie);
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/:page/:slug")
|
||||||
|
.get(SeriesController.getSerie);
|
||||||
|
/*.put(SeriesController.replaceSerie)
|
||||||
|
.patch(SeriesController.updateSerie);
|
||||||
|
.delete(); */
|
||||||
|
router
|
||||||
|
.route("/:serieId")
|
||||||
|
.put(SeriesController.replaceSerie)
|
||||||
|
.patch(SeriesController.updateSerie);
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/:serieId/episodes")
|
||||||
|
.get(SeriesController.getSerieEpisodes)
|
||||||
|
.post(SeriesController.newSerieEpisode);
|
||||||
|
|
||||||
|
module.exports = router;
|
|
@ -0,0 +1,110 @@
|
||||||
|
const express = require("express");
|
||||||
|
const router = express.Router();
|
||||||
|
const Joi = require("joi");
|
||||||
|
const User = require("../models/user.js");
|
||||||
|
const passport = require("passport");
|
||||||
|
|
||||||
|
const userSchema = Joi.object().keys({
|
||||||
|
email: Joi.string()
|
||||||
|
.email()
|
||||||
|
.required(),
|
||||||
|
username: Joi.string()
|
||||||
|
.regex(/^[a-zA-Z0-9]{4,12}$/)
|
||||||
|
.required(),
|
||||||
|
password: Joi.string()
|
||||||
|
.regex(/^[a-zA-Z0-9]{3,30}$/)
|
||||||
|
.required(),
|
||||||
|
confirmPassword: Joi.any()
|
||||||
|
.valid(Joi.ref("password"))
|
||||||
|
.required()
|
||||||
|
});
|
||||||
|
|
||||||
|
const isAuthenticated = (req, res, next) => {
|
||||||
|
if (req.isAuthenticated()) {
|
||||||
|
// GOOD
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
req.flash("error", "Sorry, but you must be registered first!");
|
||||||
|
res.redirect("/");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Revisar esta parte
|
||||||
|
/* const isNotAuthenticated = (req, res, next) => {
|
||||||
|
if (req.isAuthenticated()) {
|
||||||
|
// GOOD
|
||||||
|
return next();
|
||||||
|
req.flash("error", "Sorry, but you are already logged in!");
|
||||||
|
} else {
|
||||||
|
res.redirect("/");
|
||||||
|
}
|
||||||
|
}; */
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/register")
|
||||||
|
.get((req, res) => {
|
||||||
|
res.render("register");
|
||||||
|
})
|
||||||
|
.post(async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const result = Joi.validate(req.body, userSchema);
|
||||||
|
//console.log("result", result);
|
||||||
|
if (result.error) {
|
||||||
|
req.flash("error", "Data is not valid. Please try again.");
|
||||||
|
res.redirect("/users/register");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check email
|
||||||
|
const user = await User.findOne({ email: result.value.email });
|
||||||
|
if (user) {
|
||||||
|
req.flash("error", "Email is already in use.");
|
||||||
|
res.redirect("/users/register");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Hash the password
|
||||||
|
const hash = await User.hashPassword(result.value.password);
|
||||||
|
//console.log('hash', hash);
|
||||||
|
|
||||||
|
// Save to DB
|
||||||
|
delete result.value.confirmPassword;
|
||||||
|
// Override the password with the hash
|
||||||
|
result.value.password = hash;
|
||||||
|
//console.log('new values', result.value);
|
||||||
|
|
||||||
|
const newUser = await new User(result.value);
|
||||||
|
console.log("newUser", newUser);
|
||||||
|
await newUser.save();
|
||||||
|
|
||||||
|
req.flash("success", "You may now login.");
|
||||||
|
res.redirect("/users/login");
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/login")
|
||||||
|
.get((req, res) => {
|
||||||
|
res.render("login");
|
||||||
|
})
|
||||||
|
.post(
|
||||||
|
passport.authenticate("local", {
|
||||||
|
successRedirect: "/users/dashboard",
|
||||||
|
failureRedirect: "/users/login",
|
||||||
|
failureFlash: true
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
router.route("/dashboard").get(isAuthenticated, (req, res) => {
|
||||||
|
res.render("dashboard", {
|
||||||
|
username: req.user.username
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.route("/logout").get(isAuthenticated,(req, res) => {
|
||||||
|
req.logout();
|
||||||
|
req.flash("success", "Successfully logged out, Hope to see you soon!");
|
||||||
|
res.redirect("/");
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
|
@ -0,0 +1,46 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const chalk = require('chalk');
|
||||||
|
const log = console.log;
|
||||||
|
const error = chalk.bold.red;
|
||||||
|
|
||||||
|
//require('dotenv').config({ path: 'variables.env' });
|
||||||
|
mongoose.Promise = global.Promise;
|
||||||
|
// It is necessary to explicitly declare the connection url or it will not work in production
|
||||||
|
|
||||||
|
let mongodbUri = mongoose.connect('mongodb://YOUR MONGODB URL', {
|
||||||
|
poolSize: 5, //Number of connections in the connection pool for each server instance, set to 5 as default for legacy reasons.
|
||||||
|
reconnectTries: 240, //try to connect 60 times every few milliseconds, default 30
|
||||||
|
reconnectInterval: 900, //milliseconds
|
||||||
|
autoReconnect: true,
|
||||||
|
noDelay: true,
|
||||||
|
loggerLevel: "error",//warn, info, debug. Default: "error"
|
||||||
|
//appname: "RedMagic Corp."
|
||||||
|
});
|
||||||
|
|
||||||
|
//mongoose.set('debug', true);
|
||||||
|
|
||||||
|
const db = mongoose.connection;
|
||||||
|
|
||||||
|
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
|
||||||
|
db.once('open', function () { log(chalk.hex('#FFEB3B')("You connected to the database without errors 👠"),chalk.greenBright( "ðŸ˜"))}); // 1 speed
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
|
// application specific logging, throwing an error, or other logic here
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const start = require('./app');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Start the server
|
||||||
|
/* app.set('port', process.env.PORT || 9000);
|
||||||
|
const server = app.listen(app.get('port'), () => log(chalk.underline.hex('#DEADED')('Server is listening music on port:'), chalk.hex('#4CAF50')(`\uD83C\uDF0F http://localhost:${port} 🎶`)));
|
||||||
|
*/
|
||||||
|
|
||||||
|
start.set('port', process.env.PORT || 9000);
|
||||||
|
const server = start.listen(start.get('port'), () => {
|
||||||
|
log(chalk.underline.hex('#DEADED')('Server is listening music on port:'), chalk.hex('#4CAF50')(`\uD83C\uDF0F PORT → ${server.address().port} 🎶`));
|
||||||
|
//console.log(`Express running → PORT ${server.address().port}`);
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
NODE_ENV=development
|
||||||
|
DATABASE=Your Mongodb Url
|
||||||
|
MAIL_USER=Your Mail
|
||||||
|
MAIL_PASS=Your Password
|
||||||
|
MAIL_HOST=Your Mail Host
|
||||||
|
MAIL_PORT=2525
|
||||||
|
PORT=9000
|
||||||
|
SECRET=Your Secret
|
||||||
|
KEY=Your Key
|
|
@ -0,0 +1,77 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="elementoAnime">
|
||||||
|
<h1>View Anime </h1>
|
||||||
|
<h4 class="card-title">
|
||||||
|
<%- serie.title %>
|
||||||
|
<!--<%- serie._id %>-->
|
||||||
|
</h4>
|
||||||
|
<br>
|
||||||
|
<%- serie.synopsis.substring(0,48) %>...
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<h6>Type:</h6>
|
||||||
|
<ul>
|
||||||
|
<%- link_to(serie.type) %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h6>Genre:</h6>
|
||||||
|
<ul>
|
||||||
|
<% for(var i=0; i<serie.tags.length; i++) {%>
|
||||||
|
<li>
|
||||||
|
<%- link_to(serie.tags[i], '/'+serie.tags[i]) %>
|
||||||
|
</li>
|
||||||
|
<% } %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h6>Episode:</h6>
|
||||||
|
<ul>
|
||||||
|
<% for(var i=0; i<serie.episodes.length; i++) {%>
|
||||||
|
<li>
|
||||||
|
<%- link_to(serie.episodes[i].slug, '/'+serie.episodes[i].slug) %>
|
||||||
|
</li>
|
||||||
|
<% } %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<% if(isAuthenticated){ %>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Add episode to this anime</h2>
|
||||||
|
|
||||||
|
<h4>id: <%- serie._id %></h4>
|
||||||
|
<form class="lel" id="lel" action="/" method="POST">
|
||||||
|
<label>Id Anime</label>
|
||||||
|
<input id="anime" name="anime" type="text" placeholder="<%- serie._id %>">
|
||||||
|
<label>Title</label>
|
||||||
|
<input id="title" name="title" type="text" placeholder="title">
|
||||||
|
<label>Server</label>
|
||||||
|
<input id="server" name="server" type="text" placeholder="server">
|
||||||
|
<label>ImageCap</label>
|
||||||
|
<input id="imageCap" name="imageCap" type="text" placeholder="imageCap">
|
||||||
|
|
||||||
|
<button type="submit" class="button-primary" id="btn" style="background-color: white;">Submit</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Update Anime</h2>
|
||||||
|
<form class="lel" id="lel" action="/series/<%= serie._id %>?_method=PATCH" method="POST">
|
||||||
|
<label>Title</label>
|
||||||
|
<input id="title" type="text" name="title" value=" <%= serie.title %>">
|
||||||
|
<label>slug</label>
|
||||||
|
<input id="slug" type="text" name="slug" value=" <%= serie.slug %>">
|
||||||
|
<label>Image URL</label>
|
||||||
|
<input id="cover" type="text" name="cover" value="<%= serie.cover %>">
|
||||||
|
<label>Sinopsis</label>
|
||||||
|
<textarea id="synopsis" name="synopsis"><%= serie.synopsis %> </textarea>
|
||||||
|
|
||||||
|
<button type="submit" class="button-primary" id="btnn" style="background-color: white;">Submit</button>
|
||||||
|
</form>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<% include ./layouts/footer %>
|
||||||
|
</html>
|
|
@ -0,0 +1,66 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
|
||||||
|
<h1 id="dash">Dashboard</h1>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="elementoDash">
|
||||||
|
<form class="lel" id="lel" action="/series/1" method="POST">
|
||||||
|
|
||||||
|
<legend>Add a series</legend>
|
||||||
|
|
||||||
|
<label>Title</label>
|
||||||
|
<input id="title" name="title" type="text" placeholder="title">
|
||||||
|
|
||||||
|
<label>Cover</label>
|
||||||
|
<input id="cover" name="cover" type="text" placeholder="cover">
|
||||||
|
|
||||||
|
<label>Sinopsis</label>
|
||||||
|
<input id="synopsis" name="synopsis" type="text" placeholder="synopsis">
|
||||||
|
|
||||||
|
<select name="estate" id="estate">
|
||||||
|
<option value="Activo">Active</option>
|
||||||
|
<option value="Finalizado">Finalized</option>
|
||||||
|
<option value="Suspendido">Discontinued</option>
|
||||||
|
<option value="Cancelado">Canceled</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select name="type" id="type">
|
||||||
|
<option value="Anime">Anime</option>
|
||||||
|
<option value="OVA">OVA</option>
|
||||||
|
<option value="Pelicula">Movie</option>
|
||||||
|
<option value="Corto">Short</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select multiple="multiple" name="tags" type="text" id="tags" >
|
||||||
|
<option value="Action">Action</option>
|
||||||
|
<option value="Adventure">Adventure</option>
|
||||||
|
<option value="Comedy">Comedy</option>
|
||||||
|
<option value="Drama">Drama</option>
|
||||||
|
<option value="Fantasy">Fantasy</option>
|
||||||
|
<option value="Horror">Horror</option>
|
||||||
|
<option value="Mecha">Mecha</option>
|
||||||
|
<option value="Mystery">Mystery</option>
|
||||||
|
<option value="Romance">Romance</option>
|
||||||
|
<option value="Seinen">Seinen</option>
|
||||||
|
<option value="Slice of Life">Slice of Life</option>
|
||||||
|
<option value="Yuri">Yuri</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
<button type="submit" class="button-primary" id="btn" style="background-color: white;">Submit</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h2>Add new chapter</h2>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$('#lel').on('btn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var cuisines = $('tags').val().join(',');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<% include ./layouts/footer %>
|
||||||
|
</html>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h4>Episodes</h4>
|
||||||
|
|
||||||
|
<%- serie.serieTitle %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
<body>
|
||||||
|
<div class="elemento">
|
||||||
|
<% episode.forEach(function(episode) { %>
|
||||||
|
<div class="caps">
|
||||||
|
<% const episodeUrl = '/episodes/' + episode.slug; %>
|
||||||
|
<div class="l-box">
|
||||||
|
<a href="<%- episode.slug %>"> <img class="image" src="<%- episode.imageCap %> "></a>
|
||||||
|
<h4>
|
||||||
|
<a href="<%- episode.slug %>">
|
||||||
|
<% if(episode.title.length > 28) { %>
|
||||||
|
<%- episode.title.substring(0,28) %>...
|
||||||
|
<% } else { %>
|
||||||
|
<%- episode.title %>
|
||||||
|
<% }; %>
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
<p><small><%= moment(episode.createdAt).fromNow(); %></small></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% }); %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<% include ./layouts/footer %>
|
||||||
|
</html>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<footer>
|
||||||
|
<section class="links">
|
||||||
|
<a href="#">Start</a>
|
||||||
|
<a href="#">Blog</a>
|
||||||
|
<a href="#">Project</a>
|
||||||
|
<a href="#">Contact</a>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="social">
|
||||||
|
<a href="#">Facebook</a>
|
||||||
|
<a href="#">Twitter</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>MPOKNIMU</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link href="/css/app.css" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="contenedor">
|
||||||
|
<header>
|
||||||
|
<div class="logo">
|
||||||
|
<img src="#" width="150" alt="">
|
||||||
|
<a href="/">Home</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
<a href="/series/1">Series</a>
|
||||||
|
<% if(isAuthenticated){ %>
|
||||||
|
<a href="/users/dashboard">Dashboard</a>
|
||||||
|
<a href="/users/logout">Logout</a>
|
||||||
|
<% } else{ %>
|
||||||
|
<a href="/users/login">Login</a>
|
||||||
|
<a href="/users/register">Register</a>
|
||||||
|
<% } %>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<% if (success_messages) { %>
|
||||||
|
<div class="alert alert-success"><%= success_messages %></div>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<% if (error_messages) { %>
|
||||||
|
<div class="alert alert-danger"><%= error_messages %></div>
|
||||||
|
<% } %>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
<div class="elemento">
|
||||||
|
<form class="pure-form pure-form-stacked" action="/users/login" method="POST">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Login</legend>
|
||||||
|
|
||||||
|
<label for="email">Email</label>
|
||||||
|
<input id="inputEmail" name="email" type="email" placeholder="Email">
|
||||||
|
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input id="inputPassword" name="password" type="password" placeholder="Password">
|
||||||
|
|
||||||
|
<button type="submit" class="pure-button pure-button-primary">Sign in</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<% include ./layouts/footer %>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
<div class="elemento">
|
||||||
|
<form class="pure-form pure-form-stacked" action="/users/register" method="POST" onsubmit="if(document.getElementById('agree').checked) { return true; } else { alert('Please indicate that you have read and agree to the Terms and Conditions and Privacy Policy'); return false; }">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Register</legend>
|
||||||
|
|
||||||
|
<label for="email">Email</label>
|
||||||
|
<input id="inputEmail" name="email" type="email" placeholder="Email">
|
||||||
|
|
||||||
|
<label for="inputUsername">Username</label>
|
||||||
|
<input id="inputUsername" name="username" type="text" placeholder="Username">
|
||||||
|
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input id="inputPassword" name="password" type="password" placeholder="Password">
|
||||||
|
|
||||||
|
<label for="inputConfirmPassword">Confirm Password</label>
|
||||||
|
<input id="inputConfirmPassword" name="confirmPassword" type="password" placeholder="Confirm Password">
|
||||||
|
<input type="checkbox" name="checkbox" value="check" id="agree"> I have read and agree to the Terms and Conditions and Privacy Policy</input>
|
||||||
|
|
||||||
|
<button type="submit" class="pure-button pure-button-primary">Sign in</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<% include ./layouts/footer %>
|
|
@ -0,0 +1,51 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
<body>
|
||||||
|
<div class="elemento">
|
||||||
|
<% serie.forEach(function(serie) { %>
|
||||||
|
|
||||||
|
<% const serieUrl = '/series/' + serie.slug; %>
|
||||||
|
<div class="sada1">
|
||||||
|
<a href="anime/<%- serie.slug %>" class="card-link"> <img class="image" id="image-home" src="<%- serie.cover %>" alt="Card image cap"></a>
|
||||||
|
<h4 class="card-title">
|
||||||
|
<%- serie.title.substring(0,18) %>
|
||||||
|
</h4>
|
||||||
|
<p class="card-text">
|
||||||
|
<%- serie.synopsis.substring(0,20) %>...
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<% }); %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pagination">
|
||||||
|
<% if (pages > 0) { %>
|
||||||
|
<ul class="pagination text-center">
|
||||||
|
<% if (current == 1) { %>
|
||||||
|
<a class="disabled"><<</a>
|
||||||
|
<% } else { %>
|
||||||
|
<a href="/series/1"><<</a>
|
||||||
|
<% } %>
|
||||||
|
<% var i = (Number(current) > 5 ? Number(current) - 4 : 1) %>
|
||||||
|
<% if (i !== 1) { %>
|
||||||
|
<a class="disabled">...</a>
|
||||||
|
<% } %>
|
||||||
|
<% for (; i <= (Number(current) + 4) && i <= pages; i++) { %>
|
||||||
|
<% if (i == current) { %>
|
||||||
|
<a class="active"><%= i %></a>
|
||||||
|
<% } else { %>
|
||||||
|
<a href="/series/<%= i %>"><%= i %></a>
|
||||||
|
<% } %>
|
||||||
|
<% if (i == Number(current) + 4 && i < pages) { %>
|
||||||
|
<a class="disabled">...</a>
|
||||||
|
<% } %>
|
||||||
|
<% } %>
|
||||||
|
<% if (current == pages) { %>
|
||||||
|
<a class="disabled">>></a>
|
||||||
|
<% } else { %>
|
||||||
|
<a href="/series/<%= pages %>">>></a>
|
||||||
|
<% } %>
|
||||||
|
</ul>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<% include ./layouts/footer %>
|
||||||
|
</html>
|
|
@ -0,0 +1,58 @@
|
||||||
|
<% include ./layouts/header %>
|
||||||
|
|
||||||
|
<!-- <script type="text/javascript" src="https://content.jwplatform.com/libraries/es3tFzVf.js"></script>
|
||||||
|
<script src="player/jwplayer/jwplayer.js"></script>
|
||||||
|
<script>jwplayer.key="pTXQ0hR1iHUrKsQ//UZzTZRBTAKZzsF0FVIV";</script>-->
|
||||||
|
<script src="https://content.jwplatform.com/libraries/bfIbW5Pe.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="elementoVideo">
|
||||||
|
<div class="container" style="">
|
||||||
|
<div class="row">
|
||||||
|
<h1>
|
||||||
|
<%- episode.serieTitle %> <%- episode.chapter %>
|
||||||
|
</h1>
|
||||||
|
<div class="media80">
|
||||||
|
<div id="myElement"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var playerInstance = jwplayer("myElement");
|
||||||
|
playerInstance.setup({
|
||||||
|
file: "/assets/cap3.mp4",
|
||||||
|
width: "100%",
|
||||||
|
aspectratio: "16:9",
|
||||||
|
playbackRateControls: [0.25, 0.75, 1, 1.25, 2, 3],
|
||||||
|
image: "<%- episode.imageCap %>",
|
||||||
|
preload: "metadata"
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<% if(isAuthenticated){ %>
|
||||||
|
|
||||||
|
<h2>Update Anime</h2>
|
||||||
|
<form class="lel" id="lel" action="/episodes/<%= episode._id %>?_method=PATCH" method="POST">
|
||||||
|
<label>Title</label>
|
||||||
|
<input id="title" type="text" name="title" value=" <%= episode.title %>">
|
||||||
|
<label>slug</label>
|
||||||
|
<input id="slug" type="text" name="slug" value=" <%= episode.slug %>">
|
||||||
|
<label>imageCap</label>
|
||||||
|
<input id="imageCap" type="text" name="imageCap" value="<%= episode.imageCap %>">
|
||||||
|
<label>Server</label>
|
||||||
|
<input id="server" type="text" name="server" value="<%= episode.server %>">
|
||||||
|
|
||||||
|
|
||||||
|
<button type="submit" class="button-primary" id="btnn" style="background-color: white;">Submit</button>
|
||||||
|
</form>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<% include ./layouts/footer %>
|
||||||
|
</html>
|
Loading…
Reference in New Issue