mirror of
https://github.com/krateng/maloja.git
synced 2023-08-10 21:12:55 +03:00
Moved extra paackages
This commit is contained in:
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler.zip
Normal file
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler.zip
Normal file
Binary file not shown.
327
auxiliary/chromium_scrobbler/maloja-scrobbler/background.js
Normal file
327
auxiliary/chromium_scrobbler/maloja-scrobbler/background.js
Normal file
@@ -0,0 +1,327 @@
|
||||
|
||||
chrome.tabs.onUpdated.addListener(onTabUpdated);
|
||||
chrome.tabs.onRemoved.addListener(onTabRemoved);
|
||||
//chrome.tabs.onActivated.addListener(onTabChanged);
|
||||
chrome.runtime.onMessage.addListener(onInternalMessage);
|
||||
|
||||
tabManagers = {}
|
||||
|
||||
pages = {
|
||||
"Plex Web":{
|
||||
"patterns":[
|
||||
"https://app.plex.tv",
|
||||
"http://app.plex.tv",
|
||||
"https://plex.",
|
||||
"http://plex."
|
||||
],
|
||||
"script":"plex.js"
|
||||
},
|
||||
"YouTube Music":{
|
||||
"patterns":[
|
||||
"https://music.youtube.com"
|
||||
],
|
||||
"script":"ytmusic.js"
|
||||
},
|
||||
"Spotify Web":{
|
||||
"patterns":[
|
||||
"https://open.spotify.com"
|
||||
],
|
||||
"script":"spotify.js"
|
||||
},
|
||||
"Bandcamp":{
|
||||
"patterns":[
|
||||
"bandcamp.com"
|
||||
],
|
||||
"script":"bandcamp.js"
|
||||
},
|
||||
"Soundcloud":{
|
||||
"patterns":[
|
||||
"https://soundcloud.com"
|
||||
],
|
||||
"script":"soundcloud.js"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateTabNum() {
|
||||
|
||||
var amount = Object.keys(tabManagers).length;
|
||||
chrome.browserAction.setBadgeText({"text":amount.toString()});
|
||||
chrome.browserAction.setBadgeBackgroundColor({"color":"#333337"});
|
||||
}
|
||||
|
||||
|
||||
function onTabUpdated(tabId, changeInfo, tab) {
|
||||
|
||||
|
||||
// still same page?
|
||||
//console.log("Update to tab " + tabId + "!")
|
||||
if (tabManagers.hasOwnProperty(tabId)) {
|
||||
//console.log("Yes!")
|
||||
page = tabManagers[tabId].page;
|
||||
patterns = pages[page]["patterns"];
|
||||
//console.log("Page was managed by a " + page + " manager")
|
||||
for (var i=0;i<patterns.length;i++) {
|
||||
if (tab.url.includes(patterns[i])) {
|
||||
//console.log("Still on same page!")
|
||||
tabManagers[tabId].update();
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
console.log("Page on tab " + tabId + " changed, removing old " + page + " manager!");
|
||||
delete tabManagers[tabId];
|
||||
}
|
||||
|
||||
//check if pattern matches
|
||||
for (var key in pages) {
|
||||
if (pages.hasOwnProperty(key)) {
|
||||
patterns = pages[key]["patterns"];
|
||||
for (var i=0;i<patterns.length;i++) {
|
||||
if (tab.url.includes(patterns[i])) {
|
||||
console.log("New page on tab " + tabId + " will be handled by new " + key + " manager!");
|
||||
tabManagers[tabId] = new Controller(tabId,key);
|
||||
updateTabNum();
|
||||
return
|
||||
//chrome.tabs.executeScript(tab.id,{"file":"sitescripts/" + pages[key]["script"]})
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onTabRemoved(tabId,removeInfo) {
|
||||
|
||||
if (tabManagers.hasOwnProperty(tabId)) {
|
||||
page = tabManagers[tabId].page;
|
||||
console.log("closed tab was " + page + ", now removing manager");
|
||||
tabManagers[tabId].stopPlayback("",""); //in case we want to scrobble the playing track
|
||||
delete tabManagers[tabId];
|
||||
updateTabNum();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function onInternalMessage(request,sender) {
|
||||
// message from settings menu
|
||||
if (request.type == "query") {
|
||||
answer = [];
|
||||
for (tabId in tabManagers) {
|
||||
manager = tabManagers[tabId]
|
||||
if (manager.currentlyPlaying) {
|
||||
answer.push([manager.page,manager.currentArtist,manager.currentTitle]);
|
||||
}
|
||||
else {
|
||||
answer.push([manager.page,null]);
|
||||
}
|
||||
|
||||
}
|
||||
chrome.runtime.sendMessage({"type":"response","content":answer})
|
||||
}
|
||||
|
||||
//message from content script
|
||||
if (request.type == "startPlayback" || request.type == "stopPlayback") {
|
||||
tabId = sender.tab.id
|
||||
//console.log("Message was sent from tab id " + tabId)
|
||||
if (tabManagers.hasOwnProperty(tabId)) {
|
||||
//console.log("This is managed! Seems to be " + tabManagers[tabId].page)
|
||||
tabManagers[tabId].playbackUpdate(request);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Controller {
|
||||
|
||||
constructor(tabId,page) {
|
||||
this.tabId = tabId;
|
||||
this.page = page;
|
||||
|
||||
this.currentTitle;
|
||||
this.currentArtist;
|
||||
this.currentLength;
|
||||
this.alreadyPlayed;
|
||||
this.currentlyPlaying = false;
|
||||
this.lastUpdate = 0;
|
||||
this.alreadyScrobbled = false;
|
||||
|
||||
this.messageID = 0;
|
||||
this.lastMessage = 0;
|
||||
|
||||
this.alreadyQueued = false;
|
||||
// we reject update requests when we're already planning to run an update!
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
// the tab has been updated, we need to run the script
|
||||
update() {
|
||||
if (this.alreadyQueued) {
|
||||
}
|
||||
else {
|
||||
this.alreadyQueued = true;
|
||||
setTimeout(() => { this.actuallyupdate(); },800);
|
||||
//this.actuallyupdate();
|
||||
}
|
||||
}
|
||||
|
||||
actuallyupdate() {
|
||||
this.messageID++;
|
||||
//console.log("Update! Our page is " + this.page + ", our tab id " + this.tabId)
|
||||
try {
|
||||
chrome.tabs.executeScript(this.tabId,{"file":"sites/" + pages[this.page]["script"]});
|
||||
chrome.tabs.executeScript(this.tabId,{"file":"sitescript.js"});
|
||||
}
|
||||
catch (e) {
|
||||
console.log("Could not run site script. Tab probably closed or something idk.")
|
||||
}
|
||||
|
||||
this.alreadyQueued = false;
|
||||
}
|
||||
|
||||
// an actual update message from the script has arrived
|
||||
playbackUpdate(request) {
|
||||
|
||||
if (request.time < self.lastMessage) {
|
||||
console.log("Got message out of order, discarding!")
|
||||
return
|
||||
}
|
||||
self.lastMessage = request.time
|
||||
|
||||
//console.log("Update message from our tab " + this.tabId + " (" + this.page + ")")
|
||||
if (request.type == "stopPlayback" && this.currentlyPlaying) {
|
||||
this.stopPlayback(request.artist,request.title);
|
||||
}
|
||||
else if (request.type == "startPlayback") {
|
||||
this.startPlayback(request.artist,request.title,request.duration);
|
||||
}
|
||||
}
|
||||
|
||||
backlog_scrobble() {
|
||||
while (this.alreadyPlayed > this.currentLength) {
|
||||
this.alreadyPlayed = this.alreadyPlayed - this.currentLength
|
||||
var secondsago = this.alreadyPlayed
|
||||
scrobble(this.currentArtist,this.currentTitle,this.currentLength,secondsago)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
startPlayback(artist,title,seconds) {
|
||||
|
||||
// CASE 1: Resuming playback of previously played title
|
||||
if (artist == this.currentArtist && title == this.currentTitle && !this.currentlyPlaying) {
|
||||
console.log("Resuming playback of " + this.currentTitle)
|
||||
|
||||
// Already played full song?
|
||||
this.backlog_scrobble()
|
||||
|
||||
this.setUpdate()
|
||||
this.currentlyPlaying = true
|
||||
|
||||
}
|
||||
|
||||
// CASE 2: New track is being played
|
||||
else if (artist != this.currentArtist || title != this.currentTitle) {
|
||||
|
||||
//first inform ourselves that the previous track has now been stopped for good
|
||||
this.stopPlayback(artist,title);
|
||||
//then initialize new playback
|
||||
console.log("New track");
|
||||
this.setUpdate();
|
||||
this.alreadyPlayed = 0;
|
||||
this.currentTitle = title;
|
||||
this.currentArtist = artist;
|
||||
if (Number.isInteger(seconds)) {
|
||||
this.currentLength = seconds;
|
||||
}
|
||||
else {
|
||||
this.currentLength = 300;
|
||||
// avoid excessive scrobbling when the selector breaks
|
||||
}
|
||||
console.log(artist + " - " + title + " is playing! (" + this.currentLength + " seconds)");
|
||||
this.currentlyPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
// the artist and title arguments are not attributes of the track being stopped, but of the track active now
|
||||
// they are here to recognize whether the playback has been paused or completely ended / replaced
|
||||
stopPlayback(artist,title) {
|
||||
|
||||
//CASE 1: Playback just paused OR CASE 2: Playback ended
|
||||
if (this.currentlyPlaying) {
|
||||
var d = this.setUpdate()
|
||||
this.alreadyPlayed = this.alreadyPlayed + d
|
||||
console.log(d + " seconds played since last update, " + this.alreadyPlayed + " seconds played overall")
|
||||
}
|
||||
|
||||
|
||||
// Already played full song?
|
||||
this.backlog_scrobble()
|
||||
|
||||
this.currentlyPlaying = false
|
||||
|
||||
|
||||
|
||||
//ONLY CASE 2: Playback ended
|
||||
if (artist != this.currentArtist || title != this.currentTitle) {
|
||||
if (this.alreadyPlayed > this.currentLength / 2) {
|
||||
scrobble(this.currentArtist,this.currentTitle,this.alreadyPlayed)
|
||||
this.alreadyPlayed = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// sets last updated to now and returns how long since then
|
||||
setUpdate() {
|
||||
var d = new Date()
|
||||
var t = Math.floor(d.getTime()/1000)
|
||||
var delta = t - this.lastUpdate
|
||||
this.lastUpdate = t
|
||||
return delta
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function scrobble(artist,title,seconds,secondsago=0) {
|
||||
console.log("Scrobbling " + artist + " - " + title + "; " + seconds + " seconds playtime, " + secondsago + " seconds ago")
|
||||
var d = new Date()
|
||||
var time = Math.floor(d.getTime()/1000) - secondsago
|
||||
//console.log("Time: " + time)
|
||||
var payload = {
|
||||
"artist":artist,
|
||||
"title":title,
|
||||
"duration":seconds,
|
||||
"time":time
|
||||
}
|
||||
|
||||
chrome.storage.local.get(["serverurl","apikey"],function(result) {
|
||||
payload["key"] = result["apikey"];
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.open("POST",result["serverurl"] + "/apis/mlj_1/newscrobble",true);
|
||||
xhttp.setRequestHeader("Content-Type", "application/json");
|
||||
//xhttp.send(requestbody + "&key=" + APIKEY)
|
||||
var body = JSON.stringify(payload);
|
||||
xhttp.send(body)
|
||||
//console.log("Sent: " + body)
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler/icon128.png
Normal file
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler/icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler/icon256.png
Normal file
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler/icon256.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler/icon48.png
Normal file
BIN
auxiliary/chromium_scrobbler/maloja-scrobbler/icon48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
36
auxiliary/chromium_scrobbler/maloja-scrobbler/manifest.json
Normal file
36
auxiliary/chromium_scrobbler/maloja-scrobbler/manifest.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "Maloja Scrobbler",
|
||||
"version": "1.7",
|
||||
"description": "Scrobbles tracks from various sites to your Maloja server",
|
||||
"manifest_version": 2,
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"storage",
|
||||
"http://*/",
|
||||
"https://*/"
|
||||
],
|
||||
"background":
|
||||
{
|
||||
"scripts":
|
||||
[
|
||||
"background.js"
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
"browser_action":
|
||||
{
|
||||
"default_icon":
|
||||
{
|
||||
"128":"icon128.png",
|
||||
"48":"icon48.png"
|
||||
},
|
||||
"default_popup": "settings.html",
|
||||
"default_title": "Maloja Scrobbler"
|
||||
},
|
||||
"icons":
|
||||
{
|
||||
"128":"icon128.png",
|
||||
"48":"icon48.png"
|
||||
}
|
||||
}
|
||||
42
auxiliary/chromium_scrobbler/maloja-scrobbler/settings.html
Normal file
42
auxiliary/chromium_scrobbler/maloja-scrobbler/settings.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!doctype html />
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Wat</title>
|
||||
<script type="text/javascript" src="settings.js"></script>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css?family=Ubuntu');
|
||||
|
||||
body {
|
||||
width:300px;
|
||||
background-color:#333337;
|
||||
color:beige;
|
||||
font-family:'Ubuntu';
|
||||
}
|
||||
input {
|
||||
width:270px;
|
||||
font-family:'Ubuntu';
|
||||
outline:none;
|
||||
border: 0px solid;
|
||||
padding:2px;
|
||||
}
|
||||
span {
|
||||
line-height: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wat">
|
||||
<span id="checkmark_url"></span> <span>Server:</span><br />
|
||||
<input type="text" id="serverurl" />
|
||||
<br /><br />
|
||||
<span id="checkmark_key"></span> <span>API key:</span><br />
|
||||
<input type="text" id="apikey" />
|
||||
<br/><br/>
|
||||
<span>Tabs:</span>
|
||||
<list id="playinglist">
|
||||
</list>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
99
auxiliary/chromium_scrobbler/maloja-scrobbler/settings.js
Normal file
99
auxiliary/chromium_scrobbler/maloja-scrobbler/settings.js
Normal file
@@ -0,0 +1,99 @@
|
||||
var config_defaults = {
|
||||
serverurl:"http://localhost:42010",
|
||||
apikey:"BlackPinkInYourArea"
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener("DOMContentLoaded",function() {
|
||||
|
||||
document.getElementById("serverurl").addEventListener("change",checkServer);
|
||||
document.getElementById("apikey").addEventListener("change",checkServer);
|
||||
|
||||
document.getElementById("serverurl").addEventListener("focusout",checkServer);
|
||||
document.getElementById("apikey").addEventListener("focusout",checkServer);
|
||||
|
||||
document.getElementById("serverurl").addEventListener("input",saveConfig);
|
||||
document.getElementById("apikey").addEventListener("input",saveConfig);
|
||||
|
||||
|
||||
chrome.runtime.onMessage.addListener(onInternalMessage);
|
||||
|
||||
chrome.storage.local.get(config_defaults,function(result){
|
||||
for (var key in result) {
|
||||
document.getElementById(key).value = result[key];
|
||||
}
|
||||
checkServer();
|
||||
})
|
||||
|
||||
chrome.runtime.sendMessage({"type":"query"})
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
function onInternalMessage(request,sender) {
|
||||
if (request.type == "response") {
|
||||
players = request.content
|
||||
html = "";
|
||||
for (var i=0;i<players.length;i++) {
|
||||
if (players[i][1]) {
|
||||
html += "<li>" + players[i][0] + ": " + players[i][1] + " - " + players[i][2]
|
||||
}
|
||||
else {
|
||||
html += "<li>" + players[i][0] + ": Playing nothing"
|
||||
}
|
||||
}
|
||||
document.getElementById("playinglist").innerHTML = html;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function saveConfig() {
|
||||
for (var key in config_defaults) {
|
||||
var value = document.getElementById(key).value;
|
||||
chrome.storage.local.set({ [key]: value });
|
||||
}
|
||||
}
|
||||
|
||||
function checkServer() {
|
||||
url = document.getElementById("serverurl").value + "/api/test?key=" + document.getElementById("apikey").value
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = createCheckmarks;
|
||||
try {
|
||||
xhttp.open("GET",url,true);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (e) {
|
||||
//document.getElementById("checkmark_url").innerHTML = "❌"
|
||||
//document.getElementById("checkmark_key").innerHTML = "❌"
|
||||
document.getElementById("serverurl").style.backgroundColor = "red"
|
||||
document.getElementById("apikey").style.backgroundColor = "red"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createCheckmarks() {
|
||||
if (this.readyState == 4) {
|
||||
if ((this.status >= 200) && (this.status < 300)) {
|
||||
//document.getElementById("checkmark_url").innerHTML = "✔️"
|
||||
//document.getElementById("checkmark_key").innerHTML = "✔️"
|
||||
document.getElementById("serverurl").style.backgroundColor = "lawngreen"
|
||||
document.getElementById("apikey").style.backgroundColor = "lawngreen"
|
||||
}
|
||||
else if (this.status == 403) {
|
||||
//document.getElementById("checkmark_url").innerHTML = "✔️"
|
||||
//document.getElementById("checkmark_key").innerHTML = "❌"
|
||||
document.getElementById("serverurl").style.backgroundColor = "lawngreen"
|
||||
document.getElementById("apikey").style.backgroundColor = "red"
|
||||
}
|
||||
else {
|
||||
//document.getElementById("checkmark_url").innerHTML = "❌"
|
||||
//document.getElementById("checkmark_key").innerHTML = "❌"
|
||||
document.getElementById("serverurl").style.backgroundColor = "red"
|
||||
document.getElementById("apikey").style.backgroundColor = "red"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
maloja_scrobbler_selector_playbar = "//div[contains(@class,'trackView')]"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_metadata = "."
|
||||
// need to select everything as bar / metadata block because artist isn't shown in the inline player
|
||||
|
||||
maloja_scrobbler_selector_title = ".//span[@class='title']/text()"
|
||||
maloja_scrobbler_selector_artist = ".//span[contains(@itemprop,'byArtist')]/a/text()"
|
||||
maloja_scrobbler_selector_duration = ".//span[@class='time_total']/text()"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_control = ".//td[@class='play_cell']/a[@role='button']/div[contains(@class,'playbutton')]/@class"
|
||||
|
||||
maloja_scrobbler_label_playing = "playbutton playing"
|
||||
maloja_scrobbler_label_paused = "playbutton"
|
||||
11
auxiliary/chromium_scrobbler/maloja-scrobbler/sites/plex.js
Normal file
11
auxiliary/chromium_scrobbler/maloja-scrobbler/sites/plex.js
Normal file
@@ -0,0 +1,11 @@
|
||||
maloja_scrobbler_selector_playbar = "//div[contains(@class,'PlayerControls')]"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_metadata = ".//div[contains(@class,'PlayerControlsMetadata-container')]"
|
||||
|
||||
maloja_scrobbler_selector_title = ".//a[@data-qa-id='metadataTitleLink']/@title"
|
||||
maloja_scrobbler_selector_artist = ".//span[contains(@class,'MetadataPosterTitle-title')]/a[1]/@title"
|
||||
maloja_scrobbler_selector_duration = ".//button[@data-qa-id='mediaDuration']/text()[3]"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_control = ".//div[contains(@class,'PlayerControls-buttonGroupCenter')]/button[2]/@title"
|
||||
@@ -0,0 +1,14 @@
|
||||
maloja_scrobbler_selector_playbar = "//div[contains(@class,'playControls')]"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_metadata = ".//div[contains(@class,'playControls__soundBadge')]//div[contains(@class,'playbackSoundBadge__titleContextContainer')]"
|
||||
|
||||
maloja_scrobbler_selector_title = ".//div/a/@title"
|
||||
maloja_scrobbler_selector_artist = ".//a/text()"
|
||||
maloja_scrobbler_selector_duration = ".//div[contains(@class,'playbackTimeline__duration')]//span[@aria-hidden='true']/text()"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_control = ".//button[contains(@class,'playControl')]/@title"
|
||||
|
||||
maloja_scrobbler_label_playing = "Pause current"
|
||||
maloja_scrobbler_label_paused = "Play current"
|
||||
@@ -0,0 +1,12 @@
|
||||
maloja_scrobbler_selector_playbar = "//div[@class='now-playing-bar']"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_metadata = ".//div[@class='now-playing-bar__left']"
|
||||
|
||||
maloja_scrobbler_selector_title = ".//a[@data-testid='nowplaying-track-link']/text()"
|
||||
maloja_scrobbler_selector_artists = ".//a[contains(@href,'/artist/')]"
|
||||
maloja_scrobbler_selector_artist = "./text()"
|
||||
maloja_scrobbler_selector_duration = ".//div[@class='playback-bar']/div[3]/text()"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_control = ".//div[contains(@class,'player-controls__buttons')]/button[3]/@title"
|
||||
@@ -0,0 +1,13 @@
|
||||
maloja_scrobbler_selector_playbar = "//ytmusic-player-bar"
|
||||
|
||||
|
||||
maloja_scrobbler_selector_metadata = ".//div[contains(@class,'middle-controls')]/div[contains(@class,'content-info-wrapper')]"
|
||||
|
||||
maloja_scrobbler_selector_title = ".//yt-formatted-string[contains(@class,'title')]/@title"
|
||||
maloja_scrobbler_selector_artists = ".//span/span[contains(@class,'subtitle')]/yt-formatted-string/a[position()<last()]"
|
||||
maloja_scrobbler_selector_artist = "./text()"
|
||||
maloja_scrobbler_selector_duration = ".//div[contains(@class,'left-controls')]/span[contains(@class,'time-info')]/text()"
|
||||
duration_needs_split = true
|
||||
|
||||
|
||||
maloja_scrobbler_selector_control = ".//div[contains(@class,'left-controls')]/div/paper-icon-button[contains(@class,'play-pause-button')]/@title"
|
||||
91
auxiliary/chromium_scrobbler/maloja-scrobbler/sitescript.js
Normal file
91
auxiliary/chromium_scrobbler/maloja-scrobbler/sitescript.js
Normal file
@@ -0,0 +1,91 @@
|
||||
function getxpath(path,type) {
|
||||
result = document.evaluate(path, this, null, type, null);
|
||||
|
||||
if (type == XPathResult.FIRST_ORDERED_NODE_TYPE) {
|
||||
return result.singleNodeValue;
|
||||
}
|
||||
else if (type == XPathResult.ORDERED_NODE_ITERATOR_TYPE) {
|
||||
resultarray = [];
|
||||
while(node = result.iterateNext()) {
|
||||
resultarray.push(node);
|
||||
}
|
||||
|
||||
return resultarray;
|
||||
}
|
||||
else if (type == XPathResult.STRING_TYPE) {
|
||||
return result.stringValue;
|
||||
}
|
||||
|
||||
// if (path.split("/").slice(-1)[0].startsWith("text()") || path.split("/").slice(-1)[0].startsWith("@")) {
|
||||
// result = document.evaluate(path, this, null, XPathResult.STRING_TYPE, null);
|
||||
// return result.stringValue;
|
||||
// }
|
||||
// else {
|
||||
// result = document.evaluate(path, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
||||
// return result.singleNodeValue;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
Node.prototype.xpath = getxpath;
|
||||
|
||||
|
||||
bar = document.xpath(maloja_scrobbler_selector_playbar, XPathResult.FIRST_ORDERED_NODE_TYPE);
|
||||
if (bar == null) {
|
||||
console.log("Nothing playing right now!");
|
||||
chrome.runtime.sendMessage({type:"stopPlayback",time:Math.floor(Date.now()),artist:"",title:""});
|
||||
}
|
||||
else {
|
||||
metadata = bar.xpath(maloja_scrobbler_selector_metadata, XPathResult.FIRST_ORDERED_NODE_TYPE);
|
||||
duration = bar.xpath(maloja_scrobbler_selector_duration, XPathResult.STRING_TYPE);
|
||||
duration = duration + '';
|
||||
|
||||
|
||||
title = metadata.xpath(maloja_scrobbler_selector_title, XPathResult.STRING_TYPE);
|
||||
if (typeof maloja_scrobbler_selector_artists !== "undefined") {
|
||||
artistnodes = metadata.xpath(maloja_scrobbler_selector_artists, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
|
||||
artists = artistnodes.map(x => x.xpath(maloja_scrobbler_selector_artist, XPathResult.STRING_TYPE));
|
||||
artist = artists.join(";");
|
||||
}
|
||||
else {
|
||||
artist = metadata.xpath(maloja_scrobbler_selector_artist, XPathResult.STRING_TYPE);
|
||||
}
|
||||
|
||||
|
||||
if (typeof duration_needs_split !== "undefined" && duration_needs_split) {
|
||||
duration = duration.split("/").slice(-1)[0].trim();
|
||||
}
|
||||
|
||||
if (duration.split(":").length == 2) {
|
||||
durationSeconds = parseInt(duration.split(":")[0]) * 60 + parseInt(duration.split(":")[1]);
|
||||
}
|
||||
else {
|
||||
durationSeconds = parseInt(duration.split(":")[0]) * 60 * 60 + parseInt(duration.split(":")[1]) * 60 + parseInt(duration.split(":")[2]);
|
||||
}
|
||||
|
||||
|
||||
control = bar.xpath(maloja_scrobbler_selector_control, XPathResult.STRING_TYPE);
|
||||
try {
|
||||
label_playing = maloja_scrobbler_label_playing
|
||||
}
|
||||
catch {
|
||||
label_playing = "Pause"
|
||||
}
|
||||
try {
|
||||
label_paused = maloja_scrobbler_label_paused
|
||||
}
|
||||
catch {
|
||||
label_paused = "Play"
|
||||
}
|
||||
if (control == label_paused) {
|
||||
console.log("Not playing right now");
|
||||
chrome.runtime.sendMessage({type:"stopPlayback",time:Math.floor(Date.now()),artist:artist,title:title});
|
||||
//stopPlayback()
|
||||
}
|
||||
else if (control == label_playing) {
|
||||
console.log("Playing " + artist + " - " + title + " (" + durationSeconds + " sec)");
|
||||
chrome.runtime.sendMessage({type:"startPlayback",time:Math.floor(Date.now()),artist:artist,title:title,duration:durationSeconds});
|
||||
//startPlayback(artist,title,durationSeconds)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
convert ../../maloja/web/static/png/favicon_large.png -resize 256 icon256.png
|
||||
convert ../../maloja/web/static/png/favicon_large.png -resize 128 icon128.png
|
||||
convert ../../maloja/web/static/png/favicon_large.png -resize 48 icon48.png
|
||||
convert ../../maloja/web/static/png/favicon_large.png -background none -resize 280 -gravity center -extent 440x280 -background "#232327" -flatten tile.png
|
||||
rm ../maloja-scrobbler.zip
|
||||
zip ../maloja-scrobbler.zip sites/* *.js *.json *.html icon*.png
|
||||
12
auxiliary/malojalib/README.md
Normal file
12
auxiliary/malojalib/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# maloja-lib
|
||||
|
||||
Library for Python music players to allow users to scrobble to [Maloja](https://github.com/krateng/maloja) servers.
|
||||
|
||||
```
|
||||
from malojalib import MalojaInstance
|
||||
|
||||
instance = MalojaInstance(user_supplied_url,user_supplied_key)
|
||||
|
||||
instance.scrobble(artists=['K/DA','Howard Shore','Blackbeard's Tea Party],title='Grüezi Wohl Frau Stirnimaa')
|
||||
|
||||
```
|
||||
27
auxiliary/malojalib/malojalib/__init__.py
Normal file
27
auxiliary/malojalib/malojalib/__init__.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import requests
|
||||
|
||||
class MalojaInstance:
|
||||
def __init__(self,base_url,key):
|
||||
self.base_url = base_url
|
||||
self.key = key
|
||||
|
||||
def test(self):
|
||||
url = self.base_url + '/apis/mlj_1/test'
|
||||
response = requests.get(url,{'key':self.key})
|
||||
|
||||
return (response.status_code == 200)
|
||||
|
||||
def scrobble(self,artists,title,timestamp=None,album=None,duration=None):
|
||||
payload = {
|
||||
'key':self.key,
|
||||
'artists':artists,
|
||||
'title':title,
|
||||
'time':timestamp,
|
||||
'album':album,
|
||||
'duration':duration
|
||||
}
|
||||
|
||||
url = self.base_url + '/apis/mlj_1/newscrobble'
|
||||
response = requests.post(url,payload)
|
||||
|
||||
return response.json()
|
||||
28
auxiliary/malojalib/pyproject.toml
Normal file
28
auxiliary/malojalib/pyproject.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[project]
|
||||
name = "maloja-lib"
|
||||
version = "1.0.0"
|
||||
description = "Utilities to interact with Maloja servers"
|
||||
readme = "./README.md"
|
||||
requires-python = ">=3.6"
|
||||
license = { file="../../LICENSE" }
|
||||
authors = [ { name="Johannes Krattenmacher", email="maloja@dev.krateng.ch" } ]
|
||||
|
||||
urls.repository = "https://github.com/krateng/maloja"
|
||||
urls.documentation = "https://github.com/krateng/maloja"
|
||||
|
||||
keywords = ["scrobbling", "music", "library", "api"]
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||
"Operating System :: OS Independent"
|
||||
]
|
||||
|
||||
dependencies = [
|
||||
"requests"
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
|
||||
[build-system]
|
||||
requires = ["flit_core >=3.2,<4"]
|
||||
build-backend = "flit_core.buildapi"
|
||||
Reference in New Issue
Block a user