|
// ==UserScript== |
|
// @name Plug.dj YT API Key workaround |
|
// @namespace https://plug.dj?refuid=4613422 |
|
// @version 1.7.0 |
|
// @author WiBla ([email protected]) |
|
// @description This script will add a button next to "import/create playlist" that allows you to add videos without searching for them |
|
// @downloadURL https://gist.github.com/WiBla/ad1aa9a98949c624cd2886c1a25b5feb/raw/8d83fc7bb1ac77f8ff9494023991e21e5599ec56/yt-workaround.user.js |
|
// @updateURL https://gist.github.com/WiBla/ad1aa9a98949c624cd2886c1a25b5feb/raw/8d83fc7bb1ac77f8ff9494023991e21e5599ec56/yt-workaround.user.js |
|
// @include *://plug.dj/* |
|
// @include *://*.plug.dj/* |
|
// @exclude *://*.plug.dj/_/* |
|
// @exclude *://*.plug.dj/@/* |
|
// @exclude *://*.plug.dj/!/* |
|
// @exclude *://*.plug.dj/about |
|
// @exclude *://*.plug.dj/ba |
|
// @exclude *://*.plug.dj/forgot-password |
|
// @exclude *://*.plug.dj/founders |
|
// @exclude *://*.plug.dj/giftsub/* |
|
// @exclude *://*.plug.dj/jobs |
|
// @exclude *://*.plug.dj/legal |
|
// @exclude *://*.plug.dj/merch |
|
// @exclude *://*.plug.dj/partners |
|
// @exclude *://*.plug.dj/plot |
|
// @exclude *://*.plug.dj/privacy |
|
// @exclude *://*.plug.dj/purchase |
|
// @exclude *://*.plug.dj/subscribe |
|
// @exclude *://*.plug.dj/team |
|
// @exclude *://*.plug.dj/terms |
|
// @exclude *://*.plug.dj/press |
|
// @grant none |
|
// @run-at document-end |
|
// ==/UserScript== |
|
|
|
/* global $, gapi, API, _, require */ |
|
(function() { |
|
'use strict'; |
|
|
|
// Because plug.dj hides the interface while loading, this is necessary |
|
// We can't just use document.readyState ($.ready) |
|
function plugReady() { |
|
return typeof API !== 'undefined' && API.enabled && typeof jQuery !== 'undefined' && typeof require !== 'undefined'; |
|
} |
|
function autoReload() { |
|
if (!plugReady()) { |
|
setTimeout(autoReload, 200); |
|
} else { |
|
init(); |
|
} |
|
} |
|
function init() { |
|
var pl = {}, media = {}, APIKey = localStorage.getItem('yt-api-key'); |
|
|
|
if (APIKey == null) { |
|
APIKey = 'AIzaSyD--___tekD3NI_-Sj8cAnNyuDKFmdtOkM'; |
|
API.chatLog('⚠ YT-workaround is using the default API key, this is not recommended as everyone uses the same and it is very limited. If you know how, you should definitely get your own and configure it with /key [YOUR KEY HERE]'); |
|
} else { |
|
API.chatLog('YT-workaround is using a custom key, you rock 💪'); |
|
} |
|
window.gapi.client.setApiKey(APIKey); |
|
|
|
function convert_time(duration) { |
|
var a = duration.match(/\d+/g), |
|
indexOfH = duration.indexOf('H'), |
|
indexOfM = duration.indexOf('M'), |
|
indexOfS = duration.indexOf('S'); |
|
|
|
switch(true) { |
|
case indexOfM >= 0 && indexOfH == -1 && indexOfS == -1: |
|
a = [0, a[0], 0]; |
|
break; |
|
|
|
case indexOfH >= 0 && indexOfM == -1: |
|
a = [a[0], 0, a[1]]; |
|
break; |
|
|
|
case indexOfH >= 0 && indexOfM == -1 && indexOfS == -1: |
|
a = [a[0], 0, 0]; |
|
break; |
|
} |
|
|
|
duration = 0; |
|
|
|
switch(a.length) { |
|
case 1: |
|
duration = duration + parseInt(a[0]); |
|
break; |
|
|
|
case 2: |
|
duration = duration + parseInt(a[0]) * 60; |
|
duration = duration + parseInt(a[1]); |
|
break; |
|
|
|
case 3: |
|
duration = duration + parseInt(a[0]) * 3600; |
|
duration = duration + parseInt(a[1]) * 60; |
|
duration = duration + parseInt(a[2]); |
|
break; |
|
} |
|
|
|
return duration; |
|
} |
|
function completeMedia() { |
|
$.ajax({ |
|
url: `https://www.googleapis.com/youtube/v3/videos?id=${media.cid}&key=${gapi.config.get().client.apiKey}&part=snippet,contentDetails`, |
|
type: 'GET', |
|
success: (data) => { |
|
media.author = data.items[0].snippet.title.split('-'); |
|
|
|
// Video's title contains a "-" so parse it |
|
if (media.author.length > 1) { |
|
media.title = media.author[1].trim(); |
|
media.author = media.author[0].trim(); |
|
} else { // Otherwise, use the channel's name as author.. |
|
media.title = media.author[0].trim(); |
|
media.author = data.items[0].snippet.channelTitle; |
|
} |
|
|
|
media.image = data.items[0].snippet.thumbnails.default.url; |
|
media.duration = convert_time(data.items[0].contentDetails.duration); |
|
media.format = 1; |
|
media.id = -1; |
|
|
|
addMedia(); |
|
}, |
|
error: (err) => { |
|
if (err.responseJSON.error.message.indexOf('Daily Limit') > -1) { |
|
alert('The current API Key has exceeded its quota.\nTry setting your own by typing "/key [YOUR KEY HERE]" in the chat'); |
|
} else { |
|
console.error('[YT-WORKAROUND]', err); |
|
alert("Something went wrong with YouTube. You can check the console for more info."); |
|
} |
|
} |
|
}); |
|
} |
|
function addMedia() { |
|
$.ajax({ |
|
url: `/_/playlists/${pl.id}/media/insert`, |
|
type: 'POST', |
|
data: JSON.stringify({ |
|
media: [media], |
|
"append": false |
|
}), |
|
contentType: 'application/json', |
|
success: () => alert('Media added!\nIf you don\'t see it, try switching playlists or refreshing.'), |
|
error: (err) => { |
|
if (err.responseJSON.status === 'maxItems') { |
|
alert('This playlist is full!'); |
|
} else alert('Sorry, the media couldn\'t be added.'); |
|
} |
|
}); |
|
} |
|
function extractCID(cid) { |
|
return cid.replace(/(?:https?:)?(?:\/\/)?(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\/\S*?[^\w\s-])((?!videoseries)[\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gi, '$1'); |
|
} |
|
function askCID() { |
|
media.cid = prompt(`Importing in ${pl.name}:\nVideo's link:`); |
|
if (!!media.cid === false) return; |
|
|
|
media.cid = extractCID(media.cid); |
|
completeMedia(media); |
|
} |
|
|
|
var $grabBtn = $('<div id="playlist-add-button" class="button" title="YouTube Grab+">'+ |
|
'<i class="fa fa-plus-square"></i>'+ |
|
'</div>'); |
|
|
|
var playlists = _.find(require.s.contexts._.defined, (m)=>m&&m.activeMedia); |
|
function grabBtnClick() { |
|
playlists.models.forEach((model) => { |
|
model = model.toJSON(); |
|
if (model.visible) { |
|
if (model.count === 200) { |
|
alert(`${model.name} is full!`); |
|
} else { |
|
pl = model; |
|
askCID(); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
$grabBtn.click(grabBtnClick); |
|
$('.playlist-buttons-container .playlist-edit-group').prepend($grabBtn); |
|
|
|
function chatCmd(cmd) { |
|
cmd = cmd.split(' '); |
|
|
|
if (cmd[0] === '/key' && cmd.length == 2) { |
|
if (/AIza[0-9A-z\-_]{35}/.test(cmd[1]) === false) { |
|
API.chatLog('This is not a valid YT API Key!'); |
|
return; |
|
} |
|
|
|
window.gapi.client.setApiKey(cmd[1]); |
|
localStorage.setItem('yt-api-key', cmd[1]); |
|
API.chatLog('Custom API key saved! You\'re a pro 👍'); |
|
} else if (cmd[0] === '/grab-btn') { |
|
if ($('#playlist-add-button').length > 0) { |
|
$('#playlist-add-button').remove() |
|
} |
|
$grabBtn.off('click'); |
|
$grabBtn.click(grabBtnClick); |
|
$('.playlist-buttons-container .playlist-edit-group').prepend($grabBtn); |
|
} |
|
} |
|
API.on(API.CHAT_COMMAND, chatCmd); |
|
|
|
API.chatLog('YT-workaround fully loaded! Refresh to de-activate it.'); |
|
} |
|
|
|
autoReload(); |
|
})(); |
Hello @certuna,
First of all, thanks for using my script 😃
I have had other macOs users report me the same issue. I unfortunately don't have a mac on hand on which I could try to replicate it.
I can only confirm that using the extension doesn't seem to work for some odd reason..
Could you screenshot / upload the content of the devtool's console? It's accessible via F12 or
cmd+shift+i
This would really help me figure out the issue, so I can hopefully fix this for other macOs "pluggers" 😄
As an experience, could you try copy / pasting the content of this gist into the large input box on the extension's option menu?

It should look something like that :
Thanks in advance 👍