getHtml/routes/rss: fetch streaming_url
instead of generating it.
## Issues from the initial attempt - There are 2 versions of `Lbry` and `buildURI` -- the app and web-server version. There are subtle differences between them, and for the app case, importing the web-server version results in a query into an invalid URL. - It changed the function from returning a string to returning a promise. ## Changes - Since the new function (renamed to `fetchStreamUrl` for clarity) is currently only needed for web-server, I moved it into the `web` folder to avoid misuse in app. - Await on the promise. Unfortunately, this also means the entire chain of function calls need to be adjusted to be `async`.
This commit is contained in:
parent
251187de06
commit
de206162f9
7 changed files with 39 additions and 35 deletions
|
@ -9,7 +9,6 @@ WEB_SERVER_PORT=1337
|
|||
|
||||
# -- APIs ---
|
||||
LBRY_WEB_API=https://api.na-backend.odysee.com
|
||||
LBRY_WEB_STREAMING_API=https://player.odycdn.com
|
||||
LBRY_WEB_BUFFER_API=https://collector-service.api.lbry.tv/api/v1/events/video
|
||||
COMMENT_SERVER_API=https://comments.odysee.tv/api/v2
|
||||
SEARCH_SERVER_API_ALT=https://recsys.odysee.tv/search
|
||||
|
|
|
@ -10,7 +10,6 @@ const config = {
|
|||
LBRY_WEB_PUBLISH_API: process.env.LBRY_WEB_PUBLISH_API,
|
||||
LBRY_WEB_PUBLISH_API_V2: process.env.LBRY_WEB_PUBLISH_API_V2,
|
||||
LBRY_API_URL: process.env.LBRY_API_URL, // api.odysee.com',
|
||||
LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, // player.odycdn.com
|
||||
LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
|
||||
SEARCH_SERVER_API: process.env.SEARCH_SERVER_API,
|
||||
SEARCH_SERVER_API_ALT: process.env.SEARCH_SERVER_API_ALT,
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
const { URL, LBRY_WEB_STREAMING_API, THUMBNAIL_CARDS_CDN_URL } = require('../../config');
|
||||
const { URL, THUMBNAIL_CARDS_CDN_URL } = require('../../config');
|
||||
|
||||
const CONTINENT_COOKIE = 'continent';
|
||||
|
||||
function generateStreamUrl(claimName, claimId) {
|
||||
return `${LBRY_WEB_STREAMING_API}/content/claims/${encodeURIComponent(claimName)
|
||||
.replace(/'/g, '%27')
|
||||
.replace(/\(/g, '%28')
|
||||
.replace(/\)/g, '%29')}/${claimId}/${encodeURIComponent(claimName)}`;
|
||||
}
|
||||
|
||||
function generateEmbedUrl(claimName, claimId, startTime, referralLink) {
|
||||
let urlParams = new URLSearchParams();
|
||||
|
||||
|
@ -98,7 +91,6 @@ module.exports = {
|
|||
generateEmbedIframeData,
|
||||
generateEmbedUrl,
|
||||
generateEmbedUrlEncoded,
|
||||
generateStreamUrl,
|
||||
getParameterByName,
|
||||
getThumbnailCdnUrl,
|
||||
escapeHtmlProperty,
|
||||
|
|
15
web/src/fetchStreamUrl.js
Normal file
15
web/src/fetchStreamUrl.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const { lbryProxy: Lbry } = require('../lbry');
|
||||
const { buildURI } = require('./lbryURI');
|
||||
|
||||
async function fetchStreamUrl(claimName, claimId) {
|
||||
const uri = buildURI({ claimName, claimId });
|
||||
return await Lbry.get({ uri })
|
||||
.then(({ streaming_url }) => streaming_url)
|
||||
.catch((error) => {
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchStreamUrl,
|
||||
};
|
|
@ -14,12 +14,12 @@ const {
|
|||
const {
|
||||
generateDirectUrl,
|
||||
generateEmbedUrl,
|
||||
generateStreamUrl,
|
||||
getParameterByName,
|
||||
getThumbnailCdnUrl,
|
||||
escapeHtmlProperty,
|
||||
unscapeHtmlProperty,
|
||||
} = require('../../ui/util/web');
|
||||
const { fetchStreamUrl } = require('./fetchStreamUrl');
|
||||
const { getJsBundleId } = require('../bundle-id.js');
|
||||
const { lbryProxy: Lbry } = require('../lbry');
|
||||
const { getHomepageJsonV1 } = require('./getHomepageJSON');
|
||||
|
@ -151,7 +151,7 @@ function buildBasicOgMetadata() {
|
|||
// Metadata used for urls that need claim information
|
||||
// Also has option to override defaults
|
||||
//
|
||||
function buildClaimOgMetadata(uri, claim, overrideOptions = {}, referrerQuery) {
|
||||
async function buildClaimOgMetadata(uri, claim, overrideOptions = {}, referrerQuery) {
|
||||
// Initial setup for claim based og metadata
|
||||
const { claimName } = parseURI(uri);
|
||||
const { meta, value, signing_channel } = claim;
|
||||
|
@ -181,7 +181,7 @@ function buildClaimOgMetadata(uri, claim, overrideOptions = {}, referrerQuery) {
|
|||
let imageThumbnail;
|
||||
|
||||
if (fee <= 0 && mediaType && mediaType.startsWith('image/')) {
|
||||
imageThumbnail = generateStreamUrl(claim.name, claim.claim_id);
|
||||
imageThumbnail = await fetchStreamUrl(claim.name, claim.claim_id);
|
||||
}
|
||||
|
||||
const claimThumbnail =
|
||||
|
@ -392,7 +392,7 @@ async function getHtml(ctx) {
|
|||
const inviteChannel = requestPath.slice(invitePath.length);
|
||||
const inviteChannelUrl = normalizeClaimUrl(inviteChannel);
|
||||
const claim = await resolveClaimOrRedirect(ctx, inviteChannelUrl);
|
||||
const invitePageMetadata = buildClaimOgMetadata(inviteChannelUrl, claim, {
|
||||
const invitePageMetadata = await buildClaimOgMetadata(inviteChannelUrl, claim, {
|
||||
title: `Join ${claim.name} on ${SITE_NAME}`,
|
||||
description: `Join ${claim.name} on ${SITE_NAME}, a content wonderland owned by everyone (and no one).`,
|
||||
});
|
||||
|
@ -414,7 +414,7 @@ async function getHtml(ctx) {
|
|||
const claim = await resolveClaimOrRedirect(ctx, claimUri, true);
|
||||
|
||||
if (claim) {
|
||||
const ogMetadata = buildClaimOgMetadata(claimUri, claim);
|
||||
const ogMetadata = await buildClaimOgMetadata(claimUri, claim);
|
||||
const googleVideoMetadata = buildGoogleVideoMetadata(claimUri, claim);
|
||||
return insertToHead(html, ogMetadata.concat('\n', googleVideoMetadata));
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ async function getHtml(ctx) {
|
|||
const referrerQuery = escapeHtmlProperty(getParameterByName('r', ctx.request.url));
|
||||
|
||||
if (claim) {
|
||||
const ogMetadata = buildClaimOgMetadata(claimUri, claim, {}, referrerQuery);
|
||||
const ogMetadata = await buildClaimOgMetadata(claimUri, claim, {}, referrerQuery);
|
||||
const googleVideoMetadata = buildGoogleVideoMetadata(claimUri, claim);
|
||||
return insertToHead(html, ogMetadata.concat('\n', googleVideoMetadata));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const { generateStreamUrl } = require('../../ui/util/web');
|
||||
const { fetchStreamUrl } = require('./fetchStreamUrl');
|
||||
const { getHtml } = require('./html');
|
||||
const { getOEmbed } = require('./oEmbed');
|
||||
const { getRss } = require('./rss');
|
||||
|
@ -13,11 +13,9 @@ global.fetch = fetch;
|
|||
|
||||
const router = new Router();
|
||||
|
||||
function getStreamUrl(ctx) {
|
||||
async function getStreamUrl(ctx) {
|
||||
const { claimName, claimId } = ctx.params;
|
||||
|
||||
const streamUrl = generateStreamUrl(claimName, claimId);
|
||||
return streamUrl;
|
||||
return await fetchStreamUrl(claimName, claimId);
|
||||
}
|
||||
|
||||
const rssMiddleware = async (ctx) => {
|
||||
|
@ -43,7 +41,7 @@ router.get(`/$/api/content/v1/get`, async (ctx) => getHomepage(ctx, 1));
|
|||
router.get(`/$/api/content/v2/get`, async (ctx) => getHomepage(ctx, 2));
|
||||
|
||||
router.get(`/$/download/:claimName/:claimId`, async (ctx) => {
|
||||
const streamUrl = getStreamUrl(ctx);
|
||||
const streamUrl = await getStreamUrl(ctx);
|
||||
const downloadUrl = `${streamUrl}?download=1`;
|
||||
ctx.redirect(downloadUrl);
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const { generateStreamUrl } = require('../../ui/util/web');
|
||||
const { fetchStreamUrl } = require('./fetchStreamUrl');
|
||||
const { lbryProxy: Lbry } = require('../lbry');
|
||||
const { URL, SITE_NAME, PROXY_URL } = require('../../config.js');
|
||||
const Mime = require('mime-types');
|
||||
|
@ -62,7 +62,7 @@ function encodeWithSpecialCharEncode(string) {
|
|||
return encodeURIComponent(string).replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
|
||||
}
|
||||
|
||||
const generateEnclosureForClaimContent = (claim) => {
|
||||
async function generateEnclosureForClaimContent(claim) {
|
||||
const value = claim.value;
|
||||
if (!value || !value.stream_type) {
|
||||
return undefined;
|
||||
|
@ -72,27 +72,27 @@ const generateEnclosureForClaimContent = (claim) => {
|
|||
switch (value.stream_type) {
|
||||
case 'video':
|
||||
return {
|
||||
url: generateStreamUrl(claim.name, claim.claim_id) + (fileExt || '.mp4'),
|
||||
url: (await fetchStreamUrl(claim.name, claim.claim_id)) + (fileExt || '.mp4'),
|
||||
type: (value.source && value.source.media_type) || 'video/mp4',
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
|
||||
case 'audio':
|
||||
return {
|
||||
url: generateStreamUrl(claim.name, claim.claim_id) + ((fileExt === '.mpga' ? '.mp3' : fileExt) || '.mp3'),
|
||||
url: (await fetchStreamUrl(claim.name, claim.claim_id)) + ((fileExt === '.mpga' ? '.mp3' : fileExt) || '.mp3'),
|
||||
type: (value.source && value.source.media_type) || 'audio/mpeg',
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
case 'image':
|
||||
return {
|
||||
url: generateStreamUrl(claim.name, claim.claim_id) + (fileExt || '.jpeg'),
|
||||
url: (await fetchStreamUrl(claim.name, claim.claim_id)) + (fileExt || '.jpeg'),
|
||||
type: (value.source && value.source.media_type) || 'image/jpeg',
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
case 'document':
|
||||
case 'software':
|
||||
return {
|
||||
url: generateStreamUrl(claim.name, claim.claim_id),
|
||||
url: await fetchStreamUrl(claim.name, claim.claim_id),
|
||||
type: (value.source && value.source.media_type) || undefined,
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
|
@ -100,7 +100,7 @@ const generateEnclosureForClaimContent = (claim) => {
|
|||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getLanguageValue = (claim) => {
|
||||
const {
|
||||
|
@ -215,7 +215,7 @@ const getFormattedDescription = (claim) => replaceLineFeeds(claim.value.descript
|
|||
// Generate
|
||||
// ****************************************************************************
|
||||
|
||||
function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
||||
async function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
||||
// --- Channel ---
|
||||
let channelTitle = (channelClaim.value && channelClaim.value.title) || channelClaim.name;
|
||||
let channelURL = URL + '/' + channelClaim.canonical_url.replace('lbry://', '').replace(/#/g, ':');
|
||||
|
@ -245,7 +245,8 @@ function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
|||
});
|
||||
|
||||
// --- Content ---
|
||||
claimsInChannel.forEach((c) => {
|
||||
for (let i = 0; i < claimsInChannel.length; ++i) {
|
||||
const c = claimsInChannel[i];
|
||||
const title = (c.value && c.value.title) || c.name;
|
||||
const thumbnailUrl = (c.value && c.value.thumbnail && c.value.thumbnail.url) || '';
|
||||
const thumbnailHtml = thumbnailUrl
|
||||
|
@ -264,7 +265,7 @@ function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
|||
guid: undefined, // defaults to 'url'
|
||||
author: undefined, // defaults feed author property
|
||||
date: new Date(date),
|
||||
enclosure: generateEnclosureForClaimContent(c),
|
||||
enclosure: await generateEnclosureForClaimContent(c),
|
||||
custom_elements: [
|
||||
{ 'itunes:title': title },
|
||||
{ 'itunes:author': channelTitle },
|
||||
|
@ -273,7 +274,7 @@ function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
|||
generateItunesExplicitElement(c),
|
||||
],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return feed;
|
||||
}
|
||||
|
@ -289,7 +290,7 @@ async function getRss(ctx) {
|
|||
}
|
||||
|
||||
const latestClaimsInChannel = await getClaimsFromChannel(channelClaim.claim_id, NUM_ENTRIES);
|
||||
const feed = generateFeed(`${URL}${ctx.request.url}`, channelClaim, latestClaimsInChannel);
|
||||
const feed = await generateFeed(`${URL}${ctx.request.url}`, channelClaim, latestClaimsInChannel);
|
||||
return feed.xml();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue