From 3fa69fd75e69e446663ad35eec42596e5ae917f5 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Mon, 10 Jul 2017 17:51:29 -0700 Subject: [PATCH 1/9] reworked stats db and added trending route --- controllers/serveController.js | 2 + controllers/statsController.js | 82 ++++++++++++++++++++++++++++-- helpers/libraries/errorHandlers.js | 8 +-- models/stats.js | 10 ++++ routes/api-routes.js | 12 ++--- routes/home-routes.js | 2 +- routes/serve-routes.js | 12 ++--- routes/show-routes.js | 42 ++++++++++----- routes/sockets-routes.js | 8 +-- views/trending.handlebars | 26 ++++++++++ 10 files changed, 165 insertions(+), 39 deletions(-) create mode 100644 views/trending.handlebars diff --git a/controllers/serveController.js b/controllers/serveController.js index b3dfb700..845dfb57 100644 --- a/controllers/serveController.js +++ b/controllers/serveController.js @@ -98,6 +98,8 @@ function getClaimAndHandleResponse (uri, address, height, resolve, reject) { }); // resolve the request resolve({ + name, + claimId : claim_id, fileName: file_name, filePath: download_path, fileType: mime_type, diff --git a/controllers/statsController.js b/controllers/statsController.js index 327636da..dee75b72 100644 --- a/controllers/statsController.js +++ b/controllers/statsController.js @@ -5,7 +5,7 @@ const db = require('../models'); const googleApiKey = config.get('AnalyticsConfig.GoogleId'); module.exports = { - postToStats (action, url, ipAddress, result) { + postToStats (action, url, ipAddress, name, claimId, result) { logger.silly(`creating ${action} record for statistics db`); // make sure the result is a string if (result && (typeof result !== 'string')) { @@ -20,6 +20,8 @@ module.exports = { action, url, ipAddress, + name, + claimId, result, }) .then() @@ -58,12 +60,18 @@ module.exports = { } }); }, - getStatsSummary () { - logger.debug('retrieving site statistics'); + getStatsSummary (startDate) { + logger.debug('retrieving statistics'); const deferred = new Promise((resolve, reject) => { // get the raw statistics data db.Stats - .findAll() + .findAll({ + where: { + createdAt: { + gt: startDate, + }, + }, + }) .then(data => { const resultHashTable = {}; let totalServe = 0; @@ -125,4 +133,70 @@ module.exports = { }); return deferred; }, + getTrendingClaims (startDate) { + logger.debug('retrieving trending statistics'); + const deferred = new Promise((resolve, reject) => { + // get the raw statistics data + db.Stats + .findAll({ + where: { + createdAt: { + gt: startDate, + }, + name: { + not: null, + }, + claimId: { + not: null, + }, + }, + }) + .then(data => { + const resultHashTable = {}; + // summarise the data + for (let i = 0; i < data.length; i++) { + let key = `${data[i].name}#${data[i].claimId}`; + logger.debug(key); + console.log(resultHashTable[key]); + if (resultHashTable[key] === undefined) { + // console.log(resultHashTable[key]); + resultHashTable[key] = { + count : 0, + details: { + name : data[i].name, + claimId: data[i].claimId, + }, + }; + } else { + // console.log(resultHashTable[key]); + resultHashTable[key]['count'] += 1; + } + } + // order the results + let sortableArray = []; + for (let objKey in resultHashTable) { + if (resultHashTable.hasOwnProperty(objKey)) { + sortableArray.push([ + resultHashTable[objKey]['count'], + resultHashTable[objKey]['details'], + ]); + } + } + sortableArray.sort((a, b) => { + return a[0] - b[0]; + }); + const sortedArray = sortableArray.map((a) => { + return a[1]; + }); + // return results + logger.debug(sortedArray); + resolve(sortedArray); + }) + .catch(error => { + logger.error('sequelize error', error); + reject(error); + }); + }); + return deferred; + }, }; diff --git a/helpers/libraries/errorHandlers.js b/helpers/libraries/errorHandlers.js index b7ea5a37..188a6757 100644 --- a/helpers/libraries/errorHandlers.js +++ b/helpers/libraries/errorHandlers.js @@ -5,16 +5,16 @@ module.exports = { handleRequestError (action, originalUrl, ip, error, res) { logger.error('Request Error >>', error); if (error.response) { - postToStats(action, originalUrl, ip, error.response.data.error.messsage); + postToStats(action, originalUrl, ip, null, null, error.response.data.error.messsage); res.status(error.response.status).send(error.response.data.error.message); } else if (error.code === 'ECONNREFUSED') { - postToStats(action, originalUrl, ip, 'Connection refused. The daemon may not be running.'); + postToStats(action, originalUrl, ip, null, null, 'Connection refused. The daemon may not be running.'); res.status(503).send('Connection refused. The daemon may not be running.'); } else if (error.message) { - postToStats(action, originalUrl, ip, error); + postToStats(action, originalUrl, ip, null, null, error); res.status(400).send(error.message); } else { - postToStats(action, originalUrl, ip, error); + postToStats(action, originalUrl, ip, null, null, error); res.status(400).send(error); } }, diff --git a/models/stats.js b/models/stats.js index 931623fe..00fef482 100644 --- a/models/stats.js +++ b/models/stats.js @@ -15,6 +15,16 @@ module.exports = (sequelize, { STRING, TEXT }) => { allowNull: true, default : null, }, + name: { + type : STRING, + allowNull: true, + default : null, + }, + claimId: { + type : STRING, + allowNull: true, + default : null, + }, result: { type : TEXT('long'), allowNull: true, diff --git a/routes/api-routes.js b/routes/api-routes.js index 67c82d95..5f8327de 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -11,8 +11,8 @@ const config = require('config'); const hostedContentPath = config.get('Database.PublishUploadPath'); module.exports = app => { - // route to run a claim_list request on the daemon - app.get('/api/streamFile/:name', ({ params, headers }, res) => { + // route to return a file directly + app.get('/api/streamFile/:name', ({ params }, res) => { const filePath = `${hostedContentPath}${params.name}`; res.status(200).sendFile(filePath); }); @@ -24,7 +24,7 @@ module.exports = app => { lbryApi .getClaimsList(params.name) .then(claimsList => { - postToStats('serve', originalUrl, ip, 'success'); + postToStats('serve', originalUrl, ip, null, null, 'success'); res.status(200).json(claimsList); }) .catch(error => { @@ -56,7 +56,7 @@ module.exports = app => { lbryApi .resolveUri(params.uri) .then(resolvedUri => { - postToStats('serve', originalUrl, ip, 'success'); + postToStats('serve', originalUrl, ip, null, null, 'success'); res.status(200).json(resolvedUri); }) .catch(error => { @@ -76,7 +76,7 @@ module.exports = app => { try { validateFile(file, name, license, nsfw); } catch (error) { - postToStats('publish', originalUrl, ip, error.message); + postToStats('publish', originalUrl, ip, null, null, error.message); logger.debug('rejected >>', error.message); res.status(400).send(error.message); return; @@ -91,7 +91,7 @@ module.exports = app => { publishController .publish(publishParams, fileName, fileType) .then(result => { - postToStats('publish', originalUrl, ip, 'success'); + postToStats('publish', originalUrl, ip, null, null, 'success'); res.status(200).json(result); }) .catch(error => { diff --git a/routes/home-routes.js b/routes/home-routes.js index 81fd3219..d4d51127 100644 --- a/routes/home-routes.js +++ b/routes/home-routes.js @@ -11,7 +11,7 @@ module.exports = app => { app.use('*', ({ originalUrl, ip }, res) => { logger.error(`404 on ${originalUrl}`); // post to stats - postToStats('show', originalUrl, ip, 'Error: 404'); + postToStats('show', originalUrl, ip, null, null, 'Error: 404'); // send response res.status(404).render('fourOhFour'); }); diff --git a/routes/serve-routes.js b/routes/serve-routes.js index 8df97494..4a6bf307 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -52,14 +52,14 @@ module.exports = (app) => { if (headers['accept']) { // note: added b/c some requests errored out due to no accept param in header const mimetypes = headers['accept'].split(','); if (mimetypes.includes('text/html')) { - postToStats('show', originalUrl, ip, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); res.status(200).render('showLite', { fileInfo }); } else { - postToStats('serve', originalUrl, ip, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); serveFile(fileInfo, res); } } else { - postToStats('serve', originalUrl, ip, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); serveFile(fileInfo, res); } }) @@ -82,14 +82,14 @@ module.exports = (app) => { if (headers['accept']) { // note: added b/c some requests errored out due to no accept param in header const mimetypes = headers['accept'].split(','); if (mimetypes.includes('text/html')) { - postToStats('show', originalUrl, ip, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); res.status(200).render('showLite', { fileInfo }); } else { - postToStats('serve', originalUrl, ip, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); serveFile(fileInfo, res); } } else { - postToStats('serve', originalUrl, ip, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); serveFile(fileInfo, res); } }) diff --git a/routes/show-routes.js b/routes/show-routes.js index d662d6c9..763822b2 100644 --- a/routes/show-routes.js +++ b/routes/show-routes.js @@ -1,6 +1,6 @@ const errorHandlers = require('../helpers/libraries/errorHandlers.js'); const { getClaimByClaimId, getClaimByName, getAllClaims } = require('../controllers/serveController.js'); -const { getStatsSummary, postToStats } = require('../controllers/statsController.js'); +const { postToStats, getStatsSummary, getTrendingClaims } = require('../controllers/statsController.js'); module.exports = (app) => { // route to show 'about' page for spee.ch @@ -8,30 +8,44 @@ module.exports = (app) => { // get and render the content res.status(200).render('about'); }); - // route to show the meme-fodder meme maker - app.get('/meme-fodder/play', ({ ip, originalUrl }, res) => { - // get and render the content - getAllClaims('meme-fodder') - .then(orderedFreePublicClaims => { - postToStats('show', originalUrl, ip, 'success'); - res.status(200).render('memeFodder', { claims: orderedFreePublicClaims }); + // route to display a list of the trending images + app.get('/trending', ({ params, headers }, res) => { + const startDate = new Date(); + startDate.setDate(startDate.getDate() - 1); + getTrendingClaims(startDate) + .then(result => { + res.status(200).render('trending', { trendingAssets: result }); }) .catch(error => { - errorHandlers.handleRequestError('show', originalUrl, ip, error, res); + errorHandlers.handleRequestError(error, res); }); }); // route to show statistics for spee.ch app.get('/stats', ({ ip, originalUrl }, res) => { // get and render the content - getStatsSummary() + const startDate = new Date(); + startDate.setDate(startDate.getDate() - 1); + getStatsSummary(startDate) .then(result => { - postToStats('show', originalUrl, ip, 'success'); + postToStats('show', originalUrl, ip, null, null, 'success'); res.status(200).render('statistics', result); }) .catch(error => { errorHandlers.handleRequestError(error, res); }); }); + // route to show the meme-fodder meme maker + app.get('/meme-fodder/play', ({ ip, originalUrl }, res) => { + // get and render the content + getAllClaims('meme-fodder') + .then(orderedFreePublicClaims => { + postToStats('show', originalUrl, ip, null, null, 'success'); + res.status(200).render('memeFodder', { claims: orderedFreePublicClaims }); + }) + .catch(error => { + errorHandlers.handleRequestError('show', originalUrl, ip, error, res); + }); + }); // route to display all free public claims at a given name app.get('/:name/all', ({ ip, originalUrl, params }, res) => { // get and render the content @@ -41,7 +55,7 @@ module.exports = (app) => { res.status(307).render('noClaims'); return; } - postToStats('show', originalUrl, ip, 'success'); + postToStats('show', originalUrl, ip, null, null, 'success'); res.status(200).render('allClaims', { claims: orderedFreePublicClaims }); }) .catch(error => { @@ -59,7 +73,7 @@ module.exports = (app) => { return; } // serve the file or the show route - postToStats('show', originalUrl, ip, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); res.status(200).render('show', { fileInfo }); }) .catch(error => { @@ -77,7 +91,7 @@ module.exports = (app) => { return; } // serve the show route - postToStats('show', originalUrl, ip, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); res.status(200).render('show', { fileInfo }); }) .catch(error => { diff --git a/routes/sockets-routes.js b/routes/sockets-routes.js index 0a17e56f..bb3d23b3 100644 --- a/routes/sockets-routes.js +++ b/routes/sockets-routes.js @@ -27,7 +27,7 @@ module.exports = (app, siofu, hostedContentPath) => { // listener for when file upload encounters an error uploader.on('error', ({ error }) => { logger.error('an error occured while uploading', error); - postToStats('publish', '/', null, error); + postToStats('publish', '/', null, null, error); socket.emit('publish-status', error); }); // listener for when file has been uploaded @@ -41,18 +41,18 @@ module.exports = (app, siofu, hostedContentPath) => { publishController .publish(publishParams, file.name, file.meta.type) .then(result => { - postToStats('publish', '/', null, 'success'); + postToStats('publish', '/', null, null, 'success'); socket.emit('publish-complete', { name: publishParams.name, result }); }) .catch(error => { error = errorHandlers.handlePublishError(error); - postToStats('publish', '/', null, error); + postToStats('publish', '/', null, null, error); socket.emit('publish-failure', error); }); } else { logger.error(`An error occurred in uploading the client's file`); socket.emit('publish-failure', 'File uploaded, but with errors'); - postToStats('publish', '/', null, 'File uploaded, but with errors'); + postToStats('publish', '/', null, null, 'File uploaded, but with errors'); // to-do: remove the file if not done automatically } }); diff --git a/views/trending.handlebars b/views/trending.handlebars new file mode 100644 index 00000000..4fb91ac7 --- /dev/null +++ b/views/trending.handlebars @@ -0,0 +1,26 @@ +
+ {{> topBar}} +
+

