moved request logs to middleware and reorganized front end js

This commit is contained in:
bill bittner 2017-07-06 13:37:03 -07:00
parent ec72307d16
commit eda480b81a
18 changed files with 283 additions and 245 deletions

View file

@ -195,4 +195,7 @@ module.exports = {
});
return deferred;
},
getAllClaims (claimName) {
return getAllFreePublicClaims(claimName);
},
};

View file

@ -1,7 +0,0 @@
const getAllFreePublicClaims = require('../helpers/functions/getAllFreePublicClaims.js');
module.exports = {
getAllClaims (claimName) {
return getAllFreePublicClaims(claimName);
},
};

View file

@ -18,15 +18,15 @@
margin-right: 1%;
padding-right: 1%;
border-right: 1px lightgrey solid;
margin-bottom: 5px;
}
.sidebar {
float: left;
float: right;
width: 32%;
}
footer {
display: inline-block;
width: 100%;
margin-bottom: 2px;
padding-bottom: 2px;

View file

@ -14,8 +14,14 @@
/* show routes */
.show-image, .show-video {
.show-asset {
width: 100%;
margin-bottom: 1em;
margin-top: 1em;
}
.show-asset-lite {
margin: 0px;
}
.table-metadata {
@ -133,6 +139,10 @@ canvas {
font-size: small;
}
.show-asset-lite {
width: 100%;
}
}
@media (max-width: 475px) {

View file

@ -3,81 +3,6 @@ var socket = io();
var uploader = new SocketIOFileUpload(socket);
var stagedFiles = null;
/* helper functions */
// create a progress animation
function createProgressBar(element, size){
var x = 1;
var adder = 1;
function addOne(){
var bars = '<p>|';
for (var i = 0; i < x; i++){ bars += ' | '; }
bars += '</p>';
element.innerHTML = bars;
if (x === size){
adder = -1;
} else if ( x === 0){
adder = 1;
}
x += adder;
};
setInterval(addOne, 300);
}
// preview file and stage the image for upload
function previewAndStageFile(selectedFile){
var preview = document.getElementById('image-preview');
var dropzone = document.getElementById('drop-zone');
var previewReader = new FileReader();
var nameInput = document.getElementById('publish-name');
preview.style.display = 'block';
dropzone.style.display = 'none';
previewReader.onloadend = function () {
preview.src = previewReader.result;
};
if (selectedFile) {
previewReader.readAsDataURL(selectedFile); // reads the data and sets the img src
if (nameInput.value === "") {
nameInput.value = selectedFile.name.substring(0, selectedFile.name.indexOf('.'));
}
stagedFiles = [selectedFile]; // stores the selected file for upload
} else {
preview.src = '';
}
}
// update the publish status
function updatePublishStatus(msg){
document.getElementById('publish-status').innerHTML = msg;
}
// process the drop-zone drop
function drop_handler(ev) {
ev.preventDefault();
// if dropped items aren't files, reject them
var dt = ev.dataTransfer;
if (dt.items) {
if (dt.items[0].kind == 'file') {
var droppedFile = dt.items[0].getAsFile();
previewAndStageFile(droppedFile);
}
}
}
// prevent the browser's default drag behavior
function dragover_handler(ev) {
ev.preventDefault();
}
// remove all of the drag data
function dragend_handler(ev) {
var dt = ev.dataTransfer;
if (dt.items) {
for (var i = 0; i < dt.items.length; i++) {
dt.items.remove(i);
}
} else {
ev.dataTransfer.clearData();
}
}
/* configure the submit button */
document.getElementById('publish-submit').addEventListener('click', function(event){
event.preventDefault();

View file

@ -15,4 +15,43 @@ function toggleSection(event){
masterElement.innerText = "[open]";
masterElement.dataset.open = "false";
}
}
// create a progress animation
function createProgressBar(element, size){
var x = 1;
var adder = 1;
function addOne(){
var bars = '<p>|';
for (var i = 0; i < x; i++){ bars += ' | '; }
bars += '</p>';
element.innerHTML = bars;
if (x === size){
adder = -1;
} else if ( x === 0){
adder = 1;
}
x += adder;
};
setInterval(addOne, 300);
}
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}

View file

@ -7,97 +7,6 @@ var license = 'Creative Commons';
var nsfw = false;
var nameInput = document.getElementById("publish-name");
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}
function startPublish() {
//download the image
var dataUrl = canvas.toDataURL('image/jpeg'); // canvas defined in memeDraw.js
var blob = dataURItoBlob(dataUrl)
var fileName = nameInput.value + ".jpg"; //note: need to dynamically grab type
var file = new File([blob], fileName, {type: 'image/jpeg', lastModified: Date.now()});
stageAndPublish(file);
};
/* helper functions */
// create a progress animation
function createProgressBar(element, size){
var x = 1;
var adder = 1;
function addOne(){
var bars = '<p>|';
for (var i = 0; i < x; i++){ bars += ' | '; }
bars += '</p>';
element.innerHTML = bars;
if (x === size){
adder = -1;
} else if ( x === 0){
adder = 1;
}
x += adder;
};
setInterval(addOne, 300);
}
function stageAndPublish(file) {
var name = nameInput.value;
var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name);
// validate 'name'
if (invalidCharacters) {
alert(invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, "_" and "-" only.');
return;
} else if (name.length < 1) {
alert("You must enter a name for your claim");
return;
}
// stage files
stagedFiles = [file]; // stores the selected file for
// make sure a file was selected
if (stagedFiles) {
// make sure only 1 file was selected
if (stagedFiles.length < 1) {
alert("A file is needed");
return;
}
// make sure the content type is acceptable
switch (stagedFiles[0].type) {
case "image/png":
case "image/jpeg":
case "image/gif":
case "video/mp4":
uploader.submitFiles(stagedFiles);
break;
default:
alert("Only .png, .jpeg, .gif, and .mp4 files are currently supported");
break;
}
} else {
alert("Please select a file");
}
}
// update the publish status
function updatePublishStatus(msg){
document.getElementById('publish-status').innerHTML = msg;
}
/* socketio-file-upload listeners */
uploader.addEventListener('start', function(event){
event.file.meta.name = nameInput.value;

View file

@ -0,0 +1,107 @@
// update the publish status
function updatePublishStatus(msg){
document.getElementById('publish-status').innerHTML = msg;
}
/* regular publish helper functions */
function previewAndStageFile(selectedFile){
var preview = document.getElementById('image-preview');
var dropzone = document.getElementById('drop-zone');
var previewReader = new FileReader();
var nameInput = document.getElementById('publish-name');
preview.style.display = 'block';
dropzone.style.display = 'none';
previewReader.onloadend = function () {
preview.src = previewReader.result;
};
if (selectedFile) {
previewReader.readAsDataURL(selectedFile); // reads the data and sets the img src
if (nameInput.value === "") {
nameInput.value = selectedFile.name.substring(0, selectedFile.name.indexOf('.'));
}
stagedFiles = [selectedFile]; // stores the selected file for upload
} else {
preview.src = '';
}
}
/* drop zone function s*/
function drop_handler(ev) {
ev.preventDefault();
// if dropped items aren't files, reject them
var dt = ev.dataTransfer;
if (dt.items) {
if (dt.items[0].kind == 'file') {
var droppedFile = dt.items[0].getAsFile();
previewAndStageFile(droppedFile);
}
}
}
function dragover_handler(ev) {
ev.preventDefault();
}
function dragend_handler(ev) {
var dt = ev.dataTransfer;
if (dt.items) {
for (var i = 0; i < dt.items.length; i++) {
dt.items.remove(i);
}
} else {
ev.dataTransfer.clearData();
}
}
/* meme publish functions */
function startPublish() {
//download the image
var dataUrl = canvas.toDataURL('image/jpeg'); // canvas defined in memeDraw.js
var blob = dataURItoBlob(dataUrl)
var fileName = nameInput.value + ".jpg"; //note: need to dynamically grab type
var file = new File([blob], fileName, {type: 'image/jpeg', lastModified: Date.now()});
stageAndPublish(file);
};
function stageAndPublish(file) {
var name = nameInput.value;
var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name);
// validate 'name'
if (invalidCharacters) {
alert(invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, "_" and "-" only.');
return;
} else if (name.length < 1) {
alert("You must enter a name for your claim");
return;
}
// stage files
stagedFiles = [file]; // stores the selected file for
// make sure a file was selected
if (stagedFiles) {
// make sure only 1 file was selected
if (stagedFiles.length < 1) {
alert("A file is needed");
return;
}
// make sure the content type is acceptable
switch (stagedFiles[0].type) {
case "image/png":
case "image/jpeg":
case "image/gif":
case "video/mp4":
uploader.submitFiles(stagedFiles);
break;
default:
alert("Only .png, .jpeg, .gif, and .mp4 files are currently supported");
break;
}
} else {
alert("Please select a file");
}
}

View file

@ -12,8 +12,6 @@ module.exports = app => {
app.get('/api/claim_list/:name', ({ headers, ip, originalUrl, params }, res) => {
// google analytics
sendGoogleAnalytics('serve', headers, ip, originalUrl);
// log
logger.verbose(`GET request on ${originalUrl} from ${ip}`);
// serve the content
lbryApi
.getClaimsList(params.name)
@ -27,8 +25,6 @@ module.exports = app => {
});
// route to check whether spee.ch has published to a claim
app.get('/api/isClaimAvailable/:name', ({ ip, originalUrl, params }, res) => {
// log
logger.verbose(`GET request on ${originalUrl} from ${ip}`);
// send response
publishController
.checkNameAvailability(params.name)
@ -48,8 +44,6 @@ module.exports = app => {
app.get('/api/resolve/:uri', ({ headers, ip, originalUrl, params }, res) => {
// google analytics
sendGoogleAnalytics('serve', headers, ip, originalUrl);
// log
logger.verbose(`GET request on ${originalUrl} from ${ip}`);
// serve content
lbryApi
.resolveUri(params.uri)
@ -65,8 +59,6 @@ module.exports = app => {
app.post('/api/publish', multipartMiddleware, ({ body, files, headers, ip, originalUrl }, res) => {
// google analytics
sendGoogleAnalytics('publish', headers, ip, originalUrl);
// log
logger.verbose(`POST request on ${originalUrl} from ${ip}`);
// validate that a file was provided
const file = files.speech || files.null;
logger.debug(file);

View file

@ -4,15 +4,12 @@ const { postToStats } = require('../controllers/statsController.js');
module.exports = app => {
// route for the home page
app.get('/', ({ headers, ip, originalUrl }, res) => {
// logging
logger.verbose(`GET request on ${originalUrl} from ${ip}`);
// 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) => {
// logging
logger.error(`Get request on ${originalUrl} from ${ip} which was a 404`);
logger.error(`404 on ${originalUrl}`);
// post to stats
postToStats('show', originalUrl, ip, 'Error: 404');
// send response

View file

@ -1,7 +1,7 @@
const errorHandlers = require('../helpers/libraries/errorHandlers.js');
const serveController = require('../controllers/serveController.js');
const logger = require('winston');
const { getClaimByClaimId, getClaimByName } = require('../controllers/serveController.js');
const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
const errorHandlers = require('../helpers/libraries/errorHandlers.js');
function serveFile ({ fileName, fileType, filePath }, res) {
logger.info(`serving file ${fileName}`);
@ -31,26 +31,17 @@ function serveFile ({ fileName, fileType, filePath }, res) {
res.status(200).sendFile(filePath, options);
}
function servePage (fileInfo, res) {
logger.debug(`serving show page for ${fileInfo.fileName}`);
// set default options
res.status(200).render('show', { fileInfo });
}
function sendAnalyticsAndLog (headers, ip, originalUrl) {
// google analytics
sendGoogleAnalytics('serve', headers, ip, originalUrl);
// logging
logger.verbose(`GET request on ${originalUrl} from ${ip}`);
}
module.exports = (app) => {
// route to fetch one free public claim
// route to serve a specific asset
app.get('/:name/:claim_id', ({ headers, ip, originalUrl, params }, res) => {
sendAnalyticsAndLog(headers, ip, originalUrl);
// begin image-serve processes
serveController
.getClaimByClaimId(params.name, params.claim_id)
getClaimByClaimId(params.name, params.claim_id)
.then(fileInfo => {
// check to make sure a file was found
if (!fileInfo) {
@ -61,8 +52,7 @@ module.exports = (app) => {
const mimetypes = headers['accept'].split(',');
if (mimetypes.includes('text/html')) {
postToStats('show', originalUrl, ip, 'success');
logger.debug('fileInfo', fileInfo);
servePage(fileInfo, res);
res.status(200).render('showLite', { fileInfo });
} else {
postToStats('serve', originalUrl, ip, 'success');
serveFile(fileInfo, res);
@ -72,12 +62,11 @@ module.exports = (app) => {
errorHandlers.handleRequestError('serve', originalUrl, ip, error, res);
});
});
// route to fetch one free public claim
// route to serve the winning claim
app.get('/:name', ({ headers, ip, originalUrl, params }, res) => {
sendAnalyticsAndLog(headers, ip, originalUrl);
// begin image-serve processes
serveController
.getClaimByName(params.name)
getClaimByName(params.name)
.then(fileInfo => {
// check to make sure a file was found
if (!fileInfo) {
@ -88,7 +77,7 @@ module.exports = (app) => {
const mimetypes = headers['accept'].split(',');
if (mimetypes.includes('text/html')) {
postToStats('show', originalUrl, ip, 'success');
servePage(fileInfo, res);
res.status(200).render('showLite', { fileInfo });
} else {
postToStats('serve', originalUrl, ip, 'success');
serveFile(fileInfo, res);

View file

@ -1,18 +1,15 @@
const logger = require('winston');
const errorHandlers = require('../helpers/libraries/errorHandlers.js');
const { getAllClaims } = require('../controllers/showController.js');
const { getClaimByClaimId, getClaimByName, getAllClaims } = require('../controllers/serveController.js');
const { getStatsSummary, postToStats } = require('../controllers/statsController.js');
module.exports = (app) => {
// route to show 'about' page for spee.ch
app.get('/about', ({ ip, originalUrl }, res) => {
logger.verbose(`POST request on ${originalUrl} from ${ip}`);
// 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) => {
logger.verbose(`POST request on ${originalUrl} from ${ip}`);
// get and render the content
getAllClaims('meme-fodder')
.then(orderedFreePublicClaims => {
@ -25,7 +22,6 @@ module.exports = (app) => {
});
// route to show statistics for spee.ch
app.get('/stats', ({ ip, originalUrl }, res) => {
logger.verbose(`POST request on ${originalUrl} from ${ip}`);
// get and render the content
getStatsSummary()
.then(result => {
@ -38,7 +34,6 @@ module.exports = (app) => {
});
// route to display all free public claims at a given name
app.get('/:name/all', ({ ip, originalUrl, params }, res) => {
logger.verbose(`POST request on ${originalUrl} from ${ip}`);
// get and render the content
getAllClaims(params.name)
.then(orderedFreePublicClaims => {
@ -53,4 +48,40 @@ module.exports = (app) => {
errorHandlers.handleRequestError('show', originalUrl, ip, error, res);
});
});
// route to show a specific asset
app.get('/s/:name/:claim_id', ({ ip, originalUrl, params }, res) => {
// begin image-serve processes
getClaimByClaimId(params.name, params.claim_id)
.then(fileInfo => {
// check to make sure a file was found
if (!fileInfo) {
res.status(307).render('noClaims');
return;
}
// serve the file or the show route
postToStats('show', originalUrl, ip, 'success');
res.status(200).render('show', { fileInfo });
})
.catch(error => {
errorHandlers.handleRequestError('serve', originalUrl, ip, error, res);
});
});
// route to show the winning free, public claim
app.get('/s/:name', ({ ip, originalUrl, params }, res) => {
// get and render the content
getClaimByName(params.name)
.then(fileInfo => {
// check to make sure a file was found
if (!fileInfo) {
res.status(307).render('noClaims');
return;
}
// serve the show route
postToStats('show', originalUrl, ip, 'success');
res.status(200).render('show', { fileInfo });
})
.catch(error => {
errorHandlers.handleRequestError('serve', originalUrl, ip, error, res);
});
});
};

View file

@ -29,6 +29,10 @@ app.enable('trust proxy'); // trust the proxy to get ip address for us
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(siofu.router);
app.use((req, res, next) => { // logging middleware
winston.verbose(`Request on ${req.originalUrl} from ${req.ip}`);
next();
});
// configure handlebars & register it with Express app
const hbs = expressHandlebars.create({

View file

@ -9,4 +9,5 @@
<script src="/socket.io/socket.io.js"></script>
<script src="/siofu/client.js"></script>
<script src="/assets/js/publishFunctions.js"></script>
<script src="/assets/js/claimPublish.js"></script>

View file

@ -9,8 +9,8 @@
<link rel="stylesheet" href="/assets/css/componentStyle.css" type="text/css">
</head>
<body>
{{{ body }}}
<script src="/assets/js/generalFunctions.js"></script>
{{{ body }}}
<!-- google analytics -->
{{ googleAnalytics }}
</body>

View file

@ -1,33 +1,5 @@
<div class="panel">
<h2>{{fileInfo.name}}</h2>
<div id="asset-placeholder" data-filepath="{{{fileInfo.filePath}}}">
<p> loading... </p>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io();
var filePath = document.getElementById('asset-placeholder').dataset.filepath;
console.log(filePath);
if (filePath) {
// send request for the file
socket.emit('asset-request', filePath);
}
// wait for the file to be sent
socket.on('asset-transfer', function(data) {
switch (data.type) {
case 'image/jpeg':
case 'image/gif':
case 'image/png':
const base64Image = 'data:' + data.type + ';base64,' + data.buffer;
document.getElementById("asset-placeholder").innerHTML = '<img class="show-image" src="' + base64Image + '"/>';
break;
case 'video/mp4':
const base64video = 'data:' + data.type + ';base64,' + data.buffer;
document.getElementById("asset-placeholder").innerHTML = '<video controls class="show-video"> <source src="' + base64video + '"></video>';
break;
default: break;
}
});
</script>
</div>

View file

@ -1,11 +1,43 @@
<div class="wrapper">
{{> topBar}}
<div class="main">
<div class="main">
{{> asset}}
</div>
<div class="sidebar">
<h1>{{fileInfo.name}}</h1>
{{> assetLinks}}
{{> assetMetadata}}
</div>
{{> footer}}
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io();
var filePath = document.getElementById('asset-placeholder').dataset.filepath;
console.log(filePath);
if (filePath) {
// send request for the file
socket.emit('asset-request', filePath);
// update the html
document.getElementById('asset-placeholder').innerHTML = '<p>Loading...</p><div id="progress-bar"></div>';
// start a progress animation
createProgressBar(document.getElementById('progress-bar'), 12);
}
// wait for the file to be sent
socket.on('asset-transfer', function(data) {
switch (data.type) {
case 'image/jpeg':
case 'image/gif':
case 'image/png':
const base64Image = 'data:' + data.type + ';base64,' + data.buffer;
document.getElementById("asset-placeholder").innerHTML = '<img class="show-asset" src="' + base64Image + '"/>';
break;
case 'video/mp4':
const base64video = 'data:' + data.type + ';base64,' + data.buffer;
document.getElementById("asset-placeholder").innerHTML = '<video class="show-asset" controls> <source src="' + base64video + '"></video>';
break;
default: break;
}
});
</script>

34
views/showLite.handlebars Normal file
View file

@ -0,0 +1,34 @@
<div id="asset-placeholder" data-filepath="{{{fileInfo.filePath}}}">
<p> loading... </p>
</div>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io();
var filePath = document.getElementById('asset-placeholder').dataset.filepath;
console.log(filePath);
if (filePath) {
// send request for the file
socket.emit('asset-request', filePath);
// update the html
document.getElementById('asset-placeholder').innerHTML = '<p>Loading...</p><div id="progress-bar"></div>';
// start a progress animation
createProgressBar(document.getElementById('progress-bar'), 12);
}
// wait for the file to be sent
socket.on('asset-transfer', function(data) {
switch (data.type) {
case 'image/jpeg':
case 'image/gif':
case 'image/png':
const base64Image = 'data:' + data.type + ';base64,' + data.buffer;
document.getElementById("asset-placeholder").innerHTML = '<img class="show-asset-lite" src="' + base64Image + '"/>';
break;
case 'video/mp4':
const base64video = 'data:' + data.type + ';base64,' + data.buffer;
document.getElementById("asset-placeholder").innerHTML = '<video class="show-asset-lite" controls> <source src="' + base64video + '"></video>';
break;
default: break;
}
});
</script>