mirror of
https://github.com/YGGverse/yggtracker-wanted-torrents-receiver.git
synced 2026-03-31 13:05:27 +00:00
initial commit
This commit is contained in:
parent
7f8b45d7fe
commit
636ed417a3
5 changed files with 309 additions and 1 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
.vscode
|
||||
storage/*
|
||||
129
README.md
129
README.md
|
|
@ -1,2 +1,129 @@
|
|||
# yggtracker-wanted-torrents-receiver
|
||||
Crontab script that allows to receive wanted torrents from multiple YGGtracker nodes
|
||||
|
||||
Crontab script that allows to receive wanted torrents from multiple [YGGtracker](https://github.com/YGGverse/YGGtracker) nodes
|
||||
|
||||
#### Install
|
||||
|
||||
Latest version of toolkit could be installed with single command:
|
||||
|
||||
`git clone https://github.com/YGGverse/yggtracker-wanted-torrents-receiver.git`
|
||||
|
||||
#### Config
|
||||
|
||||
All configuration files placed at `/config` folder
|
||||
|
||||
##### local.json
|
||||
|
||||
```
|
||||
{
|
||||
"import":
|
||||
{
|
||||
// Common rules for FTP connections
|
||||
"ftp":
|
||||
{
|
||||
// How many of seconds wait for each provider response
|
||||
"timeout":5,
|
||||
// Which of remote folders grab to
|
||||
// array of target directories for each provider, eg. all, sensitive/no, locale/en, etc
|
||||
"directories":
|
||||
[
|
||||
"all"
|
||||
]
|
||||
},
|
||||
// Requirements filter before import something from providers
|
||||
"require":
|
||||
{
|
||||
// Require approved torrents import only (according to provide.approved option in remote.json for each provider)
|
||||
"approved":true
|
||||
},
|
||||
// Local storage settings for imported content
|
||||
"storage":
|
||||
{
|
||||
// Storage directory by default, feel free to change like `/home/qbittorrent-nox/import`
|
||||
"directory":"storage",
|
||||
|
||||
// Copy all torrents imported from providers folders to the storage/_common/{hash}.torrent
|
||||
// This mode check files MD5 hash sum to prevent duplicates in single folder from different providers
|
||||
// Useful when bittorrent client does not support support listening of multiple folders, recursive mode
|
||||
"common":true
|
||||
}
|
||||
},
|
||||
"update":
|
||||
{
|
||||
"config":
|
||||
{
|
||||
// This option allows to auto-update remote.json file on the fly without updating codebase with git clone
|
||||
"remote":
|
||||
{
|
||||
// If disabled, local file will not be updated, but manually
|
||||
"enabled": true,
|
||||
|
||||
// Don't worry, just this repository
|
||||
"repository":"https://raw.githubusercontent.com/YGGverse/yggtracker-wanted-torrents-receiver/main/config/remote.json",
|
||||
|
||||
// How many seconds to wait before ask repository for remote.json updates (after last file write)
|
||||
"cache":86400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### remote.json
|
||||
|
||||
The remote configuration contains available YGGtracker providers.
|
||||
|
||||
File also could be auto-updated from this repository when owner enabled `update.config.remote.enabled` option in `local.json`
|
||||
that makes registry actualization simpler for recipients and providers, as update details without `git pull`.
|
||||
|
||||
```
|
||||
[
|
||||
{
|
||||
"description":
|
||||
{
|
||||
"name":"YGGtracker", // Used as storage subfolder
|
||||
"description":"YGGtracker official node", // Just provider description
|
||||
"url":"http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker/" // Provider's website
|
||||
},
|
||||
"ftp":
|
||||
{
|
||||
"host":"201:23b4:991a:634d:8359:4521:5576:15b7", // Connection host
|
||||
"port":21, // Connection port
|
||||
"passive":true, // Recommended passive mode for better compatibility
|
||||
"username":"anonymous", // YGGtracker instances usually provides public FTP access
|
||||
"password":"anonymous",
|
||||
"directory":"/yggtracker/torrents/wanted" // Directory where wanted torrent files placed
|
||||
},
|
||||
"provide":
|
||||
{
|
||||
"approved":true // Tells to receiver that node administrator check the torrents before send to API
|
||||
}
|
||||
}
|
||||
],
|
||||
...
|
||||
```
|
||||
|
||||
#### Usage
|
||||
|
||||
`php src/receiver.php`
|
||||
|
||||
or add to crontab:
|
||||
|
||||
`* * * * * /usr/bin/php src/receiver.php > /dev/null 2>&1`
|
||||
|
||||
#### Bash, python?
|
||||
|
||||
Feel free to contribute!
|
||||
|
||||
#### Add new YGGtracker node
|
||||
|
||||
Just send PR to nodes.json file
|
||||
|
||||
#### Feedback
|
||||
|
||||
Any questions and bug reports, please send to the [Issues](https://github.com/YGGverse/yggtracker-wanted-torrents-receiver/issues)!
|
||||
|
||||
#### See also
|
||||
|
||||
* [YGGtracker - BitTorrent Network for Yggdrasil](https://github.com/YGGverse/YGGtracker)
|
||||
* [YGGtracker Search Plugin for qBittorrent](https://github.com/YGGverse/qbittorrent-yggtracker-search-plugin)
|
||||
34
config/local.json
Normal file
34
config/local.json
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"import":
|
||||
{
|
||||
"ftp":
|
||||
{
|
||||
"timeout":5,
|
||||
"directories":
|
||||
[
|
||||
"all"
|
||||
]
|
||||
},
|
||||
"require":
|
||||
{
|
||||
"approved":true
|
||||
},
|
||||
"storage":
|
||||
{
|
||||
"directory":"storage",
|
||||
"common":true
|
||||
}
|
||||
},
|
||||
"update":
|
||||
{
|
||||
"config":
|
||||
{
|
||||
"remote":
|
||||
{
|
||||
"enabled": true,
|
||||
"repository":"https://raw.githubusercontent.com/YGGverse/yggtracker-wanted-torrents-receiver/main/config/remote.json",
|
||||
"cache":86400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
config/remote.json
Normal file
23
config/remote.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
[
|
||||
{
|
||||
"description":
|
||||
{
|
||||
"name":"YGGtracker",
|
||||
"description":"YGGtracker official node",
|
||||
"url":"http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker/"
|
||||
},
|
||||
"ftp":
|
||||
{
|
||||
"host":"201:23b4:991a:634d:8359:4521:5576:15b7",
|
||||
"port":21,
|
||||
"passive":true,
|
||||
"username":"anonymous",
|
||||
"password":"anonymous",
|
||||
"directory":"/yggtracker/torrents/wanted"
|
||||
},
|
||||
"provide":
|
||||
{
|
||||
"approved":true
|
||||
}
|
||||
}
|
||||
]
|
||||
122
src/cli.php
Normal file
122
src/cli.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
// Init PHP
|
||||
declare(strict_types=1);
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
// Prevent multi-thread execution
|
||||
$semaphore = sem_get(crc32('yggtracker-wanted-torrents-receiver'), 1);
|
||||
|
||||
if (false === sem_acquire($semaphore, true))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
// Init local config
|
||||
$local = json_decode(
|
||||
file_get_contents(__DIR__ . '/../config/local.json')
|
||||
);
|
||||
|
||||
// Init remote config
|
||||
if ($local->update->config->remote->enabled)
|
||||
{
|
||||
// Reset remote config cache
|
||||
if ($local->update->config->remote->cache + (int) filectime(__DIR__ . '/../config/remote.json') < time())
|
||||
{
|
||||
// Cache results
|
||||
if ($result = @file_get_contents($local->update->config->remote->repository))
|
||||
{
|
||||
file_put_contents(
|
||||
__DIR__ . '/../config/remote.json',
|
||||
$result
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sync remotes
|
||||
foreach (
|
||||
json_decode(
|
||||
file_get_contents(__DIR__ . '/../config/remote.json')
|
||||
) as $remote)
|
||||
{
|
||||
// Apply approved filters
|
||||
if ($local->import->require->approved && !$remote->provide->approved)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Connect remote
|
||||
if (!$connection = ftp_connect($remote->ftp->host, $remote->ftp->port, $local->import->ftp->timeout))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Login
|
||||
if (!ftp_login($connection, $remote->ftp->username, $remote->ftp->password))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Apply passive mode if required
|
||||
if (!ftp_pasv($connection, $remote->ftp->passive))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Navigate to wanted directory
|
||||
if (!ftp_chdir($connection, $remote->ftp->directory))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Scan directories
|
||||
foreach ($local->import->ftp->directories as $directory)
|
||||
{
|
||||
// Get torrents
|
||||
foreach (ftp_nlist($connection, $directory) as $torrent)
|
||||
{
|
||||
// Init provider directory
|
||||
@mkdir(
|
||||
$local->import->storage->directory . '/' . $remote->description->name . '/' . $directory,
|
||||
0755,
|
||||
true
|
||||
);
|
||||
|
||||
// Save torrents
|
||||
ftp_get(
|
||||
$connection,
|
||||
$local->import->storage->directory . '/' . $remote->description->name . '/' . $torrent,
|
||||
$torrent
|
||||
);
|
||||
|
||||
// Common storage mode enabled
|
||||
if ($local->import->storage->common)
|
||||
{
|
||||
// Init common folder
|
||||
@mkdir(
|
||||
$local->import->storage->directory . '/_common',
|
||||
0755,
|
||||
true
|
||||
);
|
||||
|
||||
// Prevent same file duplicates from different providers
|
||||
$hash = md5_file(
|
||||
$local->import->storage->directory . '/' . $remote->description->name . '/' . $torrent
|
||||
);
|
||||
|
||||
// Copy torrent file into the common directory if not exists yet
|
||||
if (!file_exists($local->import->storage->directory . '/_common/' . $hash . '.torrent'))
|
||||
{
|
||||
copy(
|
||||
$local->import->storage->directory . '/' . $remote->description->name . '/' . $torrent,
|
||||
$local->import->storage->directory . '/_common/' . $hash . '.torrent'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue