added basic support for /@channelname
This commit is contained in:
parent
bcf0484b5b
commit
2490d709c9
4 changed files with 190 additions and 73 deletions
|
@ -1,43 +1,14 @@
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
const db = require('../models');
|
const db = require('../models');
|
||||||
|
|
||||||
// function determineShortChannelId (name, longChannelId) {
|
function createOpenGraphInfo ({ fileType, claimId, name, fileName, fileExt }) {
|
||||||
// return new Promise((resolve, reject) => {
|
return {
|
||||||
// logger.debug('finding short channel id');
|
embedUrl : `https://spee.ch/embed/${claimId}/${name}`,
|
||||||
// db.sequelize.query(`SELECT claimId, height FROM Certificate WHERE name = '${name}' ORDER BY height;`, { type: db.sequelize.QueryTypes.SELECT })
|
showUrl : `https://spee.ch/${claimId}/${name}`,
|
||||||
// .then(result => {
|
source : `https://spee.ch/${claimId}/${name}${fileExt}`,
|
||||||
// switch (result.length) {
|
directFileUrl: `https://spee.ch/media/${fileName}`,
|
||||||
// case 0:
|
};
|
||||||
// return reject(new Error('That is an invalid channel name'));
|
}
|
||||||
// default:
|
|
||||||
// let certificateIndex;
|
|
||||||
// let shortId = longChannelId.substring(0, 1); // default sort id is the first letter
|
|
||||||
// let shortIdLength = 0;
|
|
||||||
// // find the index of this certificate
|
|
||||||
// certificateIndex = result.findIndex(element => {
|
|
||||||
// return element.claimId === longChannelId;
|
|
||||||
// });
|
|
||||||
// if (certificateIndex < 0) { throw new Error('claimid not found in possible sorted list') }
|
|
||||||
// // get an array of all certificates with lower height
|
|
||||||
// let possibleMatches = result.slice(0, certificateIndex);
|
|
||||||
// // remove certificates with the same prefixes until none are left.
|
|
||||||
// while (possibleMatches.length > 0) {
|
|
||||||
// shortIdLength += 1;
|
|
||||||
// shortId = longChannelId.substring(0, shortIdLength);
|
|
||||||
// possibleMatches = possibleMatches.filter(element => {
|
|
||||||
// return (element.claimId.substring(0, shortIdLength) === shortId);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// // return the short Id
|
|
||||||
// logger.debug('short claim id ===', shortId);
|
|
||||||
// return resolve(shortId);
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .catch(error => {
|
|
||||||
// reject(error);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
function getLongChannelId (channelName, channelId) {
|
function getLongChannelId (channelName, channelId) {
|
||||||
if (channelId && (channelId.length === 40)) { // full channel id
|
if (channelId && (channelId.length === 40)) { // full channel id
|
||||||
|
@ -108,6 +79,24 @@ function getClaimIdByLongChannelId (channelId, claimName) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllChannelClaims (channelId) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
logger.debug(`finding all claims in channel "${channelId}"`);
|
||||||
|
db.sequelize.query(`SELECT * FROM Claim WHERE certificateId = '${channelId}' ORDeR BY height DESC;`, { type: db.sequelize.QueryTypes.SELECT })
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(null);
|
||||||
|
default:
|
||||||
|
return resolve(result);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function determineShortClaimId (claimId, height, claimList) {
|
function determineShortClaimId (claimId, height, claimList) {
|
||||||
logger.debug('determining short url based on claim id and claim list');
|
logger.debug('determining short url based on claim id and claim list');
|
||||||
logger.debug('claimlist starting length:', claimList.length);
|
logger.debug('claimlist starting length:', claimList.length);
|
||||||
|
@ -155,13 +144,42 @@ function determineShortClaimId (claimId, height, claimList) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createOpenGraphInfo ({ fileType, claimId, name, fileName, fileExt }) {
|
function getShortChannelId (channelName, longChannelId) {
|
||||||
return {
|
return new Promise((resolve, reject) => {
|
||||||
embedUrl : `https://spee.ch/embed/${claimId}/${name}`,
|
logger.debug('finding short channel id');
|
||||||
showUrl : `https://spee.ch/${claimId}/${name}`,
|
db.sequelize.query(`SELECT claimId, height FROM Certificate WHERE name = '${channelName}' ORDER BY height;`, { type: db.sequelize.QueryTypes.SELECT })
|
||||||
source : `https://spee.ch/${claimId}/${name}${fileExt}`,
|
.then(result => {
|
||||||
directFileUrl: `https://spee.ch/media/${fileName}`,
|
switch (result.length) {
|
||||||
};
|
case 0:
|
||||||
|
return reject(new Error('That is an invalid channel name'));
|
||||||
|
default:
|
||||||
|
let certificateIndex;
|
||||||
|
let shortId = longChannelId.substring(0, 1); // default sort id is the first letter
|
||||||
|
let shortIdLength = 0;
|
||||||
|
// find the index of this certificate
|
||||||
|
certificateIndex = result.findIndex(element => {
|
||||||
|
return element.claimId === longChannelId;
|
||||||
|
});
|
||||||
|
if (certificateIndex < 0) { throw new Error('claimid not found in possible sorted list') }
|
||||||
|
// get an array of all certificates with lower height
|
||||||
|
let possibleMatches = result.slice(0, certificateIndex);
|
||||||
|
// remove certificates with the same prefixes until none are left.
|
||||||
|
while (possibleMatches.length > 0) {
|
||||||
|
shortIdLength += 1;
|
||||||
|
shortId = longChannelId.substring(0, shortIdLength);
|
||||||
|
possibleMatches = possibleMatches.filter(element => {
|
||||||
|
return (element.claimId.substring(0, shortIdLength) === shortId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// return the short Id
|
||||||
|
logger.debug('short claim id ===', shortId);
|
||||||
|
return resolve(shortId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -300,4 +318,33 @@ module.exports = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getChannelContents (channelName, channelId) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let longChannelId;
|
||||||
|
let shortChannelId;
|
||||||
|
// 1. get the long channel Id
|
||||||
|
getLongChannelId(channelName, channelId)
|
||||||
|
// 2. get all claims for that channel
|
||||||
|
.then(result => {
|
||||||
|
longChannelId = result;
|
||||||
|
return getShortChannelId(channelName, longChannelId);
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
shortChannelId = result;
|
||||||
|
return getAllChannelClaims(longChannelId);
|
||||||
|
})
|
||||||
|
.then(allChannelClaims => {
|
||||||
|
allChannelClaims.forEach(element => {
|
||||||
|
element['channelName'] = channelName;
|
||||||
|
element['longChannelId'] = longChannelId;
|
||||||
|
element['shortChannelId'] = shortChannelId;
|
||||||
|
element['fileExtension'] = element.contentType.substring(element.contentType.lastIndexOf('/') + 1);
|
||||||
|
});
|
||||||
|
return resolve(allChannelClaims);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
const { serveFile, showFile, showFileLite, getShortIdFromClaimId, resolveAgainstClaimTable } = require('../helpers/serveHelpers.js');
|
const { serveFile, showFile, showFileLite, getShortIdFromClaimId, resolveAgainstClaimTable, getChannelContents } = require('../helpers/serveHelpers.js');
|
||||||
const { getAssetByChannel, getAssetByShortId, getAssetByClaimId, getAssetByName } = require('../controllers/serveController.js');
|
const { getAssetByChannel, getAssetByShortId, getAssetByClaimId, getAssetByName } = require('../controllers/serveController.js');
|
||||||
const { handleRequestError } = require('../helpers/errorHandlers.js');
|
const { handleRequestError } = require('../helpers/errorHandlers.js');
|
||||||
const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
|
const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
|
||||||
|
@ -169,6 +169,35 @@ module.exports = (app) => {
|
||||||
let name = params.name;
|
let name = params.name;
|
||||||
let method;
|
let method;
|
||||||
let fileExtension;
|
let fileExtension;
|
||||||
|
let channelName = null;
|
||||||
|
let channelId = null;
|
||||||
|
if (name.charAt(0) === '@') {
|
||||||
|
channelName = name;
|
||||||
|
const channelIdIndex = channelName.indexOf(CHANNELID_INDICATOR);
|
||||||
|
if (channelIdIndex !== -1) {
|
||||||
|
channelId = channelName.substring(channelIdIndex + 1);
|
||||||
|
channelName = channelName.substring(0, channelIdIndex);
|
||||||
|
}
|
||||||
|
logger.debug('channel name =', channelName);
|
||||||
|
logger.debug('channel Id =', channelId);
|
||||||
|
// 1. retrieve the channel contents
|
||||||
|
getChannelContents(channelName, channelId)
|
||||||
|
// 2. respond to the request
|
||||||
|
.then(channelContents => {
|
||||||
|
if (!channelContents) {
|
||||||
|
res.status(200).render('noChannel');
|
||||||
|
} else {
|
||||||
|
const handlebarsData = {
|
||||||
|
channelName,
|
||||||
|
channelContents,
|
||||||
|
};
|
||||||
|
res.status(200).render('channel', handlebarsData);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
handleRequestError('serve', originalUrl, ip, error, res);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
if (name.indexOf('.') !== -1) {
|
if (name.indexOf('.') !== -1) {
|
||||||
method = SERVE;
|
method = SERVE;
|
||||||
if (headers['accept'] && headers['accept'].split(',').includes('text/html')) {
|
if (headers['accept'] && headers['accept'].split(',').includes('text/html')) {
|
||||||
|
@ -187,7 +216,7 @@ module.exports = (app) => {
|
||||||
logger.debug('method =', method);
|
logger.debug('method =', method);
|
||||||
// 1. retrieve the asset and information
|
// 1. retrieve the asset and information
|
||||||
getAsset(CLAIM_NAME, null, null, null, null, name)
|
getAsset(CLAIM_NAME, null, null, null, null, name)
|
||||||
// 2. serve or show
|
// 2. respond to the request
|
||||||
.then(fileInfo => {
|
.then(fileInfo => {
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
res.status(200).render('noClaims');
|
res.status(200).render('noClaims');
|
||||||
|
@ -202,5 +231,6 @@ module.exports = (app) => {
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
handleRequestError('serve', originalUrl, ip, error, res);
|
handleRequestError('serve', originalUrl, ip, error, res);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
32
views/channel.handlebars
Normal file
32
views/channel.handlebars
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<div class="wrapper">
|
||||||
|
{{> topBar}}
|
||||||
|
<div>
|
||||||
|
<h3>{{this.channelName}}</h3>
|
||||||
|
<p>Below are all the free claims in this channel.</p>
|
||||||
|
{{#each channelContents}}
|
||||||
|
<div class="all-claims-item">
|
||||||
|
{{#ifConditional this.fileType '===' 'video/mp4'}}
|
||||||
|
<video class="all-claims-img" autoplay controls>
|
||||||
|
<source src="/{{this.claimId}}/{{this.name}}.{{this.fileExtension}}">
|
||||||
|
{{!--fallback--}}
|
||||||
|
Your browser does not support the <code>video</code> element.
|
||||||
|
</video>
|
||||||
|
{{else}}
|
||||||
|
<img class="all-claims-img" src="/{{this.claimId}}/{{this.name}}.{{this.fileExtension}}" />
|
||||||
|
{{/ifConditional}}
|
||||||
|
|
||||||
|
<div class="all-claims-details">
|
||||||
|
<ul style="list-style-type:none">
|
||||||
|
<li>Title: {{this.title}}</li>
|
||||||
|
<li>Description: {{this.description}}</li>
|
||||||
|
<li>License: {{this.license}}</li>
|
||||||
|
<li>Link: <a href="/{{this.channelName}}:{{this.shortChannelId}}/{{this.name}}.{{this.fileExtension}}">spee.ch/{{this.channelName}}:{{this.shortChannelId}}/{{this.name}}.{{this.fileExtension}}</a></li>
|
||||||
|
<li>Claim: {{this.name}}</li>
|
||||||
|
<li>Claim Id: {{this.claimId}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{> footer}}
|
||||||
|
</div>
|
8
views/noChannel.handlebars
Normal file
8
views/noChannel.handlebars
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="wrapper">
|
||||||
|
{{> topBar}}
|
||||||
|
<div>
|
||||||
|
<h3>No Claims</h3>
|
||||||
|
<p>There are no free, public assets on this channel.</p>
|
||||||
|
<p><i>If you think this message is an error, contact us in Slack!</i></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in a new issue