Skip to content
This repository has been archived by the owner on May 1, 2020. It is now read-only.

Commit

Permalink
Quotation marks fix
Browse files Browse the repository at this point in the history
The app had troubles parsing JSON when song's title/artist's name contained quotation marks. Closed #5 .
  • Loading branch information
yungtry committed Jul 17, 2019
1 parent c24d9dc commit 34b3b6d
Show file tree
Hide file tree
Showing 7 changed files with 3,367 additions and 71 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
node_modules/
*.DS_Store*
CatalinaScrobbler-darwin-x64/
CatalinaScrobbler-cli

# Logs
logs
Expand Down
154 changes: 154 additions & 0 deletions CatalinaScrobbler-cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
const fs = require('fs');
var osascript = require('node-osascript');

osascript.execute(`try
tell application "Finder" to get application file id "com.apple.Music"
set appExists to true
on error
set appExists to false
end try
return appExists`, function(err, result) {
if (result == true) {
var app = "Music";
} else if (result == false) {
var app = "iTunes"
} else { // Just in case something does not work.
var app = "Music";
}
fs.writeFile("/tmp/CurrentPlaying.scpt", `on run
set info to ""
tell application id "com.apple.systemevents"
set num to count (every process whose bundle identifier is "com.apple.` + app + `")
end tell
if num > 0 then
tell application id "com.apple.` + app + `"
if player state is playing then
set track_name to name of current track
set track_artist to the artist of the current track
set track_album to the album of the current track
end if
end tell
end if
return "{\\"artist\\":\\"" & track_artist & "\\", \\"track\\":\\"" & track_name & "\\", \\"album\\":\\"" & track_album & "\\"}"
end run`, function(err) {
if (err) {
return log(err);
}
});
});

var LastfmAPI = require('lastfmapi');
var Lastfm = require('simple-lastfm');
const { exec } = require('child_process');
var Prompt = require('prompt-password');
var readline = require('readline');
const dJSON = require('dirty-json');

global.timeline = 0
global.songCount = 0;

var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.stdoutMuted = true;
rl.question('Login: ', (login) => {
var prompt = new Prompt({
type: 'password',
message: 'Password: ',
name: 'password'
});
prompt.run()
.then(function(password) {
lastFMLogin(login, password);
rl.close();
});
});

function lastFMLogin(login, pass){
var lfm = new LastfmAPI({
'api_key' : '21779adaae15c5fa727a08cd75909df2',
'secret' : '8e2cfe09e0aac01bdc8474c2595d5e68'
});
var lastfm = new Lastfm({
api_key: '21779adaae15c5fa727a08cd75909df2',
api_secret: '8e2cfe09e0aac01bdc8474c2595d5e68',
username: login,
password: pass
});
lastfm.getSessionKey(function(result) {
//console.log("session key = " + result.session_key);
if(result.success) {
lfm.setSessionCredentials(login, result.session_key);
update(lfm);
} else {
console.log("Error: " + result.error);
}
});
}

function update(lfm) {

setInterval(function(){
console.log("==============================");
global.timeline += 1;
console.log("Loop: "+global.timeline);
exec('osascript /tmp/CurrentPlaying.scpt', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
console.log("Is music playing?")
global.timeline -= 1; //pause cause not playing anything
return;
}
console.log(`Now Playing: ${stdout}`);
//console.log(`stderr: ${stderr}`);
var obj = dJSON.parse(stdout);

if (stdout != undefined && stdout != global.playing){
//song changed
global.previousTime = global.timeline;
global.timeline = 0;
global.songCount += 1;
global.previous = global.playing;
console.log("SongCount: "+global.songCount);
if (global.songCount > 1){
console.log("Scrobble Previous");
console.log("Previous: "+global.previous);
var previousSong = dJSON.parse(global.previous);
if (global.previousTime > 12){ //if listened for more than 60 seconds
lfm.track.scrobble({
'artist' : previousSong.artist,
'track' : previousSong.track,
'timestamp' : Math.floor(Date.now() / 1000)
}, function (err, scrobbles) {
if (err) { return console.log('We\'re in trouble', err); }

console.log('We have just scrobbled:', scrobbles);
});
}
global.playing = stdout;
}
else {
//first run not scrobbling
global.playing = stdout;
}
}

if (stdout != undefined){
lfm.track.updateNowPlaying({
'artist' : obj.artist,
'track' : obj.track,
'album' : obj.album

}, function(err, nowPlaying){
console.log(nowPlaying);
})
}
});
}, 5000);
}

process.on('SIGINT', function() {
console.log("Caught interrupt signal");
process.exit();
});
16 changes: 5 additions & 11 deletions CatalinaScrobbler.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
var osascript = require('node-osascript');
const {
app,
Menu,
Tray
} = require('electron');
const {app,Menu,Tray} = require('electron');
const fs = require('fs');
const dJSON = require('dirty-json'); //Applescript which I made below has trouble generating proper JSON.
const open = require('open');

app.on('ready', () => {
Expand All @@ -20,7 +17,6 @@ app.on('ready', () => {
});
});
let tray = null
//defaults read -g AppleInterfaceStyle
tray = new Tray(__dirname + '/assets/icons/trayTemplate.png')
if (global.artist === undefined) {
var state = "Paused";
Expand Down Expand Up @@ -52,7 +48,7 @@ return appExists`, function(err, result) {
var app = "Music";
} else if (result == false) {
var app = "iTunes"
} else { //just in case something does not work
} else { // Just in case something does not work.
var app = "Music";
}
log("App detected: " + app);
Expand Down Expand Up @@ -99,7 +95,6 @@ return appExists`, function(err, result) {
password: pass
});
lastfm.getSessionKey(function(result) {
//log("session key = " + result.session_key);
if (result.success) {
lfm.setSessionCredentials(login, result.session_key);
update(lfm);
Expand All @@ -121,12 +116,11 @@ return appExists`, function(err, result) {
log("Is music playing?")

global.timeline -= 1; //pause cause not playing anything
//global.songCount = 0; //scrobble reset
return;
}
log(`Now Playing: ${stdout}`);
//log(`stderr: ${stderr}`);
var obj = JSON.parse(stdout);
var obj = dJSON.parse(stdout);

if (stdout != undefined && stdout != global.playing) {
//song changed
Expand Down Expand Up @@ -154,7 +148,7 @@ return appExists`, function(err, result) {
log("SongCount: " + global.songCount);
if (global.songCount > 1) {
log("Previous: " + global.previous);
var previousSong = JSON.parse(global.previous);
var previousSong = dJSON.parse(global.previous);
if (global.previousTime > 12) { //if listened for more than 60 seconds
log("Scrobble Previous");
lfm.track.scrobble({
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@
3. Login to your account and start scrobbling

### Manual
#### GUI
1. Clone the repository
2. ```npm install```
3. ```npm i electron -g```
4. ```electron CatalinaScrobbler.js```
5. (Optional) Convert it to an executable using electron-packager ```npm i electron-packager -g``` and then ```sh scripts/build.sh```

#### CLI
1. Clone the repository
2. ```npm install```
3. ```node CatalinaScrobbler-cli.js```
4. (Optional) Convert it to an executable using nexe ```npm i nexe -g``` and then ```sh scripts/build-cli.sh```

## 🐛 Bugs and issues
This repository consists of lot of bugs and issues and its code is ugly. I will try to maintain it for as longer as there is no other alternative.

Expand Down
Loading

0 comments on commit 34b3b6d

Please # to comment.