mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-11 05:57:07 +03:00
Changed whitelisting to use channel JSON instead of page scraping.
It also only pulls data once. Uses channelID now instead of URLs. Resolves https://github.com/ajayyy/SponsorBlock/issues/275 TODO: Add migration method to use channelID instead of channelURL
This commit is contained in:
@@ -540,5 +540,8 @@
|
|||||||
},
|
},
|
||||||
"hiddenDueToDuration": {
|
"hiddenDueToDuration": {
|
||||||
"message": "hidden: too short"
|
"message": "hidden: too short"
|
||||||
|
},
|
||||||
|
"channelDataNotFound": {
|
||||||
|
"message": "Channel ID not loaded yet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
140
src/content.ts
140
src/content.ts
@@ -24,6 +24,11 @@ var sponsorTimes: SponsorTime[] = null;
|
|||||||
//what video id are these sponsors for
|
//what video id are these sponsors for
|
||||||
var sponsorVideoID: VideoID = null;
|
var sponsorVideoID: VideoID = null;
|
||||||
|
|
||||||
|
// JSON video info
|
||||||
|
var videoInfo: any = null;
|
||||||
|
//the channel this video is about
|
||||||
|
var channelID;
|
||||||
|
|
||||||
// Skips are scheduled to ensure precision.
|
// Skips are scheduled to ensure precision.
|
||||||
// Skips are rescheduled every seeking event.
|
// Skips are rescheduled every seeking event.
|
||||||
// Skips are canceled every seeking event
|
// Skips are canceled every seeking event
|
||||||
@@ -56,12 +61,6 @@ var switchingVideos = null;
|
|||||||
var lastCheckTime = 0;
|
var lastCheckTime = 0;
|
||||||
var lastCheckVideoTime = -1;
|
var lastCheckVideoTime = -1;
|
||||||
|
|
||||||
//the channel this video is about
|
|
||||||
var channelURL;
|
|
||||||
|
|
||||||
//the title of the last video loaded. Used to make sure the channel URL has been updated yet.
|
|
||||||
var title;
|
|
||||||
|
|
||||||
//is this channel whitelised from getting sponsors skipped
|
//is this channel whitelised from getting sponsors skipped
|
||||||
var channelWhitelisted = false;
|
var channelWhitelisted = false;
|
||||||
|
|
||||||
@@ -183,9 +182,9 @@ function messageListener(request: any, sender: any, sendResponse: (response: any
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "getChannelURL":
|
case "getChannelID":
|
||||||
sendResponse({
|
sendResponse({
|
||||||
channelURL: channelURL
|
channelID: channelID
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -262,6 +261,10 @@ function resetValues() {
|
|||||||
sponsorTimes = null;
|
sponsorTimes = null;
|
||||||
sponsorLookupRetries = 0;
|
sponsorLookupRetries = 0;
|
||||||
|
|
||||||
|
videoInfo = null;
|
||||||
|
channelWhitelisted = false;
|
||||||
|
channelID = null;
|
||||||
|
|
||||||
//empty the preview bar
|
//empty the preview bar
|
||||||
if (previewBar !== null) {
|
if (previewBar !== null) {
|
||||||
previewBar.set([], [], 0);
|
previewBar.set([], [], 0);
|
||||||
@@ -293,6 +296,9 @@ async function videoIDChange(id) {
|
|||||||
// Wait for options to be ready
|
// Wait for options to be ready
|
||||||
await utils.wait(() => Config.config !== null, 5000, 1);
|
await utils.wait(() => Config.config !== null, 5000, 1);
|
||||||
|
|
||||||
|
// Get new video info
|
||||||
|
getVideoInfo();
|
||||||
|
|
||||||
// If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up
|
// If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up
|
||||||
if (Config.config.checkForUnlistedVideos) {
|
if (Config.config.checkForUnlistedVideos) {
|
||||||
await utils.wait(isPrivacyInfoAvailable);
|
await utils.wait(isPrivacyInfoAvailable);
|
||||||
@@ -303,10 +309,8 @@ async function videoIDChange(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use a better method here than using type any
|
// Update whitelist data when the video data is loaded
|
||||||
// This is done to be able to do channelIDPromise.isFulfilled and channelIDPromise.isRejected
|
utils.wait(() => !!videoInfo).then(whitelistCheck);
|
||||||
let channelIDPromise: any = utils.wait(getChannelID);
|
|
||||||
channelIDPromise.then(() => channelIDPromise.isFulfilled = true).catch(() => channelIDPromise.isRejected = true);
|
|
||||||
|
|
||||||
//setup the preview bar
|
//setup the preview bar
|
||||||
if (previewBar === null) {
|
if (previewBar === null) {
|
||||||
@@ -346,7 +350,7 @@ async function videoIDChange(id) {
|
|||||||
//close popup
|
//close popup
|
||||||
closeInfoMenu();
|
closeInfoMenu();
|
||||||
|
|
||||||
sponsorsLookup(id, channelIDPromise);
|
sponsorsLookup(id);
|
||||||
|
|
||||||
//make sure everything is properly added
|
//make sure everything is properly added
|
||||||
updateVisibilityOfPlayerControlsButton().then(() => {
|
updateVisibilityOfPlayerControlsButton().then(() => {
|
||||||
@@ -523,11 +527,11 @@ function incorrectVideoIDCheck(): boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sponsorsLookup(id: string, channelIDPromise?) {
|
function sponsorsLookup(id: string) {
|
||||||
video = document.querySelector('video') // Youtube video player
|
video = document.querySelector('video') // Youtube video player
|
||||||
//there is no video here
|
//there is no video here
|
||||||
if (video == null) {
|
if (video == null) {
|
||||||
setTimeout(() => sponsorsLookup(id, channelIDPromise), 100);
|
setTimeout(() => sponsorsLookup(id), 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,18 +590,6 @@ function sponsorsLookup(id: string, channelIDPromise?) {
|
|||||||
startSponsorSchedule();
|
startSponsorSchedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channelIDPromise !== undefined) {
|
|
||||||
if (channelIDPromise.isFulfilled) {
|
|
||||||
whitelistCheck();
|
|
||||||
} else if (channelIDPromise.isRejected) {
|
|
||||||
//try again
|
|
||||||
utils.wait(getChannelID).then(whitelistCheck).catch();
|
|
||||||
} else {
|
|
||||||
//add it as a then statement
|
|
||||||
channelIDPromise.then(whitelistCheck);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//check database for sponsor times
|
//check database for sponsor times
|
||||||
//made true once a setTimeout has been created to try again after a server error
|
//made true once a setTimeout has been created to try again after a server error
|
||||||
let recheckStarted = false;
|
let recheckStarted = false;
|
||||||
@@ -682,23 +674,13 @@ function sponsorsLookup(id: string, channelIDPromise?) {
|
|||||||
sponsorDataFound = false;
|
sponsorDataFound = false;
|
||||||
|
|
||||||
//check if this video was uploaded recently
|
//check if this video was uploaded recently
|
||||||
//use the invidious api to get the time published
|
utils.wait(() => !!videoInfo).then(() => {
|
||||||
sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) {
|
let dateUploaded = videoInfo.microformat.playerMicroformatRenderer.uploadDate;
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
|
||||||
let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1];
|
|
||||||
|
|
||||||
if (decodedData === undefined) {
|
//if less than 3 days old
|
||||||
console.error("[SB] Failed at getting video upload date info from YouTube.");
|
if (Date.now() - new Date(dateUploaded).getTime() < 259200000) {
|
||||||
return;
|
//TODO lower when server becomes better
|
||||||
}
|
setTimeout(() => sponsorsLookup(id), 180000);
|
||||||
|
|
||||||
let dateUploaded = JSON.parse(decodedData).microformat.playerMicroformatRenderer.uploadDate;
|
|
||||||
|
|
||||||
//if less than 3 days old
|
|
||||||
if (Date.now() - new Date(dateUploaded).getTime() < 259200000) {
|
|
||||||
//TODO lower when server becomes better
|
|
||||||
setTimeout(() => sponsorsLookup(id, channelIDPromise), 180000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -708,13 +690,30 @@ function sponsorsLookup(id: string, channelIDPromise?) {
|
|||||||
|
|
||||||
//TODO lower when server becomes better (back to 1 second)
|
//TODO lower when server becomes better (back to 1 second)
|
||||||
//some error occurred, try again in a second
|
//some error occurred, try again in a second
|
||||||
setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000);
|
setTimeout(() => sponsorsLookup(id), 10000);
|
||||||
|
|
||||||
sponsorLookupRetries++;
|
sponsorLookupRetries++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the video info for the current tab from YouTube
|
||||||
|
*/
|
||||||
|
function getVideoInfo() {
|
||||||
|
sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + sponsorVideoID, function(xmlhttp, error) {
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
|
let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1];
|
||||||
|
if (!decodedData) {
|
||||||
|
console.error("[SB] Failed at getting video info from YouTube.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
videoInfo = JSON.parse(decodedData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getYouTubeVideoID(url: string) {
|
function getYouTubeVideoID(url: string) {
|
||||||
// For YouTube TV support
|
// For YouTube TV support
|
||||||
if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", "");
|
if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", "");
|
||||||
@@ -757,55 +756,6 @@ function getYouTubeVideoID(url: string) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannelID() {
|
|
||||||
//get channel id
|
|
||||||
let channelURLContainer = null;
|
|
||||||
|
|
||||||
channelURLContainer = document.querySelector("#channel-name > #container > #text-container > #text");
|
|
||||||
if (channelURLContainer !== null) {
|
|
||||||
channelURLContainer = channelURLContainer.firstElementChild;
|
|
||||||
} else if (onInvidious) {
|
|
||||||
// Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers...
|
|
||||||
channelURLContainer = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a");
|
|
||||||
} else {
|
|
||||||
//old YouTube theme
|
|
||||||
let channelContainers = document.getElementsByClassName("yt-user-info");
|
|
||||||
if (channelContainers.length != 0) {
|
|
||||||
channelURLContainer = channelContainers[0].firstElementChild;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channelURLContainer === null) {
|
|
||||||
//try later
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//first get the title to make sure a title change has occurred (otherwise the next video might still be loading)
|
|
||||||
let titleInfoContainer = document.getElementById("info-contents");
|
|
||||||
let currentTitle = "";
|
|
||||||
if (titleInfoContainer != null) {
|
|
||||||
currentTitle = (<HTMLElement> titleInfoContainer.firstElementChild.firstElementChild.querySelector(".title").firstElementChild).innerText;
|
|
||||||
} else if (onInvidious) {
|
|
||||||
// Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers...
|
|
||||||
currentTitle = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a > div > span").textContent;
|
|
||||||
} else {
|
|
||||||
//old YouTube theme
|
|
||||||
currentTitle = document.getElementById("eow-title").innerText;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (title == currentTitle) {
|
|
||||||
//video hasn't changed yet, wait
|
|
||||||
//try later
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
title = currentTitle;
|
|
||||||
|
|
||||||
channelURL = channelURLContainer.getAttribute("href");
|
|
||||||
|
|
||||||
//reset variables
|
|
||||||
channelWhitelisted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is required on mobile YouTube and will keep getting called whenever the preview bar disapears
|
* This function is required on mobile YouTube and will keep getting called whenever the preview bar disapears
|
||||||
*/
|
*/
|
||||||
@@ -845,10 +795,12 @@ function updatePreviewBar() {
|
|||||||
|
|
||||||
//checks if this channel is whitelisted, should be done only after the channelID has been loaded
|
//checks if this channel is whitelisted, should be done only after the channelID has been loaded
|
||||||
function whitelistCheck() {
|
function whitelistCheck() {
|
||||||
|
channelID = videoInfo.videoDetails.channelId;
|
||||||
|
|
||||||
//see if this is a whitelisted channel
|
//see if this is a whitelisted channel
|
||||||
let whitelistedChannels = Config.config.whitelistedChannels;
|
let whitelistedChannels = Config.config.whitelistedChannels;
|
||||||
|
|
||||||
if (whitelistedChannels != undefined && whitelistedChannels.includes(channelURL)) {
|
if (whitelistedChannels != undefined && whitelistedChannels.includes(channelID)) {
|
||||||
channelWhitelisted = true;
|
channelWhitelisted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/popup.ts
65
src/popup.ts
@@ -919,39 +919,44 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
}, tabs => {
|
}, tabs => {
|
||||||
messageHandler.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: 'getChannelURL'},
|
{message: 'getChannelID'},
|
||||||
function(response) {
|
function(response) {
|
||||||
|
if (!response.channelID) {
|
||||||
|
alert(chrome.i18n.getMessage("channelDataNotFound"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//get whitelisted channels
|
//get whitelisted channels
|
||||||
let whitelistedChannels = Config.config.whitelistedChannels;
|
let whitelistedChannels = Config.config.whitelistedChannels;
|
||||||
if (whitelistedChannels == undefined) {
|
if (whitelistedChannels == undefined) {
|
||||||
whitelistedChannels = [];
|
whitelistedChannels = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
//add on this channel
|
||||||
|
whitelistedChannels.push(response.channelID);
|
||||||
|
|
||||||
|
//change button
|
||||||
|
PageElements.whitelistChannel.style.display = "none";
|
||||||
|
PageElements.unwhitelistChannel.style.display = "unset";
|
||||||
|
|
||||||
|
PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
||||||
|
PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
||||||
|
|
||||||
|
//save this
|
||||||
|
Config.config.whitelistedChannels = whitelistedChannels;
|
||||||
|
|
||||||
|
//send a message to the client
|
||||||
|
messageHandler.query({
|
||||||
|
active: true,
|
||||||
|
currentWindow: true
|
||||||
|
}, tabs => {
|
||||||
|
messageHandler.sendMessage(
|
||||||
|
tabs[0].id, {
|
||||||
|
message: 'whitelistChange',
|
||||||
|
value: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
);
|
||||||
//add on this channel
|
|
||||||
whitelistedChannels.push(response.channelURL);
|
|
||||||
|
|
||||||
//change button
|
|
||||||
PageElements.whitelistChannel.style.display = "none";
|
|
||||||
PageElements.unwhitelistChannel.style.display = "unset";
|
|
||||||
|
|
||||||
PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
|
||||||
PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
|
||||||
|
|
||||||
//save this
|
|
||||||
Config.config.whitelistedChannels = whitelistedChannels;
|
|
||||||
|
|
||||||
//send a message to the client
|
|
||||||
messageHandler.query({
|
|
||||||
active: true,
|
|
||||||
currentWindow: true
|
|
||||||
}, tabs => {
|
|
||||||
messageHandler.sendMessage(
|
|
||||||
tabs[0].id, {
|
|
||||||
message: 'whitelistChange',
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user