Resolve channels #150

Merged
bones7242 merged 23 commits from resolve-channels into master 2017-08-25 18:35:40 +02:00
4 changed files with 85 additions and 113 deletions
Showing only changes of commit fb900d40be - Show all commits

View file

@ -1,11 +1,9 @@
const lbryApi = require('../helpers/lbryApi.js');
const db = require('../models');
const logger = require('winston');
const { getTopFreeClaim, getFullClaimIdFromShortId, resolveAgainstClaimTable, serveFile, showFile, showFileLite, getShortClaimIdFromLongClaimId, getClaimIdByLongChannelId, getAllChannelClaims, getLongChannelId, getShortChannelIdFromLongChannelId } = require('../helpers/serveHelpers.js');
const { resolveAgainstClaimTable, serveFile, showFile, showFileLite, getShortClaimIdFromLongClaimId, getClaimIdByLongChannelId, getAllChannelClaims, getLongChannelId, getShortChannelIdFromLongChannelId, getLongClaimId } = require('../helpers/serveHelpers.js');
const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
kauffj commented 2017-08-25 19:21:21 +02:00 (Migrated from github.com)
Review

This looks like it could use better organization. I'd be inclined to put a lot of these inside of the modal folder, but I'd suggest looking at what other conventions are used in this framework before doing that.

This looks like it could use better organization. I'd be inclined to put a lot of these inside of the `modal` folder, but I'd suggest looking at what other conventions are used in this framework before doing that.
bones7242 commented 2017-09-08 02:27:09 +02:00 (Migrated from github.com)
Review

I get a little confused sometimes on the line between controller and model responsibilities. But, yes, after looking at it and re-reading some MVC notes, I think that all the database related functions should go in the model. I rearranged as such.
af046e9d36

