Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
daba2a3
Working on getting video digests running again
aksp Jun 22, 2020
e810f56
use modern fontawesome
aksp Jun 23, 2020
a5c2b5c
work in progress on simplifying code paths in editor controller
aksp Jun 23, 2020
eb5f076
remove old font-awesome link
aksp Jun 23, 2020
3e3580e
we shouldn't need https in express - we'll rely on heroku for that
aksp Jun 23, 2020
1da169e
update published urls
aksp Jun 23, 2020
4d483a2
change signup url
aksp Jun 23, 2020
cd74d19
remove dead icon from home page
aksp Jun 23, 2020
796b1d4
short-circuit much of the video form
aksp Jun 23, 2020
f6bbab1
cleanup urls on home page
aksp Jun 23, 2020
07a3081
Update package.json
aksp Jun 23, 2020
6a83a7e
secrets aren't so secret
aksp Jun 23, 2020
cfa72ac
Update app.js
aksp Jun 23, 2020
e0cccee
remove all third-party signin logic to clean things up
aksp Jun 23, 2020
fdf3311
build process
aksp Jun 23, 2020
1904835
Update secrets.js
aksp Jun 23, 2020
8aac125
serve static images
aksp Jun 23, 2020
455f497
cleanup routes
aksp Jun 23, 2020
baf107f
cleanup
aksp Jun 23, 2020
12db9a4
replace home with "under construction"
aksp Jun 23, 2020
1ee16e9
cleanup
aksp Jun 23, 2020
2319e83
force ssl redirect
aksp Jun 23, 2020
dc29197
Update login.jade
aksp Jun 23, 2020
1ded699
Update editor-controller.js
aksp Jun 23, 2020
b1d9537
Update editor-controller.js
aksp Jun 23, 2020
45ac2b3
list page shows newest 20 public video digests
aksp Jun 29, 2020
645550b
all digests on vdlist page are public, so remove check
aksp Jun 29, 2020
0670036
rename vdigests page to latest
aksp Jun 29, 2020
0708710
prettier
aksp Jun 29, 2020
52e23be
add publish modal w/ publish + unpublish + unlisted
aksp Jun 29, 2020
9564b9e
access controls
aksp Jun 29, 2020
f4a5d36
remove onbeforeunload logic
aksp Jun 29, 2020
b69c8d3
work on caption selection flow
aksp Jul 4, 2020
57d8d45
set a new speaker after each card (hack to split paragraphs)
aksp Jul 4, 2020
cbe855c
reduce paragraph spacing
aksp Jul 4, 2020
85ac894
fix bug where you can't seek to the last word of a paragraph
aksp Jul 4, 2020
a4e322d
properly get auto or manual subs from youtube
aksp Jul 4, 2020
a87e591
cmd/ctrl-S to save
aksp Jul 4, 2020
d26bef5
get a small copy of the video when creating the digest
aksp Jul 4, 2020
6ace8c7
ensure we have small video in order to take screenshots
aksp Jul 4, 2020
08e3780
autosave if necessary every 30 seconds
aksp Jul 4, 2020
2586f1b
Update editor-view.js
aksp Jul 4, 2020
1c82df6
better handling of thumbnails without image data
aksp Jul 4, 2020
75e4639
more thumbnail polish
aksp Jul 4, 2020
0db0faa
more thumbnail polish
aksp Jul 4, 2020
0749b83
don't autosave if we did not decode the digest data
aksp Jul 5, 2020
0253aab
fix build error
aksp Jul 5, 2020
810498c
descript links
aksp Jul 5, 2020
f00b50d
heroku procfile
aksp Jul 5, 2020
fc9f1b1
ignore main-built
aksp Jul 5, 2020
7fdf4c0
fix build
aksp Jul 5, 2020
f919eb5
update connect-assets to support es6+
aksp Jul 5, 2020
8eb0b32
Update app.js
aksp Jul 5, 2020
fb5b8f6
replace "coming soon" with home page
aksp Jul 20, 2020
8dfbed2
stop all players when toggling between preview and editor
aksp Jul 20, 2020
251a1d4
wording on the transcript form
aksp Jul 20, 2020
1cc3825
editing the copy
aksp Jul 20, 2020
338fb0b
switch to sequelize + postgres from mongo/mongoose
aksp Jul 21, 2020
7642642
Update .gitignore
aksp Jul 21, 2020
26abb21
use postgres db on heroku
aksp Jul 21, 2020
c5c0b67
examples coming soon!
aksp Jul 21, 2020
5f6b8a5
example
aksp Jul 21, 2020
1cbeff8
show nav header even if user is logged out
aksp Jul 21, 2020
1110383
Don't render newline after chapter title (before chapter duration)
aksp Aug 17, 2020
988b2d4
Update chapter-view.js
aksp Aug 17, 2020
34cd1ba
Fix issue with parsing shortids (they can contain hyphens)
aksp Aug 17, 2020
a459ca7
Add example to home page
aksp Aug 17, 2020
68a2c33
remove latest videos link
aksp Nov 9, 2020
70c7117
update ytdl-core
aksp Nov 9, 2020
bce4989
fix selector priority issue with adding/removing spinner... not sure …
aksp Nov 9, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
*.avi
*.mp4
*.wav
secrets.js
settings.js
public/content
ffdata
node_modules
builtAssets
vsbenv
public/js/main-built*
public/js/editing-interface/editing-interface/main-built*
*.sqlite

