diff --git a/controllers/serveController.js b/controllers/serveController.js index e2e9ff13..c638162d 100644 --- a/controllers/serveController.js +++ b/controllers/serveController.js @@ -53,7 +53,7 @@ module.exports = { }); }); }, - getChannelViewData (channelName, channelClaimId, query) { + getChannelViewData (channelName, channelClaimId, page) { return new Promise((resolve, reject) => { // 1. get the long channel Id (make sure channel exists) db.Certificate.getLongChannelId(channelName, channelClaimId) @@ -69,7 +69,7 @@ module.exports = { return resolve(NO_CHANNEL); } // 3. format the data for the view, including pagination - let paginatedChannelViewData = returnPaginatedChannelViewData(channelName, longChannelClaimId, shortChannelClaimId, channelClaimsArray, query); + let paginatedChannelViewData = returnPaginatedChannelViewData(channelName, longChannelClaimId, shortChannelClaimId, channelClaimsArray, page); // 4. return all the channel information and contents resolve(paginatedChannelViewData); }) diff --git a/helpers/channelPagination.js b/helpers/channelPagination.js index d454a9ff..e5d99b7e 100644 --- a/helpers/channelPagination.js +++ b/helpers/channelPagination.js @@ -1,9 +1,9 @@ const CLAIMS_PER_PAGE = 10; module.exports = { - returnPaginatedChannelViewData (channelName, longChannelClaimId, shortChannelClaimId, claims, query) { + returnPaginatedChannelViewData (channelName, longChannelClaimId, shortChannelClaimId, claims, page) { const totalPages = module.exports.determineTotalPages(claims); - const paginationPage = module.exports.getPageFromQuery(query); + const paginationPage = module.exports.getPageFromQuery(page); const viewData = { channelName : channelName, longChannelClaimId : longChannelClaimId, @@ -17,9 +17,9 @@ module.exports = { }; return viewData; }, - getPageFromQuery (query) { - if (query.p) { - return parseInt(query.p); + getPageFromQuery (page) { + if (page) { + return parseInt(page); } return 1; }, diff --git a/models/certificate.js b/models/certificate.js index 50a24479..07c0cc76 100644 --- a/models/certificate.js +++ b/models/certificate.js @@ -100,7 +100,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => { }; Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) { - logger.debug(`finding short channel id for ${channelName}:${longChannelId}`); + logger.debug(`getShortChannelIdFromLongChannelId ${channelName}:${longChannelId}`); return new Promise((resolve, reject) => { this .findAll({ @@ -122,6 +122,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => { }; Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) { + logger.debug(`getLongChannelIdFromShortChannelId(${channelName}, ${channelClaimId})`); return new Promise((resolve, reject) => { this .findAll({ @@ -170,6 +171,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => { }; Certificate.validateLongChannelId = function (name, claimId) { + logger.debug(`validateLongChannelId(${name}, ${claimId})`); return new Promise((resolve, reject) => { this.findOne({ where: {name, claimId}, diff --git a/react/components/AssetDisplay/index.js b/react/components/AssetDisplay/index.js index b7647322..f5cd45d8 100644 --- a/react/components/AssetDisplay/index.js +++ b/react/components/AssetDisplay/index.js @@ -1,9 +1,9 @@ import React from 'react'; -const AssetDisplay = () => { +const AssetDisplay = ({claimName, claimId}) => { return (
-

display asset here

+

display {claimName}#{claimId} here

); }; diff --git a/react/components/AssetInfo/index.js b/react/components/AssetInfo/index.js index 61e8d0ff..0fabd5a1 100644 --- a/react/components/AssetInfo/index.js +++ b/react/components/AssetInfo/index.js @@ -1,9 +1,10 @@ import React from 'react'; -const AssetTitle = () => { +const AssetTitle = ({claimId}) => { return (

Show asset info here

+

claimId: {claimId}

); }; diff --git a/react/components/AssetPreview/index.js b/react/components/AssetPreview/index.js new file mode 100644 index 00000000..c6c8e8c1 --- /dev/null +++ b/react/components/AssetPreview/index.js @@ -0,0 +1,12 @@ +import React from 'react'; + +const AssetPreview = ({asset}) => { + console.log('asset display info:', asset); + return ( +
+

Preview Asset here

+
+ ); +}; + +export default AssetPreview; diff --git a/react/components/ShowChannel/index.js b/react/components/ShowChannel/index.js index 1e8418bc..427a9646 100644 --- a/react/components/ShowChannel/index.js +++ b/react/components/ShowChannel/index.js @@ -1,37 +1,82 @@ import React from 'react'; import NavBar from 'containers/NavBar'; +import AssetPreview from 'components/AssetPreview'; +import request from 'utils/request'; class ShowChannel extends React.Component { + constructor (props) { + super(props); + this.state = { + error : null, + channelName : null, + claims : null, + currentPage : null, + longChannelClaimId : null, + nextPage : null, + previousPage : null, + shortChannelClaimId: null, + totalPages : null, + totalResults : null, + }; + this.updateChannelData = this.updateChannelData.bind(this); + } componentDidMount () { console.log(this.props); + this.updateChannelData(1); + } + updateChannelData (page) { + const that = this; + const channelName = this.props.channelName; + const channelClaimId = this.props.channelClaimId || 'none'; + const url = `/api/channel-get-content/${channelName}/${channelClaimId}/${page}`; + return request(url) + .then(({ success, message, data }) => { + console.log('get channel data response:', data); + if (!success) { + return this.setState({error: message}); + } + that.setState({ + channelName : data.channelName, + claims : data.claims, + currentPage : data.currentPage, + longChannelClaimId : data.longChannelClaimId, + nextPage : data.nextPage, + previousPage : data.previousPage, + shortChannelClaimId: data.shortChannelClaimId, + totalPages : data.totalPages, + totalResults : data.totalResults, + }); + }) + .catch((error) => { + that.setState({error: error.message}); + }); } render () { return (
-
-
-

channelName: {this.props.channelName}

-

channelClaimId: {this.props.channelClaimId}

-
-
-
- - {((this.props.totalPages === 0) && -

There is no content in {this.props.channelName}:{this.props.longChannelClaimId} yet. Upload some! -

)} - - {((this.props.totalPages >= 1) && -
-

Below are the contents for {this.channelName}:{this.longChannelClaimId}

-
- {/* claims here */} -
-
)} - + {this.state.error ? ( +
+
+

{this.state.error}

-
+ ) : ( +
+
+

channel name: {this.props.channelName}

+

full channel id: {this.state.longChannelClaimId ? this.state.longChannelClaimId : 'loading...'}

+

short channel id: {this.state.shortChannelClaimId ? this.state.shortChannelClaimId : 'loading...'}

+

# of claims in channel: {this.state.totalResults ? this.state.totalResults : 'loading...' }

+
+
+
+ {/* claims here */} + {this.state.claims && this.state.claims.map((claim, index) => )} +
+
+
+ )}
); } @@ -39,9 +84,7 @@ class ShowChannel extends React.Component { // required props // channelName -// channelLongClaimId -// channelShortClaimId -// totalPages -// claims +// channelClaimId + export default ShowChannel; diff --git a/react/components/ShowDetails/index.js b/react/components/ShowDetails/index.js index cfae88b3..1825252d 100644 --- a/react/components/ShowDetails/index.js +++ b/react/components/ShowDetails/index.js @@ -14,15 +14,18 @@ class ShowDetailsPage extends React.Component {
- +
- +
- +
@@ -31,4 +34,11 @@ class ShowDetailsPage extends React.Component { } }; +// required props +// isChannel +// channelName +// channelClaimId +// claimId +// claimName + export default ShowDetailsPage; diff --git a/react/components/ShowLite/index.js b/react/components/ShowLite/index.js index aed5d44c..fb41fc64 100644 --- a/react/components/ShowLite/index.js +++ b/react/components/ShowLite/index.js @@ -5,7 +5,10 @@ class ShowLitePage extends React.Component { render () { return (
- +
); } diff --git a/routes/api-routes.js b/routes/api-routes.js index 65057295..8fd4f224 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -9,6 +9,9 @@ const { createPublishParams, parsePublishApiRequestBody, parsePublishApiRequestF const errorHandlers = require('../helpers/errorHandlers.js'); const { sendGoogleAnalyticsTiming } = require('../helpers/statsHelpers.js'); const { authenticateIfNoUserToken } = require('../auth/authentication.js'); +const { getChannelViewData } = require('../controllers/serveController.js'); + +const NO_CHANNEL = 'NO_CHANNEL'; module.exports = (app) => { // route to run a claim_list request on the daemon @@ -185,4 +188,21 @@ module.exports = (app) => { errorHandlers.handleApiError(originalUrl, ip, error, res); }); }); + app.get('/api/channel-get-content/:name/:longId/:page', ({ ip, originalUrl, body, params }, res) => { + const channelName = params.name; + let channelClaimId = params.longId; + if (channelClaimId === 'none') channelClaimId = null; + const page = params.page; + getChannelViewData(channelName, channelClaimId, page) + .then(data => { + if (data === NO_CHANNEL) { + return res.status(200).json({success: false, message: 'No matching channel was found'}); + } + res.status(200).json({success: true, data}); + }) + .catch(error => { + logger.error('api error getting channel contents', error); + errorHandlers.handleApiError(originalUrl, ip, error, res); + }); + }); }; diff --git a/routes/serve-routes.js b/routes/serve-routes.js index d6f379e3..de34d455 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -1,5 +1,5 @@ const logger = require('winston'); -const { getClaimId, getChannelViewData, getLocalFileRecord } = require('../controllers/serveController.js'); +const { getClaimId, getLocalFileRecord } = require('../controllers/serveController.js'); const serveHelpers = require('../helpers/serveHelpers.js'); const { handleRequestError } = require('../helpers/errorHandlers.js'); const { postToStats } = require('../helpers/statsHelpers.js'); @@ -25,25 +25,6 @@ function isValidShortIdOrClaimId (input) { return (isValidClaimId(input) || isValidShortId(input)); } -function sendChannelInfoAndContentToClient (channelPageData, res) { - if (channelPageData === NO_CHANNEL) { - res.status(200).render('noChannel'); - } else { - res.status(200).render('channel', channelPageData); - } -} - -function showChannelPageToClient (channelName, channelClaimId, originalUrl, ip, query, res) { - // 1. retrieve the channel contents - getChannelViewData(channelName, channelClaimId, query) - .then(channelViewData => { - sendChannelInfoAndContentToClient(channelViewData, res); - }) - .catch(error => { - handleRequestError(originalUrl, ip, error, res); - }); -} - function clientAcceptsHtml ({accept}) { return accept && accept.match(/text\/html/); } @@ -75,31 +56,31 @@ function determineResponseType (isServeRequest, headers) { return responseType; } -function showAssetToClient (claimId, name, res) { - return Promise - .all([db.Claim.resolveClaim(name, claimId), db.Claim.getShortClaimIdFromLongClaimId(claimId, name)]) - .then(([claimInfo, shortClaimId]) => { - // logger.debug('claimInfo:', claimInfo); - // logger.debug('shortClaimId:', shortClaimId); - return serveHelpers.showFile(claimInfo, shortClaimId, res); - }) - .catch(error => { - throw error; - }); -} - -function showLiteAssetToClient (claimId, name, res) { - return Promise - .all([db.Claim.resolveClaim(name, claimId), db.Claim.getShortClaimIdFromLongClaimId(claimId, name)]) - .then(([claimInfo, shortClaimId]) => { - // logger.debug('claimInfo:', claimInfo); - // logger.debug('shortClaimId:', shortClaimId); - return serveHelpers.showFileLite(claimInfo, shortClaimId, res); - }) - .catch(error => { - throw error; - }); -} +// function showAssetToClient (claimId, name, res) { +// return Promise +// .all([db.Claim.resolveClaim(name, claimId), db.Claim.getShortClaimIdFromLongClaimId(claimId, name)]) +// .then(([claimInfo, shortClaimId]) => { +// // logger.debug('claimInfo:', claimInfo); +// // logger.debug('shortClaimId:', shortClaimId); +// return serveHelpers.showFile(claimInfo, shortClaimId, res); +// }) +// .catch(error => { +// throw error; +// }); +// } +// +// function showLiteAssetToClient (claimId, name, res) { +// return Promise +// .all([db.Claim.resolveClaim(name, claimId), db.Claim.getShortClaimIdFromLongClaimId(claimId, name)]) +// .then(([claimInfo, shortClaimId]) => { +// // logger.debug('claimInfo:', claimInfo); +// // logger.debug('shortClaimId:', shortClaimId); +// return serveHelpers.showFileLite(claimInfo, shortClaimId, res); +// }) +// .catch(error => { +// throw error; +// }); +// } function serveAssetToClient (claimId, name, res) { return getLocalFileRecord(claimId, name) @@ -115,19 +96,6 @@ function serveAssetToClient (claimId, name, res) { }); } -function showOrServeAsset (responseType, claimId, claimName, res) { - switch (responseType) { - case SHOW: - return showAssetToClient(claimId, claimName, res); - case SHOWLITE: - return showLiteAssetToClient(claimId, claimName, res); - case SERVE: - return serveAssetToClient(claimId, claimName, res); - default: - break; - } -} - function flipClaimNameAndIdForBackwardsCompatibility (identifier, name) { // this is a patch for backwards compatability with '/name/claim_id' url format if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) { @@ -161,20 +129,26 @@ module.exports = (app) => { let responseType = determineResponseType(isServeRequest, headers); // log the request data for debugging logRequestData(responseType, claimName, channelName, claimId); - // get the claim Id and then serve/show the asset - getClaimId(channelName, channelClaimId, claimName, claimId) - .then(fullClaimId => { - if (fullClaimId === NO_CLAIM) { - return res.status(200).render('noClaim'); - } else if (fullClaimId === NO_CHANNEL) { - return res.status(200).render('noChannel'); - } - showOrServeAsset(responseType, fullClaimId, claimName, res); - postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success'); - }) - .catch(error => { - handleRequestError(originalUrl, ip, error, res); - }); + // if a serve request, serve, otherwise send the react app + if (responseType === SERVE) { + // get the claim Id and then serve/show the asset + getClaimId(channelName, channelClaimId, claimName, claimId) + .then(fullClaimId => { + if (fullClaimId === NO_CLAIM) { + return res.status(200).json({success: false, message: 'no claim id could be found'}); + } else if (fullClaimId === NO_CHANNEL) { + return res.status(200).json({success: false, message: 'no channel id could be found'}); + } + serveAssetToClient(fullClaimId, claimName, res); + // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success'); + }) + .catch(error => { + handleRequestError(originalUrl, ip, error, res); + // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail'); + }); + } else { + res.status(200).render('index'); + } }); // route to serve the winning asset at a claim or a channel page app.get('/:identifier', ({ headers, ip, originalUrl, params, query }, res) => { @@ -188,7 +162,6 @@ module.exports = (app) => { // log the request data for debugging logRequestData(null, null, channelName, null); // handle showing the channel page - // showChannelPageToClient(channelName, channelClaimId, originalUrl, ip, query, res); return res.status(200).render('index'); } else { let claimName, isServeRequest; @@ -200,18 +173,24 @@ module.exports = (app) => { let responseType = determineResponseType(isServeRequest, headers); // log the request data for debugging logRequestData(responseType, claimName, null, null); - // get the claim Id and then serve/show the asset - getClaimId(null, null, claimName, null) - .then(fullClaimId => { - if (fullClaimId === NO_CLAIM) { - return res.status(200).render('index'); - } - showOrServeAsset(responseType, fullClaimId, claimName, res); - postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success'); - }) - .catch(error => { - handleRequestError(originalUrl, ip, error, res); - }); + // if a serve request, serve, otherwise send the react app + if (responseType === SERVE) { + // get the claim Id and then serve/show the asset + getClaimId(null, null, claimName, null) + .then(fullClaimId => { + if (fullClaimId === NO_CLAIM) { + return res.status(200).render('index'); + } + serveAssetToClient(fullClaimId, claimName, res); + // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success'); + }) + .catch(error => { + handleRequestError(originalUrl, ip, error, res); + // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail'); + }); + } else { + res.status(200).render('index'); + } } }); }; diff --git a/test/end-to-end/end-to-end.tests.js b/test/end-to-end/end-to-end.tests.js index 4fb9c31c..5bcf9d8e 100644 --- a/test/end-to-end/end-to-end.tests.js +++ b/test/end-to-end/end-to-end.tests.js @@ -84,6 +84,26 @@ describe('end-to-end', function () { }); }); + describe('channel data request from client', function () { + const url = '/@test'; + const urlWithShortClaimId = '/@test:3'; + const urlWithMediumClaimId = '/@test:3b5bc6b6819172c6'; + const urlWithLongClaimId = '/@test:3b5bc6b6819172c6e2f3f90aa855b14a956b4a82'; + + describe(url, function () { + it('should pass the tests I write here'); + }); + describe(urlWithShortClaimId, function () { + it('should pass the tests I write here'); + }); + describe(urlWithMediumClaimId, function () { + it('should pass the tests I write here'); + }); + describe(urlWithLongClaimId, function () { + it('should pass the tests I write here'); + }); + }); + describe('publish requests', function () { const publishUrl = '/api/claim-publish'; const filePath = './test/mock-data/bird.jpeg';