The script to display images and URLs in descriptions for thepiratebay.com
// ==UserScript==
// @name digger for TPB description
// @namespace https://github.com/sbugzu/digger_for_TPB_description
// @require https://code.jquery.com/jquery-3.6.0.min.js
// @match https://thepiratebay.org/description.php*
// @grant none
// @version 0.1.0
// @author sbugzu
// @description The script to display images and URLs in descriptions for thepiratebay.com
// @license Unlicense
// ==/UserScript==
'use strict';
/*
const isYouTubeUrl = function(url) {
try {
const parsedUrl = new URL(url);
return (
parsedUrl.hostname === "www.youtube.com" ||
parsedUrl.hostname === "youtube.com" ||
parsedUrl.hostname === "m.youtube.com" ||
parsedUrl.hostname === "youtu.be"
);
} catch (e) {
return false; // Invalid URL
}
}
*/
const buildUrl = function(url) {
/*
if(isYouTubeUrl(url)) {
const { id, service} = getVideoId(url);
if(id !== undefined) {
return "https://www.youtube.com/embed/${id}";
}
}
*/
const { id, service} = getVideoId(url);
if( service !== undefined && id !== undefined) {
if( service === "youtube" ) {
return "https://www.youtube.com/embed/" + id;
}
}
return url;
}
const text = $("#descr").text();
//const images = text.match(/https?:\/\/\S+\.(?:jpg|jpeg|png|gif|webp|bmp|svg)/gi) || [];
//const pages = text.match(/https?:\/\/[^\s]+?(?<!\.(jpg|jpeg|png|gif|webp|bmp|svg))(?=\s|$)/gi) || [];
//console.log(images)
const urlRegex = /https?:\/\/[^\s\[\]\)\}<>"']+/gi;
const urls = text.match(urlRegex) || [];
const imageRegex = /\.(jpg|jpeg|png|gif|webp|bmp|svg)(?=[?&#\[]|$)/i;
const images = urls.filter(url => imageRegex.test(url));
const pages = urls.filter(url => !imageRegex.test(url));
const $metadata = $("#metadata").first();
const $preview = $('<div id="preview"></div>').css({"text-align": "center"});
images.forEach(url => {
const $img = $("<img>").attr("src", url);
$img.css({
"max-width": "95%",
"height": "auto",
"margin": "10px 0",
"display": "inline-block"
});
$preview.append($img);
const $link = $("<p>").append($("<a>")
.attr("href", url)
.attr("target", "_blank")
.attr("rel", "noopener noreferrer")
.text("☝️ " + url)
);
$preview.append($link);
});
pages.forEach(url => {
const dstUrl = buildUrl(url);
const $iframe = $("<iframe>").attr("src", dstUrl).css({
"width": "95%",
"height": "512px",
"border": "0"
});
$preview.append($iframe);
const $link = $("<p>").append($("<a>")
.attr("href", url)
.attr("target", "_blank")
.attr("rel", "noopener noreferrer")
.text("☝️ " + url)
);
$preview.append($link);
});
$metadata.after($preview);
/* =========== embedded get-video-id ============ */
/*! get-video-id v4.1.7 | @license MIT © Michael Wuergler | https://github.com/radiovisual/get-video-id */
/**
* Strip away any remaining parameters following `?` or `/` or '&' for YouTube shortcode strings.
*
* @note this function is not meant to work with url strings containing a protocol like https://
* @param {String} shortcodeString - the parameter string
* @returns {String}
*/
function stripParameters(shortcodeString) {
// Split parameters or split folder separator
if (shortcodeString.includes('?')) {
shortcodeString = shortcodeString.split('?')[0];
}
if (shortcodeString.includes('/')) {
shortcodeString = shortcodeString.split('/')[0];
}
if (shortcodeString.includes('&')) {
shortcodeString = shortcodeString.split('&')[0];
}
return shortcodeString;
}
/**
* Get the Youtube Video id.
* @param {string} youtubeStr - the url from which you want to extract the id
* @returns {string|undefined}
*/
function youtube(youtubeString) {
let string_ = youtubeString;
// Remove the '-nocookie' flag from youtube urls
string_ = string_.replace('-nocookie', '');
// Remove time hash at the end of the string
string_ = string_.replace(/#t=.*$/, '');
// Strip the leading protocol
string_ = string_.replace(/^https?:\/\//, '');
// Shortcode
const shortcode = /youtube:\/\/|youtu\.be\/|y2u\.be\//g;
if (shortcode.test(string_)) {
const shortcodeid = string_.split(shortcode)[1];
return stripParameters(shortcodeid);
}
// Shorts
const shortsUrl = /\/shorts\//g;
if (shortsUrl.test(string_)) {
return stripParameters(string_.split(shortsUrl)[1]);
}
// V= or vi=
const parameterv = /v=|vi=/g;
if (parameterv.test(string_)) {
const array = string_.split(parameterv);
return stripParameters(array[1].split('&')[0]);
}
// /v/ or /vi/ or /watch/
const inlinev = /\/v\/|\/vi\/|\/watch\//g;
if (inlinev.test(string_)) {
const inlineid = string_.split(inlinev)[1];
return stripParameters(inlineid);
}
// Format an_webp
const parameterwebp = /\/an_webp\//g;
if (parameterwebp.test(string_)) {
const webp = string_.split(parameterwebp)[1];
return stripParameters(webp);
}
// /e/
const eformat = /\/e\//g;
if (eformat.test(string_)) {
const estring = string_.split(eformat)[1];
return stripParameters(estring);
}
// Embed
const embedreg = /\/embed\//g;
if (embedreg.test(string_)) {
const embedid = string_.split(embedreg)[1];
return stripParameters(embedid);
}
// ignore /user/username pattern
const usernamereg = /\/user\/([a-zA-Z\d]*)$/g;
if (usernamereg.test(string_)) {
return undefined;
}
// User
const userreg = /\/user\/(?!.*videos)/g;
if (userreg.test(string_)) {
const elements = string_.split('/');
return stripParameters(elements.pop());
}
// Attribution_link
const attrreg = /\/attribution_link\?.*v%3D([^%&]*)(%26|&|$)/;
if (attrreg.test(string_)) {
return stripParameters(string_.match(attrreg)[1]);
}
// Live
const livereg = /\/live\//g;
if (livereg.test(string_)) {
const liveid = string_.split(livereg)[1];
return stripParameters(liveid);
}
return undefined;
}
/**
* Get the vimeo id.
*
* @param {String} vimeoString the url from which you want to extract the id
* @returns {String|undefined}
*/
function vimeo(vimeoString) {
let string_ = vimeoString;
if (string_.includes('#')) {
[string_] = string_.split('#');
}
if (string_.includes('?') && !string_.includes('clip_id=')) {
[string_] = string_.split('?');
}
let id;
let array;
const event = /https?:\/\/vimeo\.com\/event\/(\d+)$/;
const eventMatches = event.exec(string_);
if (eventMatches && eventMatches[1]) {
return eventMatches[1];
}
const primary = /https?:\/\/vimeo\.com\/(\d+)/;
const matches = primary.exec(string_);
if (matches && matches[1]) {
return matches[1];
}
const vimeoPipe = ['https?://player.vimeo.com/video/[0-9]+$', 'https?://vimeo.com/channels', 'groups', 'album'].join('|');
const vimeoRegex = new RegExp(vimeoPipe, 'gim');
if (vimeoRegex.test(string_)) {
array = string_.split('/');
if (array && array.length > 0) {
id = array.pop();
}
} else if (/clip_id=/gim.test(string_)) {
array = string_.split('clip_id=');
if (array && array.length > 0) {
[id] = array[1].split('&');
}
}
return id;
}
/**
* Get the vine id.
* @param {string} string_ - the url from which you want to extract the id
* @returns {string|undefined}
*/
function vine(string_) {
const regex = /https:\/\/vine\.co\/v\/([a-zA-Z\d]*)\/?/;
const matches = regex.exec(string_);
if (matches && matches.length > 1) {
return matches[1];
}
return undefined;
}
/**
* Get the VideoPress id.
* @param {string} urlString - the url from which you want to extract the id
* @returns {string|undefined}
*/
function videopress(urlString) {
let idRegex;
if (urlString.includes('embed')) {
idRegex = /embed\/(\w{8})/;
return urlString.match(idRegex)[1];
}
idRegex = /\/v\/(\w{8})/;
const matches = urlString.match(idRegex);
if (matches && matches.length > 0) {
return matches[1];
}
return undefined;
}
/**
* Get the Microsoft Stream id.
* @param {string} urlString - the url from which you want to extract the id
* @returns {string|undefined}
*/
function microsoftStream(urlString) {
const regex = urlString.includes('embed') ? /https:\/\/web\.microsoftstream\.com\/embed\/video\/([a-zA-Z\d-]*)\/?/ : /https:\/\/web\.microsoftstream\.com\/video\/([a-zA-Z\d-]*)\/?/;
const matches = regex.exec(urlString);
if (matches && matches.length > 1) {
return matches[1];
}
return undefined;
}
/**
* Get the tiktok id.
* @param {string} urlString - the url from which you want to extract the id
* @returns {string|undefined}
*/
function tiktok(urlString) {
// Parse basic url and embeds
const basicReg = /tiktok\.com(.*)\/video\/(\d+)/gm;
const basicParsed = basicReg.exec(urlString);
if (basicParsed && basicParsed.length > 2) {
return basicParsed[2];
}
return undefined;
}
/**
* Get the dailymotion id.
* @param {string} urlString - the url from which you want to extract the id
* @returns {string|undefined}
*/
function dailymotion(urlString) {
// Parse basic url and embeds
const basicReg = /dailymotion\.com(.*)(video)\/([a-zA-Z\d]+)/gm;
const basicParsed = basicReg.exec(urlString);
if (basicParsed) {
return basicParsed[3];
}
// Parse shortlink
const shortRegex = /dai\.ly\/([a-zA-Z\d]+)/gm;
const shortParsed = shortRegex.exec(urlString);
if (shortParsed && shortParsed.length > 1) {
return shortParsed[1];
}
// Dynamic link
const dynamicRegex = /dailymotion\.com(.*)video=([a-zA-Z\d]+)/gm;
const dynamicParsed = dynamicRegex.exec(urlString);
if (dynamicParsed && dynamicParsed.length > 2) {
return dynamicParsed[2];
}
return undefined;
}
/**
* Get the loom id.
* @param {string} urlString - the url from which you want to extract the id
* @returns {string|undefined}
*/
function loom(urlString) {
const regex = /^https?:\/\/(?:www\.)?loom\.com\/(?:share|embed)\/([\da-zA-Z]+)\/?/;
const matches = regex.exec(urlString);
if (matches && matches.length > 1) {
return matches[1];
}
return undefined;
}
/**
* Get the value assigned to a "src" attribute in a string, or undefined.
* @param {String} input
* @returns {String|undefined}
*/
function getSrc(input) {
if (typeof input !== 'string') {
throw new TypeError('getSrc expected a string');
}
const srcRegEx = /src="(.*?)"/gm;
const matches = srcRegEx.exec(input);
if (matches && matches.length >= 2) {
return matches[1];
}
return undefined;
}
/**
* Prepare the URL by doing common cleanup operations common for all URL types.
* @param {String} input
* @returns {String}
*/
function sanitizeUrl(input) {
if (typeof input !== 'string') {
throw new TypeError(`sanitizeUrl expected a string, got ${typeof input}`);
}
let string_ = input;
if (/<iframe/gi.test(string_)) {
string_ = getSrc(string_) || '';
}
// Remove surrounding whitespaces or linefeeds
string_ = string_.trim();
// Remove any leading `www.`
string_ = string_.replace('/www.', '/');
return string_;
}
/**
* Extract the url query parameter from a Google redirect url.
*
* @example
* ```javascript
* const url = extractGoogleRedirectionUrl('https://www.google.cz/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwj30L2MvpDVAhUFZVAKHb8CBaYQuAIIIjAA&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ')
* // => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
* ```
* @param {String} input
* @returns {String}
*/
function extractGoogleRedirectionUrl(input) {
if (typeof input !== 'string') {
throw new TypeError(`extractGoogleRedirectionUrl expected a string, got ${typeof input}`);
}
const string_ = input.trim();
// Try to handle google redirection uri
if (/\/\/google|www\.google/.test(string_)) {
try {
const urlObject = new URL(input);
const parameters = new URLSearchParams(urlObject.search);
const extractedUrl = parameters.get('url');
if (extractedUrl) {
return decodeURIComponent(extractedUrl);
}
} catch {
// If there's an error (e.g., input is not a valid URL), return the trimmed input
return string_;
}
}
return string_;
}
/**
* Get the id and service from a video url.
* @param {String} urlString - the url from which you want to extract the id
* @returns {Object}
*/
function getVideoId(urlString) {
if (typeof urlString !== 'string') {
throw new TypeError('get-video-id expects a string');
}
const string_ = sanitizeUrl(urlString);
const url = extractGoogleRedirectionUrl(string_);
let metadata = {
id: undefined,
service: undefined
};
if (/youtube|youtu\.be|y2u\.be|i.ytimg\./.test(url)) {
metadata = {
id: youtube(url),
service: 'youtube'
};
} else if (/vimeo/.test(url)) {
metadata = {
id: vimeo(url),
service: 'vimeo'
};
} else if (/vine/.test(url)) {
metadata = {
id: vine(url),
service: 'vine'
};
} else if (/videopress/.test(url)) {
metadata = {
id: videopress(url),
service: 'videopress'
};
} else if (/microsoftstream/.test(url)) {
metadata = {
id: microsoftStream(url),
service: 'microsoftstream'
};
} else if (/tiktok\.com/.test(url)) {
metadata = {
id: tiktok(url),
service: 'tiktok'
};
} else if (/(dailymotion\.com|dai\.ly)/.test(url)) {
metadata = {
id: dailymotion(url),
service: 'dailymotion'
};
} else if (/loom\.com/.test(url)) {
metadata = {
id: loom(url),
service: 'loom'
};
}
return metadata;
}