优化工厂模式创建客户端实例

增加新功能:本地做种客户端转移
This commit is contained in:
iyuu.cn
2020-02-15 09:19:42 +08:00
parent 877616214c
commit 33ff8a991a
7 changed files with 327 additions and 486 deletions

View File

@ -0,0 +1,63 @@
<?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'];
$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

@ -28,7 +28,7 @@
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

@ -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;
@ -164,11 +164,6 @@ class qBittorrent implements AbstractClientInterface
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 +296,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']);
}
}