-
Notifications
You must be signed in to change notification settings - Fork 0
/
set-track-counts.js
executable file
·88 lines (78 loc) · 2.47 KB
/
set-track-counts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// https://github.com/sindresorhus/is-jxa/
const isJxa = () => {
try {
return (
typeof $ === 'function' &&
typeof Application === 'function' &&
typeof Application.currentApplication === 'function' &&
typeof ObjC === 'object' &&
typeof ObjC.import === 'function'
);
} catch (_) {
return false;
}
};
const isNode = typeof global !== 'undefined' && {}.toString.call(global) === '[object global]';
const isJest = typeof process !== 'undefined' && process.env.JEST_WORKER_ID !== undefined;
class SetTrackCounts {
constructor(music, decorate) {
this.music = music;
this.selection = this.music.selection();
decorate(this.selection);
}
sortSongs() {
this.selection.sort((a, b) => {
return (
a.get('artist').localeCompare(b.get('artist')) ||
a.get('album').localeCompare(b.get('album')) ||
a.get('year') - b.get('year') ||
a.get('discNumber') - b.get('discNumber') ||
a.get('trackNumber') - b.get('trackNumber')
);
});
}
updateTrackCounts(albumSongs) {
if (albumSongs.length > 1) {
const trackCount = albumSongs[albumSongs.length - 1].get('trackNumber');
albumSongs.forEach(song => song.set('trackCount', trackCount));
}
}
isSameAlbum(song, previousSong) {
return ['artist', 'album', 'year', 'discNumber'].every(attr => song.get(attr) === previousSong.get(attr));
}
run() {
this.sortSongs();
let currentAlbum = [this.selection[0]];
let previousSong = this.selection[0];
this.selection.slice(1).forEach(song => {
if (this.isSameAlbum(song, previousSong)) {
currentAlbum.push(song);
} else {
this.updateTrackCounts(currentAlbum);
currentAlbum = [song];
}
previousSong = song;
});
this.updateTrackCounts(currentAlbum);
}
}
if (isJxa()) {
const decorate = songs => {
songs.forEach(song => {
Object.defineProperty(song, 'get', {
value: field => eval(`song.${field}()`)
});
Object.defineProperty(song, 'set', {
value: (field, value) => eval(`song.${field}.set('${value}')`)
});
});
};
const setTrackCounts = new SetTrackCounts(Application('Music'), decorate);
setTrackCounts.run();
} else if (isNode) {
const { execSync } = require('child_process');
const shellEscape = cmd => cmd.replace(/(["\s'$`\\])/g, '\\$1');
execSync(`osascript -l JavaScript ${shellEscape(__filename)}`);
} else if (isJest) {
module.exports = SetTrackCounts;
}