mirror of
https://git.sr.ht/~cadence/cloudtube
synced 2024-11-22 15:47:30 +00:00
Rewrite URLs in subscription feed
This commit is contained in:
parent
e829dd4de6
commit
48534d4e29
@ -2,7 +2,7 @@ const {render} = require("pinski/plugins")
|
|||||||
const db = require("../utils/db")
|
const db = require("../utils/db")
|
||||||
const {fetchChannelLatest} = require("../utils/youtube")
|
const {fetchChannelLatest} = require("../utils/youtube")
|
||||||
const {getUser} = require("../utils/getuser")
|
const {getUser} = require("../utils/getuser")
|
||||||
const {timeToPastText} = require("../utils/converters")
|
const {timeToPastText, rewriteVideoDescription} = require("../utils/converters")
|
||||||
const {refresher} = require("../background/feed-update")
|
const {refresher} = require("../background/feed-update")
|
||||||
|
|
||||||
module.exports = [
|
module.exports = [
|
||||||
@ -32,6 +32,7 @@ module.exports = [
|
|||||||
.map(video => {
|
.map(video => {
|
||||||
video.publishedText = timeToPastText(video.published * 1000)
|
video.publishedText = timeToPastText(video.published * 1000)
|
||||||
video.watched = watchedVideos.includes(video.videoId)
|
video.watched = watchedVideos.includes(video.videoId)
|
||||||
|
video.descriptionHtml = rewriteVideoDescription(video.descriptionHtml, video.videoId)
|
||||||
return video
|
return video
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
36
api/video.js
36
api/video.js
@ -84,40 +84,6 @@ function sortFormats(video, preference) {
|
|||||||
return formats
|
return formats
|
||||||
}
|
}
|
||||||
|
|
||||||
function rewriteVideoDescription(descriptionHtml, id) {
|
|
||||||
// replace timestamps to clickable links and rewrite youtube links to stay on the instance instead of pointing to YouTube
|
|
||||||
// test cases
|
|
||||||
// https://www.youtube.com/watch?v=VdPsJW6AHqc 00:00 timestamps, youtu.be/<videoid>
|
|
||||||
// https://www.youtube.com/watch?v=FDMq9ie0ih0 00:00 & 00:00:00 timestamps
|
|
||||||
// https://www.youtube.com/watch?v=fhum63fAwrI www.youtube.com/watch?v=<videoid>
|
|
||||||
// https://www.youtube.com/watch?v=i-szWOrc3Mo www.youtube.com/<channelname> (unsupported by cloudtube currently)
|
|
||||||
// https://www.youtube.com/watch?v=LSG71wbKpbQ www.youtube.com/channel/<id>
|
|
||||||
|
|
||||||
descriptionHtml = descriptionHtml.replace(new RegExp(`<a href="https?://(?:www\\.)?youtu\\.be/(${constants.regex.video_id})([^"]*)">([^<]+)</a>`, "g"), `<a href="/watch?v=$1$2">$3</a>`)
|
|
||||||
descriptionHtml = descriptionHtml.replace(new RegExp(`<a href="https?://(?:www\\.)?youtu(?:\\.be|be\\.com)/([^"]*)">([^<]+)<\/a>`, "g"), `<a href="/$1">$2</a>`)
|
|
||||||
descriptionHtml = descriptionHtml.replace(new RegExp(`(?:([0-9]*):)?([0-5]?[0-9]):([0-5][0-9])`, "g"), (_, hours, minutes, seconds) => {
|
|
||||||
let timeURL, timeDisplay, timeSeconds
|
|
||||||
if (hours === undefined) {
|
|
||||||
timeURL = `${minutes}m${seconds}s`
|
|
||||||
timeDisplay = `${minutes}:${seconds}`
|
|
||||||
timeSeconds = minutes*60 + + seconds
|
|
||||||
} else {
|
|
||||||
timeURL = `${hours}h${minutes}m${seconds}s`
|
|
||||||
timeDisplay = `${hours}:${minutes}:${seconds}`
|
|
||||||
timeSeconds = hours*60*60 + minutes*60 + + seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
params.set("v", id)
|
|
||||||
params.set("t", timeURL)
|
|
||||||
const url = "/watch?" + params
|
|
||||||
|
|
||||||
return pug.render(`a(href=url data-clickable-timestamp=timeSeconds)= timeDisplay`, {url, timeURL, timeDisplay, timeSeconds})
|
|
||||||
})
|
|
||||||
|
|
||||||
return descriptionHtml
|
|
||||||
}
|
|
||||||
|
|
||||||
async function renderVideo(video, {user, settings, id, instanceOrigin}, locals = {}) {
|
async function renderVideo(video, {user, settings, id, instanceOrigin}, locals = {}) {
|
||||||
try {
|
try {
|
||||||
if (!video) throw new Error("The instance returned null.")
|
if (!video) throw new Error("The instance returned null.")
|
||||||
@ -149,7 +115,7 @@ async function renderVideo(video, {user, settings, id, instanceOrigin}, locals =
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rewrite description
|
// rewrite description
|
||||||
video.descriptionHtml = rewriteVideoDescription(video.descriptionHtml, id)
|
video.descriptionHtml = converters.rewriteVideoDescription(video.descriptionHtml, id)
|
||||||
|
|
||||||
return render(200, "pug/video.pug", Object.assign(locals, {video, formats, subscribed, instanceOrigin}))
|
return render(200, "pug/video.pug", Object.assign(locals, {video, formats, subscribed, instanceOrigin}))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
const constants = require("./constants")
|
||||||
|
const pug = require("pug")
|
||||||
|
|
||||||
function timeToPastText(timestamp) {
|
function timeToPastText(timestamp) {
|
||||||
const difference = Date.now() - timestamp
|
const difference = Date.now() - timestamp
|
||||||
return [
|
return [
|
||||||
@ -49,6 +52,43 @@ function normaliseVideoInfo(video) {
|
|||||||
if (!video.second__viewCountText) {
|
if (!video.second__viewCountText) {
|
||||||
video.second__viewCountText = viewCountToText(video.viewCount)
|
video.second__viewCountText = viewCountToText(video.viewCount)
|
||||||
}
|
}
|
||||||
|
if (video.descriptionHtml) {
|
||||||
|
video.descriptionHtml = rewriteVideoDescription(video.descriptionHtml, video.videoId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function rewriteVideoDescription(descriptionHtml, id) {
|
||||||
|
// replace timestamps to clickable links and rewrite youtube links to stay on the instance instead of pointing to YouTube
|
||||||
|
// test cases
|
||||||
|
// https://www.youtube.com/watch?v=VdPsJW6AHqc 00:00 timestamps, youtu.be/<videoid>
|
||||||
|
// https://www.youtube.com/watch?v=FDMq9ie0ih0 00:00 & 00:00:00 timestamps
|
||||||
|
// https://www.youtube.com/watch?v=fhum63fAwrI www.youtube.com/watch?v=<videoid>
|
||||||
|
// https://www.youtube.com/watch?v=i-szWOrc3Mo www.youtube.com/<channelname> (unsupported by cloudtube currently)
|
||||||
|
// https://www.youtube.com/watch?v=LSG71wbKpbQ www.youtube.com/channel/<id>
|
||||||
|
|
||||||
|
descriptionHtml = descriptionHtml.replace(new RegExp(`<a href="https?://(?:www\\.)?youtu\\.be/(${constants.regex.video_id})([^"]*)">([^<]+)</a>`, "g"), `<a href="/watch?v=$1$2">$3</a>`)
|
||||||
|
descriptionHtml = descriptionHtml.replace(new RegExp(`<a href="https?://(?:www\\.)?youtu(?:\\.be|be\\.com)/([^"]*)">([^<]+)<\/a>`, "g"), `<a href="/$1">$2</a>`)
|
||||||
|
descriptionHtml = descriptionHtml.replace(new RegExp(`(?:([0-9]*):)?([0-5]?[0-9]):([0-5][0-9])`, "g"), (_, hours, minutes, seconds) => {
|
||||||
|
let timeURL, timeDisplay, timeSeconds
|
||||||
|
if (hours === undefined) {
|
||||||
|
timeURL = `${minutes}m${seconds}s`
|
||||||
|
timeDisplay = `${minutes}:${seconds}`
|
||||||
|
timeSeconds = minutes*60 + + seconds
|
||||||
|
} else {
|
||||||
|
timeURL = `${hours}h${minutes}m${seconds}s`
|
||||||
|
timeDisplay = `${hours}:${minutes}:${seconds}`
|
||||||
|
timeSeconds = hours*60*60 + minutes*60 + + seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = new URLSearchParams()
|
||||||
|
params.set("v", id)
|
||||||
|
params.set("t", timeURL)
|
||||||
|
const url = "/watch?" + params
|
||||||
|
|
||||||
|
return pug.render(`a(href=url data-clickable-timestamp=timeSeconds)= timeDisplay`, {url, timeURL, timeDisplay, timeSeconds})
|
||||||
|
})
|
||||||
|
|
||||||
|
return descriptionHtml
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,6 +165,7 @@ function subscriberCountToText(count) {
|
|||||||
module.exports.timeToPastText = timeToPastText
|
module.exports.timeToPastText = timeToPastText
|
||||||
module.exports.lengthSecondsToLengthText = lengthSecondsToLengthText
|
module.exports.lengthSecondsToLengthText = lengthSecondsToLengthText
|
||||||
module.exports.normaliseVideoInfo = normaliseVideoInfo
|
module.exports.normaliseVideoInfo = normaliseVideoInfo
|
||||||
|
module.exports.rewriteVideoDescription = rewriteVideoDescription
|
||||||
module.exports.tToMediaFragment = tToMediaFragment
|
module.exports.tToMediaFragment = tToMediaFragment
|
||||||
module.exports.viewCountToText = viewCountToText
|
module.exports.viewCountToText = viewCountToText
|
||||||
module.exports.subscriberCountToText = subscriberCountToText
|
module.exports.subscriberCountToText = subscriberCountToText
|
||||||
|
Loading…
Reference in New Issue
Block a user