*~
.tern-port
Expand Down
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
public/js/lib/
main-built.js
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"singleQuote": true
}
17 changes: 2 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,12 @@
MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
BASE_DIR := $(realpath $(MAKEFILE_DIR))

# dirs and files ignored by gitignore
configd := $(BASE_DIR)/config
demo_secrets := $(configd)/demo-secrets.js
demo_settings := $(configd)/demo-settings.js
secrets := $(configd)/secrets.js
settings := $(configd)/settings.js

node_modules: |$(secrets) $(settings)
node_modules:
npm install

$(secrets):
cp $(demo_secrets) $(secrets)

$(settings):
cp $(demo_settings) $(settings)

update:
git pull
cd submods/p2fa-vislab; git pull

build_production:
cd public/js; r.js -o build.js
npm run build
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: npm start
303 changes: 177 additions & 126 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@ var logger = require('morgan');
var errorHandler = require('errorhandler');
var csrf = require('lusca').csrf();
var methodOverride = require('method-override');
var sslRedirect = require('heroku-ssl-redirect');
const sequelize = require('./models/sequelize');
// load models
require('./models');

var MongoStore = require('connect-mongo')({ session: session });
sequelize.sync();

var fs = require('fs');
var https = require('https');

const SequelizeStore = require('connect-session-sequelize')(session.Store);
var flash = require('express-flash');
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var expressValidator = require('express-validator');
var connectAssets = require('connect-assets');
Expand All @@ -26,7 +34,6 @@ var connectAssets = require('connect-assets');

var homeController = require('./controllers/home');
var userController = require('./controllers/user');
var apiController = require('./controllers/api');
var contactController = require('./controllers/contact');
var editorController = require('./controllers/editor-controller');
var screenShotController = require('./controllers/screenshot');
Expand All @@ -45,138 +52,182 @@ var passportConf = require('./config/passport');

var app = express();

/**
* Mongoose configuration.
*/

mongoose.connect(secrets.db);
mongoose.connection.on('error', function() {
console.error('✗ MongoDB Connection Error. Please make sure MongoDB is running.');
});

var hour = 3600000;
var day = hour * 24;
var week = day * 7;

/**
* CSRF Whitelist
*/

// TODO fix
var whitelist = ['/newvd'];

/**
* Express configuration.
*/

/**
* CORS
*/
app.all("/*", function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
function initServer() {
var hour = 3600000;
var day = hour * 24;
var week = day * 7;

/**
* CSRF Whitelist
*/

// TODO fix
var whitelist = ['/newvd'];

/**
* Express configuration.
*/

/**
* CORS
*/
app.all('/*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
);
next();
});

