From b6de2affb6caf1910e1a2a660cf12494dc07ee02 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 18 Jul 2017 22:05:34 -0700 Subject: [PATCH] added functions for retreiving short url and full claim id --- controllers/serveController.js | 58 ++++++------ helpers/libraries/lbryApi.js | 1 + helpers/libraries/serveHelpers.js | 135 +++++++++++++++++----------- routes/serve-routes.js | 4 +- routes/show-routes.js | 3 +- views/partials/assetInfo.handlebars | 8 +- 6 files changed, 120 insertions(+), 89 deletions(-) diff --git a/controllers/serveController.js b/controllers/serveController.js index 847109ec..98b97e32 100644 --- a/controllers/serveController.js +++ b/controllers/serveController.js @@ -3,10 +3,10 @@ const db = require('../models'); const logger = require('winston'); const getAllFreePublicClaims = require('../helpers/functions/getAllFreePublicClaims.js'); const isFreePublicClaim = require('../helpers/functions/isFreePublicClaim.js'); -const { validateClaimId } = require('../helpers/libraries/serveHelpers.js'); +const { getClaimIdandShortUrl } = require('../helpers/libraries/serveHelpers.js'); -function updateFileIfNeeded (uri, claimName, claimId, localOutpoint, localHeight) { - logger.debug(`Initiating resolve to check outpoint for ${claimName}:${claimId}.`); +function updateFileIfNeeded (uri, localOutpoint, localHeight) { + logger.debug(`Initiating resolve to check outpoint for ${uri}`); // 1. resolve claim lbryApi .resolveUri(uri) @@ -117,7 +117,7 @@ function getClaimAndReturnResponse (uri, address, height) { .getClaim(uri) .then(({ name, claim_id, outpoint, file_name, download_path, mime_type, metadata }) => { // create entry in the db - logger.silly(`creating new File record`); + logger.silly(`Creating new File record`); db.File .create({ name, @@ -131,15 +131,16 @@ function getClaimAndReturnResponse (uri, address, height) { nsfw : metadata.stream.metadata.nsfw, }) .then(result => { - logger.debug('successfully created File record'); + logger.debug('Successfully created File record'); resolve(result); // note: result.dataValues ? }) .catch(error => { - logger.error('sequelize create error', error); + logger.debug('db.File.create error'); reject(error); }); }) .catch(error => { + logger.debug('lbryApi.getClaim error'); reject(error); }); }); @@ -171,7 +172,7 @@ module.exports = { // serve the file resolve(claim.dataValues); // trigger update if needed - updateFileIfNeeded(uri, name, claimId, claim.dataValues.outpoint, claim.dataValues.height); + updateFileIfNeeded(uri, claim.dataValues.outpoint, claim.dataValues.height); // 3. otherwise use daemon to retrieve it } else { // get the claim and serve it @@ -179,7 +180,6 @@ module.exports = { } }) .catch(error => { - logger.error('sequelize error', error); reject(error); }); }) @@ -189,50 +189,48 @@ module.exports = { }); return deferred; }, - getClaimByClaimId (name, claimId) { + getClaimByClaimId (name, providedClaimId) { const deferred = new Promise((resolve, reject) => { let uri; + let shortUrl; // 1. validate the claim id & retrieve the full claim id if needed - validateClaimId(name, claimId) - .then(validClaimId => { + getClaimIdandShortUrl(name, providedClaimId) + .then(({ claimId, shortUrl }) => { // 2. check locally for the claim - logger.debug('valid claim id:', validClaimId); - uri = `${name}#${validClaimId}`; - return db.File.findOne({ where: { name, claimId: validClaimId } }); + uri = `${name}#${claimId}`; + return db.File.findOne({ where: { name, claimId } }); }) .then(result => { // 3. if a match is found locally, serve that claim if (result) { - logger.debug('Result found in File table'); // return the data for the file to be served + result.dataValues['shortUrl'] = shortUrl; resolve(result.dataValues); // update the file, as needed - updateFileIfNeeded(uri, name, claimId, result.dataValues.outpoint, result.dataValues.outpoint); + 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 result found in File table'); lbryApi .resolveUri(uri) .then(result => { - if (!result.claim) { // check to make sure the result is a claim - logger.debug('resolve did not return a claim'); - resolve(null); - } - if (isFreePublicClaim(result.claim)) { // check to see if the claim is free & public + if (result.claim && isFreePublicClaim(result.claim)) { // check to see if the claim is free & public // get claim and serve - resolve(getClaimAndReturnResponse(uri, result.claim.address, result.claim.height)); + getClaimAndReturnResponse(uri, result.claim.address, result.claim.height) + .then(result => { + logger.debug('returned'); + result.dataValues['shortUrl'] = shortUrl; + resolve(result.dataValues); + }) + .catch(error => reject(error)); } else { - resolve(null); + logger.debug('Resolve did not return a free, public claim'); + resolve(null, null); } }) - .catch(error => { - reject(error); - }); + .catch(error => reject(error)); } }) - .catch(error => { - reject(error); - }); + .catch(error => reject(error)); }); return deferred; }, diff --git a/helpers/libraries/lbryApi.js b/helpers/libraries/lbryApi.js index c46d56e2..8b2a2514 100644 --- a/helpers/libraries/lbryApi.js +++ b/helpers/libraries/lbryApi.js @@ -59,6 +59,7 @@ module.exports = { resolve(data.result); }) .catch(error => { + logger.debug("axios.post 'get' error"); reject(error); }); }); diff --git a/helpers/libraries/serveHelpers.js b/helpers/libraries/serveHelpers.js index e5398785..0dda7b36 100644 --- a/helpers/libraries/serveHelpers.js +++ b/helpers/libraries/serveHelpers.js @@ -2,6 +2,65 @@ const logger = require('winston'); // const db = require('../../models'); const { getClaimsList } = require('./lbryApi'); +function getClaimIdByShortUrl (name, shortUrl) { + const deferred = new Promise((resolve, reject) => { + getClaimsList(name) + .then(({ claims }) => { + const regex = new RegExp(`^${shortUrl}`); + logger.debug('regex:', regex); + const filteredClaimsList = claims.filter(claim => { + return regex.test(claim.claim_id); + }); + logger.debug('filtered claims list', filteredClaimsList); + switch (filteredClaimsList.length) { + case 0: + reject(new Error('That is an invalid short url')); + break; + case 1: + resolve(filteredClaimsList[0].claim_id); + break; + default: + const sortedClaimsList = filteredClaimsList.sort((a, b) => { + return a.height > b.height; + }); + resolve(sortedClaimsList[0].claim_id); + break; + } + }) + .catch(error => { + reject(error); + }); + }); + return deferred; +} + +function getShortUrlByClaimId (name, claimId) { + const deferred = new Promise((resolve, reject) => { + // get a list of all the claims + getClaimsList(name) + // find the smallest possible unique url for this claim + .then(({ claims }) => { + let shortUrl = claimId.substring(0, 1); + let i = 1; + claims = claims.filter(claim => { // filter out this exact claim id + return claim.claim_id !== claimId; + }); + while (claims.length !== 0) { // filter out matching claims until none or left + shortUrl = claimId.substring(0, i); + claims = claims.filter(claim => { + return (claim.claim_id.substring(0, i) === shortUrl); + }); + i++; + } + resolve(shortUrl); + }) + .catch(error => { + reject(error); + }); + }); + return deferred; +} + module.exports = { serveFile ({ fileName, fileType, filePath }, res) { logger.info(`serving file ${fileName}`); @@ -30,63 +89,37 @@ module.exports = { // send the file res.status(200).sendFile(filePath, options); }, - validateClaimId (name, claimId) { + getClaimIdandShortUrl (name, url) { const deferred = new Promise((resolve, reject) => { - logger.debug('claim id length:', claimId.length); - // see if claim id is the full 40 characters - if (claimId.length === 40) { - logger.debug('Full 40-character claim id was provided.'); - resolve(claimId); - // if the claim id is shorter than 40, check the db for the full claim id - } else if (claimId.length < 40) { - getClaimsList(name) - .then(({ claims }) => { - const regex = new RegExp(`^${claimId}`); - logger.debug('regex:', regex); - const filteredClaimsList = claims.filter(claim => { - return regex.test(claim.claim_id); - }); - logger.debug('filtered claims list', filteredClaimsList); - switch (filteredClaimsList.length) { - case 0: - reject(new Error('That is an invalid short url')); - break; - case 1: - resolve(filteredClaimsList[0].claim_id); - break; - default: - const sortedClaimsList = filteredClaimsList.sort((a, b) => { - return a.height > b.height; - }); - resolve(sortedClaimsList[0].claim_id); - break; - } + let claimId; + let shortUrl; + logger.debug('claim url length:', url.length); + // if claim id is full 40 chars, retrieve the shortest possible url + if (url.length === 40) { + getShortUrlByClaimId(name, url) + .then(result => { + claimId = url; + shortUrl = result; + resolve({ claimId, shortUrl }); + }) + .catch(error => { + reject(error); + }); + // if the claim id is shorter than 40, retrieve the full claim id & shortest possible url + } else if (url.length < 40) { + getClaimIdByShortUrl(name, url) + .then(result => { + claimId = result; + return getShortUrlByClaimId(name, claimId); + }) + .then(result => { + shortUrl = result; + resolve({claimId, shortUrl}); }) .catch(error => { reject(error); }); - // logger.debug(`Finding claim id for "${name}" "${claimId}"`); - // db.File - // .find({ - // where: { - // name, - // claimId: { $like: `${claimId}%` }, - // }, - // }) - // .then(file => { - // // if no results were found, throw an error - // if (!file) { - // reject(new Error('That is not a valid short URL.')); - // } - // // if a result was found, resolve with the full claim id - // logger.debug('Full claim id:', file.dataValues.claimId); - // resolve(file.dataValues.claimId); - // }) - // .catch(error => { - // reject(error); - // }); } else { - logger.error('The Claim Id was larger than 40 characters'); reject(new Error('That Claim Id is not valid.')); } }); diff --git a/routes/serve-routes.js b/routes/serve-routes.js index 552c399f..8a7bcf57 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -1,4 +1,3 @@ -const logger = require('winston'); const { getClaimByClaimId, getClaimByName } = require('../controllers/serveController.js'); const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js'); const errorHandlers = require('../helpers/libraries/errorHandlers.js'); @@ -11,8 +10,7 @@ module.exports = (app) => { sendGoogleAnalytics('serve', headers, ip, originalUrl); // begin image-serve processes getClaimByClaimId(params.name, params.claim_id) - .then(fileInfo => { - logger.debug('file info:', fileInfo); + .then((fileInfo) => { // check to make sure a file was found if (!fileInfo) { res.status(307).render('noClaims'); diff --git a/routes/show-routes.js b/routes/show-routes.js index 763822b2..9e23f9d8 100644 --- a/routes/show-routes.js +++ b/routes/show-routes.js @@ -66,7 +66,8 @@ module.exports = (app) => { app.get('/show/:name/:claim_id', ({ ip, originalUrl, params }, res) => { // begin image-serve processes getClaimByClaimId(params.name, params.claim_id) - .then(fileInfo => { + .then((fileInfo) => { + console.log('SHORT URL:', fileInfo.shortUrl); // check to make sure a file was found if (!fileInfo) { res.status(307).render('noClaims'); diff --git a/views/partials/assetInfo.handlebars b/views/partials/assetInfo.handlebars index b33a9026..278c19ea 100644 --- a/views/partials/assetInfo.handlebars +++ b/views/partials/assetInfo.handlebars @@ -6,18 +6,18 @@

Links

{{!--short direct link to asset--}}
- Direct Link + Direct Link
- +
{{!-- link to show route for asset--}}
- Details Link + Details Link
- +
{{!-- html text for embedding asset--}}