add oEmbed Support for video claims (#376)
* Refactor html.js * Fix Favicon * Refactor rss.js * Create oEmbed.js
This commit is contained in:
parent
7613d07c35
commit
34eaccdbee
6 changed files with 201 additions and 57 deletions
|
@ -6,11 +6,11 @@ const config = {
|
||||||
WEBPACK_WEB_PORT: process.env.WEBPACK_WEB_PORT,
|
WEBPACK_WEB_PORT: process.env.WEBPACK_WEB_PORT,
|
||||||
WEBPACK_ELECTRON_PORT: process.env.WEBPACK_ELECTRON_PORT,
|
WEBPACK_ELECTRON_PORT: process.env.WEBPACK_ELECTRON_PORT,
|
||||||
WEB_SERVER_PORT: process.env.WEB_SERVER_PORT,
|
WEB_SERVER_PORT: process.env.WEB_SERVER_PORT,
|
||||||
LBRY_WEB_API: process.env.LBRY_WEB_API, //api.na-backend.odysee.com',
|
LBRY_WEB_API: process.env.LBRY_WEB_API, // api.na-backend.odysee.com',
|
||||||
LBRY_WEB_PUBLISH_API: process.env.LBRY_WEB_PUBLISH_API,
|
LBRY_WEB_PUBLISH_API: process.env.LBRY_WEB_PUBLISH_API,
|
||||||
LBRY_WEB_PUBLISH_API_V2: process.env.LBRY_WEB_PUBLISH_API_V2,
|
LBRY_WEB_PUBLISH_API_V2: process.env.LBRY_WEB_PUBLISH_API_V2,
|
||||||
LBRY_API_URL: process.env.LBRY_API_URL, //api.lbry.com',
|
LBRY_API_URL: process.env.LBRY_API_URL, // api.lbry.com',
|
||||||
LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
|
LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, // cdn.lbryplayer.xyz',
|
||||||
LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
|
LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
|
||||||
SEARCH_SERVER_API: process.env.SEARCH_SERVER_API,
|
SEARCH_SERVER_API: process.env.SEARCH_SERVER_API,
|
||||||
SEARCH_SERVER_API_ALT: process.env.SEARCH_SERVER_API_ALT,
|
SEARCH_SERVER_API_ALT: process.env.SEARCH_SERVER_API_ALT,
|
||||||
|
@ -34,7 +34,6 @@ const config = {
|
||||||
TWITTER_ACCOUNT: process.env.TWITTER_ACCOUNT,
|
TWITTER_ACCOUNT: process.env.TWITTER_ACCOUNT,
|
||||||
// LOGO
|
// LOGO
|
||||||
LOGO_TITLE: process.env.LOGO_TITLE,
|
LOGO_TITLE: process.env.LOGO_TITLE,
|
||||||
FAVICON: process.env.FAVICON,
|
|
||||||
LOGO: process.env.LOGO,
|
LOGO: process.env.LOGO,
|
||||||
LOGO_TEXT_LIGHT: process.env.LOGO_TEXT_LIGHT,
|
LOGO_TEXT_LIGHT: process.env.LOGO_TEXT_LIGHT,
|
||||||
LOGO_TEXT_DARK: process.env.LOGO_TEXT_DARK,
|
LOGO_TEXT_DARK: process.env.LOGO_TEXT_DARK,
|
||||||
|
@ -92,5 +91,6 @@ const config = {
|
||||||
|
|
||||||
config.URL_DEV = `http://localhost:${config.WEBPACK_WEB_PORT}`;
|
config.URL_DEV = `http://localhost:${config.WEBPACK_WEB_PORT}`;
|
||||||
config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
|
config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
|
||||||
|
config.FAVICON = `/public/favicon-spaceman.png`;
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
|
|
@ -1,39 +1,42 @@
|
||||||
const {
|
const {
|
||||||
URL,
|
|
||||||
// DOMAIN,
|
|
||||||
SITE_TITLE,
|
|
||||||
SITE_CANONICAL_URL,
|
|
||||||
OG_HOMEPAGE_TITLE,
|
|
||||||
OG_TITLE_SUFFIX,
|
|
||||||
OG_IMAGE_URL,
|
|
||||||
SITE_DESCRIPTION,
|
|
||||||
SITE_NAME,
|
|
||||||
FAVICON,
|
FAVICON,
|
||||||
LBRY_WEB_API,
|
LBRY_WEB_API,
|
||||||
|
OG_HOMEPAGE_TITLE,
|
||||||
|
OG_IMAGE_URL,
|
||||||
|
OG_TITLE_SUFFIX,
|
||||||
|
SITE_CANONICAL_URL,
|
||||||
|
SITE_DESCRIPTION,
|
||||||
|
SITE_NAME,
|
||||||
|
SITE_TITLE,
|
||||||
THUMBNAIL_CARDS_CDN_URL,
|
THUMBNAIL_CARDS_CDN_URL,
|
||||||
|
URL,
|
||||||
} = require('../../config.js');
|
} = require('../../config.js');
|
||||||
|
|
||||||
const { lbryProxy: Lbry } = require('../lbry');
|
|
||||||
const { generateEmbedUrl, generateStreamUrl, generateDirectUrl } = require('../../ui/util/web');
|
|
||||||
const PAGES = require('../../ui/constants/pages');
|
|
||||||
const { CATEGORY_METADATA } = require('./category-metadata');
|
const { CATEGORY_METADATA } = require('./category-metadata');
|
||||||
const { parseURI, normalizeURI } = require('./lbryURI');
|
const { generateEmbedUrl, generateStreamUrl, generateDirectUrl } = require('../../ui/util/web');
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const moment = require('moment');
|
|
||||||
const removeMd = require('remove-markdown');
|
|
||||||
const { getJsBundleId } = require('../bundle-id.js');
|
const { getJsBundleId } = require('../bundle-id.js');
|
||||||
|
const { lbryProxy: Lbry } = require('../lbry');
|
||||||
|
const { parseURI, normalizeClaimUrl } = require('./lbryURI');
|
||||||
|
const fs = require('fs');
|
||||||
|
const moment = require('moment');
|
||||||
|
const PAGES = require('../../ui/constants/pages');
|
||||||
|
const path = require('path');
|
||||||
|
const removeMd = require('remove-markdown');
|
||||||
|
|
||||||
const jsBundleId = getJsBundleId();
|
const jsBundleId = getJsBundleId();
|
||||||
const SDK_API_PATH = `${LBRY_WEB_API}/api/v1`;
|
const SDK_API_PATH = `${LBRY_WEB_API}/api/v1`;
|
||||||
const PROXY_URL = `${SDK_API_PATH}/proxy`;
|
const PROXY_URL = `${SDK_API_PATH}/proxy`;
|
||||||
Lbry.setDaemonConnectionString(PROXY_URL);
|
Lbry.setDaemonConnectionString(PROXY_URL);
|
||||||
|
|
||||||
function getThumbnailCdnUrl(url) {
|
const BEGIN_STR = '<!-- VARIABLE_HEAD_BEGIN -->';
|
||||||
if (!THUMBNAIL_CARDS_CDN_URL || !url) {
|
const FINAL_STR = '<!-- VARIABLE_HEAD_END -->';
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url && (url.includes('https://twitter-card') || url.includes('https://cards.odysee.com'))) {
|
function getThumbnailCdnUrl(url) {
|
||||||
|
if (
|
||||||
|
!THUMBNAIL_CARDS_CDN_URL ||
|
||||||
|
!url ||
|
||||||
|
(url && (url.includes('https://twitter-card') || url.includes('https://cards.odysee.com')))
|
||||||
|
) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,16 +47,13 @@ function getThumbnailCdnUrl(url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertToHead(fullHtml, htmlToInsert) {
|
function insertToHead(fullHtml, htmlToInsert) {
|
||||||
const beginStr = '<!-- VARIABLE_HEAD_BEGIN -->';
|
const beginIndex = fullHtml.indexOf(BEGIN_STR);
|
||||||
const finalStr = '<!-- VARIABLE_HEAD_END -->';
|
const finalIndex = fullHtml.indexOf(FINAL_STR);
|
||||||
|
|
||||||
const beginIndex = fullHtml.indexOf(beginStr);
|
|
||||||
const finalIndex = fullHtml.indexOf(finalStr);
|
|
||||||
|
|
||||||
if (beginIndex > -1 && finalIndex > -1 && finalIndex > beginIndex) {
|
if (beginIndex > -1 && finalIndex > -1 && finalIndex > beginIndex) {
|
||||||
return `${fullHtml.slice(0, beginIndex)}${
|
return `${fullHtml.slice(0, beginIndex)}${
|
||||||
htmlToInsert || buildOgMetadata()
|
htmlToInsert || buildOgMetadata()
|
||||||
}<script src="/public/ui-${jsBundleId}.js" async></script>${fullHtml.slice(finalIndex + finalStr.length)}`;
|
}<script src="/public/ui-${jsBundleId}.js" async></script>${fullHtml.slice(finalIndex + FINAL_STR.length)}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +66,6 @@ function truncateDescription(description, maxChars = 200) {
|
||||||
return chars.length > maxChars ? truncated + '...' : truncated;
|
return chars.length > maxChars ? truncated + '...' : truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeClaimUrl(url) {
|
|
||||||
return normalizeURI(url.replace(/:/g, '#'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeHtmlProperty(property) {
|
function escapeHtmlProperty(property) {
|
||||||
return property
|
return property
|
||||||
? String(property)
|
? String(property)
|
||||||
|
@ -92,6 +88,7 @@ function getCategoryMeta(path) {
|
||||||
function buildOgMetadata(overrideOptions = {}) {
|
function buildOgMetadata(overrideOptions = {}) {
|
||||||
const { title, description, image, path } = overrideOptions;
|
const { title, description, image, path } = overrideOptions;
|
||||||
const cleanDescription = removeMd(description || SITE_DESCRIPTION);
|
const cleanDescription = removeMd(description || SITE_DESCRIPTION);
|
||||||
|
|
||||||
const head =
|
const head =
|
||||||
`<title>${SITE_TITLE}</title>\n` +
|
`<title>${SITE_TITLE}</title>\n` +
|
||||||
`<meta name="description" content="${cleanDescription}" />\n` +
|
`<meta name="description" content="${cleanDescription}" />\n` +
|
||||||
|
@ -138,13 +135,12 @@ function addFavicon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildHead() {
|
function buildHead() {
|
||||||
const head =
|
const head = BEGIN_STR + addFavicon() + addPWA() + buildOgMetadata() + FINAL_STR;
|
||||||
'<!-- VARIABLE_HEAD_BEGIN -->' + addFavicon() + addPWA() + buildOgMetadata() + '<!-- VARIABLE_HEAD_END -->';
|
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildBasicOgMetadata() {
|
function buildBasicOgMetadata() {
|
||||||
const head = '<!-- VARIABLE_HEAD_BEGIN -->' + addFavicon() + buildOgMetadata() + '<!-- VARIABLE_HEAD_END -->';
|
const head = BEGIN_STR + addFavicon() + buildOgMetadata() + FINAL_STR;
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +183,7 @@ function buildClaimOgMetadata(uri, claim, overrideOptions = {}) {
|
||||||
getThumbnailCdnUrl(OG_IMAGE_URL) ||
|
getThumbnailCdnUrl(OG_IMAGE_URL) ||
|
||||||
`${URL}/public/v2-og.png`;
|
`${URL}/public/v2-og.png`;
|
||||||
|
|
||||||
// Allow for ovverriding default claim based og metadata
|
// Allow for overriding default claim based og metadata
|
||||||
const title = overrideOptions.title || claimTitle;
|
const title = overrideOptions.title || claimTitle;
|
||||||
const description = overrideOptions.description || claimDescription;
|
const description = overrideOptions.description || claimDescription;
|
||||||
const cleanDescription = removeMd(description);
|
const cleanDescription = removeMd(description);
|
||||||
|
@ -218,6 +214,12 @@ function buildClaimOgMetadata(uri, claim, overrideOptions = {}) {
|
||||||
head += `<meta name="twitter:url" content="${URL}/${claim.name}:${claim.claim_id}"/>`;
|
head += `<meta name="twitter:url" content="${URL}/${claim.name}:${claim.claim_id}"/>`;
|
||||||
head += `<meta property="fb:app_id" content="1673146449633983" />`;
|
head += `<meta property="fb:app_id" content="1673146449633983" />`;
|
||||||
head += `<link rel="canonical" content="${SITE_CANONICAL_URL || URL}/${claim.name}:${claim.claim_id}"/>`;
|
head += `<link rel="canonical" content="${SITE_CANONICAL_URL || URL}/${claim.name}:${claim.claim_id}"/>`;
|
||||||
|
head += `<link rel="alternate" type="application/json+oembed" href="${URL}/$/oembed?url=${encodeURIComponent(
|
||||||
|
`${URL}/${claim.canonical_url}`
|
||||||
|
)}&format=json" title="${title}" />`;
|
||||||
|
head += `<link rel="alternate" type="text/xml+oembed" href="${URL}/$/oembed?url=${encodeURIComponent(
|
||||||
|
`${URL}/${claim.canonical_url}`
|
||||||
|
)}&format=xml" title="${title}" />`;
|
||||||
|
|
||||||
if (mediaType && (mediaType.startsWith('video/') || mediaType.startsWith('audio/'))) {
|
if (mediaType && (mediaType.startsWith('video/') || mediaType.startsWith('audio/'))) {
|
||||||
const videoUrl = generateEmbedUrl(claim.name, claim.claim_id);
|
const videoUrl = generateEmbedUrl(claim.name, claim.claim_id);
|
||||||
|
|
|
@ -330,10 +330,15 @@ function isURIEqual(uriA, uriB) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeClaimUrl(url) {
|
||||||
|
return normalizeURI(url.replace(/:/g, '#'));
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parseURI,
|
parseURI,
|
||||||
buildURI,
|
buildURI,
|
||||||
normalizeURI,
|
normalizeURI,
|
||||||
|
normalizeClaimUrl,
|
||||||
isURIValid,
|
isURIValid,
|
||||||
isURIEqual,
|
isURIEqual,
|
||||||
isNameValid,
|
isNameValid,
|
||||||
|
|
130
web/src/oEmbed.js
Normal file
130
web/src/oEmbed.js
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
const {
|
||||||
|
URL,
|
||||||
|
SITE_NAME,
|
||||||
|
LBRY_WEB_API,
|
||||||
|
THUMBNAIL_CARDS_CDN_URL,
|
||||||
|
THUMBNAIL_HEIGHT,
|
||||||
|
THUMBNAIL_WIDTH,
|
||||||
|
} = require('../../config.js');
|
||||||
|
|
||||||
|
const { generateEmbedUrl } = require('../../ui/util/web');
|
||||||
|
const { lbryProxy: Lbry } = require('../lbry');
|
||||||
|
const { normalizeURI } = require('./lbryURI');
|
||||||
|
|
||||||
|
const SDK_API_PATH = `${LBRY_WEB_API}/api/v1`;
|
||||||
|
const proxyURL = `${SDK_API_PATH}/proxy`;
|
||||||
|
Lbry.setDaemonConnectionString(proxyURL);
|
||||||
|
|
||||||
|
// ****************************************************************************
|
||||||
|
// Fetch claim info
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
function getThumbnailCdnUrl(url) {
|
||||||
|
if (
|
||||||
|
!THUMBNAIL_CARDS_CDN_URL ||
|
||||||
|
!url ||
|
||||||
|
(url && (url.includes('https://twitter-card') || url.includes('https://cards.odysee.com')))
|
||||||
|
) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
const encodedURL = Buffer.from(url).toString('base64');
|
||||||
|
return `${THUMBNAIL_CARDS_CDN_URL}${encodedURL}.jpg`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getClaim(requestUrl) {
|
||||||
|
const path = requestUrl.replace(URL, '').substring(1);
|
||||||
|
|
||||||
|
let uri;
|
||||||
|
let claim;
|
||||||
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
uri = normalizeURI(path);
|
||||||
|
|
||||||
|
const response = await Lbry.resolve({ urls: [uri] });
|
||||||
|
if (response && response[uri] && !response[uri].error) {
|
||||||
|
claim = response[uri];
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
if (!claim) {
|
||||||
|
error = 'The URL is invalid or is not associated with any claim.';
|
||||||
|
} else {
|
||||||
|
const { value_type, value } = claim;
|
||||||
|
|
||||||
|
if (value_type !== 'stream' || value.stream_type !== 'video') {
|
||||||
|
error = 'The URL is not associated with a video claim.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { claim, error };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ****************************************************************************
|
||||||
|
// Generate
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
function generateOEmbedData(claim) {
|
||||||
|
const { value, signing_channel: authorClaim } = claim;
|
||||||
|
|
||||||
|
const claimTitle = value.title;
|
||||||
|
const authorName = authorClaim ? authorClaim.value.title || authorClaim.name : 'Anonymous';
|
||||||
|
const authorUrlPath = authorClaim && authorClaim.canonical_url.replace('lbry://', '');
|
||||||
|
const authorUrl = authorClaim ? `${URL}/${authorUrlPath}` : null;
|
||||||
|
const thumbnailUrl = value && value.thumbnail && value.thumbnail.url && getThumbnailCdnUrl(value.thumbnail.url);
|
||||||
|
const videoUrl = generateEmbedUrl(claim.name, claim.claim_id);
|
||||||
|
const videoWidth = value.video && value.video.width;
|
||||||
|
const videoHeight = value.video && value.video.height;
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'video',
|
||||||
|
version: '1.0',
|
||||||
|
title: claimTitle,
|
||||||
|
author_name: authorName,
|
||||||
|
author_url: authorUrl,
|
||||||
|
provider_name: SITE_NAME,
|
||||||
|
provider_url: URL,
|
||||||
|
thumbnail_url: thumbnailUrl,
|
||||||
|
thumbnail_width: THUMBNAIL_WIDTH,
|
||||||
|
thumbnail_height: THUMBNAIL_HEIGHT,
|
||||||
|
html: `<iframe id="lbry-iframe" width="560" height="315" src="${videoUrl}" allowfullscreen></iframe>`,
|
||||||
|
width: videoWidth,
|
||||||
|
height: videoHeight,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getOEmbed(ctx) {
|
||||||
|
const path = ctx.request.url;
|
||||||
|
const urlQuery = '?url=';
|
||||||
|
const formatQuery = '&format=';
|
||||||
|
|
||||||
|
const requestUrl = decodeURIComponent(
|
||||||
|
path.substring(
|
||||||
|
path.indexOf(urlQuery) + urlQuery.length,
|
||||||
|
path.indexOf('&') > path.indexOf(urlQuery) ? path.indexOf('&') : path.length
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const requestFormat = path.substring(
|
||||||
|
path.indexOf(formatQuery) + formatQuery.length,
|
||||||
|
path.indexOf('&') > path.indexOf(formatQuery) ? path.indexOf('&') : path.length
|
||||||
|
);
|
||||||
|
|
||||||
|
const isXml = requestFormat === 'xml';
|
||||||
|
|
||||||
|
const { claim, error } = await getClaim(requestUrl);
|
||||||
|
if (error) return error;
|
||||||
|
|
||||||
|
const oEmbedData = generateOEmbedData(claim);
|
||||||
|
|
||||||
|
if (isXml) {
|
||||||
|
ctx.set('Content-Type', 'text/xml+oembed');
|
||||||
|
return oEmbedData.xml();
|
||||||
|
}
|
||||||
|
ctx.set('Content-Type', 'application/json+oembed');
|
||||||
|
return oEmbedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getOEmbed };
|
|
@ -1,11 +1,13 @@
|
||||||
|
const { CUSTOM_HOMEPAGE } = require('../../config.js');
|
||||||
|
const { generateStreamUrl } = require('../../ui/util/web');
|
||||||
|
const { getHomepageJSON } = require('./getHomepageJSON');
|
||||||
const { getHtml } = require('./html');
|
const { getHtml } = require('./html');
|
||||||
|
const { getOEmbed } = require('./oEmbed');
|
||||||
const { getRss } = require('./rss');
|
const { getRss } = require('./rss');
|
||||||
const { getTempFile } = require('./tempfile');
|
const { getTempFile } = require('./tempfile');
|
||||||
const { getHomepageJSON } = require('./getHomepageJSON');
|
|
||||||
const { generateStreamUrl } = require('../../ui/util/web');
|
|
||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
const Router = require('@koa/router');
|
const Router = require('@koa/router');
|
||||||
const { CUSTOM_HOMEPAGE } = require('../../config.js');
|
|
||||||
|
|
||||||
// So any code from 'lbry-redux'/'lbryinc' that uses `fetch` can be run on the server
|
// So any code from 'lbry-redux'/'lbryinc' that uses `fetch` can be run on the server
|
||||||
global.fetch = fetch;
|
global.fetch = fetch;
|
||||||
|
@ -27,6 +29,11 @@ const rssMiddleware = async (ctx) => {
|
||||||
ctx.body = rss;
|
ctx.body = rss;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const oEmbedMiddleware = async (ctx) => {
|
||||||
|
const oEmbed = await getOEmbed(ctx);
|
||||||
|
ctx.body = oEmbed;
|
||||||
|
};
|
||||||
|
|
||||||
const tempfileMiddleware = async (ctx) => {
|
const tempfileMiddleware = async (ctx) => {
|
||||||
const temp = await getTempFile(ctx);
|
const temp = await getTempFile(ctx);
|
||||||
ctx.body = temp;
|
ctx.body = temp;
|
||||||
|
@ -76,6 +83,8 @@ router.get('/.well-known/:filename', tempfileMiddleware);
|
||||||
router.get(`/$/rss/:claimName/:claimId`, rssMiddleware);
|
router.get(`/$/rss/:claimName/:claimId`, rssMiddleware);
|
||||||
router.get(`/$/rss/:claimName::claimId`, rssMiddleware);
|
router.get(`/$/rss/:claimName::claimId`, rssMiddleware);
|
||||||
|
|
||||||
|
router.get(`/$/oembed`, oEmbedMiddleware);
|
||||||
|
|
||||||
router.get('*', async (ctx) => {
|
router.get('*', async (ctx) => {
|
||||||
const html = await getHtml(ctx);
|
const html = await getHtml(ctx);
|
||||||
ctx.body = html;
|
ctx.body = html;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
const { generateStreamUrl } = require('../../ui/util/web');
|
const { generateStreamUrl } = require('../../ui/util/web');
|
||||||
const { URL, SITE_NAME, LBRY_WEB_API } = require('../../config.js');
|
|
||||||
const { lbryProxy: Lbry } = require('../lbry');
|
const { lbryProxy: Lbry } = require('../lbry');
|
||||||
const Rss = require('rss');
|
const { URL, SITE_NAME, LBRY_WEB_API } = require('../../config.js');
|
||||||
const Mime = require('mime-types');
|
const Mime = require('mime-types');
|
||||||
|
const Rss = require('rss');
|
||||||
|
|
||||||
const SDK_API_PATH = `${LBRY_WEB_API}/api/v1`;
|
const SDK_API_PATH = `${LBRY_WEB_API}/api/v1`;
|
||||||
const proxyURL = `${SDK_API_PATH}/proxy`;
|
const proxyURL = `${SDK_API_PATH}/proxy`;
|
||||||
|
@ -105,10 +105,11 @@ const generateEnclosureForClaimContent = (claim) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLanguageValue = (claim) => {
|
const getLanguageValue = (claim) => {
|
||||||
if (claim && claim.value && claim.value.languages && claim.value.languages.length > 0) {
|
const {
|
||||||
return claim.value.languages[0];
|
value: { languages },
|
||||||
}
|
} = claim;
|
||||||
return 'en';
|
|
||||||
|
return languages && languages.length > 0 ? languages[0] : 'en';
|
||||||
};
|
};
|
||||||
|
|
||||||
const replaceLineFeeds = (str) => str.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
const replaceLineFeeds = (str) => str.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||||
|
@ -127,12 +128,11 @@ const isEmailRoughlyValid = (email) => /^\S+@\S+$/.test(email);
|
||||||
*/
|
*/
|
||||||
const generateItunesOwnerElement = (claim) => {
|
const generateItunesOwnerElement = (claim) => {
|
||||||
let email = 'no-reply@odysee.com';
|
let email = 'no-reply@odysee.com';
|
||||||
let name = claim && (claim.value && claim.value.title ? claim.value.title : claim.name);
|
const { value } = claim;
|
||||||
|
const name = (value && value.title) || claim.name;
|
||||||
|
|
||||||
if (claim && claim.value) {
|
if (isEmailRoughlyValid(value.email)) {
|
||||||
if (isEmailRoughlyValid(claim.value.email)) {
|
email = value.email;
|
||||||
email = claim.value.email;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -211,9 +211,7 @@ const generateItunesImageElement = (claim) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFormattedDescription = (claim) => {
|
const getFormattedDescription = (claim) => replaceLineFeeds(claim.value.description || '');
|
||||||
return replaceLineFeeds((claim && claim.value && claim.value.description) || '');
|
|
||||||
};
|
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// Generate
|
// Generate
|
||||||
|
|
Loading…
Reference in a new issue