app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(sslRedirect());
app.use(
connectAssets({
paths: ['public/css', 'public/js', 'public/img'],
helperContext: app.locals,
servePath: 'vdstatic',
compress: false, // connect-assets doesn't support es6+, I think? we'll compress with terser in the build process
})
);
app.use(compress());
app.use(logger('dev'));
app.use(bodyParser.json({ limit: '100mb' }));
app.use(bodyParser.urlencoded({ limit: '100mb' }));
app.use(expressValidator());
app.use(methodOverride());
app.use(cookieParser());
app.use(passport.initialize());
app.use(passport.session());
app.use(function (req, res, next) {
// AMy change
next();
// if (whitelist.indexOf(req.path) !== -1) next();
// else csrf(req, res, next);
});
app.use(function (req, res, next) {
res.locals.user = req.user;
res.locals.prod = process.env.NODE_ENV === 'production';
next();
});
app.use(flash());

app.use(
'/:extra(videodigests)?',
express.static(path.join(__dirname, 'public'), { maxAge: week })
);
app.use(function (req, res, next) {
// Keep track of previous URL to redirect back to
// original destination after a successful login.
if (req.method !== 'GET') return next();
var path = req.path.split('/')[1];
if (/(auth|login|logout|signup)$/i.test(path)) return next();
req.session.returnTo = req.path;
next();
});

// TODO: make this more informative
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500).send('Sorry, something broke!');
});

/**
* Application routes.
*/
var extraPath = ':extra?/?';
// var extraPath = "";
app.get('/:extra(videodigests)?', homeController.index);
// TODO separate editor from the viewer
app.get('/' + extraPath + 'view/:vdid', editorController.getEditor);
app.get('/' + extraPath + 'view/:vdid/:slug', editorController.getEditor);
app.get('/' + extraPath + 'editor', editorController.getEditor);
app.get('/' + extraPath + 'tutorial', homeController.tutorial);

// TODO make more restful
app.get('/' + extraPath + 'digestdata/:vdid', editorController.getDigestData);
app.post(
'/' + extraPath + 'digestpublish/:vdid',
passportConf.isAuthenticated,
editorController.postPublishDigest
);
app.get('/' + extraPath + 'autoseg/:vdid', editorController.getAutoSeg);

// TODO add Authorization
app.post(
'/' + extraPath + 'digestdata/:vdid',
editorController.postDigestData
);
app.get('/' + extraPath + 'checkstatus', editorController.getStatus);
app.get('/' + extraPath + 'screenshot', screenShotController.getScreenShot);
app.post('/' + extraPath + 'newvd', editorController.postNewVD);
// Disable "latest" page for now
// app.get('/' + extraPath + 'latest', vdlistController.getVDList);
app.get('/' + extraPath + 'login', userController.getLogin);
app.post('/' + extraPath + 'login', userController.postLogin);
app.get('/' + extraPath + 'logout', userController.logout);
app.get('/' + extraPath + 'forgot', userController.getForgot);
app.post('/' + extraPath + 'forgot', userController.postForgot);
app.get('/' + extraPath + 'reset/:token', userController.getReset);
app.post('/' + extraPath + 'reset/:token', userController.postReset);
app.get('/' + extraPath + 'signup', userController.getSignup);
app.post('/' + extraPath + 'signup', userController.postSignup);
app.get('/' + extraPath + 'contact', contactController.getContact);
app.post('/' + extraPath + 'contact', contactController.postContact);
app.get(
'/' + extraPath + 'account',
passportConf.isAuthenticated,
userController.getAccount
);
app.post(
'/' + extraPath + 'account/profile',
passportConf.isAuthenticated,
userController.postUpdateProfile
);
app.post(
'/' + extraPath + 'account/password',
passportConf.isAuthenticated,
userController.postUpdatePassword
);
app.post(
'/' + extraPath + 'account/delete',
passportConf.isAuthenticated,
userController.postDeleteAccount
);

app.use(errorHandler());
}

const sessionStore = new SequelizeStore({
db: sequelize,
});


