]> git.r.bdr.sh - rbdr/netnewswire-to-apple-music/blob - netnewswire_to_apple_music.scpt
6bc4a6772bef815e6cf69d47d0bd27ffb0a8c62a
[rbdr/netnewswire-to-apple-music] / netnewswire_to_apple_music.scpt
1 JsOsaDAS1.001.00bplist00Ñ\ 1\ 2Vscript_\11\12dconst internals = {
2
3 /**
4 * Config. In most of the cases, you'll only have to modify values here.
5 */
6 config: {
7
8 /**
9 * Set this to the name of the account you wish to use. Only supports feeds in the same account.
10 */
11 account: "iCloud",
12
13 /**
14 * Set this to your music folder. Only supports feeds in the same folder.
15 */
16 musicFolder: "155 - music",
17
18 /**
19 * Set this to false to do an "initial import" of all your read files.
20 */
21 onlyUnread: true
22 },
23 kURLParser: /https?:\/\/[^\s'"><]+/gi,
24
25 strategies: [
26 // youtube embed
27 {
28 kMatcher: /youtube.com\/embed\/([^?]+)/,
29 canHandle(url) {
30 return url.match(this.kMatcher);
31 },
32 handle(url) {
33 return 'youtube_embed:' + url.match(this.kMatcher)[1];
34 }
35 },
36 // youtube video
37 {
38 kMatcher: /youtube.com\/watch.*v=([^&]+)/,
39 canHandle(url) {
40 return url.match(this.kMatcher);
41 },
42 handle(url) {
43 return 'youtube_video:' + url.match(this.kMatcher)[1];
44 }
45 },
46 // youtube playlist
47 {
48 kMatcher: /youtube.com\/playlist.*list=([^&]+)/,
49 canHandle(url) {
50 return url.match(this.kMatcher);
51 },
52 handle(url) {
53 return 'youtube_playlist:' + url.match(this.kMatcher)[1];
54 }
55 },
56 // youtube unmatched
57 {
58 canHandle(url) {
59 return url.match(/youtube/);
60 },
61 handle(url) {
62 return '!!!!!!!!!!!!!!!!!:' + url
63 }
64 },
65 // bandcamp embedded track
66 {
67 kMatcher: /bandcamp.*EmbeddedPlayer.*track=([0-9]+)/,
68 canHandle(url) {
69 return url.match(this.kMatcher);
70 },
71 handle(url) {
72 return 'bc_embed_track:' + url.match(this.kMatcher)[1];
73 }
74 },
75 // bandcamp embedded album
76 {
77 kMatcher: /bandcamp.*EmbeddedPlayer.*album=([0-9]+)/,
78 canHandle(url) {
79 return url.match(this.kMatcher);
80 },
81 handle(url) {
82 return 'bc_embed_album:' + url.match(this.kMatcher)[1];
83 }
84 },
85 // bandcamp album
86 {
87 canHandle(url) {
88 return url.match(/https?:\/\/([^.]+)\.bandcamp\.com\/album/);
89 },
90 handle(url) {
91 return 'bc_album:' + url
92 }
93 },
94 // bandcamp album
95 {
96 canHandle(url) {
97 return url.match(/https?:\/\/([^.]+)\.bandcamp\.com\/track/);
98 },
99 handle(url) {
100 return 'bc_track:' + url
101 }
102 },
103 // bandcamp artist
104 {
105 kMatcher: /https?:\/\/([^.]+)\.bandcamp.com(?:\/music)?/,
106 canHandle(url) {
107 return url.match(this.kMatcher);
108 },
109 handle(url) {
110 return 'bc_artist:' + url.match(this.kMatcher)[1];
111 }
112 },
113 // bandcamp unmatched
114 {
115 canHandle(url) {
116 return url.match(/bandcamp\.com/);
117 },
118 handle(url) {
119 return '!!!!!!!!!!!!!!!!!:' + url
120 }
121 },
122 // soundcloud player
123 {
124 kMatcher: /soundcloud.com\/player.*tracks%2F([^&]+)/,
125 canHandle(url) {
126 return url.match(this.kMatcher);
127 },
128 handle(url) {
129 return 'sc_player: ' + url.match(this.kMatcher)[1]
130 }
131 },
132 // soundcloud track
133 {
134 kMatcher: /soundcloud.com\/([^\/]+)\/([^\/]+)/,
135 canHandle(url) {
136 return url.match(this.kMatcher);
137 },
138 handle(url) {
139 return 'soundcloud_track: ' + url.match(this.kMatcher)[2]
140 }
141 },
142 // soundcloud unmatched
143 {
144 canHandle(url) {
145 return url.match(/soundcloud/);
146 },
147 handle(url) {
148 return '!!!!!!!!!!!!!!!!!:' + url
149 }
150 },
151 // spotify embed
152 {
153 kMatcher: /spotify.com\/embed\/track\/([^?]+)/,
154 canHandle(url) {
155 return url.match(this.kMatcher);
156 },
157 handle(url) {
158 return 'sp_embed:' + url.match(this.kMatcher)[1];
159 }
160 },
161 // spotify unmatched
162 {
163 canHandle(url) {
164 return url.match(/spotify/);
165 },
166 handle(url) {
167 return '!!!!!!!!!!!!!!!!!:' + url
168 }
169 },
170 ],
171
172 extractURLsFromFeeds() {
173 const app = Application("NetNewsWire");
174 app.includeStandardAdditions = true;
175
176 let account = app.accounts.whose({name: internals.config.account})[0];
177 let musicFolder = account.folders.whose({name: internals.config.musicFolder})[0];
178 const feeds = musicFolder.webfeeds();
179
180 const urls = [];
181
182 for (const feed of feeds) {
183 const articles = feed.articles()
184 .filter((article) => internals.config.onlyUnread ? !article.read : true);
185
186 for (const article of articles) {
187 console.log(article.title())
188 const html = article.html();
189 const extractedURLs = html.match(internals.kURLParser) || [];
190 article.read = true
191 urls.push(...extractedURLs)
192 }
193 }
194
195 return urls;
196 },
197
198 extractSongsFromURLs(urls) {
199
200 let songs = [];
201
202 for (url of urls) {
203 for (const strategy of internals.strategies) {
204 if (strategy.canHandle(url)) {
205 songs.push(strategy.handle(url))
206 break;
207 }
208 }
209 }
210
211 return songs;
212 }
213 };
214
215 const run = function () {
216
217 const urls = internals.extractURLsFromFeeds();
218 const songs = internals.extractSongsFromURLs(urls);
219
220 return songs;
221 }
222
223 run();