aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOfficial Noob <[email protected]>2019-08-11 13:38:00 +0100
committerGitHub <[email protected]>2019-08-11 13:38:00 +0100
commite1f5046ace2dd0d1010bc1b4da99d050afd20667 (patch)
treea4e775b045e7fcb240d76f54592f49ed1373a005
parent866cc33f0e7c52d996c50eb7684a927f99db5ab0 (diff)
parent699ca91a9430f6715f966533fdb5eceb0a57e7a3 (diff)
downloadSponsorBlock-e1f5046ace2dd0d1010bc1b4da99d050afd20667.tar.gz
SponsorBlock-e1f5046ace2dd0d1010bc1b4da99d050afd20667.zip
Merge branch 'experimental' into patch-19
-rw-r--r--LICENSE11
-rw-r--r--README.md10
-rw-r--r--background.js96
-rw-r--r--content.js10
-rw-r--r--manifest.json9
-rw-r--r--popup.html3
-rw-r--r--popup.js47
-rw-r--r--utils.js37
8 files changed, 128 insertions, 95 deletions
diff --git a/LICENSE b/LICENSE
index ce167a86..61e854aa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,8 @@
- GNU GENERAL PUBLIC LICENSE
+SponsorBlock Copyright (C) 2019 Ajay Ramachandran and other SponsorBlock contributors.
+
+Please refer to the license below.
+
+ GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
@@ -651,8 +655,9 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
-
- SponsorBlock Copyright (C) 2019 Ajay Ramachandran and other SponsorBlock contributors
+
+ <program> Copyright (C) <year> <name of author>
+
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
diff --git a/README.md b/README.md
index 74fbcac5..6ca1eb4c 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
# SponsorBlock
-SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
+SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
# Available for Chrome and Firefox
@@ -21,9 +21,13 @@ To make sure that this project doesn't die, I have made the database publicly do
Hopefully this project can be combined with projects like [this](https://github.com/Sponsoff/sponsorship_remover) and use this data to create a neural network to predict when sponsored segments happen. That project is sadly abandoned now, so I have decided to attempt to revive this idea.
+# API
+
+You can read the API docs [here](https://github.com/ajayyy/SponsorBlockServer#api-docs).
+
# Previous extension
-This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip). That extension has the basic video skipping functionality.
+This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip), which has the basic video skipping functionality.
# Build Yourself
@@ -35,4 +39,4 @@ The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) is u
Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
-Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
+Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
diff --git a/background.js b/background.js
index da9a1d39..c08ad16b 100644
--- a/background.js
+++ b/background.js
@@ -1,9 +1,3 @@
-//the id of this user, randomly generated once per install
-var userID = null;
-
-//the last video id loaded, to make sure it is a video id change
-var sponsorVideoID = null;
-
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.sendMessage(tabId, {
message: 'update',
@@ -40,14 +34,39 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
//add help page on install
chrome.runtime.onInstalled.addListener(function (object) {
- chrome.storage.sync.get(["shownInstallPage"], function(result) {
- let shownInstallPage = result.shownInstallPage;
- if (shownInstallPage == undefined || !shownInstallPage) {
- //open up the install page
- chrome.tabs.create({url: chrome.extension.getURL("/help/index.html")});
-
- //save that this happened
- chrome.storage.sync.set({shownInstallPage: true});
+ // TODO (shownInstallPage): remove shownInstallPage logic after sufficient amount of time,
+ // so that people have time to upgrade and move to shownInstallPage-free code.
+ chrome.storage.sync.get(["userID", "shownInstallPage"], function(result) {
+ const userID = result.userID;
+ // TODO (shownInstallPage): delete row below
+ const shownInstallPage = result.shownInstallPage;
+
+ // If there is no userID, then it is the first install.
+ if (!userID){
+ // Show install page, if there is no user id
+ // and there is no shownInstallPage.
+ // TODO (shownInstallPage): remove this if statement, but leave contents
+ if (!shownInstallPage){
+ //open up the install page
+ chrome.tabs.create({url: chrome.extension.getURL("/help/index.html")});
+ }
+
+ // TODO (shownInstallPage): delete if statement and contents
+ // If shownInstallPage is set, remove it.
+ if (!!shownInstallPage){
+ chrome.storage.sync.remove("shownInstallPage");
+ }
+
+ //generate a userID
+ const newUserID = generateUUID();
+ //save this UUID
+ chrome.storage.sync.set({
+ "userID": newUserID,
+ "serverAddress": serverAddress,
+ //the last video id loaded, to make sure it is a video id change
+ "sponsorVideoID": null,
+ "previousVideoID": null
+ });
}
});
});
@@ -87,9 +106,12 @@ function addSponsorTime(time, videoID, callback) {
}
function submitVote(type, UUID, callback) {
- getUserID(function(userID) {
+ chrome.storage.sync.get(["serverAddress", "userID"], function(result) {
+ const serverAddress = result.serverAddress;
+ const userID = result.userID;
+
//publish this vote
- sendRequestToServer('GET', "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
+ sendRequestToServer("GET", serverAddress + "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
callback({
successType: 1
@@ -114,16 +136,17 @@ function submitVote(type, UUID, callback) {
function submitTimes(videoID, callback) {
//get the video times from storage
let sponsorTimeKey = 'sponsorTimes' + videoID;
- chrome.storage.sync.get([sponsorTimeKey], function(result) {
+ chrome.storage.sync.get([sponsorTimeKey, "serverAddress"], function(result) {
let sponsorTimes = result[sponsorTimeKey];
+ const serverAddress = result.serverAddress;
+ const userID = result.userID;
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
//submit these times
for (let i = 0; i < sponsorTimes.length; i++) {
- getUserID(function(userIDStorage) {
//submit the sponsorTime
- sendRequestToServer('GET', "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
- + "&userID=" + userIDStorage, function(xmlhttp, error) {
+ sendRequestToServer("GET", serverAddress + "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
+ + "&userID=" + userID, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && !error) {
callback({
statusCode: xmlhttp.status
@@ -147,47 +170,16 @@ function submitTimes(videoID, callback) {
statusCode: -1
});
}
- });
});
}
}
});
}
-function getUserID(callback) {
- if (userID != null) {
- callback(userID);
- return;
- }
-
- //if it is not cached yet, grab it from storage
- chrome.storage.sync.get(["userID"], function(result) {
- let userIDStorage = result.userID;
- if (userIDStorage != undefined) {
- userID = userIDStorage;
- callback(userID);
- } else {
- //double check if a UUID hasn't been created since this was first called
- if (userID != null) {
- callback(userID);
- return;
- }
-
- //generate a userID
- userID = generateUUID();
-
- //save this UUID
- chrome.storage.sync.set({"userID": userID});
-
- callback(userID);
- }
- });
-}
-
function sendRequestToServer(type, address, callback) {
let xmlhttp = new XMLHttpRequest();
- xmlhttp.open(type, serverAddress + address, true);
+ xmlhttp.open(type, address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
diff --git a/content.js b/content.js
index 41ea3f78..5775abc1 100644
--- a/content.js
+++ b/content.js
@@ -10,10 +10,6 @@ var sponsorVideoID = null;
//the time this video is starting at when first played, if not zero
var youtubeVideoStartTime = null;
-if(id = getYouTubeVideoID(document.URL)){ // Direct Links
- videoIDChange(id);
-}
-
//the video
var v;
@@ -23,6 +19,10 @@ var channelURL;
//is this channel whitelised from getting sponsors skipped
var channelWhitelisted = false;
+if(id = getYouTubeVideoID(document.URL)){ // Direct Links
+ videoIDChange(id);
+}
+
//the last time looked at (used to see if this time is in the interval)
var lastTime = -1;
@@ -1190,4 +1190,4 @@ function getYouTubeVideoStartTime(url) {
}
return startTime;
-}
+} \ No newline at end of file
diff --git a/manifest.json b/manifest.json
index 0f48727c..1aead84f 100644
--- a/manifest.json
+++ b/manifest.json
@@ -11,6 +11,7 @@
"all_frames": true,
"js": [
"config.js",
+ "utils.js",
"content.js",
"popup.js"
],
@@ -32,9 +33,7 @@
"icons/downvote.png",
"icons/PlayerInfoIconSponsorBlocker256px.png",
"icons/PlayerDeleteIconSponsorBlocker256px.png",
- "popup.html",
- "help/index.html",
- "help/style.css"
+ "popup.html"
],
"permissions": [
"storage",
@@ -47,9 +46,11 @@
},
"background": {
"scripts":[
+ "utils.js",
"config.js",
"background.js"
- ]
+ ],
+ "persistent": false
},
"icons": {
"16": "icons/IconSponsorBlocker16px.png",
diff --git a/popup.html b/popup.html
index be45142b..30195294 100644
--- a/popup.html
+++ b/popup.html
@@ -193,5 +193,6 @@
<!-- Scripts that need to load after the html -->
<script src="config.js"></script>
+ <script src="utils.js"></script>
<script src="popup.js"></script>
-</html> \ No newline at end of file
+</html>
diff --git a/popup.js b/popup.js
index e1a63818..2e2ac15e 100644
--- a/popup.js
+++ b/popup.js
@@ -123,26 +123,6 @@ function runThePopup() {
}
});
- //see if whitelist button should be swapped
- chrome.tabs.query({
- active: true,
- currentWindow: true
- }, tabs => {
- chrome.tabs.sendMessage(
- tabs[0].id,
- {message: 'isChannelWhitelisted'},
- function(response) {
- if (response.value) {
- SB.whitelistChannel.style.display = "none";
- SB.unwhitelistChannel.style.display = "unset";
-
- SB.downloadedSponsorMessageTimes.innerText = "Channel Whitelisted!";
- SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
- }
- });
- }
- );
-
//if the don't show notice again letiable is true, an option to
// disable should be available
chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
@@ -294,6 +274,26 @@ function runThePopup() {
SB.videoFound.innerHTML = "No sponsors found"
}
}
+
+ //see if whitelist button should be swapped
+ chrome.tabs.query({
+ active: true,
+ currentWindow: true
+ }, tabs => {
+ chrome.tabs.sendMessage(
+ tabs[0].id,
+ {message: 'isChannelWhitelisted'},
+ function(response) {
+ if (response.value) {
+ SB.whitelistChannel.style.display = "none";
+ SB.unwhitelistChannel.style.display = "unset";
+
+ SB.downloadedSponsorMessageTimes.innerText = "Channel Whitelisted!";
+ SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
+ }
+ });
+ }
+ );
}
function setVideoID(request) {
@@ -1129,13 +1129,6 @@ function runThePopup() {
xmlhttp.send();
}
- function getYouTubeVideoID(url) { // Returns with video id else returns false
- var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
- var match = url.match(regExp);
- var id = new URL(url).searchParams.get("v");
- return (match && match[7].length == 11) ? id : false;
- }
-
//end of function
}
diff --git a/utils.js b/utils.js
new file mode 100644
index 00000000..178d4e81
--- /dev/null
+++ b/utils.js
@@ -0,0 +1,37 @@
+function getYouTubeVideoID(url) {
+ //Attempt to parse url
+ let urlObject = null;
+ try {
+ urlObject = new URL(url);
+ } catch (e) {
+ console.error("[SB] Unable to parse URL: " + url);
+ return false
+ }
+
+ //Check if valid hostname
+ if(!["www.youtube.com","www.youtube-nocookie.com"].includes(urlObject.host)) return false;
+
+ //Get ID from searchParam
+ if ((urlObject.pathname == "/watch" || urlObject.pathname == "/watch/") && urlObject.searchParams.has("v")) {
+ id = urlObject.searchParams.get("v");
+ return id.length == 11 ? id : false;
+ } else if (urlObject.pathname.startsWith("/embed/")) {
+ try {
+ return urlObject.pathname.substr(7, 11);
+ } catch (e) {
+ console.error("[SB] Video ID not valid for " + url);
+ return false;
+ }
+ }
+}
+
+//returns the start time of the video if there was one specified (ex. ?t=5s)
+function getYouTubeVideoStartTime(url) {
+ let searchParams = new URL(url).searchParams;
+ let startTime = searchParams.get("t");
+ if (startTime == null) {
+ startTime = searchParams.get("time_continue");
+ }
+
+ return startTime;
+}