app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(connectAssets({
paths: ['public/css', 'public/js'],
helperContext: app.locals,
servePath: 'vdstatic'
}));
app.use(compress());
app.use(logger('dev'));
app.use(bodyParser.json({limit: "100mb"}));
app.use(bodyParser.urlencoded({limit: "100mb"}));
app.use(expressValidator());
app.use(methodOverride());
app.use(cookieParser());
app.use(session({
secret: secrets.sessionSecret,
store: new MongoStore({
url: secrets.db,
auto_reconnect: true
app.use(
session({
secret: secrets.sessionSecret,
store: sessionStore,
resave: false,
proxy: true,
})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
if (whitelist.indexOf(req.path) !== -1) next();
else csrf(req, res, next);
});
app.use(function(req, res, next) {
res.locals.user = req.user;
res.locals.prod = app.get('env') == 'production';
next();
});
app.use(flash());

app.use('/:extra(videodigests)?', express.static(path.join(__dirname, 'public'), { maxAge: week }));
app.use(function(req, res, next) {
// Keep track of previous URL to redirect back to
// original destination after a successful login.
if (req.method !== 'GET') return next();
var path = req.path.split('/')[1];
if (/(auth|login|logout|signup)$/i.test(path)) return next();
req.session.returnTo = req.path;
next();
});

// TODO: make this more informative
app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Sorry, something broke!');
});
);

/**
* Application routes.
*/
var extraPath = ":extra?/?";
app.get('/:extra(videodigests)?', homeController.index);
// TODO separate editor from the viewer
app.get('/' + extraPath + 'view/:ptitle', editorController.getEditor);
app.get('/' + extraPath + 'editor', editorController.getEditor);
app.get('/' + extraPath + 'tutorial', homeController.tutorial);

// TODO make more restful
app.get('/' + extraPath + 'digestdata/:vdid', editorController.getDigestData);
app.post('/' + extraPath + 'digestpublish/:vdid', passportConf.isAuthenticated, editorController.postPublishDigest);
app.get('/' + extraPath + 'autoseg/:vdid', editorController.getAutoSeg);

// TODO add Authorization
app.post('/' + extraPath + 'digestdata/:vdid', editorController.postDigestData);
app.get('/' + extraPath + 'checkstatus', editorController.getStatus);
app.get('/' + extraPath + 'screenshot', screenShotController.getScreenShot);
app.post('/' + extraPath + 'newvd', editorController.postNewVD);
app.get('/' + extraPath + 'vdigests', vdlistController.getVDList);
app.get('/' + extraPath + 'login', userController.getLogin);
app.post('/' + extraPath + 'login', userController.postLogin);
app.get('/' + extraPath + 'logout', userController.logout);
app.get('/' + extraPath + 'forgot', userController.getForgot);
app.post('/' + extraPath + 'forgot', userController.postForgot);
app.get('/' + extraPath + 'reset/:token', userController.getReset);
app.post('/' + extraPath + 'reset/:token', userController.postReset);
app.get('/' + extraPath + 'signup', userController.getSignup);
app.post('/' + extraPath + 'signup', userController.postSignup);
app.get('/' + extraPath + 'contact', contactController.getContact);
app.post('/' + extraPath + 'contact', contactController.postContact);
app.get('/' + extraPath + 'account', passportConf.isAuthenticated, userController.getAccount);
app.post('/' + extraPath + 'account/profile', passportConf.isAuthenticated, userController.postUpdateProfile);
app.post('/' + extraPath + 'account/password', passportConf.isAuthenticated, userController.postUpdatePassword);
app.post('/' + extraPath + 'account/delete', passportConf.isAuthenticated, userController.postDeleteAccount);
app.get('/' + extraPath + 'account/unlink/:provider', passportConf.isAuthenticated, userController.getOauthUnlink);

app.use(errorHandler());
sessionStore.sync();
sequelize.sync();

/**
* Start Express server.
*/

app.listen(app.get('port'), function() {
console.log(" ✔ Express server listening on port %d in %s mode", app.get('port'), app.get('env'));
initServer();

app.listen(app.get('port'), function () {
console.log(
' ✔ Express server listening on port %d in %s mode',
app.get('port'),
app.get('env')
);
});

module.exports = app;
Loading