|
1 | 1 | // ==UserScript==
|
2 | 2 | // @name Taiwan ISRC to MusicBrainz
|
3 |
| -// @version 1.1.0 |
| 3 | +// @version 2.0.0 |
4 | 4 | // @namespace http://www.agj.cl/
|
5 | 5 | // @description Adds a link to any isrc.ncl.edu.tw record entry page that opens the Add Release form in MusicBrainz, prefilling it with that record's information.
|
6 | 6 | // @license Unlicense
|
7 |
| -// @include http*://isrc.ncl.edu.tw/music_view.aspx* |
| 7 | +// @include http*://isrc.ncl.edu.tw/C100/* |
8 | 8 | // @grant none
|
9 | 9 | // ==/UserScript==
|
10 | 10 |
|
|
43 | 43 | Array.isArray(item) ? r.concat(flatten(item)) : r.concat([item]),
|
44 | 44 | []
|
45 | 45 | );
|
| 46 | + const onFullLoad = (cb) => |
| 47 | + /complete/.test(document.readyState) |
| 48 | + ? setTimeout(cb, 0) |
| 49 | + : window.addEventListener("load", cb, { |
| 50 | + once: true, |
| 51 | + }); |
| 52 | + const waitFor = (milliseconds) => |
| 53 | + new Promise((resolve) => { |
| 54 | + setTimeout(resolve, milliseconds); |
| 55 | + }); |
46 | 56 |
|
47 |
| - // Get values. |
| 57 | + onFullLoad(async () => { |
| 58 | + // Get values. |
48 | 59 |
|
49 |
| - const values = Array.from(selAll(".musicView > table > tbody > tr")).reduce( |
50 |
| - (r, el) => { |
51 |
| - const label = selIn(el, "th").textContent.trim(); |
52 |
| - const value = selIn(el, "td") |
53 |
| - .textContent.trim() |
54 |
| - .replace(/^:\s+(\S.*)$/, "$1"); |
55 |
| - if (/表演者/.test(label)) r.artist = value; |
56 |
| - else if (/樂團名稱/.test(label)) r.artist = value; |
57 |
| - else if (/專輯名稱/.test(label)) r.title = value; |
58 |
| - else if (/發行公司/.test(label)) r.label = value; |
59 |
| - else if (/產品編碼/.test(label)) r.cat = value; |
60 |
| - else if (/EAN碼/.test(label)) r.barcode = value; |
61 |
| - else if (/發行日期/.test(label)) r.date = value.split("/"); |
62 |
| - return r; |
63 |
| - }, |
64 |
| - {} |
65 |
| - ); |
66 |
| - values.tracks = Array.from(selAll(".AllMusic fieldset a")) |
67 |
| - .map(get("textContent")) |
68 |
| - .map(call("trim")) |
69 |
| - .map((t) => t.replace(/^.+ ] 曲目名稱:(.*)$/, "$1")); |
| 60 | + await waitFor(1000); |
70 | 61 |
|
71 |
| - // Add submit link. |
| 62 | + const values = Array.from(sel(".table").querySelectorAll("tr")).reduce( |
| 63 | + (r, el) => { |
| 64 | + const label = selIn(el, "th").textContent.trim(); |
| 65 | + const value = selIn(el, "td").textContent.trim(); |
| 66 | + if (/表演者/.test(label)) r.artist = value; |
| 67 | + else if (/樂團名稱/.test(label)) r.artist = value; |
| 68 | + else if (/專輯名稱/.test(label)) r.title = value; |
| 69 | + else if (/發行公司/.test(label)) r.label = value; |
| 70 | + else if (/產品編碼/.test(label)) r.cat = value; |
| 71 | + else if (/EAN\/UPC碼/.test(label)) r.barcode = value; |
| 72 | + else if (/發行日期/.test(label)) r.date = value.split("."); |
| 73 | + return r; |
| 74 | + }, |
| 75 | + {} |
| 76 | + ); |
72 | 77 |
|
73 |
| - const checkValue = (value) => (value === undefined ? "" : value); |
74 |
| - const input = (name, value) => |
75 |
| - dom("input", { name: name, value: checkValue(value), type: "text" }); |
| 78 | + values.tracks = Array.from(selAll("#songsTable a")) |
| 79 | + .map(get("textContent")) |
| 80 | + .map(call("trim")) |
| 81 | + .map((t) => t.replace(/^\[\S+\] \d+[.](.*)$/, "$1")); |
76 | 82 |
|
77 |
| - const link = dom("a", null, "Add to MusicBrainz"); |
78 |
| - const form = dom( |
79 |
| - "form", |
80 |
| - { |
81 |
| - name: "musicbrainz-submit", |
82 |
| - action: "https://musicbrainz.org/release/add", |
83 |
| - method: "post", |
84 |
| - "accept-charset": "utf-8", |
85 |
| - style: "display: none", |
86 |
| - }, |
87 |
| - input("name", values.title), |
88 |
| - input("artist_credit.names.0.name", values.artist), |
89 |
| - input("labels.0.name", values.label), |
90 |
| - input("labels.0.catalog_number", values.cat), |
91 |
| - input("events.0.date.year", values.date[0]), |
92 |
| - input("events.0.date.month", values.date[1]), |
93 |
| - input("events.0.country", "TW"), |
94 |
| - input("barcode", values.barcode), |
95 |
| - input("urls.0.url", window.location.href), |
96 |
| - input("urls.0.link_type", "82"), |
97 |
| - input("language", "cmn"), |
98 |
| - input("script", "Hant"), |
99 |
| - input("status", "official"), |
100 |
| - input("mediums.0.format", "cd"), |
101 |
| - input("edit_note", "From Taiwan ISRC: " + window.location.href) |
102 |
| - ); |
103 |
| - const container = dom("div", { id: "musicbrainz-submit" }, link, form); |
| 83 | + console.log({ values }); |
104 | 84 |
|
105 |
| - const trackCount = counter(); |
106 |
| - flatten( |
107 |
| - values.tracks.map((title) => { |
108 |
| - const i = trackCount(); |
109 |
| - return [ |
110 |
| - input(`mediums.0.track.${i}.name`, title), |
111 |
| - input(`mediums.0.track.${i}.number`, i + 1), |
112 |
| - ]; |
113 |
| - }) |
114 |
| - ).map((el) => form.appendChild(el)); |
| 85 | + // Add submit link. |
115 | 86 |
|
116 |
| - sel("#mainContent > div").prepend(container); |
117 |
| - link.addEventListener("click", (e) => { |
118 |
| - form.submit(); |
119 |
| - e.preventDefault(); |
120 |
| - }); |
| 87 | + const checkValue = (value) => (value === undefined ? "" : value); |
| 88 | + const input = (name, value) => |
| 89 | + dom("input", { name: name, value: checkValue(value), type: "text" }); |
| 90 | + |
| 91 | + const link = dom("a", null, "Add to MusicBrainz"); |
| 92 | + const form = dom( |
| 93 | + "form", |
| 94 | + { |
| 95 | + name: "musicbrainz-submit", |
| 96 | + action: "https://musicbrainz.org/release/add", |
| 97 | + method: "post", |
| 98 | + "accept-charset": "utf-8", |
| 99 | + style: "display: none", |
| 100 | + }, |
| 101 | + input("name", values.title), |
| 102 | + input("artist_credit.names.0.name", values.artist), |
| 103 | + input("labels.0.name", values.label), |
| 104 | + input("labels.0.catalog_number", values.cat), |
| 105 | + input("events.0.date.year", values.date[0]), |
| 106 | + input("events.0.date.month", values.date[1]), |
| 107 | + input("events.0.country", "TW"), |
| 108 | + input("barcode", values.barcode), |
| 109 | + input("urls.0.url", window.location.href), |
| 110 | + input("urls.0.link_type", "82"), |
| 111 | + input("language", "cmn"), |
| 112 | + input("script", "Hant"), |
| 113 | + input("status", "official"), |
| 114 | + input("mediums.0.format", "cd"), |
| 115 | + input("edit_note", "From Taiwan ISRC: " + window.location.href) |
| 116 | + ); |
| 117 | + const container = dom("div", { id: "musicbrainz-submit" }, link, form); |
| 118 | + |
| 119 | + const trackCount = counter(); |
| 120 | + flatten( |
| 121 | + values.tracks.map((title) => { |
| 122 | + const i = trackCount(); |
| 123 | + return [ |
| 124 | + input(`mediums.0.track.${i}.name`, title), |
| 125 | + input(`mediums.0.track.${i}.number`, i + 1), |
| 126 | + ]; |
| 127 | + }) |
| 128 | + ).map((el) => form.appendChild(el)); |
121 | 129 |
|
122 |
| - sel("head").append( |
123 |
| - dom( |
124 |
| - "style", |
125 |
| - null, |
126 |
| - ` |
| 130 | + sel("#mainContent > div").prepend(container); |
| 131 | + link.addEventListener("click", (e) => { |
| 132 | + form.submit(); |
| 133 | + e.preventDefault(); |
| 134 | + }); |
| 135 | + |
| 136 | + sel("head").append( |
| 137 | + dom( |
| 138 | + "style", |
| 139 | + null, |
| 140 | + ` |
127 | 141 | #musicbrainz-submit {
|
128 | 142 | display: inline-flex;
|
129 | 143 | vertical-align: bottom;
|
|
137 | 151 | font-weight: bold;
|
138 | 152 | }
|
139 | 153 | `
|
140 |
| - ) |
141 |
| - ); |
| 154 | + ) |
| 155 | + ); |
| 156 | + }); |
142 | 157 | })();
|
0 commit comments