diff --git a/.gitignore b/.gitignore
index 8ddbddc..df534e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@
/php-7.2.12-nts
/*.bat
/*.sh
-/vendor
\ No newline at end of file
+/vendor
diff --git a/app/Class/Function.php b/app/Class/Function.php
index 77ce203..a444bdd 100644
--- a/app/Class/Function.php
+++ b/app/Class/Function.php
@@ -2,23 +2,24 @@
/**
* 调试函数
*/
-function p($data, $echo=true){
- $str='******************************'."\n";
- // 如果是boolean或者null直接显示文字;否则print
- if (is_bool($data)) {
- $show_data=$data ? 'true' : 'false';
- }elseif (is_null($data)) {
- $show_data='null';
- }else{
- $show_data=print_r($data,true);
- }
- $str.=$show_data;
- $str.="\n".'******************************'."\n";
- if($echo){
- echo $str;
- return null;
- }
- return $str;
+function p($data, $echo=true)
+{
+ $str='******************************'."\n";
+ // 如果是boolean或者null直接显示文字;否则print
+ if (is_bool($data)) {
+ $show_data=$data ? 'true' : 'false';
+ } elseif (is_null($data)) {
+ $show_data='null';
+ } else {
+ $show_data=print_r($data, true);
+ }
+ $str.=$show_data;
+ $str.="\n".'******************************'."\n";
+ if ($echo) {
+ echo $str;
+ return null;
+ }
+ return $str;
}
/**
@@ -26,21 +27,21 @@ function p($data, $echo=true){
*/
function sc($text='', $desp='')
{
- global $configALL;
- $token = $configALL['sc.ftqq.com'];
- $desp = ($desp=='')?date("Y-m-d H:i:s") :$desp;
- $postdata = http_build_query(array(
- 'text' => $text,
- 'desp' => $desp
- ));
- $opts = array('http' => array(
- 'method' => 'POST',
- 'header' => 'Content-type: application/x-www-form-urlencoded',
- 'content' => $postdata
- ));
- $context = stream_context_create($opts);
- $result = file_get_contents('http://sc.ftqq.com/'.$token.'.send', false, $context);
- return $result;
+ global $configALL;
+ $token = $configALL['sc.ftqq.com'];
+ $desp = ($desp=='')?date("Y-m-d H:i:s") :$desp;
+ $postdata = http_build_query(array(
+ 'text' => $text,
+ 'desp' => $desp
+ ));
+ $opts = array('http' => array(
+ 'method' => 'POST',
+ 'header' => 'Content-type: application/x-www-form-urlencoded',
+ 'content' => $postdata
+ ));
+ $context = stream_context_create($opts);
+ $result = file_get_contents('http://sc.ftqq.com/'.$token.'.send', false, $context);
+ return $result;
}
/**
@@ -48,72 +49,72 @@ function sc($text='', $desp='')
*/
function ff($text='', $desp='')
{
- global $configALL;
- $token = $configALL['iyuu.cn'];
- $desp = ($desp=='')?date("Y-m-d H:i:s") :$desp;
- $postdata = http_build_query(array(
- 'text' => $text,
- 'desp' => $desp
- ));
- $opts = array('http' => array(
- 'method' => 'POST',
- 'header' => 'Content-type: application/x-www-form-urlencoded',
- 'content' => $postdata
- ));
- $context = stream_context_create($opts);
- $result = file_get_contents('http://iyuu.cn/'.$token.'.send', false, $context);
- return $result;
+ global $configALL;
+ $token = $configALL['iyuu.cn'];
+ $desp = ($desp=='')?date("Y-m-d H:i:s") :$desp;
+ $postdata = http_build_query(array(
+ 'text' => $text,
+ 'desp' => $desp
+ ));
+ $opts = array('http' => array(
+ 'method' => 'POST',
+ 'header' => 'Content-type: application/x-www-form-urlencoded',
+ 'content' => $postdata
+ ));
+ $context = stream_context_create($opts);
+ $result = file_get_contents('http://iyuu.cn/'.$token.'.send', false, $context);
+ return $result;
}
/**
* 微信推送 爱语飞飞
* @param array $torrent 种子数组
- Array
- (
- [id] => 118632
- [h1] => CCTV5+ 2019 ATP Men's Tennis Final 20191115B HDTV 1080i H264-HDSTV
- [title] => 央视体育赛事频道 2019年ATP男子网球年终总决赛 单打小组赛 纳达尔VS西西帕斯 20191115[优惠剩余时间:4时13分]
- [details] => https://xxx.me/details.php?id=118632
- [download] => https://xxx.me/download.php?id=118632
- [filename] => 118632.torrent
- [type] => 0
- [sticky] => 1
- [time] => Array
- (
- [0] => "2019-11-16 20:41:53">4时13分
- [1] => "2019-11-16 14:41:53">1时
46分
- )
- [comments] => 0
- [size] => 5232.64MB
- [seeders] => 69
- [leechers] => 10
- [completed] => 93
- [percentage] => 100%
- [owner] => 匿名
- )
+ Array
+ (
+ [id] => 118632
+ [h1] => CCTV5+ 2019 ATP Men's Tennis Final 20191115B HDTV 1080i H264-HDSTV
+ [title] => 央视体育赛事频道 2019年ATP男子网球年终总决赛 单打小组赛 纳达尔VS西西帕斯 20191115[优惠剩余时间:4时13分]
+ [details] => https://xxx.me/details.php?id=118632
+ [download] => https://xxx.me/download.php?id=118632
+ [filename] => 118632.torrent
+ [type] => 0
+ [sticky] => 1
+ [time] => Array
+ (
+ [0] => "2019-11-16 20:41:53">4时13分
+ [1] => "2019-11-16 14:41:53">1时
46分
+ )
+ [comments] => 0
+ [size] => 5232.64MB
+ [seeders] => 69
+ [leechers] => 10
+ [completed] => 93
+ [percentage] => 100%
+ [owner] => 匿名
+ )
*/
function send($site = '', $torrent = array())
{
- $br = "\r\n";
- $text = $site. ' 免费:' .$torrent['filename']. ',添加成功';
- $desp = '主标题:'.$torrent['h1'] . $br;
+ $br = "\r\n";
+ $text = $site. ' 免费:' .$torrent['filename']. ',添加成功';
+ $desp = '主标题:'.$torrent['h1'] . $br;
- if ( isset($torrent['title']) ) {
- $desp .= '副标题:'.$torrent['title']. $br;
- }
- if ( isset($torrent['size']) ) {
- $desp .= '大小:'.$torrent['size']. $br;
- }
- if ( isset($torrent['seeders']) ) {
- $desp .= '做种数:'.$torrent['seeders']. $br;
- }
- if ( isset($torrent['leechers']) ) {
- $desp .= '下载数:'.$torrent['leechers']. $br;
- }
- if ( isset($torrent['owner']) ) {
- $desp .= '发布者:'.$torrent['owner']. $br;
- }
- return ff($text, $desp);
+ if (isset($torrent['title'])) {
+ $desp .= '副标题:'.$torrent['title']. $br;
+ }
+ if (isset($torrent['size'])) {
+ $desp .= '大小:'.$torrent['size']. $br;
+ }
+ if (isset($torrent['seeders'])) {
+ $desp .= '做种数:'.$torrent['seeders']. $br;
+ }
+ if (isset($torrent['leechers'])) {
+ $desp .= '下载数:'.$torrent['leechers']. $br;
+ }
+ if (isset($torrent['owner'])) {
+ $desp .= '发布者:'.$torrent['owner']. $br;
+ }
+ return ff($text, $desp);
}
/**
@@ -124,34 +125,34 @@ function send($site = '', $torrent = array())
*/
function download($url, $cookies, $useragent, $method = 'GET')
{
- $header = array(
- "Content-Type:application/x-www-form-urlencoded",
- 'User-Agent: '.$useragent);
- $ch = curl_init();
- if($method === 'POST'){
- curl_setopt($ch, CURLOPT_POST, true );
- }
- if(stripos($url, 'https://') !== FALSE) {
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
- curl_setopt($ch, CURLOPT_SSLVERSION, 1);
- }
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
- curl_setopt($ch, CURLOPT_COOKIE,$cookies);
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,60);
- curl_setopt($ch, CURLOPT_TIMEOUT,600);
- $data = curl_exec($ch);
- $status = curl_getinfo($ch);
- curl_close($ch);
- if (isset($status['http_code']) && $status['http_code'] == 200) {
- return $data;
- }
- if (isset($status['http_code']) && $status['http_code'] == 302) {
- return download($status['redirect_url'], $cookies, $useragent);
- }
- return $data;
+ $header = array(
+ "Content-Type:application/x-www-form-urlencoded",
+ 'User-Agent: '.$useragent);
+ $ch = curl_init();
+ if ($method === 'POST') {
+ curl_setopt($ch, CURLOPT_POST, true);
+ }
+ if (stripos($url, 'https://') !== false) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_SSLVERSION, 1);
+ }
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_COOKIE, $cookies);
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 600);
+ $data = curl_exec($ch);
+ $status = curl_getinfo($ch);
+ curl_close($ch);
+ if (isset($status['http_code']) && $status['http_code'] == 200) {
+ return $data;
+ }
+ if (isset($status['http_code']) && $status['http_code'] == 302) {
+ return download($status['redirect_url'], $cookies, $useragent);
+ }
+ return $data;
}
/**
@@ -159,19 +160,20 @@ function download($url, $cookies, $useragent, $method = 'GET')
* @param string $from 文件大小
* @return int 单位MB
*/
-function convertToMB($from){
- $number=substr($from,0,-2);
- switch(strtoupper(substr($from,-2))){
+function convertToMB($from)
+{
+ $number=substr($from, 0, -2);
+ switch (strtoupper(substr($from, -2))) {
case "KB":
return $number/1024;
case "MB":
return $number;
case "GB":
- return $number*pow(1024,1);
+ return $number*pow(1024, 1);
case "TB":
- return $number*pow(1024,2);
+ return $number*pow(1024, 2);
case "PB":
- return $number*pow(1024,3);
+ return $number*pow(1024, 3);
default:
return $from;
}
@@ -182,91 +184,92 @@ function convertToMB($from){
* @param string $site 站点标识
* @param array $torrent 种子数组
* Array
- (
- [id] => 118632
- [h1] => CCTV5+ 2019 ATP Men's Tennis Final 20191115B HDTV 1080i H264-HDSTV
- [title] => 央视体育赛事频道 2019年ATP男子网球年终总决赛 单打小组赛 纳达尔VS西西帕斯 20191115[优惠剩余时间:4时13分]
- [details] => https://xxx.me/details.php?id=118632
- [download] => https://xxx.me/download.php?id=118632
- [filename] => 118632.torrent
- [type] => 0
- [sticky] => 1
- [time] => Array
- (
- [0] => "2019-11-16 20:41:53">4时13分
- [1] => "2019-11-16 14:41:53">1时
46分
- )
- [comments] => 0
- [size] => 5232.64MB
- [seeders] => 69
- [leechers] => 10
- [completed] => 93
- [percentage] => 100%
- [owner] => 匿名
- )
+ (
+ [id] => 118632
+ [h1] => CCTV5+ 2019 ATP Men's Tennis Final 20191115B HDTV 1080i H264-HDSTV
+ [title] => 央视体育赛事频道 2019年ATP男子网球年终总决赛 单打小组赛 纳达尔VS西西帕斯 20191115[优惠剩余时间:4时13分]
+ [details] => https://xxx.me/details.php?id=118632
+ [download] => https://xxx.me/download.php?id=118632
+ [filename] => 118632.torrent
+ [type] => 0
+ [sticky] => 1
+ [time] => Array
+ (
+ [0] => "2019-11-16 20:41:53">4时13分
+ [1] => "2019-11-16 14:41:53">1时
46分
+ )
+ [comments] => 0
+ [size] => 5232.64MB
+ [seeders] => 69
+ [leechers] => 10
+ [completed] => 93
+ [percentage] => 100%
+ [owner] => 匿名
+ )
* @return bool 或 string false不过滤
*/
-function filter($site = '', $torrent = array()){
- global $configALL;
- $config = $configALL[$site];
- $filter = array();
- // 读取配置
- if (isset($configALL['default']['filter']) || isset($config['filter'])) {
- $filter = isset($config['filter']) && $config['filter'] ? $config['filter'] : $configALL['default']['filter'];
- }else {
- return false;
- }
- $filename = $torrent['filename'];
+function filter($site = '', $torrent = array())
+{
+ global $configALL;
+ $config = $configALL[$site];
+ $filter = array();
+ // 读取配置
+ if (isset($configALL['default']['filter']) || isset($config['filter'])) {
+ $filter = isset($config['filter']) && $config['filter'] ? $config['filter'] : $configALL['default']['filter'];
+ } else {
+ return false;
+ }
+ $filename = $torrent['filename'];
- // 兼容性
- if ( empty($torrent['size']) ) {
- return false;
- }
- // 大小过滤
- $size = convertToMB($torrent['size']);
- $min = isset($filter['size']['min']) ? convertToMB($filter['size']['min']) : 0;
- $max = isset($filter['size']['max']) ? convertToMB($filter['size']['max']) : 2097152; //默认 2097152MB = 2TB
- if ($min > $size || $size > $max) {
- return $filename. ' ' .$size. 'MB,被大小过滤';
- }
+ // 兼容性
+ if (empty($torrent['size'])) {
+ return false;
+ }
+ // 大小过滤
+ $size = convertToMB($torrent['size']);
+ $min = isset($filter['size']['min']) ? convertToMB($filter['size']['min']) : 0;
+ $max = isset($filter['size']['max']) ? convertToMB($filter['size']['max']) : 2097152; //默认 2097152MB = 2TB
+ if ($min > $size || $size > $max) {
+ return $filename. ' ' .$size. 'MB,被大小过滤';
+ }
- // 兼容性
- if ( empty($torrent['seeders']) ) {
- return false;
- }
- // 种子数过滤
- $seeders = $torrent['seeders'];
- $min = isset($filter['seeders']['min']) ? $filter['seeders']['min'] : 1; //默认 1
- $max = isset($filter['seeders']['max']) ? $filter['seeders']['max'] : 3; //默认 3
- if ($min > $seeders || $seeders > $max) {
- return $filename. ' 当前做种' .$seeders. '人,被过滤';
- }
+ // 兼容性
+ if (empty($torrent['seeders'])) {
+ return false;
+ }
+ // 种子数过滤
+ $seeders = $torrent['seeders'];
+ $min = isset($filter['seeders']['min']) ? $filter['seeders']['min'] : 1; //默认 1
+ $max = isset($filter['seeders']['max']) ? $filter['seeders']['max'] : 3; //默认 3
+ if ($min > $seeders || $seeders > $max) {
+ return $filename. ' 当前做种' .$seeders. '人,被过滤';
+ }
- // 兼容性
- if ( empty($torrent['leechers']) ) {
- return false;
- }
- // 下载数过滤
- $leechers = $torrent['leechers'];
- $min = isset($filter['leechers']['min']) ? $filter['leechers']['min'] : 0; //默认
- $max = isset($filter['leechers']['max']) ? $filter['leechers']['max'] : 30000; //默认
- if ($min > $leechers || $leechers > $max) {
- return $filename. ' 当前下载' .$leechers. '人,被过滤';
- }
+ // 兼容性
+ if (empty($torrent['leechers'])) {
+ return false;
+ }
+ // 下载数过滤
+ $leechers = $torrent['leechers'];
+ $min = isset($filter['leechers']['min']) ? $filter['leechers']['min'] : 0; //默认
+ $max = isset($filter['leechers']['max']) ? $filter['leechers']['max'] : 30000; //默认
+ if ($min > $leechers || $leechers > $max) {
+ return $filename. ' 当前下载' .$leechers. '人,被过滤';
+ }
- // 兼容性
- if ( empty($torrent['completed']) ) {
- return false;
- }
- // 完成数过滤
- $completed = $torrent['completed'];
- $min = isset($filter['completed']['min']) ? $filter['completed']['min'] : 0; //默认
- $max = isset($filter['completed']['max']) ? $filter['completed']['max'] : 30000; //默认
- if ($min > $completed || $completed > $max) {
- return $filename. ' 已完成数' .$completed. '人,被过滤';
- }
+ // 兼容性
+ if (empty($torrent['completed'])) {
+ return false;
+ }
+ // 完成数过滤
+ $completed = $torrent['completed'];
+ $min = isset($filter['completed']['min']) ? $filter['completed']['min'] : 0; //默认
+ $max = isset($filter['completed']['max']) ? $filter['completed']['max'] : 30000; //默认
+ if ($min > $completed || $completed > $max) {
+ return $filename. ' 已完成数' .$completed. '人,被过滤';
+ }
- return false;
+ return false;
}
/**
@@ -284,22 +287,23 @@ function oddFilter($var)
*/
function evenFilter($var)
{
- // 返回$var最后一个二进制位,
+ // 返回$var最后一个二进制位,
// 为0则保留(偶数的二进制的最后一位肯定是0)
- return(!($var & 1));
+ return(!($var & 1));
}
/**
* 发布员签名
* 注意:同时配置iyuu.cn与secret时,优先使用secret。
*/
-function sign( $timestamp ){
- global $configALL;
- // 爱语飞飞
- $token = isset($configALL['iyuu.cn']) && $configALL['iyuu.cn'] ? $configALL['iyuu.cn'] : '';
- // 鉴权
- $token = isset($configALL['secret']) && $configALL['secret'] ? $configALL['secret'] : $token;
- return sha1($timestamp . $token);
+function sign($timestamp)
+{
+ global $configALL;
+ // 爱语飞飞
+ $token = isset($configALL['iyuu.cn']) && $configALL['iyuu.cn'] ? $configALL['iyuu.cn'] : '';
+ // 鉴权
+ $token = isset($configALL['secret']) && $configALL['secret'] ? $configALL['secret'] : $token;
+ return sha1($timestamp . $token);
}
/**
@@ -307,7 +311,8 @@ function sign( $timestamp ){
* token算法:IYUU + uid + T + sha1(openid+time+盐)
* @param string $token 用户请求token
*/
-function getUid($token){
- //验证是否IYUU开头,strpos($token,'T')<15,token总长度小于60(40+10+5)
- return (strlen($token)<60)&&(strpos($token,'IYUU')===0)&&(strpos($token,'T')<15) ? substr($token,4,strpos($token,'T')-4): false;
+function getUid($token)
+{
+ //验证是否IYUU开头,strpos($token,'T')<15,token总长度小于60(40+10+5)
+ return (strlen($token)<60)&&(strpos($token, 'IYUU')===0)&&(strpos($token, 'T')<15) ? substr($token, 4, strpos($token, 'T')-4): false;
}
diff --git a/app/Class/IFile.php b/app/Class/IFile.php
index 4fa3322..f82a990 100644
--- a/app/Class/IFile.php
+++ b/app/Class/IFile.php
@@ -10,323 +10,290 @@
*/
class IFile
{
- private $resource = null; //文件资源句柄
+ private $resource = null; //文件资源句柄
- /**
- * @brief 构造函数,打开资源流,并独占锁定
- * @param String $fileName 文件路径名
- * @param String $mode 操作方式,默认为读操作,可供选择的项为:r,r+,w+,w+,a,a+
- * @note $mod,'r' 只读方式打开,将文件指针指向文件头
- * 'r+' 读写方式打开,将文件指针指向文件头
- * 'w' 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
- * 'w+' 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
- * 'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
- * 'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
- */
- function __construct($fileName,$mode='r')
- {
- $dirName = dirname($fileName);
- $baseName = basename($fileName);
-
- //检查并创建文件夹
- self::mkdir($dirName);
+ /**
+ * @brief 构造函数,打开资源流,并独占锁定
+ * @param String $fileName 文件路径名
+ * @param String $mode 操作方式,默认为读操作,可供选择的项为:r,r+,w+,w+,a,a+
+ * @note $mod,'r' 只读方式打开,将文件指针指向文件头
+ * 'r+' 读写方式打开,将文件指针指向文件头
+ * 'w' 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
+ * 'w+' 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
+ * 'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
+ * 'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
+ */
+ public function __construct($fileName, $mode='r')
+ {
+ $dirName = dirname($fileName);
+ $baseName = basename($fileName);
- $this->resource = fopen($fileName,$mode.'b');
- if($this->resource)
- {
- flock($this->resource,LOCK_EX);
- }
- }
+ //检查并创建文件夹
+ self::mkdir($dirName);
- /**
- * @brief 获取文件内容
- * @return String 文件内容
- */
- public function read()
- {
- $content = null;
- while(!feof($this->resource))
- {
- $content.= fread($this->resource,1024);
- }
- return $content;
- }
+ $this->resource = fopen($fileName, $mode.'b');
+ if ($this->resource) {
+ flock($this->resource, LOCK_EX);
+ }
+ }
- /**
- * @brief 文件写入操作
- * @param String $content 要写入的文件内容
- * @return Int or false 写入的字符数; false:写入失败;
- */
- public function write($content)
- {
- $worldsnum = fwrite($this->resource,$content);
- $this->save();
- return is_bool($worldsnum) ? false : $worldsnum;
- }
+ /**
+ * @brief 获取文件内容
+ * @return String 文件内容
+ */
+ public function read()
+ {
+ $content = null;
+ while (!feof($this->resource)) {
+ $content.= fread($this->resource, 1024);
+ }
+ return $content;
+ }
- /**
- * @brief 清空目录下的所有文件
- * @return bool false:失败; true:成功;
- */
- public static function clearDir($dir)
- {
- if($dir[0] != '.' && is_dir($dir) && is_writable($dir))
- {
- $dirRes = opendir($dir);
- while( false !== ($fileName = readdir($dirRes)) )
- {
- if($fileName[0] !== '.')
- {
- $fullpath = $dir.'/'.$fileName;
- if(is_file($fullpath))
- {
- self::unlink($fullpath);
- }
- else
- {
- self::clearDir($fullpath);
- rmdir($fullpath);
- }
- }
- }
- closedir($dirRes);
- return true;
- }
- else
- {
- return false;
- }
- }
+ /**
+ * @brief 文件写入操作
+ * @param String $content 要写入的文件内容
+ * @return Int or false 写入的字符数; false:写入失败;
+ */
+ public function write($content)
+ {
+ $worldsnum = fwrite($this->resource, $content);
+ $this->save();
+ return is_bool($worldsnum) ? false : $worldsnum;
+ }
- /**
- * @brief 获取文件信息
- * @param String $fileName 文件路径
- * @return array or null array:文件信息; null:文件不存在;
- */
- public static function getInfo($fileName)
- {
- if(is_file($fileName))
- return stat($fileName);
+ /**
+ * @brief 清空目录下的所有文件
+ * @return bool false:失败; true:成功;
+ */
+ public static function clearDir($dir)
+ {
+ if ($dir[0] != '.' && is_dir($dir) && is_writable($dir)) {
+ $dirRes = opendir($dir);
+ while (false !== ($fileName = readdir($dirRes))) {
+ if ($fileName[0] !== '.') {
+ $fullpath = $dir.'/'.$fileName;
+ if (is_file($fullpath)) {
+ self::unlink($fullpath);
+ } else {
+ self::clearDir($fullpath);
+ rmdir($fullpath);
+ }
+ }
+ }
+ closedir($dirRes);
+ return true;
+ } else {
+ return false;
+ }
+ }
- else
- return null;
- }
+ /**
+ * @brief 获取文件信息
+ * @param String $fileName 文件路径
+ * @return array or null array:文件信息; null:文件不存在;
+ */
+ public static function getInfo($fileName)
+ {
+ if (is_file($fileName)) {
+ return stat($fileName);
+ } else {
+ return null;
+ }
+ }
- /**
- * @brief 创建文件夹
- * @param String $path 路径
- * @param int $chmod 文件夹权限
- * @note $chmod 参数不能是字符串(加引号),否则linux会出现权限问题
- */
- public static function mkdir($path,$chmod=0777)
- {
- return is_dir($path) or (self::mkdir(dirname($path),$chmod) and mkdir($path,$chmod));
- }
+ /**
+ * @brief 创建文件夹
+ * @param String $path 路径
+ * @param int $chmod 文件夹权限
+ * @note $chmod 参数不能是字符串(加引号),否则linux会出现权限问题
+ */
+ public static function mkdir($path, $chmod=0777)
+ {
+ return is_dir($path) or (self::mkdir(dirname($path), $chmod) and mkdir($path, $chmod));
+ }
- /**
- * @brief 复制文件
- * @param String $from 源文件路径
- * @param String $to 目标文件路径
- * @param String $mod 操作模式,c:复制(默认); x:剪切(删除$from文件)
- * @return bool 操作结果 true:成功; false:失败;
- */
- public static function copy($from,$to,$mode = 'c')
- {
- $dir = dirname($to);
+ /**
+ * @brief 复制文件
+ * @param String $from 源文件路径
+ * @param String $to 目标文件路径
+ * @param String $mod 操作模式,c:复制(默认); x:剪切(删除$from文件)
+ * @return bool 操作结果 true:成功; false:失败;
+ */
+ public static function copy($from, $to, $mode = 'c')
+ {
+ $dir = dirname($to);
- //创建目录
- self::mkdir($dir);
+ //创建目录
+ self::mkdir($dir);
- copy($from,$to);
+ copy($from, $to);
- if(is_file($to))
- {
- if($mode == 'x')
- {
- self::unlink($from);
- }
- return true;
- }
- else
- {
- return false;
- }
- }
+ if (is_file($to)) {
+ if ($mode == 'x') {
+ self::unlink($from);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
- /**
- * @brief 删除文件
- * @param String $fileName 文件路径
- * @return bool 操作结果 false:删除失败;
- */
- public static function unlink($fileName)
- {
- if(is_file($fileName) && is_writable($fileName))
- {
- return unlink($fileName);
- }
- else
- return false;
- }
+ /**
+ * @brief 删除文件
+ * @param String $fileName 文件路径
+ * @return bool 操作结果 false:删除失败;
+ */
+ public static function unlink($fileName)
+ {
+ if (is_file($fileName) && is_writable($fileName)) {
+ return unlink($fileName);
+ } else {
+ return false;
+ }
+ }
- /**
- * @brief 删除$dir文件夹 或者 其下所有文件
- * @param String $dir 文件路径
- * @param bool $recursive 是否强制删除,如果强制删除则递归删除该目录下的全部文件,默认为false
- * @return bool true:删除成功; false:删除失败;
- */
- public static function rmdir($dir,$recursive = false)
- {
- if(is_dir($dir) && is_writable($dir))
- {
- //强制删除
- if($recursive == true)
- {
- self::clearDir($dir);
- return self::rmdir($dir,false);
- }
+ /**
+ * @brief 删除$dir文件夹 或者 其下所有文件
+ * @param String $dir 文件路径
+ * @param bool $recursive 是否强制删除,如果强制删除则递归删除该目录下的全部文件,默认为false
+ * @return bool true:删除成功; false:删除失败;
+ */
+ public static function rmdir($dir, $recursive = false)
+ {
+ if (is_dir($dir) && is_writable($dir)) {
+ //强制删除
+ if ($recursive == true) {
+ self::clearDir($dir);
+ return self::rmdir($dir, false);
+ }
- //非强制删除
- else
- {
- if(rmdir($dir))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- }
+ //非强制删除
+ else {
+ if (rmdir($dir)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ }
- /**
- * @brief 获取文件类型
- * @param String $fileName 文件名
- * @return String $filetype 文件类型
- * @note 如果文件不存在,返回false,如果文件后缀名不在识别列表之内,返回NULL,对于docx及elsx格式文档识别在会出现识别为ZIP格式的错误,这是office2007的bug目前尚未修复,请谨慎使用
- */
- public static function getFileType($fileName)
- {
- $filetype = null;
- if(!is_file($fileName))
- {
- return false;
- }
+ /**
+ * @brief 获取文件类型
+ * @param String $fileName 文件名
+ * @return String $filetype 文件类型
+ * @note 如果文件不存在,返回false,如果文件后缀名不在识别列表之内,返回NULL,对于docx及elsx格式文档识别在会出现识别为ZIP格式的错误,这是office2007的bug目前尚未修复,请谨慎使用
+ */
+ public static function getFileType($fileName)
+ {
+ $filetype = null;
+ if (!is_file($fileName)) {
+ return false;
+ }
- $fileRes = fopen($fileName,"rb");
- if(!$fileRes)
- {
- return false;
- }
+ $fileRes = fopen($fileName, "rb");
+ if (!$fileRes) {
+ return false;
+ }
$bin= fread($fileRes, 2);
fclose($fileRes);
- if($bin != null)
- {
- $strInfo = unpack("C2chars", $bin);
- $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
- $typelist = self::getTypeList();
- foreach($typelist as $val)
- {
- if(strtolower($val[0]) == strtolower($typeCode))
- {
- if($val[0] == 8075)
- {
- return array('zip','docx','xlsx');
- }
- else
- {
- return $val[1];
- }
- }
- }
+ if ($bin != null) {
+ $strInfo = unpack("C2chars", $bin);
+ $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
+ $typelist = self::getTypeList();
+ foreach ($typelist as $val) {
+ if (strtolower($val[0]) == strtolower($typeCode)) {
+ if ($val[0] == 8075) {
+ return array('zip','docx','xlsx');
+ } else {
+ return $val[1];
+ }
+ }
+ }
}
- return $filetype;
- }
+ return $filetype;
+ }
- /**
- * @brief 获取文件类型映射关系
+ /**
+ * @brief 获取文件类型映射关系
* @return array 文件类型映射关系数组
*/
public static function getTypeList()
{
- return array(
- array('255216','jpg'),
- array('13780','png'),
- array('7173','gif'),
- array('6677','bmp'),
- array('6063','xml'),
- array('60104','html'),
- array('208207','xls/doc'),
- array('8075','zip'),
- array('8075','docx'),
- array('8075','xlsx'),
- array("8297","rar"),
- );
+ return array(
+ array('255216','jpg'),
+ array('13780','png'),
+ array('7173','gif'),
+ array('6677','bmp'),
+ array('6063','xml'),
+ array('60104','html'),
+ array('208207','xls/doc'),
+ array('8075','zip'),
+ array('8075','docx'),
+ array('8075','xlsx'),
+ array("8297","rar"),
+ );
}
- /**
- * @brief 获取文件大小
- * @param String $fileName 文件名
- * @return Int 文件大小的字节数,如果文件无效则返回 NULL
- */
- public static function getFileSize($fileName)
- {
- return is_file($fileName) ? filesize($fileName):null;
- }
+ /**
+ * @brief 获取文件大小
+ * @param String $fileName 文件名
+ * @return Int 文件大小的字节数,如果文件无效则返回 NULL
+ */
+ public static function getFileSize($fileName)
+ {
+ return is_file($fileName) ? filesize($fileName):null;
+ }
- /**
- * @brief 检测文件夹是否为空
- * @param String $dir 路径地址
- * @return bool true:$dir为空目录; false:$dir为非空目录;
- */
- public static function isEmptyDir($dir)
- {
- if(is_dir($dir))
- {
- $isEmpty = true;
- $dirRes = opendir($dir);
- while(false !== ($fileName = readdir($dirRes)))
- {
- if($fileName!='.' && $fileName!='..')
- {
- $isEmpty = false;
- break;
- }
- }
- closedir($dirRes);
- return $isEmpty;
- }
- }
+ /**
+ * @brief 检测文件夹是否为空
+ * @param String $dir 路径地址
+ * @return bool true:$dir为空目录; false:$dir为非空目录;
+ */
+ public static function isEmptyDir($dir)
+ {
+ if (is_dir($dir)) {
+ $isEmpty = true;
+ $dirRes = opendir($dir);
+ while (false !== ($fileName = readdir($dirRes))) {
+ if ($fileName!='.' && $fileName!='..') {
+ $isEmpty = false;
+ break;
+ }
+ }
+ closedir($dirRes);
+ return $isEmpty;
+ }
+ }
- /**
- * @brief 释放文件锁定
- */
- public function save()
- {
- flock($this->resource,LOCK_UN);
- }
+ /**
+ * @brief 释放文件锁定
+ */
+ public function save()
+ {
+ flock($this->resource, LOCK_UN);
+ }
- /**
- * @brief 获取文件扩展名
- * @param String $fileName 文件名
- * @return String 文件后缀名
- */
- public static function getFileSuffix($fileName)
- {
- $fileInfoArray = pathinfo($fileName);
- return $fileInfoArray['extension'];
- }
+ /**
+ * @brief 获取文件扩展名
+ * @param String $fileName 文件名
+ * @return String 文件后缀名
+ */
+ public static function getFileSuffix($fileName)
+ {
+ $fileInfoArray = pathinfo($fileName);
+ return $fileInfoArray['extension'];
+ }
- /**
- * @brief 析构函数,释放文件连接句柄
- */
- function __destruct()
- {
- if(is_resource($this->resource))
- {
- fclose($this->resource);
- }
- }
-}
\ No newline at end of file
+ /**
+ * @brief 析构函数,释放文件连接句柄
+ */
+ public function __destruct()
+ {
+ if (is_resource($this->resource)) {
+ fclose($this->resource);
+ }
+ }
+}
diff --git a/app/Class/Oauth.php b/app/Class/Oauth.php
index fff4630..c8e561b 100644
--- a/app/Class/Oauth.php
+++ b/app/Class/Oauth.php
@@ -3,7 +3,9 @@
* IYUU用户注册、认证
*/
use Curl\Curl;
-class Oauth{
+
+class Oauth
+{
// 合作的站点
public static $sites = ['ourbits'];
// 爱语飞飞token
@@ -17,13 +19,14 @@ class Oauth{
/**
* 初始化配置
*/
- public static function init(){
+ public static function init()
+ {
global $configALL;
foreach (self::$sites as $name) {
- if (isset($configALL[$name]['passkey']) && $configALL[$name]['passkey'] && isset($configALL[$name]['id']) && $configALL[$name]['id'] ) {
+ if (isset($configALL[$name]['passkey']) && $configALL[$name]['passkey'] && isset($configALL[$name]['id']) && $configALL[$name]['id']) {
self::$token = self::getSign();
self::$user_id = $configALL[$name]['id'];
- self::$passkey = sha1( $configALL[$name]['passkey'] ); // 避免泄露用户passkey秘钥
+ self::$passkey = sha1($configALL[$name]['passkey']); // 避免泄露用户passkey秘钥
self::$site = $name;
return true;
}
@@ -35,7 +38,8 @@ class Oauth{
/**
* 从配置文件内读取爱语飞飞token作为鉴权参数
*/
- public static function getSign(){
+ public static function getSign()
+ {
global $configALL;
// 爱语飞飞
$token = isset($configALL['iyuu.cn']) && $configALL['iyuu.cn'] ? $configALL['iyuu.cn'] : '';
@@ -51,9 +55,10 @@ class Oauth{
* 作用:在服务器端实现微信用户与合作站点用户id的关联
* 参数:爱语飞飞token + 合作站点用户id + sha1(合作站点密钥passkey) + 合作站点标识
*/
- public static function login($apiUrl = ''){
+ public static function login($apiUrl = '')
+ {
$is_oauth = self::init();
- if ( $is_oauth ) {
+ if ($is_oauth) {
$curl = new Curl();
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
$data = [
@@ -66,6 +71,6 @@ class Oauth{
p($res->response);
return true;
}
- return false;
+ return false;
}
-}
\ No newline at end of file
+}
diff --git a/app/Class/Rpc.php b/app/Class/Rpc.php
index 76186e8..b259f28 100644
--- a/app/Class/Rpc.php
+++ b/app/Class/Rpc.php
@@ -4,78 +4,79 @@
*/
class Rpc
{
- /**
+ /**
* 版本号
* @var string
*/
const VER = '0.0.1';
- // 下载种子的请求类型 GET POST
- public static $method = 'GET';
- // RPC连接池
- public static $links = array();
- /**
+ // 下载种子的请求类型 GET POST
+ public static $method = 'GET';
+ // RPC连接池
+ public static $links = array();
+ /**
* cookie
*/
public static $cookies = '';
- /**
+ /**
* 浏览器 User-Agent
*/
public static $userAgent = '';
- /**
+ /**
* passkey
*/
public static $passkey = '';
- /**
+ /**
* 客户端配置
*/
public static $clients = '';
- /**
+ /**
* 监控目录
*/
public static $watch = '';
- /**
+ /**
* 种子存放路径
*/
public static $torrentDir = '';
- /**
+ /**
* 工作模式
*/
public static $workingMode = '';
- // 站点标识
- public static $site = '';
- /**
+ // 站点标识
+ public static $site = '';
+ /**
* 负载均衡 控制变量
*/
public static $RPC_Key = 0;
- /**
+ /**
* 退出状态码
*/
- public static $ExitCode = 0;
- /**
+ public static $ExitCode = 0;
+ /**
* 初始化
*/
- public static function init($site = '', $method = 'GET'){
- global $configALL;
+ public static function init($site = '', $method = 'GET')
+ {
+ global $configALL;
- self::$site = $site;
- self::$method = strtoupper($method);
+ self::$site = $site;
+ self::$method = strtoupper($method);
- $config = $configALL[$site];
- self::$cookies = $config['cookie'];
- self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
- self::$clients = isset($config['clients']) && $config['clients'] ? $config['clients'] : $configALL['default']['clients'];
- self::$workingMode = isset($config['workingMode']) && $config['workingMode'] ? $config['workingMode'] : 0;
- $watch = isset($config['watch']) && $config['watch'] ? $config['watch'] : $configALL['default']['watch'];
- self::$watch = rtrim($watch,'/') . DS;
- self::$torrentDir = TORRENT_PATH . $site . DS;
- // 建立目录
- IFile::mkdir(self::$torrentDir);
-
- self::links();
- }
+ $config = $configALL[$site];
+ self::$cookies = $config['cookie'];
+ self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
+ self::$clients = isset($config['clients']) && $config['clients'] ? $config['clients'] : $configALL['default']['clients'];
+ self::$workingMode = isset($config['workingMode']) && $config['workingMode'] ? $config['workingMode'] : 0;
+ $watch = isset($config['watch']) && $config['watch'] ? $config['watch'] : $configALL['default']['watch'];
+ self::$watch = rtrim($watch, '/') . DS;
+ self::$torrentDir = TORRENT_PATH . $site . DS;
+ // 建立目录
+ IFile::mkdir(self::$torrentDir);
+
+ self::links();
+ }
- /**
+ /**
* 连接远端RPC服务器
*
* @param string
@@ -83,140 +84,138 @@ class Rpc
*/
public static function links()
{
- if(self::$workingMode === 1 && empty(self::$links)){
- foreach ( self::$clients as $k => $v ){
- // 跳过未配置的客户端
- if (empty($v['username']) || empty( $v['password'])) {
- unset(self::$clients[$k]);
- echo "clients_".$k." 用户名或密码未配置,已跳过 \n\n";
- continue;
- }
- try
- {
- switch($v['type']){
- case 'transmission':
- self::$links[$k]['rpc'] = new TransmissionRPC($v['host'], $v['username'], $v['password']);
- $result = self::$links[$k]['rpc']->sstats();
- print $v['type'].':'.$v['host']." Rpc连接成功 [{$result->result}] \n";
- break;
- case 'qBittorrent':
- self::$links[$k]['rpc'] = new qBittorrent($v['host'], $v['username'], $v['password']);
- $result = self::$links[$k]['rpc']->appVersion();
- print $v['type'].':'.$v['host']." Rpc连接成功 [{$result}] \n";
- break;
- case 'uTorrent':
- self::$links[$k]['rpc'] = new uTorrent($v['host'], $v['username'], $v['password']);
- $result = self::$links[$k]['rpc']->getBuild();
- print $v['type'].':'.$v['host']." Rpc连接 [{$result}] \n";
- break;
- default:
- echo '[ERROR] '.$v['type'];
- exit(1);
- break;
- }
- self::$links[$k]['type'] = $v['type'];
- self::$links[$k]['downloadDir'] = $v['downloadDir'];
- } catch (Exception $e) {
- echo '[ERROR] ' . $e->getMessage() . PHP_EOL;
- exit(1);
- }
- }
- }
- return true;
+ if (self::$workingMode === 1 && empty(self::$links)) {
+ foreach (self::$clients as $k => $v) {
+ // 跳过未配置的客户端
+ if (empty($v['username']) || empty($v['password'])) {
+ unset(self::$clients[$k]);
+ echo "clients_".$k." 用户名或密码未配置,已跳过 \n\n";
+ continue;
+ }
+ try {
+ switch ($v['type']) {
+ case 'transmission':
+ self::$links[$k]['rpc'] = new TransmissionRPC($v['host'], $v['username'], $v['password']);
+ $result = self::$links[$k]['rpc']->sstats();
+ print $v['type'].':'.$v['host']." Rpc连接成功 [{$result->result}] \n";
+ break;
+ case 'qBittorrent':
+ self::$links[$k]['rpc'] = new qBittorrent($v['host'], $v['username'], $v['password']);
+ $result = self::$links[$k]['rpc']->appVersion();
+ print $v['type'].':'.$v['host']." Rpc连接成功 [{$result}] \n";
+ break;
+ case 'uTorrent':
+ self::$links[$k]['rpc'] = new uTorrent($v['host'], $v['username'], $v['password']);
+ $result = self::$links[$k]['rpc']->getBuild();
+ print $v['type'].':'.$v['host']." Rpc连接 [{$result}] \n";
+ break;
+ default:
+ echo '[ERROR] '.$v['type'];
+ exit(1);
+ break;
+ }
+ self::$links[$k]['type'] = $v['type'];
+ self::$links[$k]['downloadDir'] = $v['downloadDir'];
+ } catch (Exception $e) {
+ echo '[ERROR] ' . $e->getMessage() . PHP_EOL;
+ exit(1);
+ }
+ }
+ }
+ return true;
}
- /**
- * @brief 添加下载任务
- * @param string $torrent 种子元数据
- * @param string $save_path 保存路径
- * @return bool
- */
+ /**
+ * @brief 添加下载任务
+ * @param string $torrent 种子元数据
+ * @param string $save_path 保存路径
+ * @return bool
+ */
public static function add($torrent, $save_path = '', $extra_options = array())
{
- switch( (int)self::$workingMode ){
- case 0: // watch默认工作模式
- // 复制到watch目录
- copy($torrent,$save_path);
- if(is_file($save_path)){
- print "********watch模式,下载任务添加成功 \n\n";
- return true;
- }else {
- print "-----watch模式,下载任务添加失败!!! \n\n";
- }
- break;
- case 1: //负载均衡模式
- try
- {
- $is_url = false;
- if( (strpos($torrent,'http://')===0) || (strpos($torrent,'https://')===0) || (strpos($torrent,'magnet:?xt=urn:btih:')===0) ){
- $is_url = true;
- }
- // 负载均衡
- $rpcKey = self::$RPC_Key;
- echo '选中:负载均衡'.$rpcKey."\n";
- self::rpcSelect();
- // 调试
- #p($result);
- // 下载服务器类型 判断
- $type = self::$links[$rpcKey]['type'];
- switch($type){
- case 'transmission':
- if( $is_url ){
- echo 'add';
- $result = self::$links[$rpcKey]['rpc']->add( $torrent, self::$links[$rpcKey]['downloadDir'], $extra_options ); // 种子URL添加下载任务
- }else{
- echo 'add_metainfo';
- $result = self::$links[$rpcKey]['rpc']->add_metainfo( $torrent, self::$links[$rpcKey]['downloadDir'], $extra_options ); // 种子文件添加下载任务
- }
- $id = $name = '';
- if( isset($result->arguments->torrent_duplicate) ){
- $id = $result->arguments->torrent_duplicate->id;
- $name = $result->arguments->torrent_duplicate->name;
- }elseif( isset($result->arguments->torrent_added) ){
- $id = $result->arguments->torrent_added->id;
- $name = $result->arguments->torrent_added->name;
- }
- if(!$id){
- print "-----RPC添加种子任务,失败 [{$result->result}] \n\n";
- }else{
- print "********RPC添加下载任务成功 [{$result->result}] (id=$id) \n\n";
- // 新添加的任务,开始
- self::$links[$rpcKey]['rpc']->start( $id );
- return true;
- }
- break;
- case 'qBittorrent':
- if( $is_url ){
- echo 'add';
- $result = self::$links[$rpcKey]['rpc']->add( $torrent, self::$links[$rpcKey]['downloadDir'], $extra_options ); // 种子URL添加下载任务
- }else{
- echo 'add_metainfo';
- $result = self::$links[$rpcKey]['rpc']->add_metainfo( $torrent, self::$links[$rpcKey]['downloadDir'], $extra_options ); // 种子文件添加下载任务
- }
- if ($result === 'Ok.') {
- print "********RPC添加下载任务成功 [{$result}] \n\n";
- return true;
- } else {
- print "-----RPC添加种子任务,失败 [{$result}] \n\n";
- }
- break;
- default:
- echo '[ERROR] '.$type;
- break;
- }
- } catch (Exception $e) {
- die('[ERROR] ' . $e->getMessage() . PHP_EOL);
- }
- break;
- case 2:
- echo "\n\n";
- # 暂未开放
- break;
- default:
- echo "\n\n";
- break;
- }
- return false;
+ switch ((int)self::$workingMode) {
+ case 0: // watch默认工作模式
+ // 复制到watch目录
+ copy($torrent, $save_path);
+ if (is_file($save_path)) {
+ print "********watch模式,下载任务添加成功 \n\n";
+ return true;
+ } else {
+ print "-----watch模式,下载任务添加失败!!! \n\n";
+ }
+ break;
+ case 1: //负载均衡模式
+ try {
+ $is_url = false;
+ if ((strpos($torrent, 'http://')===0) || (strpos($torrent, 'https://')===0) || (strpos($torrent, 'magnet:?xt=urn:btih:')===0)) {
+ $is_url = true;
+ }
+ // 负载均衡
+ $rpcKey = self::$RPC_Key;
+ echo '选中:负载均衡'.$rpcKey."\n";
+ self::rpcSelect();
+ // 调试
+ #p($result);
+ // 下载服务器类型 判断
+ $type = self::$links[$rpcKey]['type'];
+ switch ($type) {
+ case 'transmission':
+ if ($is_url) {
+ echo 'add';
+ $result = self::$links[$rpcKey]['rpc']->add($torrent, self::$links[$rpcKey]['downloadDir'], $extra_options); // 种子URL添加下载任务
+ } else {
+ echo 'add_metainfo';
+ $result = self::$links[$rpcKey]['rpc']->add_metainfo($torrent, self::$links[$rpcKey]['downloadDir'], $extra_options); // 种子文件添加下载任务
+ }
+ $id = $name = '';
+ if (isset($result->arguments->torrent_duplicate)) {
+ $id = $result->arguments->torrent_duplicate->id;
+ $name = $result->arguments->torrent_duplicate->name;
+ } elseif (isset($result->arguments->torrent_added)) {
+ $id = $result->arguments->torrent_added->id;
+ $name = $result->arguments->torrent_added->name;
+ }
+ if (!$id) {
+ print "-----RPC添加种子任务,失败 [{$result->result}] \n\n";
+ } else {
+ print "********RPC添加下载任务成功 [{$result->result}] (id=$id) \n\n";
+ // 新添加的任务,开始
+ self::$links[$rpcKey]['rpc']->start($id);
+ return true;
+ }
+ break;
+ case 'qBittorrent':
+ if ($is_url) {
+ echo 'add';
+ $result = self::$links[$rpcKey]['rpc']->add($torrent, self::$links[$rpcKey]['downloadDir'], $extra_options); // 种子URL添加下载任务
+ } else {
+ echo 'add_metainfo';
+ $result = self::$links[$rpcKey]['rpc']->add_metainfo($torrent, self::$links[$rpcKey]['downloadDir'], $extra_options); // 种子文件添加下载任务
+ }
+ if ($result === 'Ok.') {
+ print "********RPC添加下载任务成功 [{$result}] \n\n";
+ return true;
+ } else {
+ print "-----RPC添加种子任务,失败 [{$result}] \n\n";
+ }
+ break;
+ default:
+ echo '[ERROR] '.$type;
+ break;
+ }
+ } catch (Exception $e) {
+ die('[ERROR] ' . $e->getMessage() . PHP_EOL);
+ }
+ break;
+ case 2:
+ echo "\n\n";
+ # 暂未开放
+ break;
+ default:
+ echo "\n\n";
+ break;
+ }
+ return false;
}
/**
@@ -227,142 +226,142 @@ class Rpc
*/
public static function rpcSelect()
{
- $clientsConut = count(self::$clients);
- if( $clientsConut > 1 ){
- if( $clientsConut > (self::$RPC_Key+1) ){
- self::$RPC_Key++;
- }else{
- self::$RPC_Key = 0;
- }
- }
- }
- /**
- * @brief 种子处理函数
- * @param array $data 种子数组
- * Array
- (
- [id] => 118632
- [h1] => CCTV5+ 2019 ATP Men's Tennis Final 20191115B HDTV 1080i H264-HDxxx
- [title] => 央视体育赛事频道 2019年ATP男子网球年终总决赛 单打小组赛 纳达尔VS西西帕斯 20191115[优惠剩余时间:4时13分]
- [details] => https://XXX.me/details.php?id=118632
- [download] => https://XXX.me/download.php?id=118632
- [filename] => 118632.torrent
- [type] => 0
- [sticky] => 1
- [time] => Array
- (
- [0] => "2019-11-16 20:41:53">4时13分
- [1] => "2019-11-16 14:41:53">1时
46分
- )
- [comments] => 0
- [size] => 5232.64MB
- [seeders] => 69
- [leechers] => 10
- [completed] => 93
- [percentage] => 100%
- [owner] => 匿名
- )
- * @return
- */
- public static function call($data = array())
- {
- foreach ($data as $key => $value) {
- // 控制台打印
- echo '主标题:'.$value['h1']."\n";
- echo '副标题:'.$value['title']."\n";
- echo '详情页:'.$value['details']."\n";
- if ( $value['type'] != 0 ) {
- echo "-----非免费,已忽略! \n\n";
- continue;
- }
- if ( isset($value['hr']) && ($value['hr'] == 1) ) {
- echo "-----HR种子,已忽略! \n\n";
- continue;
- }
- // 下载任务的可选参数
- $extra_options = array();
- // 保存的文件名
- $filename = $value['id'] . '.torrent';
- // 默认watch工作模式,复制到此目录
- $to = self::$watch . $filename;
- // 种子完整存放路径
- $torrentFile = self::$torrentDir . $filename;
- if(is_file($torrentFile)){
- $fileSize = filesize($torrentFile); //失败会返回false 或 0(0代表上次下载失败)
- if ( !empty($fileSize) ) {
- //种子已经存在
- echo '-----存在旧种子:'.$filename."\n\n";
- continue;
- }
- // 删除下载错误的文件
- IFile::unlink($torrentFile);
- }
-
- // 调用过滤函数
- $isFilter = filter(self::$site, $value);
- if ( is_string( $isFilter ) ) {
- echo "-----" .$isFilter. "\n\n";
- continue;
- }
- //种子不存在
- echo '正在下载新种子... '.$value['download']." \n";
- // 创建文件、下载种子以二进制写入
- $content = '';
- $content = download($value['download'], self::$cookies, self::$userAgent, self::$method);
- #p($content);
- // 文件句柄
- $resource = fopen($torrentFile, "wb");
- // 成功:返回写入字节数,失败返回false
- $worldsnum = fwrite($resource, $content);
- // 关闭
- fclose($resource);
- // 判断
- if(is_bool($worldsnum)){
- print "种子下载失败!!! \n\n";
- IFile::unlink($torrentFile);
- continue;
- }else{
- print "成功下载种子" . $filename . ',共计:' . $worldsnum . "字节 \n";
- sleep(mt_rand(2,10));
- $ret = false;
- $rpcKey = self::$RPC_Key;
- switch( (int)self::$workingMode ){
- case 0: //默认工作模式
- $ret = self::add($torrentFile, $to);
- break;
- case 1: //负载均衡模式
- $type = self::$links[$rpcKey]['type'];
- // 下载服务器类型
- switch ($type) {
- case 'transmission':
- # code...
- break;
- case 'qBittorrent':
- $extra_options['name'] = 'torrents';
- $extra_options['filename'] = $filename;
- $extra_options['autoTMM'] = 'false'; //关闭自动种子管理
- break;
- default:
- # code...
- break;
- }
- // 种子文件添加下载任务
- $ret = self::add($content, $to, $extra_options);
- break;
- case 2:
- echo "\n\n";
- # 暂未开放
- break;
- default:
- echo "\n\n";
- break;
- }
- global $configALL;
- if( isset($configALL['iyuu.cn']) && ($ret === true) ){
- send(self::$site, $value);
- }
- }
- }
- return true;
- }
+ $clientsConut = count(self::$clients);
+ if ($clientsConut > 1) {
+ if ($clientsConut > (self::$RPC_Key+1)) {
+ self::$RPC_Key++;
+ } else {
+ self::$RPC_Key = 0;
+ }
+ }
+ }
+ /**
+ * @brief 种子处理函数
+ * @param array $data 种子数组
+ * Array
+ (
+ [id] => 118632
+ [h1] => CCTV5+ 2019 ATP Men's Tennis Final 20191115B HDTV 1080i H264-HDxxx
+ [title] => 央视体育赛事频道 2019年ATP男子网球年终总决赛 单打小组赛 纳达尔VS西西帕斯 20191115[优惠剩余时间:4时13分]
+ [details] => https://XXX.me/details.php?id=118632
+ [download] => https://XXX.me/download.php?id=118632
+ [filename] => 118632.torrent
+ [type] => 0
+ [sticky] => 1
+ [time] => Array
+ (
+ [0] => "2019-11-16 20:41:53">4时13分
+ [1] => "2019-11-16 14:41:53">1时
46分
+ )
+ [comments] => 0
+ [size] => 5232.64MB
+ [seeders] => 69
+ [leechers] => 10
+ [completed] => 93
+ [percentage] => 100%
+ [owner] => 匿名
+ )
+ * @return
+ */
+ public static function call($data = array())
+ {
+ foreach ($data as $key => $value) {
+ // 控制台打印
+ echo '主标题:'.$value['h1']."\n";
+ echo '副标题:'.$value['title']."\n";
+ echo '详情页:'.$value['details']."\n";
+ if ($value['type'] != 0) {
+ echo "-----非免费,已忽略! \n\n";
+ continue;
+ }
+ if (isset($value['hr']) && ($value['hr'] == 1)) {
+ echo "-----HR种子,已忽略! \n\n";
+ continue;
+ }
+ // 下载任务的可选参数
+ $extra_options = array();
+ // 保存的文件名
+ $filename = $value['id'] . '.torrent';
+ // 默认watch工作模式,复制到此目录
+ $to = self::$watch . $filename;
+ // 种子完整存放路径
+ $torrentFile = self::$torrentDir . $filename;
+ if (is_file($torrentFile)) {
+ $fileSize = filesize($torrentFile); //失败会返回false 或 0(0代表上次下载失败)
+ if (!empty($fileSize)) {
+ //种子已经存在
+ echo '-----存在旧种子:'.$filename."\n\n";
+ continue;
+ }
+ // 删除下载错误的文件
+ IFile::unlink($torrentFile);
+ }
+
+ // 调用过滤函数
+ $isFilter = filter(self::$site, $value);
+ if (is_string($isFilter)) {
+ echo "-----" .$isFilter. "\n\n";
+ continue;
+ }
+ //种子不存在
+ echo '正在下载新种子... '.$value['download']." \n";
+ // 创建文件、下载种子以二进制写入
+ $content = '';
+ $content = download($value['download'], self::$cookies, self::$userAgent, self::$method);
+ #p($content);
+ // 文件句柄
+ $resource = fopen($torrentFile, "wb");
+ // 成功:返回写入字节数,失败返回false
+ $worldsnum = fwrite($resource, $content);
+ // 关闭
+ fclose($resource);
+ // 判断
+ if (is_bool($worldsnum)) {
+ print "种子下载失败!!! \n\n";
+ IFile::unlink($torrentFile);
+ continue;
+ } else {
+ print "成功下载种子" . $filename . ',共计:' . $worldsnum . "字节 \n";
+ sleep(mt_rand(2, 10));
+ $ret = false;
+ $rpcKey = self::$RPC_Key;
+ switch ((int)self::$workingMode) {
+ case 0: //默认工作模式
+ $ret = self::add($torrentFile, $to);
+ break;
+ case 1: //负载均衡模式
+ $type = self::$links[$rpcKey]['type'];
+ // 下载服务器类型
+ switch ($type) {
+ case 'transmission':
+ # code...
+ break;
+ case 'qBittorrent':
+ $extra_options['name'] = 'torrents';
+ $extra_options['filename'] = $filename;
+ $extra_options['autoTMM'] = 'false'; //关闭自动种子管理
+ break;
+ default:
+ # code...
+ break;
+ }
+ // 种子文件添加下载任务
+ $ret = self::add($content, $to, $extra_options);
+ break;
+ case 2:
+ echo "\n\n";
+ # 暂未开放
+ break;
+ default:
+ echo "\n\n";
+ break;
+ }
+ global $configALL;
+ if (isset($configALL['iyuu.cn']) && ($ret === true)) {
+ send(self::$site, $value);
+ }
+ }
+ }
+ return true;
+ }
}
diff --git a/app/Class/TransmissionRPC.php b/app/Class/TransmissionRPC.php
index 0d5f450..5e50336 100644
--- a/app/Class/TransmissionRPC.php
+++ b/app/Class/TransmissionRPC.php
@@ -13,7 +13,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -29,8 +29,9 @@
/**
* A friendly little version check...
*/
-if ( version_compare( PHP_VERSION, TransmissionRPC::MIN_PHPVER, '<' ) )
- die( "The TransmissionRPC class requires PHP version {TransmissionRPC::TRANSMISSIONRPC_MIN_PHPVER} or above." . PHP_EOL );
+if (version_compare(PHP_VERSION, TransmissionRPC::MIN_PHPVER, '<')) {
+ die("The TransmissionRPC class requires PHP version {TransmissionRPC::TRANSMISSIONRPC_MIN_PHPVER} or above." . PHP_EOL);
+}
/**
* Transmission bittorrent client/daemon RPC communication class
@@ -44,627 +45,687 @@ if ( version_compare( PHP_VERSION, TransmissionRPC::MIN_PHPVER, '<' ) )
*/
class TransmissionRPC
{
- /**
- * 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
- * @var string
- */
- public $url = '';
-
- /**
- * If your Transmission RPC requires authentication, supply username here
- * @var string
- */
- public $username = '';
-
- /**
- * If your Transmission RPC requires authentication, supply password here
- * @var string
- */
- 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
- */
- public $debug = false;
-
- /**
- * Transmission RPC version
- * @var int
- */
- protected $rpc_version = 0;
-
- /**
- * Transmission uses a session id to prevent CSRF attacks
- * @var string
- */
- protected $session_id = '';
-
- /**
- * Default values for stream context
- * @var array
- */
- private $default_context_opts = array( 'http' => array(
+ /**
+ * 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
+ * @var string
+ */
+ public $url = '';
+
+ /**
+ * If your Transmission RPC requires authentication, supply username here
+ * @var string
+ */
+ public $username = '';
+
+ /**
+ * If your Transmission RPC requires authentication, supply password here
+ * @var string
+ */
+ 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
+ */
+ public $debug = false;
+
+ /**
+ * Transmission RPC version
+ * @var int
+ */
+ protected $rpc_version = 0;
+
+ /**
+ * Transmission uses a session id to prevent CSRF attacks
+ * @var string
+ */
+ protected $session_id = '';
+
+ /**
+ * Default values for stream context
+ * @var array
+ */
+ private $default_context_opts = array( 'http' => array(
'user_agent' => self::HTTP_UA,
'timeout' => '60', // Don't want to be too slow
'ignore_errors' => true, // Leave the error parsing/handling to the code
)
);
- /**
- * Constants for torrent status
- */
- const TR_STATUS_STOPPED = 0;
- const TR_STATUS_CHECK_WAIT = 1;
- const TR_STATUS_CHECK = 2;
- const TR_STATUS_DOWNLOAD_WAIT = 3;
- const TR_STATUS_DOWNLOAD = 4;
- const TR_STATUS_SEED_WAIT = 5;
- const TR_STATUS_SEED = 6;
-
- const RPC_LT_14_TR_STATUS_CHECK_WAIT = 1;
- const RPC_LT_14_TR_STATUS_CHECK = 2;
- const RPC_LT_14_TR_STATUS_DOWNLOAD = 4;
- const RPC_LT_14_TR_STATUS_SEED = 8;
- const RPC_LT_14_TR_STATUS_STOPPED = 16;
-
- /**
- * Start one or more torrents
- *
- * @param int|array ids A list of transmission torrent ids
- */
- public function start ( $ids )
- {
- 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 );
- }
-
- /**
- * Stop one or more torrents
- *
- * @param int|array ids A list of transmission torrent ids
- */
- public function stop ( $ids )
- {
- 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 );
- }
-
- /**
- * Reannounce one or more torrents
- *
- * @param int|array ids A list of transmission torrent ids
- */
- public function reannounce ( $ids )
- {
- 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 );
- }
-
- /**
- * Verify one or more torrents
- *
- * @param int|array ids A list of transmission torrent ids
- */
- public function verify ( $ids )
- {
- 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 );
- }
-
- /**
- * Get information on torrents in transmission, if the ids parameter is
- * empty all torrents will be returned. The fields array can be used to return certain
- * fields. Default fields are: "id", "name", "status", "doneDate", "haveValid", "totalSize".
- * See https://github.com/transmission/transmission/blob/2.9x/extras/rpc-spec.txt for available fields
- *
- * @param array fields An array of return fields
- * @param int|array ids A list of transmission torrent ids
- *
- Request:
- {
- "arguments": {
- "fields": [ "id", "name", "totalSize" ],
- "ids": [ 7, 10 ]
- },
- "method": "torrent-get",
- "tag": 39693
- }
+ /**
+ * Constants for torrent status
+ */
+ const TR_STATUS_STOPPED = 0;
+ const TR_STATUS_CHECK_WAIT = 1;
+ const TR_STATUS_CHECK = 2;
+ const TR_STATUS_DOWNLOAD_WAIT = 3;
+ const TR_STATUS_DOWNLOAD = 4;
+ const TR_STATUS_SEED_WAIT = 5;
+ const TR_STATUS_SEED = 6;
+
+ const RPC_LT_14_TR_STATUS_CHECK_WAIT = 1;
+ const RPC_LT_14_TR_STATUS_CHECK = 2;
+ const RPC_LT_14_TR_STATUS_DOWNLOAD = 4;
+ const RPC_LT_14_TR_STATUS_SEED = 8;
+ const RPC_LT_14_TR_STATUS_STOPPED = 16;
+
+ /**
+ * Start one or more torrents
+ *
+ * @param int|array ids A list of transmission torrent ids
+ */
+ public function start($ids)
+ {
+ 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);
+ }
- Response:
- {
- "arguments": {
- "torrents": [
- {
- "id": 10,
- "name": "Fedora x86_64 DVD",
- "totalSize": 34983493932,
- },
- {
- "id": 7,
- "name": "Ubuntu x86_64 DVD",
- "totalSize", 9923890123,
- }
- ]
- },
- "result": "success",
- "tag": 39693
- }
- */
- public function get ( $ids = array(), $fields = array() )
- {
- if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed
- if ( count( $fields ) == 0 ) $fields = array( "id", "name", "status", "doneDate", "haveValid", "totalSize" ); // Defaults
+ /**
+ * Stop one or more torrents
+ *
+ * @param int|array ids A list of transmission torrent ids
+ */
+ public function stop($ids)
+ {
+ 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);
+ }
+
+ /**
+ * Reannounce one or more torrents
+ *
+ * @param int|array ids A list of transmission torrent ids
+ */
+ public function reannounce($ids)
+ {
+ 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);
+ }
+
+ /**
+ * Verify one or more torrents
+ *
+ * @param int|array ids A list of transmission torrent ids
+ */
+ public function verify($ids)
+ {
+ 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);
+ }
+
+ /**
+ * Get information on torrents in transmission, if the ids parameter is
+ * empty all torrents will be returned. The fields array can be used to return certain
+ * fields. Default fields are: "id", "name", "status", "doneDate", "haveValid", "totalSize".
+ * See https://github.com/transmission/transmission/blob/2.9x/extras/rpc-spec.txt for available fields
+ *
+ * @param array fields An array of return fields
+ * @param int|array ids A list of transmission torrent ids
+ *
+ Request:
+ {
+ "arguments": {
+ "fields": [ "id", "name", "totalSize" ],
+ "ids": [ 7, 10 ]
+ },
+ "method": "torrent-get",
+ "tag": 39693
+ }
+
+ Response:
+ {
+ "arguments": {
+ "torrents": [
+ {
+ "id": 10,
+ "name": "Fedora x86_64 DVD",
+ "totalSize": 34983493932,
+ },
+ {
+ "id": 7,
+ "name": "Ubuntu x86_64 DVD",
+ "totalSize", 9923890123,
+ }
+ ]
+ },
+ "result": "success",
+ "tag": 39693
+ }
+ */
+ public function get($ids = array(), $fields = array())
+ {
+ if (!is_array($ids)) {
+ $ids = array( $ids );
+ } // Convert $ids to an array if only a single id was passed
+ if (count($fields) == 0) {
+ $fields = array( "id", "name", "status", "doneDate", "haveValid", "totalSize" );
+ } // Defaults
$request = array(
"fields" => $fields,
"ids" => $ids
);
- return $this->request( "torrent-get", $request );
- }
-
- /**
- * Set properties on one or more torrents, available fields are:
- * "bandwidthPriority" | number this torrent's bandwidth tr_priority_t
- * "downloadLimit" | number maximum download speed (in K/s)
- * "downloadLimited" | boolean true if "downloadLimit" is honored
- * "files-wanted" | array indices of file(s) to download
- * "files-unwanted" | array indices of file(s) to not download
- * "honorsSessionLimits" | boolean true if session upload limits are honored
- * "ids" | array torrent list, as described in 3.1
- * "location" | string new location of the torrent's content
- * "peer-limit" | number maximum number of peers
- * "priority-high" | array indices of high-priority file(s)
- * "priority-low" | array indices of low-priority file(s)
- * "priority-normal" | array indices of normal-priority file(s)
- * "seedRatioLimit" | double session seeding ratio
- * "seedRatioMode" | number which ratio to use. See tr_ratiolimit
- * "uploadLimit" | number maximum upload speed (in K/s)
- * "uploadLimited" | boolean true if "uploadLimit" is honored
- * See https://github.com/transmission/transmission/blob/2.9x/extras/rpc-spec.txt for more information
- *
- * @param array arguments An associative array of arguments to set
- * @param int|array ids A list of transmission torrent ids
- */
- public function set ( $ids = array(), $arguments = array() )
- {
- // See https://github.com/transmission/transmission/blob/2.9x/extras/rpc-spec.txt for available fields
- if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed
- if ( !isset( $arguments['ids'] ) ) $arguments['ids'] = $ids; // Any $ids given in $arguments overrides the method parameter
- return $this->request( "torrent-set", $arguments );
- }
-
- /**
- * Add a new torrent
- *
- * Available extra options:
- * key | value type & description
- * ---------------------+-------------------------------------------------
- * "download-dir" | string path to download the torrent to
- * "filename" | string filename or URL of the .torrent file
- * "metainfo" | string base64-encoded .torrent content
- * "paused" | boolean if true, don't start the torrent
- * "peer-limit" | number maximum number of peers
- * "bandwidthPriority" | number torrent's bandwidth tr_priority_t
- * "files-wanted" | array indices of file(s) to download
- * "files-unwanted" | array indices of file(s) to not download
- * "priority-high" | array indices of high-priority file(s)
- * "priority-low" | array indices of low-priority file(s)
- * "priority-normal" | array indices of normal-priority file(s)
- *
- * Either "filename" OR "metainfo" MUST be included.
- * All other arguments are optional.
- *
- * @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_file ( $torrent_location, $save_path = '', $extra_options = array() )
- {
- if(!empty($save_path)) $extra_options['download-dir'] = $save_path;
- $extra_options['filename'] = $torrent_location;
+ return $this->request("torrent-get", $request);
+ }
+
+ /**
+ * Set properties on one or more torrents, available fields are:
+ * "bandwidthPriority" | number this torrent's bandwidth tr_priority_t
+ * "downloadLimit" | number maximum download speed (in K/s)
+ * "downloadLimited" | boolean true if "downloadLimit" is honored
+ * "files-wanted" | array indices of file(s) to download
+ * "files-unwanted" | array indices of file(s) to not download
+ * "honorsSessionLimits" | boolean true if session upload limits are honored
+ * "ids" | array torrent list, as described in 3.1
+ * "location" | string new location of the torrent's content
+ * "peer-limit" | number maximum number of peers
+ * "priority-high" | array indices of high-priority file(s)
+ * "priority-low" | array indices of low-priority file(s)
+ * "priority-normal" | array indices of normal-priority file(s)
+ * "seedRatioLimit" | double session seeding ratio
+ * "seedRatioMode" | number which ratio to use. See tr_ratiolimit
+ * "uploadLimit" | number maximum upload speed (in K/s)
+ * "uploadLimited" | boolean true if "uploadLimit" is honored
+ * See https://github.com/transmission/transmission/blob/2.9x/extras/rpc-spec.txt for more information
+ *
+ * @param array arguments An associative array of arguments to set
+ * @param int|array ids A list of transmission torrent ids
+ */
+ public function set($ids = array(), $arguments = array())
+ {
+ // See https://github.com/transmission/transmission/blob/2.9x/extras/rpc-spec.txt for available fields
+ if (!is_array($ids)) {
+ $ids = array( $ids );
+ } // Convert $ids to an array if only a single id was passed
+ if (!isset($arguments['ids'])) {
+ $arguments['ids'] = $ids;
+ } // Any $ids given in $arguments overrides the method parameter
+ return $this->request("torrent-set", $arguments);
+ }
+
+ /**
+ * Add a new torrent
+ *
+ * Available extra options:
+ * key | value type & description
+ * ---------------------+-------------------------------------------------
+ * "download-dir" | string path to download the torrent to
+ * "filename" | string filename or URL of the .torrent file
+ * "metainfo" | string base64-encoded .torrent content
+ * "paused" | boolean if true, don't start the torrent
+ * "peer-limit" | number maximum number of peers
+ * "bandwidthPriority" | number torrent's bandwidth tr_priority_t
+ * "files-wanted" | array indices of file(s) to download
+ * "files-unwanted" | array indices of file(s) to not download
+ * "priority-high" | array indices of high-priority file(s)
+ * "priority-low" | array indices of low-priority file(s)
+ * "priority-normal" | array indices of normal-priority file(s)
+ *
+ * Either "filename" OR "metainfo" MUST be included.
+ * All other arguments are optional.
+ *
+ * @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_file($torrent_location, $save_path = '', $extra_options = array())
+ {
+ if (!empty($save_path)) {
+ $extra_options['download-dir'] = $save_path;
+ }
+ $extra_options['filename'] = $torrent_location;
- return $this->request( "torrent-add", $extra_options );
- }
-
- /**
- * Add a torrent using the raw torrent data
- *
- * @param torrent_metainfo The raw, unencoded contents (metainfo) of a torrent
- * @param save_path Folder to save torrent in
- * @param extra options Optional extra torrent options
- */
- public function add_metainfo ( $torrent_metainfo, $save_path = '', $extra_options = array() )
- {
- $extra_options['download-dir'] = $save_path;
- $extra_options['metainfo'] = base64_encode( $torrent_metainfo );
+ return $this->request("torrent-add", $extra_options);
+ }
+
+ /**
+ * Add a torrent using the raw torrent data
+ *
+ * @param torrent_metainfo The raw, unencoded contents (metainfo) of a torrent
+ * @param save_path Folder to save torrent in
+ * @param extra options Optional extra torrent options
+ */
+ public function add_metainfo($torrent_metainfo, $save_path = '', $extra_options = array())
+ {
+ $extra_options['download-dir'] = $save_path;
+ $extra_options['metainfo'] = base64_encode($torrent_metainfo);
- 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
- *
- * @param bool delete_local_data Also remove local data?
- * @param int|array ids A list of transmission torrent ids
- */
- public function remove ( $ids, $delete_local_data = false )
- {
- if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed
- $request = array(
+ 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
+ *
+ * @param bool delete_local_data Also remove local data?
+ * @param int|array ids A list of transmission torrent ids
+ */
+ public function remove($ids, $delete_local_data = false)
+ {
+ if (!is_array($ids)) {
+ $ids = array( $ids );
+ } // Convert $ids to an array if only a single id was passed
+ $request = array(
"ids" => $ids,
"delete-local-data" => $delete_local_data
);
- return $this->request( "torrent-remove", $request );
- }
-
- /**
- * Move local storage location
- *
- * @param int|array ids A list of transmission torrent ids
- * @param string target_location The new storage location
- * @param string move_existing_data Move existing data or scan new location for available data
- */
- public function move ( $ids, $target_location, $move_existing_data = true )
- {
- if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed
- $request = array(
+ return $this->request("torrent-remove", $request);
+ }
+
+ /**
+ * Move local storage location
+ *
+ * @param int|array ids A list of transmission torrent ids
+ * @param string target_location The new storage location
+ * @param string move_existing_data Move existing data or scan new location for available data
+ */
+ public function move($ids, $target_location, $move_existing_data = true)
+ {
+ if (!is_array($ids)) {
+ $ids = array( $ids );
+ } // Convert $ids to an array if only a single id was passed
+ $request = array(
"ids" => $ids,
"location" => $target_location,
"move" => $move_existing_data
);
- return $this->request( "torrent-set-location", $request );
- }
-
- /**
- * 3.7. Renaming a Torrent's Path
- *
- * Method name: "torrent-rename-path"
- *
- * For more information on the use of this function, see the transmission.h
- * documentation of tr_torrentRenamePath(). In particular, note that if this
- * call succeeds you'll want to update the torrent's "files" and "name" field
- * with torrent-get.
- *
- * Request arguments:
- *
- * string | value type & description
- * ---------------------------------+-------------------------------------------------
- * "ids" | array the torrent torrent list, as described in 3.1
- * | (must only be 1 torrent)
- * "path" | string the path to the file or folder that will be renamed
- * "name" | string the file or folder's new name
-
- * Response arguments: "path", "name", and "id", holding the torrent ID integer
- *
- * @param int|array ids A 1-element list of transmission torrent ids
- * @param string path The path to the file or folder that will be renamed
- * @param string name The file or folder's new name
- */
- public function rename ( $ids, $path, $name )
- {
- if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $id to an array if only a single id was passed
- if ( count( $ids ) !== 1 ) {
- throw new TransmissionRPCException( 'A single id is accepted', TransmissionRPCException::E_INVALIDARG );
+ return $this->request("torrent-set-location", $request);
}
+
+ /**
+ * 3.7. Renaming a Torrent's Path
+ *
+ * Method name: "torrent-rename-path"
+ *
+ * For more information on the use of this function, see the transmission.h
+ * documentation of tr_torrentRenamePath(). In particular, note that if this
+ * call succeeds you'll want to update the torrent's "files" and "name" field
+ * with torrent-get.
+ *
+ * Request arguments:
+ *
+ * string | value type & description
+ * ---------------------------------+-------------------------------------------------
+ * "ids" | array the torrent torrent list, as described in 3.1
+ * | (must only be 1 torrent)
+ * "path" | string the path to the file or folder that will be renamed
+ * "name" | string the file or folder's new name
+
+ * Response arguments: "path", "name", and "id", holding the torrent ID integer
+ *
+ * @param int|array ids A 1-element list of transmission torrent ids
+ * @param string path The path to the file or folder that will be renamed
+ * @param string name The file or folder's new name
+ */
+ public function rename($ids, $path, $name)
+ {
+ if (!is_array($ids)) {
+ $ids = array( $ids );
+ } // Convert $id to an array if only a single id was passed
+ if (count($ids) !== 1) {
+ throw new TransmissionRPCException('A single id is accepted', TransmissionRPCException::E_INVALIDARG);
+ }
- $request = array(
+ $request = array(
"ids" => $ids,
"path" => $path,
"name" => $name
);
- return $this->request( "torrent-rename-path", $request );
- }
-
-
- /**
- * Retrieve session statistics
- *
- * @returns array of statistics
- */
- public function sstats ( )
- {
- return $this->request( "session-stats", array() );
- }
-
- /**
- * Retrieve all session variables
- *
- * @returns array of session information
- */
- public function sget ( )
- {
- return $this->request( "session-get", array() );
- }
-
- /**
- * Set session variable(s)
- *
- * @param array of session variables to set
- */
- public function sset ( $arguments )
- {
- return $this->request( "session-set", $arguments );
- }
-
- /**
- * Return the interpretation of the torrent status
- *
- * @param int The integer "torrent status"
- * @returns string The translated meaning
- */
- public function getStatusString ( $intstatus )
- {
- if($this->rpc_version < 14){
- if( $intstatus == self::RPC_LT_14_TR_STATUS_CHECK_WAIT )
- return "Waiting to verify local files";
- if( $intstatus == self::RPC_LT_14_TR_STATUS_CHECK )
- return "Verifying local files";
- if( $intstatus == self::RPC_LT_14_TR_STATUS_DOWNLOAD )
- return "Downloading";
- if( $intstatus == self::RPC_LT_14_TR_STATUS_SEED )
- return "Seeding";
- if( $intstatus == self::RPC_LT_14_TR_STATUS_STOPPED )
- return "Stopped";
- }else{
- if( $intstatus == self::TR_STATUS_CHECK_WAIT )
- return "Waiting to verify local files";
- if( $intstatus == self::TR_STATUS_CHECK )
- return "Verifying local files";
- if( $intstatus == self::TR_STATUS_DOWNLOAD )
- return "Downloading";
- if( $intstatus == self::TR_STATUS_SEED )
- return "Seeding";
- if( $intstatus == self::TR_STATUS_STOPPED )
- return "Stopped";
- if( $intstatus == self::TR_STATUS_SEED_WAIT )
- return "Queued for seeding";
- if( $intstatus == self::TR_STATUS_DOWNLOAD_WAIT )
- return "Queued for download";
+ return $this->request("torrent-rename-path", $request);
+ }
+
+
+ /**
+ * Retrieve session statistics
+ *
+ * @returns array of statistics
+ */
+ public function sstats()
+ {
+ return $this->request("session-stats", array());
}
- return "Unknown";
- }
+ /**
+ * Retrieve all session variables
+ *
+ * @returns array of session information
+ */
+ public function sget()
+ {
+ return $this->request("session-get", array());
+ }
+ /**
+ * Set session variable(s)
+ *
+ * @param array of session variables to set
+ */
+ public function sset($arguments)
+ {
+ return $this->request("session-set", $arguments);
+ }
- /**
- * Here be dragons (Internal methods)
- */
+ /**
+ * Return the interpretation of the torrent status
+ *
+ * @param int The integer "torrent status"
+ * @returns string The translated meaning
+ */
+ public function getStatusString($intstatus)
+ {
+ if ($this->rpc_version < 14) {
+ if ($intstatus == self::RPC_LT_14_TR_STATUS_CHECK_WAIT) {
+ return "Waiting to verify local files";
+ }
+ if ($intstatus == self::RPC_LT_14_TR_STATUS_CHECK) {
+ return "Verifying local files";
+ }
+ if ($intstatus == self::RPC_LT_14_TR_STATUS_DOWNLOAD) {
+ return "Downloading";
+ }
+ if ($intstatus == self::RPC_LT_14_TR_STATUS_SEED) {
+ return "Seeding";
+ }
+ if ($intstatus == self::RPC_LT_14_TR_STATUS_STOPPED) {
+ return "Stopped";
+ }
+ } else {
+ if ($intstatus == self::TR_STATUS_CHECK_WAIT) {
+ return "Waiting to verify local files";
+ }
+ if ($intstatus == self::TR_STATUS_CHECK) {
+ return "Verifying local files";
+ }
+ if ($intstatus == self::TR_STATUS_DOWNLOAD) {
+ return "Downloading";
+ }
+ if ($intstatus == self::TR_STATUS_SEED) {
+ return "Seeding";
+ }
+ if ($intstatus == self::TR_STATUS_STOPPED) {
+ return "Stopped";
+ }
+ if ($intstatus == self::TR_STATUS_SEED_WAIT) {
+ return "Queued for seeding";
+ }
+ if ($intstatus == self::TR_STATUS_DOWNLOAD_WAIT) {
+ return "Queued for download";
+ }
+ }
+ return "Unknown";
+ }
- /**
- * Clean up the request array. Removes any empty fields from the request
- *
- * @param array array The request associative array to clean
- * @returns array The cleaned array
- */
- protected function cleanRequestData ( $array )
- {
- if ( !is_array( $array ) || count( $array ) == 0 ) return null; // Nothing to clean
- setlocale( LC_NUMERIC, 'en_US.utf8' ); // Override the locale - if the system locale is wrong, then 12.34 will encode as 12,34 which is invalid JSON
- foreach ( $array as $index => $value )
+ /**
+ * Here be dragons (Internal methods)
+ */
+
+
+
+ /**
+ * Clean up the request array. Removes any empty fields from the request
+ *
+ * @param array array The request associative array to clean
+ * @returns array The cleaned array
+ */
+ protected function cleanRequestData($array)
{
- if( is_object( $value ) ) $array[$index] = $value->toArray(); // Convert objects to arrays so they can be JSON encoded
- if( is_array( $value ) ) $array[$index] = $this->cleanRequestData( $value ); // Recursion
- if( empty( $value ) && $value !== 0 ) // Remove empty members
- {
- unset( $array[$index] );
- continue; // Skip the rest of the tests - they may re-add the element.
+ if (!is_array($array) || count($array) == 0) {
+ return null;
+ } // Nothing to clean
+ setlocale(LC_NUMERIC, 'en_US.utf8'); // Override the locale - if the system locale is wrong, then 12.34 will encode as 12,34 which is invalid JSON
+ foreach ($array as $index => $value) {
+ if (is_object($value)) {
+ $array[$index] = $value->toArray();
+ } // Convert objects to arrays so they can be JSON encoded
+ if (is_array($value)) {
+ $array[$index] = $this->cleanRequestData($value);
+ } // Recursion
+ if (empty($value) && $value !== 0) { // Remove empty members
+ unset($array[$index]);
+ continue; // Skip the rest of the tests - they may re-add the element.
}
- if( is_numeric( $value ) ) $array[$index] = $value+0; // Force type-casting for proper JSON encoding (+0 is a cheap way to maintain int/float/etc)
- if( is_bool( $value ) ) $array[$index] = ( $value ? 1 : 0); // Store boolean values as 0 or 1
- if( is_string( $value ) ) {
- if ( mb_detect_encoding($value,"auto") !== 'UTF-8' ) {
- $array[$index] = mb_convert_encoding($value, "UTF-8");
- //utf8_encode( $value ); // Make sure all data is UTF-8 encoded for Transmission
- }
+ if (is_numeric($value)) {
+ $array[$index] = $value+0;
+ } // Force type-casting for proper JSON encoding (+0 is a cheap way to maintain int/float/etc)
+ if (is_bool($value)) {
+ $array[$index] = ($value ? 1 : 0);
+ } // Store boolean values as 0 or 1
+ if (is_string($value)) {
+ if (mb_detect_encoding($value, "auto") !== 'UTF-8') {
+ $array[$index] = mb_convert_encoding($value, "UTF-8");
+ //utf8_encode( $value ); // Make sure all data is UTF-8 encoded for Transmission
+ }
}
}
- 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
- */
- 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 )
+ 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
+ */
+ protected function cleanResultObject($object)
{
- 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] );
+ // 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;
}
- // Return array cast to object
- return $return_as_array ? $array : (object) $array;
- }
- /**
- * 执行 rpc 请求
- *
- * @param $method 请求类型/方法, 详见 $this->allowMethods
- * @param array $arguments 附加参数, 可选
- * @return mixed
- */
- protected function request($method, $arguments = array())
- {
- // Check the parameters
- if ( !is_scalar( $method ) )
- throw new TransmissionRPCException( 'Method name has no scalar value', TransmissionRPCException::E_INVALIDARG );
- if ( !is_array( $arguments ) )
- throw new TransmissionRPCException( 'Arguments must be given as array', TransmissionRPCException::E_INVALIDARG );
+ /**
+ * 执行 rpc 请求
+ *
+ * @param $method 请求类型/方法, 详见 $this->allowMethods
+ * @param array $arguments 附加参数, 可选
+ * @return mixed
+ */
+ protected function request($method, $arguments = array())
+ {
+ // Check the parameters
+ if (!is_scalar($method)) {
+ throw new TransmissionRPCException('Method name has no scalar value', TransmissionRPCException::E_INVALIDARG);
+ }
+ if (!is_array($arguments)) {
+ throw new TransmissionRPCException('Arguments must be given as array', TransmissionRPCException::E_INVALIDARG);
+ }
- $arguments = $this->cleanRequestData( $arguments ); // Sanitize input
+ $arguments = $this->cleanRequestData($arguments); // Sanitize input
- // Grab the X-Transmission-Session-Id if we don't have it already
- if( !$this->session_id )
- if( !$this->GetSessionID() )
- throw new TransmissionRPCException( 'Unable to acquire X-Transmission-Session-Id', TransmissionRPCException::E_SESSIONID );
+ // Grab the X-Transmission-Session-Id if we don't have it already
+ if (!$this->session_id) {
+ if (!$this->GetSessionID()) {
+ throw new TransmissionRPCException('Unable to acquire X-Transmission-Session-Id', TransmissionRPCException::E_SESSIONID);
+ }
+ }
- $data = array(
+ $data = array(
'method' => $method,
'arguments' => $arguments
);
- $header = array(
+ $header = array(
'Content-Type: application/json',
'Authorization: Basic '.base64_encode(sprintf("%s:%s", $this->username, $this->password)),
'X-Transmission-Session-Id: '.$this->session_id
);
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $this->url);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
- curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->password);
- curl_setopt($ch, CURLOPT_HEADER, false);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
- curl_setopt($ch, CURLOPT_TIMEOUT, 600);
- $content = curl_exec($ch);
- curl_close($ch);
-
- if (!$content) $content = json_encode(array('result' => 'failed'));
- return $this->return_as_array ? json_decode( $content, true ) : $this->cleanResultObject( json_decode( $content ) ); // Return the sanitized result
- }
- /**
- * Performs an empty GET on the Transmission RPC to get the X-Transmission-Session-Id
- * and store it in $this->session_id
- *
- * @return string
- */
- public function GetSessionID()
- {
- if( !$this->url )
- throw new TransmissionRPCException( "Class must be initialized before GetSessionID() can be called.", TransmissionRPCException::E_INVALIDARG );
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $this->url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->password);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 600);
+ $content = curl_exec($ch);
+ curl_close($ch);
+
+ if (!$content) {
+ $content = json_encode(array('result' => 'failed'));
+ }
+ return $this->return_as_array ? json_decode($content, true) : $this->cleanResultObject(json_decode($content)); // Return the sanitized result
+ }
+ /**
+ * Performs an empty GET on the Transmission RPC to get the X-Transmission-Session-Id
+ * and store it in $this->session_id
+ *
+ * @return string
+ */
+ public function GetSessionID()
+ {
+ if (!$this->url) {
+ throw new TransmissionRPCException("Class must be initialized before GetSessionID() can be called.", TransmissionRPCException::E_INVALIDARG);
+ }
- // Setup the context
+ // Setup the context
$contextopts = $this->default_context_opts; // Start with the defaults
// Make sure it's blank/empty (reset)
- $this->session_id = null;
+ $this->session_id = null;
- // Setup authentication (if provided)
- if ( $this->username && $this->password )
- $contextopts['http']['header'] = sprintf( "Authorization: Basic %s\r\n", base64_encode( $this->username.':'.$this->password ) );
+ // Setup authentication (if provided)
+ if ($this->username && $this->password) {
+ $contextopts['http']['header'] = sprintf("Authorization: Basic %s\r\n", base64_encode($this->username.':'.$this->password));
+ }
- if( $this->debug ) echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream context created with options:".
- PHP_EOL . print_r( $contextopts, true );
+ if ($this->debug) {
+ echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream context created with options:".
+ PHP_EOL . print_r($contextopts, true);
+ }
- $context = stream_context_create( $contextopts ); // Create the context for this request
- if ( ! $fp = @fopen( $this->url, 'r', false, $context ) ) // Open a filepointer to the data, and use fgets to get the result
- throw new TransmissionRPCException( 'Unable to connect to '.$this->url, TransmissionRPCException::E_CONNECTION );
+ $context = stream_context_create($contextopts); // Create the context for this request
+ if (! $fp = @fopen($this->url, 'r', false, $context)) { // Open a filepointer to the data, and use fgets to get the result
+ throw new TransmissionRPCException('Unable to connect to '.$this->url, TransmissionRPCException::E_CONNECTION);
+ }
- // Check the response (headers etc)
- $stream_meta = stream_get_meta_data( $fp );
- fclose( $fp );
- if( $this->debug ) echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream meta info: ".
- PHP_EOL . print_r( $stream_meta, true );
- if( $stream_meta['timed_out'] )
- throw new TransmissionRPCException( "Timed out connecting to {$this->url}", TransmissionRPCException::E_CONNECTION );
- if( substr( $stream_meta['wrapper_data'][0], 9, 3 ) == "401" )
- throw new TransmissionRPCException( "Invalid username/password.", TransmissionRPCException::E_AUTHENTICATION );
- elseif( substr( $stream_meta['wrapper_data'][0], 9, 3 ) == "409" ) // This is what we're hoping to find
- {
+ // Check the response (headers etc)
+ $stream_meta = stream_get_meta_data($fp);
+ fclose($fp);
+ if ($this->debug) {
+ echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream meta info: ".
+ PHP_EOL . print_r($stream_meta, true);
+ }
+ if ($stream_meta['timed_out']) {
+ throw new TransmissionRPCException("Timed out connecting to {$this->url}", TransmissionRPCException::E_CONNECTION);
+ }
+ if (substr($stream_meta['wrapper_data'][0], 9, 3) == "401") {
+ throw new TransmissionRPCException("Invalid username/password.", TransmissionRPCException::E_AUTHENTICATION);
+ } elseif (substr($stream_meta['wrapper_data'][0], 9, 3) == "409") { // This is what we're hoping to find
// Loop through the returned headers and extract the X-Transmission-Session-Id
- foreach( $stream_meta['wrapper_data'] as $header )
- {
- if( strpos( $header, 'X-Transmission-Session-Id: ' ) === 0 )
- {
- if( $this->debug ) echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Session-Id header: ".
- PHP_EOL . print_r( $header, true );
- $this->session_id = trim( substr( $header, 27 ) );
- break;
+ foreach ($stream_meta['wrapper_data'] as $header) {
+ if (strpos($header, 'X-Transmission-Session-Id: ') === 0) {
+ if ($this->debug) {
+ echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Session-Id header: ".
+ PHP_EOL . print_r($header, true);
+ }
+ $this->session_id = trim(substr($header, 27));
+ break;
+ }
+ }
+ if (! $this->session_id) { // Didn't find a session_id
+ throw new TransmissionRPCException("Unable to retrieve X-Transmission-Session-Id", TransmissionRPCException::E_SESSIONID);
+ }
+ } else {
+ throw new TransmissionRPCException("Unexpected response from Transmission RPC: ".$stream_meta['wrapper_data'][0]);
}
- }
- if( ! $this->session_id ) { // Didn't find a session_id
- throw new TransmissionRPCException( "Unable to retrieve X-Transmission-Session-Id", TransmissionRPCException::E_SESSIONID );
- }
- } else {
- throw new TransmissionRPCException( "Unexpected response from Transmission RPC: ".$stream_meta['wrapper_data'][0] );
+ return $this->session_id;
}
- return $this->session_id;
- }
-
- /**
- * 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 )
- {
- // server URL
- $this->url = $url;
+
+ /**
+ * 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)
+ {
+ // server URL
+ $this->url = $url;
- // Username & password
- $this->username = $username;
- $this->password = $password;
+ // Username & password
+ $this->username = $username;
+ $this->password = $password;
- // Get the Transmission RPC_version
- $this->rpc_version = self::sget()->arguments->rpc_version;
+ // Get the Transmission RPC_version
+ $this->rpc_version = self::sget()->arguments->rpc_version;
- // Return As Array
- $this->return_as_array = $return_as_array;
+ // Return As Array
+ $this->return_as_array = $return_as_array;
- // Reset X-Transmission-Session-Id so we (re)fetch one
- $this->session_id = null;
- }
+ // Reset X-Transmission-Session-Id so we (re)fetch one
+ $this->session_id = null;
+ }
}
/**
@@ -672,37 +733,36 @@ class TransmissionRPC
*/
class TransmissionRPCException extends Exception
{
- /**
- * Exception: Invalid arguments
- */
- const E_INVALIDARG = -1;
-
- /**
- * Exception: Invalid Session-Id
- */
- const E_SESSIONID = -2;
-
- /**
- * Exception: Error while connecting
- */
- const E_CONNECTION = -3;
-
- /**
- * Exception: Error 401 returned, unauthorized
- */
- const E_AUTHENTICATION = -4;
-
- /**
- * Exception constructor
- */
- public function __construct( $message = null, $code = 0, Exception $previous = null )
- {
- // PHP version 5.3.0 and above support Exception linking
- if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) )
- parent::__construct( $message, $code, $previous );
- else
- parent::__construct( $message, $code );
- }
+ /**
+ * Exception: Invalid arguments
+ */
+ const E_INVALIDARG = -1;
+
+ /**
+ * Exception: Invalid Session-Id
+ */
+ const E_SESSIONID = -2;
+
+ /**
+ * Exception: Error while connecting
+ */
+ const E_CONNECTION = -3;
+
+ /**
+ * Exception: Error 401 returned, unauthorized
+ */
+ const E_AUTHENTICATION = -4;
+
+ /**
+ * Exception constructor
+ */
+ public function __construct($message = null, $code = 0, Exception $previous = null)
+ {
+ // PHP version 5.3.0 and above support Exception linking
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+ parent::__construct($message, $code, $previous);
+ } else {
+ parent::__construct($message, $code);
+ }
+ }
}
-
-?>
diff --git a/app/Class/qBittorrent.php b/app/Class/qBittorrent.php
index aa0e747..d61d0f5 100644
--- a/app/Class/qBittorrent.php
+++ b/app/Class/qBittorrent.php
@@ -1,5 +1,6 @@
null,
'2' => '/api/v2/app/setPreferences'
],
- 'defaultSavePath' => [
+ 'defaultSavePath' => [
'1' => null,
'2' => '/api/v2/app/defaultSavePath'
],
@@ -72,7 +73,7 @@ class qBittorrent
public function __construct($url='', $username='', $password='', $api_version = 2, $debug = false)
{
$this->debug = $debug;
- $this->url = rtrim($url,'/');
+ $this->url = rtrim($url, '/');
$this->username = $username;
$this->password = $password;
$this->api_version = $api_version;
@@ -130,29 +131,33 @@ class qBittorrent
*/
public function add($torrent_url, $save_path = '', $extra_options = array())
{
- if(!empty($save_path)) $extra_options['savepath'] = $save_path;
+ if (!empty($save_path)) {
+ $extra_options['savepath'] = $save_path;
+ }
$extra_options['urls'] = $torrent_url;
#$extra_options['skip_checking'] = 'true'; //跳校验
// 关键 上传文件流 multipart/form-data【严格按照api文档编写】
$post_data = $this->buildUrls($extra_options);
#p($post_data);
// 设置请求头
- $this->curl->setHeader('Content-Type','multipart/form-data; boundary='.$this->delimiter);
- $this->curl->setHeader('Content-Length',strlen($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 add_metainfo($torrent_metainfo, $save_path = '', $extra_options = array())
+ public function add_metainfo($torrent_metainfo, $save_path = '', $extra_options = array())
{
- if(!empty($save_path)) $extra_options['savepath'] = $save_path;
+ if (!empty($save_path)) {
+ $extra_options['savepath'] = $save_path;
+ }
$extra_options['torrents'] = $torrent_metainfo;
#$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));
+ $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);
}
@@ -250,7 +255,8 @@ class qBittorrent
* 拼接种子urls multipart/form-data
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation#add-new-torrent
*/
- private function buildUrls($param){
+ private function buildUrls($param)
+ {
$this->delimiter = uniqid();
$eol = "\r\n";
$data = '';
@@ -267,7 +273,8 @@ class qBittorrent
* 拼接种子上传文件流 multipart/form-data
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation#add-new-torrent
*/
- private function buildData($param){
+ private function buildData($param)
+ {
$this->delimiter = uniqid();
$eol = "\r\n";
$data = '';
diff --git a/app/Class/uTorrent.php b/app/Class/uTorrent.php
index 0f3412e..7be390a 100644
--- a/app/Class/uTorrent.php
+++ b/app/Class/uTorrent.php
@@ -29,7 +29,8 @@ define("UTORRENT_STATUS_STARTED", 1);
define("UTORRENT_STATUS_CHECKED", 2);
define("UTORRENT_STATUS_START_AFTER_CHECK", 4);
-class uTorrent {
+class uTorrent
+{
// class static variables
private static $base = "%s/gui/%s";
@@ -42,8 +43,9 @@ class uTorrent {
protected $guid;
// constructor
- function __construct($host = "", $user = "", $pass = "") {
- $this->host = rtrim($host,'/');
+ public function __construct($host = "", $user = "", $pass = "")
+ {
+ $this->host = rtrim($host, '/');
$this->user = $user;
$this->pass = $pass;
@@ -54,7 +56,8 @@ class uTorrent {
}
// performs request
- private function makeRequest($request, $decode = true, $options = array()) {
+ private function makeRequest($request, $decode = true, $options = array())
+ {
$request = preg_replace('/^\?/', '?token='.$this->token . '&', $request);
$ch = curl_init();
@@ -71,12 +74,14 @@ class uTorrent {
}
// implodes given parameter with glue, whether it is an array or not
- private function paramImplode($glue, $param) {
+ private function paramImplode($glue, $param)
+ {
return $glue.implode($glue, is_array($param) ? $param : array($param));
}
// gets token, returns true on success
- private function getToken() {
+ private function getToken()
+ {
$url = sprintf(self::$base, $this->host, 'token.html');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@@ -101,7 +106,8 @@ class uTorrent {
}
// returns the uTorrent build number
- public function getBuild(){
+ public function getBuild()
+ {
$json = $this->makeRequest("?");
return $json['build'];
}
@@ -109,13 +115,15 @@ class uTorrent {
// returns an array of files for the specified torrent hash
// TODO:
// - (when implemented in API) allow multiple hashes to be specified
- public function getFiles($hash) {
+ public function getFiles($hash)
+ {
$json = $this->makeRequest("?action=getfiles&hash=".$hash);
return $json['files'];
}
// returns an array of all labels
- public function getLabels(){
+ public function getLabels()
+ {
$json = $this->makeRequest("?list=1");
return $json['label'];
}
@@ -123,19 +131,22 @@ class uTorrent {
// returns an array of the properties for the specified torrent hash
// TODO:
// - (when implemented in API) allow multiple hashes to be specified
- public function getProperties($hash) {
+ public function getProperties($hash)
+ {
$json = $this->makeRequest("?action=getprops&hash=".$hash);
return $json['props'];
}
// returns an array of all settings
- public function getSettings() {
+ public function getSettings()
+ {
$json = $this->makeRequest("?action=getsettings");
return $json['settings'];
}
// returns an array of all torrent jobs and related information
- public function getTorrents() {
+ public function getTorrents()
+ {
$json = $this->makeRequest("?list=1");
return $json['torrents'];
}
@@ -144,7 +155,8 @@ class uTorrent {
* Get all the RSS favourites/filters
* @return model\Filter[]
*/
- public function getRSSFilters() {
+ public function getRSSFilters()
+ {
$json = $this->makeRequest("?list=1");
$filters = array();
foreach ($json['rssfilters'] as $filter) {
@@ -157,7 +169,8 @@ class uTorrent {
* Update an RSS filter as retrieved from getRSSFilters
* @param \uTorrent\model\Filter $filter
*/
- public function setRSSFilter(model\Filter $filter) {
+ public function setRSSFilter(model\Filter $filter)
+ {
$request = array_merge(array('action' => 'filter-update'), $filter->toParams());
return $this->makeRequest('?'.http_build_query($request));
}
@@ -168,7 +181,8 @@ class uTorrent {
* @param \uTorrent\model\Filter $filter
* @return int ID of the new filter
*/
- public function addRSSFilter(model\Filter $filter) {
+ public function addRSSFilter(model\Filter $filter)
+ {
$filter->filterId = -1;
$resp = $this->setRSSFilter($filter);
if (!empty($resp['filter_ident'])) {
@@ -179,77 +193,90 @@ class uTorrent {
}
// returns true if WebUI server is online and enabled, false otherwise
- public function is_online() {
+ public function is_online()
+ {
return is_array($this->makeRequest("?"));
}
// sets the properties for the specified torrent hash
// TODO:
// - allow multiple hashes, properties, and values to be set simultaneously
- public function setProperties($hash, $property, $value) {
+ public function setProperties($hash, $property, $value)
+ {
$this->makeRequest("?action=setprops&hash=".$hash."&s=".$property."&v=".$value, false);
}
// sets the priorities for the specified files in the specified torrent hash
- public function setPriority($hash, $files, $priority) {
+ public function setPriority($hash, $files, $priority)
+ {
$this->makeRequest("?action=setprio&hash=".$hash."&p=".$priority.$this->paramImplode("&f=", $files), false);
}
// sets the settings
// TODO:
// - allow multiple settings and values to be set simultaneously
- public function setSetting($setting, $value) {
+ public function setSetting($setting, $value)
+ {
$this->makeRequest("?action=setsetting&s=".$setting."&v=".$value, false);
}
// add a file to the list
- public function torrentAdd($filename, &$estring = false) {
+ public function torrentAdd($filename, &$estring = false)
+ {
$split = explode(":", $filename, 2);
if (count($split) > 1 && (stristr("|http|https|file|magnet|", "|".$split[0]."|") !== false)) {
$this->makeRequest("?action=add-url&s=".urlencode($filename), false);
- }
- elseif (file_exists($filename)) {
+ } elseif (file_exists($filename)) {
$json = $this->makeRequest("?action=add-file", true, array(CURLOPT_POSTFIELDS => array("torrent_file" => "@".realpath($filename))));
if (isset($json['error'])) {
- if ($estring !== false) $estring = $json['error'];
+ if ($estring !== false) {
+ $estring = $json['error'];
+ }
return false;
}
return true;
- }
- else {
- if ($estring !== false) $estring = "File doesn't exist!";
+ } else {
+ if ($estring !== false) {
+ $estring = "File doesn't exist!";
+ }
return false;
}
}
// force start the specified torrent hashes
- public function torrentForceStart($hash) {
+ public function torrentForceStart($hash)
+ {
$this->makeRequest("?action=forcestart".$this->paramImplode("&hash=", $hash), false);
}
// pause the specified torrent hashes
- public function torrentPause($hash) {
+ public function torrentPause($hash)
+ {
$this->makeRequest("?action=pause".$this->paramImplode("&hash=", $hash), false);
}
// recheck the specified torrent hashes
- public function torrentRecheck($hash) {
+ public function torrentRecheck($hash)
+ {
$this->makeRequest("?action=recheck".$this->paramImplode("&hash=", $hash), false);
}
// start the specified torrent hashes
- public function torrentStart($hash) {
+ public function torrentStart($hash)
+ {
$this->makeRequest("?action=start".$this->paramImplode("&hash=", $hash), false);
}
// stop the specified torrent hashes
- public function torrentStop($hash) {
+ public function torrentStop($hash)
+ {
$this->makeRequest("?action=stop".$this->paramImplode("&hash=", $hash), false);
}
// remove the specified torrent hashes (and data, if $data is set to true)
- public function torrentRemove($hash, $data = false) {
+ public function torrentRemove($hash, $data = false)
+ {
$this->makeRequest("?action=".($data ? "removedata" : "remove").$this->paramImplode("&hash=", $hash), false);
}
}
diff --git a/app/config/config.sample.php b/app/config/config.sample.php
index d7202c2..6b3b559 100644
--- a/app/config/config.sample.php
+++ b/app/config/config.sample.php
@@ -1,352 +1,352 @@
'IYUU',
- // 2.server酱 微信通知配置
- 'sc.ftqq.com' => '',
- // 3.发布员鉴权
- 'secret' => '',
- // 4.全局默认配置
+ // 1.爱语飞飞 微信通知配置
+ 'iyuu.cn' => 'IYUU',
+ // 2.server酱 微信通知配置
+ 'sc.ftqq.com' => '',
+ // 3.发布员鉴权
+ 'secret' => '',
+ // 4.全局默认配置
'default' => array(
- // 5.【必须配置】浏览器UA,打开http://demo.iyuu.cn 复制过来即可
- 'userAgent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
- // 6.【自动辅种必须配置】全局客户端设置(条目不够可以复制,用不到的请删除)
+ // 5.【必须配置】浏览器UA,打开http://demo.iyuu.cn 复制过来即可
+ 'userAgent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
+ // 6.【自动辅种必须配置】全局客户端设置(条目不够可以复制,用不到的请删除)
'clients' => array(
- // 全局客户端设置 开始
+ // 全局客户端设置 开始
array(
- 'type' => 'transmission', // 支持:transmission、qBittorrent
- 'host' => 'http://127.0.0.1:9091/transmission/rpc',
- 'username' => '',
- 'password' => '',
- //'move' =>array(
- // 'type' => 2, // 0保持不变,1减,2加, 3直接替换
- // 'path' =>array(
- // '/sda1' => '/volume1',
- // ),
- //),
- ),
- // (条目不够可以复制,用不到的请删除)
- array(
- 'type' => 'qBittorrent', // 支持:transmission、qBittorrent
- 'host' => 'http://www.baidu.com:8083',
- 'username' => '',
- 'password' => '',
- ),
- // 全局客户端设置 结束
- ),
- 'CONNECTTIMEOUT'=> 60,
+ 'type' => 'transmission', // 支持:transmission、qBittorrent
+ 'host' => 'http://127.0.0.1:9091/transmission/rpc',
+ 'username' => '',
+ 'password' => '',
+ //'move' =>array(
+ // 'type' => 2, // 0保持不变,1减,2加, 3直接替换
+ // 'path' =>array(
+ // '/sda1' => '/volume1',
+ // ),
+ //),
+ ),
+ // (条目不够可以复制,用不到的请删除)
+ array(
+ 'type' => 'qBittorrent', // 支持:transmission、qBittorrent
+ 'host' => 'http://www.baidu.com:8083',
+ 'username' => '',
+ 'password' => '',
+ ),
+ // 全局客户端设置 结束
+ ),
+ 'CONNECTTIMEOUT'=> 60,
'TIMEOUT' => 600,
- ),
- /**
- * 以下为各站点的独立配置(互不影响、互不冲突)
- * 自动辅种:需要配置各站的passkey(没有配置passkey的站点会自动跳过)
- */
+ ),
+ /**
+ * 以下为各站点的独立配置(互不影响、互不冲突)
+ * 自动辅种:需要配置各站的passkey(没有配置passkey的站点会自动跳过)
+ */
// m-team 序号:1
'm-team' => array(
- // 14.m-team的cookie 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => 'tp=',
- // 15.m-team的passkey 【必须配置】
- 'passkey' => '',
- // 种子Tracker的IP地址选择 可选:ipv4,ipv6
- 'ip_type' => 'ipv4',
+ // 14.m-team的cookie 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => 'tp=',
+ // 15.m-team的passkey 【必须配置】
+ 'passkey' => '',
+ // 种子Tracker的IP地址选择 可选:ipv4,ipv6
+ 'ip_type' => 'ipv4',
),
// keepfrds 序号:2
'keepfrds' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // ourbits 序号:3
- 'ourbits' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- 'id' => 0, // 用户ID
- 'is_vip' => 0, // 是否具有VIP或特殊权限?0 普通,1 VIP
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // ourbits 序号:3
+ 'ourbits' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ 'id' => 0, // 用户ID
+ 'is_vip' => 0, // 是否具有VIP或特殊权限?0 普通,1 VIP
),
// HDSky 序号:4
'hdsky' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // pter 序号:5
- 'pter' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // pter 序号:5
+ 'pter' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // tjupt 序号:6
- 'tjupt' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // tjupt 序号:6
+ 'tjupt' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // hdhome 序号:7
- 'hdhome' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // hdhome 序号:7
+ 'hdhome' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // btschool 序号:8
- 'btschool' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // btschool 序号:8
+ 'btschool' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // PTHome 序号:9
+ ),
+ // PTHome 序号:9
'pthome' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // hddolby 序号:10
- 'hddolby' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // hddolby 序号:10
+ 'hddolby' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // TorrentCCF 序号:11
+ // TorrentCCF 序号:11
'torrentccf' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // PTMSG 序号:12
+ // PTMSG 序号:12
'ptmsg' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // MoeCat 序号:13
+ // MoeCat 序号:13
'moecat' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- // 种子Tracker的IP地址选择 可选:ipv4,ipv6
- 'ip_type' => 'ipv4',
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ // 种子Tracker的IP地址选择 可选:ipv4,ipv6
+ 'ip_type' => 'ipv4',
),
// totheglory 序号:14
'ttg' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
),
- // nanyangpt 序号:15
+ // nanyangpt 序号:15
'nanyangpt' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // springsunday.net 序号:16
+ ),
+ // springsunday.net 序号:16
'ssd' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // yingk 序号:17
+ ),
+ // yingk 序号:17
'yingk' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // hdcity 序号:18
+ ),
+ // hdcity 序号:18
'hdcity' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置 cuhash
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置 cuhash
'passkey' => '',
- ),
- // 52pt.site 序号:19
+ ),
+ // 52pt.site 序号:19
'52pt' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // brobits.cc 序号:20
+ ),
+ // brobits.cc 序号:20
'brobits' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // www.beitai.pt 序号:21
+ ),
+ // www.beitai.pt 序号:21
'beitai' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // pt.eastgame.org 序号:22
+ ),
+ // pt.eastgame.org 序号:22
'eastgame' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // pt.soulvoice.club 序号:23
+ ),
+ // pt.soulvoice.club 序号:23
'soulvoice' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // chdbits 序号:24
+ ),
+ // chdbits 序号:24
'chdbits' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
'passkey' => '',
- ),
- // leaguehd 序号:25
+ ),
+ // leaguehd 序号:25
'leaguehd' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // ptsbao.club 序号:26
- 'ptsbao' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // hdchina 序号:27
- 'hdchina' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // hdarea 序号:28
- 'hdarea' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // hdtime 序号:29
- 'hdtime' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // 1ptba 序号:30
- '1ptba' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // hd4fans 序号:31
- 'hd4fans' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // hdbug 序号:32
- 'hdbug' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // opencd 序号:33
- 'opencd' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // hdstreet 序号:34
- 'hdstreet' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // joyhd 序号:35
- 'joyhd' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // dmhy 序号:36
- 'dmhy' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // upxin 序号:37
- 'upxin' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // oshen 序号:38
- 'oshen' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // discfan 序号:39
- 'discfan' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // hdzone 序号:40
- 'hdzone' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // cnscg 序号:41
- 'cnscg' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
- // nicept 序号:42
- 'nicept' => array(
- // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
- 'cookie' => '',
- // 如果需要自动辅种,必须配置
- 'passkey' => '',
- ),
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // ptsbao.club 序号:26
+ 'ptsbao' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // hdchina 序号:27
+ 'hdchina' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // hdarea 序号:28
+ 'hdarea' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // hdtime 序号:29
+ 'hdtime' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // 1ptba 序号:30
+ '1ptba' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // hd4fans 序号:31
+ 'hd4fans' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // hdbug 序号:32
+ 'hdbug' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // opencd 序号:33
+ 'opencd' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // hdstreet 序号:34
+ 'hdstreet' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // joyhd 序号:35
+ 'joyhd' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // dmhy 序号:36
+ 'dmhy' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // upxin 序号:37
+ 'upxin' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // oshen 序号:38
+ 'oshen' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // discfan 序号:39
+ 'discfan' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // hdzone 序号:40
+ 'hdzone' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // cnscg 序号:41
+ 'cnscg' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
+ // nicept 序号:42
+ 'nicept' => array(
+ // 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
+ 'cookie' => '',
+ // 如果需要自动辅种,必须配置
+ 'passkey' => '',
+ ),
- // 配置文件结束
-);
\ No newline at end of file
+ // 配置文件结束
+);