LastFM Scrobbling
This commit is contained in:
parent
df6ba93242
commit
130cfed2b4
7 changed files with 331 additions and 22 deletions
|
@ -7,6 +7,7 @@ const windowStateKeeper = require("electron-window-state");
|
|||
const os = require('os');
|
||||
const yt = require('youtube-search-without-api-key');
|
||||
const discord = require('./discordrpc');
|
||||
const lastfm = require('./lastfm');
|
||||
const mpris = require('./mpris');
|
||||
|
||||
// Analytics for debugging.
|
||||
|
@ -14,9 +15,10 @@ const ElectronSentry = require("@sentry/electron");
|
|||
ElectronSentry.init({dsn: "https://68c422bfaaf44dea880b86aad5a820d2@o954055.ingest.sentry.io/6112214"});
|
||||
|
||||
const CiderBase = {
|
||||
win: null,
|
||||
async Start() {
|
||||
this.clientPort = await getPort({port: 9000});
|
||||
this.CreateBrowserWindow()
|
||||
this.win = this.CreateBrowserWindow()
|
||||
},
|
||||
clientPort: 0,
|
||||
CreateBrowserWindow() {
|
||||
|
@ -204,15 +206,22 @@ const CiderBase = {
|
|||
|
||||
mpris.connect(win)
|
||||
|
||||
lastfm.authenticate()
|
||||
// Discord
|
||||
discord.connect((app.cfg.get("general.discord_rpc") == 1) ? '911790844204437504' : '886578863147192350');
|
||||
ipcMain.on('playbackStateDidChange', (_event, a) => {
|
||||
app.media = a;
|
||||
discord.updateActivity(a)
|
||||
mpris.updateState(a)
|
||||
lastfm.scrobbleSong(a)
|
||||
lastfm.updateNowPlayingSong(a)
|
||||
});
|
||||
ipcMain.on('nowPlayingItemDidChange', (_event, a) => {
|
||||
app.media = a;
|
||||
discord.updateActivity(a)
|
||||
mpris.updateAttributes(a)
|
||||
lastfm.scrobbleSong(a)
|
||||
lastfm.updateNowPlayingSong(a)
|
||||
});
|
||||
|
||||
return win
|
||||
|
@ -224,6 +233,31 @@ const CiderBase = {
|
|||
dev: app.isPackaged
|
||||
}
|
||||
},
|
||||
LinkHandler: (startArgs) => {
|
||||
if (!startArgs) return;
|
||||
console.log("lfmtoken",String(startArgs))
|
||||
if (String(startArgs).includes('auth')) {
|
||||
let authURI = String(startArgs).split('/auth/')[1]
|
||||
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
|
||||
const authKey = authURI.split('lastfm?token=')[1];
|
||||
app.cfg.set('lastfm.enabled', true);
|
||||
app.cfg.set('lastfm.auth_token', authKey);
|
||||
CiderBase.win.webContents.send('LastfmAuthenticated', authKey);
|
||||
lastfm.authenticate()
|
||||
}
|
||||
} else {
|
||||
const formattedSongID = startArgs.replace('ame://', '').replace('/', '');
|
||||
console.warn(`[LinkHandler] Attempting to load song id: ${formattedSongID}`);
|
||||
|
||||
// setQueue can be done with album, song, url, playlist id
|
||||
this.win.webContents.executeJavaScript(`
|
||||
MusicKit.getInstance().setQueue({ song: '${formattedSongID}'}).then(function(queue) {
|
||||
MusicKit.getInstance().play();
|
||||
});
|
||||
`).catch((err) => console.error(err));
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
async InitWebServer() {
|
||||
const webapp = express();
|
||||
|
|
153
src/main/lastfm.js
Normal file
153
src/main/lastfm.js
Normal file
|
@ -0,0 +1,153 @@
|
|||
const {app, Notification} = require('electron'),
|
||||
fs = require('fs'),
|
||||
{resolve} = require('path'),
|
||||
sessionPath = resolve(app.getPath('userData'), 'session.json'),
|
||||
apiCredentials = require('../../resources/lfmApiCredentials.json'),
|
||||
LastfmAPI = require('lastfmapi');
|
||||
|
||||
const lfm = {
|
||||
authenticateFromFile: function () {
|
||||
let sessionData = require(sessionPath)
|
||||
console.log("[LastFM][authenticateFromFile] Logging in with Session Info.")
|
||||
app.lastfm.setSessionCredentials(sessionData.name, sessionData.key)
|
||||
console.log("[LastFM][authenticateFromFile] Logged in.")
|
||||
},
|
||||
|
||||
authenticate: function () {
|
||||
if (app.cfg.get('lastfm.auth_token')) {
|
||||
app.cfg.set('lastfm.enabled', true);
|
||||
}
|
||||
|
||||
if (!app.cfg.get('lastfm.enabled') || !app.cfg.get('lastfm.auth_token')) {
|
||||
app.cfg.set('lastfm.enabled', false);
|
||||
return
|
||||
}
|
||||
|
||||
const lfmAPI = new LastfmAPI({
|
||||
'api_key': apiCredentials.key,
|
||||
'secret': apiCredentials.secret
|
||||
});
|
||||
|
||||
app.lastfm = Object.assign(lfmAPI, {cachedAttributes: false, cachedNowPlayingAttributes: false});
|
||||
|
||||
fs.stat(sessionPath, function (err) {
|
||||
if (err) {
|
||||
console.error("[LastFM][Session] Session file couldn't be opened or doesn't exist,", err)
|
||||
console.log("[LastFM][Auth] Beginning authentication from configuration")
|
||||
app.lastfm.authenticate(app.cfg.get('lastfm.auth_token'), function (err, session) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
console.log("[LastFM] Successfully obtained LastFM session info,", session); // {"name": "LASTFM_USERNAME", "key": "THE_USER_SESSION_KEY"}
|
||||
console.log("[LastFM] Saving session info to disk.")
|
||||
let tempData = JSON.stringify(session)
|
||||
fs.writeFile(sessionPath, tempData, (err) => {
|
||||
if (err)
|
||||
console.log("[LastFM][fs]", err)
|
||||
else {
|
||||
console.log("[LastFM][fs] File was written successfully.")
|
||||
lfm.authenticateFromFile()
|
||||
new Notification({
|
||||
title: app.getName(),
|
||||
body: "Successfully logged into LastFM using Authentication Key."
|
||||
}).show()
|
||||
}
|
||||
})
|
||||
});
|
||||
} else {
|
||||
lfm.authenticateFromFile()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
scrobbleSong: async function (attributes) {
|
||||
await new Promise(resolve => setTimeout(resolve, app.cfg.get('lastfm.scrobble_after') * 1000));
|
||||
const currentAttributes = app.media;
|
||||
|
||||
if (!app.lastfm || app.lastfm.cachedAttributes === attributes ) {
|
||||
return
|
||||
}
|
||||
|
||||
if (app.lastfm.cachedAttributes) {
|
||||
if (app.lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return;
|
||||
}
|
||||
|
||||
if (currentAttributes.status && currentAttributes === attributes) {
|
||||
if (fs.existsSync(sessionPath)) {
|
||||
// Scrobble playing song.
|
||||
if (attributes.status === true) {
|
||||
app.lastfm.track.scrobble({
|
||||
'artist': lfm.filterArtistName(attributes.artistName),
|
||||
'track': attributes.name,
|
||||
'album': attributes.albumName,
|
||||
'albumArtist': this.filterArtistName(attributes.artistName),
|
||||
'timestamp': new Date().getTime() / 1000
|
||||
}, function (err, scrobbled) {
|
||||
if (err) {
|
||||
return console.error('[LastFM] An error occurred while scrobbling', err);
|
||||
}
|
||||
|
||||
console.log('[LastFM] Successfully scrobbled: ', scrobbled);
|
||||
});
|
||||
app.lastfm.cachedAttributes = attributes
|
||||
}
|
||||
} else {
|
||||
this.authenticate();
|
||||
}
|
||||
} else {
|
||||
return console.log('[LastFM] Did not add ', attributes.name , '-' , lfm.filterArtistName(attributes.artistName), 'because now playing a other song.');
|
||||
}
|
||||
},
|
||||
|
||||
filterArtistName: function (artist) {
|
||||
if (!app.cfg.get('lastfm.enabledRemoveFeaturingArtists')) return artist;
|
||||
|
||||
artist = artist.split(' ');
|
||||
if (artist.includes('&')) {
|
||||
artist.length = artist.indexOf('&');
|
||||
}
|
||||
if (artist.includes('and')) {
|
||||
artist.length = artist.indexOf('and');
|
||||
}
|
||||
artist = artist.join(' ');
|
||||
if (artist.includes(',')) {
|
||||
artist = artist.split(',')
|
||||
artist = artist[0]
|
||||
}
|
||||
return artist.charAt(0).toUpperCase() + artist.slice(1);
|
||||
},
|
||||
|
||||
updateNowPlayingSong: function (attributes) {
|
||||
if (!app.lastfm ||app.lastfm.cachedNowPlayingAttributes === attributes | !app.cfg.get('lastfm.NowPlaying')) {
|
||||
return
|
||||
}
|
||||
|
||||
if (app.lastfm.cachedNowPlayingAttributes) {
|
||||
if (app.lastfm.cachedNowPlayingAttributes.playParams.id === attributes.playParams.id) return;
|
||||
}
|
||||
|
||||
if (fs.existsSync(sessionPath)) {
|
||||
// update Now Playing
|
||||
if (attributes.status === true) {
|
||||
app.lastfm.track.updateNowPlaying({
|
||||
'artist': lfm.filterArtistName(attributes.artistName),
|
||||
'track': attributes.name,
|
||||
'album': attributes.albumName,
|
||||
'albumArtist': this.filterArtistName(attributes.artistName)
|
||||
}, function (err, nowPlaying) {
|
||||
if (err) {
|
||||
return console.error('[LastFM] An error occurred while updating nowPlayingSong', err);
|
||||
}
|
||||
|
||||
console.log('[LastFM] Successfully updated nowPlayingSong', nowPlaying);
|
||||
});
|
||||
app.lastfm.cachedNowPlayingAttributes = attributes
|
||||
}
|
||||
|
||||
} else {
|
||||
this.authenticate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = lfm;
|
Loading…
Add table
Add a link
Reference in a new issue