tor-dl 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -47
- package/dist/cli/display.d.ts.map +1 -1
- package/dist/cli/display.js +9 -4
- package/dist/cli/display.js.map +1 -1
- package/dist/cli/parser.d.ts.map +1 -1
- package/dist/cli/parser.js +40 -12
- package/dist/cli/parser.js.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +39 -1
- package/dist/commands/search.js.map +1 -1
- package/dist/filters/seeds.d.ts +1 -1
- package/dist/filters/seeds.d.ts.map +1 -1
- package/dist/filters/seeds.js +4 -1
- package/dist/filters/seeds.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/help.txt +30 -0
- package/package.json +1 -1
- package/src/cli/display.ts +12 -5
- package/src/cli/parser.ts +117 -88
- package/src/commands/search.ts +47 -2
- package/src/filters/seeds.ts +4 -1
- package/src/types.ts +1 -0
package/README.md
CHANGED
|
@@ -1,28 +1,6 @@
|
|
|
1
1
|
# tor-dl
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<img src="https://img.shields.io/npm/v/tor-dl" alt="npm version">
|
|
5
|
-
<img src="https://img.shields.io/node-version/tor-dl" alt="node version">
|
|
6
|
-
<img src="https://img.shields.io/github/license/tor-dl" alt="license">
|
|
7
|
-
</p>
|
|
8
|
-
|
|
9
|
-
> A CLI torrent search tool. Search across multiple sources, open .torrent in browser, or copy magnet links to your clipboard.
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- 🔍 **Multi-Source Search** - Search across multiple torrent sources simultaneously
|
|
14
|
-
- 🎯 **Smart Filters** - Filter by category, seeders, size
|
|
15
|
-
- ⬇️ **Open in Browser** - Open .torrent files directly in your browser
|
|
16
|
-
- 📋 **Copy Magnet** - Copy magnet links to clipboard for use with your torrent client
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
git clone https://github.com/eaeoz/tor-dl.git
|
|
22
|
-
cd tor-dl
|
|
23
|
-
npm install
|
|
24
|
-
npm run build
|
|
25
|
-
```
|
|
3
|
+
A CLI torrent search tool. Search across multiple sources, open .torrent in browser, or copy magnet links to clipboard.
|
|
26
4
|
|
|
27
5
|
## Quick Start
|
|
28
6
|
|
|
@@ -30,13 +8,17 @@ npm run build
|
|
|
30
8
|
# Search for torrents
|
|
31
9
|
tor-dl search "movie title"
|
|
32
10
|
|
|
33
|
-
#
|
|
11
|
+
# Copy magnet link to clipboard
|
|
34
12
|
tor-dl o 3
|
|
13
|
+
|
|
14
|
+
# Show version
|
|
15
|
+
tor-dl --version
|
|
35
16
|
```
|
|
36
17
|
|
|
37
|
-
##
|
|
18
|
+
## Commands
|
|
38
19
|
|
|
39
|
-
###
|
|
20
|
+
### search <query>
|
|
21
|
+
Search for torrents across multiple sources.
|
|
40
22
|
|
|
41
23
|
```bash
|
|
42
24
|
tor-dl search <query> [options]
|
|
@@ -44,16 +26,32 @@ tor-dl search <query> [options]
|
|
|
44
26
|
|
|
45
27
|
**Options:**
|
|
46
28
|
|
|
47
|
-
| Flag | Description |
|
|
29
|
+
| Flag | Description | Example |
|
|
48
30
|
|------|-------------|---------|
|
|
49
|
-
| `-c, --cat <category>` | Category
|
|
50
|
-
| `-s, --min-seeds <number>` | Minimum seeders |
|
|
51
|
-
| `--
|
|
52
|
-
| `--
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
31
|
+
| `-c, --cat <category>` | Category to filter results | `all`, `movie`, `tv`, `anime`, `music`, `games`, `apps` |
|
|
32
|
+
| `-s, --min-seeds <number>` | Minimum number of seeders | `100` |
|
|
33
|
+
| `--max-seeds <number>` | Maximum number of seeders | `1000` |
|
|
34
|
+
| `--min-size <size>` | Minimum file size | `500MB`, `1GB`, `2GB` |
|
|
35
|
+
| `--max-size <size>` | Maximum file size | `5GB`, `10GB` |
|
|
36
|
+
| `-o, --sort <field>` | Sort results by field | `seeds`, `size`, `date` |
|
|
37
|
+
| `--order <order>` | Sort order | `asc` (low to high), `desc` (high to low) |
|
|
38
|
+
| `-l, --limit <number>` | Maximum results to return | `10`, `50`, `100` |
|
|
39
|
+
| `-S, --sources <sources>` | Sources to search (comma-separated) | `yts,thepiratebay,nyaa` |
|
|
40
|
+
|
|
41
|
+
**Available Categories:**
|
|
42
|
+
- `all` - Search all categories
|
|
43
|
+
- `movie` - Movies
|
|
44
|
+
- `tv` - TV shows
|
|
45
|
+
- `anime` - Anime (mainly Nyaa)
|
|
46
|
+
- `music` - Music
|
|
47
|
+
- `games` - Games
|
|
48
|
+
- `apps` - Applications
|
|
49
|
+
|
|
50
|
+
**Available Sources:**
|
|
51
|
+
- `yts` - YTS (Movies only)
|
|
52
|
+
- `eztv` - EZTV (TV shows)
|
|
53
|
+
- `thepiratebay` - The Pirate Bay (All categories)
|
|
54
|
+
- `nyaa` - Nyaa.si (Anime, Software)
|
|
57
55
|
|
|
58
56
|
**Examples:**
|
|
59
57
|
|
|
@@ -61,36 +59,89 @@ tor-dl search <query> [options]
|
|
|
61
59
|
# Basic search
|
|
62
60
|
tor-dl search "Blade Runner 2049"
|
|
63
61
|
|
|
64
|
-
#
|
|
65
|
-
tor-dl search "
|
|
62
|
+
# Search movies with minimum seeds
|
|
63
|
+
tor-dl search "movie" --cat movie --min-seeds 100
|
|
64
|
+
|
|
65
|
+
# Search with size limits
|
|
66
|
+
tor-dl search "linux" --min-size 500MB --max-size 2GB
|
|
67
|
+
|
|
68
|
+
# Search specific sources only
|
|
69
|
+
tor-dl search "game" -S yts,thepiratebay
|
|
66
70
|
|
|
67
|
-
#
|
|
68
|
-
tor-dl search "
|
|
71
|
+
# Sort by size (smallest first)
|
|
72
|
+
tor-dl search "documentary" --sort size --order asc
|
|
73
|
+
|
|
74
|
+
# Limit results to top 10
|
|
75
|
+
tor-dl search "podcast" -l 10
|
|
69
76
|
```
|
|
70
77
|
|
|
71
|
-
###
|
|
78
|
+
### o <number>
|
|
79
|
+
Copy .torrent URL or magnet link to clipboard for the selected result number.
|
|
72
80
|
|
|
73
81
|
```bash
|
|
74
82
|
tor-dl o <number>
|
|
75
83
|
```
|
|
76
84
|
|
|
77
|
-
|
|
85
|
+
After running a search, enter the result number to copy the link to your clipboard.
|
|
86
|
+
|
|
87
|
+
**Example:**
|
|
88
|
+
```bash
|
|
89
|
+
tor-dl search "python tutorial"
|
|
90
|
+
# Results displayed...
|
|
91
|
+
tor-dl o 5
|
|
92
|
+
# Magnet link copied to clipboard!
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### open <number>
|
|
96
|
+
Same as `o` command - opens .torrent in browser or copies magnet link.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
tor-dl open <number>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Options
|
|
103
|
+
|
|
104
|
+
| Flag | Description |
|
|
105
|
+
|------|-------------|
|
|
106
|
+
| `-v, --version` | Show version number |
|
|
107
|
+
| `-h, --help` | Show help information |
|
|
78
108
|
|
|
79
109
|
## Supported Sources
|
|
80
110
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
111
|
+
| Source | Categories | Description |
|
|
112
|
+
|--------|------------|-------------|
|
|
113
|
+
| YTS | movie | Movie torrents with direct .torrent download |
|
|
114
|
+
| The Pirate Bay | all | General torrent search |
|
|
115
|
+
| Nyaa | anime, tv | Anime and Japanese media |
|
|
116
|
+
| EZTV | tv | TV show torrents |
|
|
117
|
+
|
|
118
|
+
## Size Format
|
|
119
|
+
|
|
120
|
+
Size can be specified in various formats:
|
|
121
|
+
- `KB` - Kilobytes
|
|
122
|
+
- `MB` - Megabytes
|
|
123
|
+
- `GB` - Gigabytes
|
|
124
|
+
- `TB` - Terabytes
|
|
125
|
+
|
|
126
|
+
Examples: `500MB`, `1.5GB`, `2GB`
|
|
86
127
|
|
|
87
128
|
## Requirements
|
|
88
129
|
|
|
89
130
|
- Node.js >= 18.0.0
|
|
131
|
+
- npm
|
|
132
|
+
|
|
133
|
+
## Local Installation
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
git clone https://github.com/eaeoz/tor-dl.git
|
|
137
|
+
cd tor-dl
|
|
138
|
+
npm install
|
|
139
|
+
npm run build
|
|
140
|
+
```
|
|
90
141
|
|
|
91
142
|
## License
|
|
92
143
|
|
|
93
|
-
MIT License
|
|
144
|
+
MIT License
|
|
94
145
|
|
|
95
146
|
## Disclaimer
|
|
96
147
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/cli/display.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/cli/display.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAQzC,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAmC7D;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAYhE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjD"}
|
package/dist/cli/display.js
CHANGED
|
@@ -10,12 +10,14 @@ exports.displaySuccess = displaySuccess;
|
|
|
10
10
|
exports.displayInfo = displayInfo;
|
|
11
11
|
const chalk_1 = __importDefault(require("chalk"));
|
|
12
12
|
chalk_1.default.level = 1;
|
|
13
|
+
function makeClickable(url, text) {
|
|
14
|
+
return `\u001b]8;;${url}\u0007${text}\u001b]8;;\u0007`;
|
|
15
|
+
}
|
|
13
16
|
function displayResults(results) {
|
|
14
17
|
if (results.length === 0) {
|
|
15
18
|
console.log(chalk_1.default.yellow('No results found.'));
|
|
16
19
|
return;
|
|
17
20
|
}
|
|
18
|
-
console.log(chalk_1.default.gray('\nTip: "tor-dl o <number>" to open .torrent or copy magnet link\n'));
|
|
19
21
|
const out = (s) => process.stdout.write(s + '\n');
|
|
20
22
|
out('\n' + [
|
|
21
23
|
'┌─────┬───┬────────────────────────────────────────┬────────┬───────┬───────┬────────┐',
|
|
@@ -29,13 +31,16 @@ function displayResults(results) {
|
|
|
29
31
|
const peers = r.peers > 50 ? chalk_1.default.cyan(r.peers.toString().padStart(5)) : r.peers.toString().padStart(5);
|
|
30
32
|
const source = (r.source || 'unknown').slice(0, 6).padEnd(6);
|
|
31
33
|
const num = chalk_1.default.cyan(r.num.toString().padStart(3));
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
+
const url = r.torrentUrl || r.magnet || '';
|
|
35
|
+
const pageUrl = r.url || '';
|
|
36
|
+
const clickableName = url ? makeClickable(url, name.padEnd(38)) : name.padEnd(38);
|
|
37
|
+
const clickableLink = pageUrl ? makeClickable(pageUrl, chalk_1.default.green('✓')) : chalk_1.default.gray(' ');
|
|
38
|
+
out(`│ ${num} │ ${clickableLink} │ ${clickableName} │ ${size} │ ${seeds} │ ${peers} │ ${source} │`);
|
|
34
39
|
}
|
|
35
40
|
out('├─────┼───┼────────────────────────────────────────┼────────┼───────┼───────┼────────┤');
|
|
36
41
|
out('└─────┴───┴────────────────────────────────────────┴────────┴───────┴───────┴────────┘');
|
|
37
42
|
out('');
|
|
38
|
-
out(chalk_1.default.gray('
|
|
43
|
+
out(chalk_1.default.gray('Click name = open magnet/torrent | Click ✓ = open source page'));
|
|
39
44
|
}
|
|
40
45
|
function displayResultDetails(result) {
|
|
41
46
|
console.log(chalk_1.default.bold('\n--- Torrent Details ---'));
|
package/dist/cli/display.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/cli/display.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/cli/display.ts"],"names":[],"mappings":";;;;;AASA,wCAmCC;AAED,oDAYC;AAED,oCAEC;AAED,wCAEC;AAED,kCAEC;AAtED,kDAA0B;AAGzB,eAAa,CAAC,KAAK,GAAG,CAAC,CAAC;AAEzB,SAAS,aAAa,CAAC,GAAW,EAAE,IAAY;IAC9C,OAAO,aAAa,GAAG,SAAS,IAAI,kBAAkB,CAAC;AACzD,CAAC;AAED,SAAgB,cAAc,CAAC,OAAwB;IACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAE1D,GAAG,CAAC,IAAI,GAAG;QACT,wFAAwF;QACxF,wFAAwF;QACxF,wFAAwF;KACzF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEd,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3E,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC9D,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,eAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,eAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzK,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,eAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzG,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,eAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAErD,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;QAE5B,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClF,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,eAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE3F,GAAG,CAAC,KAAK,GAAG,MAAM,aAAa,MAAM,aAAa,MAAM,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC;IACtG,CAAC;IAED,GAAG,CAAC,wFAAwF,CAAC,CAAC;IAC9F,GAAG,CAAC,wFAAwF,CAAC,CAAC;IAC9F,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,SAAgB,oBAAoB,CAAC,MAAqB;IACxD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,SAAgB,YAAY,CAAC,OAAe;IAC1C,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC;AAChD,CAAC;AAED,SAAgB,cAAc,CAAC,OAAe;IAC5C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,WAAW,CAAC,OAAe;IACzC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;AAC1C,CAAC"}
|
package/dist/cli/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/cli/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAiB,MAAM,UAAU,CAAC;AAWvD,wBAAgB,WAAW,IAAI,YAAY,CAc1C;AAED,wBAAgB,YAAY,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/cli/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAiB,MAAM,UAAU,CAAC;AAWvD,wBAAgB,WAAW,IAAI,YAAY,CAc1C;AAED,wBAAgB,YAAY,IAAI,OAAO,CAuFtC"}
|
package/dist/cli/parser.js
CHANGED
|
@@ -64,27 +64,55 @@ function loadFilters() {
|
|
|
64
64
|
}
|
|
65
65
|
function createParser() {
|
|
66
66
|
const program = new commander_1.Command();
|
|
67
|
+
const filters = loadFilters();
|
|
68
|
+
const mainHelp = `
|
|
69
|
+
Categories: all, movie, tv, anime, music, games, apps
|
|
70
|
+
Sources:
|
|
71
|
+
yts - YTS (Movies) | eztv - EZTV (TV) | thepiratebay - The Pirate Bay | nyaa - Nyaa.si (Anime)`;
|
|
67
72
|
program
|
|
68
73
|
.name('tor-dl')
|
|
69
|
-
.description('CLI torrent search tool - search, open in browser, copy magnet links')
|
|
70
|
-
.version(getVersion(), '-v, --version')
|
|
74
|
+
.description('CLI torrent search tool - search, open in browser, copy magnet links' + mainHelp)
|
|
75
|
+
.version(getVersion(), '-v, --version')
|
|
76
|
+
.showHelpAfterError()
|
|
77
|
+
.showSuggestionAfterError();
|
|
71
78
|
program
|
|
72
79
|
.command('search <query>')
|
|
73
|
-
.description('Search for torrents')
|
|
74
|
-
.option('-c, --cat <category>', 'Category
|
|
75
|
-
.option('-s, --min-seeds <number>', 'Minimum
|
|
76
|
-
.option('--
|
|
77
|
-
.option('--
|
|
78
|
-
.option('-
|
|
79
|
-
.option('--
|
|
80
|
-
.option('
|
|
81
|
-
.option('--
|
|
80
|
+
.description('Search for torrents. Use -h after search term for examples: tor-dl search "movie" -h')
|
|
81
|
+
.option('-c, --cat <category>', 'Category (all|movie|tv|anime|music|games|apps)')
|
|
82
|
+
.option('-s, --min-seeds <number>', 'Minimum seeders', parseInt)
|
|
83
|
+
.option('--max-seeds <number>', 'Maximum seeders', parseInt)
|
|
84
|
+
.option('--min-size <size>', 'Min size (e.g. 500MB, 1GB)')
|
|
85
|
+
.option('--max-size <size>', 'Max size (e.g. 5GB)')
|
|
86
|
+
.option('-o, --sort <sortBy>', 'Sort by (seeds|size|date)')
|
|
87
|
+
.option('--order <order>', 'Order (asc|desc)')
|
|
88
|
+
.option('-l, --limit <number>', 'Max results (default: 50)', parseInt)
|
|
89
|
+
.option('-S, --sources <sources>', 'Sources (yts,eztv,thepiratebay,nyaa)')
|
|
90
|
+
.option('-h, --help', 'Show help with examples')
|
|
91
|
+
.allowUnknownOption()
|
|
92
|
+
.hook('preAction', (thisCommand) => {
|
|
93
|
+
const opts = thisCommand.opts();
|
|
94
|
+
if (opts.help || thisCommand.args.includes('-h')) {
|
|
95
|
+
console.log('');
|
|
96
|
+
console.log('Categories: all, movie, tv, anime, music, games, apps');
|
|
97
|
+
console.log('Sources:');
|
|
98
|
+
console.log(' yts - YTS (Movies)');
|
|
99
|
+
console.log(' eztv - EZTV (TV)');
|
|
100
|
+
console.log(' thepiratebay - The Pirate Bay');
|
|
101
|
+
console.log(' nyaa - Nyaa.si (Anime)');
|
|
102
|
+
console.log('');
|
|
103
|
+
console.log('Examples:');
|
|
104
|
+
console.log(' tor-dl search "movie" -c movie -s 100');
|
|
105
|
+
console.log(' tor-dl search "anime" --sources nyaa --max-size 2GB');
|
|
106
|
+
console.log(' tor-dl search "linux" --min-size 500MB -l 10');
|
|
107
|
+
process.exit(0);
|
|
108
|
+
}
|
|
109
|
+
})
|
|
82
110
|
.action(async (query, options) => {
|
|
83
|
-
const filters = loadFilters();
|
|
84
111
|
const searchOptions = {
|
|
85
112
|
query,
|
|
86
113
|
category: options.cat || filters.category,
|
|
87
114
|
minSeeds: options.minSeeds ?? filters.minSeeds,
|
|
115
|
+
maxSeeds: options.maxSeeds,
|
|
88
116
|
minSize: options.minSize || filters.minSize,
|
|
89
117
|
maxSize: options.maxSize || filters.maxSize,
|
|
90
118
|
sortBy: options.sort || filters.sortBy,
|
package/dist/cli/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/cli/parser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,kCAcC;AAED,
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/cli/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAoCxD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DzE"}
|
package/dist/commands/search.js
CHANGED
|
@@ -5,16 +5,53 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.searchCommand = searchCommand;
|
|
7
7
|
const ora_1 = __importDefault(require("ora"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
9
|
const registry_1 = require("../sources/registry");
|
|
9
10
|
const filters_1 = require("../filters");
|
|
10
11
|
const display_1 = require("../cli/display");
|
|
11
12
|
const engine_1 = require("../download/engine");
|
|
13
|
+
function displaySearchInfo(options, sources) {
|
|
14
|
+
console.log(chalk_1.default.gray('\n--- Search Parameters ---'));
|
|
15
|
+
const sourceNames = sources.map(s => s.name).join(', ');
|
|
16
|
+
console.log(chalk_1.default.white('Sources: ') + chalk_1.default.cyan(sourceNames));
|
|
17
|
+
console.log(chalk_1.default.white('Query: ') + chalk_1.default.cyan(options.query));
|
|
18
|
+
if (options.category) {
|
|
19
|
+
console.log(chalk_1.default.white('Category: ') + chalk_1.default.cyan(options.category));
|
|
20
|
+
}
|
|
21
|
+
if (options.minSeeds) {
|
|
22
|
+
const seeds = options.maxSeeds ? `${options.minSeeds} - ${options.maxSeeds}` : `${options.minSeeds}+`;
|
|
23
|
+
console.log(chalk_1.default.white('Seeds: ') + chalk_1.default.cyan(seeds));
|
|
24
|
+
}
|
|
25
|
+
if (options.minSize) {
|
|
26
|
+
console.log(chalk_1.default.white('Min Size: ') + chalk_1.default.cyan(options.minSize));
|
|
27
|
+
}
|
|
28
|
+
if (options.maxSize) {
|
|
29
|
+
console.log(chalk_1.default.white('Max Size: ') + chalk_1.default.cyan(options.maxSize));
|
|
30
|
+
}
|
|
31
|
+
if (options.sortBy) {
|
|
32
|
+
console.log(chalk_1.default.white('Sort: ') + chalk_1.default.cyan(`${options.sortBy} (${options.order})`));
|
|
33
|
+
}
|
|
34
|
+
if (options.limit) {
|
|
35
|
+
console.log(chalk_1.default.white('Limit: ') + chalk_1.default.cyan(options.limit.toString()));
|
|
36
|
+
}
|
|
37
|
+
console.log(chalk_1.default.gray('------------------------\n'));
|
|
38
|
+
}
|
|
12
39
|
async function searchCommand(options) {
|
|
13
40
|
const spinner = (0, ora_1.default)('Searching torrent sources...').start();
|
|
14
41
|
let sources = (0, registry_1.getEnabledSources)();
|
|
42
|
+
const validSourceNames = sources.map(s => s.name.toLowerCase());
|
|
15
43
|
if (options.sources && options.sources.length > 0) {
|
|
16
44
|
const requested = options.sources.map(s => s.toLowerCase());
|
|
45
|
+
const unknownSources = requested.filter(s => !validSourceNames.includes(s));
|
|
46
|
+
if (unknownSources.length > 0) {
|
|
47
|
+
spinner.warn(chalk_1.default.yellow(`Unknown sources: ${unknownSources.join(', ')}. Available: ${validSourceNames.join(', ')}`));
|
|
48
|
+
}
|
|
17
49
|
sources = sources.filter(s => requested.includes(s.name.toLowerCase()));
|
|
50
|
+
if (sources.length === 0) {
|
|
51
|
+
spinner.fail('No valid sources selected. Use --sources with valid names.');
|
|
52
|
+
console.log(chalk_1.default.cyan('\nAvailable sources:'), validSourceNames.join(', '));
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
18
55
|
}
|
|
19
56
|
const allResults = [];
|
|
20
57
|
for (const source of sources) {
|
|
@@ -30,7 +67,7 @@ async function searchCommand(options) {
|
|
|
30
67
|
spinner.succeed(`Search complete. Found ${allResults.length} results.`);
|
|
31
68
|
let filtered = (0, filters_1.filterByCategory)(allResults, options.category || 'all');
|
|
32
69
|
if (options.minSeeds && options.minSeeds > 0) {
|
|
33
|
-
filtered = (0, filters_1.filterBySeeds)(filtered, options.minSeeds);
|
|
70
|
+
filtered = (0, filters_1.filterBySeeds)(filtered, options.minSeeds, options.maxSeeds);
|
|
34
71
|
}
|
|
35
72
|
if (options.minSize || options.maxSize) {
|
|
36
73
|
filtered = (0, filters_1.filterBySize)(filtered, options.minSize, options.maxSize);
|
|
@@ -41,6 +78,7 @@ async function searchCommand(options) {
|
|
|
41
78
|
}
|
|
42
79
|
filtered = filtered.map((r, i) => ({ ...r, num: i + 1 }));
|
|
43
80
|
(0, engine_1.cacheResults)(filtered);
|
|
81
|
+
displaySearchInfo(options, sources);
|
|
44
82
|
(0, display_1.displayResults)(filtered);
|
|
45
83
|
}
|
|
46
84
|
//# sourceMappingURL=search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
|
package/dist/filters/seeds.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { TorrentResult } from '../types';
|
|
2
|
-
export declare function filterBySeeds(results: TorrentResult[], minSeeds?: number): TorrentResult[];
|
|
2
|
+
export declare function filterBySeeds(results: TorrentResult[], minSeeds?: number, maxSeeds?: number): TorrentResult[];
|
|
3
3
|
//# sourceMappingURL=seeds.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seeds.d.ts","sourceRoot":"","sources":["../../src/filters/seeds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,GAAE,MAAU,GAAG,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"seeds.d.ts","sourceRoot":"","sources":["../../src/filters/seeds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,GAAE,MAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAKhH"}
|
package/dist/filters/seeds.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.filterBySeeds = filterBySeeds;
|
|
4
|
-
function filterBySeeds(results, minSeeds = 0) {
|
|
4
|
+
function filterBySeeds(results, minSeeds = 0, maxSeeds) {
|
|
5
|
+
if (maxSeeds) {
|
|
6
|
+
return results.filter(r => r.seeds >= minSeeds && r.seeds <= maxSeeds);
|
|
7
|
+
}
|
|
5
8
|
return results.filter(r => r.seeds >= minSeeds);
|
|
6
9
|
}
|
|
7
10
|
//# sourceMappingURL=seeds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seeds.js","sourceRoot":"","sources":["../../src/filters/seeds.ts"],"names":[],"mappings":";;AAEA,
|
|
1
|
+
{"version":3,"file":"seeds.js","sourceRoot":"","sources":["../../src/filters/seeds.ts"],"names":[],"mappings":";;AAEA,sCAKC;AALD,SAAgB,aAAa,CAAC,OAAwB,EAAE,WAAmB,CAAC,EAAE,QAAiB;IAC7F,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC;AAClD,CAAC"}
|
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnE,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnE,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD"}
|
package/help.txt
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Usage: tor-dl search [options] <query>
|
|
2
|
+
|
|
3
|
+
Search for torrents across multiple sources
|
|
4
|
+
|
|
5
|
+
Options:
|
|
6
|
+
-c, --cat <category> Category: all, movie, tv, anime, music, games, apps
|
|
7
|
+
-s, --min-seeds <number> Minimum seeders (e.g., 100)
|
|
8
|
+
--max-seeds <number> Maximum seeders (e.g., 1000)
|
|
9
|
+
--min-size <size> Minimum size (e.g., 500MB, 1GB, 2GB)
|
|
10
|
+
--max-size <size> Maximum size (e.g., 5GB, 10GB)
|
|
11
|
+
-o, --sort <sortBy> Sort by: seeds, size, date
|
|
12
|
+
--order <order> Sort order: asc (low to high), desc (high to low)
|
|
13
|
+
-l, --limit <number> Maximum results to return (default: 50)
|
|
14
|
+
--sources <sources> Sources: yts, eztv, thepiratebay, nyaa
|
|
15
|
+
(comma-separated)
|
|
16
|
+
-h, --help display help for command
|
|
17
|
+
|
|
18
|
+
Available Categories:
|
|
19
|
+
all, movie, tv, anime, music, games, apps
|
|
20
|
+
|
|
21
|
+
Available Sources:
|
|
22
|
+
yts - YTS (Movies only)
|
|
23
|
+
eztv - EZTV (TV shows)
|
|
24
|
+
thepiratebay - The Pirate Bay (All categories)
|
|
25
|
+
nyaa - Nyaa.si (Anime, Japanese media)
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
tor-dl search "movie" --cat movie --min-seeds 100
|
|
29
|
+
tor-dl search "anime" --sources nyaa --max-size 2GB
|
|
30
|
+
tor-dl search "linux" --min-size 500MB --max-size 2GB -l 10
|
package/package.json
CHANGED
package/src/cli/display.ts
CHANGED
|
@@ -3,14 +3,16 @@ import { TorrentResult } from '../types';
|
|
|
3
3
|
|
|
4
4
|
(chalk as any).level = 1;
|
|
5
5
|
|
|
6
|
+
function makeClickable(url: string, text: string): string {
|
|
7
|
+
return `\u001b]8;;${url}\u0007${text}\u001b]8;;\u0007`;
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
export function displayResults(results: TorrentResult[]): void {
|
|
7
11
|
if (results.length === 0) {
|
|
8
12
|
console.log(chalk.yellow('No results found.'));
|
|
9
13
|
return;
|
|
10
14
|
}
|
|
11
15
|
|
|
12
|
-
console.log(chalk.gray('\nTip: "tor-dl o <number>" to open .torrent or copy magnet link\n'));
|
|
13
|
-
|
|
14
16
|
const out = (s: string) => process.stdout.write(s + '\n');
|
|
15
17
|
|
|
16
18
|
out('\n' + [
|
|
@@ -26,15 +28,20 @@ export function displayResults(results: TorrentResult[]): void {
|
|
|
26
28
|
const peers = r.peers > 50 ? chalk.cyan(r.peers.toString().padStart(5)) : r.peers.toString().padStart(5);
|
|
27
29
|
const source = (r.source || 'unknown').slice(0, 6).padEnd(6);
|
|
28
30
|
const num = chalk.cyan(r.num.toString().padStart(3));
|
|
29
|
-
|
|
31
|
+
|
|
32
|
+
const url = r.torrentUrl || r.magnet || '';
|
|
33
|
+
const pageUrl = r.url || '';
|
|
34
|
+
|
|
35
|
+
const clickableName = url ? makeClickable(url, name.padEnd(38)) : name.padEnd(38);
|
|
36
|
+
const clickableLink = pageUrl ? makeClickable(pageUrl, chalk.green('✓')) : chalk.gray(' ');
|
|
30
37
|
|
|
31
|
-
out(`│ ${num} │ ${
|
|
38
|
+
out(`│ ${num} │ ${clickableLink} │ ${clickableName} │ ${size} │ ${seeds} │ ${peers} │ ${source} │`);
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
out('├─────┼───┼────────────────────────────────────────┼────────┼───────┼───────┼────────┤');
|
|
35
42
|
out('└─────┴───┴────────────────────────────────────────┴────────┴───────┴───────┴────────┘');
|
|
36
43
|
out('');
|
|
37
|
-
out(chalk.gray('
|
|
44
|
+
out(chalk.gray('Click name = open magnet/torrent | Click ✓ = open source page'));
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
export function displayResultDetails(result: TorrentResult): void {
|
package/src/cli/parser.ts
CHANGED
|
@@ -1,89 +1,118 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { readFileSync, existsSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
import { FilterConfig, SearchOptions } from '../types';
|
|
5
|
-
|
|
6
|
-
function getVersion(): string {
|
|
7
|
-
try {
|
|
8
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));
|
|
9
|
-
return pkg.version || '1.0.0';
|
|
10
|
-
} catch {
|
|
11
|
-
return '1.0.0';
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function loadFilters(): FilterConfig {
|
|
16
|
-
const filtersPath = join(process.cwd(), 'filters.json');
|
|
17
|
-
if (existsSync(filtersPath)) {
|
|
18
|
-
return JSON.parse(readFileSync(filtersPath, 'utf-8'));
|
|
19
|
-
}
|
|
20
|
-
return {
|
|
21
|
-
category: 'all',
|
|
22
|
-
minSeeds: 0,
|
|
23
|
-
minSize: '0',
|
|
24
|
-
maxSize: '50GB',
|
|
25
|
-
sortBy: 'seeds',
|
|
26
|
-
order: 'desc',
|
|
27
|
-
limit: 50
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function createParser(): Command {
|
|
32
|
-
const program = new Command();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
.
|
|
43
|
-
.
|
|
44
|
-
.
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
.
|
|
50
|
-
.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { readFileSync, existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { FilterConfig, SearchOptions } from '../types';
|
|
5
|
+
|
|
6
|
+
function getVersion(): string {
|
|
7
|
+
try {
|
|
8
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));
|
|
9
|
+
return pkg.version || '1.0.0';
|
|
10
|
+
} catch {
|
|
11
|
+
return '1.0.0';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function loadFilters(): FilterConfig {
|
|
16
|
+
const filtersPath = join(process.cwd(), 'filters.json');
|
|
17
|
+
if (existsSync(filtersPath)) {
|
|
18
|
+
return JSON.parse(readFileSync(filtersPath, 'utf-8'));
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
category: 'all',
|
|
22
|
+
minSeeds: 0,
|
|
23
|
+
minSize: '0',
|
|
24
|
+
maxSize: '50GB',
|
|
25
|
+
sortBy: 'seeds',
|
|
26
|
+
order: 'desc',
|
|
27
|
+
limit: 50
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createParser(): Command {
|
|
32
|
+
const program = new Command();
|
|
33
|
+
const filters = loadFilters();
|
|
34
|
+
|
|
35
|
+
const mainHelp = `
|
|
36
|
+
Categories: all, movie, tv, anime, music, games, apps
|
|
37
|
+
Sources:
|
|
38
|
+
yts - YTS (Movies) | eztv - EZTV (TV) | thepiratebay - The Pirate Bay | nyaa - Nyaa.si (Anime)`;
|
|
39
|
+
|
|
40
|
+
program
|
|
41
|
+
.name('tor-dl')
|
|
42
|
+
.description('CLI torrent search tool - search, open in browser, copy magnet links' + mainHelp)
|
|
43
|
+
.version(getVersion(), '-v, --version')
|
|
44
|
+
.showHelpAfterError()
|
|
45
|
+
.showSuggestionAfterError();
|
|
46
|
+
|
|
47
|
+
program
|
|
48
|
+
.command('search <query>')
|
|
49
|
+
.description('Search for torrents. Use -h after search term for examples: tor-dl search "movie" -h')
|
|
50
|
+
.option('-c, --cat <category>', 'Category (all|movie|tv|anime|music|games|apps)')
|
|
51
|
+
.option('-s, --min-seeds <number>', 'Minimum seeders', parseInt)
|
|
52
|
+
.option('--max-seeds <number>', 'Maximum seeders', parseInt)
|
|
53
|
+
.option('--min-size <size>', 'Min size (e.g. 500MB, 1GB)')
|
|
54
|
+
.option('--max-size <size>', 'Max size (e.g. 5GB)')
|
|
55
|
+
.option('-o, --sort <sortBy>', 'Sort by (seeds|size|date)')
|
|
56
|
+
.option('--order <order>', 'Order (asc|desc)')
|
|
57
|
+
.option('-l, --limit <number>', 'Max results (default: 50)', parseInt)
|
|
58
|
+
.option('-S, --sources <sources>', 'Sources (yts,eztv,thepiratebay,nyaa)')
|
|
59
|
+
.option('-h, --help', 'Show help with examples')
|
|
60
|
+
.allowUnknownOption()
|
|
61
|
+
.hook('preAction', (thisCommand) => {
|
|
62
|
+
const opts = thisCommand.opts();
|
|
63
|
+
if (opts.help || thisCommand.args.includes('-h')) {
|
|
64
|
+
console.log('');
|
|
65
|
+
console.log('Categories: all, movie, tv, anime, music, games, apps');
|
|
66
|
+
console.log('Sources:');
|
|
67
|
+
console.log(' yts - YTS (Movies)');
|
|
68
|
+
console.log(' eztv - EZTV (TV)');
|
|
69
|
+
console.log(' thepiratebay - The Pirate Bay');
|
|
70
|
+
console.log(' nyaa - Nyaa.si (Anime)');
|
|
71
|
+
console.log('');
|
|
72
|
+
console.log('Examples:');
|
|
73
|
+
console.log(' tor-dl search "movie" -c movie -s 100');
|
|
74
|
+
console.log(' tor-dl search "anime" --sources nyaa --max-size 2GB');
|
|
75
|
+
console.log(' tor-dl search "linux" --min-size 500MB -l 10');
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.action(async (query: string, options) => {
|
|
80
|
+
|
|
81
|
+
const searchOptions: SearchOptions = {
|
|
82
|
+
query,
|
|
83
|
+
category: options.cat || filters.category,
|
|
84
|
+
minSeeds: options.minSeeds ?? filters.minSeeds,
|
|
85
|
+
maxSeeds: options.maxSeeds,
|
|
86
|
+
minSize: options.minSize || filters.minSize,
|
|
87
|
+
maxSize: options.maxSize || filters.maxSize,
|
|
88
|
+
sortBy: (options.sort as 'seeds' | 'size' | 'date') || filters.sortBy,
|
|
89
|
+
order: (options.order as 'asc' | 'desc') || filters.order,
|
|
90
|
+
limit: options.limit || filters.limit,
|
|
91
|
+
sources: options.sources ? options.sources.split(',') : undefined
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const { searchCommand } = await import('../commands/search');
|
|
95
|
+
await searchCommand(searchOptions);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const openCmd = program.command('open <number>', { hidden: true });
|
|
99
|
+
openCmd.description('Open .torrent in browser or copy magnet to clipboard');
|
|
100
|
+
openCmd.action(async (number: string) => {
|
|
101
|
+
const { openInBrowser } = await import('../commands/download');
|
|
102
|
+
await openInBrowser(parseInt(number));
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const oCmd = program.command('o <number>');
|
|
106
|
+
oCmd.description('Open .torrent in browser or copy magnet to clipboard');
|
|
107
|
+
oCmd.action(async (number: string) => {
|
|
108
|
+
const { openInBrowser } = await import('../commands/download');
|
|
109
|
+
await openInBrowser(parseInt(number));
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
program.on('command:*', () => {
|
|
113
|
+
console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args[0]);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return program;
|
|
89
118
|
}
|
package/src/commands/search.ts
CHANGED
|
@@ -1,18 +1,62 @@
|
|
|
1
1
|
import ora from 'ora';
|
|
2
|
+
import chalk from 'chalk';
|
|
2
3
|
import { SearchOptions, TorrentResult } from '../types';
|
|
3
4
|
import { getEnabledSources } from '../sources/registry';
|
|
4
5
|
import { filterByCategory, filterBySize, filterBySeeds, sortResults } from '../filters';
|
|
5
|
-
import { displayResults
|
|
6
|
+
import { displayResults } from '../cli/display';
|
|
6
7
|
import { cacheResults } from '../download/engine';
|
|
7
8
|
|
|
9
|
+
function displaySearchInfo(options: SearchOptions, sources: any[]): void {
|
|
10
|
+
console.log(chalk.gray('\n--- Search Parameters ---'));
|
|
11
|
+
|
|
12
|
+
const sourceNames = sources.map(s => s.name).join(', ');
|
|
13
|
+
console.log(chalk.white('Sources: ') + chalk.cyan(sourceNames));
|
|
14
|
+
console.log(chalk.white('Query: ') + chalk.cyan(options.query));
|
|
15
|
+
|
|
16
|
+
if (options.category) {
|
|
17
|
+
console.log(chalk.white('Category: ') + chalk.cyan(options.category));
|
|
18
|
+
}
|
|
19
|
+
if (options.minSeeds) {
|
|
20
|
+
const seeds = options.maxSeeds ? `${options.minSeeds} - ${options.maxSeeds}` : `${options.minSeeds}+`;
|
|
21
|
+
console.log(chalk.white('Seeds: ') + chalk.cyan(seeds));
|
|
22
|
+
}
|
|
23
|
+
if (options.minSize) {
|
|
24
|
+
console.log(chalk.white('Min Size: ') + chalk.cyan(options.minSize));
|
|
25
|
+
}
|
|
26
|
+
if (options.maxSize) {
|
|
27
|
+
console.log(chalk.white('Max Size: ') + chalk.cyan(options.maxSize));
|
|
28
|
+
}
|
|
29
|
+
if (options.sortBy) {
|
|
30
|
+
console.log(chalk.white('Sort: ') + chalk.cyan(`${options.sortBy} (${options.order})`));
|
|
31
|
+
}
|
|
32
|
+
if (options.limit) {
|
|
33
|
+
console.log(chalk.white('Limit: ') + chalk.cyan(options.limit.toString()));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(chalk.gray('------------------------\n'));
|
|
37
|
+
}
|
|
38
|
+
|
|
8
39
|
export async function searchCommand(options: SearchOptions): Promise<void> {
|
|
9
40
|
const spinner = ora('Searching torrent sources...').start();
|
|
10
41
|
|
|
11
42
|
let sources = getEnabledSources();
|
|
43
|
+
const validSourceNames = sources.map(s => s.name.toLowerCase());
|
|
12
44
|
|
|
13
45
|
if (options.sources && options.sources.length > 0) {
|
|
14
46
|
const requested = options.sources.map(s => s.toLowerCase());
|
|
47
|
+
const unknownSources = requested.filter(s => !validSourceNames.includes(s));
|
|
48
|
+
|
|
49
|
+
if (unknownSources.length > 0) {
|
|
50
|
+
spinner.warn(chalk.yellow(`Unknown sources: ${unknownSources.join(', ')}. Available: ${validSourceNames.join(', ')}`));
|
|
51
|
+
}
|
|
52
|
+
|
|
15
53
|
sources = sources.filter(s => requested.includes(s.name.toLowerCase()));
|
|
54
|
+
|
|
55
|
+
if (sources.length === 0) {
|
|
56
|
+
spinner.fail('No valid sources selected. Use --sources with valid names.');
|
|
57
|
+
console.log(chalk.cyan('\nAvailable sources:'), validSourceNames.join(', '));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
16
60
|
}
|
|
17
61
|
|
|
18
62
|
const allResults: TorrentResult[] = [];
|
|
@@ -32,7 +76,7 @@ export async function searchCommand(options: SearchOptions): Promise<void> {
|
|
|
32
76
|
let filtered = filterByCategory(allResults, options.category || 'all');
|
|
33
77
|
|
|
34
78
|
if (options.minSeeds && options.minSeeds > 0) {
|
|
35
|
-
filtered = filterBySeeds(filtered, options.minSeeds);
|
|
79
|
+
filtered = filterBySeeds(filtered, options.minSeeds, options.maxSeeds);
|
|
36
80
|
}
|
|
37
81
|
|
|
38
82
|
if (options.minSize || options.maxSize) {
|
|
@@ -49,5 +93,6 @@ export async function searchCommand(options: SearchOptions): Promise<void> {
|
|
|
49
93
|
|
|
50
94
|
cacheResults(filtered);
|
|
51
95
|
|
|
96
|
+
displaySearchInfo(options, sources);
|
|
52
97
|
displayResults(filtered);
|
|
53
98
|
}
|
package/src/filters/seeds.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { TorrentResult } from '../types';
|
|
2
2
|
|
|
3
|
-
export function filterBySeeds(results: TorrentResult[], minSeeds: number = 0): TorrentResult[] {
|
|
3
|
+
export function filterBySeeds(results: TorrentResult[], minSeeds: number = 0, maxSeeds?: number): TorrentResult[] {
|
|
4
|
+
if (maxSeeds) {
|
|
5
|
+
return results.filter(r => r.seeds >= minSeeds && r.seeds <= maxSeeds);
|
|
6
|
+
}
|
|
4
7
|
return results.filter(r => r.seeds >= minSeeds);
|
|
5
8
|
}
|