Trending Images

+ {{#each trendingAssets}} + + + {{/each}} +
+
+ + + + + + From f8ad476488c73337e190336a0e7f91043765e89f Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 11 Jul 2017 16:55:03 -0700 Subject: [PATCH 2/9] formatted trending images and added homepage section --- config/default.json | 3 +- config/development.json | 5 +- config/loggerSetup.js | 18 +----- config/production.json | 3 +- config/test.json | 3 +- controllers/statsController.js | 32 +++++----- helpers/libraries/errorHandlers.js | 8 +-- models/stats.js | 17 +++-- public/assets/css/componentStyle.css | 62 +++++++++---------- .../css/{allStyle.css => generalStyle.css} | 7 +++ routes/api-routes.js | 8 +-- routes/home-routes.js | 16 +++-- routes/serve-routes.js | 12 ++-- routes/show-routes.js | 10 +-- routes/sockets-routes.js | 8 +-- server.js | 17 ++--- views/index.handlebars | 3 + views/layouts/main.handlebars | 3 +- views/memeFodder.handlebars | 1 + views/partials/asset.handlebars | 2 +- views/partials/memeFodderResults.handlebars | 2 +- views/partials/trending.handlebars | 19 ++++++ views/showLite.handlebars | 2 +- views/trending.handlebars | 13 +--- 24 files changed, 148 insertions(+), 126 deletions(-) rename public/assets/css/{allStyle.css => generalStyle.css} (96%) create mode 100644 views/partials/trending.handlebars diff --git a/config/default.json b/config/default.json index a50953a0..2a048516 100644 --- a/config/default.json +++ b/config/default.json @@ -12,7 +12,6 @@ "PublishUploadPath": "none" }, "Logging": { - "LogLevel": "none", - "LogDirectory": "none" + "LogLevel": "none" } } \ No newline at end of file diff --git a/config/development.json b/config/development.json index 9b0e04cf..2c132e88 100644 --- a/config/development.json +++ b/config/development.json @@ -9,10 +9,9 @@ }, "Database": { "MySqlConnectionUri": "none", - "PublishUploadPath": "C:\\lbry\\speech\\hosted_content\\" + "PublishUploadPath": "C:\\Users\\Bones\\Downloads\\lbry\\" }, "Logging": { - "LogLevel": "silly", - "LogDirectory": "C:\\lbry\\speech\\logs\\" + "LogLevel": "silly" } } \ No newline at end of file diff --git a/config/loggerSetup.js b/config/loggerSetup.js index 7a0b2e41..ffd4c970 100644 --- a/config/loggerSetup.js +++ b/config/loggerSetup.js @@ -1,10 +1,4 @@ -const fs = require('fs'); - -module.exports = (winston, logLevel, logDir) => { - if (!fs.existsSync(logDir)) { - fs.mkdirSync(logDir); - } - +module.exports = (winston, logLevel) => { winston.configure({ transports: [ new (winston.transports.Console)({ @@ -15,16 +9,6 @@ module.exports = (winston, logLevel, logDir) => { handleExceptions : true, humanReadableUnhandledException: true, }), - new (winston.transports.File)({ - filename : `${logDir}/speechLogs.log`, - level : logLevel, - json : false, - timestamp : true, - colorize : true, - prettyPrint : true, - handleExceptions : true, - humanReadableUnhandledException: true, - }), ], }); diff --git a/config/production.json b/config/production.json index 848f1700..27d3fc04 100644 --- a/config/production.json +++ b/config/production.json @@ -12,7 +12,6 @@ "PublishUploadPath": "/home/lbry/Downloads/" }, "Logging": { - "LogLevel": "verbose", - "LogDirectory": "/home/lbry/Logs" + "LogLevel": "verbose" } } diff --git a/config/test.json b/config/test.json index bab71bfa..80a771a7 100644 --- a/config/test.json +++ b/config/test.json @@ -12,7 +12,6 @@ "PublishUploadPath": "/home/ubuntu/Downloads/" }, "Logging": { - "LogLevel": "debug", - "LogDirectory": "/home/ubuntu/Logs" + "LogLevel": "debug" } } diff --git a/controllers/statsController.js b/controllers/statsController.js index dee75b72..1242a86a 100644 --- a/controllers/statsController.js +++ b/controllers/statsController.js @@ -5,7 +5,7 @@ const db = require('../models'); const googleApiKey = config.get('AnalyticsConfig.GoogleId'); module.exports = { - postToStats (action, url, ipAddress, name, claimId, result) { + postToStats (action, url, ipAddress, name, claimId, fileName, fileType, nsfw, result) { logger.silly(`creating ${action} record for statistics db`); // make sure the result is a string if (result && (typeof result !== 'string')) { @@ -22,6 +22,9 @@ module.exports = { ipAddress, name, claimId, + fileName, + fileType, + nsfw, result, }) .then() @@ -73,13 +76,14 @@ module.exports = { }, }) .then(data => { - const resultHashTable = {}; + let resultHashTable = {}; let totalServe = 0; let totalPublish = 0; let totalShow = 0; let totalCount = 0; let totalSuccess = 0; let totalFailure = 0; + let percentSuccess; // sumarise the data for (let i = 0; i < data.length; i++) { let key = data[i].action + data[i].url; @@ -122,7 +126,7 @@ module.exports = { } } } - const percentSuccess = Math.round(totalSuccess / totalCount * 100); + percentSuccess = Math.round(totalSuccess / totalCount * 100); // return results resolve({ records: resultHashTable, totals: { totalServe, totalPublish, totalShow, totalCount, totalSuccess, totalFailure }, percentSuccess }); }) @@ -152,28 +156,27 @@ module.exports = { }, }) .then(data => { - const resultHashTable = {}; + let resultHashTable = {}; + let sortableArray = []; + let sortedArray; // summarise the data for (let i = 0; i < data.length; i++) { let key = `${data[i].name}#${data[i].claimId}`; - logger.debug(key); - console.log(resultHashTable[key]); if (resultHashTable[key] === undefined) { - // console.log(resultHashTable[key]); resultHashTable[key] = { count : 0, details: { - name : data[i].name, - claimId: data[i].claimId, + name : data[i].name, + claimId : data[i].claimId, + fileName: data[i].fileName, + fileType: data[i].fileType, + nsfw : data[i].nsfw, }, }; } else { - // console.log(resultHashTable[key]); resultHashTable[key]['count'] += 1; } } - // order the results - let sortableArray = []; for (let objKey in resultHashTable) { if (resultHashTable.hasOwnProperty(objKey)) { sortableArray.push([ @@ -183,13 +186,12 @@ module.exports = { } } sortableArray.sort((a, b) => { - return a[0] - b[0]; + return b[0] - a[0]; }); - const sortedArray = sortableArray.map((a) => { + sortedArray = sortableArray.map((a) => { return a[1]; }); // return results - logger.debug(sortedArray); resolve(sortedArray); }) .catch(error => { diff --git a/helpers/libraries/errorHandlers.js b/helpers/libraries/errorHandlers.js index 188a6757..a256b048 100644 --- a/helpers/libraries/errorHandlers.js +++ b/helpers/libraries/errorHandlers.js @@ -5,16 +5,16 @@ module.exports = { handleRequestError (action, originalUrl, ip, error, res) { logger.error('Request Error >>', error); if (error.response) { - postToStats(action, originalUrl, ip, null, null, error.response.data.error.messsage); + postToStats(action, originalUrl, ip, null, null, null, null, null, error.response.data.error.messsage); res.status(error.response.status).send(error.response.data.error.message); } else if (error.code === 'ECONNREFUSED') { - postToStats(action, originalUrl, ip, null, null, 'Connection refused. The daemon may not be running.'); + postToStats(action, originalUrl, ip, null, null, null, null, null, 'Connection refused. The daemon may not be running.'); res.status(503).send('Connection refused. The daemon may not be running.'); } else if (error.message) { - postToStats(action, originalUrl, ip, null, null, error); + postToStats(action, originalUrl, ip, null, null, null, null, null, error); res.status(400).send(error.message); } else { - postToStats(action, originalUrl, ip, null, null, error); + postToStats(action, originalUrl, ip, null, null, null, null, null, error); res.status(400).send(error); } }, diff --git a/models/stats.js b/models/stats.js index 00fef482..a18ee472 100644 --- a/models/stats.js +++ b/models/stats.js @@ -1,4 +1,4 @@ -module.exports = (sequelize, { STRING, TEXT }) => { +module.exports = (sequelize, { STRING, BOOLEAN, TEXT }) => { const Stats = sequelize.define( 'Stats', { @@ -13,17 +13,26 @@ module.exports = (sequelize, { STRING, TEXT }) => { ipAddress: { type : STRING, allowNull: true, - default : null, }, name: { type : STRING, allowNull: true, - default : null, }, claimId: { type : STRING, allowNull: true, - default : null, + }, + fileName: { + type : STRING, + allowNull: true, + }, + fileType: { + type : STRING, + allowNull: true, + }, + nsfw: { + type : BOOLEAN, + allowNull: true, }, result: { type : TEXT('long'), diff --git a/public/assets/css/componentStyle.css b/public/assets/css/componentStyle.css index a837dabd..a7735c32 100644 --- a/public/assets/css/componentStyle.css +++ b/public/assets/css/componentStyle.css @@ -12,6 +12,29 @@ margin: 2px 5px 2px 5px; } +/* publish */ +#drop-zone { + border: 1px dashed lightgrey; + padding: 1em; + height: 6em; +} + +#asset-preview-holder { + width: 100%; + margin-bottom: 1em; +} + +.snapshot-generator { + display: block; + height: 1px; + left: 0; + object-fit: contain; + position: fixed; + top: 0; + width: 1px; + z-index: -1; +} + /* show routes */ .show-asset { width: 100%; @@ -53,7 +76,14 @@ button.copy-button { vertical-align: top; } -/* learn more */ +/* trending claims */ +.asset-trending { + width: 21%; + margin: 2%; + float: left; +} + +/* learn more */ .learn-more { text-align: center; margin-top: 2px; @@ -115,29 +145,6 @@ button.copy-button { list-style-type: none; } -/* publish */ -#drop-zone { - border: 1px dashed lightgrey; - padding: 1em; - height: 6em; -} - -#asset-preview-holder { - width: 100%; - margin-bottom: 1em; -} - -.snapshot-generator { - display: block; - height: 1px; - left: 0; - object-fit: contain; - position: fixed; - top: 0; - width: 1px; - z-index: -1; -} - /* meme */ canvas { background-color: white; @@ -145,13 +152,6 @@ canvas { height: auto; } -.meme-fodder-img { - width: 21%; - padding: 0px; - margin: 2% 4% 2% 0px; - float: left; -} - /* statistics */ .totals-row { border-top: 1px solid grey; diff --git a/public/assets/css/allStyle.css b/public/assets/css/generalStyle.css similarity index 96% rename from public/assets/css/allStyle.css rename to public/assets/css/generalStyle.css index ee0991fa..668ba44c 100644 --- a/public/assets/css/allStyle.css +++ b/public/assets/css/generalStyle.css @@ -91,6 +91,13 @@ h4 { /* other */ +.asset-small { + height: 200px; + padding: 0px; + margin: 10px; + float: left; +} + input { padding: 0.3em; } diff --git a/routes/api-routes.js b/routes/api-routes.js index 5f8327de..75442175 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -24,7 +24,7 @@ module.exports = app => { lbryApi .getClaimsList(params.name) .then(claimsList => { - postToStats('serve', originalUrl, ip, null, null, 'success'); + postToStats('serve', originalUrl, ip, null, null, null, null, 'success'); res.status(200).json(claimsList); }) .catch(error => { @@ -56,7 +56,7 @@ module.exports = app => { lbryApi .resolveUri(params.uri) .then(resolvedUri => { - postToStats('serve', originalUrl, ip, null, null, 'success'); + postToStats('serve', originalUrl, ip, null, null, null, null, 'success'); res.status(200).json(resolvedUri); }) .catch(error => { @@ -76,7 +76,7 @@ module.exports = app => { try { validateFile(file, name, license, nsfw); } catch (error) { - postToStats('publish', originalUrl, ip, null, null, error.message); + postToStats('publish', originalUrl, ip, null, null, null, null, error.message); logger.debug('rejected >>', error.message); res.status(400).send(error.message); return; @@ -91,7 +91,7 @@ module.exports = app => { publishController .publish(publishParams, fileName, fileType) .then(result => { - postToStats('publish', originalUrl, ip, null, null, 'success'); + postToStats('publish', originalUrl, ip, null, null, null, null, 'success'); res.status(200).json(result); }) .catch(error => { diff --git a/routes/home-routes.js b/routes/home-routes.js index d4d51127..d3632aa0 100644 --- a/routes/home-routes.js +++ b/routes/home-routes.js @@ -1,17 +1,25 @@ const logger = require('winston'); -const { postToStats } = require('../controllers/statsController.js'); +const { postToStats, getTrendingClaims } = require('../controllers/statsController.js'); +const errorHandlers = require('../helpers/libraries/errorHandlers.js'); module.exports = app => { // route for the home page app.get('/', ({ headers, ip, originalUrl }, res) => { - // send response - res.status(200).render('index'); + const startDate = new Date(); + startDate.setDate(startDate.getDate() - 1); + getTrendingClaims(startDate) + .then(result => { + res.status(200).render('index', { trendingAssets: result }); + }) + .catch(error => { + errorHandlers.handleRequestError(error, res); + }); }); // a catch-all route if someone visits a page that does not exist app.use('*', ({ originalUrl, ip }, res) => { logger.error(`404 on ${originalUrl}`); // post to stats - postToStats('show', originalUrl, ip, null, null, 'Error: 404'); + postToStats('show', originalUrl, ip, null, null, null, null, null, 'Error: 404'); // send response res.status(404).render('fourOhFour'); }); diff --git a/routes/serve-routes.js b/routes/serve-routes.js index 4a6bf307..d8608d61 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -52,14 +52,14 @@ module.exports = (app) => { if (headers['accept']) { // note: added b/c some requests errored out due to no accept param in header const mimetypes = headers['accept'].split(','); if (mimetypes.includes('text/html')) { - postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); res.status(200).render('showLite', { fileInfo }); } else { - postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); serveFile(fileInfo, res); } } else { - postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); serveFile(fileInfo, res); } }) @@ -82,14 +82,14 @@ module.exports = (app) => { if (headers['accept']) { // note: added b/c some requests errored out due to no accept param in header const mimetypes = headers['accept'].split(','); if (mimetypes.includes('text/html')) { - postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); res.status(200).render('showLite', { fileInfo }); } else { - postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); serveFile(fileInfo, res); } } else { - postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('serve', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); serveFile(fileInfo, res); } }) diff --git a/routes/show-routes.js b/routes/show-routes.js index 763822b2..8f69270a 100644 --- a/routes/show-routes.js +++ b/routes/show-routes.js @@ -27,7 +27,7 @@ module.exports = (app) => { startDate.setDate(startDate.getDate() - 1); getStatsSummary(startDate) .then(result => { - postToStats('show', originalUrl, ip, null, null, 'success'); + postToStats('show', originalUrl, ip, null, null, null, null, null, 'success'); res.status(200).render('statistics', result); }) .catch(error => { @@ -39,7 +39,7 @@ module.exports = (app) => { // get and render the content getAllClaims('meme-fodder') .then(orderedFreePublicClaims => { - postToStats('show', originalUrl, ip, null, null, 'success'); + postToStats('show', originalUrl, ip, null, null, null, null, null, 'success'); res.status(200).render('memeFodder', { claims: orderedFreePublicClaims }); }) .catch(error => { @@ -55,7 +55,7 @@ module.exports = (app) => { res.status(307).render('noClaims'); return; } - postToStats('show', originalUrl, ip, null, null, 'success'); + postToStats('show', originalUrl, ip, null, null, null, null, null, 'success'); res.status(200).render('allClaims', { claims: orderedFreePublicClaims }); }) .catch(error => { @@ -73,7 +73,7 @@ module.exports = (app) => { return; } // serve the file or the show route - postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); res.status(200).render('show', { fileInfo }); }) .catch(error => { @@ -91,7 +91,7 @@ module.exports = (app) => { return; } // serve the show route - postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, fileInfo.fileName, fileInfo.fileType, fileInfo.nsfw, 'success'); res.status(200).render('show', { fileInfo }); }) .catch(error => { diff --git a/routes/sockets-routes.js b/routes/sockets-routes.js index bb3d23b3..feeb0e3b 100644 --- a/routes/sockets-routes.js +++ b/routes/sockets-routes.js @@ -27,7 +27,7 @@ module.exports = (app, siofu, hostedContentPath) => { // listener for when file upload encounters an error uploader.on('error', ({ error }) => { logger.error('an error occured while uploading', error); - postToStats('publish', '/', null, null, error); + postToStats('publish', '/', null, null, null, null, error); socket.emit('publish-status', error); }); // listener for when file has been uploaded @@ -41,18 +41,18 @@ module.exports = (app, siofu, hostedContentPath) => { publishController .publish(publishParams, file.name, file.meta.type) .then(result => { - postToStats('publish', '/', null, null, 'success'); + postToStats('publish', '/', null, null, null, null, 'success'); socket.emit('publish-complete', { name: publishParams.name, result }); }) .catch(error => { error = errorHandlers.handlePublishError(error); - postToStats('publish', '/', null, null, error); + postToStats('publish', '/', null, null, null, null, error); socket.emit('publish-failure', error); }); } else { logger.error(`An error occurred in uploading the client's file`); socket.emit('publish-failure', 'File uploaded, but with errors'); - postToStats('publish', '/', null, null, 'File uploaded, but with errors'); + postToStats('publish', '/', null, null, null, null, 'File uploaded, but with errors'); // to-do: remove the file if not done automatically } }); diff --git a/server.js b/server.js index 359c99a5..332889f4 100644 --- a/server.js +++ b/server.js @@ -11,8 +11,7 @@ const hostedContentPath = config.get('Database.PublishUploadPath'); // configure logging const logLevel = config.get('Logging.LogLevel'); -const logDir = config.get('Logging.LogDirectory'); -require('./config/loggerSetup.js')(winston, logLevel, logDir); +require('./config/loggerSetup.js')(winston, logLevel); // set port const PORT = 3000; @@ -92,9 +91,13 @@ const server = require('./routes/sockets-routes.js')(app, siofu, hostedContentPa // sync sequelize // wrap the server in socket.io to intercept incoming sockets requests // start server -db.sequelize.sync().then(() => { - server.listen(PORT, () => { - winston.info('Trusting proxy?', app.get('trust proxy')); - winston.info(`Server is listening on PORT ${PORT}`); +db.sequelize.sync() + .then(() => { + server.listen(PORT, () => { + winston.info('Trusting proxy?', app.get('trust proxy')); + winston.info(`Server is listening on PORT ${PORT}`); + }); + }) + .catch((error) => { + winston.log('Error syncing sequelize db:', error); }); -}); diff --git a/views/index.handlebars b/views/index.handlebars index a698756f..7f74f50b 100644 --- a/views/index.handlebars +++ b/views/index.handlebars @@ -3,11 +3,14 @@
{{> publish}} {{> learnMore}} + {{> trending}}
+ {{> footer}} + diff --git a/views/layouts/main.handlebars b/views/layouts/main.handlebars index ee2311da..a3babda6 100644 --- a/views/layouts/main.handlebars +++ b/views/layouts/main.handlebars @@ -5,11 +5,10 @@ Spee.ch - + - {{{ body }}} {{ googleAnalytics }} diff --git a/views/memeFodder.handlebars b/views/memeFodder.handlebars index 12a1dd50..f85e883b 100644 --- a/views/memeFodder.handlebars +++ b/views/memeFodder.handlebars @@ -10,5 +10,6 @@ + \ No newline at end of file diff --git a/views/partials/asset.handlebars b/views/partials/asset.handlebars index aeda960a..157c572b 100644 --- a/views/partials/asset.handlebars +++ b/views/partials/asset.handlebars @@ -1,5 +1,5 @@
-
+
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
{{#each claims}} - + {{/each}}
\ No newline at end of file diff --git a/views/partials/trending.handlebars b/views/partials/trending.handlebars new file mode 100644 index 00000000..3fbc585a --- /dev/null +++ b/views/partials/trending.handlebars @@ -0,0 +1,19 @@ +
+

Trending

+ {{#each trendingAssets}} + {{#if this.nsfw}} + {{else }} + {{#ifConditional this.fileType '===' 'video/mp4'}} + + {{else}} + + + + {{/ifConditional}} + {{/if}} + {{/each}} +
diff --git a/views/showLite.handlebars b/views/showLite.handlebars index b44d724a..c3477088 100644 --- a/views/showLite.handlebars +++ b/views/showLite.handlebars @@ -1,4 +1,4 @@ -
+
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
- - - - - - From 352defd0d87d8e75a8ad5b259ef7506c0e9796df Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 11 Jul 2017 17:12:39 -0700 Subject: [PATCH 3/9] updated some cosmetics --- views/about.handlebars | 1 + views/partials/assetInfo.handlebars | 18 ++---------------- views/show.handlebars | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/views/about.handlebars b/views/about.handlebars index 5c93d61a..9600c2f0 100644 --- a/views/about.handlebars +++ b/views/about.handlebars @@ -14,3 +14,4 @@ {{> footer}}
+ \ No newline at end of file diff --git a/views/partials/assetInfo.handlebars b/views/partials/assetInfo.handlebars index 6aa678a4..66bd1d6a 100644 --- a/views/partials/assetInfo.handlebars +++ b/views/partials/assetInfo.handlebars @@ -43,7 +43,7 @@ {{fileInfo.fileName}} - fileType + File Type {{#if fileInfo.fileType}} {{fileInfo.fileType}} {{else}} @@ -52,18 +52,4 @@ -
- - \ No newline at end of file + \ No newline at end of file diff --git a/views/show.handlebars b/views/show.handlebars index fe8935dc..4701240b 100644 --- a/views/show.handlebars +++ b/views/show.handlebars @@ -7,4 +7,17 @@ {{> assetInfo}} {{> footer}} - \ No newline at end of file + + + \ No newline at end of file From 45d1aca1c8133cd7f8aeac787e60454580e3f1c8 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 11 Jul 2017 17:40:23 -0700 Subject: [PATCH 4/9] added 'null ' to fix publish stats --- routes/sockets-routes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/routes/sockets-routes.js b/routes/sockets-routes.js index feeb0e3b..614a709d 100644 --- a/routes/sockets-routes.js +++ b/routes/sockets-routes.js @@ -27,7 +27,7 @@ module.exports = (app, siofu, hostedContentPath) => { // listener for when file upload encounters an error uploader.on('error', ({ error }) => { logger.error('an error occured while uploading', error); - postToStats('publish', '/', null, null, null, null, error); + postToStats('publish', '/', null, null, null, null, null, error); socket.emit('publish-status', error); }); // listener for when file has been uploaded @@ -41,18 +41,18 @@ module.exports = (app, siofu, hostedContentPath) => { publishController .publish(publishParams, file.name, file.meta.type) .then(result => { - postToStats('publish', '/', null, null, null, null, 'success'); + postToStats('publish', '/', null, null, null, null, null, 'success'); socket.emit('publish-complete', { name: publishParams.name, result }); }) .catch(error => { error = errorHandlers.handlePublishError(error); - postToStats('publish', '/', null, null, null, null, error); + postToStats('publish', '/', null, null, null, null, null, error); socket.emit('publish-failure', error); }); } else { logger.error(`An error occurred in uploading the client's file`); socket.emit('publish-failure', 'File uploaded, but with errors'); - postToStats('publish', '/', null, null, null, null, 'File uploaded, but with errors'); + postToStats('publish', '/', null, null, null, null, null, 'File uploaded, but with errors'); // to-do: remove the file if not done automatically } }); From 709db8e7414245456bb8266006ec05daa2770bd0 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 11 Jul 2017 18:17:38 -0700 Subject: [PATCH 5/9] removed trending from homepage --- routes/home-routes.js | 14 +++----------- views/index.handlebars | 1 - 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/routes/home-routes.js b/routes/home-routes.js index d3632aa0..ffe5ec78 100644 --- a/routes/home-routes.js +++ b/routes/home-routes.js @@ -1,19 +1,11 @@ const logger = require('winston'); -const { postToStats, getTrendingClaims } = require('../controllers/statsController.js'); -const errorHandlers = require('../helpers/libraries/errorHandlers.js'); +const { postToStats } = require('../controllers/statsController.js'); module.exports = app => { // route for the home page app.get('/', ({ headers, ip, originalUrl }, res) => { - const startDate = new Date(); - startDate.setDate(startDate.getDate() - 1); - getTrendingClaims(startDate) - .then(result => { - res.status(200).render('index', { trendingAssets: result }); - }) - .catch(error => { - errorHandlers.handleRequestError(error, res); - }); + // send response + res.status(200).render('index'); }); // a catch-all route if someone visits a page that does not exist app.use('*', ({ originalUrl, ip }, res) => { diff --git a/views/index.handlebars b/views/index.handlebars index 7f74f50b..e3b87ed4 100644 --- a/views/index.handlebars +++ b/views/index.handlebars @@ -3,7 +3,6 @@
{{> publish}} {{> learnMore}} - {{> trending}}
{{> footer}} From 1fb396c6603dc9d40322bf238fc9da74007bd716 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 11 Jul 2017 18:27:27 -0700 Subject: [PATCH 6/9] added nsfw filter on trending --- views/trending.handlebars | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/views/trending.handlebars b/views/trending.handlebars index 74cc80ea..3af0fad4 100644 --- a/views/trending.handlebars +++ b/views/trending.handlebars @@ -1,17 +1,4 @@
{{> topBar}} -
-

Trending Images

- {{#each trendingAssets}} - {{#ifConditional this.fileType '===' 'video/mp4'}} - - {{else}} - - {{/ifConditional}} - {{/each}} -
+ {{> trending}}
From 5d862ccce446c2311d3d134952eda2ed6efafa65 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Wed, 12 Jul 2017 07:48:04 -0700 Subject: [PATCH 7/9] updated template names --- .../partials/{trending.handlebars => trendingAssets.handlebars} | 2 +- views/trending.handlebars | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename views/partials/{trending.handlebars => trendingAssets.handlebars} (98%) diff --git a/views/partials/trending.handlebars b/views/partials/trendingAssets.handlebars similarity index 98% rename from views/partials/trending.handlebars rename to views/partials/trendingAssets.handlebars index 3fbc585a..0f94924b 100644 --- a/views/partials/trending.handlebars +++ b/views/partials/trendingAssets.handlebars @@ -16,4 +16,4 @@ {{/ifConditional}} {{/if}} {{/each}} - + \ No newline at end of file diff --git a/views/trending.handlebars b/views/trending.handlebars index 3af0fad4..cc9b963d 100644 --- a/views/trending.handlebars +++ b/views/trending.handlebars @@ -1,4 +1,4 @@
{{> topBar}} - {{> trending}} + {{> trendingAssets}}
From fadd055e330d42fee425f326b4fc4905ef242623 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Wed, 12 Jul 2017 08:24:45 -0700 Subject: [PATCH 8/9] added markdown as a share option --- views/partials/assetInfo.handlebars | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/views/partials/assetInfo.handlebars b/views/partials/assetInfo.handlebars index 66bd1d6a..986718ce 100644 --- a/views/partials/assetInfo.handlebars +++ b/views/partials/assetInfo.handlebars @@ -4,12 +4,24 @@