Development #287

Merged
bones7242 merged 58 commits from development into master 2017-12-11 20:53:02 +01:00
7 changed files with 61 additions and 57 deletions
Showing only changes of commit 0ae03d0684 - Show all commits

View file

@ -24,19 +24,23 @@ spee.ch is a single-serving site that reads and publishes images and videos to a
## API ## API
#### GET #### GET
* /api/resolve/:name * /api/claim-resolve/:name
* example: `curl https://spee.ch/api/resolve/doitlive` * example: `curl https://spee.ch/api/claim-resolve/doitlive`
* /api/claim-list/:name * /api/claim-list/:name
* example: `curl https://spee.ch/api/claim-list/doitlive` * example: `curl https://spee.ch/api/claim-list/doitlive`
* /api/is-claim-available/:name (returns `true`/`false` for whether a name is available through spee.ch) * /api/claim-is-available/:name (
* example: `curl https://spee.ch/api/is-claim-available/doitlive` * returns `true`/`false` for whether a name is available through spee.ch
* example: `curl https://spee.ch/api/claim-is-available/doitlive`
* /api/channel-is-available/:name (
* returns `true`/`false` for whether a channel is available through spee.ch
* example: `curl https://spee.ch/api/channel-is-available/@CoolChannel`
#### POST #### POST
* /api/publish * /api/claim-publish
* example: `curl -X POST -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg' https://spee.ch/api/publish` * example: `curl -X POST -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg' https://spee.ch/api/claim-publish`
* Parameters: * Parameters:
* `name` * `name`
* `file` (.mp4, .jpeg, .jpg, .gif, or .png) * `file` (must be type .mp4, .jpeg, .jpg, .gif, or .png)
* `nsfw` (optional) * `nsfw` (optional)
* `license` (optional) * `license` (optional)
* `title` (optional) * `title` (optional)

View file

@ -6,9 +6,9 @@ const NO_CHANNEL = 'NO_CHANNEL';
const NO_FILE = 'NO_FILE'; const NO_FILE = 'NO_FILE';
module.exports = { module.exports = {
getClaimId (channelName, channelId, name, claimId) { getClaimId (channelName, channelClaimId, name, claimId) {
if (channelName) { if (channelName) {
return module.exports.getClaimIdByChannel(channelName, channelId, name); return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);
} else { } else {
return module.exports.getClaimIdByClaim(name, claimId); return module.exports.getClaimIdByClaim(name, claimId);
} }
@ -25,10 +25,10 @@ module.exports = {
}); });
}); });
}, },
getClaimIdByChannel (channelName, channelId, claimName) { getClaimIdByChannel (channelName, channelClaimId, claimName) {
logger.debug(`getClaimIdByChannel(${channelName}, ${channelId}, ${claimName})`); logger.debug(`getClaimIdByChannel(${channelName}, ${channelClaimId}, ${claimName})`);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
db.Certificate.getLongChannelId(channelName, channelId) // 1. get the long channel id db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id
.then(result => { .then(result => {
if (result === NO_CHANNEL) { if (result === NO_CHANNEL) {
resolve(result); // resolves NO_CHANNEL resolve(result); // resolves NO_CHANNEL
@ -44,24 +44,24 @@ module.exports = {
}); });
}); });
}, },
getChannelContents (channelName, channelId) { getChannelContents (channelName, channelClaimId) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let longChannelId; let longChannelClaimId;
let shortChannelId; let shortChannelClaimId;
db.Certificate.getLongChannelId(channelName, channelId) // 1. get the long channel Id db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel Id
.then(result => { // 2. get all claims for that channel .then(result => { // 2. get all claims for that channel
if (result === NO_CHANNEL) { if (result === NO_CHANNEL) {
return NO_CHANNEL; return NO_CHANNEL;
} }
longChannelId = result; longChannelClaimId = result;
return db.Certificate.getShortChannelIdFromLongChannelId(longChannelId, channelName); return db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName);
}) })
.then(result => { // 3. get all Claim records for this channel .then(result => { // 3. get all Claim records for this channel
if (result === NO_CHANNEL) { if (result === NO_CHANNEL) {
return NO_CHANNEL; return NO_CHANNEL;
} }
shortChannelId = result; shortChannelClaimId = result;
return db.Claim.getAllChannelClaims(longChannelId); return db.Claim.getAllChannelClaims(longChannelClaimId);
}) })
.then(result => { // 4. add extra data not available from Claim table .then(result => { // 4. add extra data not available from Claim table
if (result === NO_CHANNEL) { if (result === NO_CHANNEL) {
@ -71,17 +71,17 @@ module.exports = {
if (result) { if (result) {
result.forEach(element => { result.forEach(element => {
const fileExtenstion = element.contentType.substring(element.contentType.lastIndexOf('/') + 1); const fileExtenstion = element.contentType.substring(element.contentType.lastIndexOf('/') + 1);
element['showUrlLong'] = `/${channelName}:${longChannelId}/${element.name}`; element['showUrlLong'] = `/${channelName}:${longChannelClaimId}/${element.name}`;
element['directUrlLong'] = `/${channelName}:${longChannelId}/${element.name}.${fileExtenstion}`; element['directUrlLong'] = `/${channelName}:${longChannelClaimId}/${element.name}.${fileExtenstion}`;
element['showUrlShort'] = `/${channelName}:${shortChannelId}/${element.name}`; element['showUrlShort'] = `/${channelName}:${shortChannelClaimId}/${element.name}`;
element['directUrlShort'] = `/${channelName}:${shortChannelId}/${element.name}.${fileExtenstion}`; element['directUrlShort'] = `/${channelName}:${shortChannelClaimId}/${element.name}.${fileExtenstion}`;
element['thumbnail'] = module.exports.chooseThumbnail(element, DEFAULT_THUMBNAIL); element['thumbnail'] = module.exports.chooseThumbnail(element, DEFAULT_THUMBNAIL);
}); });
} }
resolve({ resolve({
channelName, channelName,
longChannelId, longChannelClaimId,
shortChannelId, shortChannelClaimId,
claims: result, claims: result,
}); });
}) })

View file

@ -78,7 +78,7 @@ const Asset = function () {
}; };
this.checkClaimAvailability = function () { this.checkClaimAvailability = function () {
const that = this; const that = this;
const uri = `/api/local-file-available/${this.state.claimName}/${this.state.claimId}`; const uri = `/api/file-is-available/${this.state.claimName}/${this.state.claimId}`;
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
console.log(`checking local availability for ${this.state.claimName}#${this.state.claimId}`) console.log(`checking local availability for ${this.state.claimName}#${this.state.claimId}`)
xhr.open("GET", uri, true); xhr.open("GET", uri, true);
@ -103,7 +103,7 @@ const Asset = function () {
}; };
this.getAsset = function() { this.getAsset = function() {
const that = this; const that = this;
const uri = `/api/get-claim/${this.state.claimName}/${this.state.claimId}`; const uri = `/api/claim-get/${this.state.claimName}/${this.state.claimId}`;
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
console.log(`getting ${this.state.claimName}#${this.state.claimId}`) console.log(`getting ${this.state.claimName}#${this.state.claimId}`)
xhr.open("GET", uri, true); xhr.open("GET", uri, true);

View file

@ -102,7 +102,7 @@ const publishFileFunctions = {
return fd; return fd;
}, },
publishFile: function (file, metadata) { publishFile: function (file, metadata) {
var uri = "/api/publish"; var uri = "/api/claim-publish";
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
var fd = this.appendDataToFormData(file, metadata); var fd = this.appendDataToFormData(file, metadata);
var that = this; var that = this;

View file

@ -119,13 +119,13 @@ const validationFunctions = {
checkClaimName: function (name) { checkClaimName: function (name) {
const successDisplayElement = document.getElementById('input-success-claim-name'); const successDisplayElement = document.getElementById('input-success-claim-name');
const errorDisplayElement = document.getElementById('input-error-claim-name'); const errorDisplayElement = document.getElementById('input-error-claim-name');
this.checkAvailability(name, successDisplayElement, errorDisplayElement, this.validateClaimName, 'Sorry, that ending is already taken', '/api/is-claim-available/'); this.checkAvailability(name, successDisplayElement, errorDisplayElement, this.validateClaimName, 'Sorry, that ending is already taken', '/api/claim-is-available/');
}, },
checkChannelName: function (name) { checkChannelName: function (name) {
const successDisplayElement = document.getElementById('input-success-channel-name'); const successDisplayElement = document.getElementById('input-success-channel-name');
const errorDisplayElement = document.getElementById('input-error-channel-name'); const errorDisplayElement = document.getElementById('input-error-channel-name');
name = `@${name}`; name = `@${name}`;
this.checkAvailability(name, successDisplayElement, errorDisplayElement, this.validateChannelName, 'Sorry, that name is already taken', '/api/is-channel-available/'); this.checkAvailability(name, successDisplayElement, errorDisplayElement, this.validateChannelName, 'Sorry, that name is already taken', '/api/channel-is-available/');
}, },
// validation function which checks all aspects of the publish submission // validation function which checks all aspects of the publish submission
validateFilePublishSubmission: function (stagedFiles, metadata) { validateFilePublishSubmission: function (stagedFiles, metadata) {
@ -162,7 +162,7 @@ const validationFunctions = {
return; return;
} }
// if all validation passes, check availability of the name (note: do we need to re-validate channel name vs. credentials as well?) // if all validation passes, check availability of the name (note: do we need to re-validate channel name vs. credentials as well?)
return that.isNameAvailable(claimName, '/api/is-claim-available/') return that.isNameAvailable(claimName, '/api/claim-is-available/')
.then(result => { .then(result => {
if (result) { if (result) {
resolve(); resolve();
@ -193,7 +193,7 @@ const validationFunctions = {
return reject(error); return reject(error);
} }
// 3. if all validation passes, check availability of the name // 3. if all validation passes, check availability of the name
that.isNameAvailable(channelName, '/api/is-channel-available/') // validate the availability that.isNameAvailable(channelName, '/api/channel-is-available/') // validate the availability
.then(function(result) { .then(function(result) {
if (result) { if (result) {
resolve(); resolve();

View file

@ -43,7 +43,7 @@ module.exports = (app) => {
}); });
}); });
// route to see if asset is available locally // route to see if asset is available locally
app.get('/api/local-file-available/:name/:claimId', ({ ip, originalUrl, params }, res) => { app.get('/api/file-is-available/:name/:claimId', ({ ip, originalUrl, params }, res) => {
const name = params.name; const name = params.name;
const claimId = params.claimId; const claimId = params.claimId;
let isLocalFileAvailable = false; let isLocalFileAvailable = false;
@ -59,7 +59,7 @@ module.exports = (app) => {
}); });
}); });
// route to get an asset // route to get an asset
app.get('/api/get-claim/:name/:claimId', ({ ip, originalUrl, params }, res) => { app.get('/api/claim-get/:name/:claimId', ({ ip, originalUrl, params }, res) => {
const name = params.name; const name = params.name;
const claimId = params.claimId; const claimId = params.claimId;
// resolve the claim // resolve the claim
@ -86,7 +86,7 @@ module.exports = (app) => {
}); });
// route to check whether spee.ch has published to a claim // route to check whether spee.ch has published to a claim
app.get('/api/is-claim-available/:name', ({ params }, res) => { app.get('/api/claim-is-available/:name', ({ params }, res) => {
checkClaimNameAvailability(params.name) checkClaimNameAvailability(params.name)
.then(result => { .then(result => {
if (result === true) { if (result === true) {
@ -101,7 +101,7 @@ module.exports = (app) => {
}); });
}); });
// route to check whether spee.ch has published to a channel // route to check whether spee.ch has published to a channel
app.get('/api/is-channel-available/:name', ({ params }, res) => { app.get('/api/channel-is-available/:name', ({ params }, res) => {
checkChannelAvailability(params.name) checkChannelAvailability(params.name)
.then(result => { .then(result => {
if (result === true) { if (result === true) {
@ -112,12 +112,12 @@ module.exports = (app) => {
} }
}) })
.catch(error => { .catch(error => {
logger.debug('api/is-channel-available/ error', error); logger.debug('api/channel-is-available/ error', error);
res.status(500).json(error); res.status(500).json(error);
}); });
}); });
// route to run a resolve request on the daemon // route to run a resolve request on the daemon
app.get('/api/resolve/:uri', ({ headers, ip, originalUrl, params }, res) => { app.get('/api/claim-resolve/:uri', ({ headers, ip, originalUrl, params }, res) => {
resolveUri(params.uri) resolveUri(params.uri)
.then(resolvedUri => { .then(resolvedUri => {
postToStats('serve', originalUrl, ip, null, null, 'success'); postToStats('serve', originalUrl, ip, null, null, 'success');
@ -128,7 +128,7 @@ module.exports = (app) => {
}); });
}); });
// route to run a publish request on the daemon // route to run a publish request on the daemon
app.post('/api/publish', multipartMiddleware, ({ body, files, ip, originalUrl, user }, res) => { app.post('/api/claim-publish', multipartMiddleware, ({ body, files, ip, originalUrl, user }, res) => {
let file, fileName, filePath, fileType, name, nsfw, license, title, description, thumbnail, anonymous, skipAuth, channelName, channelPassword; let file, fileName, filePath, fileType, name, nsfw, license, title, description, thumbnail, anonymous, skipAuth, channelName, channelPassword;
// validate that mandatory parts of the request are present // validate that mandatory parts of the request are present
try { try {
@ -179,7 +179,7 @@ module.exports = (app) => {
} }
} }
channelName = cleanseChannelName(channelName); channelName = cleanseChannelName(channelName);
logger.debug(`/api/publish > name: ${name}, license: ${license} title: "${title}" description: "${description}" channelName: "${channelName}" channelPassword: "${channelPassword}" nsfw: "${nsfw}"`); logger.debug(`name: ${name}, license: ${license} title: "${title}" description: "${description}" channelName: "${channelName}" channelPassword: "${channelPassword}" nsfw: "${nsfw}"`);
// check channel authorization // check channel authorization
authenticateOrSkip(skipAuth, channelName, channelPassword) authenticateOrSkip(skipAuth, channelName, channelPassword)
.then(authenticated => { .then(authenticated => {
@ -216,7 +216,7 @@ module.exports = (app) => {
}); });
}); });
// route to get a short claim id from long claim Id // route to get a short claim id from long claim Id
app.get('/api/short-claim-id/:longId/:name', ({ params }, res) => { app.get('/api/claim-shorten-id/:longId/:name', ({ params }, res) => {
db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name) db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name)
.then(shortId => { .then(shortId => {
res.status(200).json(shortId); res.status(200).json(shortId);
@ -227,7 +227,7 @@ module.exports = (app) => {
}); });
}); });
// route to get a short channel id from long channel Id // route to get a short channel id from long channel Id
app.get('/api/short-channel-id/:longId/:name', ({ ip, originalUrl, params }, res) => { app.get('/api/channel-shorten-id/:longId/:name', ({ ip, originalUrl, params }, res) => {
db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name) db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name)
.then(shortId => { .then(shortId => {
logger.debug('sending back short channel id', shortId); logger.debug('sending back short channel id', shortId);

View file

@ -105,16 +105,16 @@ function returnOptionsForChannelPageRendering (result, query) {
const totalPages = determineTotalPages(result.claims); const totalPages = determineTotalPages(result.claims);
const paginationPage = getPage(query); const paginationPage = getPage(query);
const options = { const options = {
layout : 'channel', layout : 'channel',
channelName : result.channelName, channelName : result.channelName,
longChannelId : result.longChannelId, longChannelClaimId : result.longChannelClaimId,
shortChannelId: result.shortChannelId, shortChannelClaimId: result.shortChannelClaimId,
claims : extractPageFromClaims(result.claims, paginationPage), claims : extractPageFromClaims(result.claims, paginationPage),
previousPage : determinePreviousPage(paginationPage), previousPage : determinePreviousPage(paginationPage),
currentPage : paginationPage, currentPage : paginationPage,
nextPage : determineNextPage(totalPages, paginationPage), nextPage : determineNextPage(totalPages, paginationPage),
totalPages : totalPages, totalPages : totalPages,
totalResults : determineTotalClaims(result), totalResults : determineTotalClaims(result),
}; };
return options; return options;
} }
@ -131,10 +131,10 @@ function sendChannelContentsToClient (result, query, res) {
function showChannelPageToClient (uri, originalUrl, ip, query, res) { function showChannelPageToClient (uri, originalUrl, ip, query, res) {
let channelName = returnChannelNameFromUri(uri); let channelName = returnChannelNameFromUri(uri);
logger.debug('channel name =', channelName); logger.debug('channel name =', channelName);
let channelId = returnChannelIdFromUri(uri); let channelClaimId = returnChannelIdFromUri(uri);
logger.debug('channel Id =', channelId); logger.debug('channel Id =', channelClaimId);
// 1. retrieve the channel contents // 1. retrieve the channel contents
getChannelContents(channelName, channelId) getChannelContents(channelName, channelClaimId)
.then(result => { .then(result => {
sendChannelContentsToClient(result, query, res); sendChannelContentsToClient(result, query, res);
}) })
@ -202,7 +202,7 @@ function serveAssetToClient (claimId, name, res) {
.then(fileInfo => { .then(fileInfo => {
logger.debug('fileInfo:', fileInfo); logger.debug('fileInfo:', fileInfo);
if (fileInfo === NO_FILE) { if (fileInfo === NO_FILE) {
res.status(307).redirect(`/api/get-claim/${name}/${claimId}`); res.status(307).redirect(`/api/claim-get/${name}/${claimId}`);
} else { } else {
return serveHelpers.serveFile(fileInfo, claimId, name, res); return serveHelpers.serveFile(fileInfo, claimId, name, res);
} }