Browse Source

initial commit

main
ghost 1 year ago
parent
commit
636ed417a3
  1. 2
      .gitignore
  2. 129
      README.md
  3. 34
      config/local.json
  4. 23
      config/remote.json
  5. 122
      src/cli.php

2
.gitignore vendored

@ -0,0 +1,2 @@
.vscode
storage/*

129
README.md

@ -1,2 +1,129 @@
# yggtracker-wanted-torrents-receiver # 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

@ -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

@ -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

@ -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…
Cancel
Save