From 530de9ad319e811840f6f499c7daadf7fd0f2c52 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 15 Jun 2017 08:03:29 -0700 Subject: [PATCH 01/10] small skin change --- views/partials/documentation.handlebars | 2 +- views/partials/examples.handlebars | 2 +- views/partials/publish.handlebars | 2 +- views/partials/topBar.handlebars | 17 ++++++++++++++--- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/views/partials/documentation.handlebars b/views/partials/documentation.handlebars index 217649a6..a7d8243a 100644 --- a/views/partials/documentation.handlebars +++ b/views/partials/documentation.handlebars @@ -1,6 +1,6 @@
-
+

Site Navigation

diff --git a/views/partials/examples.handlebars b/views/partials/examples.handlebars index 43acd663..3535d957 100644 --- a/views/partials/examples.handlebars +++ b/views/partials/examples.handlebars @@ -1,6 +1,6 @@
-
+

Examples

diff --git a/views/partials/publish.handlebars b/views/partials/publish.handlebars index a6c40fde..e99aedbb 100644 --- a/views/partials/publish.handlebars +++ b/views/partials/publish.handlebars @@ -1,6 +1,6 @@
-
+

Publish Your Own

diff --git a/views/partials/topBar.handlebars b/views/partials/topBar.handlebars index 3d406f09..16095f68 100644 --- a/views/partials/topBar.handlebars +++ b/views/partials/topBar.handlebars @@ -1,10 +1,21 @@
-
+
-

Spee.ch

+
+
+ +
+
+

Spee.ch

+
+
+
+
+

Spee.ch is a single-serving site that reads and publishes images to and from the LBRY blockchain.

+
+
-

Spee.ch is a single-serving site that reads and publishes images to and from the LBRY blockchain.

