Compare commits

...

18 Commits

Author SHA1 Message Date
iyuu.cn
854121884b 新增转移成功跳校验、转移成功删除当前做种功能。 2020-02-18 14:48:35 +08:00
iyuu.cn
da88f3e7fc 新增种子删除上报功能! 2020-02-17 16:54:27 +08:00
iyuu.cn
3abc02d660 修改示例配置 2020-02-17 16:46:59 +08:00
iyuu.cn
339f1304c6 优化日志记录 2020-02-16 20:51:39 +08:00
iyuu.cn
c4df9899c8 修复transmission添加任务成功后,获取名字和id 2020-02-16 15:10:15 +08:00
iyuu.cn
6494351ff3 修复transmission返回值判断错误 2020-02-16 14:39:23 +08:00
iyuu.cn
e01dbfd601 审查代码,删除无用接口 2020-02-16 01:26:40 +08:00
iyuu.cn
940f948f43 增加客户端文件是否存在判断 2020-02-15 22:12:12 +08:00
iyuu.cn
958bef0dfa windows大小写不敏感,新增 2020-02-15 19:24:58 +08:00
iyuu.cn
ea74b96293 windows大小写不敏感,删除 2020-02-15 19:24:10 +08:00
iyuu.cn
94948610e4 优化瓷器cookie有效性检查 2020-02-15 19:20:12 +08:00
iyuu.cn
0f1605ffca 修改transmission首字母小写 2020-02-15 16:05:05 +08:00
iyuu.cn
33ff8a991a 优化工厂模式创建客户端实例
增加新功能:本地做种客户端转移
2020-02-15 09:20:41 +08:00
iyuu.cn
877616214c 新增本地转移做种客户端示例配置 2020-02-15 09:19:20 +08:00
iyuu.cn
aa4a8c76fe 升级php版本号 2020-02-12 14:50:05 +08:00
iyuu.cn
f6870a4e95 增加瓷器的第一次下载种子检测 2020-02-12 14:16:38 +08:00
iyuu.cn
e073f165ac 优化提示信息。echo对隐私信息脱敏 2020-02-09 23:20:20 +08:00
iyuu.cn
6144b8b301 更新Readme.md 2020-02-08 11:59:30 +08:00
14 changed files with 617 additions and 715 deletions

2
.gitignore vendored
View File

@@ -1,9 +1,9 @@
/torrent
/config/config.php
/config/sites.json
/php-7.2.12-nts
/*.bat
/*.sh
.idea
.php_cs.cache
vendor
php-7.4.2-nts-Win32-vc15-x86

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
<?php
/**
* Created by PhpStorm.
* User: David <367013672@qq.com>
* Date: 2020-2-14
* Time: 21:31:49
*/
namespace IYUU\Client;
abstract class AbstractClient
{
/**
* 公共方法:创建客户端实例
*/
public static function create($config = array())
{
$type = $config['type'];
$host = $config['host'];
$username = $config['username'];
$password = $config['password'];
$file = __DIR__ . DIRECTORY_SEPARATOR . $type . DIRECTORY_SEPARATOR . $type .'.php';
if (!is_file($file)) {
die($file.' 文件不存在');
}
$className = "\IYUU\Client\\" . $type . "\\" . $type;
if (class_exists($className)) {
echo $type." 客户端正在实例化!".PHP_EOL;
return new $className($host, $username, $password);
} else {
die($className.' 客户端不存在');
}
}
/**
* 查询Bittorrent客户端状态
*
* @return string
*/
abstract public function status();
/**
* 获取种子列表
* @return array(
'hash' => string json,
'sha1' => string,
'hashString '=> array
)
*/
abstract public function getList(&$move = array());
/**
* 添加种子连接
*/
abstract public function add($torrent_url, $save_path = '', $extra_options = array());
/**
* 添加种子原数据
*/
abstract public function add_metainfo($torrent_url, $save_path = '', $extra_options = array());
/**
* 删除种子
*/
abstract public function delete($hash, $deleteFiles = false);
}

View File

@@ -1,20 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 1/17/2020
* Time: 2020
*/
namespace IYUU\Client;
interface AbstractClientInterface
{
/**
* 查询Bittorrent客户端状态
*
* @return string
*/
public function status();
}

View File

