From 238f2af63fe5d0e0f1eccfc491d31e089ff01a6d Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 1 Aug 2017 18:58:13 -0700 Subject: [PATCH] rebuilt the /claim_id/claim route (no update yet) --- controllers/serveController.js | 174 +++++++++++++++++------ helpers/functions/isFreePublicClaim.js | 3 +- helpers/libraries/serveHelpers.js | 138 +++++++++--------- routes/serve-routes.js | 38 +++-- views/partials/asset.handlebars | 2 +- views/partials/assetInfo.handlebars | 10 +- views/partials/publish.handlebars | 7 +- views/partials/trendingAssets.handlebars | 2 +- views/showLite.handlebars | 2 +- 9 files changed, 239 insertions(+), 137 deletions(-) diff --git a/controllers/serveController.js b/controllers/serveController.js index 06b8fe70..502cca99 100644 --- a/controllers/serveController.js +++ b/controllers/serveController.js @@ -5,15 +5,139 @@ const getAllFreePublicClaims = require('../helpers/functions/getAllFreePublicCla const isFreePublicClaim = require('../helpers/functions/isFreePublicClaim.js'); const serveHelpers = require('../helpers/libraries/serveHelpers.js'); +function checkForLocalAssetByShortUrl (channel, name) { + return new Promise((resolve, reject) => { + db.File + .findOne({where: { name, channel }}) + .then(result => { + if (result) { + resolve(result.dataValues); + } else { + resolve(null); + } + }) + .catch(error => { + reject(error); + }); + }); +} + +function checkForLocalAssetByChannel (channelName, name) { + return new Promise((resolve, reject) => { + + }); +} + +function checkForLocalAssetByClaimId (claimId, name) { + return new Promise((resolve, reject) => { + db.File + .findOne({where: { name, claimId }}) + .then(result => { + if (result) { + resolve(result.dataValues); + } else { + resolve(null); + } + }) + .catch(error => { + reject(error); + }); + }); +} + +function formatGetResultsToFileInfo ({ name, claim_id, outpoint, file_name, download_path, mime_type, metadata }) { + return { + name, + claimId : claim_id, + outpoint, + fileName: file_name, + filePath: download_path, + fileType: mime_type, + nsfw : metadata.stream.metadata.nsfw, + }; +} + module.exports = { getAssetByChannel (channelName, name) { - + return new Promise((resolve, reject) => { + // check locally for claim + checkForLocalAssetByChannel(channelName, name) + .then(result => { + // if not found locally, make a get request + if (!result) { + resolve(); + // if a result was found, resolve the result + } else { + resolve(result); + } + }) + .catch(error => { + reject(error); + }); + }); }, getAssetByShortUrl (shortUrl, name) { - + return new Promise((resolve, reject) => { + // check locally for claim + checkForLocalAssetByShortUrl(shortUrl, name) + .then(result => { + // if not found locally, make a get request + if (!result) { + resolve(); + // if a result was found, resolve the result + } else { + resolve(result); + } + }) + .catch(error => { + reject(error); + }); + }); }, getAssetByClaimId (fullClaimId, name) { - + return new Promise((resolve, reject) => { + // 1. check locally for claim + checkForLocalAssetByClaimId(fullClaimId, name) + .then(dataValues => { + // 2. if a result was found, resolve the result + if (dataValues) { + logger.debug('found a local file for this claimId'); + // trigger an update check for the file + serveHelpers.updateFileIfNeeded(dataValues.name, dataValues.claimId, dataValues.outpoint, dataValues.height); + // resolve promise + resolve(dataValues); + // 2. if not found locally, make a get request + } else { + logger.debug('no local file for this claimId'); + // 3. resolve the claim + lbryApi.resolveUri(`${name}#${fullClaimId}`) + .then(resolveResult => { + // if the claim is free and public, then get it + if (resolveResult.claim && isFreePublicClaim(resolveResult.claim)) { + lbryApi.getClaim(`${name}#${fullClaimId}`) + .then(getResult => { + let fileInfo = formatGetResultsToFileInfo(getResult); + fileInfo['address'] = resolveResult.claim.address; + fileInfo['height'] = resolveResult.claim.height; + resolve(fileInfo); + }) + .catch(error => { + reject(error); + }); + // if not, resolve with no claims + } else { + resolve(null); + } + }) + .catch(error => { + reject(error); + }); + } + }) + .catch(error => { + reject(error); + }); + }); }, serveClaimByName (claimName) { const deferred = new Promise((resolve, reject) => { @@ -56,49 +180,7 @@ module.exports = { }); return deferred; }, - serveClaimByClaimId (name, claimId) { - logger.debug(`serving claim "${name}" with claimid "${claimId}"`); - const deferred = new Promise((resolve, reject) => { - // 1. check locally for the claim - const uri = `${name}#${claimId}`; - db.File - .findOne({ where: { name, claimId } }) - .then(result => { - // 3. if a match is found locally, serve that claim - if (result) { - logger.debug('local result found'); - // return the data for the file to be served - resolve(result.dataValues); - serveHelpers.updateFileIfNeeded(uri, result.dataValues.outpoint, result.dataValues.outpoint); - // 3. if a match was not found locally, use the daemon to retrieve the claim & return the db data once it is created - } else { - logger.debug('no local result found'); - lbryApi - .resolveUri(uri) - .then(result => { - if (result.claim && isFreePublicClaim(result.claim)) { // check to see if the claim is free & public - // get claim and serve - serveHelpers - .getClaimAndReturnResponse(uri, result.claim.address, result.claim.height) - .then(result => { - resolve(result.dataValues); - }) - .catch(error => reject(error)); - } else { - logger.debug('Resolve did not return a free, public claim'); - resolve(null); - } - }) - .catch(error => { - logger.debug('resolve returned an error'); - reject(error); - }); - } - }) - .catch(error => reject(error)); - }); - return deferred; - }, + serveClaimByShortUrl (name, shortUrl) { const deferred = new Promise((resolve, reject) => { let uri; diff --git a/helpers/functions/isFreePublicClaim.js b/helpers/functions/isFreePublicClaim.js index c58dccee..d501e736 100644 --- a/helpers/functions/isFreePublicClaim.js +++ b/helpers/functions/isFreePublicClaim.js @@ -2,10 +2,11 @@ const logger = require('winston'); const licenses = ['Creative Commons', 'Public Domain', 'CC Attribution-NonCommercial 4.0 International']; module.exports = ({ value }) => { - logger.debug('checking isFreePublicClaim ?'); if ((licenses.includes(value.stream.metadata.license)) && (!value.stream.metadata.fee || value.stream.metadata.fee.amount === 0)) { + logger.debug('checking isFreePublicClaim...', true); return true; } else { + logger.debug('checking isFreePublicClaim...', false); return false; } }; diff --git a/helpers/libraries/serveHelpers.js b/helpers/libraries/serveHelpers.js index 70dc5571..363d777b 100644 --- a/helpers/libraries/serveHelpers.js +++ b/helpers/libraries/serveHelpers.js @@ -1,7 +1,6 @@ const logger = require('winston'); const db = require('../../models'); const lbryApi = require('./lbryApi'); -const { postToStats } = require('../controllers/statsController.js'); function determineShortUrl (claimId, claimList) { logger.debug('determining short url based on claim id and claim list'); @@ -60,39 +59,39 @@ function checkLocalDbForClaims (name, shortUrl) { }); } -function getClaimAndUpdate (uri, address, height) { - // 1. get the claim - lbryApi - .getClaim(uri) - .then(({ name, claim_id, outpoint, file_name, download_path, mime_type, metadata }) => { - logger.debug(' Get returned outpoint: ', outpoint); - // 2. update the entry in db - db.File - .update({ - outpoint, - height, // note: height is coming from the 'resolve', not 'get'. - address, // note: address is coming from the 'resolve', not 'get'. - fileName: file_name, - filePath: download_path, - fileType: mime_type, - nsfw : metadata.stream.metadata.nsfw, - }, { - where: { - name, - claimId: claim_id, - }, - }) - .then(result => { - logger.debug('successfully updated mysql record', result); - }) - .catch(error => { - logger.error('sequelize error', error); - }); - }) - .catch(error => { - logger.error(`error while getting claim for ${uri} >> `, error); - }); -} +// function getClaimAndUpdate (uri, address, height) { +// // 1. get the claim +// lbryApi +// .getClaim(uri) +// .then(({ name, claim_id, outpoint, file_name, download_path, mime_type, metadata }) => { +// logger.debug(' Get returned outpoint: ', outpoint); +// // 2. update the entry in db +// db.File +// .update({ +// outpoint, +// height, // note: height is coming from the 'resolve', not 'get'. +// address, // note: address is coming from the 'resolve', not 'get'. +// fileName: file_name, +// filePath: download_path, +// fileType: mime_type, +// nsfw : metadata.stream.metadata.nsfw, +// }, { +// where: { +// name, +// claimId: claim_id, +// }, +// }) +// .then(result => { +// logger.debug('successfully updated mysql record', result); +// }) +// .catch(error => { +// logger.error('sequelize error', error); +// }); +// }) +// .catch(error => { +// logger.error(`error while getting claim for ${uri} >> `, error); +// }); +// } module.exports = { serveFile ({ fileName, fileType, filePath }, res) { @@ -119,12 +118,10 @@ module.exports = { // send the file res.status(200).sendFile(filePath, options); }, - showFile (originalUrl, ip, fileInfo, res) { - postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + showFile (fileInfo, res) { res.status(200).render('show', { layout: 'show', fileInfo }); }, - showFileLite (originalUrl, ip, fileInfo, res) { - postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + showFileLite (fileInfo, res) { res.status(200).render('showLite', { layout: 'show', fileInfo }); }, getClaimIdByShortUrl (name, shortUrl) { @@ -187,38 +184,39 @@ module.exports = { determineShortUrl (claimId, claimList) { return determineShortUrl(claimId, claimList); }, - updateFileIfNeeded (uri, localOutpoint, localHeight) { - logger.debug(`Initiating resolve to check outpoint for ${uri}`); - // 1. resolve claim - lbryApi - .resolveUri(uri) - .then(result => { - // check to make sure the result is a claim - if (!result.claim) { - logger.debug('resolve did not return a claim'); - return; - } - // logger.debug('resolved result:', result); - const resolvedOutpoint = `${result.claim.txid}:${result.claim.nout}`; - const resolvedHeight = result.claim.height; - const resolvedAddress = result.claim.address; - logger.debug('database outpoint:', localOutpoint); - logger.debug('resolved outpoint:', resolvedOutpoint); - // 2. if the outpoint's match, no further work needed - if (localOutpoint === resolvedOutpoint) { - logger.debug('local outpoint matched'); - // 2. if the outpoints don't match, check the height - } else if (localHeight > resolvedHeight) { - logger.debug('local height was greater than resolved height'); - // 2. get the resolved claim - } else { - logger.debug(`local outpoint did not match for ${uri}. Initiating update.`); - getClaimAndUpdate(uri, resolvedAddress, resolvedHeight); - } - }) - .catch(error => { - logger.error(error); - }); + updateFileIfNeeded (name, claimId, localOutpoint, localHeight) { + // const uri = `${name}#${claimId}`; + // logger.debug(`Initiating resolve to check outpoint for ${uri}`); + // // 1. resolve claim + // lbryApi + // .resolveUri(uri) + // .then(result => { + // // check to make sure the result is a claim + // if (!result.claim) { + // logger.debug('resolve did not return a claim'); + // return; + // } + // // logger.debug('resolved result:', result); + // const resolvedOutpoint = `${result.claim.txid}:${result.claim.nout}`; + // const resolvedHeight = result.claim.height; + // const resolvedAddress = result.claim.address; + // logger.debug('database outpoint:', localOutpoint); + // logger.debug('resolved outpoint:', resolvedOutpoint); + // // 2. if the outpoint's match, no further work needed + // if (localOutpoint === resolvedOutpoint) { + // logger.debug('local outpoint matched'); + // // 2. if the outpoints don't match, check the height + // } else if (localHeight > resolvedHeight) { + // logger.debug('local height was greater than resolved height'); + // // 2. get the resolved claim + // } else { + // logger.debug(`local outpoint did not match for ${uri}. Initiating update.`); + // getClaimAndUpdate(uri, resolvedAddress, resolvedHeight); + // } + // }) + // .catch(error => { + // logger.error(error); + // }); }, getClaimAndHandleResponse (uri, address, height, resolve, reject) { lbryApi diff --git a/routes/serve-routes.js b/routes/serve-routes.js index 09975957..db027dce 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -1,6 +1,7 @@ +const logger = require('winston'); const { serveFile, showFile, showFileLite } = require('../helpers/libraries/serveHelpers.js'); const { getAssetByChannel, getAssetByShortUrl, getAssetByClaimId } = require('../controllers/serveController.js'); -const logger = require('winston'); +const { postToStats } = require('../controllers/statsController.js'); const SERVE = 'SERVE'; const SHOW = 'SHOW'; @@ -36,46 +37,61 @@ module.exports = (app) => { channelName = identifier.substring(1); logger.debug('channel name =', channelName); claimType = CHANNEL; - } else if (identifier.length < 40) { + } else if (identifier.length === 40) { fullClaimId = identifier; logger.debug('full claim id =', fullClaimId); claimType = CLAIMID; - } else { + } else if (identifier.length < 40) { shortUrl = identifier; logger.debug('short url =', shortUrl); claimType = SHORTURL; + } else { + logger.error('that url does not compute'); + res.send('that url is invalid'); + return; }; // parse the name let method; let desiredExtension; - if (name.lastIndexOf('.') === -1) { + if (name.indexOf('.') !== -1) { method = SERVE; if (headers['accept'] && headers['accept'].split(',').includes('text/html')) { method = SHOWLITE; } + desiredExtension = name.substring(name.indexOf('.')); + name = name.substring(0, name.indexOf('.')); + logger.debug('file extension =', desiredExtension); } else { method = SHOW; if (headers['accept'] && !headers['accept'].split(',').includes('text/html')) { method = SERVE; } - desiredExtension = name.substring(name.lastIndexOf('.')); - name = name.substring(0, name.lastIndexOf('.')); - logger.debug('file extension =', desiredExtension); } logger.debug('claim name = ', name); logger.debug('method =', method); getAsset(claimType, channelName, shortUrl, fullClaimId, name) - .then(result => { + .then(fileInfo => { + // add file extension to the file info + fileInfo['fileExt'] = fileInfo.fileName.substring(fileInfo.fileName.lastIndexOf('.')); + // test logging + logger.debug(fileInfo); + // serve or show + if (!fileInfo) { + res.status(200).render('noClaims'); + return; + } switch (method) { case SERVE: - serveFile(result, res); + serveFile(fileInfo, res); break; case SHOWLITE: - showFileLite(result, res); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + showFileLite(fileInfo, res); break; case SHOW: - showFile(result, res); + postToStats('show', originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); + showFile(fileInfo, res); break; default: logger.error('I did not recognize that method'); diff --git a/views/partials/asset.handlebars b/views/partials/asset.handlebars index 26482b5a..9bf493a1 100644 --- a/views/partials/asset.handlebars +++ b/views/partials/asset.handlebars @@ -1,6 +1,6 @@
{{!-- link to show route for asset--}} {{!-- html text for embedding asset--}} @@ -28,9 +28,9 @@
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}} - + {{else}} - + {{/ifConditional}}
@@ -41,7 +41,7 @@ Markdown
- + {{/ifConditional}} diff --git a/views/partials/publish.handlebars b/views/partials/publish.handlebars index a8d7b2ed..b127f53e 100644 --- a/views/partials/publish.handlebars +++ b/views/partials/publish.handlebars @@ -20,7 +20,12 @@
diff --git a/views/partials/trendingAssets.handlebars b/views/partials/trendingAssets.handlebars index 9c7999e5..599d671d 100644 --- a/views/partials/trendingAssets.handlebars +++ b/views/partials/trendingAssets.handlebars @@ -5,7 +5,7 @@
{{#each trendingAssets}} {{#unless this.nsfw}} - + {{#ifConditional this.fileType '===' 'video/mp4'}}