mirror of
https://github.com/leoherzog/TorrentParts.git
synced 2026-01-23 19:58:03 -08:00
Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddb4a7da06 | ||
|
|
8d81259d1a | ||
|
|
1440ac69a1 | ||
|
|
0651975b13 | ||
|
|
a94258296c | ||
|
|
66cb2914a1 | ||
|
|
de3c73f3c1 | ||
|
|
b1794f000b | ||
|
|
013318d258 | ||
|
|
93ef3186f2 | ||
|
|
7d2871abcb | ||
|
|
6e748cde77 | ||
|
|
2c728a61c2 | ||
|
|
7a9aa3bb10 | ||
|
|
aac24cfdd3 | ||
|
|
25eb970141 | ||
|
|
5244cd3710 | ||
|
|
28c2d03f55 | ||
|
|
cda94dd48a | ||
|
|
03c6ae0e17 | ||
|
|
006c8db5e6 | ||
|
|
43f63d8f22 | ||
|
|
9f26fb2384 | ||
|
|
92f5abdb96 | ||
|
|
8813e819c4 | ||
|
|
fa23c0ff3f | ||
|
|
a4152d0542 | ||
|
|
855e4140a0 | ||
|
|
c512101c4e | ||
|
|
e754ee965f | ||
|
|
5298bab66c | ||
|
|
acc6c5ba8c | ||
|
|
b150a2770a | ||
|
|
397d398f36 | ||
|
|
3ad1488a21 | ||
|
|
a47bd05d12 | ||
|
|
3daf51acca | ||
|
|
ad09499db9 | ||
|
|
b14ef98a23 | ||
|
|
85ffd7a9a0 | ||
|
|
73e99937b9 | ||
|
|
be414070b2 | ||
|
|
ffb1e250e4 | ||
|
|
6863553b66 | ||
|
|
f79c280de2 | ||
|
|
c654968116 | ||
|
|
a6a60a0722 | ||
|
|
753afdf70f | ||
|
|
6406bae502 | ||
|
|
26bb58ff05 | ||
|
|
233140a64e | ||
|
|
9ea7ac5a38 | ||
|
|
58f559ff78 | ||
|
|
9e53b06dd0 | ||
|
|
1687f59a71 | ||
|
|
69d9f807ed | ||
|
|
3d8efd6245 | ||
|
|
096919ec30 |
17
README.md
17
README.md
@@ -2,19 +2,21 @@
|
||||
|
||||
## What is this?
|
||||
|
||||
[BitTorrent](https://bittorrent.com/) is a ubiquitus and powerful way to transfer files peer-to-peer. To specify what file(s) to download with your client, you need to input either a Torrent file or Magnet link. [Torrent Parts](https://torrent.parts/) is a client-side static web app to read and edit the metadata of a Torrent file or Magnet link so you know what you're downloading, before you add it to your Torrent client.
|
||||
[BitTorrent](https://bittorrent.com/) is a ubiquitous and powerful way to transfer files peer-to-peer. To specify what file(s) to download with your client, you need to input either a Torrent file or Magnet URL. [Torrent Parts](https://torrent.parts/) is a client-side static web app to read and edit the metadata of a Torrent file or Magnet URL so you know what you're downloading, before you add it to your Torrent client.
|
||||
|
||||
### Features
|
||||
|
||||
- 📑 Display metadata of a Torrent file, Magnet link, or URL to a Torrent file ([CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) required)
|
||||
- 📑 Display metadata of a Torrent file, Magnet URL, or URL to a Torrent file ([CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) required)
|
||||
- 📝 Edit title, comment, Tracker URLs, and Webseeds
|
||||
- ↔️ Save and convert between Torrent file and Magnet link
|
||||
- 🔗 Generate link directly to [Torrent Parts](https://torrent.parts/) with prefilled info
|
||||
- ↔️ Save and convert between Torrent file and Magnet URL
|
||||
- 🔗 Generate a link directly to [Torrent Parts](https://torrent.parts/) with prefilled info<sup>[1]</sup>
|
||||
- 🌐 Add currently known working trackers from [newTrackon](https://newtrackon.com/)
|
||||
- 👥 Fetch files metadata for a Magnet link via [WebTorrent](https://webtorrent.io/)
|
||||
- 👥 Fetch files metadata for a Magnet URL via [WebTorrent](https://webtorrent.io/)
|
||||
- ℹ️ Learn the basic parts of Torrent metadata and what they mean
|
||||
- 🔒 Fully client-side, no files leave your computer
|
||||
|
||||
<sup>1. Just include the Magnet URL after `https://torrent.parts/#`, [like so](https://torrent.parts#magnet:?xt=urn:btih:9fc20b9e98ea98b4a35e6223041a5ef94ea27809&dn=ubuntu-20.04-desktop-amd64.iso&tr=https://torrent.ubuntu.com/announce&tr=https://ipv6.torrent.ubuntu.com/announce).</sup>
|
||||
|
||||
## Special Thanks
|
||||
|
||||
This project wouldn't be possible without the fantastic work of:
|
||||
@@ -23,7 +25,7 @@ This project wouldn't be possible without the fantastic work of:
|
||||
- [@cvisuri](https://github.com/cvisuri), for design work
|
||||
- [@CorralPeltzer](https://github.com/CorralPeltzer), for [`newTrackon`](https://github.com/CorralPeltzer/newTrackon)
|
||||
- [@substack](https://github.com/substack) and contributors, for [`Browserify`](https://github.com/browserify/browserify)
|
||||
- [Github Pages](https://pages.github.com/) hosting
|
||||
- [Cloudflare Pages](https://pages.cloudflare.com/) hosting
|
||||
|
||||
## License
|
||||
|
||||
@@ -45,9 +47,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
<a href="https://twitter.com/xd1936" target="_blank">
|
||||
<img src="https://herzog.tech/signature/twitter.svg.png" width="32px" />
|
||||
</a>
|
||||
<a href="https://facebook.com/xd1936" target="_blank">
|
||||
<img src="https://herzog.tech/signature/facebook.svg.png" width="32px" />
|
||||
</a>
|
||||
<a href="https://github.com/leoherzog" target="_blank">
|
||||
<img src="https://herzog.tech/signature/github.svg.png" width="32px" />
|
||||
</a>
|
||||
|
||||
File diff suppressed because one or more lines are too long
108
bin/bundle.min.js
vendored
Normal file
108
bin/bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
87
bundle.min.js
vendored
87
bundle.min.js
vendored
File diff suppressed because one or more lines are too long
53
ext/TorrentPartsFASubset.yaml
Normal file
53
ext/TorrentPartsFASubset.yaml
Normal file
@@ -0,0 +1,53 @@
|
||||
projectName: 'C:\Users\Leo\Desktop\TorrentPartsFASubset'
|
||||
version: 6.2.1
|
||||
icons:
|
||||
- magnet:
|
||||
- light
|
||||
- solid
|
||||
- duotone
|
||||
- file-lines:
|
||||
- light
|
||||
- regular
|
||||
- duotone
|
||||
- cloud-arrow-up:
|
||||
- solid
|
||||
- link:
|
||||
- light
|
||||
- solid
|
||||
- duotone
|
||||
- file-arrow-down:
|
||||
- solid
|
||||
- arrow-up-right-from-square:
|
||||
- solid
|
||||
- file:
|
||||
- regular
|
||||
- file-word:
|
||||
- regular
|
||||
- file-powerpoint:
|
||||
- regular
|
||||
- file-excel:
|
||||
- regular
|
||||
- file-zipper:
|
||||
- regular
|
||||
- file-csv:
|
||||
- regular
|
||||
- file-pdf:
|
||||
- regular
|
||||
- file-contract:
|
||||
- regular
|
||||
- file-audio:
|
||||
- regular
|
||||
- file-video:
|
||||
- regular
|
||||
- file-image:
|
||||
- regular
|
||||
- folder-tree:
|
||||
- regular
|
||||
- trash:
|
||||
- regular
|
||||
- xmark:
|
||||
- regular
|
||||
- circle-info:
|
||||
- regular
|
||||
- circle-plus:
|
||||
- regular
|
||||
BIN
ext/alata-latin-400.woff
Normal file
BIN
ext/alata-latin-400.woff
Normal file
Binary file not shown.
BIN
ext/alata-latin-400.woff2
Normal file
BIN
ext/alata-latin-400.woff2
Normal file
Binary file not shown.
6
ext/fa.min.js
vendored
Normal file
6
ext/fa.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
ext/notyf.min.js
vendored
Normal file
2
ext/notyf.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
img/TorrentParts-Icon-3x.png
Normal file
BIN
img/TorrentParts-Icon-3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
53
index.html
53
index.html
@@ -14,8 +14,10 @@
|
||||
<link href="/favicon.ico" rel="icon" />
|
||||
<link href="/img/TorrentParts-Icon-1x.png" rel="icon" type="image/png" sizes="128x128" />
|
||||
<link href="/img/TorrentParts-Icon-2x.png" rel="icon" type="image/png" sizes="256x256" />
|
||||
<link href="/img/TorrentParts-Icon-3x.png" rel="icon" type="image/png" sizes="512x512" />
|
||||
<link href="/img/TorrentParts-Icon-1x.png" rel="apple-touch-icon" type="image/png" sizes="128x128" />
|
||||
<link href="/img/TorrentParts-Icon-2x.png" rel="apple-touch-icon" type="image/png" sizes="256x256" />
|
||||
<link href="/img/TorrentParts-Icon-3x.png" rel="apple-touch-icon" type="image/png" sizes="512x512" />
|
||||
<meta name="msapplication-TileColor" content="#102030" />
|
||||
<meta name="msapplication-TileImage" content="/img/TorrentParts-Icon-2x.png" />
|
||||
<meta property="og:image" content="/img/TorrentParts-Social.png" />
|
||||
@@ -34,20 +36,14 @@
|
||||
|
||||
<title>Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link</title>
|
||||
|
||||
<link href="style.css" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Alata&display=swap" rel="stylesheet" />
|
||||
<link href="notyf.min.css" rel="stylesheet" />
|
||||
<script async src="https://kit.fontawesome.com/9ca49f101f.js"></script>
|
||||
<link href="/src/style.css" rel="stylesheet" />
|
||||
<link href="/ext/alata-latin-400.woff2" rel="preload" as="style">
|
||||
<link href="/ext/alata-latin-400.woff" rel="preload" as="style">
|
||||
<script async src="/ext/fa.min.js"></script>
|
||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||
<script src="notyf.min.js"></script>
|
||||
<script src="/ext/notyf.min.js"></script>
|
||||
|
||||
<script async defer src="https://www.googletagmanager.com/gtag/js?id=G-VT4953Z89H"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-VT4953Z89H');
|
||||
</script>
|
||||
<script async defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "6f97f49b4c384ee197a2f319cebec274"}'></script>
|
||||
|
||||
</head>
|
||||
|
||||
@@ -65,7 +61,7 @@
|
||||
Enter URL and press enter
|
||||
</label>
|
||||
|
||||
<input id="torrent" type="file" aria-label="Select Torrent file" />
|
||||
<input id="torrent" type="file" accept=".torrent" aria-label="Select Torrent file" />
|
||||
<label for="torrent">
|
||||
<span class="fas fa-cloud-upload" aria-hidden="true"></span> Select Torrent File
|
||||
</label>
|
||||
@@ -86,9 +82,14 @@
|
||||
</button>
|
||||
|
||||
<div id="share">
|
||||
<a id="openURLWrapper" target="_blank">
|
||||
<button id="openURL" aria-label="Open this Magnet URL in your Torrent client">
|
||||
<span class="fas fa-arrow-up-right-from-square fa-2x"></span>
|
||||
</button>
|
||||
</a>
|
||||
<div>
|
||||
<button id="copyURL" aria-label="Copy this torrent.parts link to the clipboard">
|
||||
<span class="fas fa-share-alt fa-2x" data-fa-transform="left-1"></span>
|
||||
<span class="fas fa-link fa-2x"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
@@ -136,7 +137,7 @@
|
||||
<label for="createdBy" style="display:none">Created By</label>
|
||||
</div>
|
||||
<div class="content">
|
||||
<input id="created" type="text" placeholder="Creation time unspecified" aria-label="Creation time" disabled />
|
||||
<input id="created" type="text" placeholder="Creation time unspecified" aria-label="Creation time" disabled required />
|
||||
<br />
|
||||
<input id="createdBy" type="text" placeholder="Creation client unspecified" aria-label="Creation client" disabled />
|
||||
</div>
|
||||
@@ -187,6 +188,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="property">
|
||||
<div class="labels">
|
||||
<div>
|
||||
<span class="info" data-tippy-content="Torrents take files and split them into equal size pieces to make them easy to share. Piece size is configurable when a Torrent file is made."><span class="far fa-info-circle"></span></span>
|
||||
<label for="pieces">Pieces</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<input id="pieces" type="text" placeholder="Not included in the URL/File provided" aria-label="Piece size and length" disabled required />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="property">
|
||||
<div class="labels">
|
||||
<div>
|
||||
@@ -203,10 +216,16 @@
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<a href="https://github.com/leoherzog/TorrentParts/releases" target="_blank">v1.0</a>
|
||||
<a href="https://github.com/leoherzog/TorrentParts/releases" target="_blank" rel="noopener">v1.2</a>
|
||||
</footer>
|
||||
|
||||
<script src="bundle.min.js"></script>
|
||||
<script src="/bin/bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => navigator.serviceWorker.register('/src/sw.js'));
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
{
|
||||
"src": "/img/TorrentParts-Icon-2x.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/img/TorrentParts-Icon-3x.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
}
|
||||
|
||||
2
notyf.min.css
vendored
2
notyf.min.css
vendored
File diff suppressed because one or more lines are too long
2
notyf.min.js
vendored
2
notyf.min.js
vendored
File diff suppressed because one or more lines are too long
40
package.json
40
package.json
@@ -1,34 +1,38 @@
|
||||
{
|
||||
"name": "torrentparts",
|
||||
"version": "0.0.1",
|
||||
"version": "1.2",
|
||||
"description": "📑 A website to inspect and edit Torrent files and Magnet URLs",
|
||||
"main": "bundle.js",
|
||||
"main": "bin/bundle.js",
|
||||
"dependencies": {
|
||||
"browserify": "latest",
|
||||
"Buffer": "latest",
|
||||
"bytes": "latest",
|
||||
"clipboard": "latest",
|
||||
"dropzone": "latest",
|
||||
"mime-types": "latest",
|
||||
"parse-torrent": "latest",
|
||||
"tippy.js": "latest",
|
||||
"webtorrent": "latest"
|
||||
"browserify": "^17.0.0",
|
||||
"bytes": "^3.1.2",
|
||||
"clipboard": "^2.0.10",
|
||||
"magnet-uri": "^6.2.0",
|
||||
"mime-types": "^2.1.35",
|
||||
"parse-torrent": "^9.1.4",
|
||||
"tippy.js": "^6.3.7",
|
||||
"webtorrent": "^1.8.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"notyf": "latest",
|
||||
"terser": "latest",
|
||||
"watchify": "latest"
|
||||
"buffer": "^6.0.3",
|
||||
"notyf": "^3.10.0",
|
||||
"terser": "^5.12.1",
|
||||
"watchify": "^4.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "watchify parse.js -o bundle.js",
|
||||
"compile": "browserify parse.js -o bundle.js",
|
||||
"minify": "terser bundle.js -c -m -o bundle.min.js",
|
||||
"build": "npm run compile && npm run minify"
|
||||
"watch": "watchify src/parse.js -o bin/bundle.js",
|
||||
"compile": "browserify src/parse.js -o bin/bundle.js",
|
||||
"minify": "terser bin/bundle.js -c -m -o bin/bundle.min.js",
|
||||
"build": "npm run compile && npm run minify",
|
||||
"update": "npm update -g && npm update && npm run build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/leoherzog/TorrentParts.git"
|
||||
},
|
||||
"glitch": {
|
||||
"projectType": "generated_static"
|
||||
},
|
||||
"author": "Leo Herzog",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
|
||||
2
robots.txt
Normal file
2
robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
@@ -1,6 +1,6 @@
|
||||
require('buffer');
|
||||
const clipboard = require('clipboard');
|
||||
const parser = require('parse-torrent');
|
||||
const Buffer = require('Buffer');
|
||||
const bytes = require('bytes');
|
||||
const mime = require('mime-types');
|
||||
const WebTorrent = require('webtorrent');
|
||||
@@ -27,12 +27,16 @@ var announce = document.getElementById('announce');
|
||||
var urlList = document.getElementById('urlList');
|
||||
var addWebseed = document.getElementById('addWebseed');
|
||||
var removeWebseeds = document.getElementById('removeWebseeds');
|
||||
var pieces = document.getElementById('pieces');
|
||||
var files = document.getElementById('filesBody');
|
||||
var getFiles = document.getElementById('getFiles');
|
||||
var openURLWrapper = document.getElementById('openURLWrapper');
|
||||
var openURL = document.getElementById('openURL');
|
||||
var copyURL = document.getElementById('copyURL');
|
||||
var copyMagnet = document.getElementById('copyMagnet');
|
||||
var downloadTorrentWrapper = document.getElementById('downloadTorrentWrapper');
|
||||
var downloadTorrent = document.getElementById('downloadTorrent');
|
||||
var openURLTooltip = tippy(openURL, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Open this Magnet URL in your Torrent client"});
|
||||
var copyURLTooltip = tippy(copyURL, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Copy torrent.parts link to clipboard"});
|
||||
var copyMagnetTooltip = tippy(copyMagnet, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Copy Magnet link to clipboard"});
|
||||
var downloadTorrentTooltip = tippy(downloadTorrentWrapper, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Download Torrent file"});
|
||||
@@ -62,10 +66,12 @@ var notyf = new Notyf({
|
||||
|
||||
function placeDownloadTooltips(e) {
|
||||
if (window.innerWidth > 1080) {
|
||||
openURLTooltip.setProps({"placement": "right"});
|
||||
copyURLTooltip.setProps({"placement": "right"});
|
||||
copyMagnetTooltip.setProps({"placement": "right"});
|
||||
downloadTorrentTooltip.setProps({"placement": "right"});
|
||||
} else {
|
||||
openURLTooltip.setProps({"placement": "top"});
|
||||
copyURLTooltip.setProps({"placement": "top"});
|
||||
copyMagnetTooltip.setProps({"placement": "top"});
|
||||
downloadTorrentTooltip.setProps({"placement": "top"});
|
||||
@@ -79,54 +85,78 @@ document.addEventListener('DOMContentLoaded', start);
|
||||
|
||||
function start() {
|
||||
|
||||
// magnet input
|
||||
document.getElementById('magnet').addEventListener('keyup', function(event) {
|
||||
event.preventDefault();
|
||||
if (event.key === "Enter") {
|
||||
source = "magnet";
|
||||
if (event.key === 'Enter') {
|
||||
source = 'magnet';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-magnet fa-fw"></span>';
|
||||
sourceTooltip.setContent("Currently loaded information sourced from Magnet URL");
|
||||
sourceTooltip.setContent('Currently loaded information sourced from Magnet URL');
|
||||
parse(magnet.value);
|
||||
}
|
||||
});
|
||||
|
||||
// torrent select button
|
||||
document.getElementById('torrent').addEventListener('change', function(event) {
|
||||
event.preventDefault();
|
||||
event.target.files[0].arrayBuffer().then(function(arrayBuffer) {
|
||||
source = "torrent-file";
|
||||
source = 'torrent-file';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-file-alt fa-fw"></span>';
|
||||
sourceTooltip.setContent("Currently loaded information sourced from Torrent file");
|
||||
sourceTooltip.setContent('Currently loaded information sourced from Torrent file');
|
||||
parse(Buffer.from(arrayBuffer));
|
||||
});
|
||||
});
|
||||
|
||||
// body drag-and-drop torrent file support
|
||||
document.addEventListener('dragover', function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
document.addEventListener('drop', function(event) {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.items[0].getAsFile().arrayBuffer().then(function(arrayBuffer) {
|
||||
source = 'torrent-file';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-file-alt fa-fw"></span>';
|
||||
sourceTooltip.setContent('Currently loaded information sourced from Torrent file');
|
||||
parse(Buffer.from(arrayBuffer));
|
||||
});
|
||||
});
|
||||
|
||||
// example buttons
|
||||
example1.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
notyf.success("Parsing Ubuntu 20.04 Magnet URL");
|
||||
parse("magnet:?xt=urn:btih:9fc20b9e98ea98b4a35e6223041a5ef94ea27809&dn=ubuntu-20.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce");
|
||||
notyf.success('Parsing Ubuntu 22.04 Magnet URL');
|
||||
source = 'magnet';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-magnet fa-fw"></span>';
|
||||
sourceTooltip.setContent('Currently loaded information sourced from Magnet URL');
|
||||
parse('magnet:?xt=urn:btih:2c6b6858d61da9543d4231a71db4b1c9264b0685&dn=ubuntu-22.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce');
|
||||
});
|
||||
|
||||
example2.addEventListener('click', async function(event) {
|
||||
event.preventDefault();
|
||||
notyf.success("Fetching and Parsing “The WIRED CD” Torrent File...");
|
||||
parseRemote("https://webtorrent.io/torrents/wired-cd.torrent");
|
||||
notyf.success('Fetching and Parsing “The WIRED CD” Torrent File...');
|
||||
source = 'remote-torrent-file';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-file-alt fa-fw"></span>';
|
||||
sourceTooltip.setContent('Currently loaded information sourced from remotely fetched Torrent file');
|
||||
parseRemote('https://webtorrent.io/torrents/wired-cd.torrent');
|
||||
});
|
||||
|
||||
example3.addEventListener('click', async function(event) {
|
||||
event.preventDefault();
|
||||
notyf.success("Parsing Jack Johnson Archive.org Torrent File");
|
||||
let response = await fetch("jj2008-06-14.mk4_archive.torrent");
|
||||
notyf.success('Parsing Jack Johnson Archive.org Torrent File');
|
||||
let response = await fetch('/ext/jj2008-06-14.mk4_archive.torrent');
|
||||
let arrayBuffer = await response.arrayBuffer();
|
||||
source = 'torrent-file';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-file-alt fa-fw"></span>';
|
||||
sourceTooltip.setContent('Currently loaded information sourced from Torrent file');
|
||||
parse(Buffer.from(arrayBuffer));
|
||||
});
|
||||
|
||||
// share buttons
|
||||
let copyurl = new clipboard('#copyURL');
|
||||
copyurl.on('success', function(e) {
|
||||
notyf.success('Copied site URL to clipboard!');
|
||||
console.info(e);
|
||||
gtag('event', 'share', {
|
||||
"method": "Copy URL",
|
||||
"content_id": e.text,
|
||||
});
|
||||
});
|
||||
copyurl.on('failure', function(e) {
|
||||
notyf.error('Problem copying to clipboard');
|
||||
@@ -136,16 +166,13 @@ function start() {
|
||||
let copymagnet = new clipboard('#copyMagnet');
|
||||
copymagnet.on('success', function(e) {
|
||||
notyf.success('Copied Magnet URL to clipboard!');
|
||||
gtag('event', 'share', {
|
||||
"method": "Copy Magnet",
|
||||
"content_id": e.text,
|
||||
});
|
||||
});
|
||||
copymagnet.on('failure', function(e) {
|
||||
notyf.error('Problem copying to clipboard');
|
||||
console.warn(e);
|
||||
});
|
||||
|
||||
// details field listeners
|
||||
name.addEventListener('input', propertyChange);
|
||||
name.addEventListener('change', propertyChange);
|
||||
name.addEventListener('reset', propertyChange);
|
||||
@@ -166,9 +193,9 @@ function start() {
|
||||
sourceTooltip.disable();
|
||||
|
||||
if (window.location.hash) {
|
||||
source = "shared-url";
|
||||
source = 'shared-url';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-link fa-fw"></span>';
|
||||
sourceTooltip.setContent("Currently loaded information sourced from shared torrent.parts link");
|
||||
sourceTooltip.setContent('Currently loaded information sourced from shared torrent.parts link');
|
||||
parse(window.location.hash.split('#')[1]);
|
||||
}
|
||||
|
||||
@@ -177,18 +204,18 @@ function start() {
|
||||
function parse(toLoad) {
|
||||
resetProperties();
|
||||
try {
|
||||
console.info("Attempting parse");
|
||||
console.info('Attempting parse');
|
||||
parsed = parser(toLoad);
|
||||
display();
|
||||
if (parsed.xs) {
|
||||
console.info("Magnet includes xs, attempting remote parse");
|
||||
console.info('Magnet includes xs, attempting remote parse');
|
||||
parseRemote(parsed.xs);
|
||||
}
|
||||
}
|
||||
catch(e) { // maybe they put a URL to a torrent file in the magnet box?
|
||||
console.warn(e);
|
||||
if (source == "magnet") {
|
||||
console.info("Attempting remote parse");
|
||||
if (source == 'magnet') {
|
||||
console.info('Attempting remote parse');
|
||||
parseRemote(toLoad);
|
||||
} else { // probably not. Just a bad file.
|
||||
notyf.error('Problem parsing input. Is this a .torrent file?');
|
||||
@@ -205,9 +232,9 @@ function parseRemote(toLoad) {
|
||||
resetProperties();
|
||||
return;
|
||||
}
|
||||
source = "remote-torrent-file";
|
||||
source = 'remote-torrent-file';
|
||||
originalSourceIcon.innerHTML = '<span class="fad fa-file-alt fa-fw"></span>';
|
||||
sourceTooltip.setContent("Currently loaded information sourced from remotely fetched Torrent file");
|
||||
sourceTooltip.setContent('Currently loaded information sourced from remotely fetched Torrent file');
|
||||
parsed = result;
|
||||
display();
|
||||
});
|
||||
@@ -218,17 +245,18 @@ function display() {
|
||||
console.log(parsed);
|
||||
|
||||
hash.value = parsed.infoHash;
|
||||
name.value = parsed.name ? parsed.name : "";
|
||||
name.value = parsed.name ? parsed.name : '';
|
||||
if (parsed.created) {
|
||||
created.value = parsed.created.toISOString().slice(0, 19);
|
||||
created.type = "datetime-local";
|
||||
created.type = 'datetime-local';
|
||||
} else {
|
||||
created.type = "text";
|
||||
created.type = 'text';
|
||||
}
|
||||
createdBy.value = parsed.createdBy ? "by " + parsed.createdBy : "";
|
||||
comment.value = parsed.comment ? parsed.comment : "";
|
||||
createdBy.value = parsed.createdBy ? ' by ' + parsed.createdBy : '';
|
||||
comment.value = parsed.comment ? parsed.comment : '';
|
||||
pieces.value = parsed.pieces ? parsed.pieces.length.toLocaleString() + ' ' + bytes.format(parsed.pieceLength, {"decimalPlaces": 1, "unitSeparator": " "}) + ' pieces (last piece ' + bytes.format(parsed.lastPieceLength, {"decimalPlaces": 1, "unitSeparator": " "}) + ')' : '';
|
||||
|
||||
announce.innerHTML = "";
|
||||
announce.innerHTML = '';
|
||||
if (parsed.announce && parsed.announce.length) {
|
||||
for (let i = 0; i < parsed.announce.length; i++) {
|
||||
let row = document.createElement('div');
|
||||
@@ -251,10 +279,10 @@ function display() {
|
||||
announce.appendChild(row);
|
||||
}
|
||||
// } else {
|
||||
// announce.innerHTML = "<em>No trackers specified in the URL/File provided</em>";
|
||||
// announce.innerHTML = '<em>No trackers specified in the URL/File provided</em>';
|
||||
}
|
||||
|
||||
urlList.innerHTML = "";
|
||||
urlList.innerHTML = '';
|
||||
if (parsed.urlList && parsed.urlList.length) {
|
||||
for (let i = 0; i < parsed.urlList.length; i++) {
|
||||
let row = document.createElement('div');
|
||||
@@ -277,26 +305,35 @@ function display() {
|
||||
urlList.appendChild(row);
|
||||
}
|
||||
// } else {
|
||||
// urlList.innerHTML = "<em>No webseed URLs in the URL/File provided</em>";
|
||||
// urlList.innerHTML = '<em>No webseed URLs in the URL/File provided</em>';
|
||||
}
|
||||
|
||||
files.innerHTML = "";
|
||||
files.innerHTML = '';
|
||||
if (parsed.files && parsed.files.length) {
|
||||
getFiles.style.display = "none";
|
||||
for (let file of parsed.files) {
|
||||
let icon = getFontAwesomeIconForMimetype(mime.lookup(file.name));
|
||||
files.appendChild(createFileRow(icon, file.name, file.length));
|
||||
getFiles.style.display = 'none';
|
||||
if (parsed.files.length < 100) {
|
||||
for (let file of parsed.files) {
|
||||
let icon = getFontAwesomeIconForMimetype(mime.lookup(file.name));
|
||||
files.appendChild(createFileRow(icon, file.name, file.length));
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
let icon = getFontAwesomeIconForMimetype(mime.lookup(parsed.files[i].name));
|
||||
files.appendChild(createFileRow(icon, parsed.files[i].name, parsed.files[i].length));
|
||||
}
|
||||
files.appendChild(createFileRow('', '...and another ' + (parsed.files.length - 100) + ' more files', ''));
|
||||
}
|
||||
files.appendChild(createFileRow('folder-tree', '', parsed.length));
|
||||
openURLWrapper.href = parser.toMagnetURI(parsed);
|
||||
downloadTorrentTooltip.setContent('Download Torrent file');
|
||||
downloadTorrent.addEventListener('click', saveTorrent);
|
||||
downloadTorrent.disabled = false;
|
||||
} else {
|
||||
if (client.torrents.length > 0) {
|
||||
getFiles.style.display = "none";
|
||||
getFiles.style.display = 'none';
|
||||
files.innerHTML = '<input type="text" placeholder="Attempting fetching of files from Webtorrent..." aria-label="Attempting fetching of files from Webtorrent..." disabled>';
|
||||
} else {
|
||||
getFiles.style.display = "block";
|
||||
getFiles.style.display = 'block';
|
||||
files.innerHTML = '<input type="text" placeholder="Not included in the URL/File provided" aria-label="Files information not included in the URL/File provided" disabled>';
|
||||
}
|
||||
downloadTorrentTooltip.setContent('Files metadata is required to generate a Torrent file. Try fetching files list from WebTorrent.');
|
||||
@@ -304,7 +341,7 @@ function display() {
|
||||
downloadTorrent.disabled = true;
|
||||
}
|
||||
|
||||
copyURL.setAttribute('data-clipboard-text', window.location.origin + "#" + parser.toMagnetURI(parsed));
|
||||
copyURL.setAttribute('data-clipboard-text', window.location.origin + '#' + parser.toMagnetURI(parsed));
|
||||
copyMagnet.setAttribute('data-clipboard-text', parser.toMagnetURI(parsed));
|
||||
|
||||
examples.style.display = 'none';
|
||||
@@ -313,27 +350,19 @@ function display() {
|
||||
window.location.hash = parser.toMagnetURI(parsed);
|
||||
|
||||
if (parsed.name) {
|
||||
document.title = "Torrent Parts | " + parsed.name;
|
||||
document.title = 'Torrent Parts | ' + parsed.name;
|
||||
} else {
|
||||
document.title = "Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link";
|
||||
document.title = 'Torrent Parts | Inspect and edit what\'s in your Torrent file or Magnet link';
|
||||
}
|
||||
|
||||
sourceTooltip.enable();
|
||||
|
||||
gtag('event', 'view_item', {
|
||||
items: [{
|
||||
"item_id": parsed.infoHash,
|
||||
"item_name": parsed.name,
|
||||
"item_category": source
|
||||
}]
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function createFileRow(icon, name, size) {
|
||||
let row = document.createElement('tr');
|
||||
let iconcell = document.createElement('td');
|
||||
iconcell.innerHTML = '<span class="far fa-' + icon + '"></span>';
|
||||
if (icon) iconcell.innerHTML = '<span class="far fa-' + icon + '"></span>';
|
||||
row.appendChild(iconcell);
|
||||
let namecell = document.createElement('td');
|
||||
namecell.innerHTML = name;
|
||||
@@ -347,37 +376,37 @@ function createFileRow(icon, name, size) {
|
||||
function getFontAwesomeIconForMimetype(mimetype) {
|
||||
if (!mimetype) return 'file';
|
||||
switch (true) {
|
||||
case mimetype.includes("msword"):
|
||||
case mimetype.includes("wordprocessingml"):
|
||||
case mimetype.includes("opendocument.text"):
|
||||
case mimetype.includes("abiword"):
|
||||
case mimetype.includes('msword'):
|
||||
case mimetype.includes('wordprocessingml'):
|
||||
case mimetype.includes('opendocument.text'):
|
||||
case mimetype.includes('abiword'):
|
||||
return 'file-word';
|
||||
case mimetype.includes("ms-excel"):
|
||||
case mimetype.includes("spreadsheet"):
|
||||
case mimetype.includes('ms-excel'):
|
||||
case mimetype.includes('spreadsheet'):
|
||||
return 'file-powerpoint';
|
||||
case mimetype.includes("powerpoint"):
|
||||
case mimetype.includes("presentation"):
|
||||
case mimetype.includes('powerpoint'):
|
||||
case mimetype.includes('presentation'):
|
||||
return 'file-powerpoint';
|
||||
case mimetype.includes("7z-"):
|
||||
case mimetype.includes("iso9660"):
|
||||
case mimetype.includes("zip"):
|
||||
case mimetype.includes("octet-stream"):
|
||||
case mimetype.includes('7z-'):
|
||||
case mimetype.includes('iso9660'):
|
||||
case mimetype.includes('zip'):
|
||||
case mimetype.includes('octet-stream'):
|
||||
return 'file-archive';
|
||||
case mimetype.includes("csv"):
|
||||
case mimetype.includes('csv'):
|
||||
return 'file-csv';
|
||||
case mimetype.includes("pdf"):
|
||||
case mimetype.includes('pdf'):
|
||||
return 'file-pdf';
|
||||
case mimetype.includes("font"):
|
||||
case mimetype.includes('font'):
|
||||
return 'file-contract';
|
||||
case mimetype.includes("text"):
|
||||
case mimetype.includes("subrip"):
|
||||
case mimetype.includes("vtt"):
|
||||
case mimetype.includes('text'):
|
||||
case mimetype.includes('subrip'):
|
||||
case mimetype.includes('vtt'):
|
||||
return 'file-alt';
|
||||
case mimetype.includes("audio"):
|
||||
case mimetype.includes('audio'):
|
||||
return 'file-audio';
|
||||
case mimetype.includes("image"):
|
||||
case mimetype.includes('image'):
|
||||
return 'file-image';
|
||||
case mimetype.includes("video"):
|
||||
case mimetype.includes('video'):
|
||||
return 'file-video';
|
||||
default:
|
||||
return 'file';
|
||||
@@ -386,46 +415,45 @@ function getFontAwesomeIconForMimetype(mimetype) {
|
||||
|
||||
function propertyChange(e) {
|
||||
if (this.dataset.group) {
|
||||
parsed[this.dataset.group][this.dataset.index] = this.value ? this.value : "";
|
||||
parsed[this.dataset.group][this.dataset.index] = this.value ? this.value : '';
|
||||
} else {
|
||||
parsed[this.id] = this.value ? this.value : "";
|
||||
parsed[this.id] = this.value ? this.value : '';
|
||||
}
|
||||
window.location.hash = parser.toMagnetURI(parsed);
|
||||
updateModified();
|
||||
}
|
||||
|
||||
function resetProperties() {
|
||||
document.getElementById('magnet').value = "";
|
||||
document.getElementById('torrent').value = "";
|
||||
document.getElementById('magnet').value = '';
|
||||
document.getElementById('torrent').value = '';
|
||||
examples.style.display = 'flex';
|
||||
properties.style.display = 'none';
|
||||
name.value = "";
|
||||
created.value = "";
|
||||
createdBy.value = "";
|
||||
comment.value = "";
|
||||
hash.value = "";
|
||||
announce.innerHTML = "";
|
||||
urlList.innerHTML = "";
|
||||
name.value = '';
|
||||
created.value = '';
|
||||
createdBy.value = '';
|
||||
comment.value = '';
|
||||
hash.value = '';
|
||||
announce.innerHTML = '';
|
||||
urlList.innerHTML = '';
|
||||
client.torrents.forEach(torrent => torrent.destroy());
|
||||
getFiles.style.display = "block";
|
||||
files.innerHTML = "";
|
||||
window.location.hash = "";
|
||||
copyURL.setAttribute('data-clipboard-text', "");
|
||||
copyMagnet.setAttribute('data-clipboard-text', "");
|
||||
document.title = "Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link";
|
||||
getFiles.style.display = 'block';
|
||||
files.innerHTML = '';
|
||||
window.location.hash = '';
|
||||
copyURL.setAttribute('data-clipboard-text', '');
|
||||
copyMagnet.setAttribute('data-clipboard-text', '');
|
||||
document.title = 'Torrent Parts | Inspect and edit what\'s in your Torrent file or Magnet link';
|
||||
sourceTooltip.disable();
|
||||
gtag('event', 'reset');
|
||||
}
|
||||
|
||||
async function addCurrentTrackers() {
|
||||
addTrackers.className = 'disabled';
|
||||
addTrackers.innerHTML = 'Adding...';
|
||||
try {
|
||||
let response = await fetch("https://newtrackon.com/api/100"); // get trackers with 100% uptime
|
||||
let response = await fetch('https://newtrackon.com/api/stable'); // get trackers with 95% uptime
|
||||
let trackers = await response.text();
|
||||
parsed.announce = parsed.announce.concat(trackers.split('\n\n'));
|
||||
parsed.announce.push("http://bt1.archive.org:6969/announce");
|
||||
parsed.announce.push("http://bt2.archive.org:6969/announce");
|
||||
parsed.announce.push('http://bt1.archive.org:6969/announce');
|
||||
parsed.announce.push('http://bt2.archive.org:6969/announce');
|
||||
parsed.announce = parsed.announce.filter((v,i) => v && parsed.announce.indexOf(v) === i); // remove duplicates and empties
|
||||
notyf.success('Added known working trackers from newTrackon');
|
||||
updateModified();
|
||||
@@ -437,11 +465,10 @@ async function addCurrentTrackers() {
|
||||
addTrackers.className = '';
|
||||
addTrackers.innerHTML = 'Add Known Working Trackers';
|
||||
display();
|
||||
gtag('event', 'add_trackers');
|
||||
}
|
||||
|
||||
function addRow() {
|
||||
parsed[this.dataset.type].unshift("");
|
||||
parsed[this.dataset.type].unshift('');
|
||||
display();
|
||||
}
|
||||
|
||||
@@ -458,23 +485,23 @@ function removeAllRows(type) {
|
||||
|
||||
function updateModified() {
|
||||
parsed.created = new Date();
|
||||
parsed.createdBy = "Torrent Parts <https://torrent.parts/>";
|
||||
parsed.createdBy = 'Torrent Parts <https://torrent.parts/>';
|
||||
if (parsed.created) {
|
||||
created.value = parsed.created.toISOString().slice(0, 19);
|
||||
created.type = "datetime-local";
|
||||
created.type = 'datetime-local';
|
||||
} else {
|
||||
created.type = "text";
|
||||
created.type = 'text';
|
||||
}
|
||||
createdBy.value = parsed.createdBy ? "by " + parsed.createdBy : "";
|
||||
createdBy.value = parsed.createdBy ? ' by ' + parsed.createdBy : '';
|
||||
}
|
||||
|
||||
function getFilesFromPeers() {
|
||||
console.info("Attempting fetching files from Webtorrent...");
|
||||
getFiles.style.display = "none";
|
||||
parsed.announce.push("wss://tracker.webtorrent.io");
|
||||
parsed.announce.push("wss://tracker.openwebtorrent.com");
|
||||
parsed.announce.push("wss://tracker.btorrent.xyz");
|
||||
parsed.announce.push("wss://tracker.fastcast.nz");
|
||||
console.info('Attempting fetching files from Webtorrent...');
|
||||
getFiles.style.display = 'none';
|
||||
parsed.announce.push('wss://tracker.webtorrent.io');
|
||||
parsed.announce.push('wss://tracker.openwebtorrent.com');
|
||||
parsed.announce.push('wss://tracker.btorrent.xyz');
|
||||
parsed.announce.push('wss://tracker.fastcast.nz');
|
||||
parsed.announce = parsed.announce.filter((v,i) => v && parsed.announce.indexOf(v) === i); // remove duplicates and empties
|
||||
client.add(parser.toMagnetURI(parsed), (torrent) => {
|
||||
parsed.info = Object.assign({}, torrent.info); // clone object
|
||||
@@ -488,7 +515,6 @@ function getFilesFromPeers() {
|
||||
torrent.destroy();
|
||||
});
|
||||
display();
|
||||
gtag('event', 'attempt_webtorrent_fetch');
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/36899900/2700296
|
||||
@@ -499,14 +525,10 @@ function saveTorrent() {
|
||||
let a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
let url = window.URL.createObjectURL(new Blob([data], { "type": "application/x-bittorrent" }));
|
||||
a.setAttribute("href", url);
|
||||
a.setAttribute("download", parsed.name + '.torrent');
|
||||
a.setAttribute('href', url);
|
||||
a.setAttribute('download', parsed.name + '.torrent');
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
a.remove();
|
||||
gtag('event', 'share', {
|
||||
"method": "Torrent Download",
|
||||
"content_id": parsed.name
|
||||
});
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
33
src/sw.js
Normal file
33
src/sw.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const assets = [
|
||||
'/',
|
||||
'/index.html',
|
||||
'/bin/bundle.min.js',
|
||||
'/src/style.css',
|
||||
'/ext/alata-latin-400.woff2',
|
||||
'/ext/alata-latin-400.woff',
|
||||
'/ext/fa.min.js',
|
||||
'/ext/notyf.min.js',
|
||||
'/ext/jj2008-06-14.mk4_archive.torrent'
|
||||
];
|
||||
|
||||
self.addEventListener('install', function(event) {
|
||||
event.waitUntil(
|
||||
caches.open('assets')
|
||||
.then(function(cache) {
|
||||
return cache.addAll(assets);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', function(event) {
|
||||
event.respondWith(
|
||||
caches.match(event.request)
|
||||
.then(function(response) {
|
||||
if (response) {
|
||||
return response;
|
||||
}
|
||||
return fetch(event.request);
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user