@@ -2,12 +2,12 @@
namespace IYUU\Client\qBittorrent;
use Curl\Curl;
use IYUU\Client\AbstractClientInterface;
use IYUU\Client\AbstractClient;
/**
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation
*/
class qBittorrent implements AbstractClientInterface
class qBittorrent extends AbstractClient
{
private $debug;
private $url;
@@ -157,18 +157,12 @@ class qBittorrent implements AbstractClientInterface
#$extra_options['skip_checking'] = 'true'; //跳校验
// 关键 上传文件流 multipart/form-data【严格按照api文档编写】
$post_data = $this->buildData($extra_options);
#p($post_data);
// 设置请求头
$this->curl->setHeader('Content-Type', 'multipart/form-data; boundary='.$this->delimiter);
$this->curl->setHeader('Content-Length', strlen($post_data));
return $this->postData('torrent_add', $post_data);
}
public function torrentDelete($hash='', $deleteFiles = false)
{
return $this->postData('torrent_delete', ['hashes' => $hash, 'deleteFiles' => $deleteFiles ? 'true':'false']);
}
public function torrentDeleteAll($deleteFiles = false)
{
$torrents = json_decode($this->torrentList());
@@ -301,10 +295,56 @@ class qBittorrent implements AbstractClientInterface
}
/**
* @inheritDoc
* 抽象方法,子类实现
*/
public function status()
{
return $this->appVersion();
}
/**
* 抽象方法,子类实现
*/
public function getList(&$move = array())
{
$result = $this->getData('torrent_list');
$res = json_decode($result, true);
if (empty($res)) {
echo "获取种子列表失败可能qBittorrent暂时无响应请稍后重试".PHP_EOL;
return array();
}
// 过滤,只保留正常做种
$res = array_filter($res, function ($v) {
if (isset($v['state']) && in_array($v['state'], array('uploading','stalledUP','pausedUP','queuedUP','checkingUP','forcedUP'))) {
return true;
}
return false;
}, ARRAY_FILTER_USE_BOTH);
if (empty($res)) {
echo "未获取到正常做种数据,请多保种,然后重试!".PHP_EOL;
return array();
}
// 提取数组hashString
$info_hash = array_column($res, 'hash');
// 升序排序
sort($info_hash);
$json = json_encode($info_hash, JSON_UNESCAPED_UNICODE);
// 去重 应该从文件读入,防止重复提交
$sha1 = sha1($json);
// 组装返回数据
$hashArray['hash'] = $json;
$hashArray['sha1'] = $sha1;
// 变换数组hashString为键
$hashArray['hashString'] = array_column($res, "save_path", 'hash');
return $hashArray;
}
/**
* 抽象方法,子类实现
*/
public function delete($hash='', $deleteFiles = false)
{
return $this->postData('torrent_delete', ['hashes' => $hash, 'deleteFiles' => $deleteFiles ? 'true':'false']);
}
}

View File

@@ -6,7 +6,7 @@
* Time: 2020
*/
namespace IYUU\Client\Transmission;
namespace IYUU\Client\transmission;
/**
* This is the type of exception the TransmissionRPC class will throw

View File

@@ -26,9 +26,9 @@
* PHP Class support (PHP 5) (PHP 4 might work, untested)
*/
namespace IYUU\Client\Transmission;
namespace IYUU\Client\transmission;
use IYUU\Client\AbstractClientInterface;
use IYUU\Client\AbstractClient;
/**
* A friendly little version check...
@@ -47,19 +47,13 @@ if (version_compare(PHP_VERSION, '5.2.10', '<')) {
* </code>
*
*/
class TransmissionRPC implements AbstractClientInterface
class transmission extends AbstractClient
{
/**
* User agent used in all http communication
*/
const HTTP_UA = 'TransmissionRPC for PHP/0.3';
/**
* Minimum PHP version required
* 5.2.10 implemented the required http stream ignore_errors option
*/
const MIN_PHPVER = '5.2.10';
/**
* The URL to the bittorent client you want to communicate with
* the port (default: 9091) can be set in you Transmission preferences
@@ -79,12 +73,6 @@ class TransmissionRPC implements AbstractClientInterface
*/
public $password = '';
/**
* Return results as an array, or an object (default)
* @var bool
*/
public $return_as_array = false;
/**
* Print debugging information, default is off
* @var bool
@@ -139,29 +127,15 @@ class TransmissionRPC implements AbstractClientInterface
/**
* Takes the connection parameters
*
* TODO: Sanitize username, password, and URL
*
* @param string $url
* @param string $username
* @param string $password
*/
public function __construct($url = 'http://localhost:9091/transmission/rpc', $username = null, $password = null, $return_as_array = false)
public function __construct($url = 'http://127.0.0.1:9091/transmission/rpc', $username = null, $password = null)
{
// server URL
$this->url = $url;
// Username & password
$this->username = $username;
$this->password = $password;
// Get the Transmission RPC_version
$this->rpc_version = self::sget()->arguments->rpc_version;
// Return As Array
$this->return_as_array = $return_as_array;
// Reset X-Transmission-Session-Id so we (re)fetch one
$this->session_id = null;
}
/**
@@ -175,7 +149,7 @@ class TransmissionRPC implements AbstractClientInterface
{
if (!is_array($ids)) {
$ids = array($ids);
} // Convert $ids to an array if only a single id was passed
}
$request = array("ids" => $ids);
return $this->request("torrent-start", $request);
}
@@ -191,7 +165,7 @@ class TransmissionRPC implements AbstractClientInterface
{
if (!is_array($ids)) {
$ids = array($ids);
} // Convert $ids to an array if only a single id was passed
}
$request = array("ids" => $ids);
return $this->request("torrent-stop", $request);
}
@@ -207,7 +181,7 @@ class TransmissionRPC implements AbstractClientInterface
{
if (!is_array($ids)) {
$ids = array($ids);
} // Convert $ids to an array if only a single id was passed
}
$request = array("ids" => $ids);
return $this->request("torrent-reannounce", $request);
}
@@ -223,7 +197,7 @@ class TransmissionRPC implements AbstractClientInterface
{
if (!is_array($ids)) {
$ids = array($ids);
} // Convert $ids to an array if only a single id was passed
}
$request = array("ids" => $ids);
return $this->request("torrent-verify", $request);
}
@@ -358,6 +332,16 @@ class TransmissionRPC implements AbstractClientInterface
return $this->request("torrent-add", $extra_options);
}
/* Add a new torrent using a file path or a URL (For backwards compatibility)
* @param torrent_location The URL or path to the torrent file
* @param save_path Folder to save torrent in
* @param extra options Optional extra torrent options
*/
public function add($torrent_location, $save_path = '', $extra_options = array())
{
return $this->add_file($torrent_location, $save_path, $extra_options);
}
/**
* Add a torrent using the raw torrent data
*
@@ -377,16 +361,6 @@ class TransmissionRPC implements AbstractClientInterface
return $this->request("torrent-add", $extra_options);
}
/* Add a new torrent using a file path or a URL (For backwards compatibility)
* @param torrent_location The URL or path to the torrent file
* @param save_path Folder to save torrent in
* @param extra options Optional extra torrent options
*/
public function add($torrent_location, $save_path = '', $extra_options = array())
{
return $this->add_file($torrent_location, $save_path, $extra_options);
}
/**
* Remove torrent from transmission
*
@@ -395,7 +369,7 @@ class TransmissionRPC implements AbstractClientInterface
* @return mixed
* @throws TransmissionRPCException
*/
public function remove($ids, $delete_local_data = false)
public function delete($ids, $delete_local_data = false)
{
if (!is_array($ids)) {
$ids = array($ids);
@@ -594,7 +568,8 @@ class TransmissionRPC implements AbstractClientInterface
$array[$index] = ($value ? 1 : 0);
} // Store boolean values as 0 or 1
if (is_string($value)) {
if (mb_detect_encoding($value, "auto") !== 'UTF-8') {
$type = mb_detect_encoding($value, "auto");
if ($type !== 'UTF-8') {
$array[$index] = mb_convert_encoding($value, "UTF-8");
//utf8_encode( $value ); // Make sure all data is UTF-8 encoded for Transmission
}
@@ -603,50 +578,12 @@ class TransmissionRPC implements AbstractClientInterface
return $array;
}
/**
* Clean up the result object. Replaces all minus(-) characters in the object properties with underscores
* and converts any object with any all-digit property names to an array.
*
* @param object The request result to clean
* @returns array The cleaned object
* @return array|object
*/
protected function cleanResultObject($object)
{
// Prepare and cast object to array
$return_as_array = false;
$array = $object;
if (!is_array($array)) {
$array = (array)$array;
}
foreach ($array as $index => $value) {
if (is_array($array[$index]) || is_object($array[$index])) {
$array[$index] = $this->cleanResultObject($array[$index]); // Recursion
}
if (strstr($index, '-')) {
$valid_index = str_replace('-', '_', $index);
$array[$valid_index] = $array[$index];
unset($array[$index]);
$index = $valid_index;
}
// Might be an array, check index for digits, if so, an array should be returned
if (ctype_digit((string)$index)) {
$return_as_array = true;
}
if (empty($value)) {
unset($array[$index]);
}
}
// Return array cast to object
return $return_as_array ? $array : (object)$array;
}
/**
* 执行 rpc 请求
*
* @param string $method 请求类型/方法, 详见 $this->allowMethods
* @param array $arguments 附加参数, 可选
* @return mixed
* @return array
* @throws TransmissionRPCException
*/
protected function request($method, $arguments = array())
@@ -694,9 +631,9 @@ class TransmissionRPC implements AbstractClientInterface
curl_close($ch);
if (!$content) {
$content = json_encode(array('result' => 'failed'));
$content = array('result' => 'failed');
}
return $this->return_as_array ? json_decode($content, true) : $this->cleanResultObject(json_decode($content)); // Return the sanitized result
return json_decode($content, true);
}
/**
@@ -767,10 +704,56 @@ class TransmissionRPC implements AbstractClientInterface
}
/**
* @inheritDoc
* 抽象方法,子类实现
*/
public function status()
{
return isset($this->sstats()->result) ? $this->sstats()->result : 'error';
$rs = $this->sstats();
return isset($rs['result']) ? $rs['result'] : 'error';
}
/**
* 抽象方法,子类实现
*/
public function getList(&$move = array())
{
$ids = array();
$fields = array( "id", "status", "name", "hashString", "downloadDir", "torrentFile" );
$res = $this->get($ids, $fields);
if (isset($res['result']) && $res['result'] == 'success') {
// 成功
} else {
// 失败
echo "获取种子列表失败可能transmission暂时无响应请稍后重试".PHP_EOL;
return array();
}
if (empty($res['arguments']['torrents'])) {
echo "未获取到正常做种数据,请多保种,然后重试!".PHP_EOL;
return array();
}
$res = $res['arguments']['torrents'];
// 过滤,只保留正常做种
$res = array_filter($res, function ($v) {
return isset($v['status']) && $v['status']===6;
}, ARRAY_FILTER_USE_BOTH);
if (empty($res)) {
echo "未获取到正常做种数据,请多保种,然后重试!".PHP_EOL;
return array();
}
// 提取数组hashString
$info_hash = array_column($res, 'hashString');
// 升序排序
sort($info_hash);
$json = json_encode($info_hash, JSON_UNESCAPED_UNICODE);
// 去重 应该从文件读入,防止重复提交
$sha1 = sha1($json);
// 组装返回数据
$hashArray['hash'] = $json;
$hashArray['sha1'] = $sha1;
// 变换数组hashString为键
$hashArray['hashString'] = array_column($res, "downloadDir", 'hashString');
$move = array_column($res, null, 'hashString');
return $hashArray;
}
}

View File

@@ -343,24 +343,6 @@ function wlog($data='', $name = '', $path = '')
@fclose($file_pointer);
return $worldsnum;
}
/**
* transmission过滤函数只保留正常做种
*/
function filterStatus($v)
{
return isset($v['status']) && $v['status']===6;
}
/**
* qBittorrent过滤函数只保留正常做种
*/
function qbfilterStatus($v)
{
if (isset($v['state']) && in_array($v['state'], array('uploading','stalledUP','pausedUP','queuedUP','checkingUP','forcedUP'))) {
return true;
}
return false;
}
//PHP stdClass Object转array
function object_array($array)
@@ -439,7 +421,7 @@ function ShowTableSites($dir = 'Protocols', $filter = array())
break;
}
$data = [];
$i = $j = $k = 0;
$i = $j = $k = 0; //i列、j序号、k行
foreach (glob(APP_PATH.$dir.DS.'*.php') as $key => $start_file) {
$start_file = str_replace("\\", "/", $start_file);
$offset = strripos($start_file, '/');

View File

@@ -33,7 +33,8 @@ return array(
'host' => 'http://127.0.0.1:9091/transmission/rpc', // 警告注意transmission/rpc这段别动你只需要修改 127.0.0.1:9091
'username' => '',
'password' => '',
#'move' => 0, // 0不移动1移动并辅种2移动仅辅种自身3未定义4未定义
'BT_backup' => '/var/lib/transmission/torrents', // 移动做种:如果脚本与当前客户端不在一台机器,必须配置
'move' => 0, // 0不移动1移动并辅种2移动仅辅种自身3未定义
),
# 结束
# 开始
@@ -42,16 +43,21 @@ return array(
'host' => 'http://127.0.0.1:8083',
'username' => '',
'password' => '',
'BT_backup' => 'C:\Users\ASUS\AppData\Local\qBittorrent\BT_backup', // 移动做种:必须配置
'move' => 0, // 0不移动1移动并辅种2移动仅辅种自身3未定义
),
# 结束
// 全局客户端设置 结束
),
// 移动做种必须配置
'move' =>array(
'type' => 0, // 0保持不变1减2加3替换
'path' =>array(
// 当前路径 => 目标路径
'/downloads' => '/volume1',
),
'skip_check' => 0, //转移成功,跳校验
'delete_torrent' => 0, //转移成功,删除当前做种
),
'workingMode' => 0,
'watch' => '/volume1/downloads',
@@ -436,6 +442,27 @@ return array(
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// hdbits 序号46
'hdbits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// PTPBD 序号47
'ptpbd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// HD-T 序号48
'hd-torrents' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// 配置文件结束
);

View File

@@ -32,6 +32,13 @@ if (file_exists(ROOT_PATH."/config/config.php")) {
} else {
// 示例配置
$configALL = require_once ROOT_PATH . '/config/config.sample.php';
echo microtime(true).' 缺少config.php已载入config.sample.php示例配置。'.PHP_EOL;
echo microtime(true).' 请把配置文件改名为config.php以免后续版本升级覆盖配置'.PHP_EOL;
$t = 30;
do {
echo microtime(true)." 请把配置文件改名为config.php{$t}秒后继续...".PHP_EOL;
sleep(1);
} while (--$t > 0);
}
echo microtime(true).' 全局配置载入完成!'.PHP_EOL;
// 读取支持列表
@@ -40,7 +47,7 @@ if (is_file(ROOT_PATH . "/config/sites.json")) {
$configALL['sitesALL'] = json_decode($sitesJson, true);
echo microtime(true).' 支持站点JSON载入完成'.PHP_EOL;
}
echo microtime(true).' 正在加载composer包管理器...'.PHP_EOL;
require_once ROOT_PATH . '/vendor/autoload.php';
echo microtime(true).' composer依赖载入完成'.PHP_EOL;
global $argv;

View File

@@ -4,6 +4,5 @@ use IYUU\AutoReseed;
echo microtime(true).' IYUU自动辅种正在初始化...'.PHP_EOL;
AutoReseed::init();
$hashArray = AutoReseed::get();
AutoReseed::call($hashArray);
AutoReseed::call();
exit(0);

View File

@@ -42,14 +42,16 @@ IYUU自动辅种工具英文名IYUUAutoReseed是一款PHP语言编
## 下载源码
- github仓库https://github.com/ledccn/IYUUAutoReseed
- 码云仓库https://gitee.com/ledc/IYUUAutoReseed
- 仓库下载的源码缺少vendor目录可以去群内下载或者通过安装php包管理器composer进到源码目录内执行命令`composer install`会自动帮你安装vendor目录。
## 使用方法
详见Wiki
https://gitee.com/ledc/IYUUAutoReseed/wikis
https://gitee.com/ledc/IYUUAutoReseed/tree/master/wiki
## 接口文档
## 接口开发文档
http://api.iyuu.cn/docs.php?type=expand
@@ -112,6 +114,12 @@ http://api.iyuu.cn/docs.php?type=expand
| 小城流水 | ¥5元 | 2020年1月22日22:14 |
| 国旗(未署名) | ¥8.8元 | 2020年1月22日23:28 |
| 当下丶 | ¥100元 | 2020年1月28日1:45 |
| 陈君政 | ¥10元 | 2020年2月3日11:32 |
| 不寐夜游 | ¥10元 | 2020年2月8日17:17 |
| Jack | ¥10元 | 2020年2月13日08:05 |
| 陈伟平 | ¥28.88元 | 2020年2月13日12:35 |
| PhalApi Pro商业授权 | ¥-950元 | 2020年2月14日21:56 |
| jonnaszheng | ¥10元 | 2020年2月15日10:25 |
补充说明:

View File

@@ -1,4 +1,4 @@
@echo off
chcp 65001
%cd%\php-7.2.12-nts\php %cd%\iyuu.php
%cd%\php-7.4.2-nts-Win32-vc15-x86\php %cd%\iyuu.php
pause

View File

@@ -1,4 +1,4 @@
@echo off
chcp 65001
D:\IYUUAutoReseed\php-7.2.12-nts\php D:\IYUUAutoReseed\iyuu.php
D:\IYUUAutoReseed\php-7.4.2-nts-Win32-vc15-x86\php.exe D:\IYUUAutoReseed\iyuu.php
exit