From 81b2c77b98391c521307b04fe6fef6778fd5dd87 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Mon, 22 Jun 2020 02:04:15 +1200 Subject: [PATCH] Add youtube/twitter rewrite (closes #22) --- src/lib/constants.js | 9 ++++- src/lib/structures/BaseUser.js | 66 +++++++++++++++++++++++++++++++ src/lib/structures/ReelUser.js | 27 ++----------- src/lib/structures/User.js | 27 ++----------- src/site/api/utils/getsettings.js | 2 + src/site/pug/settings.pug | 29 ++++++++++++-- src/site/pug/user.pug | 5 ++- 7 files changed, 111 insertions(+), 54 deletions(-) create mode 100644 src/lib/structures/BaseUser.js diff --git a/src/lib/constants.js b/src/lib/constants.js index bed8425..f9584d7 100644 --- a/src/lib/constants.js +++ b/src/lib/constants.js @@ -106,6 +106,11 @@ let constants = { collatedFiles: [] }, + default_user_settings: { + rewrite_youtube: "invidio.us", + rewrite_twitter: "nitter.net" + }, + user_settings: [ { name: "language", @@ -166,12 +171,12 @@ let constants = { name: "rewrite_youtube", default: "", boolean: false, - replaceEmptyWithDefault: true + replaceEmptyWithDefault: false },{ name: "rewrite_twitter", default: "", boolean: false, - replaceEmptyWithDefault: true + replaceEmptyWithDefault: false } ], diff --git a/src/lib/structures/BaseUser.js b/src/lib/structures/BaseUser.js new file mode 100644 index 0000000..debf045 --- /dev/null +++ b/src/lib/structures/BaseUser.js @@ -0,0 +1,66 @@ +const constants = require("../constants") +const {proxyProfilePic} = require("../utils/proxyurl") +const {structure} = require("../utils/structuretext") + +const rewriters = { + rewrite_youtube: ["youtube.com", "www.youtube.com", "youtu.be"], + rewrite_twitter: ["twitter.com", "www.twitter.com", "twtr.cm"] +} + +class BaseUser { + constructor() { + /** @type {import("../types").GraphUser} */ + this.data + /** @type {number} */ + this.cachedAt + } + + /** + * @param {object} settings + * @param {string} settings.rewrite_youtube + * @param {string} settings.rewrite_twitter + */ + getRewriteLink(settings) { + if (!this.data.external_url) return null + let url + try { + url = new URL(this.data.external_url) + } catch (e) { + return null + } + for (const key of Object.keys(rewriters)) { // for each thing we can rewrite + if (key in settings) { // if the settings want to replace it + if (rewriters[key].includes(url.host)) { // if the url matches this filter + if (settings[key].includes("://")) { + [url.protocol, url.host] = settings[key].split("//") + } else { + url.host = settings[key] + url.protocol = "https:" + } + } + } + } + return url.toString() + } + + computeProxyProfilePic() { + this.proxyProfilePicture = proxyProfilePic(this.data.profile_pic_url, this.data.id) + } + + getStructuredBio() { + if (!this.data.biography) return null + return structure(this.data.biography) + } + + getTtl(scale = 1) { + const expiresAt = this.cachedAt + constants.caching.resource_cache_time + const ttl = expiresAt - Date.now() + return Math.ceil(Math.max(ttl, 0) / scale) + } + + export() { + return this.data + } +} + +module.exports = BaseUser diff --git a/src/lib/structures/ReelUser.js b/src/lib/structures/ReelUser.js index 97eab91..95ae382 100644 --- a/src/lib/structures/ReelUser.js +++ b/src/lib/structures/ReelUser.js @@ -1,11 +1,11 @@ const constants = require("../constants") -const {proxyProfilePic} = require("../utils/proxyurl") -const {structure} = require("../utils/structuretext") const Timeline = require("./Timeline") -require("../testimports")(constants, Timeline) +const BaseUser = require("./BaseUser") +require("../testimports")(constants, Timeline, BaseUser) -class ReelUser { +class ReelUser extends BaseUser { constructor(data) { + super() /** @type {import("../types").GraphUser} */ this.data = data this.fromReel = true @@ -17,25 +17,6 @@ class ReelUser { this.cachedAt = Date.now() this.computeProxyProfilePic() } - - computeProxyProfilePic() { - this.proxyProfilePicture = proxyProfilePic(this.data.profile_pic_url, this.data.id) - } - - getStructuredBio() { - if (!this.data.biography) return null - return structure(this.data.biography) - } - - getTtl(scale = 1) { - const expiresAt = this.cachedAt + constants.caching.resource_cache_time - const ttl = expiresAt - Date.now() - return Math.ceil(Math.max(ttl, 0) / scale) - } - - export() { - return this.data - } } module.exports = ReelUser diff --git a/src/lib/structures/User.js b/src/lib/structures/User.js index 4fe3e57..a9ac566 100644 --- a/src/lib/structures/User.js +++ b/src/lib/structures/User.js @@ -1,14 +1,14 @@ const constants = require("../constants") -const {proxyProfilePic} = require("../utils/proxyurl") -const {structure} = require("../utils/structuretext") const Timeline = require("./Timeline") -require("../testimports")(constants, Timeline) +const BaseUser = require("./BaseUser") +require("../testimports")(constants, Timeline, BaseUser) -class User { +class User extends BaseUser { /** * @param {import("../types").GraphUser} data */ constructor(data) { + super() this.data = data this.following = data.edge_follow.count this.followedBy = data.edge_followed_by.count @@ -17,25 +17,6 @@ class User { this.cachedAt = Date.now() this.computeProxyProfilePic() } - - computeProxyProfilePic() { - this.proxyProfilePicture = proxyProfilePic(this.data.profile_pic_url, this.data.id) - } - - getStructuredBio() { - if (!this.data.biography) return null - return structure(this.data.biography) - } - - getTtl(scale = 1) { - const expiresAt = this.cachedAt + constants.caching.resource_cache_time - const ttl = expiresAt - Date.now() - return Math.ceil(Math.max(ttl, 0) / scale) - } - - export() { - return this.data - } } module.exports = User diff --git a/src/site/api/utils/getsettings.js b/src/site/api/utils/getsettings.js index cbafd82..8001739 100644 --- a/src/site/api/utils/getsettings.js +++ b/src/site/api/utils/getsettings.js @@ -12,6 +12,8 @@ function addDefaults(input = {}) { } else { if (setting.boolean) { result[setting.name] = +(setting.default !== "") + } else if (setting.name in constants.default_user_settings) { + result[setting.name] = constants.default_user_settings[setting.name] } else { result[setting.name] = setting.default } diff --git a/src/site/pug/settings.pug b/src/site/pug/settings.pug index 2e71808..817f763 100644 --- a/src/site/pug/settings.pug +++ b/src/site/pug/settings.pug @@ -6,10 +6,14 @@ mixin fieldset(name) .fieldset-contents block -mixin input(id, description, placeholder, disabled) +mixin input(id, description, placeholder, disabled, list) .field-row label.description(for=id)= description - input(type="text" id=id name=id value=settings[id] placeholder=placeholder disabled=disabled) + input(type="text" id=id name=id value=settings[id] placeholder=placeholder disabled=disabled list=`${id}-list`) + if list + datalist(id=`${id}-list`) + each item in list + option(value=item) mixin checkbox(id, description, label, disabled) .field-row.checkbox-row @@ -53,9 +57,26 @@ html {value: "full", text: "Full"} ]) - +input("rewrite_youtube", "Rewrite YouTube domain", "youtube.com", true) + +input("rewrite_youtube", "Rewrite YouTube domain", constants.default_user_settings.rewrite_youtube, false, [ + "invidio.us", + "invidious.snopyta.org", + "invidious.13ad.de", + "watch.nettohikari.com", + "invidious.fdn.fr", + "yewtu.be" + ]) - +input("rewrite_twitter", "Rewrite Twitter domain", "twitter.com", true) + +input("rewrite_twitter", "Rewrite Twitter domain", constants.default_user_settings.rewrite_twitter, false, [ + "nitter.net", + "nitter.snopyta.org", + "nitter.pussthecat.org", + "nitter.42l.fr", + "nitter.mastodont.cat", + "nitter.tedomum.net", + "nitter.cattube.org", + "nitter.fdn.fr", + "nitter.1d4.us" + ]) +checkbox("remove_trailing_hashtags", "Hide trailing hashtags", "Hide", false) diff --git a/src/site/pug/user.pug b/src/site/pug/user.pug index 082cd7a..4c34446 100644 --- a/src/site/pug/user.pug +++ b/src/site/pug/user.pug @@ -54,9 +54,10 @@ html - const bio = user.getStructuredBio() if bio +display_structured(bio) - if user.data.external_url + - const userURL = user.getRewriteLink(settings) + if userURL p.website - a(href=user.data.external_url)= user.data.external_url + a(href=userURL)= userURL if user.posts != undefined div.profile-counter #[span(data-numberformat=user.posts).count #{numberFormat(user.posts)}] posts if followerCountsAvailable