From 859654e6e4ac774392c0fb53d3e29e0a32cb7c0b Mon Sep 17 00:00:00 2001 From: bill bittner Date: Mon, 20 Nov 2017 15:51:05 -0800 Subject: [PATCH 01/56] added /api/get route --- helpers/lbryApi.js | 3 +- routes/api-routes.js | 31 +++++----- views/layouts/showlite.handlebars | 2 +- views/partials/getAsset.handlebars | 91 ++++++++++++++++++++++++++++++ views/show-getAsset.handlebars | 17 ++++++ views/showLite-getAsset.handlebars | 2 + views/showLite.handlebars | 23 +------- 7 files changed, 132 insertions(+), 37 deletions(-) create mode 100644 views/partials/getAsset.handlebars create mode 100644 views/show-getAsset.handlebars create mode 100644 views/showLite-getAsset.handlebars diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index bfd3139c..3da72a05 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -6,11 +6,10 @@ function handleLbrynetResponse ({ data }, resolve, reject) { if (data.result) { // check for an error if (data.result.error) { - logger.debug('Lbrynet api error:', data.result.error); + logger.warn('Lbrynet api error:', data.result.error); reject(data.result.error); return; }; - // logger.debug('data.result', data.result); resolve(data.result); return; } diff --git a/routes/api-routes.js b/routes/api-routes.js index 38b5b1e8..df891f0d 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -4,18 +4,15 @@ const config = require('../config/speechConfig.js'); const multipartMiddleware = multipart({uploadDir: config.files.uploadDirectory}); const db = require('../models'); const { publish } = require('../controllers/publishController.js'); -const { getClaimList, resolveUri } = require('../helpers/lbryApi.js'); +const { getClaimList, resolveUri, getClaim } = require('../helpers/lbryApi.js'); const { createPublishParams, validateApiPublishRequest, validatePublishSubmission, cleanseChannelName, checkClaimNameAvailability, checkChannelAvailability } = require('../helpers/publishHelpers.js'); const errorHandlers = require('../helpers/errorHandlers.js'); -const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js'); +const { postToStats } = require('../controllers/statsController.js'); const { authenticateOrSkip } = require('../auth/authentication.js'); module.exports = (app) => { // route to run a claim_list request on the daemon - app.get('/api/claim_list/:name', ({ headers, ip, originalUrl, params }, res) => { - // google analytics - sendGoogleAnalytics('SERVE', headers, ip, originalUrl); - // serve the content + app.get('/api/claim_list/:name', ({ ip, originalUrl, params }, res) => { getClaimList(params.name) .then(claimsList => { postToStats('serve', originalUrl, ip, null, null, 'success'); @@ -25,9 +22,22 @@ module.exports = (app) => { errorHandlers.handleApiError('claim_list', originalUrl, ip, error, res); }); }); + // route to get an asset + app.get('/api/get/:name/:claimId', ({ ip, originalUrl, params }, res) => { + if (!params.name || !params.claimId) { + res.status(400).json({success: false, message: 'provide a claimId and/or a name'}); + } + getClaim(`${params.name}#${params.claimId}`) + .then(result => { + res.status(200).json({status: 'success', message: result}); + }) + .catch(error => { + errorHandlers.handleApiError('get', originalUrl, ip, error, res); + }); + }); + // route to check whether spee.ch has published to a claim app.get('/api/isClaimAvailable/:name', ({ params }, res) => { - // send response checkClaimNameAvailability(params.name) .then(result => { if (result === true) { @@ -59,9 +69,6 @@ module.exports = (app) => { }); // route to run a resolve request on the daemon app.get('/api/resolve/:uri', ({ headers, ip, originalUrl, params }, res) => { - // google analytics - sendGoogleAnalytics('SERVE', headers, ip, originalUrl); - // serve content resolveUri(params.uri) .then(resolvedUri => { postToStats('serve', originalUrl, ip, null, null, 'success'); @@ -161,8 +168,7 @@ module.exports = (app) => { }); // route to get a short claim id from long claim Id - app.get('/api/shortClaimId/:longId/:name', ({ originalUrl, ip, params }, res) => { - // serve content + app.get('/api/shortClaimId/:longId/:name', ({ params }, res) => { db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name) .then(shortId => { res.status(200).json(shortId); @@ -174,7 +180,6 @@ module.exports = (app) => { }); // route to get a short channel id from long channel Id app.get('/api/shortChannelId/:longId/:name', ({ ip, originalUrl, params }, res) => { - // serve content db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name) .then(shortId => { logger.debug('sending back short channel id', shortId); diff --git a/views/layouts/showlite.handlebars b/views/layouts/showlite.handlebars index d446f578..17cc0ddf 100644 --- a/views/layouts/showlite.handlebars +++ b/views/layouts/showlite.handlebars @@ -17,7 +17,7 @@ {{ googleAnalytics }} - {{{ body }}} + {{> getAsset}} diff --git a/views/partials/getAsset.handlebars b/views/partials/getAsset.handlebars new file mode 100644 index 00000000..f56293a2 --- /dev/null +++ b/views/partials/getAsset.handlebars @@ -0,0 +1,91 @@ +
+
+

Searching for peers for this asset...

+ + +
+
+ + + + +
+
+ + \ No newline at end of file diff --git a/views/show-getAsset.handlebars b/views/show-getAsset.handlebars new file mode 100644 index 00000000..cdb1ad1d --- /dev/null +++ b/views/show-getAsset.handlebars @@ -0,0 +1,17 @@ +
+
+ + {{fileInfo.title}} +
+
+ +
+ {{> getAsset}} +
+
+ +
+ {{> assetInfo}} +
+
+
\ No newline at end of file diff --git a/views/showLite-getAsset.handlebars b/views/showLite-getAsset.handlebars new file mode 100644 index 00000000..ac918c8d --- /dev/null +++ b/views/showLite-getAsset.handlebars @@ -0,0 +1,2 @@ +{{> getAsset }} +hosted via spee<h \ No newline at end of file diff --git a/views/showLite.handlebars b/views/showLite.handlebars index 3243b5bd..aca805cb 100644 --- a/views/showLite.handlebars +++ b/views/showLite.handlebars @@ -1,21 +1,2 @@ -{{#ifConditional fileInfo.fileType '===' 'video/mp4'}} - {{#ifConditional fileInfo.fileExt '===' '.gifv'}} - - {{else}} - - {{/ifConditional}} -
- hosted via spee<h -{{else}} - - {{fileInfo.fileName}} - -{{/ifConditional}} \ No newline at end of file +{{> asset }} +hosted via spee<h \ No newline at end of file -- 2.45.2 From cda9efa8000cba1126e9bb019f15a036a75709db Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 21 Nov 2017 12:53:43 -0800 Subject: [PATCH 02/56] removed duplicate templates --- controllers/serveController.js | 211 ++++-------------- helpers/handlebarsHelpers.js | 4 +- helpers/serveHelpers.js | 70 +++--- models/certificate.js | 24 +- models/claim.js | 26 ++- routes/api-routes.js | 94 +++++++- routes/serve-routes.js | 85 +++---- views/layouts/show.handlebars | 6 +- views/layouts/showlite.handlebars | 8 +- views/partials/asset.handlebars | 95 ++++++-- views/partials/assetInfo.handlebars | 36 +-- views/partials/getAsset.handlebars | 91 -------- ...Asset.handlebars => show-local.handlebars} | 4 +- views/show.handlebars | 2 +- views/showLite-getAsset.handlebars | 2 - views/showLite-local.handlebars | 2 + views/showLite.handlebars | 2 +- 17 files changed, 374 insertions(+), 388 deletions(-) delete mode 100644 views/partials/getAsset.handlebars rename views/{show-getAsset.handlebars => show-local.handlebars} (83%) delete mode 100644 views/showLite-getAsset.handlebars create mode 100644 views/showLite-local.handlebars diff --git a/controllers/serveController.js b/controllers/serveController.js index 233906c5..d712819a 100644 --- a/controllers/serveController.js +++ b/controllers/serveController.js @@ -1,105 +1,8 @@ -const lbryApi = require('../helpers/lbryApi.js'); const db = require('../models'); const logger = require('winston'); -const { serveFile, showFile, showFileLite } = require('../helpers/serveHelpers.js'); -const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js'); -const SERVE = 'SERVE'; -const SHOW = 'SHOW'; -const SHOWLITE = 'SHOWLITE'; const DEFAULT_THUMBNAIL = 'https://spee.ch/assets/img/video_thumb_default.png'; const NO_CHANNEL = 'NO_CHANNEL'; -const NO_CLAIM = 'NO_CLAIM'; - -function checkForLocalAssetByClaimId (claimId, name) { - logger.debug(`checkForLocalAssetsByClaimId(${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 addGetResultsToFileRecord (fileInfo, getResult) { - fileInfo.fileName = getResult.file_name; - fileInfo.filePath = getResult.download_path; - fileInfo.fileType = getResult.mime_type; - return fileInfo; -} - -function createFileRecord ({ name, claimId, outpoint, height, address, nsfw }) { - return { - name, - claimId, - outpoint, - height, - address, - fileName: '', - filePath: '', - fileType: '', - nsfw, - }; -} - -function getAssetByLongClaimId (fullClaimId, name) { - logger.debug('...getting asset by claim Id...'); - return new Promise((resolve, reject) => { - // 1. check locally for claim - checkForLocalAssetByClaimId(fullClaimId, name) - .then(dataValues => { - // if a result was found, return early with the result - if (dataValues) { - logger.debug('found a local file for this name and claimId'); - resolve(dataValues); - return; - } - logger.debug('no local file found for this name and claimId'); - // 2. if no local claim, resolve and get the claim - db.Claim - .resolveClaim(name, fullClaimId) - .then(resolveResult => { - // if no result, return early (claim doesn't exist or isn't free) - if (!resolveResult) { - resolve(NO_CLAIM); - return; - } - logger.debug('resolve result >> ', resolveResult.dataValues); - let fileRecord = {}; - // get the claim - lbryApi.getClaim(`${name}#${fullClaimId}`) - .then(getResult => { - logger.debug('getResult >>', getResult); - fileRecord = createFileRecord(resolveResult); - fileRecord = addGetResultsToFileRecord(fileRecord, getResult); - // insert a record in the File table & Update Claim table - return db.File.create(fileRecord); - }) - .then(() => { - logger.debug('File record successfully updated'); - resolve(fileRecord); - }) - .catch(error => { - reject(error); - }); - }) - .catch(error => { - reject(error); - }); - }) - .catch(error => { - reject(error); - }); - }); -} function chooseThumbnail (claimInfo, defaultThumbnail) { if (!claimInfo.thumbnail || claimInfo.thumbnail.trim() === '') { @@ -109,42 +12,38 @@ function chooseThumbnail (claimInfo, defaultThumbnail) { } module.exports = { - getAssetByClaim (claimName, claimId) { - logger.debug(`getAssetByClaim(${claimName}, ${claimId})`); + getClaimId (channelName, channelId, name, claimId) { + if (channelName) { + return module.exports.getClaimIdByChannel(channelName, channelId, name); + } else { + return module.exports.getClaimIdByClaim(name, claimId); + } + }, + getClaimIdByClaim (claimName, claimId) { + logger.debug(`getClaimIdByClaim(${claimName}, ${claimId})`); return new Promise((resolve, reject) => { - db.Claim.getLongClaimId(claimName, claimId) // 1. get the long claim id - .then(result => { // 2. get the asset using the long claim id - logger.debug('long claim id ===', result); - if (result === NO_CLAIM) { - logger.debug('resolving NO_CLAIM'); - resolve(NO_CLAIM); - return; - } - resolve(getAssetByLongClaimId(result, claimName)); + db.Claim.getLongClaimId(claimName, claimId) // get the long claim id + .then(result => { + resolve(result); // resolves with NO_CLAIM or valid claim id }) .catch(error => { reject(error); }); }); }, - getAssetByChannel (channelName, channelId, claimName) { - logger.debug('getting asset by channel'); + getClaimIdByChannel (channelName, channelId, claimName) { + logger.debug(`getClaimIdByChannel(${channelName}, ${channelId}, ${claimName})`); return new Promise((resolve, reject) => { db.Certificate.getLongChannelId(channelName, channelId) // 1. get the long channel id - .then(result => { // 2. get the long claim Id + .then(result => { if (result === NO_CHANNEL) { - resolve(NO_CHANNEL); + resolve(result); // resolves NO_CHANNEL return; } - return db.Claim.getClaimIdByLongChannelId(result, claimName); + return db.Claim.getClaimIdByLongChannelId(result, claimName); // 2. get the long claim id }) - .then(result => { // 3. get the asset using the long claim id - logger.debug('asset claim id =', result); - if (result === NO_CHANNEL || result === NO_CLAIM) { - resolve(result); - return; - } - resolve(getAssetByLongClaimId(result, claimName)); + .then(result => { + resolve(result); // resolves with NO_CLAIM or valid claim id }) .catch(error => { reject(error); @@ -172,7 +71,7 @@ module.exports = { }) .then(result => { // 4. add extra data not available from Claim table if (result === NO_CHANNEL) { - resolve(NO_CHANNEL); + resolve(result); return; } if (result) { @@ -197,57 +96,23 @@ module.exports = { }); }); }, - serveOrShowAsset (fileInfo, extension, method, headers, originalUrl, ip, res) { - // add file extension to the file info - if (extension === 'gifv') { - fileInfo['fileExt'] = 'gifv'; - } else { - fileInfo['fileExt'] = fileInfo.fileName.substring(fileInfo.fileName.lastIndexOf('.') + 1); - } - // add a record to the stats table - postToStats(method, originalUrl, ip, fileInfo.name, fileInfo.claimId, 'success'); - // serve or show - switch (method) { - case SERVE: - serveFile(fileInfo, res); - sendGoogleAnalytics(method, headers, ip, originalUrl); - return fileInfo; - case SHOWLITE: - return db.Claim.resolveClaim(fileInfo.name, fileInfo.claimId) - .then(claimRecord => { - fileInfo['title'] = claimRecord.title; - fileInfo['description'] = claimRecord.description; - showFileLite(fileInfo, res); - return fileInfo; - }) - .catch(error => { - logger.error('throwing serverOrShowAsset SHOWLITE error...'); - throw error; - }); - case SHOW: - return db.Claim - .getShortClaimIdFromLongClaimId(fileInfo.claimId, fileInfo.name) - .then(shortId => { - fileInfo['shortId'] = shortId; - return db.Claim.resolveClaim(fileInfo.name, fileInfo.claimId); - }) - .then(resolveResult => { - logger.debug('resolve result >>', resolveResult.dataValues); - fileInfo['thumbnail'] = chooseThumbnail(resolveResult, DEFAULT_THUMBNAIL); - fileInfo['title'] = resolveResult.title; - fileInfo['description'] = resolveResult.description; - if (resolveResult.certificateId) { fileInfo['certificateId'] = resolveResult.certificateId }; - if (resolveResult.channelName) { fileInfo['channelName'] = resolveResult.channelName }; - showFile(fileInfo, res); - return fileInfo; - }) - .catch(error => { - logger.error('throwing serverOrShowAsset SHOW error...'); - throw error; - }); - default: - logger.error('I did not recognize that method'); - break; - } + getLocalFileRecord (claimId, name) { + return db.File.findOne({where: {claimId, name}}) + .then(file => { + if (!file) { + return null; + } + return file.dataValues; + }); + }, + getClaimRecord (claimId, name) { + return db.Claim.findOne({where: {claimId, name}}) + .then(claim => { + if (!claim) { + throw new Error('no record found in Claim table'); + } + claim.dataValues.thumbnail = chooseThumbnail(claim.dataValues.thumbnail, DEFAULT_THUMBNAIL); + return claim.dataValues; + }); }, }; diff --git a/helpers/handlebarsHelpers.js b/helpers/handlebarsHelpers.js index 59275e0c..b2560c03 100644 --- a/helpers/handlebarsHelpers.js +++ b/helpers/handlebarsHelpers.js @@ -13,10 +13,10 @@ module.exports = { return new Handlebars.SafeString(gaCode); }, addOpenGraph (title, mimeType, showUrl, source, description, thumbnail) { - if (title === null || title.trim() === '') { + if (!title || title.trim() === '') { title = 'Spee.ch'; } - if (description === null || description.trim() === '') { + if (!description || description.trim() === '') { description = 'Open-source, decentralized image and video sharing.'; } const ogTitle = ``; diff --git a/helpers/serveHelpers.js b/helpers/serveHelpers.js index 6e7c610a..a5e5b318 100644 --- a/helpers/serveHelpers.js +++ b/helpers/serveHelpers.js @@ -1,6 +1,10 @@ const logger = require('winston'); +const SERVE = 'SERVE'; +const SHOW = 'SHOW'; +const SHOWLITE = 'SHOWLITE'; +// const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js'); -function createOpenGraphInfo ({ fileType, claimId, name, fileName, fileExt }) { +function createOpenGraphInfo ({ claimId, name, fileExt }) { return { embedUrl : `https://spee.ch/embed/${claimId}/${name}`, showUrl : `https://spee.ch/${claimId}/${name}`, @@ -10,36 +14,50 @@ function createOpenGraphInfo ({ fileType, claimId, name, fileName, fileExt }) { } module.exports = { - serveFile ({ fileName, fileType, filePath }, res) { - logger.verbose(`serving file ${fileName}`); - // set default options - let options = { - headers: { - 'X-Content-Type-Options': 'nosniff', - 'Content-Type' : fileType, - }, - }; - // adjust default options as needed - switch (fileType) { - case 'image/jpeg': - case 'image/gif': - case 'image/png': - case 'video/mp4': - break; + serveOrShowAsset (method, fileInfo, claimInfo, shortId, res) { + // add file extension to the file info + claimInfo['fileExt'] = fileInfo.fileName.substring(fileInfo.fileName.lastIndexOf('.') + 1); + // serve or show + switch (method) { + case SERVE: + module.exports.serveFile(fileInfo, claimInfo, shortId, res); + return fileInfo; + case SHOWLITE: + module.exports.showFileLite(fileInfo, claimInfo, shortId, res); + return fileInfo; + case SHOW: + module.exports.showFile(fileInfo, claimInfo, shortId, res); + return fileInfo; default: - logger.warn('sending file with unknown type as .jpeg'); - options['headers']['Content-Type'] = 'image/jpeg'; + logger.error('I did not recognize that method'); break; } + }, + serveFile ({ filePath }, { claimId, name, contentType }, shortId, res) { + logger.verbose(`serving ${name}#${claimId}`); + // set response options + const headerContentType = contentType || 'image/jpeg'; + const options = { + headers: { + 'X-Content-Type-Options': 'nosniff', + 'Content-Type' : headerContentType, + }, + }; // send the file - res.status(200).sendFile(filePath, options); + if (filePath) { + res.status(200).sendFile(filePath, options); + } else { + // 'get' the file + // send the file + res.status(307).redirect(`/api/get/${name}/${claimId}`); + } }, - showFile (fileInfo, res) { - const openGraphInfo = createOpenGraphInfo(fileInfo); - res.status(200).render('show', { layout: 'show', fileInfo, openGraphInfo }); + showFile (fileInfo, claimInfo, shortId, res) { + const openGraphInfo = createOpenGraphInfo(claimInfo); + res.status(200).render('show', { layout: 'show', claimInfo, shortId, openGraphInfo }); }, - showFileLite (fileInfo, res) { - const openGraphInfo = createOpenGraphInfo(fileInfo); - res.status(200).render('showLite', { layout: 'showlite', fileInfo, openGraphInfo }); + showFileLite (fileInfo, claimInfo, shortId, res) { + const openGraphInfo = createOpenGraphInfo(claimInfo); + res.status(200).render('showLite', { layout: 'showlite', claimInfo, shortId, openGraphInfo }); }, }; diff --git a/models/certificate.js b/models/certificate.js index 37dafbaa..0501dd0c 100644 --- a/models/certificate.js +++ b/models/certificate.js @@ -171,10 +171,32 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => { }); }; + Certificate.validateLongChannelId = function (name, claimId) { + return new Promise((resolve, reject) => { + this.findOne({ + where: {name, claimId}, + }) + .then(result => { + switch (result.length) { + case 0: + return resolve(NO_CHANNEL); + case 1: + return resolve(result[0]); + default: + logger.warn(`more than one entry matches that name (${name}) and certificate Id (${claimId})`); + return resolve(result[0]); + } + }) + .catch(error => { + reject(error); + }); + }); + }; + Certificate.getLongChannelId = function (channelName, channelId) { logger.debug(`getLongChannelId(${channelName}, ${channelId})`); if (channelId && (channelId.length === 40)) { // if a full channel id is provided - return new Promise((resolve, reject) => resolve(channelId)); + return this.validateLongChannelId(channelName, channelId); } else if (channelId && channelId.length < 40) { // if a short channel id is provided return this.getLongChannelIdFromShortChannelId(channelName, channelId); } else { diff --git a/models/claim.js b/models/claim.js index 0c7289fd..9027b087 100644 --- a/models/claim.js +++ b/models/claim.js @@ -274,10 +274,34 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => { }); }; + Claim.validateLongClaimId = function (name, claimId) { + return new Promise((resolve, reject) => { + this.findOne({ + where: {name, claimId}, + }) + .then(result => { + // logger.debug('validateLongClaimId result:', result.dataValues); + logger.debug('validateLongClaimId result.length:', result.dataValues.length); + switch (result.dataValues.length) { + case 0: + return resolve(NO_CLAIM); + case 1: + return resolve(claimId); + default: + logger.warn(`more than one entry matches that name (${name}) and claimID (${claimId})`); + return resolve(claimId); + } + }) + .catch(error => { + reject(error); + }); + }); + }; + Claim.getLongClaimId = function (claimName, claimId) { logger.debug(`getLongClaimId(${claimName}, ${claimId})`); if (claimId && (claimId.length === 40)) { // if a full claim id is provided - return new Promise((resolve, reject) => resolve(claimId)); + return this.validateLongClaimId(claimName, claimId); } else if (claimId && claimId.length < 40) { return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided } else { diff --git a/routes/api-routes.js b/routes/api-routes.js index df891f0d..bcd7a9da 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -10,6 +10,77 @@ const errorHandlers = require('../helpers/errorHandlers.js'); const { postToStats } = require('../controllers/statsController.js'); const { authenticateOrSkip } = require('../auth/authentication.js'); +function addGetResultsToFileRecord (fileInfo, getResult) { + fileInfo.fileName = getResult.file_name; + fileInfo.filePath = getResult.download_path; + return fileInfo; +} + +function createFileRecord ({ name, claimId, outpoint, height, address, nsfw, contentType }) { + return { + name, + claimId, + outpoint, + height, + address, + fileName: '', + filePath: '', + fileType: contentType, + nsfw, + }; +} + +// function getAssetByLongClaimId (fullClaimId, name) { +// logger.debug('...getting asset by claim Id...'); +// return new Promise((resolve, reject) => { +// // 1. check locally for claim +// checkForLocalAssetByClaimId(fullClaimId, name) +// .then(dataValues => { +// // if a result was found, return early with the result +// if (dataValues) { +// logger.debug('found a local file for this name and claimId'); +// resolve(dataValues); +// return; +// } +// logger.debug('no local file found for this name and claimId'); +// // 2. if no local claim, resolve and get the claim +// db.Claim +// .resolveClaim(name, fullClaimId) +// .then(resolveResult => { +// // if no result, return early (claim doesn't exist or isn't free) +// if (!resolveResult) { +// resolve(NO_CLAIM); +// return; +// } +// logger.debug('resolve result >> ', resolveResult.dataValues); +// let fileRecord = {}; +// // get the claim +// lbryApi.getClaim(`${name}#${fullClaimId}`) +// .then(getResult => { +// logger.debug('getResult >>', getResult); +// fileRecord = createFileRecord(resolveResult); +// fileRecord = addGetResultsToFileRecord(fileRecord, getResult); +// // insert a record in the File table & Update Claim table +// return db.File.create(fileRecord); +// }) +// .then(() => { +// logger.debug('File record successfully updated'); +// resolve(fileRecord); +// }) +// .catch(error => { +// reject(error); +// }); +// }) +// .catch(error => { +// reject(error); +// }); +// }) +// .catch(error => { +// reject(error); +// }); +// }); +// } + module.exports = (app) => { // route to run a claim_list request on the daemon app.get('/api/claim_list/:name', ({ ip, originalUrl, params }, res) => { @@ -27,9 +98,26 @@ module.exports = (app) => { if (!params.name || !params.claimId) { res.status(400).json({success: false, message: 'provide a claimId and/or a name'}); } - getClaim(`${params.name}#${params.claimId}`) - .then(result => { - res.status(200).json({status: 'success', message: result}); + let fileRecord; + // 1. resolve the claim + db.Claim.resolveClaim(params.name, params.claimId) + .then(resolveResult => { + if (!resolveResult) { + throw new Error('No matching uri found in Claim table'); + } + fileRecord = createFileRecord(resolveResult); + // 2. get the claim + return getClaim(`${params.name}#${params.claimId}`); + }) + .then(getResult => { + res.status(200).json({status: 'success', message: getResult}); + logger.debug('response was sent to the client'); + fileRecord = addGetResultsToFileRecord(fileRecord, getResult); + // 3. insert a record for the claim into the File table + return db.File.create(fileRecord); + }) + .then(() => { + logger.debug('File record successfully created'); }) .catch(error => { errorHandlers.handleApiError('get', originalUrl, ip, error, res); diff --git a/routes/serve-routes.js b/routes/serve-routes.js index 3cde0875..82dfe569 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -1,12 +1,14 @@ const logger = require('winston'); -const { getAssetByClaim, getChannelContents, getAssetByChannel, serveOrShowAsset } = require('../controllers/serveController.js'); +const { getClaimId, getChannelContents, getLocalFileRecord, getClaimRecord } = require('../controllers/serveController.js'); +const { serveOrShowAsset } = require('../helpers/serveHelpers.js'); const { handleRequestError } = require('../helpers/errorHandlers.js'); +const db = require('../models'); const SERVE = 'SERVE'; const SHOW = 'SHOW'; const SHOWLITE = 'SHOWLITE'; -const CHANNEL = 'CHANNEL'; -const CLAIM = 'CLAIM'; +// const CHANNEL = 'CHANNEL'; +// const CLAIM = 'CLAIM'; const CLAIM_ID_CHAR = ':'; const CHANNEL_CHAR = '@'; const CLAIMS_PER_PAGE = 10; @@ -25,17 +27,6 @@ function isValidShortIdOrClaimId (input) { return (isValidClaimId(input) || isValidShortId(input)); } -function getAsset (claimType, channelName, channelId, name, claimId) { - switch (claimType) { - case CHANNEL: - return getAssetByChannel(channelName, channelId, name); - case CLAIM: - return getAssetByClaim(name, claimId); - default: - return new Error('that claim type was not found'); - } -} - function getPage (query) { if (query.p) { return parseInt(query.p); @@ -86,7 +77,6 @@ module.exports = (app) => { app.get('/:identifier/:name', ({ headers, ip, originalUrl, params }, res) => { let identifier = params.identifier; let name = params.name; - let claimOrChannel; let channelName = null; let claimId = null; let channelId = null; @@ -123,7 +113,6 @@ module.exports = (app) => { // parse identifier for whether it is a channel, short url, or claim_id if (identifier.charAt(0) === '@') { channelName = identifier; - claimOrChannel = CHANNEL; const channelIdIndex = channelName.indexOf(CLAIM_ID_CHAR); if (channelIdIndex !== -1) { channelId = channelName.substring(channelIdIndex + 1); @@ -133,13 +122,11 @@ module.exports = (app) => { } else { claimId = identifier; logger.debug('claim id =', claimId); - claimOrChannel = CLAIM; } - // 1. retrieve the asset and information - getAsset(claimOrChannel, channelName, channelId, name, claimId) - // 2. serve or show + // get the claim id + getClaimId(channelName, channelId, name, claimId) .then(result => { - logger.debug('getAsset result:', result); + logger.debug('getClaimId result:', result); if (result === NO_CLAIM) { res.status(200).render('noClaim'); return; @@ -147,7 +134,15 @@ module.exports = (app) => { res.status(200).render('noChannel'); return; } - return serveOrShowAsset(result, fileExtension, method, headers, originalUrl, ip, res); + // check for local file info and resolve the claim + return Promise.all([getLocalFileRecord(result, name), getClaimRecord(result, name), db.Claim.getShortClaimIdFromLongClaimId(result, name)]); + }) + .then(([fileInfo, claimInfo, shortClaimId]) => { + logger.debug(`file record:`, fileInfo); + logger.debug('claim record:', claimInfo); + logger.debug('short url:', shortClaimId); + // serve or show + return serveOrShowAsset(method, fileInfo, claimInfo, shortClaimId, res); }) // 3. update the file .then(fileInfoForUpdate => { @@ -229,24 +224,34 @@ module.exports = (app) => { } logger.debug('claim name = ', name); logger.debug('method =', method); - // 1. retrieve the asset and information - getAsset(CLAIM, null, null, name, null) - // 2. respond to the request - .then(result => { - logger.debug('getAsset result', result); - if (result === NO_CLAIM) { - res.status(200).render('noClaim'); - } else { - return serveOrShowAsset(result, fileExtension, method, headers, originalUrl, ip, res); - } - }) - // 3. update the database - .then(fileInfoForUpdate => { - // if needed, this is where we would update the file - }) - .catch(error => { - handleRequestError('serve', originalUrl, ip, error, res); - }); + // get the claim id + getClaimId(null, null, name, null) + .then(result => { + logger.debug('getClaimId result:', result); + if (result === NO_CLAIM) { + res.status(200).render('noClaim'); + return; + } else if (result === NO_CHANNEL) { + res.status(200).render('noChannel'); + return; + } + // check for local file info and resolve the claim + return Promise.all([getLocalFileRecord(result, name), getClaimRecord(result, name), db.Claim.getShortClaimIdFromLongClaimId(result, name)]); + }) + .then(([fileInfo, claimInfo, shortClaimId]) => { + logger.debug(`fileInfo:`, fileInfo); + logger.debug('claimInfo:', claimInfo); + logger.debug('shortClaimId:', shortClaimId); + // serve or show + return serveOrShowAsset(method, fileInfo, claimInfo, shortClaimId, res); + }) + // 3. update the file + .then(fileInfoForUpdate => { + // if needed, this is where we would update the file + }) + .catch(error => { + handleRequestError('serve', originalUrl, ip, error, res); + }); } }); }; diff --git a/views/layouts/show.handlebars b/views/layouts/show.handlebars index 47519103..5c96d323 100644 --- a/views/layouts/show.handlebars +++ b/views/layouts/show.handlebars @@ -9,9 +9,9 @@ - {{#unless fileInfo.nsfw}} - {{{addTwitterCard fileInfo.fileType openGraphInfo.source openGraphInfo.embedUrl openGraphInfo.directFileUrl}}} - {{{addOpenGraph fileInfo.title fileInfo.fileType openGraphInfo.showUrl openGraphInfo.source fileInfo.description fileInfo.thumbnail}}} + {{#unless claimInfo.nsfw}} + {{{addTwitterCard claimInfo.contentType openGraphInfo.source openGraphInfo.embedUrl openGraphInfo.directFileUrl}}} + {{{addOpenGraph claimInfo.title claimInfo.contentType openGraphInfo.showUrl openGraphInfo.source claimInfo.description claimInfo.thumbnail}}} {{/unless}} diff --git a/views/layouts/showlite.handlebars b/views/layouts/showlite.handlebars index 17cc0ddf..7fb7a400 100644 --- a/views/layouts/showlite.handlebars +++ b/views/layouts/showlite.handlebars @@ -9,10 +9,10 @@ - {{#unless fileInfo.nsfw}} - {{{addTwitterCard fileInfo.fileType openGraphInfo.source openGraphInfo.embedUrl openGraphInfo.directFileUrl}}} - {{{addOpenGraph fileInfo.title fileInfo.fileType openGraphInfo.showUrl openGraphInfo.source fileInfo.description fileInfo.thumbnail}}} - {{/unless}} + {{#unless claimInfo.nsfw}} + {{{addTwitterCard claimInfo.contentType openGraphInfo.source openGraphInfo.embedUrl openGraphInfo.directFileUrl}}} + {{{addOpenGraph claimInfo.title claimInfo.contentType openGraphInfo.showUrl openGraphInfo.source claimInfo.description claimInfo.thumbnail}}} + {{/unless}} {{ googleAnalytics }} diff --git a/views/partials/asset.handlebars b/views/partials/asset.handlebars index ad16bb9f..29d3ef28 100644 --- a/views/partials/asset.handlebars +++ b/views/partials/asset.handlebars @@ -1,29 +1,84 @@ -{{#ifConditional fileInfo.fileType '===' 'video/mp4'}} - {{#ifConditional fileInfo.fileExt '===' 'gifv'}} +{{#ifConditional claimInfo.contentType '===' 'video/mp4'}} + {{#ifConditional claimInfo.fileExt '===' 'gifv'}} {{else}} - - - {{/ifConditional}} {{else}} - - + + -{{/ifConditional}} \ No newline at end of file +{{/ifConditional}} + +
+ + + +
+ + \ No newline at end of file diff --git a/views/partials/assetInfo.handlebars b/views/partials/assetInfo.handlebars index 8677710d..31d6b02f 100644 --- a/views/partials/assetInfo.handlebars +++ b/views/partials/assetInfo.handlebars @@ -1,28 +1,28 @@ -{{#if fileInfo.channelName}} +{{#if claimInfo.channelName}} {{/if}} -{{#if fileInfo.description}} +{{#if claimInfo.description}}
- {{fileInfo.description}} + {{claimInfo.description}}
{{/if}}