diff --git a/config/production.json b/config/production.json index 7e7e70bb..56fde915 100644 --- a/config/production.json +++ b/config/production.json @@ -1,9 +1,9 @@ { "WalletConfig": { - "lbryAddress": "none" + "LbryAddress": "none" }, "AnalyticsConfig":{ - "googleId": "UA-60403362-2" + "GoogleId": "UA-60403362-2" }, "Database": { "MySqlConnectionUri": "none", diff --git a/controllers/publishController.js b/controllers/publishController.js index abf3dca8..39410804 100644 --- a/controllers/publishController.js +++ b/controllers/publishController.js @@ -1,32 +1,8 @@ const fs = require('fs'); const logger = require('winston'); const lbryApi = require('../helpers/libraries/lbryApi.js'); -const config = require('config'); -const walledAddress = config.get('WalletConfig.lbryAddress'); -const errorHandlers = require('../helpers/libraries/errorHandlers.js'); const db = require('../models'); -function createPublishParams (claim, filePath, license, nsfw) { - logger.debug(`Creating Publish Parameters for "${claim}"`); - const publishParams = { - name : claim, - file_path: filePath, - bid : 0.01, - metadata : { - description: `${claim} published via spee.ch`, - title : claim, - author : 'spee.ch', - language : 'en', - license, - nsfw, - }, - claim_address : walledAddress, - change_address: walledAddress, - }; - logger.debug('publishParams:', publishParams); - return publishParams; -} - function deleteTemporaryFile (filePath) { fs.unlink(filePath, err => { if (err) throw err; @@ -49,51 +25,34 @@ function upsert (Model, values, condition) { } module.exports = { - publish (name, fileName, filePath, fileType, license, nsfw, socket, visitor) { - console.log('nsfw:', nsfw); - // validate nsfw - if (typeof nsfw === 'string') { - nsfw = (nsfw.toLowerCase() === 'true'); - } - // update the client - socket.emit('publish-status', 'Your image is being published (this might take a second)...'); - // send to analytics - visitor.event('Publish Route', 'Publish Request', filePath).send(); - // create the publish object - const publishParams = createPublishParams(name, filePath, license, nsfw); + publish: (publishParams, fileName, fileType) => { // 1. publish the file lbryApi - .publishClaim(publishParams, fileName, fileType) + .publishClaim(publishParams) .then(result => { logger.info(`Successfully published ${fileName}`, result); - // google analytics - visitor.event('Publish Route', 'Publish Success', filePath).send(); // 2. update old record of create new one (update is in case the claim has been published before by this daemon) upsert( db.File, { - name, + name : publishParams.name, claimId : result.claim_id, outpoint: `${result.txid}:${result.nout}`, height : 0, fileName, - filePath, + filePath: publishParams.file_path, fileType, - nsfw, + nsfw : publishParams.metadata.nsfw, }, - { name, claimId: result.claim_id } + { name: publishParams.name, claimId: result.claim_id } ).catch(error => { logger.error('Sequelize findOne error', error); }); - // update client - socket.emit('publish-complete', { name, result }); }) .catch(error => { logger.error(`Error publishing ${fileName}`, error); - // google analytics - visitor.event('Publish Route', 'Publish Failure', filePath).send(); - socket.emit('publish-failure', errorHandlers.handlePublishError(error)); - deleteTemporaryFile(filePath); + // delete the local file + deleteTemporaryFile(publishParams.file_path); }); }, }; diff --git a/helpers/libraries/lbryApi.js b/helpers/libraries/lbryApi.js index 3ff86cfd..026e1eee 100644 --- a/helpers/libraries/lbryApi.js +++ b/helpers/libraries/lbryApi.js @@ -2,8 +2,8 @@ const axios = require('axios'); const logger = require('winston'); module.exports = { - publishClaim (publishParams, fileName, fileType) { - logger.debug(`Publishing claim for "${fileName}"`); + publishClaim (publishParams) { + logger.debug(`Publishing claim to "${publishParams.name}"`); const deferred = new Promise((resolve, reject) => { axios .post('http://localhost:5279/lbryapi', { diff --git a/helpers/libraries/publishHelpers.js b/helpers/libraries/publishHelpers.js new file mode 100644 index 00000000..c0f8be79 --- /dev/null +++ b/helpers/libraries/publishHelpers.js @@ -0,0 +1,27 @@ +const logger = require('winston'); + +const config = require('config'); +const walletAddress = config.get('WalletConfig.LbryAddress'); + +module.exports = { + createPublishParams (name, filePath, license, nsfw) { + logger.debug(`Creating Publish Parameters for "${name}"`); + const publishParams = { + name, + file_path: filePath, + bid : 0.01, + metadata : { + description: `${name} published via spee.ch`, + title : name, + author : 'spee.ch', + language : 'en', + license, + nsfw, + }, + claim_address : walletAddress, + change_address: walletAddress, + }; + logger.debug('publishParams:', publishParams); + return publishParams; + }, +}; diff --git a/package.json b/package.json index 1204d3e9..b4706565 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "axios": "^0.16.1", "body-parser": "^1.17.1", "config": "^1.26.1", + "connect-multiparty": "^2.0.0", "express": "^4.15.2", "express-handlebars": "^3.0.0", "mysql2": "^1.3.5", diff --git a/routes/api-routes.js b/routes/api-routes.js index 65e8056b..7576c2e4 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -1,6 +1,10 @@ const errorHandlers = require('../helpers/libraries/errorHandlers.js'); const lbryApi = require('../helpers/libraries/lbryApi.js'); const logger = require('winston'); +const multipart = require('connect-multiparty'); +const multipartMiddleware = multipart(); +const publishController = require('../helpers/libraries/publishController.js'); +const publishHelpers = require('../helpers/libraries/publishHelpers.js'); module.exports = app => { // route to run a claim_list request on the daemon @@ -27,4 +31,36 @@ module.exports = app => { errorHandlers.handleRequestError(error, res); }); }); + // route to run a publish request on the daemon + app.post('/api/publish', multipartMiddleware, ({ originalUrl, body, files }, res) => { + logger.debug(`POST request on ${originalUrl}`); + console.log('>> req.files:', files); + console.log(' >> req.body:', body); + const name = body.claimName; + const license = body.license; + const nsfw = body.nsfw; + const fileName = files.file1.name; + const filePath = files.file1.path; + const fileType = files.file1.type; + /* + make sure it's not a harmful file type + */ + // prepare the publish parameters + const publishParams = publishHelpers.createPublishParams(name, filePath, license, nsfw); + // publish the file + publishController + .publish(publishParams, fileName, fileType) + .then(result => { + res.status(200).json(result); + }) + .catch(error => { + errorHandlers.handleRequestError(error, res); + }); + + if (files) { + res.status(200).json({'status': 'file(s) received'}); + } else { + res.status(400).josn({'status': 'no files(s) received'}); + } + }); }; diff --git a/routes/sockets-routes.js b/routes/sockets-routes.js index 0589a58b..705d47ff 100644 --- a/routes/sockets-routes.js +++ b/routes/sockets-routes.js @@ -1,5 +1,7 @@ -const publishController = require('../controllers/publishController.js'); const logger = require('winston'); +const publishController = require('../controllers/publishController.js'); +const publishHelpers = require('../controllers/publishHelpers.js'); +const errorHandlers = require('../helpers/libraries/errorHandlers.js'); module.exports = (app, siofu, hostedContentPath, ua, googleAnalyticsId) => { const http = require('http').Server(app); @@ -7,8 +9,9 @@ module.exports = (app, siofu, hostedContentPath, ua, googleAnalyticsId) => { io.on('connection', socket => { logger.silly('a user connected via sockets'); - // create visitor record + // google analytics const visitor = ua(googleAnalyticsId, { https: true }); + visitor.event('Publish Route', 'Publish Request').send(); // attach upload listeners const uploader = new siofu(); uploader.dir = hostedContentPath; @@ -27,8 +30,18 @@ module.exports = (app, siofu, hostedContentPath, ua, googleAnalyticsId) => { uploader.on('saved', ({ file }) => { if (file.success) { logger.debug(`Client successfully uploaded ${file.name}`); - socket.emit('publish-status', 'file upload successfully completed'); - publishController.publish(file.meta.name, file.name, file.pathName, file.meta.type, file.meta.license, file.meta.nsfw, socket, visitor); + socket.emit('publish-status', 'file upload successfully completed. Your image is being published (this might take a second)...'); + // prepare the publish parameters + const publishParams = publishHelpers.createPublishParams(file.meta.name, file.pathName, file.meta.license, file.meta.nsfw); + // publish the file + publishController + .publish(publishParams, file.name, file.meta.type) + .then(result => { + socket.emit('publish-complete', { name: publishParams.name, result }); + }) + .catch(error => { + socket.emit('publish-failure', errorHandlers.handlePublishError(error)); + }); } else { logger.error(`An error occurred in uploading the client's file`); socket.emit('publish-failure', 'file uploaded, but with errors'); diff --git a/uploadTest.html b/uploadTest.html new file mode 100644 index 00000000..16e7aae4 --- /dev/null +++ b/uploadTest.html @@ -0,0 +1,17 @@ + + + + + upload + + +
+

+

+

+

+

+

+

+ + \ No newline at end of file