added browser extension proof of concept
26
browser_extension/README.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Tube Archivist Companion
|
||||||
|
A browser extension to directly add videos from YouTube to Tube Archivist.
|
||||||
|
|
||||||
|
## MVP or better *bearly viable product*
|
||||||
|
This is a proof of concept with the following functionality:
|
||||||
|
- Add your Tube Archivist connection details in the addon popup
|
||||||
|
- Inject a download button into youtube search results page
|
||||||
|
- Clicking the button will automatically add the video to the your download queue
|
||||||
|
|
||||||
|
## Test this extension
|
||||||
|
- Firefox
|
||||||
|
- Open `about:debugging#/runtime/this-firefox`
|
||||||
|
- Click on *Load Temporary Add-on*
|
||||||
|
- Select the *manifest.json* file to load the addon.
|
||||||
|
- Chrome / Chromium
|
||||||
|
- Open `chrome://extensions/`
|
||||||
|
- Toggle *Developer mode* on top right
|
||||||
|
- Click on *Load unpacked*
|
||||||
|
- Open the folder containing the *manifest.json* file.
|
||||||
|
|
||||||
|
## Help needed
|
||||||
|
This is only minimally useful in this state. Join us on our Discord and please help us improve that.
|
||||||
|
|
||||||
|
## Note:
|
||||||
|
- For mysterious reasons sometimes the download buttons will only load when refreshing the YouTube search page and not on first load... Hence: Help needed!
|
||||||
|
- For your testing environment only for now: Point the extension to the newest *unstable* build.
|
94
browser_extension/extension/background.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
extension background script listening for events
|
||||||
|
*/
|
||||||
|
|
||||||
|
console.log("running background.js");
|
||||||
|
|
||||||
|
let browserType = getBrowser();
|
||||||
|
|
||||||
|
|
||||||
|
// boilerplate to dedect browser type api
|
||||||
|
function getBrowser() {
|
||||||
|
if (typeof chrome !== "undefined") {
|
||||||
|
if (typeof browser !== "undefined") {
|
||||||
|
console.log("detected firefox");
|
||||||
|
return browser;
|
||||||
|
} else {
|
||||||
|
console.log("detected chrome");
|
||||||
|
return chrome;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("failed to dedect browser");
|
||||||
|
throw "browser detection error"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// send post request to API backend
|
||||||
|
async function sendPayload(url, token, payload) {
|
||||||
|
|
||||||
|
const rawResponse = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": token,
|
||||||
|
"mode": "no-cors"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
});
|
||||||
|
|
||||||
|
const content = await rawResponse.json();
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// read access storage and send
|
||||||
|
function forwardRequest(payload) {
|
||||||
|
|
||||||
|
console.log("running forwardRequest");
|
||||||
|
|
||||||
|
function onGot(item) {
|
||||||
|
console.log(item.access);
|
||||||
|
|
||||||
|
const url = `${item.access.url}:${item.access.port}/api/download/`;
|
||||||
|
console.log(`sending to ${url}`);
|
||||||
|
const token = `Token ${item.access.apiKey}`;
|
||||||
|
|
||||||
|
sendPayload(url, token, payload).then(content => {
|
||||||
|
console.log(content);
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function onError(error) {
|
||||||
|
console.local("failed to get access details");
|
||||||
|
console.log(`Error: ${error}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
browserType.storage.local.get("access", function(result) {
|
||||||
|
onGot(result)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// listen for messages
|
||||||
|
browserType.runtime.onMessage.addListener(
|
||||||
|
function(request, sender, sendResponse) {
|
||||||
|
console.log("responding from background.js listener");
|
||||||
|
console.log(JSON.stringify(request));
|
||||||
|
if (request.download) {
|
||||||
|
console.log("found new download task");
|
||||||
|
let payload = {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"youtube_id": request.download["videoId"],
|
||||||
|
"status": "pending",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
forwardRequest(payload);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
BIN
browser_extension/extension/images/icon.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
browser_extension/extension/images/icon128.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
browser_extension/extension/images/icon16.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
102
browser_extension/extension/images/logo.svg
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 350 75" style="enable-background:new 0 0 350 75;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
.st1{fill:#2C9D8A;}
|
||||||
|
</style>
|
||||||
|
<g id="Layer_1_00000061458428874772671790000018384579824765206440_">
|
||||||
|
<g id="archivist">
|
||||||
|
<path class="st0" d="M218.5,15.2v4.6c-0.7-0.5-1.5-0.8-2.5-0.8c-1.8,0-3,1.4-3.9,3.1v8.9h-4v-16h4v3c1.1-1.9,2.6-3.3,4.5-3.3
|
||||||
|
C217.3,14.7,217.9,14.9,218.5,15.2z"/>
|
||||||
|
<path class="st0" d="M233.6,16.3V20c-1.1-0.8-2.4-1.4-4.4-1.4c-2.4,0-4.5,1.9-4.5,4.5c0,2.6,1.9,4.5,4.5,4.5c2,0,3.3-0.6,4.4-1.4
|
||||||
|
v3.7c-0.9,0.8-2.3,1.6-4.7,1.6c-4.8,0-8.4-3.9-8.4-8.4c0-4.5,3.6-8.5,8.4-8.5C231.3,14.6,232.7,15.6,233.6,16.3z"/>
|
||||||
|
<path class="st0" d="M251.8,21.2v9.8h-4l0-9.3c0-2.2-1.1-3.2-2.9-3.2c-1.4,0-2.7,1.1-3.6,2.3v10.1h-4V8.2h4v9.1
|
||||||
|
c1-1.3,2.7-2.7,4.8-2.7C249.3,14.6,251.8,16.9,251.8,21.2z"/>
|
||||||
|
<path class="st0" d="M262.1,31.1h-4V18.5h-2.5v-3.4h6.5V31.1z M256.9,10.1c0-1.5,1.2-2.6,2.6-2.6s2.7,1.2,2.7,2.6
|
||||||
|
c0,1.5-1.2,2.7-2.7,2.7S256.9,11.6,256.9,10.1z"/>
|
||||||
|
<path class="st0" d="M272.2,31.1l-7.5-16h4.7l4,9.9l4.2-9.9h4.7l-7.6,16H272.2z"/>
|
||||||
|
<path class="st0" d="M290.8,31.1h-4V18.5h-2.5v-3.4h6.5V31.1z M285.6,10.1c0-1.5,1.2-2.6,2.6-2.6c1.5,0,2.7,1.2,2.7,2.6
|
||||||
|
c0,1.5-1.2,2.7-2.7,2.7C286.8,12.8,285.6,11.6,285.6,10.1z"/>
|
||||||
|
<path class="st0" d="M305.5,16.1v3.5c-1-0.7-2.5-1.5-4.1-1.5c-1.5,0-2.5,0.8-2.5,1.7c0,0.7,0.4,1.2,1.8,1.7l1.8,0.6
|
||||||
|
c2.5,0.7,3.6,2.2,3.6,4.2c0,2.9-2.8,5.1-6.2,5.1c-2.2,0-4.4-0.8-5.5-1.6v-3.5c1.2,0.8,3.4,1.6,4.9,1.6c1.6,0,2.5-0.6,2.5-1.6
|
||||||
|
c0-0.8-0.7-1.2-2.1-1.6l-2-0.7c-2.4-0.8-3.2-2.3-3.2-4.3c0-3,2.5-5.1,6.1-5.1C302.7,14.6,304.5,15.3,305.5,16.1z"/>
|
||||||
|
<path class="st0" d="M319.8,15.1v3.4h-4.4v6.9c0,1.4,0.7,2.3,2,2.3c1.1,0,1.9-0.3,2.6-0.7v3.2c-0.8,0.8-1.9,1.4-3.8,1.4
|
||||||
|
c-2.9,0-4.8-2-4.8-5.2v-8h-2.9v-2.1c2.1-0.7,4.2-2.7,5.2-6h1.7v4.7H319.8z"/>
|
||||||
|
<polygon id="A" class="st0" points="183.9,31.1 192.7,8 196.6,8 205.4,31.1 201,31.1 194.7,13.5 188.3,31.1 "/>
|
||||||
|
<path class="st1" d="M197.7,26.2l-1.8,1.6v-5.2v-0.7v-1.8c0-0.8-0.6-1.4-1.3-1.4s-1.3,0.6-1.3,1.4v1.8v0.7v5.2l-1.8-1.6l-1.2,1.2
|
||||||
|
l4.3,3.9l4.3-3.9L197.7,26.2z"/>
|
||||||
|
</g>
|
||||||
|
<g id="tube">
|
||||||
|
<g id="T_00000039852614045324270430000005353782644941079486_">
|
||||||
|
<polygon class="st0" points="94.7,8.3 94.7,12.3 101.3,12.3 101.3,18.4 105.5,18.4 105.5,12.3 111.9,12.3 111.9,8.3 "/>
|
||||||
|
<rect x="101.3" y="22.6" class="st0" width="4.1" height="9"/>
|
||||||
|
<path class="st1" d="M105.8,21.7H101c-0.7,0-1.3-0.6-1.3-1.3l0,0c0-0.7,0.6-1.3,1.3-1.3h4.8c0.7,0,1.3,0.6,1.3,1.3l0,0
|
||||||
|
C107.1,21.1,106.5,21.7,105.8,21.7z"/>
|
||||||
|
</g>
|
||||||
|
<path class="st0" d="M127.4,24.5c0,4.2-3,6.8-7.1,6.8c-4.1,0-7.1-2.6-7.1-6.8v-9.4h4l0,8.7c0,2.4,1.3,3.7,3.1,3.7
|
||||||
|
c1.8,0,3.1-1.2,3.1-3.7v-8.7h4V24.5z"/>
|
||||||
|
<path class="st0" d="M136,17.3c1-1.8,2.8-3.1,5.2-3.1c3.9,0,7.3,3,7.3,8.4c0,5.4-3.4,8.7-7.5,8.7c-1.8,0-3.7-1-4.9-2.3v1.8h-4.1
|
||||||
|
V7.7h4.1V17.3z M136,22.9v2.3c1.2,1.2,2.5,2.1,4.1,2.1c2.5,0,4.1-2.3,4.1-4.7c0-2.4-1.6-4.3-4-4.3C138,18.3,135.9,20,136,22.9z"/>
|
||||||
|
<path class="st0" d="M167,24.1h-11.7c0.4,2.2,2.3,3.7,4.8,3.7c2.4,0,3.9-1,4.9-1.6v3.7c-0.9,0.7-2.6,1.6-5.1,1.6
|
||||||
|
c-4.8,0-8.7-3.5-8.7-8.4c0-4.7,3.6-8.7,8.2-8.7c4.8,0,7.6,3.3,7.6,8.1V24.1z M163.1,21.5c-0.2-2.3-2-3.5-3.8-3.5
|
||||||
|
c-2.1,0-3.5,1.4-3.9,3.5H163.1z"/>
|
||||||
|
</g>
|
||||||
|
<g id="icon">
|
||||||
|
<path class="st1" d="M27.6,33.7l1,0.4l0.5-2l-6.7-2l-0.7,2l0.9,0.4C20.9,44.4,25,54.5,34,61.9l2.9-4
|
||||||
|
C29.6,51.4,25.8,43.2,27.6,33.7z"/>
|
||||||
|
<path class="st1" d="M41.2,60.5l0.6-0.8L40,58.4L35.7,64l1.8,1.3l0.6-0.7c10.7,5.7,21.9,4.7,31.8-1.5L66.8,59
|
||||||
|
C58.3,63.9,49.9,65.3,41.2,60.5z"/>
|
||||||
|
<path class="st1" d="M70.8,55.6l-0.7-0.7l-1.8,1.3l4.3,5.9l1.8-1.3L73.9,60c8.7-8.5,11.2-18.7,8.4-30l-4.9,1.4
|
||||||
|
C79.3,40.9,78,48.7,70.8,55.6z"/>
|
||||||
|
<path class="st1" d="M75.5,26.5l-0.9,0.4l0.6,2.4l7.2-2.1l-0.7-2.4l-0.9,0.3c-5.7-10.7-15-17.4-26.6-17.9v5.4
|
||||||
|
C63.8,13.4,70.9,17.6,75.5,26.5z"/>
|
||||||
|
<path class="st1" d="M49,12.8l0.1,0.9l2.3-0.1v-7h-2.3v0.9C40,8.8,28.6,14.8,24,27.6l4.9,1.4C32.4,19,40.2,14.7,49,12.8z"/>
|
||||||
|
<polygon id="A_00000111884739883312047940000001222474654974762168_" class="st0" points="48,54 60.6,20.9 66.1,20.9 78.8,54
|
||||||
|
72.5,54 63.4,28.8 54.3,54 "/>
|
||||||
|
<g id="T">
|
||||||
|
<polygon class="st0" points="27.6,20.4 27.6,26.1 37.1,26.1 37.1,35 43.1,35 43.1,26.1 52.4,26.1 52.4,20.4 "/>
|
||||||
|
<rect x="37.1" y="41" class="st0" width="6" height="13"/>
|
||||||
|
</g>
|
||||||
|
<path class="st1" d="M43.5,39.7h-6.9c-1,0-1.9-0.8-1.9-1.9l0,0c0-1,0.8-1.9,1.9-1.9h6.9c1,0,1.9,0.8,1.9,1.9l0,0
|
||||||
|
C45.4,38.9,44.5,39.7,43.5,39.7z"/>
|
||||||
|
<path class="st1" d="M67.8,47l-2.5,2.3v-7.5v-1v-2.5c0-1.1-0.8-2-1.9-2s-1.9,0.9-1.9,2v2.5v1v7.5L58.9,47l-1.7,1.7l6.2,5.6
|
||||||
|
l6.1-5.6L67.8,47z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="Layer_2">
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M142.1,58c0,6-4.3,9.6-10.1,9.6c-5.8,0-10.1-3.6-10.1-9.6V44.7h5.7l0,12.3c0,3.4,1.8,5.2,4.4,5.2
|
||||||
|
c2.6,0,4.4-1.7,4.4-5.2V44.7h5.7V58z"/>
|
||||||
|
<path class="st0" d="M154.1,48.5c1.3-2.4,3.8-4.3,7.2-4.3c5.4,0,10,4.1,10,11.6c0,7.4-4.6,12-10.4,12c-2.4,0-5.1-1.3-6.8-3.2V67
|
||||||
|
h-5.6V35.2h5.6V48.5z M154.1,56.1v3.2c1.6,1.7,3.4,2.9,5.6,2.9c3.5,0,5.7-3.2,5.7-6.5c0-3.4-2.2-6-5.6-6
|
||||||
|
C156.9,49.7,154.1,52.1,154.1,56.1z"/>
|
||||||
|
<path class="st0" d="M190.4,46.2v5c-1.4-0.9-3.5-2-5.7-2c-2.1,0-3.4,1.1-3.4,2.4c0,1,0.6,1.7,2.6,2.3l2.5,0.8c3.4,1,5.1,3,5.1,5.9
|
||||||
|
c0,4.1-3.9,7.2-8.7,7.2c-3,0-6.1-1.1-7.6-2.3v-4.9c1.7,1.1,4.7,2.3,6.9,2.3c2.3,0,3.5-0.8,3.5-2.3c0-1.2-1-1.6-3-2.3l-2.7-1
|
||||||
|
c-3.4-1.1-4.5-3.2-4.5-6.1c0-4.2,3.5-7.1,8.6-7.1C186.6,44.1,189.2,45.1,190.4,46.2z"/>
|
||||||
|
<path class="st0" d="M212.9,46.5v5.2c-1.5-1.1-3.4-2-6.1-2c-3.4,0-6.2,2.7-6.2,6.3s2.6,6.3,6.2,6.3c2.7,0,4.6-0.8,6.1-1.9v5.1
|
||||||
|
c-1.2,1.1-3.3,2.3-6.6,2.3c-6.7,0-11.7-5.4-11.7-11.7s5-11.9,11.7-11.9C209.7,44.1,211.7,45.5,212.9,46.5z"/>
|
||||||
|
<path class="st0" d="M232.5,44.9v6.4c-1-0.7-2.1-1.1-3.4-1.1c-2.6,0-4.2,1.9-5.5,4.4V67h-5.6V44.7h5.6v4.2
|
||||||
|
c1.5-2.7,3.6-4.6,6.3-4.6C230.9,44.3,231.7,44.5,232.5,44.9z"/>
|
||||||
|
<path class="st0" d="M244.7,67h-5.6V49.5h-3.5v-4.8h9.1V67z M237.5,37.8c0-2,1.6-3.7,3.7-3.7s3.7,1.6,3.7,3.7s-1.7,3.7-3.7,3.7
|
||||||
|
S237.5,39.8,237.5,37.8z"/>
|
||||||
|
<path class="st0" d="M257,48.5c1.3-2.4,3.8-4.3,7.2-4.3c5.4,0,10,4.1,10,11.6c0,7.4-4.6,12-10.4,12c-2.4,0-5.1-1.3-6.8-3.2V67
|
||||||
|
h-5.6V35.2h5.6V48.5z M257,56.1v3.2c1.6,1.7,3.4,2.9,5.6,2.9c3.5,0,5.7-3.2,5.7-6.5c0-3.4-2.2-6-5.6-6
|
||||||
|
C259.8,49.7,257,52.1,257,56.1z"/>
|
||||||
|
<path class="st0" d="M299.8,57.6h-16.2c0.6,3.1,3.1,5,6.5,5c3.3,0,5.4-1.4,6.8-2.3v5.1c-1.2,0.9-3.6,2.3-7,2.3
|
||||||
|
c-6.6,0-12-4.9-12-11.6c0-6.5,5-12,11.3-12c6.6,0,10.5,4.6,10.5,11.1V57.6z M294.4,54c-0.2-3.2-2.7-4.8-5.3-4.8
|
||||||
|
c-2.9,0-4.8,1.9-5.4,4.8H294.4z"/>
|
||||||
|
<path class="st0" d="M319.5,44.9v6.4c-1-0.7-2.1-1.1-3.4-1.1c-2.6,0-4.2,1.9-5.5,4.4V67H305V44.7h5.6v4.2c1.5-2.7,3.6-4.6,6.3-4.6
|
||||||
|
C317.9,44.3,318.7,44.5,319.5,44.9z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M102.6,54l2.4,0.9v-6.1c0-0.2,0-0.3,0.1-0.5c-1.2-0.6-1.9-1.4-1.9-2.6c0-2.3,2.6-3.2,4.9-3.2
|
||||||
|
c3.1,0,5.4,1.3,7.5,2.7v-6.1c-1.9-1.2-4.8-2.3-8.3-2.3c-5.5,0-10.5,3.5-10.5,9C96.7,49.3,98,52.3,102.6,54z"/>
|
||||||
|
<path class="st0" d="M111.1,51l-1.9-0.8v6.6c0.8,0.5,1.3,1.2,1.3,2.1c0,1.9-2,2.9-4.5,2.9c-3.5,0-6.7-1.5-9.3-3.4v6.1
|
||||||
|
c2.4,1.7,5.7,3.1,9.2,3.1c6.1,0,11.2-3.8,11.2-9C117.2,55.3,115.3,52.8,111.1,51z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<path class="st1" d="M105.5,56.1v-6.9c0-1,0.8-1.9,1.6-1.9l0,0c0.9,0,1.6,0.9,1.6,1.9v6.9c0,1-0.8,1.9-1.6,1.9l0,0
|
||||||
|
C106.2,58,105.5,57.1,105.5,56.1z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 7.4 KiB |
16
browser_extension/extension/images/question.svg
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 374.4 375.1" style="enable-background:new 0 0 374.4 375.1;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M187.5,0C84.2-0.1,0.1,83.8,0,187.2C-0.2,290.8,83.7,375,187.1,375.1c103.3,0,187.2-83.9,187.3-187.4
|
||||||
|
C374.5,84.3,290.7,0.2,187.5,0z M187.9,304.5c-16,0-29.2-13.3-29.2-29.3c0.1-16,13.2-29,29.1-29.1c16,0,29.2,13.3,29.2,29.3
|
||||||
|
C216.9,291.4,203.8,304.5,187.9,304.5z M238.2,195.7c-4.8,2.9-9.7,5.8-14.5,8.7c-9.1,5.5-13.6,13.6-13.9,24.2c0,0.8,0,1.7,0,2.7
|
||||||
|
c-14.6,0-29,0-43.8,0c0.1-2.8,0.2-5.6,0.4-8.5c0.8-10.6,3.2-20.9,8.4-30.3c5.9-11,14.9-18.9,25.5-25.1c4.1-2.4,8.4-4.7,12.5-7.1
|
||||||
|
c12.7-7.7,13.1-19.1,6.2-29.9c-6.5-10.3-16.3-14.9-28.1-15.7c-8-0.5-15.7,0.7-22.6,4.9c-10.1,6.2-15,15.6-16.9,26.9
|
||||||
|
c-0.1,0.4-0.1,0.9-0.2,1.6c-14.5-1.9-28.9-3.8-43.9-5.8c1.4-5.4,2.5-10.8,4.2-15.9c5.2-14.9,13.6-27.8,25.8-38
|
||||||
|
c11.1-9.3,23.9-14.7,38.2-16.6c2.3-0.3,4.6-0.6,6.9-1c3.2,0,6.4,0,9.6,0c4.4,0.6,8.9,1.1,13.3,1.9c29.8,5.9,55.4,28.1,61.4,59.3
|
||||||
|
C271.5,157.5,260.7,182.2,238.2,195.7z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
24
browser_extension/extension/images/social/discord.svg
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M191.57,379.5C88.15,379.44,4.32,295.25,4.46,191.57C4.6,88.18,88.66,4.28,191.95,4.42
|
||||||
|
c103.29,0.14,187.02,84.23,186.93,187.72C378.8,295.6,294.86,379.55,191.57,379.5z M244.55,271.24
|
||||||
|
c4.89,5.91,9.44,11.19,13.73,16.69c1.8,2.32,3.72,3.11,6.64,2.93c28.39-1.75,53.17-11.56,72.96-32.55c1.12-1.19,2.08-3.2,1.97-4.76
|
||||||
|
c-0.79-11.71-1.27-23.48-2.97-35.07c-5.07-34.65-16.23-67.36-32.74-98.23c-0.73-1.36-1.88-2.67-3.15-3.55
|
||||||
|
c-19.34-13.43-40.61-21.62-64.16-23.63c-3.19-0.27-5.5,0.48-6.89,3.09c10.27,3.97,20.59,7.65,30.65,11.94
|
||||||
|
c10.1,4.32,19.64,9.74,28.21,16.92c-64.82-29.49-129.53-29.49-194.34,0.02c17.77-13.75,38.02-22.07,59.27-28.39
|
||||||
|
c-1.74-3.15-4.12-3.86-7.32-3.58c-23.15,2.02-44.13,9.94-63.2,23.08c-1.76,1.21-3.51,2.96-4.4,4.86
|
||||||
|
c-5.36,11.39-11.02,22.69-15.57,34.41c-12.22,31.43-19.35,64-19.75,97.86c-0.02,1.71,0.88,3.85,2.07,5.1
|
||||||
|
c18.74,19.74,41.98,29.72,68.88,32.19c5.73,0.53,9.64-0.46,12.96-5.26c3.36-4.86,7.35-9.28,11.2-14.05
|
||||||
|
c-22.46-8.05-39.37-18.53-42.93-26.17c63.97,36.11,128.17,36.13,192.51-0.02C276.69,258.45,261.71,265.95,244.55,271.24z"/>
|
||||||
|
<path class="st0" d="M237.28,232.74c-14.34-0.02-26.07-12-25.9-26.45c0.17-14.67,11.86-26.25,26.56-26.33
|
||||||
|
c13.63-0.07,25.18,12,25.21,26.35C263.18,220.98,251.66,232.76,237.28,232.74z"/>
|
||||||
|
<path class="st0" d="M146.11,232.74c-14.35,0.05-25.9-11.7-25.92-26.38c-0.02-14.3,11.56-26.46,25.16-26.41
|
||||||
|
c14.85,0.06,26.74,11.96,26.62,26.66C171.84,221.04,160.32,232.69,146.11,232.74z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
23
browser_extension/extension/images/social/github.svg
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M244.51,375.15c0-10.59-0.31-21.12,0.08-31.61c0.5-13.65,0.02-26.89-10.41-37.88
|
||||||
|
c8.18-2.06,15.59-3.84,22.95-5.83c3.51-0.95,6.95-2.22,10.37-3.47c27.26-9.99,40.88-31.15,45.79-58.73
|
||||||
|
c2.71-15.21,4.11-30.82-0.74-45.88c-2.65-8.23-6.01-16.69-11.08-23.5c-3.83-5.14-3.43-9.05-2.23-14.27
|
||||||
|
c2.86-12.48,0.71-24.71-2.64-36.79c-0.99-3.58-3.09-4.99-6.88-4.6c-11.45,1.18-21.48,6.12-31.34,11.6
|
||||||
|
c-1.42,0.79-2.97,1.46-4.16,2.52c-5.55,4.99-11.4,5.13-18.58,3.42c-25.28-6.04-50.67-5.14-75.85,1.12
|
||||||
|
c-3.59,0.89-6.27,0.27-9.31-1.86c-11.08-7.73-22.87-14.02-36.37-16.31c-0.13-0.02-0.26-0.07-0.4-0.09
|
||||||
|
c-7.12-1.23-8.12-0.76-10.11,6.16c-3.51,12.23-5.18,24.6-1.55,37.14c1.14,3.94,0.44,7.16-2.01,10.61
|
||||||
|
c-23.14,32.46-16.36,80.65,0.11,103.41c12.16,16.81,29.02,26.2,48.63,31.06c5.49,1.36,11.11,2.15,17.1,3.28
|
||||||
|
c-0.24,0.79-0.43,1.81-0.85,2.71c-3.15,6.91-6.27,13.83-9.6,20.65c-0.67,1.38-2.06,3.14-3.34,3.35c-7.3,1.18-14.65,2.46-22.02,2.7
|
||||||
|
c-6.5,0.21-12.09-3.32-16.37-8c-5.11-5.59-9.65-11.73-14.19-17.83c-6.07-8.15-14.2-12.42-24.05-13.3c-2.22-0.2-4.58,1.12-7.99,2.05
|
||||||
|
c2.69,3.23,4.46,6.17,6.96,8.2c10.32,8.35,17.42,19.1,22.26,31.24c4.72,11.85,14.1,16.55,25.31,19.27
|
||||||
|
c9.24,2.24,18.51,1.5,27.83,0.78c6.07-0.47,6.09-0.22,6.09,5.98c0.01,5.58,0,11.17,0,16.81C86.7,368.22,7.24,301.96,4.67,198.28
|
||||||
|
C2.19,97.88,77.65,13.69,175.94,5.34c103.69-8.81,192.95,68.52,202.14,171.23C387.22,278.72,317.17,355.78,244.51,375.15z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
35
browser_extension/extension/images/social/reddit.svg
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M240.82,274c-3.86,3.78-8.45,6.33-13.43,8.26c-9.77,3.79-19.98,5.34-30.38,5.85
|
||||||
|
c-5.42,0.26-10.85,0.12-16.26-0.44c-5.89-0.61-11.72-1.56-17.42-3.18c-7.65-2.17-14.86-5.18-20.68-10.86
|
||||||
|
c-0.98-0.96-2.26-1.44-3.64-1.48c-2.72-0.08-4.71,1.17-5.94,3.55c-1.14,2.2-0.8,4.87,0.94,6.7c1.28,1.35,2.7,2.59,4.17,3.73
|
||||||
|
c5.88,4.57,12.58,7.49,19.65,9.63c11.11,3.37,22.52,4.66,36.04,4.85c2.63-0.18,7.2-0.42,11.76-0.82c6.75-0.6,13.38-1.86,19.88-3.8
|
||||||
|
c6.56-1.95,12.83-4.56,18.42-8.57c1.94-1.4,3.82-2.93,5.52-4.61c2.44-2.4,2.35-6.62,0.01-8.95
|
||||||
|
C247.1,271.52,243.37,271.51,240.82,274z"/>
|
||||||
|
<path class="st0" d="M192.39,4.72C89.03,4.5,5.07,88.18,4.86,191.61c-0.21,103.43,83.4,187.46,186.75,187.67
|
||||||
|
c103.35,0.21,187.31-83.46,187.53-186.89C379.36,88.96,295.74,4.93,192.39,4.72z M327.66,225.47c0.14,1.32,0.27,2.64,0.41,3.96
|
||||||
|
c0.53,4.98,0.43,9.96-0.23,14.91c-2.24,16.85-10.03,30.98-21.45,43.28c-8.94,9.62-19.42,17.22-30.95,23.42
|
||||||
|
c-13.96,7.52-28.79,12.64-44.3,15.87c-8.46,1.76-17,2.91-25.62,3.51c-6.58,0.46-13.16,0.6-19.75,0.39
|
||||||
|
c-6.8-0.22-13.58-0.8-20.34-1.72c-11.93-1.64-23.6-4.38-34.96-8.39c-14.15-4.99-27.38-11.73-39.34-20.86
|
||||||
|
c-9.74-7.44-18.15-16.12-24.63-26.59c-5.11-8.26-8.64-17.14-10.2-26.75c-1.1-6.76-1.23-13.55-0.14-20.33c0.03-0.21,0-0.44,0-0.7
|
||||||
|
c-10.51-5.25-17.19-13.54-19.32-25.14c-1.71-9.32,0.32-17.97,5.8-25.72c11.73-16.6,35.97-19.53,51.41-4.96
|
||||||
|
c27.77-19.23,59-27.5,92.46-28.92c0.46-2.12,0.92-4.2,1.36-6.28c3.46-16.26,6.92-32.53,10.37-48.79
|
||||||
|
c1.82-8.57,3.63-17.14,5.43-25.71c0.26-1.23,0.59-2.42,1.44-3.4c1.68-1.92,3.83-2.34,6.2-1.85c6.31,1.3,12.62,2.66,18.92,3.99
|
||||||
|
c10.35,2.19,20.7,4.39,31.05,6.59c2,0.42,4,0.84,6.09,1.28c3.7-6.86,9.29-11.3,16.92-12.93c5.54-1.19,10.89-0.41,15.96,2.14
|
||||||
|
c10.03,5.06,15.32,16.56,12.65,27.42c-2.74,11.12-12.68,18.73-24.01,18.65c-11.69-0.08-23.34-9.38-24.16-23.21
|
||||||
|
c-1.43-0.6-49.41-10.81-50.5-10.7c-5.15,24.12-10.32,48.27-15.51,72.57c0.64,0.04,1.07,0.07,1.51,0.09
|
||||||
|
c19.74,0.93,38.91,4.68,57.37,11.79c11.05,4.25,21.5,9.64,31.21,16.44c0.29,0.2,0.6,0.38,0.94,0.59
|
||||||
|
c8.62-7.75,18.62-11.01,30.07-8.89c9.47,1.76,16.97,6.78,22.22,14.87c5.67,8.73,7.06,18.26,4.21,28.25
|
||||||
|
C343.42,213.65,337.03,220.82,327.66,225.47z"/>
|
||||||
|
<path class="st0" d="M162.26,218.68c0.08-13.49-10.62-24.33-24.09-24.41c-13.86,0-24.09,11.31-24.22,23.89
|
||||||
|
c-0.13,12.52,9.75,24.24,23.96,24.42C151.22,242.73,162.19,231.9,162.26,218.68z"/>
|
||||||
|
<path class="st0" d="M245.16,194.56c-13.42,0.03-24.09,10.83-24.11,24.24c-0.02,12.58,10.14,24.01,24.17,24.05
|
||||||
|
c13.33,0.04,24.16-10.89,24.12-24.26C269.32,205.3,258.48,194.52,245.16,194.56z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
93
browser_extension/extension/index.html
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>TubeArchivist Companion</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapi.com/css?family=Sen" type="text/css">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Sen-Regular, sans-serif;
|
||||||
|
background-color: #00202f;
|
||||||
|
color: #97d4c8;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
padding: 10px;
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
height: 1px;
|
||||||
|
color: white;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.login-form {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
.login-form label,
|
||||||
|
.login-form input {
|
||||||
|
margin: 3px 0;
|
||||||
|
}
|
||||||
|
.submit button {
|
||||||
|
margin: 10px auto 15px auto;
|
||||||
|
display: block;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 5px 13px;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #259485;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.submit button:hover {
|
||||||
|
background-color: #97d4c8;
|
||||||
|
transform: scale(1.05);
|
||||||
|
color: #00202f;
|
||||||
|
}
|
||||||
|
.icons {
|
||||||
|
display: flex;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.icons img {
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<img src="/images/logo.svg" alt="ta-logo">
|
||||||
|
<hr>
|
||||||
|
<form class="login-form">
|
||||||
|
<label for="url">Tube Archivist Url:</label>
|
||||||
|
<input type="text" id="url" name="url">
|
||||||
|
<label for="port">Tube Archivist Port:</label>
|
||||||
|
<input type="text" id="port" name="port">
|
||||||
|
<label for="api-key">API key:</label>
|
||||||
|
<input type="text" id="api-key" name="api-key">
|
||||||
|
</form>
|
||||||
|
<div class="submit">
|
||||||
|
<button onclick="storeLogin()" id="save-login">Save</button>
|
||||||
|
</div>
|
||||||
|
<div class="icons">
|
||||||
|
<div>
|
||||||
|
<a href="https://www.reddit.com/r/TubeArchivist/" target="_blank">
|
||||||
|
<img src="/images/social/reddit.svg" alt="reddit-icon">
|
||||||
|
</a>
|
||||||
|
<a href="https://discord.gg/AFwz8nE7BK" target="_blank">
|
||||||
|
<img src="/images/social/discord.svg" alt="discord-icon">
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/bbilly1/tubearchivist" target="_blank">
|
||||||
|
<img src="/images/social/github.svg" alt="github-icon">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="#">
|
||||||
|
<img src="/images/question.svg" alt="question-icon">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="popup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
25
browser_extension/extension/manifest.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "TubeArchivist Companion",
|
||||||
|
"description": "Interact with your selhosted TA server.",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"icons": {
|
||||||
|
"128": "/images/icon128.png"
|
||||||
|
},
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": "/images/icon.png",
|
||||||
|
"default_popup": "index.html"
|
||||||
|
},
|
||||||
|
"permissions": [
|
||||||
|
"storage"
|
||||||
|
],
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": ["https://www.youtube.com/results*"],
|
||||||
|
"js": ["script.js"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"scripts": ["background.js"]
|
||||||
|
}
|
||||||
|
}
|
63
browser_extension/extension/popup.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
Loaded into popup index.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
let browserType = getBrowser();
|
||||||
|
|
||||||
|
// boilerplate to dedect browser type api
|
||||||
|
function getBrowser() {
|
||||||
|
if (typeof chrome !== "undefined") {
|
||||||
|
if (typeof browser !== "undefined") {
|
||||||
|
console.log("detected firefox");
|
||||||
|
return browser;
|
||||||
|
} else {
|
||||||
|
console.log("detected chrome");
|
||||||
|
return chrome;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("failed to dedect browser");
|
||||||
|
throw "browser detection error"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// store access details
|
||||||
|
document.getElementById("save-login").addEventListener("click", function () {
|
||||||
|
console.log("save form");
|
||||||
|
let toStore = {
|
||||||
|
"access": {
|
||||||
|
"url": document.getElementById("url").value,
|
||||||
|
"port": document.getElementById("port").value,
|
||||||
|
"apiKey": document.getElementById("api-key").value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(toStore);
|
||||||
|
browserType.storage.local.set(toStore, function() {
|
||||||
|
console.log("Stored connection details: " + JSON.stringify(toStore));
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// fill in form
|
||||||
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
|
|
||||||
|
console.log("executing dom loader");
|
||||||
|
|
||||||
|
function onGot(item) {
|
||||||
|
if (!item.access) {
|
||||||
|
console.log("no access details found");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(item.access);
|
||||||
|
document.getElementById("url").value = item.access.url;
|
||||||
|
document.getElementById("port").value = item.access.port;
|
||||||
|
document.getElementById("api-key").value = item.access.apiKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
function onError(error) {
|
||||||
|
console.log(`Error: ${error}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
browserType.storage.local.get("access", function(result) {
|
||||||
|
onGot(result)
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
72
browser_extension/extension/script.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
content script running on youtube.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
console.log("running script.js");
|
||||||
|
|
||||||
|
let browserType = getBrowser();
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
console.log("running setimeout")
|
||||||
|
linkFinder();
|
||||||
|
return false;
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
|
||||||
|
// boilerplate to dedect browser type api
|
||||||
|
function getBrowser() {
|
||||||
|
if (typeof chrome !== "undefined") {
|
||||||
|
if (typeof browser !== "undefined") {
|
||||||
|
console.log("detected firefox");
|
||||||
|
return browser;
|
||||||
|
} else {
|
||||||
|
console.log("detected chrome");
|
||||||
|
return chrome;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("failed to dedect browser");
|
||||||
|
throw "browser detection error"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// event handler for download task
|
||||||
|
function addToDownload(videoId) {
|
||||||
|
|
||||||
|
console.log(`downloading ${videoId}`);
|
||||||
|
let payload = {
|
||||||
|
"download": {
|
||||||
|
"videoId": videoId
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
browserType.runtime.sendMessage(payload);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// find relevant links to add a button to
|
||||||
|
function linkFinder() {
|
||||||
|
|
||||||
|
console.log("running link finder");
|
||||||
|
|
||||||
|
var allLinks = document.links;
|
||||||
|
for (let i = 0; i < allLinks.length; i++) {
|
||||||
|
|
||||||
|
const linkItem = allLinks[i];
|
||||||
|
const linkDest = linkItem.getAttribute("href");
|
||||||
|
|
||||||
|
if (linkDest.startsWith("/watch?v=") && linkItem.id == "video-title") {
|
||||||
|
var dlButton = document.createElement("button");
|
||||||
|
dlButton.innerText = "download";
|
||||||
|
var videoId = linkDest.split("=")[1];
|
||||||
|
dlButton.setAttribute("data-id", videoId);
|
||||||
|
dlButton.setAttribute("id", "ta-dl-" + videoId);
|
||||||
|
dlButton.onclick = function(event) {
|
||||||
|
var videoId = this.getAttribute("data-id");
|
||||||
|
addToDownload(videoId);
|
||||||
|
};
|
||||||
|
linkItem.parentElement.appendChild(dlButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|