Alex revised this gist . Go to revision
No changes
Alex Thomassen revised this gist . Go to revision
1 file changed, 64 insertions, 6 deletions
nyaa-shit.user.js
@@ -3,7 +3,7 @@ | |||
3 | 3 | // @namespace github.com/Decicus | |
4 | 4 | // @match https://nyaa.si/* | |
5 | 5 | // @grant GM_setClipboard | |
6 | - | // @version 1.4.1 | |
6 | + | // @version 1.5.0 | |
7 | 7 | // @author Decicus | |
8 | 8 | // @description Adds some extra functionality to Nyaa. | |
9 | 9 | // ==/UserScript== | |
@@ -194,16 +194,21 @@ const titleReplacements = [ | |||
194 | 194 | search: / \"[A-z0-9-!\s]+\"$/, | |
195 | 195 | replacement: '', | |
196 | 196 | }, | |
197 | - | { | |
198 | - | comment: 'Move release group to the end', | |
199 | - | search: /^\[([-\w ]+)\] (.+)$/, | |
200 | - | replacement: '$2 [$1]', | |
201 | - | }, | |
197 | + | // { | |
198 | + | // comment: 'Move release group to the end', | |
199 | + | // search: /^\[([-\w ]+)\] (.+)$/, | |
200 | + | // replacement: '$2 [$1]', | |
201 | + | // }, | |
202 | 202 | { | |
203 | 203 | comment: 'Colon space to space dash space', | |
204 | 204 | search: /: /g, | |
205 | 205 | replacement: ' - ', | |
206 | 206 | }, | |
207 | + | { | |
208 | + | comment: 'Ensure seasons have two numbers', | |
209 | + | search: / \(Season (\d)\)/g, | |
210 | + | replacement: ' (Season 0$1)', | |
211 | + | }, | |
207 | 212 | { | |
208 | 213 | comment: 'Season naming so Sonarr doesnt get confused because its dumb', | |
209 | 214 | search: / \(Season (\d+)\)/g, | |
@@ -294,6 +299,58 @@ function titleHandler() | |||
294 | 299 | titleParent.insertAdjacentElement('afterbegin', buttonParent); | |
295 | 300 | } | |
296 | 301 | ||
302 | + | /** | |
303 | + | * Used by `copyFilenameHandler()` to do the actual copying | |
304 | + | */ | |
305 | + | function copyFilenameTrigger(ev) | |
306 | + | { | |
307 | + | const { target } = ev; | |
308 | + | ||
309 | + | // Trust no one, not even yourself | |
310 | + | if (!target) { | |
311 | + | return; | |
312 | + | } | |
313 | + | ||
314 | + | // We clone it here because I want to remove the file size that's normally at the end | |
315 | + | // If I simply do a `remove()` on the usual element, it will actually remove it from the DOM. | |
316 | + | const parent = target.parentElement.cloneNode(true); | |
317 | + | const fileSize = parent.querySelector('.file-size'); | |
318 | + | ||
319 | + | if (fileSize) { | |
320 | + | fileSize.remove(); | |
321 | + | } | |
322 | + | ||
323 | + | const filename = parent.textContent.trim(); | |
324 | + | ||
325 | + | target.classList.remove('fa-file'); | |
326 | + | target.classList.add('fa-check'); | |
327 | + | ||
328 | + | GM_setClipboard(filename); | |
329 | + | ||
330 | + | setTimeout(() => { | |
331 | + | target.classList.remove('fa-check'); | |
332 | + | target.classList.add('fa-file'); | |
333 | + | }, 1500); | |
334 | + | } | |
335 | + | ||
336 | + | /** | |
337 | + | * Clicking the file icon in front of each file will allow you to copy the filename | |
338 | + | */ | |
339 | + | async function copyFilenameHandler() | |
340 | + | { | |
341 | + | const fileList = document.querySelector('.torrent-file-list'); | |
342 | + | if (!fileList) { | |
343 | + | return; | |
344 | + | } | |
345 | + | ||
346 | + | const fileIcons = fileList.querySelectorAll('.fa-file'); | |
347 | + | ||
348 | + | for (const icon of fileIcons) | |
349 | + | { | |
350 | + | icon.addEventListener('click', copyFilenameTrigger); | |
351 | + | } | |
352 | + | } | |
353 | + | ||
297 | 354 | function bbcodeConverter(html) { | |
298 | 355 | html = html.replace(/<pre(.*?)>(.*?)<\/pre>/gmi, "[code]$2[/code]"); | |
299 | 356 | html = html.replace(/<h[1-7](.*?)>(.*?)<\/h[1-7]>/, "\n[h]$2[/h]\n"); | |
@@ -559,6 +616,7 @@ function init() { | |||
559 | 616 | changeToCopy(); | |
560 | 617 | titleHandler(); | |
561 | 618 | descriptionHandler(); | |
619 | + | copyFilenameHandler(); | |
562 | 620 | torrentListViewHandler(); | |
563 | 621 | calculateTotalSize(); | |
564 | 622 | widerContainers(); |
Alex Thomassen revised this gist . Go to revision
1 file changed, 25 insertions, 15 deletions
nyaa-shit.user.js
@@ -3,7 +3,7 @@ | |||
3 | 3 | // @namespace github.com/Decicus | |
4 | 4 | // @match https://nyaa.si/* | |
5 | 5 | // @grant GM_setClipboard | |
6 | - | // @version 1.4.0 | |
6 | + | // @version 1.4.1 | |
7 | 7 | // @author Decicus | |
8 | 8 | // @description Adds some extra functionality to Nyaa. | |
9 | 9 | // ==/UserScript== | |
@@ -83,6 +83,9 @@ function calculateTotalSize() | |||
83 | 83 | return; | |
84 | 84 | } | |
85 | 85 | ||
86 | + | const sampleTorrent = "https://nyaa.si/download/222409.torrent"; | |
87 | + | const sampleMagnet = "magnet:?xt=urn:btih:db0ffe8174317b0b0ee4beb7b54f558bb9089746&dn=%5Beoy%5D%20dark%20dragoon%20-%2001.txt&tr=http%3A%2F%2Fnyaa.tracker.wf%3A7777%2Fannounce&tr=udp%3A%2F%2Fopen.stealth.si%3A80%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Fexodus.desync.com%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.torrent.eu.org%3A451%2Fannounce"; | |
88 | + | ||
86 | 89 | const html = `<tr class="default" id="all-torrents-size"> | |
87 | 90 | <td class="text-center"> | |
88 | 91 | <a href="#all-torrents-size" title="Total size"> | |
@@ -92,7 +95,12 @@ function calculateTotalSize() | |||
92 | 95 | <td colspan="2"> | |
93 | 96 | <a href="#all-torrents-size">Total size</a> | |
94 | 97 | </td> | |
95 | - | <td class="text-center"><!-- Download --></td> | |
98 | + | <td class="text-center"> | |
99 | + | <!-- These elements purely exist to avoid any issues with extensions or userscripts that would normally expect valid torrent/magnet URIs --> | |
100 | + | <!-- In my case I only found an issue with NyaaBlue from SeaDex --> | |
101 | + | <a href="${sampleTorrent}" style="display: none;"><!-- Download torrent --></a> | |
102 | + | <a href="${sampleMagnet}" style="display: none;"><!-- Magnet URI --></a> | |
103 | + | </td> | |
96 | 104 | <td class="text-center">${totalSize}</td> | |
97 | 105 | <td class="text-center"><!-- Timestamp --></td> | |
98 | 106 | <td class="text-center"><!-- Seeders --></td> | |
@@ -528,21 +536,23 @@ function torrentListViewHandler() | |||
528 | 536 | parentElement.insertAdjacentElement('beforebegin', amountCopyLinks); | |
529 | 537 | } | |
530 | 538 | ||
531 | - | function changeContainers() | |
539 | + | /** | |
540 | + | * This previously changed some `.container` classes to `.container-fluid`, | |
541 | + | * but since that breaks other userscripts, such as NyaaBlue from SeaDex, | |
542 | + | * I figured it'd be better to simply override the CSS width that .container usually applies. | |
543 | + | */ | |
544 | + | function widerContainers() | |
532 | 545 | { | |
533 | - | const selectors = ['.navbar-static-top > .container', 'body > .container']; | |
534 | - | for (const selector of selectors) | |
535 | - | { | |
536 | - | const element = document.querySelector(selector); | |
537 | - | if (!element) { | |
538 | - | console.error('Could not find any element with selector', selector); | |
539 | - | continue; | |
546 | + | const styleDoc = document.createElement('style'); | |
547 | + | styleDoc.setAttribute('type', 'text/css'); | |
548 | + | ||
549 | + | styleDoc.textContent = ` | |
550 | + | .container { | |
551 | + | width: auto !important; | |
540 | 552 | } | |
553 | + | `; | |
541 | 554 | ||
542 | - | element.classList.remove('container'); | |
543 | - | element.classList.add('container-fluid'); | |
544 | - | console.log('Element updated with container-fluid', selector, element); | |
545 | - | } | |
555 | + | document.head.insertAdjacentElement('beforeend', styleDoc); | |
546 | 556 | } | |
547 | 557 | ||
548 | 558 | function init() { | |
@@ -551,7 +561,7 @@ function init() { | |||
551 | 561 | descriptionHandler(); | |
552 | 562 | torrentListViewHandler(); | |
553 | 563 | calculateTotalSize(); | |
554 | - | changeContainers(); | |
564 | + | widerContainers(); | |
555 | 565 | } | |
556 | 566 | ||
557 | 567 | init(); |
Alex Thomassen revised this gist . Go to revision
1 file changed, 19 insertions, 2 deletions
nyaa-shit.user.js
@@ -3,7 +3,7 @@ | |||
3 | 3 | // @namespace github.com/Decicus | |
4 | 4 | // @match https://nyaa.si/* | |
5 | 5 | // @grant GM_setClipboard | |
6 | - | // @version 1.3.1 | |
6 | + | // @version 1.4.0 | |
7 | 7 | // @author Decicus | |
8 | 8 | // @description Adds some extra functionality to Nyaa. | |
9 | 9 | // ==/UserScript== | |
@@ -60,7 +60,6 @@ function calculateTotalSize() | |||
60 | 60 | const torrentBytes = sizeNumber * multiplier; | |
61 | 61 | ||
62 | 62 | totalBytes += torrentBytes; | |
63 | - | console.log(totalBytes); | |
64 | 63 | } | |
65 | 64 | ||
66 | 65 | const multiplierKeys = Object.keys(multipliers).reverse(); | |
@@ -529,12 +528,30 @@ function torrentListViewHandler() | |||
529 | 528 | parentElement.insertAdjacentElement('beforebegin', amountCopyLinks); | |
530 | 529 | } | |
531 | 530 | ||
531 | + | function changeContainers() | |
532 | + | { | |
533 | + | const selectors = ['.navbar-static-top > .container', 'body > .container']; | |
534 | + | for (const selector of selectors) | |
535 | + | { | |
536 | + | const element = document.querySelector(selector); | |
537 | + | if (!element) { | |
538 | + | console.error('Could not find any element with selector', selector); | |
539 | + | continue; | |
540 | + | } | |
541 | + | ||
542 | + | element.classList.remove('container'); | |
543 | + | element.classList.add('container-fluid'); | |
544 | + | console.log('Element updated with container-fluid', selector, element); | |
545 | + | } | |
546 | + | } | |
547 | + | ||
532 | 548 | function init() { | |
533 | 549 | changeToCopy(); | |
534 | 550 | titleHandler(); | |
535 | 551 | descriptionHandler(); | |
536 | 552 | torrentListViewHandler(); | |
537 | 553 | calculateTotalSize(); | |
554 | + | changeContainers(); | |
538 | 555 | } | |
539 | 556 | ||
540 | 557 | init(); |
Alex Thomassen revised this gist . Go to revision
1 file changed, 5 insertions, 1 deletion
nyaa-shit.user.js
@@ -3,7 +3,7 @@ | |||
3 | 3 | // @namespace github.com/Decicus | |
4 | 4 | // @match https://nyaa.si/* | |
5 | 5 | // @grant GM_setClipboard | |
6 | - | // @version 1.3.0 | |
6 | + | // @version 1.3.1 | |
7 | 7 | // @author Decicus | |
8 | 8 | // @description Adds some extra functionality to Nyaa. | |
9 | 9 | // ==/UserScript== | |
@@ -80,6 +80,10 @@ function calculateTotalSize() | |||
80 | 80 | } | |
81 | 81 | ||
82 | 82 | const torrentList = document.querySelector('.torrent-list tbody'); | |
83 | + | if (!torrentList) { | |
84 | + | return; | |
85 | + | } | |
86 | + | ||
83 | 87 | const html = `<tr class="default" id="all-torrents-size"> | |
84 | 88 | <td class="text-center"> | |
85 | 89 | <a href="#all-torrents-size" title="Total size"> |
Alex Thomassen revised this gist . Go to revision
1 file changed, 68 insertions, 68 deletions
nyaa-shit.user.js
@@ -81,21 +81,21 @@ function calculateTotalSize() | |||
81 | 81 | ||
82 | 82 | const torrentList = document.querySelector('.torrent-list tbody'); | |
83 | 83 | const html = `<tr class="default" id="all-torrents-size"> | |
84 | - | <td class="text-center"> | |
85 | - | <a href="#all-torrents-size" title="Total size"> | |
86 | - | 💽 | |
87 | - | </a> | |
88 | - | </td> | |
89 | - | <td colspan="2"> | |
84 | + | <td class="text-center"> | |
85 | + | <a href="#all-torrents-size" title="Total size"> | |
86 | + | 💽 | |
87 | + | </a> | |
88 | + | </td> | |
89 | + | <td colspan="2"> | |
90 | 90 | <a href="#all-torrents-size">Total size</a> | |
91 | - | </td> | |
92 | - | <td class="text-center"><!-- Download --></td> | |
93 | - | <td class="text-center">${totalSize}</td> | |
94 | - | <td class="text-center"><!-- Timestamp --></td> | |
95 | - | <td class="text-center"><!-- Seeders --></td> | |
96 | - | <td class="text-center"><!-- Leechers --></td> | |
97 | - | <td class="text-center"><!-- Completed --></td> | |
98 | - | </tr>`; | |
91 | + | </td> | |
92 | + | <td class="text-center"><!-- Download --></td> | |
93 | + | <td class="text-center">${totalSize}</td> | |
94 | + | <td class="text-center"><!-- Timestamp --></td> | |
95 | + | <td class="text-center"><!-- Seeders --></td> | |
96 | + | <td class="text-center"><!-- Leechers --></td> | |
97 | + | <td class="text-center"><!-- Completed --></td> | |
98 | + | </tr>`; | |
99 | 99 | ||
100 | 100 | torrentList.insertAdjacentHTML('beforeend', html); | |
101 | 101 | } | |
@@ -285,63 +285,63 @@ function titleHandler() | |||
285 | 285 | ||
286 | 286 | function bbcodeConverter(html) { | |
287 | 287 | html = html.replace(/<pre(.*?)>(.*?)<\/pre>/gmi, "[code]$2[/code]"); | |
288 | - | html = html.replace(/<h[1-7](.*?)>(.*?)<\/h[1-7]>/, "\n[h]$2[/h]\n"); | |
289 | - | //paragraph handling: | |
290 | - | //- if a paragraph opens on the same line as another one closes, insert an extra blank line | |
291 | - | //- opening tag becomes two line breaks | |
292 | - | //- closing tags are just removed | |
293 | - | // html += html.replace(/<\/p><p/<\/p>\n<p/gi; | |
294 | - | // html += html.replace(/<p[^>]*>/\n\n/gi; | |
295 | - | // html += html.replace(/<\/p>//gi; | |
288 | + | html = html.replace(/<h[1-7](.*?)>(.*?)<\/h[1-7]>/, "\n[h]$2[/h]\n"); | |
289 | + | //paragraph handling: | |
290 | + | //- if a paragraph opens on the same line as another one closes, insert an extra blank line | |
291 | + | //- opening tag becomes two line breaks | |
292 | + | //- closing tags are just removed | |
293 | + | // html += html.replace(/<\/p><p/<\/p>\n<p/gi; | |
294 | + | // html += html.replace(/<p[^>]*>/\n\n/gi; | |
295 | + | // html += html.replace(/<\/p>//gi; | |
296 | 296 | ||
297 | 297 | html = html.replace(/<\/p>\n<p>/gi, "\n\n\n"); | |
298 | 298 | ||
299 | - | html = html.replace(/<br(.*?)>/gi, "\n"); | |
300 | - | html = html.replace(/<textarea(.*?)>(.*?)<\/textarea>/gmi, "\[code]$2\[\/code]"); | |
301 | - | html = html.replace(/<b>/gi, "[b]"); | |
302 | - | html = html.replace(/<i>/gi, "[i]"); | |
303 | - | html = html.replace(/<u>/gi, "[u]"); | |
304 | - | html = html.replace(/<\/b>/gi, "[/b]"); | |
305 | - | html = html.replace(/<\/i>/gi, "[/i]"); | |
306 | - | html = html.replace(/<\/u>/gi, "[/u]"); | |
307 | - | html = html.replace(/<em>/gi, "[b]"); | |
308 | - | html = html.replace(/<\/em>/gi, "[/b]"); | |
309 | - | html = html.replace(/<strong>/gi, "[b]"); | |
310 | - | html = html.replace(/<\/strong>/gi, "[/b]"); | |
311 | - | html = html.replace(/<cite>/gi, "[i]"); | |
312 | - | html = html.replace(/<\/cite>/gi, "[/i]"); | |
313 | - | html = html.replace(/<font color="(.*?)">(.*?)<\/font>/gmi, "[color=$1]$2[/color]"); | |
314 | - | html = html.replace(/<font color=(.*?)>(.*?)<\/font>/gmi, "[color=$1]$2[/color]"); | |
315 | - | html = html.replace(/<link(.*?)>/gi, ""); | |
316 | - | html = html.replace(/<li(.*?)>(.*?)<\/li>/gi, "[*]$2"); | |
317 | - | html = html.replace(/<ul(.*?)>/gi, "[list]"); | |
318 | - | html = html.replace(/<\/ul>/gi, "[/list]"); | |
319 | - | html = html.replace(/<div>/gi, "\n"); | |
320 | - | html = html.replace(/<\/div>/gi, "\n"); | |
321 | - | html = html.replace(/<td(.*?)>/gi, " "); | |
322 | - | html = html.replace(/<tr(.*?)>/gi, "\n"); | |
323 | - | ||
324 | - | html = html.replace(/<img(.*?)src="(.*?)"(.*?)>/gi, "[img]$2[/img]"); | |
325 | - | html = html.replace(/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/gi, "[url=$2]$4[/url]"); | |
326 | - | ||
327 | - | html = html.replace(/<head>(.*?)<\/head>/gmi, ""); | |
328 | - | html = html.replace(/<object>(.*?)<\/object>/gmi, ""); | |
329 | - | html = html.replace(/<script(.*?)>(.*?)<\/script>/gmi, ""); | |
330 | - | html = html.replace(/<style(.*?)>(.*?)<\/style>/gmi, ""); | |
331 | - | html = html.replace(/<title>(.*?)<\/title>/gmi, ""); | |
332 | - | html = html.replace(/<!--(.*?)-->/gmi, "\n"); | |
333 | - | ||
334 | - | html = html.replace(/\/\//gi, "/"); | |
335 | - | html = html.replace(/http:\//gi, "http://"); | |
336 | - | ||
337 | - | html = html.replace(/<(?:[^>'"]*|(['"]).*?\1)*>/gmi, ""); | |
338 | - | html = html.replace(/\r\r/gi, ""); | |
339 | - | html = html.replace(/\[img]\//gi, "[img]"); | |
340 | - | html = html.replace(/\[url=\//gi, "[url="); | |
341 | - | ||
342 | - | html = html.replace(/(\S)\n/gi, "$1 "); | |
343 | - | ||
344 | - | return html; | |
299 | + | html = html.replace(/<br(.*?)>/gi, "\n"); | |
300 | + | html = html.replace(/<textarea(.*?)>(.*?)<\/textarea>/gmi, "\[code]$2\[\/code]"); | |
301 | + | html = html.replace(/<b>/gi, "[b]"); | |
302 | + | html = html.replace(/<i>/gi, "[i]"); | |
303 | + | html = html.replace(/<u>/gi, "[u]"); | |
304 | + | html = html.replace(/<\/b>/gi, "[/b]"); | |
305 | + | html = html.replace(/<\/i>/gi, "[/i]"); | |
306 | + | html = html.replace(/<\/u>/gi, "[/u]"); | |
307 | + | html = html.replace(/<em>/gi, "[b]"); | |
308 | + | html = html.replace(/<\/em>/gi, "[/b]"); | |
309 | + | html = html.replace(/<strong>/gi, "[b]"); | |
310 | + | html = html.replace(/<\/strong>/gi, "[/b]"); | |
311 | + | html = html.replace(/<cite>/gi, "[i]"); | |
312 | + | html = html.replace(/<\/cite>/gi, "[/i]"); | |
313 | + | html = html.replace(/<font color="(.*?)">(.*?)<\/font>/gmi, "[color=$1]$2[/color]"); | |
314 | + | html = html.replace(/<font color=(.*?)>(.*?)<\/font>/gmi, "[color=$1]$2[/color]"); | |
315 | + | html = html.replace(/<link(.*?)>/gi, ""); | |
316 | + | html = html.replace(/<li(.*?)>(.*?)<\/li>/gi, "[*]$2"); | |
317 | + | html = html.replace(/<ul(.*?)>/gi, "[list]"); | |
318 | + | html = html.replace(/<\/ul>/gi, "[/list]"); | |
319 | + | html = html.replace(/<div>/gi, "\n"); | |
320 | + | html = html.replace(/<\/div>/gi, "\n"); | |
321 | + | html = html.replace(/<td(.*?)>/gi, " "); | |
322 | + | html = html.replace(/<tr(.*?)>/gi, "\n"); | |
323 | + | ||
324 | + | html = html.replace(/<img(.*?)src="(.*?)"(.*?)>/gi, "[img]$2[/img]"); | |
325 | + | html = html.replace(/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/gi, "[url=$2]$4[/url]"); | |
326 | + | ||
327 | + | html = html.replace(/<head>(.*?)<\/head>/gmi, ""); | |
328 | + | html = html.replace(/<object>(.*?)<\/object>/gmi, ""); | |
329 | + | html = html.replace(/<script(.*?)>(.*?)<\/script>/gmi, ""); | |
330 | + | html = html.replace(/<style(.*?)>(.*?)<\/style>/gmi, ""); | |
331 | + | html = html.replace(/<title>(.*?)<\/title>/gmi, ""); | |
332 | + | html = html.replace(/<!--(.*?)-->/gmi, "\n"); | |
333 | + | ||
334 | + | html = html.replace(/\/\//gi, "/"); | |
335 | + | html = html.replace(/http:\//gi, "http://"); | |
336 | + | ||
337 | + | html = html.replace(/<(?:[^>'"]*|(['"]).*?\1)*>/gmi, ""); | |
338 | + | html = html.replace(/\r\r/gi, ""); | |
339 | + | html = html.replace(/\[img]\//gi, "[img]"); | |
340 | + | html = html.replace(/\[url=\//gi, "[url="); | |
341 | + | ||
342 | + | html = html.replace(/(\S)\n/gi, "$1 "); | |
343 | + | ||
344 | + | return html; | |
345 | 345 | } | |
346 | 346 | ||
347 | 347 | function descriptionHandler() |
Alex Thomassen revised this gist . Go to revision
1 file changed, 74 insertions, 1 deletion
nyaa-shit.user.js
@@ -3,12 +3,21 @@ | |||
3 | 3 | // @namespace github.com/Decicus | |
4 | 4 | // @match https://nyaa.si/* | |
5 | 5 | // @grant GM_setClipboard | |
6 | - | // @version 1.2.0 | |
6 | + | // @version 1.3.0 | |
7 | 7 | // @author Decicus | |
8 | 8 | // @description Adds some extra functionality to Nyaa. | |
9 | 9 | // ==/UserScript== | |
10 | 10 | ||
11 | 11 | let copyAmount = 5; | |
12 | + | const multipliers = { | |
13 | + | Bytes: 1, | |
14 | + | KiB: 1024, | |
15 | + | MiB: 1024 * 1024, | |
16 | + | GiB: 1024 * 1024 * 1024, | |
17 | + | TiB: 1024 * 1024 * 1024 * 1024, | |
18 | + | }; | |
19 | + | ||
20 | + | const sizesRegex = /(Bytes|KiB|MiB|GiB|TiB)/g; | |
12 | 21 | ||
13 | 22 | function getElements(linkType = 'download') | |
14 | 23 | { | |
@@ -28,6 +37,69 @@ function getMagnets() | |||
28 | 37 | return getElements('magnet'); | |
29 | 38 | } | |
30 | 39 | ||
40 | + | /** | |
41 | + | * Calculate the approximate total size of all torrents listed in the table and append it as an information row at the bottom of the table | |
42 | + | */ | |
43 | + | function calculateTotalSize() | |
44 | + | { | |
45 | + | const timestamps = document.querySelectorAll('.torrent-list td[data-timestamp]'); | |
46 | + | let totalBytes = 0; | |
47 | + | for (const timestamp of timestamps) | |
48 | + | { | |
49 | + | const sizeCell = timestamp.previousElementSibling; | |
50 | + | const size = sizeCell.textContent.trim(); | |
51 | + | let suffix = size.match(sizesRegex); | |
52 | + | if (!suffix || suffix.length < 1) { | |
53 | + | console.error('Could not find size in element', sizeCell); | |
54 | + | continue; | |
55 | + | } | |
56 | + | ||
57 | + | suffix = suffix[0]; | |
58 | + | const multiplier = multipliers[suffix]; | |
59 | + | const sizeNumber = parseFloat(size.replace(` ${suffix}`, '').trim()); | |
60 | + | const torrentBytes = sizeNumber * multiplier; | |
61 | + | ||
62 | + | totalBytes += torrentBytes; | |
63 | + | console.log(totalBytes); | |
64 | + | } | |
65 | + | ||
66 | + | const multiplierKeys = Object.keys(multipliers).reverse(); | |
67 | + | let totalSize = `${totalBytes} Bytes`; | |
68 | + | for (const key of multiplierKeys) | |
69 | + | { | |
70 | + | if (totalBytes === 0) { | |
71 | + | break; | |
72 | + | } | |
73 | + | ||
74 | + | const divideBy = multipliers[key]; | |
75 | + | const result = totalBytes / divideBy; | |
76 | + | if (result > 1) { | |
77 | + | totalSize = `${result.toFixed(2)} ${key}`; | |
78 | + | break; | |
79 | + | } | |
80 | + | } | |
81 | + | ||
82 | + | const torrentList = document.querySelector('.torrent-list tbody'); | |
83 | + | const html = `<tr class="default" id="all-torrents-size"> | |
84 | + | <td class="text-center"> | |
85 | + | <a href="#all-torrents-size" title="Total size"> | |
86 | + | 💽 | |
87 | + | </a> | |
88 | + | </td> | |
89 | + | <td colspan="2"> | |
90 | + | <a href="#all-torrents-size">Total size</a> | |
91 | + | </td> | |
92 | + | <td class="text-center"><!-- Download --></td> | |
93 | + | <td class="text-center">${totalSize}</td> | |
94 | + | <td class="text-center"><!-- Timestamp --></td> | |
95 | + | <td class="text-center"><!-- Seeders --></td> | |
96 | + | <td class="text-center"><!-- Leechers --></td> | |
97 | + | <td class="text-center"><!-- Completed --></td> | |
98 | + | </tr>`; | |
99 | + | ||
100 | + | torrentList.insertAdjacentHTML('beforeend', html); | |
101 | + | } | |
102 | + | ||
31 | 103 | /** | |
32 | 104 | * Handler for copying download links (torrents) | |
33 | 105 | */ | |
@@ -458,6 +530,7 @@ function init() { | |||
458 | 530 | titleHandler(); | |
459 | 531 | descriptionHandler(); | |
460 | 532 | torrentListViewHandler(); | |
533 | + | calculateTotalSize(); | |
461 | 534 | } | |
462 | 535 | ||
463 | 536 | init(); |
Alex Thomassen revised this gist . Go to revision
1 file changed, 463 insertions
nyaa-shit.user.js(file created)
@@ -0,0 +1,463 @@ | |||
1 | + | // ==UserScript== | |
2 | + | // @name Nyaa - Personal Tweaks | |
3 | + | // @namespace github.com/Decicus | |
4 | + | // @match https://nyaa.si/* | |
5 | + | // @grant GM_setClipboard | |
6 | + | // @version 1.2.0 | |
7 | + | // @author Decicus | |
8 | + | // @description Adds some extra functionality to Nyaa. | |
9 | + | // ==/UserScript== | |
10 | + | ||
11 | + | let copyAmount = 5; | |
12 | + | ||
13 | + | function getElements(linkType = 'download') | |
14 | + | { | |
15 | + | const elements = document.querySelectorAll(`.fa-${linkType}`); | |
16 | + | return Array.from(elements) | |
17 | + | .map(x => x.parentElement.href) | |
18 | + | .filter(x => x && x.trim() !== ''); | |
19 | + | } | |
20 | + | ||
21 | + | function getLinks() | |
22 | + | { | |
23 | + | return getElements('download'); | |
24 | + | } | |
25 | + | ||
26 | + | function getMagnets() | |
27 | + | { | |
28 | + | return getElements('magnet'); | |
29 | + | } | |
30 | + | ||
31 | + | /** | |
32 | + | * Handler for copying download links (torrents) | |
33 | + | */ | |
34 | + | function copyLinks(amount) | |
35 | + | { | |
36 | + | let links = getLinks(); | |
37 | + | if (amount && typeof amount === 'number') { | |
38 | + | amount = amount > links.length ? links.length : amount; | |
39 | + | links = links.slice(0, amount); | |
40 | + | } | |
41 | + | ||
42 | + | const list = links.join('\n'); | |
43 | + | GM_setClipboard(list); | |
44 | + | } | |
45 | + | ||
46 | + | /** | |
47 | + | * Handler for copying magnets | |
48 | + | */ | |
49 | + | function copyMagnets(amount) | |
50 | + | { | |
51 | + | let magnets = getMagnets(); | |
52 | + | if (amount && typeof amount === 'number') { | |
53 | + | amount = amount > magnets.length ? magnets.length : amount; | |
54 | + | magnets = magnets.slice(0, amount); | |
55 | + | } | |
56 | + | ||
57 | + | const list = magnets.join('\n'); | |
58 | + | GM_setClipboard(list); | |
59 | + | } | |
60 | + | ||
61 | + | /** | |
62 | + | * Changes the download links for torrents/magnets to trigger a copy, | |
63 | + | * instead of default handling (download for torrents, torrent *client* for magnets). | |
64 | + | */ | |
65 | + | function copyOnClick(ev) | |
66 | + | { | |
67 | + | ev.preventDefault(); | |
68 | + | ||
69 | + | const target = ev.target; | |
70 | + | const isAnchor = target.nodeName === 'A'; | |
71 | + | const parent = isAnchor ? target : target.parentElement; | |
72 | + | GM_setClipboard(parent.href + '\n'); | |
73 | + | ||
74 | + | const checkIcon = 'fa-check'; | |
75 | + | const originalIcon = parent.href.includes('/download/') ? 'fa-download' : 'fa-magnet'; | |
76 | + | ||
77 | + | const iconElement = !target.classList.contains('fa') ? target.querySelector('.fa') : target; | |
78 | + | console.log(iconElement); | |
79 | + | ||
80 | + | if (iconElement) { | |
81 | + | iconElement.classList.replace(originalIcon, checkIcon); | |
82 | + | ||
83 | + | setTimeout( | |
84 | + | function() { | |
85 | + | iconElement.classList.replace(checkIcon, originalIcon); | |
86 | + | }, | |
87 | + | 1500 | |
88 | + | ); | |
89 | + | } | |
90 | + | } | |
91 | + | ||
92 | + | /** | |
93 | + | * Changes said magnet/torrent links to use the `copyOnClick` handler. | |
94 | + | */ | |
95 | + | function changeToCopy() | |
96 | + | { | |
97 | + | const links = document.querySelectorAll('.fa-magnet, .fa-download'); | |
98 | + | ||
99 | + | for (const link of links) | |
100 | + | { | |
101 | + | link.parentElement.addEventListener('click', copyOnClick); | |
102 | + | } | |
103 | + | } | |
104 | + | ||
105 | + | /** | |
106 | + | * List of regex replacements so that I can copy titles as directory names, with my personally preferred naming scheme. | |
107 | + | */ | |
108 | + | const titleReplacements = [ | |
109 | + | { | |
110 | + | comment: 'Remove quoted series/movie title from the end', | |
111 | + | search: / \"[A-z0-9-!\s]+\"$/, | |
112 | + | replacement: '', | |
113 | + | }, | |
114 | + | { | |
115 | + | comment: 'Move release group to the end', | |
116 | + | search: /^\[([-\w ]+)\] (.+)$/, | |
117 | + | replacement: '$2 [$1]', | |
118 | + | }, | |
119 | + | { | |
120 | + | comment: 'Colon space to space dash space', | |
121 | + | search: /: /g, | |
122 | + | replacement: ' - ', | |
123 | + | }, | |
124 | + | { | |
125 | + | comment: 'Season naming so Sonarr doesnt get confused because its dumb', | |
126 | + | search: / \(Season (\d+)\)/g, | |
127 | + | replacement: ' - S$1', | |
128 | + | }, | |
129 | + | { | |
130 | + | comment: 'No slashes, please', | |
131 | + | search: /\//g, | |
132 | + | replacement: '-', | |
133 | + | }, | |
134 | + | { | |
135 | + | comment: 'Closing => Opening bracket spacing between each "tag"', | |
136 | + | search: /\]\[/g, | |
137 | + | replacement: '] [', | |
138 | + | }, | |
139 | + | { | |
140 | + | comment: 'Final replacement: Replace 2+ spaces with one space', | |
141 | + | search: /\s{2,}/g, | |
142 | + | replacement: ' ', | |
143 | + | }, | |
144 | + | ]; | |
145 | + | ||
146 | + | /** | |
147 | + | * Uses `titleReplacements` to "fix" torrent name when "Copy torrent name" button is clicked. | |
148 | + | */ | |
149 | + | function fixTitle(input) | |
150 | + | { | |
151 | + | let finalString = input.trim(); | |
152 | + | for (const replace of titleReplacements) | |
153 | + | { | |
154 | + | const { comment, search, replacement } = replace; | |
155 | + | ||
156 | + | const match = finalString.match(search); | |
157 | + | if (match === null) { | |
158 | + | continue; | |
159 | + | } | |
160 | + | ||
161 | + | console.log(`\nFound: ${search}\nComment: ${comment}\nMatches:\n- ${match.join('\n- ')}`); | |
162 | + | finalString = finalString.replace(search, replacement || ''); | |
163 | + | } | |
164 | + | ||
165 | + | // Deal with any excess whitespace | |
166 | + | finalString = finalString.trim(); | |
167 | + | console.log(`Original input: ${input}\nFinal string: ${finalString}`); | |
168 | + | ||
169 | + | return finalString; | |
170 | + | } | |
171 | + | ||
172 | + | /** | |
173 | + | * Adds copy button for torrent titles on torrent pages | |
174 | + | * Implements `fixTitle()` | |
175 | + | */ | |
176 | + | function titleHandler() | |
177 | + | { | |
178 | + | const title = document.querySelector('h3.panel-title'); | |
179 | + | ||
180 | + | if (!title) { | |
181 | + | return; | |
182 | + | } | |
183 | + | ||
184 | + | const titleParent = title.parentElement; | |
185 | + | ||
186 | + | const buttonParent = document.createElement('div'); | |
187 | + | buttonParent.setAttribute('class', 'btn-group pull-right'); | |
188 | + | ||
189 | + | const button = document.createElement('button'); | |
190 | + | button.textContent = '📋'; | |
191 | + | button.setAttribute('class', 'btn btn-primary btn-sm'); | |
192 | + | button.addEventListener('click', function() { | |
193 | + | const origText = button.textContent; | |
194 | + | ||
195 | + | button.textContent = '✔'; | |
196 | + | button.setAttribute('disabled', '1'); | |
197 | + | ||
198 | + | const fixedTitle = fixTitle(title.textContent.trim()); | |
199 | + | GM_setClipboard(fixedTitle); | |
200 | + | ||
201 | + | setTimeout( | |
202 | + | () => { | |
203 | + | button.textContent = origText; | |
204 | + | button.removeAttribute('disabled'); | |
205 | + | }, 1500 | |
206 | + | ); | |
207 | + | }); | |
208 | + | ||
209 | + | titleParent.classList.add('clearfix'); | |
210 | + | buttonParent.insertAdjacentElement('afterbegin', button); | |
211 | + | titleParent.insertAdjacentElement('afterbegin', buttonParent); | |
212 | + | } | |
213 | + | ||
214 | + | function bbcodeConverter(html) { | |
215 | + | html = html.replace(/<pre(.*?)>(.*?)<\/pre>/gmi, "[code]$2[/code]"); | |
216 | + | html = html.replace(/<h[1-7](.*?)>(.*?)<\/h[1-7]>/, "\n[h]$2[/h]\n"); | |
217 | + | //paragraph handling: | |
218 | + | //- if a paragraph opens on the same line as another one closes, insert an extra blank line | |
219 | + | //- opening tag becomes two line breaks | |
220 | + | //- closing tags are just removed | |
221 | + | // html += html.replace(/<\/p><p/<\/p>\n<p/gi; | |
222 | + | // html += html.replace(/<p[^>]*>/\n\n/gi; | |
223 | + | // html += html.replace(/<\/p>//gi; | |
224 | + | ||
225 | + | html = html.replace(/<\/p>\n<p>/gi, "\n\n\n"); | |
226 | + | ||
227 | + | html = html.replace(/<br(.*?)>/gi, "\n"); | |
228 | + | html = html.replace(/<textarea(.*?)>(.*?)<\/textarea>/gmi, "\[code]$2\[\/code]"); | |
229 | + | html = html.replace(/<b>/gi, "[b]"); | |
230 | + | html = html.replace(/<i>/gi, "[i]"); | |
231 | + | html = html.replace(/<u>/gi, "[u]"); | |
232 | + | html = html.replace(/<\/b>/gi, "[/b]"); | |
233 | + | html = html.replace(/<\/i>/gi, "[/i]"); | |
234 | + | html = html.replace(/<\/u>/gi, "[/u]"); | |
235 | + | html = html.replace(/<em>/gi, "[b]"); | |
236 | + | html = html.replace(/<\/em>/gi, "[/b]"); | |
237 | + | html = html.replace(/<strong>/gi, "[b]"); | |
238 | + | html = html.replace(/<\/strong>/gi, "[/b]"); | |
239 | + | html = html.replace(/<cite>/gi, "[i]"); | |
240 | + | html = html.replace(/<\/cite>/gi, "[/i]"); | |
241 | + | html = html.replace(/<font color="(.*?)">(.*?)<\/font>/gmi, "[color=$1]$2[/color]"); | |
242 | + | html = html.replace(/<font color=(.*?)>(.*?)<\/font>/gmi, "[color=$1]$2[/color]"); | |
243 | + | html = html.replace(/<link(.*?)>/gi, ""); | |
244 | + | html = html.replace(/<li(.*?)>(.*?)<\/li>/gi, "[*]$2"); | |
245 | + | html = html.replace(/<ul(.*?)>/gi, "[list]"); | |
246 | + | html = html.replace(/<\/ul>/gi, "[/list]"); | |
247 | + | html = html.replace(/<div>/gi, "\n"); | |
248 | + | html = html.replace(/<\/div>/gi, "\n"); | |
249 | + | html = html.replace(/<td(.*?)>/gi, " "); | |
250 | + | html = html.replace(/<tr(.*?)>/gi, "\n"); | |
251 | + | ||
252 | + | html = html.replace(/<img(.*?)src="(.*?)"(.*?)>/gi, "[img]$2[/img]"); | |
253 | + | html = html.replace(/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/gi, "[url=$2]$4[/url]"); | |
254 | + | ||
255 | + | html = html.replace(/<head>(.*?)<\/head>/gmi, ""); | |
256 | + | html = html.replace(/<object>(.*?)<\/object>/gmi, ""); | |
257 | + | html = html.replace(/<script(.*?)>(.*?)<\/script>/gmi, ""); | |
258 | + | html = html.replace(/<style(.*?)>(.*?)<\/style>/gmi, ""); | |
259 | + | html = html.replace(/<title>(.*?)<\/title>/gmi, ""); | |
260 | + | html = html.replace(/<!--(.*?)-->/gmi, "\n"); | |
261 | + | ||
262 | + | html = html.replace(/\/\//gi, "/"); | |
263 | + | html = html.replace(/http:\//gi, "http://"); | |
264 | + | ||
265 | + | html = html.replace(/<(?:[^>'"]*|(['"]).*?\1)*>/gmi, ""); | |
266 | + | html = html.replace(/\r\r/gi, ""); | |
267 | + | html = html.replace(/\[img]\//gi, "[img]"); | |
268 | + | html = html.replace(/\[url=\//gi, "[url="); | |
269 | + | ||
270 | + | html = html.replace(/(\S)\n/gi, "$1 "); | |
271 | + | ||
272 | + | return html; | |
273 | + | } | |
274 | + | ||
275 | + | function descriptionHandler() | |
276 | + | { | |
277 | + | const descriptionElem = document.querySelector('#torrent-description'); | |
278 | + | if (!descriptionElem) { | |
279 | + | return; | |
280 | + | } | |
281 | + | ||
282 | + | console.log(bbcodeConverter(descriptionElem.innerHTML)); | |
283 | + | ||
284 | + | const button = document.createElement('button'); | |
285 | + | button.textContent = '📋 Copy description as BBCode'; | |
286 | + | button.setAttribute('class', 'btn btn-primary'); | |
287 | + | button.addEventListener('click', function() { | |
288 | + | const origText = button.textContent; | |
289 | + | ||
290 | + | button.textContent = '✔ Copied!'; | |
291 | + | button.setAttribute('disabled', '1'); | |
292 | + | ||
293 | + | const descriptionBBcode = bbcodeConverter(descriptionElem.innerHTML).trim(); | |
294 | + | GM_setClipboard(descriptionBBcode); | |
295 | + | ||
296 | + | setTimeout( | |
297 | + | () => { | |
298 | + | button.textContent = origText; | |
299 | + | button.removeAttribute('disabled'); | |
300 | + | }, 1500 | |
301 | + | ); | |
302 | + | }); | |
303 | + | ||
304 | + | const panelHeading = document.createElement('div'); | |
305 | + | panelHeading.setAttribute('class', 'panel-heading'); | |
306 | + | panelHeading.insertAdjacentElement('beforeend', button); | |
307 | + | ||
308 | + | descriptionElem.insertAdjacentElement('beforebegin', panelHeading); | |
309 | + | } | |
310 | + | ||
311 | + | /** | |
312 | + | * Adds a clipboard icon (using Font Awesome 4) to each row that is marked for "mass copy". | |
313 | + | */ | |
314 | + | function addClipboardIconToRow() | |
315 | + | { | |
316 | + | const rows = document.querySelectorAll('.torrent-list > tbody > tr > td[colspan="2"]'); | |
317 | + | ||
318 | + | let currentAmount = 0; | |
319 | + | ||
320 | + | for (const row of rows) | |
321 | + | { | |
322 | + | currentAmount++; | |
323 | + | const iconExists = row.querySelector('a.clipboard-icon'); | |
324 | + | if (iconExists) { | |
325 | + | iconExists.remove(); | |
326 | + | } | |
327 | + | ||
328 | + | // Check if this row is past the point of "don't receive icon" | |
329 | + | if (currentAmount > copyAmount) { | |
330 | + | // `continue`, not `break` - If we break, then when we lower `copyAmount`, there will be extra rows with clipboard icon. | |
331 | + | continue; | |
332 | + | } | |
333 | + | ||
334 | + | row.insertAdjacentHTML('afterbegin', '<a href="#" class="comments clipboard-icon" style="margin-left: 0.5em;"><i class="fa fa-clipboard"></i></a>'); | |
335 | + | } | |
336 | + | } | |
337 | + | ||
338 | + | /** | |
339 | + | * Adds buttons and number input fields above torrent table, for "mass copying" links/magnets. | |
340 | + | */ | |
341 | + | function torrentListViewHandler() | |
342 | + | { | |
343 | + | const parentElement = document.querySelector('.table-responsive'); | |
344 | + | ||
345 | + | if (!parentElement) { | |
346 | + | return; | |
347 | + | } | |
348 | + | ||
349 | + | addClipboardIconToRow(); | |
350 | + | ||
351 | + | /** | |
352 | + | * Start: Copy all links/magnets | |
353 | + | */ | |
354 | + | const element = document.createElement('button'); | |
355 | + | element.innerHTML = '📋 Copy all download links <i class="fa fa-fw fa-download"></i>'; | |
356 | + | element.setAttribute('class', 'btn btn-default'); | |
357 | + | element.addEventListener('click', function() { | |
358 | + | const origText = element.innerHTML; | |
359 | + | ||
360 | + | element.innerHTML = '✔'; | |
361 | + | element.setAttribute('disabled', '1'); | |
362 | + | copyLinks(); | |
363 | + | ||
364 | + | setTimeout(() => { | |
365 | + | element.innerHTML = origText; | |
366 | + | element.removeAttribute('disabled'); | |
367 | + | }, 1500); | |
368 | + | }); | |
369 | + | ||
370 | + | const magnetCopy = document.createElement('button'); | |
371 | + | magnetCopy.innerHTML = '📋 Copy all magnets <i class="fa fa-fw fa-magnet"></i>'; | |
372 | + | magnetCopy.setAttribute('class', 'btn btn-default'); | |
373 | + | magnetCopy.addEventListener('click', function() { | |
374 | + | const origText = magnetCopy.innerHTML; | |
375 | + | ||
376 | + | magnetCopy.innerHTML = '✔'; | |
377 | + | magnetCopy.setAttribute('disabled', '1'); | |
378 | + | copyMagnets(); | |
379 | + | ||
380 | + | setTimeout(() => { | |
381 | + | magnetCopy.innerHTML = origText; | |
382 | + | magnetCopy.removeAttribute('disabled'); | |
383 | + | }, 1500); | |
384 | + | }); | |
385 | + | ||
386 | + | /** | |
387 | + | * End: Copy all links/magnets | |
388 | + | */ | |
389 | + | ||
390 | + | /** | |
391 | + | * Start: Copy X links/magnets | |
392 | + | */ | |
393 | + | const linkAmount = (getLinks()).length; | |
394 | + | copyAmount = linkAmount < 5 ? linkAmount : 5; | |
395 | + | const amountSelect = document.createElement('input'); | |
396 | + | amountSelect.setAttribute('type', 'number'); | |
397 | + | amountSelect.setAttribute('min', '2'); | |
398 | + | amountSelect.setAttribute('max', linkAmount); | |
399 | + | amountSelect.setAttribute('value', copyAmount); | |
400 | + | amountSelect.setAttribute('class', 'pull-right'); | |
401 | + | ||
402 | + | const amountCopyLinks = document.createElement('button'); | |
403 | + | amountCopyLinks.innerHTML = `📋 Copy ${copyAmount} download links <i class="fa fa-fw fa-download"></i>`; | |
404 | + | amountCopyLinks.setAttribute('class', 'btn btn-default pull-right'); | |
405 | + | amountCopyLinks.addEventListener('click', function() { | |
406 | + | const origText = amountCopyLinks.innerHTML; | |
407 | + | ||
408 | + | amountCopyLinks.innerHTML = '✔'; | |
409 | + | amountCopyLinks.setAttribute('disabled', '1'); | |
410 | + | copyLinks(copyAmount); | |
411 | + | ||
412 | + | setTimeout(() => { | |
413 | + | amountCopyLinks.innerHTML = origText; | |
414 | + | amountCopyLinks.removeAttribute('disabled'); | |
415 | + | }, 1500); | |
416 | + | }); | |
417 | + | ||
418 | + | const amountCopyMagnets = document.createElement('button'); | |
419 | + | amountCopyMagnets.innerHTML = `📋 Copy ${copyAmount} magnets <i class="fa fa-fw fa-magnet"></i>`; | |
420 | + | amountCopyMagnets.setAttribute('class', 'btn btn-default pull-right'); | |
421 | + | amountCopyMagnets.addEventListener('click', function() { | |
422 | + | const origText = amountCopyMagnets.innerHTML; | |
423 | + | ||
424 | + | amountCopyMagnets.innerHTML = '✔'; | |
425 | + | amountCopyMagnets.setAttribute('disabled', '1'); | |
426 | + | copyMagnets(copyAmount); | |
427 | + | ||
428 | + | setTimeout(() => { | |
429 | + | amountCopyMagnets.innerHTML = origText; | |
430 | + | amountCopyMagnets.removeAttribute('disabled'); | |
431 | + | }, 1500); | |
432 | + | }); | |
433 | + | ||
434 | + | amountSelect.addEventListener('change', function() { | |
435 | + | copyAmount = parseInt(amountSelect.value, 10); | |
436 | + | amountCopyLinks.innerHTML = `📋 Copy ${copyAmount} download links <i class="fa fa-fw fa-download"></i>`; | |
437 | + | amountCopyMagnets.innerHTML = `📋 Copy ${copyAmount} magnets <i class="fa fa-fw fa-magnet"></i>`; | |
438 | + | ||
439 | + | addClipboardIconToRow(); | |
440 | + | }); | |
441 | + | /** | |
442 | + | * End: Copy X links/magnets | |
443 | + | */ | |
444 | + | ||
445 | + | /** | |
446 | + | * Append all these buttons and inputs to the DOM. | |
447 | + | */ | |
448 | + | parentElement.insertAdjacentElement('beforebegin', element); | |
449 | + | parentElement.insertAdjacentElement('beforebegin', magnetCopy); | |
450 | + | ||
451 | + | parentElement.insertAdjacentElement('beforebegin', amountSelect); | |
452 | + | parentElement.insertAdjacentElement('beforebegin', amountCopyMagnets); | |
453 | + | parentElement.insertAdjacentElement('beforebegin', amountCopyLinks); | |
454 | + | } | |
455 | + | ||
456 | + | function init() { | |
457 | + | changeToCopy(); | |
458 | + | titleHandler(); | |
459 | + | descriptionHandler(); | |
460 | + | torrentListViewHandler(); | |
461 | + | } | |
462 | + | ||
463 | + | init(); |