From cd03218940485d7a7d65d693ae9ca39be1bb91aa Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 9 Apr 2020 01:19:00 -0400 Subject: [PATCH] Now uses new GET api when testing server is enabled --- config.json.example | 1 + src/content.ts | 321 ++++++++++++++++++++++++++++++-------------- src/utils.ts | 41 +++++- 3 files changed, 260 insertions(+), 103 deletions(-) diff --git a/config.json.example b/config.json.example index 90698dd9..451d8c14 100644 --- a/config.json.example +++ b/config.json.example @@ -1,5 +1,6 @@ { "serverAddress": "https://sponsor.ajay.app", + "testingServerAddress": "https://sponsor.ajay.app/test", "serverAddressComment": "This specifies the default SponsorBlock server to conect to", "categoryList": ["sponsor", "intro", "outro", "interaction", "merchandise", "offtopic"] } diff --git a/src/content.ts b/src/content.ts index 237e0aa5..aebfa5a8 100644 --- a/src/content.ts +++ b/src/content.ts @@ -593,120 +593,239 @@ function sponsorsLookup(id: string, channelIDPromise?) { //check database for sponsor times //made true once a setTimeout has been created to try again after a server error let recheckStarted = false; - utils.sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) { - if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - sponsorDataFound = true; + if (Config.config.testingServer) { + // Create categories list + let categories: string[] = []; + for (const categorySelection of Config.config.categorySelections) { + categories.push(categorySelection.name); + } - let recievedSegments: number[][] = JSON.parse(xmlhttp.responseText).sponsorTimes; - let recievedUUIDs: string[] = JSON.parse(xmlhttp.responseText).UUIDs; + utils.requestToServer('GET', "/api/skipSegments", { + videoID: id, + categories + }).then(async (response: Response) => { + if (response.status === 200) { + sponsorDataFound = true; - // Check if any old submissions should be kept - if (sponsorTimes !== null) { - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i].UUID === null) { - // This is a user submission, keep it - recievedSegments.push(sponsorTimes[i].segment); - } + let recievedSegments: SponsorTime[] = await response.json(); + if (!recievedSegments.length) { + console.error("[SponsorBlock] Server returned malformed response: " + JSON.stringify(recievedSegments)); } - } - - // Create formatted array - sponsorTimes = []; - for (let i = 0; i < recievedSegments.length; i++) { - sponsorTimes.push({ - segment: recievedSegments[i], - UUID: recievedUUIDs[i], - // Force sponsor category for now - //TODO: Remove this - category: "sponsor" - }); - } - - // Remove all submissions smaller than the minimum duration - if (Config.config.minDuration !== 0) { - let smallSegments: SponsorTime[] = []; - - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] >= Config.config.minDuration) { - smallSegments.push(sponsorTimes[i]); - } - } - - sponsorTimes = smallSegments; - } - - if (!switchingVideos) { - // See if there are any starting sponsors - let startingSponsor: number = -1; - for (const time of sponsorTimes) { - if (time[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { - startingSponsor = time.segment[0]; - break; - } - } - if (!startingSponsor) { - for (const time of sponsorTimesSubmitting) { - if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { - startingSponsor = time.segment[0]; - break; + + // Check if any old submissions should be kept + if (sponsorTimes !== null) { + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i].UUID === null) { + // This is a user submission, keep it + recievedSegments.push(sponsorTimes[i]); } } } - if (startingSponsor !== -1) { - startSponsorSchedule(false, startingSponsor); - } else { - startSponsorSchedule(); - } - } - - // Reset skip save - sponsorSkipped = []; - - //update the preview bar - //leave the type blank for now until categories are added - if (lastPreviewBarUpdate == id || (lastPreviewBarUpdate == null && !isNaN(video.duration))) { - //set it now - //otherwise the listener can handle it - updatePreviewBar(); - } - - sponsorLookupRetries = 0; - } else if (xmlhttp.readyState == 4 && xmlhttp.status == 404) { - sponsorDataFound = false; - - //check if this video was uploaded recently - //use the invidious api to get the time published - sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) { - if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; - - if (decodedData === undefined) { - console.error("[SB] Failed at getting video upload date info from YouTube."); - return; + sponsorTimes = recievedSegments; + console.log(sponsorTimes) + + // Remove all submissions smaller than the minimum duration + if (Config.config.minDuration !== 0) { + let smallSegments: SponsorTime[] = []; + + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] >= Config.config.minDuration) { + smallSegments.push(sponsorTimes[i]); + } } - - 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); + + sponsorTimes = smallSegments; + } + + if (!switchingVideos) { + // See if there are any starting sponsors + let startingSponsor: number = -1; + for (const time of sponsorTimes) { + if (time[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { + startingSponsor = time.segment[0]; + break; + } + } + if (!startingSponsor) { + for (const time of sponsorTimesSubmitting) { + if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { + startingSponsor = time.segment[0]; + break; + } + } + } + + if (startingSponsor !== -1) { + startSponsorSchedule(false, startingSponsor); + } else { + startSponsorSchedule(); } } - }); + + // Reset skip save + sponsorSkipped = []; + + //update the preview bar + //leave the type blank for now until categories are added + if (lastPreviewBarUpdate == id || (lastPreviewBarUpdate == null && !isNaN(video.duration))) { + //set it now + //otherwise the listener can handle it + updatePreviewBar(); + } + + sponsorLookupRetries = 0; + } else if (response.status === 404) { + sponsorDataFound = false; - sponsorLookupRetries = 0; - } else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 90 && !recheckStarted) { - recheckStarted = true; + //check if this video was uploaded recently + //use the invidious api to get the time published + sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; - //TODO lower when server becomes better (back to 1 second) - //some error occurred, try again in a second - setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000); + if (decodedData === undefined) { + console.error("[SB] Failed at getting video upload date info from YouTube."); + return; + } - sponsorLookupRetries++; - } - }); + 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); + } + } + }); + + sponsorLookupRetries = 0; + } else if (sponsorLookupRetries < 90 && !recheckStarted) { + recheckStarted = true; + + //TODO lower when server becomes better (back to 1 second) + //some error occurred, try again in a second + setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000); + + sponsorLookupRetries++; + } + }); + } else { + utils.sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + sponsorDataFound = true; + + let recievedSegments: number[][] = JSON.parse(xmlhttp.responseText).sponsorTimes; + let recievedUUIDs: string[] = JSON.parse(xmlhttp.responseText).UUIDs; + + // Check if any old submissions should be kept + if (sponsorTimes !== null) { + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i].UUID === null) { + // This is a user submission, keep it + recievedSegments.push(sponsorTimes[i].segment); + } + } + } + + // Create formatted array + sponsorTimes = []; + for (let i = 0; i < recievedSegments.length; i++) { + sponsorTimes.push({ + segment: recievedSegments[i], + UUID: recievedUUIDs[i], + // Force sponsor category for now + //TODO: Remove this + category: "sponsor" + }); + } + + // Remove all submissions smaller than the minimum duration + if (Config.config.minDuration !== 0) { + let smallSegments: SponsorTime[] = []; + + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] >= Config.config.minDuration) { + smallSegments.push(sponsorTimes[i]); + } + } + + sponsorTimes = smallSegments; + } + + if (!switchingVideos) { + // See if there are any starting sponsors + let startingSponsor: number = -1; + for (const time of sponsorTimes) { + if (time[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { + startingSponsor = time.segment[0]; + break; + } + } + if (!startingSponsor) { + for (const time of sponsorTimesSubmitting) { + if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { + startingSponsor = time.segment[0]; + break; + } + } + } + + if (startingSponsor !== -1) { + startSponsorSchedule(false, startingSponsor); + } else { + startSponsorSchedule(); + } + } + + // Reset skip save + sponsorSkipped = []; + + //update the preview bar + //leave the type blank for now until categories are added + if (lastPreviewBarUpdate == id || (lastPreviewBarUpdate == null && !isNaN(video.duration))) { + //set it now + //otherwise the listener can handle it + updatePreviewBar(); + } + + sponsorLookupRetries = 0; + } else if (xmlhttp.readyState == 4 && xmlhttp.status == 404) { + sponsorDataFound = false; + + //check if this video was uploaded recently + //use the invidious api to get the time published + sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; + + if (decodedData === undefined) { + console.error("[SB] Failed at getting video upload date info from YouTube."); + return; + } + + 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); + } + } + }); + + sponsorLookupRetries = 0; + } else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 90 && !recheckStarted) { + recheckStarted = true; + + //TODO lower when server becomes better (back to 1 second) + //some error occurred, try again in a second + setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000); + + sponsorLookupRetries++; + } + }); + } } function getYouTubeVideoID(url: string) { diff --git a/src/utils.ts b/src/utils.ts index 974b62b6..1c8f0067 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,8 @@ import Config from "./config"; import { CategorySelection, SponsorTime } from "./types"; +import * as CompileConfig from "../config.json"; + class Utils { // Contains functions needed from the background script @@ -267,6 +269,39 @@ class Utils { return errorMessage; } + /** + * Sends a request to the SponsorBlock server with address added as a query + * + * @param type The request type. "GET", "POST", etc. + * @param address The address to add to the SponsorBlock server address + * @param callback + */ + async requestToServer(type: string, address: string, data = {}) { + let serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress; + + // If GET, convert JSON to parameters + if (type.toLowerCase() === "get") { + for (const key in data) { + let seperator = address.includes("?") ? "&" : "?"; + let value = (typeof(data[key]) === "string") ? data[key]: JSON.stringify(data[key]); + address += seperator + key + "=" + value; + } + + data = null; + } + + const response = await fetch(serverAddress + address, { + method: type, + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + body: data ? JSON.stringify(data) : null + }); + + return response; + } + /** * Sends a request to the SponsorBlock server with address added as a query * @@ -276,8 +311,10 @@ class Utils { */ sendRequestToServer(type: string, address: string, callback?: (xmlhttp: XMLHttpRequest, err: boolean) => any) { let xmlhttp = new XMLHttpRequest(); - - xmlhttp.open(type, Config.config.serverAddress + address, true); + + let serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress; + + xmlhttp.open(type, serverAddress + address, true); if (callback != undefined) { xmlhttp.onreadystatechange = function () {