* test

* fix multiroom

* attempt for fix rare cast bug

* changes for local files: read below

* added pouchdb-node
* moved all logic for local files to src/main/providers/local
* added new local library section on sidebar

* removed dupe

* added caching headers

* fix

* add path menu to settings-window

* fix mxm for local

* some test

* some fix

* clear this

* clear log

* add playlist folder class

* sometest

* fix

* Auto focus search bar

* use object instead of array for albums (#1219)

* feat: 🌐 Update French language (#1218)

* add pagination for library songs

* Add 'go to' page

* Make playlist search icon use hero color

* Merge pull request #1 from vapormusic/patch-1

dont populate out-of-display doms

* both infinite and paging

* Add color to search button background

* Add shadow to follow button

* im dumb sorry

* Add brightness effect of search button

* add some delay to scroll v-observe-visibility

* some multiroom fixes

* somefixes

* [Audio] Fix VBass & Added COCS

* [Audio] COCS revision

* some fix

* fix m1 mac

* fix m1 build

* some fix regarding audiocontext

* [Audio] Fix #1207 (discussions)

Eliminates audio stuttering even when AudioContext is enabled. Make lyrics account for the extra latency introduced by Audio Lab.

* idk what I did

* apparently this no worki

* should default to 0

* expose bitrate of localfiles

* [Audio] Added CAP & Normalization behavior for local files

* smh musickit

* Expose more local files metadata + fix norm error

* pokemon gotta catch them all

* maikiwi is a clown confirmed

* pokemon gotta catch them all v2

* pokemon gotta catch them all v5

* Update zh_TW.json (#1229)

Fix errors, update zh-TW translation.

* Change No Lyrics Message in Full Screen Player (#1210)

* Modify term.noLyrics text in 5 files

* Minor change in 3 files

* Colorize sponsor buttons in about page

Co-authored-by: ctaetcsh  <48845980+ctaetcsh@users.noreply.github.com>

* max size of more info panel dynamic

* Add twitter social button for some developers in about page (#1232)

* Big Chungus Window settings (#1230)

* Initial Changes

* I suposse this is the last

* cryptofyre

* Documentation

* Revert "Big Chungus Window settings (#1230)" (#1233)

This reverts commit e133b2c38b.

* test

* Just changed it and gonna leave for debugging

* reimp e133b2c, adjustments for macOS

* resolve #1

* copied files

* readded strings to en_US

* adjustments to settings sidebar collapse

* add multiplex

* Update version.sh

* Update style.css

* dont break pls thx

* swag

* I forgot that (#1239)

* Update zh_TW.json (#1236)

Update TW language.

* Update zh_CN.json (#1240)

* because I can

* Fix cider team buttons in about page

* Update style.less

* Float right looks better

* support custom port via optional CIDER_PORT var

* Scan Local Files now 46 times faster

* Update .gitignore

* cleanups

* remove console time (1s/1600 tracks)

* fix m1

* sometest

* Update build-macos.yml

* Fix absolutely unacceptable punctuation error (#1249)

* ok

* pray

* revert mxm back to local

* Update zh_CN.json (#1242)

* Update de_DE.json (#1246)

* Musixmatch fix (thx plank ily)

* whoops

* yes

* whoops v2

* bump to e18.3.5

* don't give the lyric api id if local files

* Update afterPack.js

* ukie

* Update afterPack.js

* Update afterPack.js

* how the fuck did this not throw an error

* fix stupid svg smh

* new mediaitem scaling method

* added Maximum Element Scale

* mediaitem square artwork res now adapts to window size

* will not affect high dpi

* fix now playing artwork

* fix album genre names

before: gets genre from 1st track
now: gets genre from album data

* clamped element scale to 1.5x

* added caching for auth

* adjustment to artist page

* changed to v-show for list item vis

* Bring back mxm lyrics (Fully tested)

* fix mmx translation

* fix settings view

* remove useless args & nonexistent funcs

* fix div hell

* fixed missing end tag for local playlist

* fix divs

* Fix cider list

* the amount of brain cells that I have lost because of mxm trans

* WIP language filter

* it was fun while it lasted, goodbye MXM languages

* MXM changes

* 4am code moments

* move logic

* fix lyrics translation & allow other lang

* default store.ts mxm trans to be disabled

* this is why you dont code at 4am

* and this is why you should test your code before pushing

* added Romanized langs to mxm trans

* love how previous MXM changes are in vain till now

* stop. uploading. this.

* NEVER. CODE. AT. FOUR. AYE. EM. AGAIN.

* test

* Revert "test"

This reverts commit 256d06bbcc.

* did a funny

* did another funny

* yes

* add prime symbol to apostrophe

* Don't do anything if res != 200

* Recursive Folder Search in Cider Utils

* 4am code moment

* fix function (force recompile utils)

* did a funny there

* I need sleep

* Update zh_CN.json (#1265)

This is a big work

* Update zh_TW.json (#1260)

Update TW language.

* performant logging is enabled by default

* test getting rid of lyriccurrenttime

* set timeout can go away now

* boops forgot this

* mxm moms

* mxm moms

* Revert "mxm moms"

This reverts commit 51fc09280e.

* README download link fix

* Update vueapp.js

* Fix settings menu (#1271)

* remove unused pages

* profile page (for search for now)

* lol

* updated recordLabel with i18n and root usage

* Local Lossless Icon and more

- add Cider-profile boilerplate
- add local lossless icon
-add hover for PPE and lossless

Co-authored-by: Core <coredev-uk@users.noreply.github.com>

* no coding at 4am

* fix units for local lossless badge

* fix units for local lossless badge

* remove CAP icon for local files, cuz unsupported

* mpris overhaul

* Fix seeking in mpris

* changed am section on sidebar to v-show allowing css manipulation

* added class for css

* new effect when entering fullscreen lyrics

* fixes text wrapping on tab text

* added is-album

* linux is cooollll

* Lyrics API migration

* Update musickit to use api mirror by default

* add div for app-playback-buttons

* Add spatialization icon (#1276)

* Add spatialization icon

* that never happened

* add checkmode func to webremote

* whoops sorry

* Updated config.yml

* mogus

* fix string matching

* may Maikiwi bless your CI

* MKV3 red

* Go touch grass;

* this was so unreadable lmao

* add logic for showing spatialization icon

* add space in lossless icon

* Remove dead fallback token, add error log if capi call fails (#1289)

I tested and the fallback key you are using is dead. 401s. Unusable.

* Fix #1282

* Fix #1237

* fix default CAP

* someone played with translation code

* lmao yaz why

* stop polluting my logs you lil POST

* I18n (#1293)

* Update es_ES

* I18N

* idk this only breaking now

* added framework for c2 parity

* fixes

* Fix volume bar on miniplayer (#1297)

* Update stale-issues.yml

* removed loading bar, testing without hlscider

* overwrite restriction

* allow listennow "more like" nav to work

* garbage gone

* fix for primary-content linking

* Update README.md

Add QQ group info

* Revert back to music metadata

* gimp v2

* remove local files as experiment

* just to be safe

* world is now a better place

* meltdown avoided

* meltdown avoided

* Revert "meltdown avoided"

This reverts commit 38e6f1b7fa.

* Revert "meltdown avoided"

This reverts commit 54cc6656d6.

* Revert "world is now a better place"

This reverts commit c019bf9c63.

* remove quasar

* add some shiz (#1313)

* Update ru_RU.json

keeping russian lang actual

* ok

* Add gradient to lyric-footer

* *Commit en español Ñ (#1304)

* i hate my life (#1307)

* world is now a better place

* meltdown avoided

* meltdown avoided

* stylize new listen now childs

* full scale artwork, finally

* dynamic width for search categories

* hd all album work

* Update afterPack.js

* force hq quality

* oops

* attempt to fix

* misc cleanup

* why what

* what was i thinking

* fix duplicated text in listen now childs

* Paginate/infinite scroll for  albums, playlists (#1234)

* Infinite scroll, pagination to album, playlists

* move pagination below tracks

* Make page size configurable

* remove renderer

* Mitigate songs / album slow app issue.

* add ratings, library change to web remote (#1285)

* Add compact artist header option (#1308)

* Support compact artist header (optional)

* Add required term

Co-authored-by: h0ckerman <35598335+h0ckerman@users.noreply.github.com>
Co-authored-by: vapormusic <vietanhfat@gmail.com>
Co-authored-by: Monochromish <chillygamer7@gmail.com>
Co-authored-by: Gabriel Davila <56521591+mefsaal@users.noreply.github.com>
Co-authored-by: Core <64542347+coredev-uk@users.noreply.github.com>
Co-authored-by: Maikiwi <stella@mai.kiwi>
Co-authored-by: yazninja <yazlesean@gmail.com>
Co-authored-by: booploops <49113086+booploops@users.noreply.github.com>
Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
Co-authored-by: Pedro Galhardo <pgalhardo@icloud.com>

* obama (#1314)

* Update ru_RU.json

keeping russian lang actual

* ok

* Add gradient to lyric-footer

* *Commit en español Ñ (#1304)

* i hate my life (#1307)

* world is now a better place

* meltdown avoided

* meltdown avoided

* stylize new listen now childs

* full scale artwork, finally

* dynamic width for search categories

* hd all album work

* Update afterPack.js

* force hq quality

* oops

* attempt to fix

* misc cleanup

* why what

* what was i thinking

* fix duplicated text in listen now childs

* Paginate/infinite scroll for  albums, playlists (#1234)

* Infinite scroll, pagination to album, playlists

* move pagination below tracks

* Make page size configurable

* remove renderer

* Mitigate songs / album slow app issue.

* add ratings, library change to web remote (#1285)

* Add compact artist header option (#1308)

* Support compact artist header (optional)

* Add required term

* improve pagination styling

Co-authored-by: h0ckerman <35598335+h0ckerman@users.noreply.github.com>
Co-authored-by: vapormusic <vietanhfat@gmail.com>
Co-authored-by: Monochromish <chillygamer7@gmail.com>
Co-authored-by: Gabriel Davila <56521591+mefsaal@users.noreply.github.com>
Co-authored-by: Core <64542347+coredev-uk@users.noreply.github.com>
Co-authored-by: Maikiwi <stella@mai.kiwi>
Co-authored-by: yazninja <yazlesean@gmail.com>
Co-authored-by: booploops <49113086+booploops@users.noreply.github.com>
Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
Co-authored-by: Pedro Galhardo <pgalhardo@icloud.com>
Co-authored-by: yazninja <71800112+yazninja@users.noreply.github.com>

* obama episode 2. (#1317)

* Update ru_RU.json

keeping russian lang actual

* ok

* Add gradient to lyric-footer

* *Commit en español Ñ (#1304)

* i hate my life (#1307)

* world is now a better place

* meltdown avoided

* meltdown avoided

* stylize new listen now childs

* full scale artwork, finally

* dynamic width for search categories

* hd all album work

* Update afterPack.js

* force hq quality

* oops

* attempt to fix

* misc cleanup

* why what

* what was i thinking

* fix duplicated text in listen now childs

* Paginate/infinite scroll for  albums, playlists (#1234)

* Infinite scroll, pagination to album, playlists

* move pagination below tracks

* Make page size configurable

* remove renderer

* Mitigate songs / album slow app issue.

* add ratings, library change to web remote (#1285)

* Add compact artist header option (#1308)

* Support compact artist header (optional)

* Add required term

* improve pagination styling

* Disable Fullscreen view when artist/album name is clicked. (#1315)

* Disable Fullscreen view when artist/album name is clicked.

idk why this change didn't exist

* Seperate dash from album name

* Replace `$root.showSearch()` with `app.appRoute('search')`

`$root.showSearch()` prevents going back to previous page from sidebar.

* Fix Anim (#1316)

Co-authored-by: h0ckerman <35598335+h0ckerman@users.noreply.github.com>
Co-authored-by: vapormusic <vietanhfat@gmail.com>
Co-authored-by: Monochromish <chillygamer7@gmail.com>
Co-authored-by: Gabriel Davila <56521591+mefsaal@users.noreply.github.com>
Co-authored-by: Core <64542347+coredev-uk@users.noreply.github.com>
Co-authored-by: Maikiwi <stella@mai.kiwi>
Co-authored-by: yazninja <yazlesean@gmail.com>
Co-authored-by: booploops <49113086+booploops@users.noreply.github.com>
Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
Co-authored-by: Pedro Galhardo <pgalhardo@icloud.com>
Co-authored-by: Monochromish <79590499+Monochromish@users.noreply.github.com>

* re add that i guess. github is fucked.

* aa (#1320)

* Update ru_RU.json

keeping russian lang actual

* ok

* Add gradient to lyric-footer

* *Commit en español Ñ (#1304)

* i hate my life (#1307)

* world is now a better place

* meltdown avoided

* meltdown avoided

* stylize new listen now childs

* full scale artwork, finally

* dynamic width for search categories

* hd all album work

* Update afterPack.js

* force hq quality

* oops

* attempt to fix

* misc cleanup

* why what

* what was i thinking

* fix duplicated text in listen now childs

* Paginate/infinite scroll for  albums, playlists (#1234)

* Infinite scroll, pagination to album, playlists

* move pagination below tracks

* Make page size configurable

* remove renderer

* Mitigate songs / album slow app issue.

* add ratings, library change to web remote (#1285)

* Add compact artist header option (#1308)

* Support compact artist header (optional)

* Add required term

* improve pagination styling

* Disable Fullscreen view when artist/album name is clicked. (#1315)

* Disable Fullscreen view when artist/album name is clicked.

idk why this change didn't exist

* Seperate dash from album name

* Replace `$root.showSearch()` with `app.appRoute('search')`

`$root.showSearch()` prevents going back to previous page from sidebar.

* Fix Anim (#1316)

* make tracks tab active (#1318)

* welp that wasn't it.

* Thnks (#1319)

* Thnks

* i need sleep

Co-authored-by: h0ckerman <35598335+h0ckerman@users.noreply.github.com>
Co-authored-by: vapormusic <vietanhfat@gmail.com>
Co-authored-by: Monochromish <chillygamer7@gmail.com>
Co-authored-by: Gabriel Davila <56521591+mefsaal@users.noreply.github.com>
Co-authored-by: Core <64542347+coredev-uk@users.noreply.github.com>
Co-authored-by: Maikiwi <stella@mai.kiwi>
Co-authored-by: yazninja <yazlesean@gmail.com>
Co-authored-by: booploops <49113086+booploops@users.noreply.github.com>
Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
Co-authored-by: Pedro Galhardo <pgalhardo@icloud.com>
Co-authored-by: Monochromish <79590499+Monochromish@users.noreply.github.com>

Co-authored-by: vapormusic <vietanhfat@gmail.com>
Co-authored-by: booploops <49113086+booploops@users.noreply.github.com>
Co-authored-by: yazninja <yazlesean@gmail.com>
Co-authored-by: Pedro Galhardo <pedromgalhardo@tecnico.ulisboa.pt>
Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
Co-authored-by: Erwan <24718500+ErwanGit@users.noreply.github.com>
Co-authored-by: Monochromish <chillygamer7@gmail.com>
Co-authored-by: maikirakiwi <stella@mai.kiwi>
Co-authored-by: yazninja <71800112+yazninja@users.noreply.github.com>
Co-authored-by: 宥叡 <46503943+jay900604@users.noreply.github.com>
Co-authored-by: Nathan Ritchie <48845980+ctaetcsh@users.noreply.github.com>
Co-authored-by: Monochromish <79590499+Monochromish@users.noreply.github.com>
Co-authored-by: Gabriel Davila <56521591+mefsaal@users.noreply.github.com>
Co-authored-by: Core <64542347+coredev-uk@users.noreply.github.com>
Co-authored-by: 椎名アヤネ <53814845+sakura0224@users.noreply.github.com>
Co-authored-by: Jonathan Fenske <929220+jfenske89@users.noreply.github.com>
Co-authored-by: UnbreakCode <unbreakcode@gmail.com>
Co-authored-by: SoNothing <git@sonothing.com>
Co-authored-by: Core <coredev-uk@users.noreply.github.com>
Co-authored-by: Amaru8 <52407090+Amaru8@users.noreply.github.com>
Co-authored-by: rlaphoenix <pragma.exe@gmail.com>
Co-authored-by: h0ckerman <35598335+h0ckerman@users.noreply.github.com>
Co-authored-by: Pedro Galhardo <pgalhardo@icloud.com>
This commit is contained in:
cryptofyre 2022-07-27 01:05:51 -05:00 committed by GitHub
parent 57b2a86913
commit c03f408ba5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
157 changed files with 33489 additions and 10407 deletions

View file

@ -1,278 +1,236 @@
import * as electron from 'electron';
import * as fs from 'fs';
import {resolve} from 'path';
export default class lastfm {
export default class LastFMPlugin {
private sessionPath = resolve(electron.app.getPath('userData'), 'session.json');
private apiCredentials = {
/**
* Base Plugin Information
*/
public name: string = 'LastFM Plugin';
public version: string = '2.0.0';
public author: string = 'Core (Cider Collective)';
private _apiCredentials = {
key: "f9986d12aab5a0fe66193c559435ede3",
secret: "acba3c29bd5973efa38cc2f0b63cc625"
}
/**
* Private variables for interaction in plugins
* Plugin Initialization
*/
private _win: any;
private _app: any;
private _lastfm: any;
private _store: any;
private _timer: any;
private authenticateFromFile() {
let sessionData = require(this.sessionPath)
console.log("[LastFM][authenticateFromFile] Logging in with Session Info.")
this._lastfm.setSessionCredentials(sessionData.username, sessionData.key)
console.log("[LastFM][authenticateFromFile] Logged in.", sessionData.username, sessionData.key)
}
authenticate() {
try {
if (this._store.lastfm.auth_token) {
this._store.lastfm.enabled = true;
}
if (!this._store.lastfm.enabled || !this._store.lastfm.auth_token) {
this._store.lastfm.enabled = false;
return
}
/// dont move this require to top , app wont load
const LastfmAPI = require('lastfmapi');
const lfmAPI = new LastfmAPI({
'api_key': this.apiCredentials.key,
'secret': this.apiCredentials.secret
});
this._lastfm = Object.assign(lfmAPI, {cachedAttributes: false, cachedNowPlayingAttributes: false});
fs.stat(this.sessionPath, (err: any) => {
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")
console.log("[LastFM][tk]", this._store.lastfm.auth_token)
this._lastfm.authenticate(this._store.lastfm.auth_token, (err: any, session: any) => {
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(this.sessionPath, tempData, (err: any) => {
if (err)
console.log("[LastFM][fs]", err)
else {
console.log("[LastFM][fs] File was written successfully.")
this.authenticateFromFile()
new electron.Notification({
title: electron.app.getName(),
body: "Successfully logged into LastFM using Authentication Key."
}).show()
}
})
});
} else {
this.authenticateFromFile()
}
})
} catch (err) {
console.log(err)
}
}
private scrobbleSong(attributes: any) {
if (this._timer) clearTimeout(this._timer);
var self = this;
this._timer = setTimeout(async () => {
const currentAttributes = attributes;
if (!self._lastfm || self._lastfm.cachedAttributes === attributes) {
return
}
if (self._lastfm.cachedAttributes) {
if (self._lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return;
}
const artist = await this.getPrimaryArtist(attributes)
const album = this.getAlbumName(attributes)
if (currentAttributes.status && currentAttributes === attributes) {
if (fs.existsSync(this.sessionPath)) {
// Scrobble playing song.
if (attributes.status === true) {
self._lastfm.track.scrobble({
'artist': artist,
'track': attributes.name,
'album': album,
'albumArtist': artist,
'timestamp': new Date().getTime() / 1000
}, function (err: any, scrobbled: any) {
if (err) {
return console.error('[LastFM] An error occurred while scrobbling', err);
}
console.log('[LastFM] Successfully scrobbled: ', scrobbled);
});
self._lastfm.cachedAttributes = attributes
}
} else {
self.authenticate();
}
} else {
return console.log('[LastFM] Did not add ', attributes.name, '—', artist, 'because now playing a other song.');
}
}, Math.round(attributes.durationInMillis * Math.min((self._store.lastfm.scrobble_after / 100), 0.8)));
}
private async updateNowPlayingSong(attributes: any) {
if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._store.lastfm.NowPlaying) {
return
}
if (this._lastfm.cachedNowPlayingAttributes) {
if (this._lastfm.cachedNowPlayingAttributes.playParams.id === attributes.playParams.id) return;
}
if (fs.existsSync(this.sessionPath)) {
const artist = await this.getPrimaryArtist(attributes)
const album = this.getAlbumName(attributes)
// update Now Playing
if (attributes.status === true) {
this._lastfm.track.updateNowPlaying({
'artist': artist,
'track': attributes.name,
'album': album,
'albumArtist': artist
}, function (err: any, nowPlaying: any) {
if (err) {
return console.error('[LastFM] An error occurred while updating nowPlayingSong', err);
}
console.log('[LastFM] Successfully updated nowPlayingSong', nowPlaying);
});
this._lastfm.cachedNowPlayingAttributes = attributes
}
} else {
this.authenticate()
}
}
private getAlbumName(attributes: any): string {
return attributes.albumName.replace(/ - Single| - EP/g, '');
}
private async getPrimaryArtist(attributes: any) {
const songId = attributes.playParams.catalogId || attributes.playParams.id
if (!this._store.lastfm.enabledRemoveFeaturingArtists || !songId) return attributes.artistName;
const res = await this._win.webContents.executeJavaScript(`
(async () => {
const subMk = await MusicKit.getInstance().api.v3.music("/v1/catalog/" + MusicKit.getInstance().storefrontId + "/songs/${songId}", {
include: {
songs: ["artists"]
}
})
if (!subMk) console.error('[LastFM] Request failed: /v1/catalog/us/songs/${songId}')
return subMk.data
})()
`).catch(console.error)
if (!res) return attributes.artistName
const data = res.data
if (!data.length) {
console.error(`[LastFM] Unable to locate song with id of ${songId}`)
return attributes.artistName;
}
const artists = res.data[0].relationships.artists.data
if (!artists.length) {
console.error(`[LastFM] Unable to find artists related to the song with id of ${songId}`)
return attributes.artistName;
}
const primaryArtist = artists[0]
return primaryArtist.attributes.name
}
private _lfm: any = null;
private _authenticated: boolean = false;
private _scrobbleDelay: any = null;
private _utils: any = null;
private _scrobbleCache: any = {};
private _nowPlayingCache: any = {};
/**
* Base Plugin Details (Eventually implemented into a GUI in settings)
* Public Methods
*/
public name: string = 'LastFMPlugin';
public description: string = 'LastFM plugin for Cider';
public version: string = '0.0.1';
public author: string = 'vapormusic / Cider Collective';
/**
* Runs on plugin load (Currently run on application start)
*/
constructor(utils: { getApp: () => any; getStore: () => any; }) {
this._app = utils.getApp();
this._store = utils.getStore()
utils.getApp().on('second-instance', (_e: any, argv: any) => {
// Checks if first instance is authorized and if second instance has protocol args
argv.forEach((value: any) => {
if (value.includes('auth')) {
console.log('[LastFMPlugin ok]')
let authURI = String(argv).split('/auth/')[1];
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
const authKey = authURI.split('lastfm?token=')[1];
this._store.lastfm.enabled = true;
this._store.lastfm.auth_token = authKey;
console.log(authKey);
this._win.webContents.send('LastfmAuthenticated', authKey);
this.authenticate();
}
}
})
constructor(utils: any) {
this._utils = utils;
}
onReady(_win: Electron.BrowserWindow): void {
this.initializeLastFM("", this._apiCredentials)
// Register the ipcMain handlers
this._utils.getIPCMain().handle('lastfm:url', (event: any) => {
console.debug(`[${lastfm.name}:url] Called.`)
return this._lfm.getAuthenticationUrl({"cb": "cider://auth/lastfm"})
})
electron.app.on('open-url', (event: any, arg: any) => {
console.log('[LastFMPlugin] yes')
event.preventDefault();
if (arg.includes('auth')) {
let authURI = String(arg).split('/auth/')[1];
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
const authKey = authURI.split('lastfm?token=')[1];
this._store.lastfm.enabled = true;
this._store.lastfm.auth_token = authKey;
this._win.webContents.send('LastfmAuthenticated', authKey);
console.log(authKey);
this.authenticate();
}
}
this._utils.getIPCMain().on('lastfm:auth', (event: any, token: string) => {
console.debug(`[${lastfm.name}:auth] Token: `, token)
this.authenticateLastFM(token)
})
this._utils.getIPCMain().on('lastfm:disconnect', (_event: any) => {
this._lfm.setSessionCredentials(null, null);
this._authenticated = false;
console.debug(`[${lastfm.name}:disconnect] Disconnected`)
})
this._utils.getIPCMain().on('lastfm:nowPlayingChange', (event: any, attributes: any) => {
if (this._utils.getStoreValue("connectivity.lastfm.filter_loop") || this._utils.getStoreValue("general.privateEnabled")) return;
this.updateNowPlayingTrack(attributes)
})
this._utils.getIPCMain().on('lastfm:scrobbleTrack', (event: any, attributes: any) => {
if (this._utils.getStoreValue("general.privateEnabled")) return;
this.scrobbleTrack(attributes)
})
}
/**
* Runs on app ready
* Runs on playback State Change
* @param attributes Music Attributes (attributes.status = current state)
*/
onReady(win: any): void {
this._win = win;
this.authenticate();
}
/**
* Runs on app stop
*/
onBeforeQuit(): void {
console.log('Example plugin stopped');
onPlaybackStateDidChange(attributes: object): void {
}
/**
* Runs on song change
* @param attributes Music Attributes
* @param scrobble
*/
nowPlayingItemDidChangeLastFM(attributes: any): void {
if (!this._store.general.privateEnabled) {
attributes.status = true
if (!this._store.lastfm.filterLoop) {
this._lastfm.cachedNowPlayingAttributes = false;
this._lastfm.cachedAttributes = false
}
this.updateNowPlayingSong(attributes)
this.scrobbleSong(attributes)
onNowPlayingItemDidChange(attributes: any, scrobble = false): void {
if (this._utils.getStoreValue("general.privateEnabled")) return;
this.updateNowPlayingTrack(attributes)
}
/**
* Initialize LastFM
* @param token
* @param api
* @private
*/
private initializeLastFM(token: string, api: { key: string, secret: string }): void {
console.debug(`[${lastfm.name}:initialize] Initializing LastFM`)
const LastfmAPI = require("lastfmapi")
this._lfm = new LastfmAPI({
'api_key': api.key,
'secret': api.secret,
});
if (this._utils.getStoreValue("connectivity.lastfm.secrets.username") && this._utils.getStoreValue("connectivity.lastfm.secrets.key")) {
this._lfm.setSessionCredentials(this._utils.getStoreValue("connectivity.lastfm.secrets.username"), this._utils.getStoreValue("connectivity.lastfm.secrets.key"));
this._authenticated = true;
} else {
this.authenticateLastFM(token)
}
}
}
/**
* Authenticate the user with the given token
* @param token
* @private
*/
private authenticateLastFM(token: string): void {
if (!token) return;
this._lfm.authenticate(token, (err: any, session: any) => {
if (err) {
console.error(`[${lastfm.name}:authenticate] Error: ${typeof err === "string" ? err : err.message}`);
this._utils.getWindow().webContents.executeJavaScript(`app.notyf.error("${err.message}");`)
return;
}
this._utils.getWindow().webContents.send('lastfm:authenticated', session)
this._authenticated = true;
console.debug(`[${lastfm.name}:authenticate] Authenticated as ${session.username}`)
});
}
/**
* Verifies the track information with lastfm
* @param attributes
* @param callback
* @private
*/
private verifyTrack(attributes: any, callback: Function): void {
if (!attributes) return attributes;
if (!attributes.lfmAlbum) {
this._lfm.album.getInfo({
"artist": attributes.artistName,
"album": attributes.albumName
}, (err: any, data: any) => {
if (err) {
console.error(`[${lastfm.name}] [album.getInfo] Error: ${typeof err === "string" ? err : err.message}`)
return {};
}
if (data) {
attributes.lfmAlbum = data
callback(attributes)
}
})
} else {
this._lfm.track.getCorrection(attributes.artistName, attributes.name, (err: any, data: any) => {
if (err) {
console.error(`[${lastfm.name}] [track.getCorrection] Error: ${typeof err === "string" ? err : err.message}`)
return {};
}
if (data) {
attributes.lfmTrack = data.correction.track
callback(attributes)
}
})
}
}
/**
* Scrobbles the track to lastfm
* @param attributes
* @private
*/
private scrobbleTrack(attributes: any): void {
if (!attributes?.lfmTrack || !attributes?.lfmAlbum) {
this.verifyTrack(attributes, (a: any) => {
this.scrobbleTrack(a)
})
return
}
if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._scrobbleCache.track === attributes.lfmTrack.name)) return;
// Scrobble
const scrobble = {
'artist': attributes.lfmTrack.artist.name,
'track': attributes.lfmTrack.name,
'album': attributes.lfmAlbum.name,
'albumArtist': attributes.lfmAlbum.artist,
'timestamp': new Date().getTime() / 1000,
'trackNumber': attributes.trackNumber,
'duration': attributes.durationInMillis / 1000,
}
// Easy Debugging
console.debug(`[${lastfm.name}:scrobble] Scrobbling ${scrobble.artist} - ${scrobble.track}`)
// Scrobble the track
this._lfm.track.scrobble(scrobble, (err: any, _res: any) => {
if (err) {
console.error(`[${lastfm.name}:scrobble] Scrobble failed: ${err.message}`);
} else {
console.debug(`[${lastfm.name}:scrobble] Track scrobbled: ${scrobble.artist} - ${scrobble.track}`);
this._scrobbleCache = scrobble
}
});
}
/**
* Updates the now playing track
* @param attributes
* @private
*/
private updateNowPlayingTrack(attributes: any): void {
if (!attributes?.lfmTrack || !attributes?.lfmAlbum) {
this.verifyTrack(attributes, (a: any) => {
this.updateNowPlayingTrack(a)
})
return
}
if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._nowPlayingCache.track === attributes.lfmTrack.name)) return;
const nowPlaying = {
'artist': attributes.lfmTrack.artist.name,
'track': attributes.lfmTrack.name,
'album': attributes.lfmAlbum.name,
'trackNumber': attributes.trackNumber,
'duration': attributes.durationInMillis / 1000,
'albumArtist': attributes.lfmAlbum.artist,
}
this._lfm.track.updateNowPlaying(nowPlaying, (err: any, res: any) => {
if (err) {
console.error(`[${lastfm.name}:updateNowPlaying] Now Playing Update failed: ${err.message}`);
} else {
console.debug(`[${lastfm.name}:updateNowPlaying] Now Playing Updated: ${nowPlaying.artist} - ${nowPlaying.track}`);
this._nowPlayingCache = nowPlaying
}
});
}
}