\ No newline at end of file From 36d64ad7b0eafc5976a394d0b527c19a534ee450 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 15 Jun 2017 11:15:13 -0700 Subject: [PATCH 02/10] added sequelize and 'file' row creation on publish --- config/custom-environment-variables.json | 3 ++ config/default.json | 4 +++ config/development.json | 3 ++ config/production.json | 4 +++ config/test.json | 12 +++++++ helpers/socketHelpers.js | 37 +++++++++++++-------- models/file.js | 27 ++++++++++++++++ models/index.js | 41 ++++++++++++++++++++++++ package.json | 2 ++ routes/sockets-routes.js | 11 ++++--- server.js | 20 ++++++++---- views/index.handlebars | 1 + 12 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 config/test.json create mode 100644 models/file.js create mode 100644 models/index.js diff --git a/config/custom-environment-variables.json b/config/custom-environment-variables.json index 1a2f8501..cb9b9aa3 100644 --- a/config/custom-environment-variables.json +++ b/config/custom-environment-variables.json @@ -1,5 +1,8 @@ { "WalletConfig": { "lbryAddress": "LBRY_WALLET_ADDRESS" + }, + "Database": { + "MySqlConnectionUri": "MYSQL_CONNECTION_STRING" } } \ No newline at end of file diff --git a/config/default.json b/config/default.json index 17c51244..cabec5e8 100644 --- a/config/default.json +++ b/config/default.json @@ -4,5 +4,9 @@ }, "AnalyticsConfig":{ "googleId": "none" + }, + "Database": { + "MySqlConnectionUri": "none", + "DownloadAddress": "C:\\lbry\\speech\\hosted_content" } } \ No newline at end of file diff --git a/config/development.json b/config/development.json index c1bac572..b1bac598 100644 --- a/config/development.json +++ b/config/development.json @@ -4,5 +4,8 @@ }, "AnalyticsConfig":{ "googleId": "UA-100747990-1" + }, + "Database": { + "MySqlConnectionUri": "none" } } \ No newline at end of file diff --git a/config/production.json b/config/production.json index 95f72955..c2ced7e9 100644 --- a/config/production.json +++ b/config/production.json @@ -4,5 +4,9 @@ }, "AnalyticsConfig":{ "googleId": "UA-60403362-2" + }, + "Database": { + "MySqlConnectionUri": "none", + "DownloadAddress": "~/Downloads/" } } \ No newline at end of file diff --git a/config/test.json b/config/test.json new file mode 100644 index 00000000..7c18d6eb --- /dev/null +++ b/config/test.json @@ -0,0 +1,12 @@ +{ + "WalletConfig": { + "lbryAddress": "none" + }, + "AnalyticsConfig":{ + "googleId": "UA-100747990-1" + }, + "Database": { + "MySqlConnectionUri": "none", + "DownloadAddress": "~/Downloads/" + } +} \ No newline at end of file diff --git a/helpers/socketHelpers.js b/helpers/socketHelpers.js index 59688edd..d3aeb387 100644 --- a/helpers/socketHelpers.js +++ b/helpers/socketHelpers.js @@ -1,6 +1,7 @@ var fs = require('fs'); -var lbryApi = require('../helpers/lbryApi.js'); +var lbryApi = require('./lbryApi.js'); var config = require('config'); +var db = require("../models"); var walledAddress = config.get('WalletConfig.lbryAddress'); @@ -14,10 +15,10 @@ function handlePublishError(error) { }; } -function createPublishParams(name, filepath, license, nsfw) { +function createPublishParams(name, filePath, license, nsfw) { var publishParams = { "name": name, - "file_path": filepath, + "file_path": filePath, "bid": 0.01, "metadata": { "description": name + " published via spee.ch", @@ -25,7 +26,7 @@ function createPublishParams(name, filepath, license, nsfw) { "author": "spee.ch", "language": "en", "license": license, - "nsfw": (nsfw.toLowerCase() === "true") + "nsfw": nsfw }, "claim_address": walledAddress, "change_address": walledAddress //requires daemon 0.12.2rc1 or above @@ -33,33 +34,41 @@ function createPublishParams(name, filepath, license, nsfw) { return publishParams; } -function deleteTemporaryFile(filepath) { - fs.unlink(filepath, function(err) { +function deleteTemporaryFile(filePath) { + fs.unlink(filePath, function(err) { if (err) throw err; - console.log('successfully deleted ' + filepath); + console.log('successfully deleted ' + filePath); }); } module.exports = { - publish: function(name, filepath, license, nsfw, socket, visitor) { + publish: function(name, filePath, fileType, license, nsfw, socket, visitor) { + nsfw = (nsfw.toLowerCase() === "true"); // update the client socket.emit("publish-status", "Your image is being published (this might take a second)..."); - visitor.event("Publish Route", "Publish Request", filepath).send(); + // send to analytics + visitor.event("Publish Route", "Publish Request", filePath).send(); // create the publish object - var publishParams = createPublishParams(name, filepath, license, nsfw); + var publishParams = createPublishParams(name, filePath, license, nsfw); // get a promise to publish lbryApi.publishClaim(publishParams) .then(function(data){ - visitor.event("Publish Route", "Publish Success", filepath).send(); + visitor.event("Publish Route", "Publish Success", filePath).send(); console.log("publish promise success. Tx info:", data) socket.emit("publish-complete", {name: name, result: data.result}); - deleteTemporaryFile(filepath); + db.File.create({ + name: name, + path: filePath, + file_type: fileType, + claim_id: data.result.claim_id, + nsfw: nsfw, + }); }) .catch(function(error){ - visitor.event("Publish Route", "Publish Failure", filepath).send(); + visitor.event("Publish Route", "Publish Failure", filePath).send(); console.log("error:", error); socket.emit("publish-failure", handlePublishError(error)); - deleteTemporaryFile(filepath); + deleteTemporaryFile(filePath); }); } } \ No newline at end of file diff --git a/models/file.js b/models/file.js new file mode 100644 index 00000000..c5a4dbf1 --- /dev/null +++ b/models/file.js @@ -0,0 +1,27 @@ +module.exports = function(sequelize, DataTypes){ + var File = sequelize.define("File", { + name: { + type: DataTypes.STRING, + allowNull: false, + validate: { + len: [1] + } + }, + path: { + type: DataTypes.STRING + }, + file_type: { + type: DataTypes.STRING + }, + claim_id: { + type: DataTypes.STRING + }, + nsfw: { + type: DataTypes.BOOLEAN, + defaultValue: false + } + }, { + freezeTableName: true + }); + return File; +} \ No newline at end of file diff --git a/models/index.js b/models/index.js new file mode 100644 index 00000000..7d1ffe47 --- /dev/null +++ b/models/index.js @@ -0,0 +1,41 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var Sequelize = require('sequelize'); +var basename = path.basename(module.filename); +var config = require('config'); +var db = {}; + +var connectionUri = config.get('Database.MySqlConnectionUri'); +var sequelize = new Sequelize(connectionUri); + +sequelize + .authenticate() + .then(() => { + console.log('Connection has been established successfully.'); + }) + .catch(err => { + console.error('Unable to connect to the database:', err); + }); + +fs + .readdirSync(__dirname) + .filter(function(file) { + return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); + }) + .forEach(function(file) { + var model = sequelize['import'](path.join(__dirname, file)); + db[model.name] = model; + }); + +Object.keys(db).forEach(function(modelName) { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/package.json b/package.json index ddc14060..0b28aec9 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,9 @@ "config": "^1.26.1", "express": "^4.15.2", "express-handlebars": "^3.0.0", + "mysql2": "^1.3.5", "nodemon": "^1.11.0", + "sequelize": "^4.1.0", "socket.io": "^2.0.1", "socketio-file-upload": "^0.6.0", "universal-analytics": "^0.4.13" diff --git a/routes/sockets-routes.js b/routes/sockets-routes.js index 570268d6..f09f7d65 100644 --- a/routes/sockets-routes.js +++ b/routes/sockets-routes.js @@ -1,4 +1,6 @@ -module.exports = function(app, path, siofu, socketHelpers, ua, googleAnalyticsId) { +var socketHelpers = require('../helpers/socketHelpers.js'); + +module.exports = function(app, path, siofu, hostedContentPath, ua, googleAnalyticsId) { var http = require('http').Server(app); var io = require('socket.io')(http); @@ -8,9 +10,10 @@ module.exports = function(app, path, siofu, socketHelpers, ua, googleAnalyticsId var visitor = ua(googleAnalyticsId, {https: true}); // attach upload listeners var uploader = new siofu(); - uploader.dir = path.join(__dirname, '../../Uploads'); + uploader.dir = hostedContentPath; //path.join(__dirname, '../../Uploads'); uploader.listen(socket); uploader.on("start", function(event){ + // server side test to make sure file is not a bad file type if (/\.exe$/.test(event.file.name)) { uploader.abort(event.file.id, socket); } @@ -20,10 +23,10 @@ module.exports = function(app, path, siofu, socketHelpers, ua, googleAnalyticsId socket.emit("publish-status", event.error) }); uploader.on("saved", function(event){ - console.log("saved " + event.file.name); + console.log("saved ", event.file.name, "deets:", event.file); if (event.file.success){ socket.emit("publish-status", "file upload successfully completed"); - socketHelpers.publish(event.file.meta.name, event.file.pathName, event.file.meta.license, event.file.meta.nsfw, socket, visitor) + socketHelpers.publish(event.file.meta.name, event.file.pathName, event.file.meta.type, event.file.meta.license, event.file.meta.nsfw, socket, visitor) } else { socket.emit("publish-failure", "file uploaded, but with errors") }; diff --git a/server.js b/server.js index c27b7fed..e203a6b5 100644 --- a/server.js +++ b/server.js @@ -9,18 +9,19 @@ var axios = require('axios'); var config = require('config'); var ua = require('universal-analytics'); -var socketHelpers = require('./helpers/socketHelpers.js'); var routeHelpers = require('./helpers/routeHelpers.js'); var lbryApi = require('./helpers/lbryApi.js'); var lbryHelpers = require('./helpers/lbryHelpers.js'); var googleAnalyticsId = config.get('AnalyticsConfig.googleId'); +var hostedContentPath = config.get('Database.DownloadAddress'); // set port var PORT = 3000; - // initialize express app var app = express(); +//require our models for syncing +var db = require("./models"); // make express look in the public directory for assets (css/js/img) app.use(express.static(__dirname + '/public')); @@ -57,10 +58,15 @@ require("./routes/show-routes.js")(app, routeHelpers, lbryHelpers, ua, googleAna require("./routes/serve-routes.js")(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId); require("./routes/home-routes.js")(app); -// wrap the server in socket.io to intercept incoming sockets requests -var http = require("./routes/sockets-routes.js")(app, path, siofu, socketHelpers, ua, googleAnalyticsId); +// require socket.io routes +var http = require("./routes/sockets-routes.js")(app, path, siofu, hostedContentPath, ua, googleAnalyticsId); +// sync sequelize +// wrap the server in socket.io to intercept incoming sockets requests // start server -http.listen(PORT, function() { - console.log("Listening on PORT " + PORT); -}); +db.sequelize.sync({}).then(function(){ + http.listen(PORT, function() { + console.log("Listening on PORT " + PORT); + }); +}) + diff --git a/views/index.handlebars b/views/index.handlebars index 57a4f439..ea81218f 100644 --- a/views/index.handlebars +++ b/views/index.handlebars @@ -132,6 +132,7 @@ event.file.meta.name = name; event.file.meta.license = license; event.file.meta.nsfw = nsfw; + event.file.meta.type = stagedFiles[0].type; // re-set the html in the publish area document.getElementById('publish-active-area').innerHTML = '
'; // start a progress animation From 6f7d9af768164640a29702e88f75470713887bba Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 15 Jun 2017 13:06:35 -0700 Subject: [PATCH 03/10] C:/Program Files/Git/name/claim_id checks local first --- helpers/lbryApi.js | 2 +- helpers/lbryHelpers.js | 58 ++++++++++++++++++++++++++-------------- helpers/socketHelpers.js | 2 ++ routes/serve-routes.js | 25 ++++++++--------- server.js | 5 ++-- 5 files changed, 57 insertions(+), 35 deletions(-) diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index 79d2ce08..68e05c83 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -24,7 +24,7 @@ module.exports = { "method": "get", "params": { "uri": uri, "timeout": 20} }).then(function (getResponse) { - console.log(">> 'get' success"); + console.log(">> 'get' success", getResponse.data); //check to make sure the daemon didn't just time out (or otherwise send an error that appears to be a success response) if (getResponse.data.result.error){ reject(getResponse.data.result.error); diff --git a/helpers/lbryHelpers.js b/helpers/lbryHelpers.js index b4fb8d21..5a5d0b25 100644 --- a/helpers/lbryHelpers.js +++ b/helpers/lbryHelpers.js @@ -1,6 +1,7 @@ var path = require('path'); var axios = require('axios'); var lbryApi = require('./lbryApi'); +var db = require("../models"); function filterForFreePublicClaims(claimsListArray){ //console.log("claims list:", claimsListArray) @@ -98,33 +99,50 @@ module.exports = { }); return deferred; }, - getClaimBasedOnUri: function(uri){ + getClaimBasedOnUri: function(claimName, claimId){ var deferred = new Promise(function (resolve, reject){ + var uri = claimName + "#" + claimId; console.log(">> lbryHelpers >> getClaimBasedOnUri:", uri); - // resolve the claim - lbryApi.resolveUri(uri) - .then(function(resolvedUri){ - //console.log("result >>", resolvedUri) - // check to make sure it is free and public - if (isFreePublicClaim(resolvedUri.result[uri].claim)){ - // promise to get the chosen uri - lbryApi.getClaim(uri) - .then(function(data){ - resolve({ - fileName: data.result.file_name, - directory: data.result.download_directory, - contentType: data.result.metadata.stream.source.contentType - }); + // check locally for the claim + db.File.findOne({where: { claim_id: claimId }}) + .then(function(claim){ + console.log("asset found locally >>", claim) + // if a record is found, return it + if (claim){ + var fileInfo = { + file_name: claim.dataValues.name, + download_path: claim.dataValues.path, + content_type: claim.dataValues.file_type + } + resolve(fileInfo); + // ... otherwise use daemon to retrieve it + } else { + // get the claim info via 'resolve' + lbryApi.resolveUri(uri) + .then(function(resolvedUri){ + // check to make sure it is free and public + if (isFreePublicClaim(resolvedUri.result[uri].claim)){ + // 'get' the claim + lbryApi.getClaim(uri) + .then(function(data){ + resolve({ + file_name: data.result.file_name, + download_path: data.result.download_path, + content_type: data.result.metadata.stream.source.contentType + }); + }).catch(function(error){ + reject(error) + }); + } else { + reject("NO_FREE_PUBLIC_CLAIMS"); + } }).catch(function(error){ reject(error) }); - } else { - reject("NO_FREE_PUBLIC_CLAIMS"); } }).catch(function(error){ - reject(error) - }); - + reject(error); + }) }); return deferred; }, diff --git a/helpers/socketHelpers.js b/helpers/socketHelpers.js index d3aeb387..3caf7042 100644 --- a/helpers/socketHelpers.js +++ b/helpers/socketHelpers.js @@ -62,6 +62,8 @@ module.exports = { file_type: fileType, claim_id: data.result.claim_id, nsfw: nsfw, + }).catch(function(error){ + console.log('an error occurred when writing to the MySQL database. Check the logs.'); }); }) .catch(function(error){ diff --git a/routes/serve-routes.js b/routes/serve-routes.js index ed50f446..6d83a0d4 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -1,14 +1,13 @@ function serveFile(fileInfo, res){ // set default options var options = { - root: fileInfo.directory, headers: { "X-Content-Type-Options": "nosniff", - "Content-Type": fileInfo.contentType + "Content-Type": fileInfo.content_type } }; // adjust default options as needed - switch (fileInfo.contentType){ + switch (fileInfo.content_type){ case "image/jpeg": break; case "image/gif": @@ -23,19 +22,20 @@ function serveFile(fileInfo, res){ break; } // send file - res.status(200).sendFile(fileInfo.fileName, options); + res.status(200).sendFile(fileInfo.download_path, options); } module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId){ // route to fetch one free public claim app.get("/:name/:claim_id", function(req, res){ - ua(googleAnalyticsId, {https: true}).event("Serve Route", "/name/claimId", req.params.name + "/" + req.params.claim_id).send(); - var uri = req.params.name + "#" + req.params.claim_id; - console.log(">> GET request on /" + uri); - // create promise - lbryHelpers.getClaimBasedOnUri(uri) + var routeString = req.params.name + "/" + req.params.claim_id; + // google analytics + ua(googleAnalyticsId, {https: true}).event("Serve Route", "/name/claimId", routeString).send(); + // begin image-serve processes + console.log(">> GET request on /" + routeString); + lbryHelpers.getClaimBasedOnUri(req.params.name, req.params.claim_id) .then(function(fileInfo){ - console.log("/:name/:claim_id success.", fileInfo.fileName); + console.log("/:name/:claim_id success.", fileInfo.file_name); serveFile(fileInfo, res); }).catch(function(error){ console.log("/:name/:claim_id error:", error) @@ -44,12 +44,13 @@ module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId) }); // route to fetch one free public claim app.get("/:name", function(req, res){ + // google analytics ua(googleAnalyticsId, {https: true}).event("Serve Route", "/name", req.params.name).send(); + // begin image-serve processes console.log(">> GET request on /" + req.params.name); - // create promise lbryHelpers.getClaimBasedOnNameOnly(req.params.name) .then(function(fileInfo){ - console.log("/:name success.", fileInfo.fileName); + console.log("/:name success.", fileInfo.file_name); serveFile(fileInfo, res); }).catch(function(error){ console.log("/:name error:", error); diff --git a/server.js b/server.js index e203a6b5..f23ca659 100644 --- a/server.js +++ b/server.js @@ -64,9 +64,10 @@ var http = require("./routes/sockets-routes.js")(app, path, siofu, hostedContent // sync sequelize // wrap the server in socket.io to intercept incoming sockets requests // start server -db.sequelize.sync({}).then(function(){ +db.sequelize.sync({}) +.then(function(){ http.listen(PORT, function() { console.log("Listening on PORT " + PORT); }); -}) +}); From 6b2b397b85de8cda6d10a3e2cfafd6ff13edfec4 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 15 Jun 2017 14:37:19 -0700 Subject: [PATCH 04/10] added local search to /name route --- helpers/lbryHelpers.js | 48 ++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/helpers/lbryHelpers.js b/helpers/lbryHelpers.js index 5a5d0b25..2b1496cf 100644 --- a/helpers/lbryHelpers.js +++ b/helpers/lbryHelpers.js @@ -77,21 +77,41 @@ module.exports = { getClaimBasedOnNameOnly: function(claimName){ var deferred = new Promise(function (resolve, reject){ console.log(">> lbryHelpers >> getClaim BasedOnNameOnly:", claimName); - // promise to get all free public claims + // get all free public claims getAllFreePublicClaims(claimName) .then(function(freePublicClaimList){ - var freePublicClaimUri = freePublicClaimList[0].name + "#" + freePublicClaimList[0].claim_id; - console.log(">> successfully received free public claim URI:", freePublicClaimUri); - // promise to get the chosen uri - lbryApi.getClaim(freePublicClaimUri) - .then(function(data){ - resolve({ - fileName: data.result.file_name, - directory: data.result.download_directory, - contentType: data.result.metadata.stream.source.contentType - }); + var claimName = freePublicClaimList[0].name; + var claimId = freePublicClaimList[0].claim_id; + var freePublicClaimUri = claimName + "#" + claimId; + console.log(">> Decided on public claim URI:", freePublicClaimUri); + // check to see if the file is available locally + db.File.findOne({where: { claim_id: claimId }}) + .then(function(claim){ + console.log("asset found locally >>", claim) + // if a record is found, return it + if (claim){ + var fileInfo = { + file_name: claim.dataValues.name, + download_path: claim.dataValues.path, + content_type: claim.dataValues.file_type + } + resolve(fileInfo); + // ... otherwise use daemon to retrieve it + } else { + // promise to get the chosen uri + lbryApi.getClaim(freePublicClaimUri) + .then(function(data){ + resolve({ + file_name: data.result.file_name, + download_path: data.result.download_path, + content_type: data.result.metadata.stream.source.contentType + }); + }).catch(function(error){ + reject(error) + }); + } }).catch(function(error){ - reject(error) + reject(error); }); }).catch(function(error){ reject(error); @@ -116,7 +136,7 @@ module.exports = { } resolve(fileInfo); // ... otherwise use daemon to retrieve it - } else { + } else { // get the claim info via 'resolve' lbryApi.resolveUri(uri) .then(function(resolvedUri){ @@ -142,7 +162,7 @@ module.exports = { } }).catch(function(error){ reject(error); - }) + }); }); return deferred; }, From 50d65de6a494159d4a09554ac62f86bf6976d347 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 15 Jun 2017 15:03:40 -0700 Subject: [PATCH 05/10] added creation of db record when files are retrieved via daemon --- helpers/lbryApi.js | 14 +++++++++++++- helpers/lbryHelpers.js | 9 ++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index 68e05c83..4d14d7d3 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -1,4 +1,5 @@ var axios = require('axios'); +var db = require("../models"); module.exports = { publishClaim: function(publishParams){ @@ -33,7 +34,18 @@ module.exports = { /* note: put in a check to make sure we do not resolve until the download is actually complete (response.data.completed === true) */ - resolve(getResponse.data); + // save a record of the file to the Files table + db.File.create({ + name: getResponse.data.result.file_name, + path: getResponse.data.result.download_path, + file_type: getResponse.data.result.mime_type, + claim_id: getResponse.data.result.claim_id, + nsfw: getResponse.data.result.metadata.stream.metadata.nsfw, + }).catch(function(error){ + console.log('an error occurred when writing to the MySQL database. Check the logs.'); + }); + // resolve the promise + resolve(getResponse.data); //to do: return the result }).catch(function(getUriError){ console.log(">> 'get' error"); // reject the promise with an error message diff --git a/helpers/lbryHelpers.js b/helpers/lbryHelpers.js index 2b1496cf..9f431ed0 100644 --- a/helpers/lbryHelpers.js +++ b/helpers/lbryHelpers.js @@ -87,7 +87,7 @@ module.exports = { // check to see if the file is available locally db.File.findOne({where: { claim_id: claimId }}) .then(function(claim){ - console.log("asset found locally >>", claim) + console.log(">> Asset was found locally"); // if a record is found, return it if (claim){ var fileInfo = { @@ -126,15 +126,14 @@ module.exports = { // check locally for the claim db.File.findOne({where: { claim_id: claimId }}) .then(function(claim){ - console.log("asset found locally >>", claim) + console.log(">> Asset was found locally"); // if a record is found, return it if (claim){ - var fileInfo = { + resolve({ file_name: claim.dataValues.name, download_path: claim.dataValues.path, content_type: claim.dataValues.file_type - } - resolve(fileInfo); + }); // ... otherwise use daemon to retrieve it } else { // get the claim info via 'resolve' From 99413abdf6b8ed993b830965e5ac9efaa305b0f1 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 15 Jun 2017 15:56:40 -0700 Subject: [PATCH 06/10] added 'outpoint' to Files model' --- helpers/lbryApi.js | 6 ++--- helpers/socketHelpers.js | 1 + models/file.js | 50 ++++++++++++++++++++++------------------ 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index 4d14d7d3..9bca7521 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -26,11 +26,10 @@ module.exports = { "params": { "uri": uri, "timeout": 20} }).then(function (getResponse) { console.log(">> 'get' success", getResponse.data); - //check to make sure the daemon didn't just time out (or otherwise send an error that appears to be a success response) + //check to make sure the daemon didn't just time out if (getResponse.data.result.error){ reject(getResponse.data.result.error); } - // resolve the promise with the download path for the claim we got /* note: put in a check to make sure we do not resolve until the download is actually complete (response.data.completed === true) */ @@ -40,12 +39,13 @@ module.exports = { path: getResponse.data.result.download_path, file_type: getResponse.data.result.mime_type, claim_id: getResponse.data.result.claim_id, + outpoint: getResponse.data.result.outpoint, nsfw: getResponse.data.result.metadata.stream.metadata.nsfw, }).catch(function(error){ console.log('an error occurred when writing to the MySQL database. Check the logs.'); }); // resolve the promise - resolve(getResponse.data); //to do: return the result + resolve(getResponse.data); }).catch(function(getUriError){ console.log(">> 'get' error"); // reject the promise with an error message diff --git a/helpers/socketHelpers.js b/helpers/socketHelpers.js index 3caf7042..520479dc 100644 --- a/helpers/socketHelpers.js +++ b/helpers/socketHelpers.js @@ -61,6 +61,7 @@ module.exports = { path: filePath, file_type: fileType, claim_id: data.result.claim_id, + outpoint: getResponse.data.result.outpoint, nsfw: nsfw, }).catch(function(error){ console.log('an error occurred when writing to the MySQL database. Check the logs.'); diff --git a/models/file.js b/models/file.js index c5a4dbf1..0e6bf6db 100644 --- a/models/file.js +++ b/models/file.js @@ -1,27 +1,31 @@ module.exports = function(sequelize, DataTypes){ - var File = sequelize.define("File", { - name: { - type: DataTypes.STRING, - allowNull: false, - validate: { - len: [1] - } - }, - path: { - type: DataTypes.STRING - }, - file_type: { - type: DataTypes.STRING - }, - claim_id: { - type: DataTypes.STRING - }, - nsfw: { - type: DataTypes.BOOLEAN, - defaultValue: false - } - }, { + var File = sequelize.define("File", { + name: { + type: DataTypes.STRING, + allowNull: false + }, + path: { + type: DataTypes.STRING, + allowNull: false + }, + file_type: { + type: DataTypes.STRING, + }, + claim_id: { + type: DataTypes.STRING, + allowNull: false + }, + outpoint: { + type: DataTypes.STRING, + allowNull: false + }, + nsfw: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + } + }, { freezeTableName: true }); - return File; + return File; } \ No newline at end of file From 2f3f2784b530f4ec3af37dbcec0bd081bde3c41a Mon Sep 17 00:00:00 2001 From: bill bittner Date: Fri, 16 Jun 2017 10:07:31 -0700 Subject: [PATCH 07/10] refactored mysql calls db fields --- helpers/lbryApi.js | 46 ++++++++++++++++++++------------ helpers/lbryHelpers.js | 30 ++++++++------------- helpers/socketHelpers.js | 18 +++---------- models/file.js | 18 ++++++++----- routes/serve-routes.js | 7 ++--- views/partials/topBar.handlebars | 2 +- 6 files changed, 60 insertions(+), 61 deletions(-) diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index 9bca7521..d161f297 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -2,15 +2,26 @@ var axios = require('axios'); var db = require("../models"); module.exports = { - publishClaim: function(publishParams){ + publishClaim: function(publishParams, fileType){ var deferred = new Promise(function(resolve, reject){ console.log(">> lbryApi >> publishClaim:", publishParams); axios.post('http://localhost:5279/lbryapi', { "method": "publish", "params": publishParams }).then(function (response) { - console.log(">> 'publish' success"); - resolve(response.data); + console.log(">> 'publish' success", response); + db.File.create({ + name: publishParams.name, + claim_id: response.data.result.claim_id, + outpoint: response.data.result.outpoint, + file_name: "test", + file_path: publishParams.filePath, + file_type: fileType, + nsfw: nsfw, + }).catch(function(error){ + console.log('An error occurred when writing to the MySQL database:', error); + }); + resolve(response.data.result); }).catch(function(error){ console.log(">> 'publish' error"); reject(error); @@ -24,32 +35,33 @@ module.exports = { axios.post('http://localhost:5279/lbryapi', { "method": "get", "params": { "uri": uri, "timeout": 20} - }).then(function (getResponse) { - console.log(">> 'get' success", getResponse.data); + }).then(function (response) { + console.log(">> 'get' success", response.data); //check to make sure the daemon didn't just time out - if (getResponse.data.result.error){ - reject(getResponse.data.result.error); + if (response.data.result.error){ + reject(response.data.result.error); } /* note: put in a check to make sure we do not resolve until the download is actually complete (response.data.completed === true) */ // save a record of the file to the Files table db.File.create({ - name: getResponse.data.result.file_name, - path: getResponse.data.result.download_path, - file_type: getResponse.data.result.mime_type, - claim_id: getResponse.data.result.claim_id, - outpoint: getResponse.data.result.outpoint, - nsfw: getResponse.data.result.metadata.stream.metadata.nsfw, + name: response.data.result.name, + claim_id: response.data.result.claim_id, + outpoint: response.data.result.outpoint, + file_name: response.data.result.file_name, + file_path: response.data.result.download_path, + file_type: response.data.result.mime_type, + nsfw: response.data.result.metadata.stream.metadata.nsfw, }).catch(function(error){ - console.log('an error occurred when writing to the MySQL database. Check the logs.'); + console.log('An error occurred when writing to the MySQL database:', error); }); // resolve the promise - resolve(getResponse.data); - }).catch(function(getUriError){ + resolve(response.data.result); + }).catch(function(error){ console.log(">> 'get' error"); // reject the promise with an error message - reject(getUriError); + reject(error); return; }); }); diff --git a/helpers/lbryHelpers.js b/helpers/lbryHelpers.js index 9f431ed0..0da1b692 100644 --- a/helpers/lbryHelpers.js +++ b/helpers/lbryHelpers.js @@ -90,21 +90,17 @@ module.exports = { console.log(">> Asset was found locally"); // if a record is found, return it if (claim){ - var fileInfo = { - file_name: claim.dataValues.name, - download_path: claim.dataValues.path, - content_type: claim.dataValues.file_type - } - resolve(fileInfo); + console.log("claim.dataValues", claim.dataValues); + resolve(claim.dataValues); // ... otherwise use daemon to retrieve it } else { // promise to get the chosen uri lbryApi.getClaim(freePublicClaimUri) - .then(function(data){ + .then(function(result){ resolve({ - file_name: data.result.file_name, - download_path: data.result.download_path, - content_type: data.result.metadata.stream.source.contentType + file_name: result.file_name, + file_path: result.download_path, + file_type: result.mime_type }); }).catch(function(error){ reject(error) @@ -129,11 +125,7 @@ module.exports = { console.log(">> Asset was found locally"); // if a record is found, return it if (claim){ - resolve({ - file_name: claim.dataValues.name, - download_path: claim.dataValues.path, - content_type: claim.dataValues.file_type - }); + resolve(claim.dataValues); // ... otherwise use daemon to retrieve it } else { // get the claim info via 'resolve' @@ -143,11 +135,11 @@ module.exports = { if (isFreePublicClaim(resolvedUri.result[uri].claim)){ // 'get' the claim lbryApi.getClaim(uri) - .then(function(data){ + .then(function(result){ resolve({ - file_name: data.result.file_name, - download_path: data.result.download_path, - content_type: data.result.metadata.stream.source.contentType + file_name: result.file_name, + file_path: result.download_path, + file_type: result.mime_type }); }).catch(function(error){ reject(error) diff --git a/helpers/socketHelpers.js b/helpers/socketHelpers.js index 520479dc..430aa683 100644 --- a/helpers/socketHelpers.js +++ b/helpers/socketHelpers.js @@ -51,21 +51,11 @@ module.exports = { // create the publish object var publishParams = createPublishParams(name, filePath, license, nsfw); // get a promise to publish - lbryApi.publishClaim(publishParams) - .then(function(data){ + lbryApi.publishClaim(publishParams, fileType) + .then(function(result){ visitor.event("Publish Route", "Publish Success", filePath).send(); - console.log("publish promise success. Tx info:", data) - socket.emit("publish-complete", {name: name, result: data.result}); - db.File.create({ - name: name, - path: filePath, - file_type: fileType, - claim_id: data.result.claim_id, - outpoint: getResponse.data.result.outpoint, - nsfw: nsfw, - }).catch(function(error){ - console.log('an error occurred when writing to the MySQL database. Check the logs.'); - }); + console.log("publish promise success. Tx info:", result) + socket.emit("publish-complete", {name: name, result: result}); }) .catch(function(error){ visitor.event("Publish Route", "Publish Failure", filePath).send(); diff --git a/models/file.js b/models/file.js index 0e6bf6db..3e696558 100644 --- a/models/file.js +++ b/models/file.js @@ -4,13 +4,6 @@ module.exports = function(sequelize, DataTypes){ type: DataTypes.STRING, allowNull: false }, - path: { - type: DataTypes.STRING, - allowNull: false - }, - file_type: { - type: DataTypes.STRING, - }, claim_id: { type: DataTypes.STRING, allowNull: false @@ -19,6 +12,17 @@ module.exports = function(sequelize, DataTypes){ type: DataTypes.STRING, allowNull: false }, + file_name: { + type: DataTypes.STRING, + allowNull: false + }, + file_path: { + type: DataTypes.STRING, + allowNull: false + }, + file_type: { + type: DataTypes.STRING, + }, nsfw: { type: DataTypes.BOOLEAN, allowNull: false, diff --git a/routes/serve-routes.js b/routes/serve-routes.js index 6d83a0d4..fbb27eb2 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -3,11 +3,11 @@ function serveFile(fileInfo, res){ var options = { headers: { "X-Content-Type-Options": "nosniff", - "Content-Type": fileInfo.content_type + "Content-Type": fileInfo.file_type } }; // adjust default options as needed - switch (fileInfo.content_type){ + switch (fileInfo.file_type){ case "image/jpeg": break; case "image/gif": @@ -22,7 +22,7 @@ function serveFile(fileInfo, res){ break; } // send file - res.status(200).sendFile(fileInfo.download_path, options); + res.status(200).sendFile(fileInfo.file_path, options); } module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId){ @@ -50,6 +50,7 @@ module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId) console.log(">> GET request on /" + req.params.name); lbryHelpers.getClaimBasedOnNameOnly(req.params.name) .then(function(fileInfo){ + console.log("/:name success.", fileInfo.file_name); serveFile(fileInfo, res); }).catch(function(error){ diff --git a/views/partials/topBar.handlebars b/views/partials/topBar.handlebars index 16095f68..27cd80ab 100644 --- a/views/partials/topBar.handlebars +++ b/views/partials/topBar.handlebars @@ -4,7 +4,7 @@
- +

Spee.ch

From 5c40a5ccd08ec48578ca45ec97d02600b51681ea Mon Sep 17 00:00:00 2001 From: bill bittner Date: Fri, 16 Jun 2017 12:29:02 -0700 Subject: [PATCH 08/10] added outpoint check for local files --- helpers/lbryApi.js | 2 +- helpers/lbryHelpers.js | 109 +++++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index d161f297..d4c27f81 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -91,7 +91,7 @@ module.exports = { "params": { "uri": uri} }).then(function(response){ console.log(">> 'resolve' success"); - resolve(response.data); + resolve(response.data.result); }).catch(function(error){ console.log(">> 'resolve' error"); reject(error); diff --git a/helpers/lbryHelpers.js b/helpers/lbryHelpers.js index 0da1b692..1cf4d540 100644 --- a/helpers/lbryHelpers.js +++ b/helpers/lbryHelpers.js @@ -73,6 +73,19 @@ function getAllFreePublicClaims(claimName){ return deferred; } +function getClaimAndHandleResponse(claimUri, resolve, reject){ + lbryApi.getClaim(claimUri) + .then(function(result){ + resolve({ + file_name: result.file_name, + file_path: result.download_path, + file_type: result.mime_type + }); + }).catch(function(error){ + reject(error) + }); +} + module.exports = { getClaimBasedOnNameOnly: function(claimName){ var deferred = new Promise(function (resolve, reject){ @@ -80,31 +93,28 @@ module.exports = { // get all free public claims getAllFreePublicClaims(claimName) .then(function(freePublicClaimList){ - var claimName = freePublicClaimList[0].name; - var claimId = freePublicClaimList[0].claim_id; - var freePublicClaimUri = claimName + "#" + claimId; - console.log(">> Decided on public claim URI:", freePublicClaimUri); + console.log(">> Decided on public claim id:", freePublicClaimList[0].claim_id); + var freePublicClaimOutpoint = freePublicClaimList[0].txid + ":" + freePublicClaimList[0].nout; + var freePublicClaimUri = freePublicClaimList[0].name + "#" + freePublicClaimList[0].claim_id; // check to see if the file is available locally - db.File.findOne({where: { claim_id: claimId }}) + db.File.findOne({where: { claim_id: freePublicClaimList[0].claim_id }}) .then(function(claim){ - console.log(">> Asset was found locally"); - // if a record is found, return it + // if a found locally... if (claim){ - console.log("claim.dataValues", claim.dataValues); - resolve(claim.dataValues); + console.log(">> A matching claim_id was found locally"); + // if the outpoint's match return it + if (claim.dataValues.outpoint === freePublicClaimOutpoint){ + console.log(">> Local outpoint matched"); + resolve(claim.dataValues); + // if the outpoint's don't match, fetch updated claim + } else { + console.log(">> local outpoint did not match"); + getClaimAndHandleResponse(freePublicClaimUri, resolve, reject); + } // ... otherwise use daemon to retrieve it } else { - // promise to get the chosen uri - lbryApi.getClaim(freePublicClaimUri) - .then(function(result){ - resolve({ - file_name: result.file_name, - file_path: result.download_path, - file_type: result.mime_type - }); - }).catch(function(error){ - reject(error) - }); + // 'get' the claim + getClaimAndHandleResponse(freePublicClaimUri, resolve, reject) } }).catch(function(error){ reject(error); @@ -119,45 +129,46 @@ module.exports = { var deferred = new Promise(function (resolve, reject){ var uri = claimName + "#" + claimId; console.log(">> lbryHelpers >> getClaimBasedOnUri:", uri); - // check locally for the claim - db.File.findOne({where: { claim_id: claimId }}) - .then(function(claim){ - console.log(">> Asset was found locally"); - // if a record is found, return it - if (claim){ - resolve(claim.dataValues); - // ... otherwise use daemon to retrieve it - } else { - // get the claim info via 'resolve' - lbryApi.resolveUri(uri) - .then(function(resolvedUri){ - // check to make sure it is free and public - if (isFreePublicClaim(resolvedUri.result[uri].claim)){ + // resolve the Uri + lbryApi.resolveUri(uri) // note: use 'spread' and make parallel with db.File.findOne() + .then(function(result){ // note should just be 'result' returned. + // get the outpoint + var resolvedOutpoint = result[uri].claim.txid + ":" + result[uri].claim.nout; + // check locally for the claim + db.File.findOne({where: { claim_id: claimId }}) + .then(function(claim){ + // if a found locally... + if (claim){ + console.log(">> A matching claim_id was found locally"); + // if the outpoint's match return it + if (claim.dataValues.outpoint === resolvedOutpoint){ + console.log(">> Local outpoint matched"); + resolve(claim.dataValues); + // if the outpoint's don't match, fetch updated claim + } else { + console.log(">> Local outpoint did not match"); + getClaimAndHandleResponse(uri, resolve, reject); + } + // ... otherwise use daemon to retrieve it + } else { + // check to make sure it is free and public (note: no need for another resolve?) + if (isFreePublicClaim(result[uri].claim)){ // 'get' the claim - lbryApi.getClaim(uri) - .then(function(result){ - resolve({ - file_name: result.file_name, - file_path: result.download_path, - file_type: result.mime_type - }); - }).catch(function(error){ - reject(error) - }); + getClaimAndHandleResponse(uri, resolve, reject); } else { reject("NO_FREE_PUBLIC_CLAIMS"); } - }).catch(function(error){ - reject(error) - }); - } + } + }).catch(function(error){ + reject(error) + }); }).catch(function(error){ reject(error); }); }); return deferred; }, - getAllClaims: function(claimName){ // note: work in progress + getAllClaims: function(claimName){ return getAllFreePublicClaims(claimName); } } From 6d9523ff395b8aa7578f446044cb2ce903e2a4ac Mon Sep 17 00:00:00 2001 From: bill bittner Date: Fri, 16 Jun 2017 17:48:51 -0700 Subject: [PATCH 09/10] refactored /helpers into /helpers and /controllers --- .../publishController.js | 19 +---- .../serveController.js | 82 ++----------------- controllers/showController.js | 7 ++ helpers/functions/getAllFreePublicClaims.js | 61 ++++++++++++++ helpers/functions/isFreePublicClaim.js | 11 +++ .../errorHandlers.js} | 13 ++- helpers/{ => libraries}/lbryApi.js | 39 +++++---- routes/api-routes.js | 12 +-- routes/serve-routes.js | 14 ++-- routes/show-routes.js | 13 +-- routes/sockets-routes.js | 8 +- server.js | 12 +-- 12 files changed, 148 insertions(+), 143 deletions(-) rename helpers/socketHelpers.js => controllers/publishController.js (78%) rename helpers/lbryHelpers.js => controllers/serveController.js (56%) create mode 100644 controllers/showController.js create mode 100644 helpers/functions/getAllFreePublicClaims.js create mode 100644 helpers/functions/isFreePublicClaim.js rename helpers/{routeHelpers.js => libraries/errorHandlers.js} (64%) rename helpers/{ => libraries}/lbryApi.js (75%) diff --git a/helpers/socketHelpers.js b/controllers/publishController.js similarity index 78% rename from helpers/socketHelpers.js rename to controllers/publishController.js index 430aa683..03564076 100644 --- a/helpers/socketHelpers.js +++ b/controllers/publishController.js @@ -1,20 +1,10 @@ var fs = require('fs'); -var lbryApi = require('./lbryApi.js'); +var lbryApi = require('../helpers/libraries/lbryApi.js'); var config = require('config'); -var db = require("../models"); +var errorHandlers = require("../helpers/libraries/errorHandlers.js"); var walledAddress = config.get('WalletConfig.lbryAddress'); -function handlePublishError(error) { - if (error.code === "ECONNREFUSED"){ - return "Connection refused. The daemon may not be running."; - } else if (error.response.data.error) { - return error.response.data.error; - } else { - return error; - }; -} - function createPublishParams(name, filePath, license, nsfw) { var publishParams = { "name": name, @@ -26,7 +16,7 @@ function createPublishParams(name, filePath, license, nsfw) { "author": "spee.ch", "language": "en", "license": license, - "nsfw": nsfw + "nsfw": (nsfw.toLowerCase() === "true") }, "claim_address": walledAddress, "change_address": walledAddress //requires daemon 0.12.2rc1 or above @@ -43,7 +33,6 @@ function deleteTemporaryFile(filePath) { module.exports = { publish: function(name, filePath, fileType, license, nsfw, socket, visitor) { - nsfw = (nsfw.toLowerCase() === "true"); // update the client socket.emit("publish-status", "Your image is being published (this might take a second)..."); // send to analytics @@ -60,7 +49,7 @@ module.exports = { .catch(function(error){ visitor.event("Publish Route", "Publish Failure", filePath).send(); console.log("error:", error); - socket.emit("publish-failure", handlePublishError(error)); + socket.emit("publish-failure", errorHandlers.handlePublishError(error)); deleteTemporaryFile(filePath); }); } diff --git a/helpers/lbryHelpers.js b/controllers/serveController.js similarity index 56% rename from helpers/lbryHelpers.js rename to controllers/serveController.js index 1cf4d540..324cfd6c 100644 --- a/helpers/lbryHelpers.js +++ b/controllers/serveController.js @@ -1,77 +1,8 @@ -var path = require('path'); -var axios = require('axios'); -var lbryApi = require('./lbryApi'); +var lbryApi = require('../helpers/libraries/lbryApi.js'); var db = require("../models"); -function filterForFreePublicClaims(claimsListArray){ - //console.log("claims list:", claimsListArray) - if (!claimsListArray) { - return null; - }; - var freePublicClaims = claimsListArray.filter(function(claim){ - if (!claim.value){ - return false; - } - return (((claim.value.stream.metadata.license.indexOf('Public Domain') != -1) || (claim.value.stream.metadata.license.indexOf('Creative Commons') != -1)) && - (!claim.value.stream.metadata.fee || claim.value.stream.metadata.fee === 0)); - }); - return freePublicClaims; -} - -function isFreePublicClaim(claim){ - console.log(">> isFreePublicClaim? claim:", claim); - if ((claim.value.stream.metadata.license === 'Public Domain' || claim.value.stream.metadata.license === 'Creative Commons') && - (!claim.value.stream.metadata.fee || claim.value.stream.metadata.fee.amount === 0)) { - return true; - } else { - return false; - } -} - -function orderTopClaims(claimsListArray){ - console.log(">> orderTopClaims"); - claimsListArray.sort(function(claimA, claimB){ - if (claimA.amount === claimB.amount){ - return (claimA.height > claimB.height); - } else { - return (claimA.amount < claimB.amount); - } - }) - return claimsListArray; -} - -function getAllFreePublicClaims(claimName){ - var deferred = new Promise(function(resolve, reject){ - // make a call to the daemon to get the claims list - lbryApi.getClaimsList(claimName) - .then(function(data){ - var claimsList = data.result.claims; - console.log(">> Number of claims:", claimsList.length) - // return early if no claims were found - if (claimsList.length === 0){ - reject("NO_CLAIMS"); - console.log("exiting due to lack of claims"); - return; - } - // filter the claims to return only free, public claims - var freePublicClaims = filterForFreePublicClaims(claimsList); - // return early if no free, public claims were found - if (!freePublicClaims || (freePublicClaims.length === 0)){ - reject("NO_FREE_PUBLIC_CLAIMS"); - console.log("exiting due to lack of free or public claims"); - return; - } - // order the claims - var orderedPublicClaims = orderTopClaims(freePublicClaims); - // resolve the promise - resolve(orderedPublicClaims); - }).catch(function(error){ - console.log(">> 'claim_list' error"); - reject(error); - }); - }); - return deferred; -} +var getAllFreePublicClaims = require("../helpers/functions/getAllFreePublicClaims.js"); +var isFreePublicClaim = require("../helpers/functions/isFreePublicClaim.js"); function getClaimAndHandleResponse(claimUri, resolve, reject){ lbryApi.getClaim(claimUri) @@ -87,7 +18,7 @@ function getClaimAndHandleResponse(claimUri, resolve, reject){ } module.exports = { - getClaimBasedOnNameOnly: function(claimName){ + getClaimByName: function(claimName){ var deferred = new Promise(function (resolve, reject){ console.log(">> lbryHelpers >> getClaim BasedOnNameOnly:", claimName); // get all free public claims @@ -125,7 +56,7 @@ module.exports = { }); return deferred; }, - getClaimBasedOnUri: function(claimName, claimId){ + getClaimByClaimId: function(claimName, claimId){ var deferred = new Promise(function (resolve, reject){ var uri = claimName + "#" + claimId; console.log(">> lbryHelpers >> getClaimBasedOnUri:", uri); @@ -167,8 +98,5 @@ module.exports = { }); }); return deferred; - }, - getAllClaims: function(claimName){ - return getAllFreePublicClaims(claimName); } } diff --git a/controllers/showController.js b/controllers/showController.js new file mode 100644 index 00000000..04d81f0e --- /dev/null +++ b/controllers/showController.js @@ -0,0 +1,7 @@ +var getAllFreePublicClaims = require("../helpers/functions/getAllFreePublicClaims.js"); + +module.exports = { + getAllClaims: function(claimName){ + return getAllFreePublicClaims(claimName); // to-do: does this need to be returned? + } +} \ No newline at end of file diff --git a/helpers/functions/getAllFreePublicClaims.js b/helpers/functions/getAllFreePublicClaims.js new file mode 100644 index 00000000..f9e1f0d6 --- /dev/null +++ b/helpers/functions/getAllFreePublicClaims.js @@ -0,0 +1,61 @@ +var isFreePublicClaim = require("./isFreePublicClaim.js"); +var lbryApi = require('../libraries/lbryApi.js'); + +function filterForFreePublicClaims(claimsListArray){ + //console.log("claims list:", claimsListArray) + if (!claimsListArray) { + return null; + }; + var freePublicClaims = claimsListArray.filter(function(claim){ + if (!claim.value){ + return false; + } + return (isFreePublicClaim(claim)); + }); + return freePublicClaims; +} + +function orderTopClaims(claimsListArray){ + console.log(">> orderTopClaims"); + claimsListArray.sort(function(claimA, claimB){ + if (claimA.amount === claimB.amount){ + return (claimA.height > claimB.height); + } else { + return (claimA.amount < claimB.amount); + } + }) + return claimsListArray; +} + +module.exports = function(claimName){ + var deferred = new Promise(function(resolve, reject){ + // make a call to the daemon to get the claims list + lbryApi.getClaimsList(claimName) + .then(function(result){ + var claimsList = result.claims; + console.log(">> Number of claims:", claimsList.length) + // return early if no claims were found + if (claimsList.length === 0){ + reject("NO_CLAIMS"); + console.log("exiting due to lack of claims"); + return; + } + // filter the claims to return only free, public claims + var freePublicClaims = filterForFreePublicClaims(claimsList); + // return early if no free, public claims were found + if (!freePublicClaims || (freePublicClaims.length === 0)){ + reject("NO_FREE_PUBLIC_CLAIMS"); + console.log("exiting due to lack of free or public claims"); + return; + } + // order the claims + var orderedPublicClaims = orderTopClaims(freePublicClaims); + // resolve the promise + resolve(orderedPublicClaims); + }).catch(function(error){ + console.log(">> 'claim_list' error"); + reject(error); + }); + }); + return deferred; +} \ No newline at end of file diff --git a/helpers/functions/isFreePublicClaim.js b/helpers/functions/isFreePublicClaim.js new file mode 100644 index 00000000..3915b564 --- /dev/null +++ b/helpers/functions/isFreePublicClaim.js @@ -0,0 +1,11 @@ + +module.exports = function(claim){ + console.log(">> isFreePublicClaim? claim:", claim); + if (((claim.value.stream.metadata.license.indexOf("Public Domain") != -1 ) || (claim.value.stream.metadata.license.indexOf("Creative Commons") != -1 )) + && + (!claim.value.stream.metadata.fee || claim.value.stream.metadata.fee.amount === 0)) { + return true; + } else { + return false; + } +}; \ No newline at end of file diff --git a/helpers/routeHelpers.js b/helpers/libraries/errorHandlers.js similarity index 64% rename from helpers/routeHelpers.js rename to helpers/libraries/errorHandlers.js index f3f43814..031e1ebc 100644 --- a/helpers/routeHelpers.js +++ b/helpers/libraries/errorHandlers.js @@ -1,5 +1,3 @@ -var path = require('path'); - module.exports = { handleRequestError: function(error, res) { if ((error === "NO_CLAIMS") || (error === "NO_FREE_PUBLIC_CLAIMS")){ @@ -11,5 +9,14 @@ module.exports = { } else { res.status(400).send(error.toString()); }; - } + }, + handlePublishError: function(error) { + if (error.code === "ECONNREFUSED"){ + return "Connection refused. The daemon may not be running."; + } else if (error.response.data.error) { + return error.response.data.error; + } else { + return error; + }; +} } diff --git a/helpers/lbryApi.js b/helpers/libraries/lbryApi.js similarity index 75% rename from helpers/lbryApi.js rename to helpers/libraries/lbryApi.js index d4c27f81..56962725 100644 --- a/helpers/lbryApi.js +++ b/helpers/libraries/lbryApi.js @@ -1,5 +1,5 @@ var axios = require('axios'); -var db = require("../models"); +var db = require("../../models"); module.exports = { publishClaim: function(publishParams, fileType){ @@ -9,19 +9,20 @@ module.exports = { "method": "publish", "params": publishParams }).then(function (response) { - console.log(">> 'publish' success", response); + console.log(">> 'publish' success"); + var result = response.data.result; db.File.create({ name: publishParams.name, - claim_id: response.data.result.claim_id, - outpoint: response.data.result.outpoint, + claim_id: result.claim_id, + outpoint: result.txid + ":" + result.nout, file_name: "test", - file_path: publishParams.filePath, + file_path: publishParams.file_path, file_type: fileType, - nsfw: nsfw, + nsfw: publishParams.metadata.nsfw, }).catch(function(error){ console.log('An error occurred when writing to the MySQL database:', error); }); - resolve(response.data.result); + resolve(result); }).catch(function(error){ console.log(">> 'publish' error"); reject(error); @@ -36,7 +37,7 @@ module.exports = { "method": "get", "params": { "uri": uri, "timeout": 20} }).then(function (response) { - console.log(">> 'get' success", response.data); + console.log(">> 'get' success"); //check to make sure the daemon didn't just time out if (response.data.result.error){ reject(response.data.result.error); @@ -45,24 +46,22 @@ module.exports = { note: put in a check to make sure we do not resolve until the download is actually complete (response.data.completed === true) */ // save a record of the file to the Files table + var result = response.data.result db.File.create({ - name: response.data.result.name, - claim_id: response.data.result.claim_id, - outpoint: response.data.result.outpoint, - file_name: response.data.result.file_name, - file_path: response.data.result.download_path, - file_type: response.data.result.mime_type, - nsfw: response.data.result.metadata.stream.metadata.nsfw, + name: result.name, + claim_id: result.claim_id, + outpoint: result.outpoint, + file_name: result.file_name, + file_path: result.download_path, + file_type: result.mime_type, + nsfw: result.metadata.stream.metadata.nsfw, }).catch(function(error){ console.log('An error occurred when writing to the MySQL database:', error); }); - // resolve the promise - resolve(response.data.result); + resolve(result); }).catch(function(error){ console.log(">> 'get' error"); - // reject the promise with an error message reject(error); - return; }); }); return deferred; @@ -75,7 +74,7 @@ module.exports = { params: { name: claimName } }).then(function (response) { console.log(">> 'claim_list' success"); - resolve(response.data); + resolve(response.data.result); }).catch(function(error){ console.log(">> 'claim_list' error"); reject(error); diff --git a/routes/api-routes.js b/routes/api-routes.js index 5eb306a0..449f5b50 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -1,15 +1,17 @@ +var errorHandlers = require("../helpers/libraries/errorHandlers.js"); +var lbryApi = require("../helpers/libraries/lbryApi.js"); -module.exports = function(app, routeHelpers, lbryApi){ +module.exports = function(app){ // route to run a claim_list request on the daemon app.get("/api/claim_list/:claim", function(req, res){ lbryApi.getClaimsList(req.params.claim) - .then(function(orderedFreePublicImages){ + .then(function(claimsList){ console.log("/api/claim_list/:claim success."); - res.status(200).json(orderedFreePublicImages); + res.status(200).json(claimsList); }) .catch(function(error){ console.log("/api/claim_list/:name error:", error); - routeHelpers.handleRequestError(error, res); + errorHandlers.handleRequestError(error, res); }); }); // route to run a resolve request on the daemon @@ -19,7 +21,7 @@ module.exports = function(app, routeHelpers, lbryApi){ console.log("/api/resolve/:claim success."); res.status(200).json(resolvedUri); }).catch(function(error){ - routeHelpers.handleRequestError(error, res); + errorHandlers.handleRequestError(error, res); }); }); diff --git a/routes/serve-routes.js b/routes/serve-routes.js index fbb27eb2..933121d9 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -1,3 +1,6 @@ +var errorHandlers = require("../helpers/libraries/errorHandlers.js"); +var serveController = require("../controllers/serveController.js"); + function serveFile(fileInfo, res){ // set default options var options = { @@ -25,7 +28,7 @@ function serveFile(fileInfo, res){ res.status(200).sendFile(fileInfo.file_path, options); } -module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId){ +module.exports = function(app, ua, googleAnalyticsId){ // route to fetch one free public claim app.get("/:name/:claim_id", function(req, res){ var routeString = req.params.name + "/" + req.params.claim_id; @@ -33,13 +36,13 @@ module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId) ua(googleAnalyticsId, {https: true}).event("Serve Route", "/name/claimId", routeString).send(); // begin image-serve processes console.log(">> GET request on /" + routeString); - lbryHelpers.getClaimBasedOnUri(req.params.name, req.params.claim_id) + serveController.getClaimByClaimId(req.params.name, req.params.claim_id) .then(function(fileInfo){ console.log("/:name/:claim_id success.", fileInfo.file_name); serveFile(fileInfo, res); }).catch(function(error){ console.log("/:name/:claim_id error:", error) - routeHelpers.handleRequestError(error, res); + errorHandlers.handleRequestError(error, res); }); }); // route to fetch one free public claim @@ -48,14 +51,13 @@ module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId) ua(googleAnalyticsId, {https: true}).event("Serve Route", "/name", req.params.name).send(); // begin image-serve processes console.log(">> GET request on /" + req.params.name); - lbryHelpers.getClaimBasedOnNameOnly(req.params.name) + serveController.getClaimByName(req.params.name) .then(function(fileInfo){ - console.log("/:name success.", fileInfo.file_name); serveFile(fileInfo, res); }).catch(function(error){ console.log("/:name error:", error); - routeHelpers.handleRequestError(error, res); + errorHandlers.handleRequestError(error, res); }); }); } \ No newline at end of file diff --git a/routes/show-routes.js b/routes/show-routes.js index 2a809d62..623f7c60 100644 --- a/routes/show-routes.js +++ b/routes/show-routes.js @@ -1,11 +1,14 @@ +var errorHandlers = require("../helpers/libraries/errorHandlers.js"); +var showController = require("../controllers/serveController.js"); -module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId){ - // route to fetch all free public claims +module.exports = function(app, ua, googleAnalyticsId){ + // route to fetch all free public claims app.get("/:name/all", function(req, res){ console.log(">> GET request on /" + req.params.name + "/all"); + // google analytics ua(googleAnalyticsId, {https: true}).event("Show Routes", "/name/all", req.params.name + "/all").send(); - // create promise - lbryHelpers.getAllClaims(req.params.name) + // fetch all free public claims + showController.getAllClaims(req.params.name) .then(function(orderedFreePublicClaims){ console.log("/:name/all success."); res.status(200).render('allClaims', { claims: orderedFreePublicClaims }); @@ -13,7 +16,7 @@ module.exports = function(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId) }) .catch(function(error){ console.log("/:name/all error:", error); - routeHelpers.handleRequestError(error, res); + errorHandlers.handleRequestError(error, res); }) }); } diff --git a/routes/sockets-routes.js b/routes/sockets-routes.js index f09f7d65..98997ee8 100644 --- a/routes/sockets-routes.js +++ b/routes/sockets-routes.js @@ -1,6 +1,6 @@ -var socketHelpers = require('../helpers/socketHelpers.js'); +var publishController = require('../controllers/publishController.js'); -module.exports = function(app, path, siofu, hostedContentPath, ua, googleAnalyticsId) { +module.exports = function(app, siofu, hostedContentPath, ua, googleAnalyticsId) { var http = require('http').Server(app); var io = require('socket.io')(http); @@ -10,7 +10,7 @@ module.exports = function(app, path, siofu, hostedContentPath, ua, googleAnalyti var visitor = ua(googleAnalyticsId, {https: true}); // attach upload listeners var uploader = new siofu(); - uploader.dir = hostedContentPath; //path.join(__dirname, '../../Uploads'); + uploader.dir = hostedContentPath; uploader.listen(socket); uploader.on("start", function(event){ // server side test to make sure file is not a bad file type @@ -26,7 +26,7 @@ module.exports = function(app, path, siofu, hostedContentPath, ua, googleAnalyti console.log("saved ", event.file.name, "deets:", event.file); if (event.file.success){ socket.emit("publish-status", "file upload successfully completed"); - socketHelpers.publish(event.file.meta.name, event.file.pathName, event.file.meta.type, event.file.meta.license, event.file.meta.nsfw, socket, visitor) + publishController.publish(event.file.meta.name, event.file.pathName, event.file.meta.type, event.file.meta.license, event.file.meta.nsfw, socket, visitor) } else { socket.emit("publish-failure", "file uploaded, but with errors") }; diff --git a/server.js b/server.js index f23ca659..158b9fb7 100644 --- a/server.js +++ b/server.js @@ -9,10 +9,6 @@ var axios = require('axios'); var config = require('config'); var ua = require('universal-analytics'); -var routeHelpers = require('./helpers/routeHelpers.js'); -var lbryApi = require('./helpers/lbryApi.js'); -var lbryHelpers = require('./helpers/lbryHelpers.js'); - var googleAnalyticsId = config.get('AnalyticsConfig.googleId'); var hostedContentPath = config.get('Database.DownloadAddress'); @@ -53,13 +49,13 @@ app.engine('handlebars', hbs.engine); app.set('view engine', 'handlebars'); // require express routes -require("./routes/api-routes.js")(app, routeHelpers, lbryApi); -require("./routes/show-routes.js")(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId); -require("./routes/serve-routes.js")(app, routeHelpers, lbryHelpers, ua, googleAnalyticsId); +require("./routes/api-routes.js")(app); +require("./routes/show-routes.js")(app, ua, googleAnalyticsId); +require("./routes/serve-routes.js")(app, ua, googleAnalyticsId); require("./routes/home-routes.js")(app); // require socket.io routes -var http = require("./routes/sockets-routes.js")(app, path, siofu, hostedContentPath, ua, googleAnalyticsId); +var http = require("./routes/sockets-routes.js")(app, siofu, hostedContentPath, ua, googleAnalyticsId); // sync sequelize // wrap the server in socket.io to intercept incoming sockets requests From d7a35bed780cb4954466e61b866405b91529e7e5 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Fri, 16 Jun 2017 19:31:31 -0700 Subject: [PATCH 10/10] fixed publish issues --- config/default.json | 2 +- config/development.json | 3 ++- config/production.json | 2 +- config/test.json | 2 +- controllers/publishController.js | 21 +++++++++++---------- controllers/showController.js | 2 +- helpers/functions/isFreePublicClaim.js | 2 +- helpers/libraries/lbryApi.js | 6 +++--- routes/show-routes.js | 2 +- routes/sockets-routes.js | 5 +++-- server.js | 2 +- views/allClaims.handlebars | 2 +- 12 files changed, 27 insertions(+), 24 deletions(-) diff --git a/config/default.json b/config/default.json index cabec5e8..5691ff63 100644 --- a/config/default.json +++ b/config/default.json @@ -7,6 +7,6 @@ }, "Database": { "MySqlConnectionUri": "none", - "DownloadAddress": "C:\\lbry\\speech\\hosted_content" + "PublishUploadPath": "none" } } \ No newline at end of file diff --git a/config/development.json b/config/development.json index b1bac598..a673979c 100644 --- a/config/development.json +++ b/config/development.json @@ -6,6 +6,7 @@ "googleId": "UA-100747990-1" }, "Database": { - "MySqlConnectionUri": "none" + "MySqlConnectionUri": "none", + "PublishUploadPath": "C:\\lbry\\speech\\hosted_content" } } \ No newline at end of file diff --git a/config/production.json b/config/production.json index c2ced7e9..4f815ce7 100644 --- a/config/production.json +++ b/config/production.json @@ -7,6 +7,6 @@ }, "Database": { "MySqlConnectionUri": "none", - "DownloadAddress": "~/Downloads/" + "PublishUploadPath": "~/Downloads/" } } \ No newline at end of file diff --git a/config/test.json b/config/test.json index 7c18d6eb..8d0379c2 100644 --- a/config/test.json +++ b/config/test.json @@ -7,6 +7,6 @@ }, "Database": { "MySqlConnectionUri": "none", - "DownloadAddress": "~/Downloads/" + "PublishUploadPath": "~/Downloads/" } } \ No newline at end of file diff --git a/controllers/publishController.js b/controllers/publishController.js index 03564076..9bf8f5e4 100644 --- a/controllers/publishController.js +++ b/controllers/publishController.js @@ -5,21 +5,22 @@ var errorHandlers = require("../helpers/libraries/errorHandlers.js"); var walledAddress = config.get('WalletConfig.lbryAddress'); -function createPublishParams(name, filePath, license, nsfw) { +function createPublishParams(claim, filePath, license, nsfw) { + console.log("nsfw:", nsfw, typeof nsfw); var publishParams = { - "name": name, + "name": claim, "file_path": filePath, "bid": 0.01, "metadata": { - "description": name + " published via spee.ch", - "title": name, + "description": claim + " published via spee.ch", + "title": claim, "author": "spee.ch", "language": "en", "license": license, - "nsfw": (nsfw.toLowerCase() === "true") + "nsfw": (nsfw.toLowerCase() === "on") }, "claim_address": walledAddress, - "change_address": walledAddress //requires daemon 0.12.2rc1 or above + "change_address": walledAddress }; return publishParams; } @@ -32,19 +33,19 @@ function deleteTemporaryFile(filePath) { } module.exports = { - publish: function(name, filePath, fileType, license, nsfw, socket, visitor) { + publish: function(claim, fileName, filePath, fileType, license, nsfw, socket, visitor) { // 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 - var publishParams = createPublishParams(name, filePath, license, nsfw); + var publishParams = createPublishParams(claim, filePath, license, nsfw); // get a promise to publish - lbryApi.publishClaim(publishParams, fileType) + lbryApi.publishClaim(publishParams, fileName, fileType) .then(function(result){ visitor.event("Publish Route", "Publish Success", filePath).send(); console.log("publish promise success. Tx info:", result) - socket.emit("publish-complete", {name: name, result: result}); + socket.emit("publish-complete", {name: claim, result: result}); }) .catch(function(error){ visitor.event("Publish Route", "Publish Failure", filePath).send(); diff --git a/controllers/showController.js b/controllers/showController.js index 04d81f0e..78adc0f9 100644 --- a/controllers/showController.js +++ b/controllers/showController.js @@ -2,6 +2,6 @@ var getAllFreePublicClaims = require("../helpers/functions/getAllFreePublicClaim module.exports = { getAllClaims: function(claimName){ - return getAllFreePublicClaims(claimName); // to-do: does this need to be returned? + return getAllFreePublicClaims(claimName); } } \ No newline at end of file diff --git a/helpers/functions/isFreePublicClaim.js b/helpers/functions/isFreePublicClaim.js index 3915b564..5103635e 100644 --- a/helpers/functions/isFreePublicClaim.js +++ b/helpers/functions/isFreePublicClaim.js @@ -1,6 +1,6 @@ module.exports = function(claim){ - console.log(">> isFreePublicClaim? claim:", claim); + console.log(">> check: isFreePublicClaim?"); if (((claim.value.stream.metadata.license.indexOf("Public Domain") != -1 ) || (claim.value.stream.metadata.license.indexOf("Creative Commons") != -1 )) && (!claim.value.stream.metadata.fee || claim.value.stream.metadata.fee.amount === 0)) { diff --git a/helpers/libraries/lbryApi.js b/helpers/libraries/lbryApi.js index 56962725..82466a51 100644 --- a/helpers/libraries/lbryApi.js +++ b/helpers/libraries/lbryApi.js @@ -2,20 +2,20 @@ var axios = require('axios'); var db = require("../../models"); module.exports = { - publishClaim: function(publishParams, fileType){ + publishClaim: function(publishParams, fileName, fileType){ var deferred = new Promise(function(resolve, reject){ console.log(">> lbryApi >> publishClaim:", publishParams); axios.post('http://localhost:5279/lbryapi', { "method": "publish", "params": publishParams }).then(function (response) { - console.log(">> 'publish' success"); + console.log(">> 'publish' success", response); var result = response.data.result; db.File.create({ name: publishParams.name, claim_id: result.claim_id, outpoint: result.txid + ":" + result.nout, - file_name: "test", + file_name: fileName, file_path: publishParams.file_path, file_type: fileType, nsfw: publishParams.metadata.nsfw, diff --git a/routes/show-routes.js b/routes/show-routes.js index 623f7c60..a705271a 100644 --- a/routes/show-routes.js +++ b/routes/show-routes.js @@ -1,5 +1,5 @@ var errorHandlers = require("../helpers/libraries/errorHandlers.js"); -var showController = require("../controllers/serveController.js"); +var showController = require("../controllers/showController.js"); module.exports = function(app, ua, googleAnalyticsId){ // route to fetch all free public claims diff --git a/routes/sockets-routes.js b/routes/sockets-routes.js index 98997ee8..4a476f02 100644 --- a/routes/sockets-routes.js +++ b/routes/sockets-routes.js @@ -23,12 +23,13 @@ module.exports = function(app, siofu, hostedContentPath, ua, googleAnalyticsId) socket.emit("publish-status", event.error) }); uploader.on("saved", function(event){ - console.log("saved ", event.file.name, "deets:", event.file); + console.log("uploaded ", event.file.name); if (event.file.success){ socket.emit("publish-status", "file upload successfully completed"); - publishController.publish(event.file.meta.name, event.file.pathName, event.file.meta.type, event.file.meta.license, event.file.meta.nsfw, socket, visitor) + publishController.publish(event.file.meta.name, event.file.name, event.file.pathName, event.file.meta.type, event.file.meta.license, event.file.meta.nsfw, socket, visitor) } else { socket.emit("publish-failure", "file uploaded, but with errors") + // to-do: remove the file }; }); // handle disconnect diff --git a/server.js b/server.js index 158b9fb7..c56bbadd 100644 --- a/server.js +++ b/server.js @@ -10,7 +10,7 @@ var config = require('config'); var ua = require('universal-analytics'); var googleAnalyticsId = config.get('AnalyticsConfig.googleId'); -var hostedContentPath = config.get('Database.DownloadAddress'); +var hostedContentPath = config.get('Database.PublishUploadPath'); // set port var PORT = 3000; diff --git a/views/allClaims.handlebars b/views/allClaims.handlebars index 28abbad4..75b5eb20 100644 --- a/views/allClaims.handlebars +++ b/views/allClaims.handlebars @@ -8,7 +8,7 @@

claim_id: {{this.claim_id}}

-

direct link here

+

direct link here

author: {{this.value.stream.metadata.author}}

description: {{this.value.stream.metadata.description}}

license: {{this.value.stream.metadata.license}}