I get a little confused sometimes on the line between controller and model responsibilities. But, yes, after looking at it and re-reading some MVC notes, I think that all the database related functions should go in the model. I rearranged as such. https://github.com/lbryio/spee.ch/commit/af046e9d3655a57bf9cd67d3a67a54d4d44ed802
const SERVE = 'SERVE';
const SHOW = 'SHOW';
const SHOWLITE = 'SHOWLITE';
const { SERVE, SHOW, SHOWLITE } = require('../helpers/constants.js');
function checkForLocalAssetByClaimId (claimId, name) {
return new Promise((resolve, reject) => {
@ -45,7 +43,7 @@ function createFileRecord ({ name, claimId, outpoint, height, address, nsfw }) {
};
}
function getAssetByClaimId (fullClaimId, name) {
function getAssetByLongClaimId (fullClaimId, name) {
logger.debug('...getting asset by claim Id...');
return new Promise((resolve, reject) => {
// 1. check locally for claim
@ -94,40 +92,15 @@ function getAssetByClaimId (fullClaimId, name) {
}
module.exports = {
getAssetByShortId: function (shortId, name) {
logger.debug('...getting asset by short id...');
getAssetByClaim (claimName, claimId) {
logger.debug('getting asset by claim');
return new Promise((resolve, reject) => {
// get the full claimId
getFullClaimIdFromShortId(shortId, name)
// get the asset by the claimId
.then(claimId => {
logger.debug('claim id =', claimId);
resolve(getAssetByClaimId(claimId, name));
})
.catch(error => {
reject(error);
});
});
},
getAssetByClaimId (fullClaimId, name) {
return getAssetByClaimId(fullClaimId, name);
},
getAssetByName (name) {
logger.debug('...getting asset by claim name...');
return new Promise((resolve, reject) => {
// 1. get a list of the free public claims
getTopFreeClaim(name)
// 2. check locally for the top claim
.then(topFreeClaim => {
// if no claims were found, return null
if (!topFreeClaim) {
return resolve(null);
}
// parse the result
const claimId = topFreeClaim.claimId;
logger.debug('top free claim id =', claimId);
// get the asset
resolve(getAssetByClaimId(claimId, name));
// 1. get the long claim id
getLongClaimId(claimName, claimId) // here
// 2. get the claim Id
.then(longClaimId => {
logger.debug('long claim id = ', longClaimId);
resolve(getAssetByLongClaimId(longClaimId, claimName));
})
.catch(error => {
reject(error);
@ -135,7 +108,7 @@ module.exports = {
});
},
getAssetByChannel (channelName, channelId, claimName) {
logger.debug('channelId =', channelId);
logger.debug('getting asset by channel');
return new Promise((resolve, reject) => {
// 1. get the long channel id
getLongChannelId(channelName, channelId)
@ -146,7 +119,7 @@ module.exports = {
// 3. get the asset by this claim id and name
.then(claimId => {
logger.debug('asset claim id = ', claimId);
resolve(getAssetByClaimId(claimId, claimName));
resolve(getAssetByLongClaimId(claimId, claimName));
})
.catch(error => {
reject(error);

8
helpers/constants.js Normal file
View file

@ -0,0 +1,8 @@
module.exports = {
kauffj commented 2017-08-25 19:33:20 +02:00 (Migrated from github.com)
Review

I'd be more inclined to keep these where they were, or to put them on the object/class they relate to, then to create a single constants file like this.

I'd be more inclined to keep these where they were, or to put them on the object/class they relate to, then to create a single constants file like this.
bones7242 commented 2017-09-08 00:33:42 +02:00 (Migrated from github.com)
Review

moved to their individual modules f0435be0b2

moved to their individual modules https://github.com/lbryio/spee.ch/commit/f0435be0b27d25333fbc74939f204b3bd94a444f
SERVE : 'SERVE',
SHOW : 'SHOW',
SHOWLITE : 'SHOWLITE',
CHANNEL : 'CHANNEL',
CLAIM : 'CLAIM',
CHANNELID_INDICATOR: ':',
};

View file

@ -51,6 +51,42 @@ function getLongChannelIdFromChannelName (channelName) {
});
}
function getLongClaimIdFromShortClaimId (name, shortId) {
return new Promise((resolve, reject) => {
logger.debug('getting claim_id from short url');
// use the daemon to check for claims list
db.sequelize.query(`SELECT claimId FROM Claim WHERE name = '${name}' AND claimId LIKE '${shortId}%' ORDER BY height ASC LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
.then(result => {
switch (result.length) {
case 0:
return reject(new Error('That is an invalid Short Claim Id'));
default: // note results must be sorted
return resolve(result[0].claimId);
}
})
.catch(error => {
reject(error);
});
});
}
function getTopFreeClaimIdByClaimName (name) {
return new Promise((resolve, reject) => {
db.sequelize.query(`SELECT claimId FROM Claim WHERE name = '${name}' ORDER BY amount DESC, height ASC LIMIT 1`, { type: db.sequelize.QueryTypes.SELECT })
.then(result => {
switch (result.length) {
case 0:
return resolve(null);
default:
return resolve(result[0].claimId);
}
})
.catch(error => {
reject(error);
});
});
};
function sortResult (result, longId) {
let claimIndex;
let shortId = longId.substring(0, 1); // default sort id is the first letter
@ -108,23 +144,14 @@ module.exports = {
const openGraphInfo = createOpenGraphInfo(fileInfo);
res.status(200).render('showLite', { layout: 'show', fileInfo, openGraphInfo });
},
getFullClaimIdFromShortId (shortId, name) {
return new Promise((resolve, reject) => {
logger.debug('getting claim_id from short url');
// use the daemon to check for claims list
db.sequelize.query(`SELECT claimId FROM Claim WHERE name = '${name}' AND claimId LIKE '${shortId}%' ORDER BY height ASC LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
.then(result => {
switch (result.length) {
case 0:
return reject(new Error('That is an invalid Short Claim Id'));
default: // note results must be sorted
return resolve(result[0].claimId);
}
})
.catch(error => {
reject(error);
});
});
getLongClaimId (claimName, claimId) { // read the various inputs and decide how to return the long claim id
if (claimId && (claimId.length === 40)) {
return new Promise((resolve, reject) => resolve(claimId));
} else if (claimId && claimId.length < 40) {
return getLongClaimIdFromShortClaimId(claimName, claimId); // need to create this function
} else { // if no claim id provided
return getTopFreeClaimIdByClaimName(claimName);
}
},
getShortClaimIdFromLongClaimId (claimId, claimName) {
return new Promise((resolve, reject) => {
@ -159,22 +186,6 @@ module.exports = {
});
});
},
getTopFreeClaim (name) {
return new Promise((resolve, reject) => {
db.sequelize.query(`SELECT * FROM Claim WHERE name = '${name}' ORDER BY amount DESC, height ASC LIMIT 1`, { type: db.sequelize.QueryTypes.SELECT })
.then(result => {
switch (result.length) {
case 0:
return resolve(null);
default:
return resolve(result[0]);
}
})
.catch(error => {
reject(error);
});
});
},
resolveAgainstClaimTable (name, claimId) {
return new Promise((resolve, reject) => {
db.sequelize.query(`SELECT * FROM Claim WHERE name = '${name}' AND claimId = '${claimId}'`, { type: db.sequelize.QueryTypes.SELECT })

View file

@ -1,29 +1,7 @@
const logger = require('winston');
const { getAssetByShortId, getAssetByClaimId, getAssetByName, getChannelContents, getAssetByChannel, serveOrShowAsset } = require('../controllers/serveController.js');
const { getAssetByClaim, getChannelContents, getAssetByChannel, serveOrShowAsset } = require('../controllers/serveController.js');
const { handleRequestError } = require('../helpers/errorHandlers.js');
const SERVE = 'SERVE';
const SHOW = 'SHOW';
const SHOWLITE = 'SHOWLITE';
const CHANNEL = 'CHANNEL';
const CLAIM_ID_SHORT = 'CLAIM_ID_SHORT';
const CLAIM_ID_LONG = 'CLAIM_ID_LONG';
const CLAIM_NAME = 'CLAIM_NAME';
const CHANNELID_INDICATOR = ':';
function getAsset (claimType, channelName, channelId, shortId, fullClaimId, name) {
switch (claimType) {
case CHANNEL:
return getAssetByChannel(channelName, channelId, name);
case CLAIM_ID_SHORT:
return getAssetByShortId(shortId, name);
case CLAIM_ID_LONG:
return getAssetByClaimId(fullClaimId, name);
case CLAIM_NAME:
return getAssetByName(name);
default:
return new Error('that claim type was not found');
}
}
const { SERVE, SHOW, SHOWLITE, CHANNEL, CLAIM, CHANNELID_INDICATOR } = require('../helpers/constants.js');
function isValidClaimId (claimId) {
return ((claimId.length === 40) && !/[^A-Za-z0-9]/g.test(claimId));
@ -37,6 +15,17 @@ 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');
}
}
module.exports = (app) => {
// route to serve a specific asset
app.get('/:identifier/:name', ({ headers, ip, originalUrl, params }, res) => {
@ -44,8 +33,7 @@ module.exports = (app) => {
let name = params.name;
let claimType;
let channelName = null;
let shortId = null;
let fullClaimId = null;
let claimId = null;
let channelId = null;
let method;
let extension;
@ -87,21 +75,13 @@ module.exports = (app) => {
channelName = channelName.substring(0, channelIdIndex);
}
logger.debug('channel name =', channelName);
} else if (identifier.length === 40) {
fullClaimId = identifier;
logger.debug('full claim id =', fullClaimId);
claimType = CLAIM_ID_LONG;
} else if (identifier.length < 40) {
shortId = identifier;
logger.debug('short claim id =', shortId);
claimType = CLAIM_ID_SHORT;
} else {
logger.error('The URL provided could not be parsed');
res.send('that url is invalid');
return;
};
claimId = identifier;
logger.debug('claim id =', claimId);
claimType = CLAIM;
}
// 1. retrieve the asset and information
getAsset(claimType, channelName, channelId, shortId, fullClaimId, name)
getAsset(claimType, channelName, channelId, name, claimId)
// 2. serve or show
.then(fileInfo => {
logger.debug('fileInfo', fileInfo);
@ -171,7 +151,7 @@ module.exports = (app) => {
logger.debug('claim name = ', name);
logger.debug('method =', method);
// 1. retrieve the asset and information
getAsset(CLAIM_NAME, null, null, null, null, name)
getAsset(CLAIM, null, null, null, name, null)
// 2. respond to the request
.then(fileInfo => {
if (!fileInfo) {