Skip to content

Commit

Permalink
Merge pull request #47 from Fabrizz/dev-features
Browse files Browse the repository at this point in the history
Added localization to API response
  • Loading branch information
Fabrizz authored Feb 6, 2024
2 parents 87a8243 + 059fc54 commit b547ef3
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 62 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ ex.json
test.json
api.json
svgs.html
lyrics.js

3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "always",
"proseWrap": "always"
"proseWrap": "always",
"endOfLine": "auto"
}
13 changes: 8 additions & 5 deletions MMM-OnSpotify.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Module.register("MMM-OnSpotify", {
deviceFilter: [],
deviceFilterExclude: false,
filterNoticeSubtitle: true,
// Changes the language sent to Spotify
language: config.language,

updateInterval: {
isPlaying: 1,
Expand Down Expand Up @@ -143,7 +145,7 @@ Module.register("MMM-OnSpotify", {
typeof this.config.theming.experimentalCSSOverridesForMM2 === "object";

////////////////////////////////////////////////////////////////////////////////////////////
this.version = "3.3.0";
this.version = "3.3.1";
////////////////////////////////////////////////////////////////////////////////////////////

this.displayUser =
Expand Down Expand Up @@ -205,6 +207,7 @@ Module.register("MMM-OnSpotify", {
accessToken: this.config.accessToken,
refreshToken: this.config.refreshToken,
},
language: this.config.language,
});
this.updateFetchingLoop(this.config.updateInterval[this.lastStatus]);
},
Expand Down Expand Up @@ -364,8 +367,9 @@ Module.register("MMM-OnSpotify", {
this.userData = {
...payload,
subtitleOverride:
this.playerData && this.config.filteredDeviceNotice ?
this.playerData.notAllowedDevice : false,
this.playerData && this.config.filteredDeviceNotice
? this.playerData.notAllowedDevice
: false,
};
this.userData.age = Date.now();
this.requestUserData = false;
Expand Down Expand Up @@ -664,8 +668,7 @@ Module.register("MMM-OnSpotify", {
? (this.config.theming.textAnimations = this.config.textAnimations)
: null;
typeof this.config.scrollAnimations === "boolean"
? (this.config.theming.scrollAnimations =
this.config.scrollAnimations)
? (this.config.theming.scrollAnimations = this.config.scrollAnimations)
: null;
typeof this.config.spotifyVectorAnimations === "boolean"
? (this.config.theming.spotifyVectorAnimations =
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Once you finish, you are all set with the basic configuration. Scroll down to se
deviceFilter: [],
deviceFilterExclude: false,
filterNoticeSubtitle: true,
language: config.language,
// Update intervals [SEE BELOW]
isPlaying: 1,
isEmpty: 2,
Expand Down Expand Up @@ -129,6 +130,7 @@ experimentalCSSOverridesForMM2: [
| deviceFilter <br> `list[]` | List of device names to filter from the module, by default, its an inclusion list, you can change this using `deviceFilterExclude` (making it an exclusion list). When a filtered device plays `displayWhenEmpty` shows. Example: `["Sonos Bedroom", "DESKTOP-ABCD123"]` |
| deviceFilterExclude <br> `false` | Inverts the `deviceFilter` list, making it exclude devices |
| filterNoticeSubtitle <br> `true`| Changes the subtitle of `displayWhenEmpty`, to not show a false status if the `deviceFilter` is set |
| language <br> `config.language`| Changes the language in which titles of songs are shown. When it is not set, it depends on `config.language`. Example: `en-US` (Or `false` if you prefer the default api response) |

### Polling Intervals:
| Key | Description |
Expand Down
24 changes: 11 additions & 13 deletions auth/authorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
* and Raywoo implementation:
* https://github.com/raywo/MMM-NowPlayingOnSpotify/tree/master/authorization
*/

const querystring = require("querystring");
const express = require("express");
const request = require("request");
const querystring = require("querystring");
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");

Expand Down Expand Up @@ -75,9 +74,9 @@ function getAuthOptions(code) {
grant_type: "authorization_code",
},
headers: {
Authorization:
"Basic " +
Buffer.from(client_id + ":" + client_secret).toString("base64"),
Authorization: `Basic ${Buffer.from(
`${client_id}:${client_secret}`,
).toString("base64")}`,
},
json: true,
};
Expand All @@ -88,19 +87,18 @@ function redirectToSuccess(response, body) {
let refresh_token = body.refresh_token;
// we can also pass the token to the browser to make requests from there
response.redirect(
"/#" +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
client_id: client_id,
client_secret: client_secret,
}),
`/#${querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
client_id: client_id,
client_secret: client_secret,
})}`,
);
}

let stateKey = "spotify_auth_state";
let app = express();
app.use(express.static(__dirname + "/client"));
app.use(express.static(`${__dirname}/client`));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
Expand Down
37 changes: 23 additions & 14 deletions node_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = NodeHelper.create({
case "SET_CREDENTIALS_REFRESH":
this.fetcher = new SpotifyFetcher(payload);
this.fetchSpotifyData("PLAYER");
this.preferences = payload.preferences
this.preferences = payload.preferences;
break;
case "REFRESH_PLAYER":
this.fetchSpotifyData("PLAYER");
Expand Down Expand Up @@ -61,23 +61,28 @@ module.exports = NodeHelper.create({
switch (type) {
case "PLAYER":
// CASE S1 The data is OK and the target is a filtered device
if (data && data.device && data.device.name && !this.isAllowedDevice(data.device.name)) {
if (
data &&
data.device &&
data.device.name &&
!this.isAllowedDevice(data.device.name)
) {
this.sendSocketNotification("PLAYER_DATA", {
statusIsPlayerEmpty: true,
statusIsNewSong: false,
statusIsChangeToEmptyPlayer: this.lastPlayerStatus,
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: false,
statusIsDeviceChange: false,
notAllowedDevice: data.device.name
notAllowedDevice: data.device.name,
});
this.lastMediaUri = "empty";
this.lastPlayerStatus = false;
this.lastPlayerStatusCount = 0;
this.lastDeviceName = "unknown";
break
break;
}
// CASE S2 The data is OK and the target is in a private session
// CASE S2 The data is OK and the target is in a private session
if (data && data.device && data.device.is_private_session) {
let payload = {
/* Player data */
Expand All @@ -97,7 +102,7 @@ module.exports = NodeHelper.create({
statusPlayerUpdating: false,
statusIsDeviceChange:
this.lastDeviceName !== data.device.name ? true : false,
notAllowedDevice: false
notAllowedDevice: false,
};
this.sendSocketNotification("PLAYER_DATA", payload);
this.lastMediaUri = "privatesession";
Expand Down Expand Up @@ -150,7 +155,7 @@ module.exports = NodeHelper.create({
statusPlayerUpdating: false,
statusIsDeviceChange:
this.lastDeviceName !== data.device.name ? true : false,
notAllowedDevice: false
notAllowedDevice: false,
};
this.sendSocketNotification("PLAYER_DATA", payload);
this.lastMediaUri = data.item.uri;
Expand All @@ -169,7 +174,7 @@ module.exports = NodeHelper.create({
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: true,
statusIsDeviceChange: false,
notAllowedDevice: false
notAllowedDevice: false,
});
this.lastPlayerStatusCount = this.lastPlayerStatusCount + 1;
this.lastPlayerStatus = true;
Expand All @@ -182,7 +187,7 @@ module.exports = NodeHelper.create({
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: false,
statusIsDeviceChange: false,
notAllowedDevice: false
notAllowedDevice: false,
});
this.lastMediaUri = "empty";
this.lastPlayerStatus = false;
Expand All @@ -197,7 +202,7 @@ module.exports = NodeHelper.create({
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: false,
statusIsDeviceChange: false,
notAllowedDevice: false
notAllowedDevice: false,
});
this.lastMediaUri = "empty";
this.lastPlayerStatus = false;
Expand Down Expand Up @@ -254,10 +259,14 @@ module.exports = NodeHelper.create({
},

isAllowedDevice: function (currentDevice) {
if (!this.preferences.deviceFilter || this.preferences.deviceFilter.length < 1) return true
return this.preferences.deviceFilterExclude ?
!this.preferences.deviceFilter.includes(currentDevice) :
this.preferences.deviceFilter.includes(currentDevice)
if (
!this.preferences.deviceFilter ||
this.preferences.deviceFilter.length < 1
)
return true;
return this.preferences.deviceFilterExclude
? !this.preferences.deviceFilter.includes(currentDevice)
: this.preferences.deviceFilter.includes(currentDevice);
},
processArtists: (artists) => artists.map((artist) => artist.name).join(", "),
processImages: (images) => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mmm-onspotify",
"version": "3.3.0",
"version": "3.3.1",
"description": "A MagicMirror2 module to display Spotify Connect data. Highly customizable. Allows DynamicTheming.",
"repository": {
"type": "git",
Expand Down
16 changes: 8 additions & 8 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
"FILTERED_PLAYING": "Nothing is playing in this room.",
"PRODUCT_WARNING": "The current account is not using Spotify Premium. This module requieres a Premium account.",
"CONNECTION_WARNING": "There was a connection error. Slowing the polling of api.spotify/...",
"CONNECTION_ERROR": "Connection errors persists. Slowing the polling more. Hiding old player data.",
"VIBRANT_NOT_LOADED": "(vendor) Vibrant did not load correctly.",
"USER_CSS_ERROR": "There was an error extracting CSS information. (The duration of animations/transitions should be in \"ms\")",
"CONNECTION_ERROR": "Connection errors persist. Slowing the polling rate to <onError> seconds. Emptying player as the data is outdated.",
"VIBRANT_NOT_LOADED": "[VENDOR] Vibrant library did not load correctly.",
"USER_CSS_ERROR": "An error ocurred while extracting CSS information. (The duration of animations/transitions should be in \"ms\")",
"STABLISHING_CONNECTION": "Connecting to Spotify...",
"NOTHING_PLAYING": "Nothing is playing",
"SPOTIFY_HEADER": "MMM-OnSpotify",
"DEBUG_COLORS": "Debug palettes are shown because <showDebugPalette> is set to true",
"SPOTIFYCODE_EXPERIMENTAL": "<spotifyCodeExperimentalShow> is enabled. The api to generate codes is not public, and can end without prior notice. (https://github.com/Fabrizz/MMM-OnSpotify#other)",
"DEBUG_COLORS": "<showDebugPalette> is enabled. The module will log Vibrant data when color processing is requested.",
"SPOTIFYCODE_EXPERIMENTAL": "<spotifyCodeExperimentalShow> is enabled. The API used is not documented, as its an Spotify service. This service could stop working at any time. (https://github.com/Fabrizz/MMM-OnSpotify#other)",
"RESUME": "Resuming module",
"SUSPEND": "Suspending module",
"LIVELYRICS_NOTICE": "MMM-LiveLyrics found! - Check MMM-LL logs to see more. (https://github.com/Fabrizz/MMM-LiveLyrics)",
"CSSOVERRIDE_NOTICE": "You are overriding default MM2 CSS variables. Check for spelling errors and contrast issues",
"CSSOVERRIDE_MALFORMED": "There was an error parsing your \"experimentalCSSOverridesForMM2\" array. Remove your custom config entry or check it for errors"
"LIVELYRICS_NOTICE": "MMM-LiveLyrics found! - LiveLyrics should log the connection to this module. (https://github.com/Fabrizz/MMM-LiveLyrics)",
"CSSOVERRIDE_NOTICE": "You are overriding default MM2 CSS variables. Check spelling errors (and contrast issues)",
"CSSOVERRIDE_MALFORMED": "There was an error parsing your \"experimentalCSSOverridesForMM2\" array. This entry should be an array, check the docs for more information."
}
14 changes: 5 additions & 9 deletions utils/SpotifyDomBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -1191,19 +1191,15 @@ class SpotifyDomBuilder {
document
.getElementById("VSNO-TARGET-SUBTITLE")
.classList.remove("scroll");
document.getElementById("VSNO-TARGET-TITLE").classList.remove("scroll");
document
.getElementById("VSNO-TARGET-TITLE")
.classList.remove("scroll");
}
}
} catch (error) {
console.info(
`%c· MMM-OnSpotify %c %c[INFO]%c Unknown unsync, could not change scroller status`,
"background-color:#84CC16;color:black;border-radius:0.4em",
"",
"background-color:orange;color:black",
"",
);
/* This effect is based on the current TS of the song, the module reference is going to always be some ms behind,
here we catch, any even if it never happens, the error thown if the player changes state */
}

}

/* Utils */
Expand Down
21 changes: 10 additions & 11 deletions utils/SpotifyFetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = class SpotifyFetcher {
constructor(payload) {
this.credentials = payload.credentials;
this.preferences = payload.preferences;
this.language = payload.language;
this.tokenExpiresAt = moment();
}

Expand All @@ -40,16 +41,18 @@ module.exports = class SpotifyFetcher {

requestData(type) {
let sl = "v1/me/top/artists?limit=9";
const headers = new Headers();
headers.append("Authorization", `Bearer ${this.credentials.accessToken}`);
// TODO: Check if using &locale= (or &market=) has any different effect, as its not documented correctly
if (this.language) headers.append("Accept-Language", this.language);
switch (type) {
case "PLAYER":
return fetch(
new URL("v1/me/player?additional_types=track,episode", userBase),
{
method: "GET",
referrerPolicy: "no-referrer",
headers: {
Authorization: `Bearer ${this.credentials.accessToken}`,
},
headers: headers,
},
)
.then((res) => {
Expand All @@ -75,7 +78,7 @@ module.exports = class SpotifyFetcher {
return fetch(new URL("v1/me", userBase), {
method: "GET",
referrerPolicy: "no-referrer",
headers: { Authorization: `Bearer ${this.credentials.accessToken}` },
headers: headers,
})
.then((res) => {
if (!res.ok && res.status === 429)
Expand All @@ -98,7 +101,7 @@ module.exports = class SpotifyFetcher {
return fetch(new URL("v1/me/player/queue", userBase), {
method: "GET",
referrerPolicy: "no-referrer",
headers: { Authorization: `Bearer ${this.credentials.accessToken}` },
headers: headers,
})
.then((res) => {
if (!res.ok && res.status === 429)
Expand All @@ -123,9 +126,7 @@ module.exports = class SpotifyFetcher {
return fetch(new URL(sl, userBase), {
method: "GET",
referrerPolicy: "no-referrer",
headers: {
Authorization: `Bearer ${this.credentials.accessToken}`,
},
headers: headers,
})
.then((res) => {
if (!res.ok && res.status === 429)
Expand All @@ -148,9 +149,7 @@ module.exports = class SpotifyFetcher {
return fetch(new URL("v1/me/player/recently-played", userBase), {
method: "GET",
referrerPolicy: "no-referrer",
headers: {
Authorization: `Bearer ${this.credentials.accessToken}`,
},
headers: headers,
})
.then((res) => {
if (!res.ok && res.status === 429)
Expand Down

0 comments on commit b547ef3

Please sign in to comment.