changed upload to use formdata and /post api

This commit is contained in:
bill bittner 2017-11-01 13:07:13 -07:00
parent e48a7b596d
commit 7884fa31b0
10 changed files with 58 additions and 112 deletions

View file

@ -1,6 +1,7 @@
{ {
"WalletConfig": { "WalletConfig": {
"LbryClaimAddress": null, "LbryClaimAddress": null,
"LbryChangeAddress": null,
"DefaultChannel": null "DefaultChannel": null
}, },
"AnalyticsConfig":{ "AnalyticsConfig":{

View file

@ -1,6 +1,7 @@
{ {
"WalletConfig": { "WalletConfig": {
"DefaultChannel": "@speechDev" "DefaultChannel": "@speechDev",
"LbryChangeAddress": "bPsZ4wmrNUsn7gMP9cZ9G6RjM5RpuJAeTt"
}, },
"AnalyticsConfig":{ "AnalyticsConfig":{
"GoogleId": "UA-100747990-1" "GoogleId": "UA-100747990-1"

View file

@ -1,6 +1,7 @@
{ {
"WalletConfig": { "WalletConfig": {
"DefaultChannel": "@speech" "DefaultChannel": "@speech",
"LbryChangeAddress": null
}, },
"AnalyticsConfig":{ "AnalyticsConfig":{
"GoogleId": "UA-60403362-3" "GoogleId": "UA-60403362-3"

View file

@ -11,9 +11,6 @@ module.exports = {
if (!body.name) { if (!body.name) {
throw new Error('no name field found in request'); throw new Error('no name field found in request');
} }
if (!body.nsfw) {
throw new Error('no nsfw field found in request');
}
if (!files) { if (!files) {
throw new Error('no files found in request'); throw new Error('no files found in request');
} }
@ -94,7 +91,7 @@ module.exports = {
case '0': case '0':
return false; return false;
default: default:
return null; return false;
} }
}, },
cleanseChannelName (channelName) { cleanseChannelName (channelName) {
@ -138,7 +135,8 @@ module.exports = {
license, license,
nsfw, nsfw,
}, },
claim_address: config.get('WalletConfig.LbryClaimAddress'), claim_address : config.get('WalletConfig.LbryClaimAddress'),
change_address: config.get('WalletConfig.LbryChangeAddress'),
}; };
// add thumbnail to channel if video // add thumbnail to channel if video
if (thumbnail !== null) { if (thumbnail !== null) {

View file

@ -44,8 +44,6 @@
"sequelize": "^4.1.0", "sequelize": "^4.1.0",
"sequelize-cli": "^3.0.0-3", "sequelize-cli": "^3.0.0-3",
"sleep": "^5.1.1", "sleep": "^5.1.1",
"socket.io": "^2.0.1",
"socketio-file-upload": "^0.6.0",
"universal-analytics": "^0.4.13", "universal-analytics": "^0.4.13",
"winston": "^2.3.1", "winston": "^2.3.1",
"winston-slack-webhook": "billbitt/winston-slack-webhook" "winston-slack-webhook": "billbitt/winston-slack-webhook"

View file

@ -81,7 +81,7 @@ function publishStagedFile(event) {
// validate, submit, and handle response // validate, submit, and handle response
validateFilePublishSubmission(stagedFiles, claimName, channelName) validateFilePublishSubmission(stagedFiles, claimName, channelName)
.then(() => { .then(() => {
uploader.submitFiles(stagedFiles); publishFile(stagedFiles[0], claimName);
}) })
.catch(error => { .catch(error => {
if (error.name === 'FileError') { if (error.name === 'FileError') {
@ -96,4 +96,37 @@ function publishStagedFile(event) {
} }
return; return;
}) })
}; };
var publishFile = function (file, name) {
var uri = "/api/publish";
var xhr = new XMLHttpRequest();
var fd = new FormData();
console.log('publish file, file:', file);
console.log('publish file, name:', name);
fd.append('file', file);
fd.append('name', name);
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentage = Math.round((e.loaded * 100) / e.total);
console.log('progress:', percentage);
}
}, false);
xhr.upload.addEventListener("load", function(e){
console.log('loaded 100%');
}, false);
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText); // handle response.
} else {
console.log('xhr.readyState', xhr.readyState, 'xhr.status', xhr.status);
}
};
// Initiate a multipart/form-data upload
xhr.send(fd);
}

View file

@ -72,7 +72,7 @@ module.exports = (app) => {
}); });
// route to run a publish request on the daemon // route to run a publish request on the daemon
app.post('/api/publish', multipartMiddleware, (req, res) => { app.post('/api/publish', multipartMiddleware, (req, res) => {
logger.debug('req:', req); logger.debug('req:', req.body, req.files);
// validate that mandatory parts of the request are present // validate that mandatory parts of the request are present
const body = req.body; const body = req.body;
const files = req.files; const files = req.files;
@ -89,8 +89,7 @@ module.exports = (app) => {
const filePath = file.path; const filePath = file.path;
const fileType = file.type; const fileType = file.type;
const name = body.name; const name = body.name;
let nsfw = body.nsfw; const nsfw = cleanseNSFW(body.nsfw); // cleanse nsfw input
nsfw = cleanseNSFW(nsfw); // cleanse nsfw
try { try {
validatePublishSubmission(file, name, nsfw); validatePublishSubmission(file, name, nsfw);
} catch (error) { } catch (error) {
@ -107,7 +106,7 @@ module.exports = (app) => {
let channelName = body.channelName || null; let channelName = body.channelName || null;
channelName = cleanseChannelName(channelName); channelName = cleanseChannelName(channelName);
const channelPassword = body.channelPassword || null; const channelPassword = body.channelPassword || null;
logger.debug(`license: ${license} title: "${title}" description: "${description}" channelName: "${channelName}" channelPassword: "${channelPassword}"`); logger.debug(`license: ${license} title: "${title}" description: "${description}" channelName: "${channelName}" channelPassword: "${channelPassword}" nsfw: "${nsfw}"`);
// check channel authorization // check channel authorization
authenticateChannelCredentials(channelName, channelPassword) authenticateChannelCredentials(channelName, channelPassword)
.then(result => { .then(result => {

View file

@ -1,79 +0,0 @@
const logger = require('winston');
const { publish } = require('../controllers/publishController.js');
const { createPublishParams } = require('../helpers/publishHelpers.js');
const { useObjectPropertiesIfNoKeys } = require('../helpers/errorHandlers.js');
const { postToStats } = require('../controllers/statsController.js');
module.exports = (app, siofu, hostedContentPath) => {
const http = require('http');
const server = http.Server(app);
const io = require('socket.io')(server);
io.on('connection', socket => {
logger.silly('a user connected via sockets');
// attach upload listeners
const uploader = new siofu();
uploader.dir = hostedContentPath;
uploader.listen(socket);
// listener for when file upload starts
uploader.on('start', ({ file }) => {
// log
logger.info('client started an upload:', file.name);
// server side test to make sure file is not a bad file type
if (/\.exe$/.test(file.name)) {
uploader.abort(file.id, socket);
}
});
// 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, error);
socket.emit('publish-status', error);
});
// listener for when file has been uploaded
uploader.on('saved', ({ file }) => {
if (file.success) {
logger.debug(`Client successfully uploaded ${file.name}`);
socket.emit('publish-update', 'File upload successfully completed. Your image is being published to LBRY (this might take a second)...');
// /*
// NOTE: need to validate that client has the credentials to the channel they chose
// otherwise they could circumvent security.
// */
let thumbnail;
if (file.meta.thumbnail) {
thumbnail = file.meta.thumbnail;
} else {
thumbnail = null;
}
let channelName;
if (file.meta.channel) {
channelName = file.meta.channel;
} else {
channelName = null;
}
// prepare the publish parameters
const publishParams = createPublishParams(file.pathName, file.meta.name, file.meta.title, file.meta.description, file.meta.license, file.meta.nsfw, thumbnail, channelName);
logger.debug('publish parameters:', publishParams);
// publish the file
publish(publishParams, file.name, file.meta.type)
.then(result => {
socket.emit('publish-complete', { name: publishParams.name, result });
})
.catch(error => {
logger.error('Publish Error:', useObjectPropertiesIfNoKeys(error));
socket.emit('publish-failure', error.message);
});
} else {
socket.emit('publish-failure', 'File uploaded, but with errors');
logger.error(`An error occurred in uploading the client's file`);
// to-do: remove the file, if not done automatically
}
});
// handle disconnect
socket.on('disconnect', () => {
logger.silly('a user disconnected via sockets');
});
});
return server;
};

View file

@ -82,7 +82,8 @@ db.sequelize
require('./routes/page-routes.js')(app); require('./routes/page-routes.js')(app);
require('./routes/serve-routes.js')(app); require('./routes/serve-routes.js')(app);
require('./routes/home-routes.js')(app); require('./routes/home-routes.js')(app);
return require('./routes/sockets-routes.js')(app, siofu, hostedContentPath); const http = require('http');
return http.Server(app);
}) })
.then(server => { // start the server .then(server => { // start the server
server.listen(PORT, () => { server.listen(PORT, () => {

View file

@ -51,15 +51,10 @@
</div> </div>
</div> </div>
<script src="/socket.io/socket.io.js"></script>
<script src="/siofu/client.js"></script>
<script typ="text/javascript"> <script typ="text/javascript">
checkCookie(); checkCookie();
const socket = io();
const uploader = new SocketIOFileUpload(socket);
let stagedFiles = null; let stagedFiles = null;
const publishFormWrapper = document.getElementById('publish-form'); const publishFormWrapper = document.getElementById('publish-form');
@ -68,8 +63,7 @@
const publishProgressBar = document.getElementById('publish-progress-bar'); const publishProgressBar = document.getElementById('publish-progress-bar');
const uploadPercent = document.getElementById('upload-percent'); const uploadPercent = document.getElementById('upload-percent');
/* socketio-file-upload listeners */ function uploadStarted (event){
uploader.addEventListener('start', function(event){
console.log('starting upload'); console.log('starting upload');
addInputValuesToFileMetaData(event) addInputValuesToFileMetaData(event)
// hide the publish tool // hide the publish tool
@ -77,30 +71,29 @@
// show the progress status and animation // show the progress status and animation
showPublishStatus(); showPublishStatus();
showPublishProgressBar(); showPublishProgressBar();
}); };
uploader.addEventListener('progress', function(event){ function uploadProgress (event){
var percent = event.bytesLoaded / event.file.size * 100; var percent = event.bytesLoaded / event.file.size * 100;
updatePublishStatus('<p>File is loading to server</p>') updatePublishStatus('<p>File is loading to server</p>')
updateUploadPercent(`<p class="blue">${percent.toFixed(2)}%</p>`) updateUploadPercent(`<p class="blue">${percent.toFixed(2)}%</p>`)
}); };
/* socket.io message listeners */ function filePublishUpdate (msg) {
socket.on('publish-update', function(msg){
updatePublishStatus(`<p>${msg}</p>`); updatePublishStatus(`<p>${msg}</p>`);
updateUploadPercent(`<p>Curious what magic is happening here? <a class="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>`); updateUploadPercent(`<p>Curious what magic is happening here? <a class="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>`);
}); };
socket.on('publish-failure', function(msg){ function filePublishFailure (msg){
updatePublishStatus('<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">lbry discord</a></strong>'); updatePublishStatus('<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">lbry discord</a></strong>');
hidePublishProgressBar(); hidePublishProgressBar();
hideUploadPercent(); hideUploadPercent();
}); };
socket.on('publish-complete', function(msg){ function filePublishComplete (msg) {
const showUrl = msg.result.claim_id + "/" + msg.name; const showUrl = msg.result.claim_id + "/" + msg.name;
// update status // update status
updatePublishStatus('<p>Your publish is complete! You are being redirected to it now.</p>'); updatePublishStatus('<p>Your publish is complete! You are being redirected to it now.</p>');
updateUploadPercent('<p><a class="link--primary" target="_blank" href="\' + showUrl + \'">If you do not get redirected, click here.</a></p>') updateUploadPercent('<p><a class="link--primary" target="_blank" href="\' + showUrl + \'">If you do not get redirected, click here.</a></p>')
// redirect the user // redirect the user
window.location.href = showUrl; window.location.href = showUrl;
}); };
function hidePublishTools() { function hidePublishTools() {
publishFormWrapper.setAttribute('class', 'hidden'); publishFormWrapper.setAttribute('class', 'hidden');