Skip to content

Instantly share code, notes, and snippets.

@AmadeusWizard
Forked from WiBla/README.md
Created March 24, 2020 19:05
Show Gist options
  • Save AmadeusWizard/781552175557b7cf67161b6bcd29b21b to your computer and use it in GitHub Desktop.
Save AmadeusWizard/781552175557b7cf67161b6bcd29b21b to your computer and use it in GitHub Desktop.
This script will add a button next to "import/create playlist" that allows you to add videos without searching for them
// ==UserScript==
// @name Plug.dj YT API Key workaround
// @namespace https://plug.dj?refuid=4613422
// @version 1.3.3
// @author WiBla (contact.wibla@gmail.com)
// @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 */
(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() {
window.gapi.client.setApiKey('AIzaSyD--___tekD3NI_-Sj8cAnNyuDKFmdtOkM');
var pl = {}, media = {};
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) {
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[1].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: () => alert('YT API didn\'t reply, is your key still valid?')
});
}
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! You might need a refresh to see it.'),
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);
}
let found = false;
function findPlaylist() {
if (found) return askCID();
pl.name = prompt('In which playlist do you wish to add the song?\nName must be exactly the same');
if (!!pl.name === false) return;
$.ajax({
url: '/_/playlists',
success: (data) => {
data.data.forEach((playlist, i, a) => {
if (playlist.name === pl.name) {
if (playlist.count === 200) {
alert(`${pl.name} is full!`);
} else {
pl.id = playlist.id;
found = true;
askCID();
}
}
if (i + 1 >= a.length && !found) {
if (confirm(`${pl.name} couldn't be found. Do you whish to add the live in "${playlist.name}"?`)) {
pl = playlist;
askCID();
}
}
});
}
});
}
var $grabBtn = $(`<div id="playlist-import" class="button" title="CTRL + Click to change playlist">
<i class="fa fa-plus-circle"></i>
<span>YT Grab+</span>
</div>`);
$grabBtn.click(function(event) {
found = event.ctrlKey ? false : found;
findPlaylist();
});
$('.playlist-buttons-import-create').append($grabBtn);
console.log('yt-workaround loaded! You\'ll need to refresh to deactivate it');
};
autoReload();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment