From b99cf8b77dcbf963b073067e80eca323eacc396e Mon Sep 17 00:00:00 2001 From: Krateng Date: Mon, 13 May 2019 13:18:22 +0200 Subject: [PATCH] Updated Chromium scrobbler to be more modularized --- README.md | 11 ++- scrobblers/chromium-generic/background.js | 48 ++++++++--- scrobblers/chromium-generic/manifest.json | 2 +- scrobblers/chromium-generic/sites/plex.js | 11 +++ scrobblers/chromium-generic/sites/ytmusic.js | 13 +++ scrobblers/chromium-generic/sitescript.js | 79 +++++++++++++++++++ .../chromium-generic/sitescripts/plex.js | 31 -------- .../chromium-generic/sitescripts/ytmusic.js | 40 ---------- 8 files changed, 146 insertions(+), 89 deletions(-) create mode 100644 scrobblers/chromium-generic/sites/plex.js create mode 100644 scrobblers/chromium-generic/sites/ytmusic.js create mode 100644 scrobblers/chromium-generic/sitescript.js delete mode 100644 scrobblers/chromium-generic/sitescripts/plex.js delete mode 100644 scrobblers/chromium-generic/sitescripts/ytmusic.js diff --git a/README.md b/README.md index 7acec3f..c95283a 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ If you didn't install Maloja from the package (and therefore don't have it in `/ The `update` command will always fetch the latest version, while packages are only offered for release versions. +3) Various folders have `.info` files with more information on how to use their associated features. ## How to scrobble @@ -65,7 +66,7 @@ If you didn't install Maloja from the package (and therefore don't have it in `/ If you use Plex Web or Youtube Music on Chromium, you can use the included extension. Make sure to enter the random key Maloja generates on first startup in the extension settings. -If you want to implement your own method of scrobbling, it's very simple: You only need one POST request with the keys `artist`, `title` and `key`. +If you want to implement your own method of scrobbling, it's very simple: You only need one POST request to `/api/newscrobble` with the keys `artist`, `title` and `key`. ### Standard-compliant API @@ -75,10 +76,12 @@ GNU FM |   ------ | --------- Gnukebox URL | Your Maloja URL followed by `/api/s/audioscrobbler` Username | Any name, doesn't matter -Password | Any of your API keys (you can define new ones in `clients/authenticated_machines` in your Maloja folder) +Password | Any of your API keys ListenBrainz |   ------ | --------- -API URL | Your Maloja URL followed by `api/s/listenbrainz` +API URL | Your Maloja URL followed by `/api/s/listenbrainz` Username | Any name, doesn't matter -Auth Token | Any of your API keys (you can define new ones in `clients/authenticated_machines` in your Maloja folder) +Auth Token | Any of your API keys + +It is recommended to define a different API key for every scrobbler you use in `clients/authenticated_machines.tsv` in your Maloja folder. diff --git a/scrobblers/chromium-generic/background.js b/scrobblers/chromium-generic/background.js index 9c8cc89..fdedfca 100644 --- a/scrobblers/chromium-generic/background.js +++ b/scrobblers/chromium-generic/background.js @@ -41,8 +41,8 @@ function onTabUpdated(tabId, changeInfo, tab) { for (var i=0;i { this.actuallyupdate(); },800); + //this.actuallyupdate(); + } + } + + actuallyupdate() { this.messageID++; //console.log("Update! Our page is " + this.page + ", our tab id " + this.tabId) - chrome.tabs.executeScript(this.tabId,{"file":"sitescripts/" + pages[this.page]["script"]}) + chrome.tabs.executeScript(this.tabId,{"file":"sites/" + pages[this.page]["script"]}); + chrome.tabs.executeScript(this.tabId,{"file":"sitescript.js"}); + + this.alreadyQueued = false; } // an actual update message from the script has arrived @@ -184,16 +200,22 @@ class Controller { 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) + this.stopPlayback(artist,title); //then initialize new playback - console.log("New track") - this.setUpdate() - this.alreadyPlayed = 0 - this.currentTitle = title - this.currentArtist = artist - this.currentLength = seconds - console.log(artist + " - " + title + " is playing!") - this.currentlyPlaying = true + 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; } } diff --git a/scrobblers/chromium-generic/manifest.json b/scrobblers/chromium-generic/manifest.json index 34e70e7..4f73fe5 100644 --- a/scrobblers/chromium-generic/manifest.json +++ b/scrobblers/chromium-generic/manifest.json @@ -1,6 +1,6 @@ { "name": "Maloja Scrobbler", - "version": "1.1", + "version": "1.2", "description": "Scrobbles tracks from various sites to your Maloja server", "manifest_version": 2, "permissions": ["activeTab", diff --git a/scrobblers/chromium-generic/sites/plex.js b/scrobblers/chromium-generic/sites/plex.js new file mode 100644 index 0000000..b81de28 --- /dev/null +++ b/scrobblers/chromium-generic/sites/plex.js @@ -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" diff --git a/scrobblers/chromium-generic/sites/ytmusic.js b/scrobblers/chromium-generic/sites/ytmusic.js new file mode 100644 index 0000000..8e9275d --- /dev/null +++ b/scrobblers/chromium-generic/sites/ytmusic.js @@ -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() 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); + if (control == "Play") { + console.log("Not playing right now"); + chrome.runtime.sendMessage({type:"stopPlayback",time:Math.floor(Date.now()),artist:artist,title:title}); + //stopPlayback() + } + else if (control == "Pause") { + console.log("Playing " + artist + " - " + title); + chrome.runtime.sendMessage({type:"startPlayback",time:Math.floor(Date.now()),artist:artist,title:title,duration:durationSeconds}); + //startPlayback(artist,title,durationSeconds) + } + +} diff --git a/scrobblers/chromium-generic/sitescripts/plex.js b/scrobblers/chromium-generic/sitescripts/plex.js deleted file mode 100644 index 42e6ac8..0000000 --- a/scrobblers/chromium-generic/sitescripts/plex.js +++ /dev/null @@ -1,31 +0,0 @@ -bar = document.querySelector("div[class*=PlayerControls]") -if (bar == null) { - console.log("Nothing playing right now!") - chrome.runtime.sendMessage({type:"stopPlayback",time:Math.floor(Date.now()),artist:"",title:""}) - exit() -} - -metadata = bar.querySelector("div[class*=PlayerControlsMetadata-container]") - -title = metadata.querySelector("a[class*=MetadataPosterTitle-singleLineTitle]").getAttribute("title") -artist = metadata.querySelector("span[class*=MetadataPosterTitle-title] > a:nth-child(1)").getAttribute("title") -duration = metadata.querySelector("[data-qa-id=mediaDuration]").innerHTML.split("/")[1] -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.querySelector("div[class*=PlayerControls-buttonGroupCenter] > button:nth-child(2)").getAttribute("title") -if (control == "Play") { - console.log("Not playing right now") - chrome.runtime.sendMessage({type:"stopPlayback",time:Math.floor(Date.now()),artist:artist,title:title}) - //stopPlayback() -} -else if (control == "Pause") { - console.log("Playing " + artist + " - " + title) - chrome.runtime.sendMessage({type:"startPlayback",time:Math.floor(Date.now()),artist:artist,title:title,duration:durationSeconds}) - //startPlayback(artist,title,durationSeconds) -} diff --git a/scrobblers/chromium-generic/sitescripts/ytmusic.js b/scrobblers/chromium-generic/sitescripts/ytmusic.js deleted file mode 100644 index 3ccb1c7..0000000 --- a/scrobblers/chromium-generic/sitescripts/ytmusic.js +++ /dev/null @@ -1,40 +0,0 @@ -bar = document.querySelector("ytmusic-player-bar") -if (bar == null) { - console.log("Nothing playing right now!") - chrome.runtime.sendMessage({type:"stopPlayback",time:Math.floor(Date.now()),artist:"",title:""}) - exit() -} - -metadata = bar.querySelector("div[class*=middle-controls] > div[class*=content-info-wrapper]") - -ctrl = bar.querySelector("div[class*=left-controls]") - -title = metadata.querySelector("yt-formatted-string[class*=title]").getAttribute("title") -artistlist = metadata.querySelector("span > span[class*=subtitle] > yt-formatted-string") -artistelements = artistlist.getElementsByTagName("a") -artists = [] -for (var i=0;i span[class*=subtitle] > yt-formatted-string > a:nth-child(1)").innerHTML -artist = artists.join(";"); -duration = ctrl.querySelector("[class*=time-info]").innerHTML.split("/")[1] -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 = ctrl.querySelector("div > paper-icon-button[class*=play-pause-button]").getAttribute("title") -if (control == "Play") { - console.log("Not playing right now") - chrome.runtime.sendMessage({type:"stopPlayback",time:Math.floor(Date.now()),artist:artist,title:title}) - //stopPlayback() -} -else if (control == "Pause") { - console.log("Playing " + artist + " - " + title) - chrome.runtime.sendMessage({type:"startPlayback",time:Math.floor(Date.now()),artist:artist,title:title,duration:durationSeconds}) - //startPlayback(artist,title,durationSeconds) -}