Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added oembed controller to v2 api (#10057)
refs #9866 - Added oembed controller to v2 API
- Loading branch information
1 parent
31c35e1
commit 94b3735
Showing
6 changed files
with
181 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
const common = require('../../lib/common'); | ||
const {extract, hasProvider} = require('oembed-parser'); | ||
const Promise = require('bluebird'); | ||
const request = require('../../lib/request'); | ||
const cheerio = require('cheerio'); | ||
|
||
const findUrlWithProvider = (url) => { | ||
let provider; | ||
|
||
// build up a list of URL variations to test against because the oembed | ||
// providers list is not always up to date with scheme or www vs non-www | ||
let baseUrl = url.replace(/^\/\/|^https?:\/\/(?:www\.)?/, ''); | ||
let testUrls = [ | ||
`http://${baseUrl}`, | ||
`https://${baseUrl}`, | ||
`http://www.${baseUrl}`, | ||
`https://www.${baseUrl}` | ||
]; | ||
|
||
for (let testUrl of testUrls) { | ||
provider = hasProvider(testUrl); | ||
if (provider) { | ||
url = testUrl; | ||
break; | ||
} | ||
} | ||
|
||
return {url, provider}; | ||
}; | ||
|
||
const getOembedUrlFromHTML = (html) => { | ||
return cheerio('link[type="application/json+oembed"]', html).attr('href'); | ||
}; | ||
|
||
module.exports = { | ||
docName: 'oembed', | ||
|
||
read: { | ||
permissions: false, | ||
data: [ | ||
'url' | ||
], | ||
options: [], | ||
query({data}) { | ||
let {url} = data; | ||
|
||
if (!url || !url.trim()) { | ||
return Promise.reject(new common.errors.BadRequestError({ | ||
message: common.i18n.t('errors.api.oembed.noUrlProvided') | ||
})); | ||
} | ||
|
||
function unknownProvider() { | ||
return Promise.reject(new common.errors.ValidationError({ | ||
message: common.i18n.t('errors.api.oembed.unknownProvider') | ||
})); | ||
} | ||
|
||
function knownProvider(url) { | ||
return extract(url).catch((err) => { | ||
return Promise.reject(new common.errors.InternalServerError({ | ||
message: err.message | ||
})); | ||
}); | ||
} | ||
|
||
let provider; | ||
({url, provider} = findUrlWithProvider(url)); | ||
|
||
if (provider) { | ||
return knownProvider(url); | ||
} | ||
|
||
// see if the URL is a redirect to cater for shortened urls | ||
return request(url, { | ||
method: 'GET', | ||
timeout: 2 * 1000, | ||
followRedirect: true | ||
}).then((response) => { | ||
if (response.url !== url) { | ||
({url, provider} = findUrlWithProvider(response.url)); | ||
return provider ? knownProvider(url) : unknownProvider(); | ||
} | ||
|
||
const oembedUrl = getOembedUrlFromHTML(response.body); | ||
|
||
if (!oembedUrl) { | ||
return unknownProvider(); | ||
} | ||
|
||
return request(oembedUrl, { | ||
method: 'GET', | ||
json: true | ||
}).then((response) => { | ||
return response.body; | ||
}); | ||
}).catch(() => { | ||
return unknownProvider(); | ||
}); | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const debug = require('ghost-ignition').debug('api:v2:utils:serializers:output:oembed'); | ||
|
||
module.exports = { | ||
all(res, apiConfig, frame) { | ||
debug('all'); | ||
frame.response = res; | ||
debug(frame.response); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
const nock = require('nock'); | ||
const should = require('should'); | ||
const supertest = require('supertest'); | ||
const testUtils = require('../../../../utils'); | ||
const config = require('../../../../../../core/server/config'); | ||
const localUtils = require('./utils'); | ||
|
||
const ghost = testUtils.startGhost; | ||
|
||
describe('Oembed API', function () { | ||
let ghostServer, request; | ||
|
||
before(function () { | ||
return ghost() | ||
.then((_ghostServer) => { | ||
ghostServer = _ghostServer; | ||
request = supertest.agent(config.get('url')); | ||
}) | ||
.then(() => { | ||
return localUtils.doAuth(request); | ||
}); | ||
}); | ||
|
||
describe('success', function () { | ||
it('can fetch an embed', function (done) { | ||
let requestMock = nock('https://www.youtube.com') | ||
.get('/oembed') | ||
.query(true) | ||
.reply(200, { | ||
html: '<iframe width="480" height="270" src="https://www.youtube.com/embed/E5yFcdPAGv0?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>', | ||
thumbnail_width: 480, | ||
width: 480, | ||
author_url: 'https://www.youtube.com/user/gorillaz', | ||
height: 270, | ||
thumbnail_height: 360, | ||
provider_name: 'YouTube', | ||
title: 'Gorillaz - Humility (Official Video)', | ||
provider_url: 'https://www.youtube.com/', | ||
author_name: 'Gorillaz', | ||
version: '1.0', | ||
thumbnail_url: 'https://i.ytimg.com/vi/E5yFcdPAGv0/hqdefault.jpg', | ||
type: 'video' | ||
}); | ||
|
||
request.get(localUtils.API.getApiQuery('oembed/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DE5yFcdPAGv0')) | ||
.set('Origin', config.get('url')) | ||
.expect('Content-Type', /json/) | ||
.expect('Cache-Control', testUtils.cacheRules.private) | ||
.expect(200) | ||
.end(function (err, res) { | ||
if (err) { | ||
return done(err); | ||
} | ||
|
||
requestMock.isDone().should.be.true(); | ||
should.exist(res.body.html); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |