mirror of
https://gitee.com/ledc/IYUUAutoReseed
synced 2025-06-12 11:48:57 +00:00
IYUU自动辅种工具初始化版本
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/app/api
|
||||
/app/torrent
|
||||
/app/config/config.php
|
58
LICENSE
Normal file
58
LICENSE
Normal file
@ -0,0 +1,58 @@
|
||||
木兰宽松许可证, 第1版
|
||||
2019年8月 http://license.coscl.org.cn/MulanPSL
|
||||
|
||||
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第1版(“本许可证”)的如下条款的约束:
|
||||
|
||||
0. 定义
|
||||
|
||||
“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
|
||||
|
||||
“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
|
||||
|
||||
“法人实体”是指提交贡献的机构及其“关联实体”。
|
||||
|
||||
“关联实体”是指,对“本许可证”下的一方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
|
||||
|
||||
“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
|
||||
|
||||
1. 授予版权许可
|
||||
|
||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
|
||||
|
||||
2. 授予专利许可
|
||||
|
||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括仅因您或他人修改“贡献”或其他结合而将必然会侵犯到的专利权利要求。如您或您的“关联实体”直接或间接地(包括通过代理、专利被许可人或受让人),就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
|
||||
|
||||
3. 无商标许可
|
||||
|
||||
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
|
||||
|
||||
4. 分发限制
|
||||
|
||||
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
|
||||
|
||||
5. 免责声明与责任限制
|
||||
|
||||
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
|
||||
|
||||
条款结束
|
||||
|
||||
如何将木兰宽松许可证,第1版,应用到您的软件
|
||||
|
||||
如果您希望将木兰宽松许可证,第1版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
|
||||
|
||||
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
|
||||
|
||||
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
|
||||
|
||||
3, 请将如下声明文本放入每个源文件的头部注释中。
|
||||
|
||||
Copyright (c) [2019] [name of copyright holder]
|
||||
[Software Name] is licensed under the Mulan PSL v1.
|
||||
You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||
You may obtain a copy of Mulan PSL v1 at:
|
||||
http://license.coscl.org.cn/MulanPSL
|
||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||
PURPOSE.
|
||||
See the Mulan PSL v1 for more details.
|
92
Readme.txt
Normal file
92
Readme.txt
Normal file
@ -0,0 +1,92 @@
|
||||
【特别提示】php命令与脚本路径之间是有个空格,请注意!请注意!请注意!
|
||||
点击链接加入群聊【IYUU自动辅种交流】:https://jq.qq.com/?_wv=1027&k=5JOfOlM
|
||||
|
||||
【重要说明:实际路径,以你实际的为准,切勿生搬硬套!】
|
||||
自动辅种脚本命令:
|
||||
php /volume1/ssd/phpspider/iyuu.cn.php
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
添加免费种 PHP命令:
|
||||
php /volume1/ssd/phpspider/app/beitai.php
|
||||
php /volume1/ssd/phpspider/app/brobits.php
|
||||
php /volume1/ssd/phpspider/app/btschool.php
|
||||
php /volume1/ssd/phpspider/app/chdbits.php
|
||||
php /volume1/ssd/phpspider/app/eastgame.php
|
||||
php /volume1/ssd/phpspider/app/hd4fans.php
|
||||
php /volume1/ssd/phpspider/app/hdarea.php
|
||||
php /volume1/ssd/phpspider/app/hdbug.php
|
||||
php /volume1/ssd/phpspider/app/hddolby.php
|
||||
php /volume1/ssd/phpspider/app/hdhome.php
|
||||
php /volume1/ssd/phpspider/app/hdsky.php
|
||||
php /volume1/ssd/phpspider/app/hdtime.php
|
||||
php /volume1/ssd/phpspider/app/keepfrds.php
|
||||
php /volume1/ssd/phpspider/app/leaguehd.php
|
||||
php /volume1/ssd/phpspider/app/moecat.php
|
||||
php /volume1/ssd/phpspider/app/m-team.php
|
||||
php /volume1/ssd/phpspider/app/nanyangpt.php
|
||||
php /volume1/ssd/phpspider/app/opencd.php
|
||||
php /volume1/ssd/phpspider/app/ourbits.php
|
||||
php /volume1/ssd/phpspider/app/ptba.php
|
||||
php /volume1/ssd/phpspider/app/pterclub.php
|
||||
php /volume1/ssd/phpspider/app/pthome.php
|
||||
php /volume1/ssd/phpspider/app/ptmsg.php
|
||||
php /volume1/ssd/phpspider/app/ptsbao.php
|
||||
php /volume1/ssd/phpspider/app/site52pt.php
|
||||
php /volume1/ssd/phpspider/app/soulvoice.php
|
||||
php /volume1/ssd/phpspider/app/ssd.php
|
||||
php /volume1/ssd/phpspider/app/tjupt.php
|
||||
php /volume1/ssd/phpspider/app/torrentccf.php
|
||||
php /volume1/ssd/phpspider/app/totheglory.php
|
||||
php /volume1/ssd/phpspider/app/yingk.php
|
||||
|
||||
|
||||
【重要说明:实际路径,以你实际的为准,切勿生搬硬套!】
|
||||
|
||||
|
||||
【功能】
|
||||
1.群晖、威联通不装软件,添加免费种子到transmission、qBittorrent,支持微信通知、邮件通知,支持自定义目录、支持下载服务器集群。
|
||||
2.自动化辅种,支持客户端transmission、qBittorrent,辅种目录自动识别。
|
||||
因为我的站点不多【有邀请码的,也请各位踊跃发来】
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
2019年12月21日
|
||||
新增兽站、opencd、hdbug;
|
||||
自动辅种33个站:学校、杜比、家园、天空、朋友、馒头、萌猫、我堡、猫站、铂金家、烧包、北洋、TCCF、南洋、TTG、映客、城市、52pt、brobits、备胎、SSD、CHD、ptmsg、leaguehd、聆音、瓷器、hdarea、eastgame、1ptba、hdtime、hd4fans、opencd、hdbug。
|
||||
|
||||
---------------------------------------------
|
||||
2019年12月20日
|
||||
新增1ptba、hdtime
|
||||
|
||||
---------------------------------------------
|
||||
2019年12月17日
|
||||
新增站点瓷器;
|
||||
|
||||
---------------------------------------------
|
||||
2019年12月16日15:27:00
|
||||
新增leaguehd、聆音;
|
||||
|
||||
---------------------------------------------
|
||||
2019年12月15日
|
||||
1.自动辅种20个站;
|
||||
2.支持qBittorrent做种转transmission
|
||||
3.新增qBittorrent自动辅种时的状态过滤,只辅种已完成的种子
|
||||
|
||||
---------------------------------------------
|
||||
2019年12月12日
|
||||
目前支持17个站点的自动辅种;
|
||||
目前支持18个站点下载免费种;
|
||||
|
||||
---------------------------------------------
|
||||
2019年12月10日
|
||||
自动辅种工具完成!
|
||||
|
||||
---------------------------------------------
|
||||
2019年11月19日
|
||||
我堡、天空 完美适配,支持大小、做种数、下载数筛选。
|
||||
=============================================================
|
||||
技术讨论及后续更新,请加入QQ群!
|
||||
群名称:IYUU自动辅种交流
|
||||
QQ群号:859882209
|
||||
=============================================================
|
141
app/Class/Bencode.php
Normal file
141
app/Class/Bencode.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Rhilip
|
||||
* Date: 2019/4/21
|
||||
* Time: 21:12
|
||||
*/
|
||||
class Bencode
|
||||
{
|
||||
/**
|
||||
* Decodes a BEncoded string to the following values:
|
||||
* - Dictionary (starts with d, ends with e)
|
||||
* - List (starts with l, ends with e
|
||||
* - Integer (starts with i, ends with e
|
||||
* - String (starts with number denoting number of characters followed by : and then the string)
|
||||
*
|
||||
* @see https://wiki.theory.org/index.php/BitTorrentSpecification
|
||||
*
|
||||
* @param string $data
|
||||
* @param int $pos
|
||||
* @return mixed
|
||||
*/
|
||||
public static function decode($data, &$pos = 0)
|
||||
{
|
||||
$start_decode = ($pos === 0);
|
||||
if ($data[$pos] === 'd') {
|
||||
$pos++;
|
||||
$return = [];
|
||||
while ($data[$pos] !== 'e') {
|
||||
$key = self::decode($data, $pos);
|
||||
$value = self::decode($data, $pos);
|
||||
if ($key === null || $value === null) {
|
||||
break;
|
||||
}
|
||||
if (!is_string($key)) {
|
||||
throw new RuntimeException('Invalid key type, must be string: ' . gettype($key));
|
||||
}
|
||||
$return[$key] = $value;
|
||||
}
|
||||
ksort($return);
|
||||
$pos++;
|
||||
} elseif ($data[$pos] === 'l') {
|
||||
$pos++;
|
||||
$return = [];
|
||||
while ($data[$pos] !== 'e') {
|
||||
$value = self::decode($data, $pos);
|
||||
$return[] = $value;
|
||||
}
|
||||
$pos++;
|
||||
} elseif ($data[$pos] === 'i') {
|
||||
$pos++;
|
||||
$digits = strpos($data, 'e', $pos) - $pos;
|
||||
$return = substr($data, $pos, $digits);
|
||||
if ($return === '-0') {
|
||||
throw new RuntimeException('Cannot have integer value -0');
|
||||
}
|
||||
$multiplier = 1;
|
||||
if ($return[0] === '-') {
|
||||
$multiplier = -1;
|
||||
$return = substr($return, 1);
|
||||
}
|
||||
if (!ctype_digit($return)) {
|
||||
throw new RuntimeException('Cannot have non-digit values in integer number: ' . $return);
|
||||
}
|
||||
$return = $multiplier * ((int)$return);
|
||||
$pos += $digits + 1;
|
||||
} else {
|
||||
$digits = strpos($data, ':', $pos) - $pos;
|
||||
$len = (int)substr($data, $pos, $digits);
|
||||
$pos += ($digits + 1);
|
||||
$return = substr($data, $pos, $len);
|
||||
$pos += $len;
|
||||
}
|
||||
if ($start_decode) {
|
||||
if ($pos !== strlen($data)) {
|
||||
throw new RuntimeException('Could not fully decode bencode string');
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
$return = '';
|
||||
$check = -1;
|
||||
$list = true;
|
||||
foreach ($data as $key => $value) {
|
||||
if ($key !== ++$check) {
|
||||
$list = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($list) {
|
||||
$return .= 'l';
|
||||
foreach ($data as $value) {
|
||||
$return .= self::encode($value);
|
||||
}
|
||||
} else {
|
||||
$return .= 'd';
|
||||
foreach ($data as $key => $value) {
|
||||
$return .= self::encode(strval($key));
|
||||
$return .= self::encode($value);
|
||||
}
|
||||
}
|
||||
$return .= 'e';
|
||||
} elseif (is_integer($data)) {
|
||||
$return = 'i' . $data . 'e';
|
||||
} else {
|
||||
$return = strlen($data) . ':' . $data;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
/**
|
||||
* Given a path to a file, decode the contents of it
|
||||
*
|
||||
* @param string $path
|
||||
* @return mixed
|
||||
*/
|
||||
public static function load($path)
|
||||
{
|
||||
if (is_file($path)) {
|
||||
return self::decode(file_get_contents($path));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Given a path for a file, encode the contents of it
|
||||
*
|
||||
* @param string $path
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function dump($path, $data)
|
||||
{
|
||||
return file_put_contents($path, self::encode($data));
|
||||
}
|
||||
}
|
332
app/Class/File.php
Normal file
332
app/Class/File.php
Normal file
@ -0,0 +1,332 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 文件处理
|
||||
* @version 0.6
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class IFile
|
||||
* @brief IFile 文件处理类
|
||||
*/
|
||||
class IFile
|
||||
{
|
||||
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);
|
||||
|
||||
$this->resource = fopen($fileName,$mode.'b');
|
||||
if($this->resource)
|
||||
{
|
||||
flock($this->resource,LOCK_EX);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取文件内容
|
||||
* @return String 文件内容
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
$content = null;
|
||||
while(!feof($this->resource))
|
||||
{
|
||||
$content.= fread($this->resource,1024);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 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 $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 $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);
|
||||
|
||||
copy($from,$to);
|
||||
|
||||
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 删除$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
$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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $filetype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 释放文件锁定
|
||||
*/
|
||||
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 析构函数,释放文件连接句柄
|
||||
*/
|
||||
function __destruct()
|
||||
{
|
||||
if(is_resource($this->resource))
|
||||
{
|
||||
fclose($this->resource);
|
||||
}
|
||||
}
|
||||
}
|
294
app/Class/Function.php
Normal file
294
app/Class/Function.php
Normal file
@ -0,0 +1,294 @@
|
||||
<?php
|
||||
/**
|
||||
* 调试函数
|
||||
*/
|
||||
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;
|
||||
}
|
||||
/**
|
||||
* 微信推送Server酱
|
||||
*/
|
||||
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;
|
||||
}
|
||||
/**
|
||||
* 微信推送 爱语飞飞
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信推送 爱语飞飞
|
||||
* @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://hdsky.me/details.php?id=118632
|
||||
[download] => https://hdsky.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时<br />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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 下载种子
|
||||
* @param string $url 种子URL
|
||||
* @param string $cookies 模拟登陆的cookie
|
||||
* @return mixed 返回的数据
|
||||
*/
|
||||
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);
|
||||
curl_close($ch);
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* @brief 文件大小格式化为MB
|
||||
* @param string $from 文件大小
|
||||
* @return int 单位MB
|
||||
*/
|
||||
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);
|
||||
case "TB":
|
||||
return $number*pow(1024,2);
|
||||
case "PB":
|
||||
return $number*pow(1024,3);
|
||||
default:
|
||||
return $from;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 种子过滤器
|
||||
* @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://hdsky.me/details.php?id=118632
|
||||
[download] => https://hdsky.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时<br />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'];
|
||||
|
||||
// 兼容性
|
||||
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['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. '人,被过滤';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function oddFilter($var)
|
||||
{
|
||||
// 返回$var最后一个二进制位,
|
||||
// 为1则保留(奇数的二进制的最后一位肯定是1)
|
||||
return($var & 1);
|
||||
}
|
||||
|
||||
function evenFilter($var)
|
||||
{
|
||||
// 返回$var最后一个二进制位,
|
||||
// 为0则保留(偶数的二进制的最后一位肯定是0)
|
||||
return(!($var & 1));
|
||||
}
|
||||
|
||||
// 签名函数
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 分离token中的用户uid
|
||||
* 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;
|
||||
}
|
340
app/Class/Rpc.php
Normal file
340
app/Class/Rpc.php
Normal file
@ -0,0 +1,340 @@
|
||||
<?php
|
||||
/**
|
||||
* Rpc操作类
|
||||
*/
|
||||
class Rpc
|
||||
{
|
||||
/**
|
||||
* 版本号
|
||||
* @var string
|
||||
*/
|
||||
const VER = '0.0.1';
|
||||
|
||||
// 下载种子的请求类型 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 $RPC_Key = 0;
|
||||
/**
|
||||
* 退出状态码
|
||||
*/
|
||||
public static $ExitCode = 0;
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
public static function init($site = '', $method = 'GET'){
|
||||
global $configALL;
|
||||
|
||||
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::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
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
|
||||
* @return array
|
||||
*/
|
||||
public static function links()
|
||||
{
|
||||
if(self::$workingMode === 1 && empty(self::$links)){
|
||||
foreach ( self::$clients as $k => $v ){
|
||||
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
|
||||
*/
|
||||
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
|
||||
{
|
||||
$rpcKey = self::$RPC_Key;
|
||||
$type = self::$links[$rpcKey]['type'];
|
||||
echo '选中:负载均衡'.$rpcKey."\n";
|
||||
if( (strpos($torrent,'http://')===0) || (strpos($torrent,'https://')===0) ){
|
||||
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 ); // 种子文件添加下载任务
|
||||
}
|
||||
// 负载均衡
|
||||
self::rpcSelect();
|
||||
// 调试
|
||||
#p($result);
|
||||
// 下载服务器类型 判断
|
||||
switch($type){
|
||||
case 'transmission':
|
||||
$id = $result->arguments->torrent_added->id;
|
||||
if(!$id){
|
||||
print "-----RPC添加种子任务,失败 [{$result->result}] \n\n";
|
||||
}else{
|
||||
print "********RPC添加下载任务成功 [{$result->result}] (id=$id) \n\n";
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 'qBittorrent':
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 负载均衡 选择算法
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
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-HDSTV
|
||||
[title] => 央视体育赛事频道 2019年ATP男子网球年终总决赛 单打小组赛 纳达尔VS西西帕斯 20191115[优惠剩余时间:4时13分]
|
||||
[details] => https://hdsky.me/details.php?id=118632
|
||||
[download] => https://hdsky.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时<br />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);
|
||||
// 文件句柄
|
||||
$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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
707
app/Class/TransmissionRPC.class.php
Normal file
707
app/Class/TransmissionRPC.class.php
Normal file
@ -0,0 +1,707 @@
|
||||
<?php
|
||||
/**
|
||||
* Transmission bittorrent client/daemon RPC communication class
|
||||
* Copyright (C) 2010 Johan Adriaans <johan.adriaans@gmail.com>,
|
||||
* Bryce Chidester <bryce@cobryce.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHP version specific information
|
||||
* version_compare() (PHP 4 >= 4.1.0, PHP 5)
|
||||
* ctype_digit() (PHP 4 >= 4.0.4, PHP 5)
|
||||
* stream_context_create (PHP 4 >= 4.3.0, PHP 5)
|
||||
* PHP Class support (PHP 5) (PHP 4 might work, untested)
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
|
||||
/**
|
||||
* Transmission bittorrent client/daemon RPC communication class
|
||||
*
|
||||
* Usage example:
|
||||
* <code>
|
||||
* $rpc = new TransmissionRPC($rpc_url);
|
||||
* $result = $rpc->add_file( $url_or_path_to_torrent, $target_folder );
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
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' => 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
|
||||
}
|
||||
|
||||
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-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(
|
||||
"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(
|
||||
"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 );
|
||||
}
|
||||
|
||||
$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 "Unknown";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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_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
|
||||
}
|
||||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
if( is_array( $array[$index] ) || is_object( $array[$index] ) )
|
||||
{
|
||||
$array[$index] = $this->cleanResultObject( $array[$index] ); // Recursion
|
||||
}
|
||||
if ( strstr( $index, '-' ) )
|
||||
{
|
||||
$valid_index = str_replace( '-', '_', $index );
|
||||
$array[$valid_index] = $array[$index];
|
||||
unset( $array[$index] );
|
||||
$index = $valid_index;
|
||||
}
|
||||
// Might be an array, check index for digits, if so, an array should be returned
|
||||
if ( ctype_digit( (string) $index ) ) { $return_as_array = true; }
|
||||
if ( empty( $value ) ) unset( $array[$index] );
|
||||
}
|
||||
// Return array cast to object
|
||||
return $return_as_array ? $array : (object) $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行 rpc 请求
|
||||
*
|
||||
* @param $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
|
||||
|
||||
// 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(
|
||||
'method' => $method,
|
||||
'arguments' => $arguments
|
||||
);
|
||||
|
||||
$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_TIMEOUT, 10);
|
||||
$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
|
||||
$contextopts = $this->default_context_opts; // Start with the defaults
|
||||
|
||||
// Make sure it's blank/empty (reset)
|
||||
$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 ) );
|
||||
|
||||
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 );
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
// Get the Transmission RPC_version
|
||||
$this->rpc_version = self::sget()->arguments->rpc_version;
|
||||
|
||||
// Return As Array
|
||||
$this->return_as_array = $return_as_array;
|
||||
|
||||
// Reset X-Transmission-Session-Id so we (re)fetch one
|
||||
$this->session_id = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the type of exception the TransmissionRPC class will throw
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
285
app/Class/qBittorrent.php
Normal file
285
app/Class/qBittorrent.php
Normal file
@ -0,0 +1,285 @@
|
||||
<?php
|
||||
use Curl\Curl;
|
||||
/**
|
||||
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation
|
||||
*/
|
||||
class qBittorrent
|
||||
{
|
||||
private $debug;
|
||||
private $url;
|
||||
private $api_version;
|
||||
private $curl;
|
||||
protected $delimiter;
|
||||
private $endpoints = [
|
||||
'login' => [
|
||||
'1' => '/login',
|
||||
'2' => '/api/v2/auth/login'
|
||||
],
|
||||
'app_version' => [
|
||||
'1' => '/version/qbittorrent',
|
||||
'2' => '/api/v2/app/version'
|
||||
],
|
||||
'api_version' => [
|
||||
'1' => '/version/api',
|
||||
'2' => '/api/v2/app/webapiVersion'
|
||||
],
|
||||
'build_info' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/app/buildInfo'
|
||||
],
|
||||
'preferences' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/app/preferences'
|
||||
],
|
||||
'setPreferences' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/app/setPreferences'
|
||||
],
|
||||
'defaultSavePath' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/app/defaultSavePath'
|
||||
],
|
||||
'torrent_list' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/torrents/info'
|
||||
],
|
||||
'torrent_add' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/torrents/add'
|
||||
],
|
||||
'torrent_delete' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/torrents/delete'
|
||||
],
|
||||
'torrent_pause' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/torrents/pause'
|
||||
],
|
||||
'torrent_resume' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/torrents/resume'
|
||||
],
|
||||
'set_torrent_location' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/torrents/setLocation'
|
||||
],
|
||||
'maindata' => [
|
||||
'1' => null,
|
||||
'2' => '/api/v2/sync/maindata'
|
||||
]
|
||||
];
|
||||
|
||||
public function __construct($url='', $username='', $password='', $api_version = 2, $debug = false)
|
||||
{
|
||||
$this->debug = $debug;
|
||||
$this->url = rtrim($url,'/');
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->api_version = $api_version;
|
||||
$this->curl = new Curl();
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false); // 禁止验证证书
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYHOST, false); // 不检查证书
|
||||
// Authenticate and get cookie, else throw exception
|
||||
if (!$this->authenticate()) {
|
||||
throw new \Exception("Unable to authenticate with Web Api.");
|
||||
}
|
||||
}
|
||||
|
||||
public function appVersion()
|
||||
{
|
||||
return $this->getData('app_version');
|
||||
}
|
||||
|
||||
public function apiVersion()
|
||||
{
|
||||
return $this->getData('api_version');
|
||||
}
|
||||
|
||||
public function buildInfo()
|
||||
{
|
||||
return $this->getData('build_info');
|
||||
}
|
||||
|
||||
public function preferences($data = null)
|
||||
{
|
||||
if (!empty($data)) {
|
||||
return $this->postData('setPreferences', ['json' => json_encode($data)]);
|
||||
}
|
||||
|
||||
return $this->getData('preferences');
|
||||
}
|
||||
|
||||
public function torrentList()
|
||||
{
|
||||
return $this->getData('torrent_list');
|
||||
}
|
||||
/**
|
||||
* @param array $extra_options
|
||||
array(
|
||||
'urls' => '',
|
||||
'savepath' => '',
|
||||
'cookie' => '',
|
||||
'category' => '',
|
||||
'skip_checking' => true,
|
||||
'paused' => true,
|
||||
'root_folder' => true,
|
||||
)
|
||||
* @return array
|
||||
*/
|
||||
public function add($torrent_url, $save_path = '', $extra_options = array())
|
||||
{
|
||||
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));
|
||||
return $this->postData('torrent_add', $post_data);
|
||||
}
|
||||
|
||||
public function add_metainfo($torrent_metainfo, $save_path = '', $extra_options = array())
|
||||
{
|
||||
if(!empty($save_path)) $extra_options['savepath'] = $save_path;
|
||||
$extra_options['torrents'] = $torrent_metainfo;
|
||||
// 关键 上传文件流 multipart/form-data【严格按照api文档编写】
|
||||
$post_data = $this->buildData($extra_options);
|
||||
#p($post_data);
|
||||
// 设置请求头
|
||||
$this->curl->setHeader('Content-Type','multipart/form-data; boundary='.$this->delimiter);
|
||||
$this->curl->setHeader('Content-Length',strlen($post_data));
|
||||
return $this->postData('torrent_add', $post_data);
|
||||
}
|
||||
|
||||
public function torrentDelete($hash='', $deleteFiles = false)
|
||||
{
|
||||
return $this->postData('torrent_delete', ['hashes' => $hash, 'deleteFiles' => $deleteFiles ? 'true':'false']);
|
||||
}
|
||||
|
||||
public function torrentDeleteAll($deleteFiles = false)
|
||||
{
|
||||
$torrents = json_decode($this->torrentList());
|
||||
$response = '';
|
||||
foreach ($torrents as $torrent) {
|
||||
$response .= $this->torrentDelete($torrent->hash, $deleteFiles);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function torrentPause($hash)
|
||||
{
|
||||
return $this->postData('torrent_pause', ['hashes' => $hash]);
|
||||
}
|
||||
|
||||
public function torrentResume($hash)
|
||||
{
|
||||
return $this->postData('torrent_resume', ['hashes' => $hash]);
|
||||
}
|
||||
|
||||
public function setTorrentLocation($hash, $location)
|
||||
{
|
||||
return $this->postData('set_torrent_location', ['hashes' => $hash, 'location' => $location]);
|
||||
}
|
||||
|
||||
private function getData($endpoint)
|
||||
{
|
||||
$this->curl->get($this->url . $this->endpoints[$endpoint][$this->api_version]);
|
||||
|
||||
if ($this->debug) {
|
||||
var_dump($this->curl->request_headers);
|
||||
var_dump($this->curl->response_headers);
|
||||
}
|
||||
|
||||
if ($this->curl->error) {
|
||||
return $this->errorMessage();
|
||||
}
|
||||
|
||||
return $this->curl->response;
|
||||
}
|
||||
|
||||
private function postData($endpoint, $data)
|
||||
{
|
||||
$this->curl->post($this->url . $this->endpoints[$endpoint][$this->api_version], $data);
|
||||
|
||||
if ($this->debug) {
|
||||
var_dump($this->curl->request_headers);
|
||||
var_dump($this->curl->response_headers);
|
||||
}
|
||||
|
||||
if ($this->curl->error) {
|
||||
return $this->errorMessage();
|
||||
}
|
||||
|
||||
return $this->curl->response;
|
||||
}
|
||||
|
||||
private function authenticate()
|
||||
{
|
||||
$this->curl->post($this->url . $this->endpoints['login'][$this->api_version], [
|
||||
'username' => $this->username,
|
||||
'password' => $this->password
|
||||
]);
|
||||
|
||||
if ($this->debug) {
|
||||
var_dump($this->curl->request_headers);
|
||||
var_dump($this->curl->response_headers);
|
||||
}
|
||||
|
||||
// Find authentication cookie and set in curl connection
|
||||
foreach ($this->curl->response_headers as $header) {
|
||||
if (preg_match('/SID=(\S[^;]+)/', $header, $matches)) {
|
||||
$this->curl->setHeader('Cookie', $matches[0]);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function errorMessage()
|
||||
{
|
||||
return 'Curl Error Code: ' . $this->curl->error_code . ' (' . $this->curl->response . ')';
|
||||
}
|
||||
/**
|
||||
* 拼接种子urls multipart/form-data
|
||||
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation#add-new-torrent
|
||||
*/
|
||||
private function buildUrls($param){
|
||||
$this->delimiter = uniqid();
|
||||
$eol = "\r\n";
|
||||
$data = '';
|
||||
// 拼接文件流
|
||||
foreach ($param as $name => $content) {
|
||||
$data .= "--" . $this->delimiter . $eol;
|
||||
$data .= 'Content-Disposition: form-data; name' . '="' .$name. '"' . "\r\n\r\n";
|
||||
$data .= $content . $eol;
|
||||
}
|
||||
$data .= "--" . $this->delimiter . "--" . $eol;
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* 拼接种子上传文件流 multipart/form-data
|
||||
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation#add-new-torrent
|
||||
*/
|
||||
private function buildData($param){
|
||||
$this->delimiter = uniqid();
|
||||
$eol = "\r\n";
|
||||
$data = '';
|
||||
$torrents = $param['torrents'];
|
||||
unset($param['torrents']);
|
||||
// 拼接文件流
|
||||
$data .= "--" . $this->delimiter . $eol
|
||||
. 'Content-Disposition: form-data; ';
|
||||
foreach ($param as $name => $content) {
|
||||
$data.= $name . '="' . $content.'"; ';
|
||||
}
|
||||
$data .= $eol;
|
||||
$data .= 'Content-Type: application/x-bittorrent'."\r\n\r\n";
|
||||
$data .= $torrents . $eol;
|
||||
$data .= "--" . $this->delimiter . "--" . $eol;
|
||||
return $data;
|
||||
}
|
||||
}
|
255
app/Class/uTorrent.php
Normal file
255
app/Class/uTorrent.php
Normal file
@ -0,0 +1,255 @@
|
||||
<?php
|
||||
define("UTORRENT_TORRENT_HASH", 0);
|
||||
define("UTORRENT_TORRENT_STATUS", 1);
|
||||
define("UTORRENT_TORRENT_NAME", 2);
|
||||
define("UTORRENT_TORRENT_SIZE", 3);
|
||||
define("UTORRENT_TORRENT_PROGRESS", 4);
|
||||
define("UTORRENT_TORRENT_DOWNLOADED", 5);
|
||||
define("UTORRENT_TORRENT_UPLOADED", 6);
|
||||
define("UTORRENT_TORRENT_RATIO", 7);
|
||||
define("UTORRENT_TORRENT_UPSPEED", 8);
|
||||
define("UTORRENT_TORRENT_DOWNSPEED", 9);
|
||||
define("UTORRENT_TORRENT_ETA", 10);
|
||||
define("UTORRENT_TORRENT_LABEL", 11);
|
||||
define("UTORRENT_TORRENT_PEERS_CONNECTED", 12);
|
||||
define("UTORRENT_TORRENT_PEERS_SWARM", 13);
|
||||
define("UTORRENT_TORRENT_SEEDS_CONNECTED", 14);
|
||||
define("UTORRENT_TORRENT_SEEDS_SWARM", 15);
|
||||
define("UTORRENT_TORRENT_AVAILABILITY", 16);
|
||||
define("UTORRENT_TORRENT_QUEUE_POSITION", 17);
|
||||
define("UTORRENT_TORRENT_REMAINING", 18);
|
||||
define("UTORRENT_FILEPRIORITY_HIGH", 3);
|
||||
define("UTORRENT_FILEPRIORITY_NORMAL", 2);
|
||||
define("UTORRENT_FILEPRIORITY_LOW", 1);
|
||||
define("UTORRENT_FILEPRIORITY_SKIP", 0);
|
||||
define("UTORRENT_TYPE_INTEGER", 0);
|
||||
define("UTORRENT_TYPE_BOOLEAN", 1);
|
||||
define("UTORRENT_TYPE_STRING", 2);
|
||||
define("UTORRENT_STATUS_STARTED", 1);
|
||||
define("UTORRENT_STATUS_CHECKED", 2);
|
||||
define("UTORRENT_STATUS_START_AFTER_CHECK", 4);
|
||||
|
||||
class uTorrent {
|
||||
// class static variables
|
||||
private static $base = "%s/gui/%s";
|
||||
|
||||
// member variables
|
||||
public $host;
|
||||
public $user;
|
||||
public $pass;
|
||||
|
||||
protected $token;
|
||||
protected $guid;
|
||||
|
||||
// constructor
|
||||
function __construct($host = "", $user = "", $pass = "") {
|
||||
$this->host = rtrim($host,'/');
|
||||
$this->user = $user;
|
||||
$this->pass = $pass;
|
||||
|
||||
if (!$this->getToken()) {
|
||||
//handle error here, don't know how to best do this yet
|
||||
die('could not get token');
|
||||
}
|
||||
}
|
||||
|
||||
// performs request
|
||||
private function makeRequest($request, $decode = true, $options = array()) {
|
||||
$request = preg_replace('/^\?/', '?token='.$this->token . '&', $request);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, $options);
|
||||
curl_setopt($ch, CURLOPT_URL, sprintf(self::$base, $this->host, $request));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $this->user.":".$this->pass);
|
||||
curl_setopt($ch, CURLOPT_COOKIE, "GUID=".$this->guid);
|
||||
|
||||
$req = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return ($decode ? json_decode($req, true) : $req);
|
||||
}
|
||||
|
||||
// implodes given parameter with glue, whether it is an array or not
|
||||
private function paramImplode($glue, $param) {
|
||||
return $glue.implode($glue, is_array($param) ? $param : array($param));
|
||||
}
|
||||
|
||||
// gets token, returns true on success
|
||||
private function getToken() {
|
||||
$url = sprintf(self::$base, $this->host, 'token.html');
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $this->user.":".$this->pass);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
$output = curl_exec($ch);
|
||||
$info = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$headers = substr($output, 0, $info['header_size']);
|
||||
|
||||
if (preg_match("@Set-Cookie: GUID=([^;]+);@i", $headers, $matches)) {
|
||||
$this->guid = $matches[1];
|
||||
}
|
||||
|
||||
if (preg_match('/<div id=\'token\'.+>(.*)<\/div>/', $output, $m)) {
|
||||
$this->token = $m[1];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns the uTorrent build number
|
||||
public function getBuild(){
|
||||
$json = $this->makeRequest("?");
|
||||
return $json['build'];
|
||||
}
|
||||
|
||||
// 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) {
|
||||
$json = $this->makeRequest("?action=getfiles&hash=".$hash);
|
||||
return $json['files'];
|
||||
}
|
||||
|
||||
// returns an array of all labels
|
||||
public function getLabels(){
|
||||
$json = $this->makeRequest("?list=1");
|
||||
return $json['label'];
|
||||
}
|
||||
|
||||
// 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) {
|
||||
$json = $this->makeRequest("?action=getprops&hash=".$hash);
|
||||
return $json['props'];
|
||||
}
|
||||
|
||||
// returns an array of all settings
|
||||
public function getSettings() {
|
||||
$json = $this->makeRequest("?action=getsettings");
|
||||
return $json['settings'];
|
||||
}
|
||||
|
||||
// returns an array of all torrent jobs and related information
|
||||
public function getTorrents() {
|
||||
$json = $this->makeRequest("?list=1");
|
||||
return $json['torrents'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the RSS favourites/filters
|
||||
* @return model\Filter[]
|
||||
*/
|
||||
public function getRSSFilters() {
|
||||
$json = $this->makeRequest("?list=1");
|
||||
$filters = array();
|
||||
foreach ($json['rssfilters'] as $filter) {
|
||||
$filters[] = model\Filter::fromData($filter);
|
||||
}
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an RSS filter as retrieved from getRSSFilters
|
||||
* @param \uTorrent\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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new RSS filter
|
||||
* Requires a utorrent > 2.2.1 (not sure which version exactly)
|
||||
* @param \uTorrent\model\Filter $filter
|
||||
* @return int ID of the new filter
|
||||
*/
|
||||
public function addRSSFilter(model\Filter $filter) {
|
||||
$filter->filterId = -1;
|
||||
$resp = $this->setRSSFilter($filter);
|
||||
if (!empty($resp['filter_ident'])) {
|
||||
return $resp['filter_ident'];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if WebUI server is online and enabled, false otherwise
|
||||
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) {
|
||||
$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) {
|
||||
$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) {
|
||||
$this->makeRequest("?action=setsetting&s=".$setting."&v=".$value, false);
|
||||
}
|
||||
|
||||
// add a file to the list
|
||||
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)) {
|
||||
$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'];
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if ($estring !== false) $estring = "File doesn't exist!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// force start the specified torrent hashes
|
||||
public function torrentForceStart($hash) {
|
||||
$this->makeRequest("?action=forcestart".$this->paramImplode("&hash=", $hash), false);
|
||||
}
|
||||
|
||||
// pause the specified torrent hashes
|
||||
public function torrentPause($hash) {
|
||||
$this->makeRequest("?action=pause".$this->paramImplode("&hash=", $hash), false);
|
||||
}
|
||||
|
||||
// recheck the specified torrent hashes
|
||||
public function torrentRecheck($hash) {
|
||||
$this->makeRequest("?action=recheck".$this->paramImplode("&hash=", $hash), false);
|
||||
}
|
||||
|
||||
// start the specified torrent hashes
|
||||
public function torrentStart($hash) {
|
||||
$this->makeRequest("?action=start".$this->paramImplode("&hash=", $hash), false);
|
||||
}
|
||||
|
||||
// stop the specified torrent hashes
|
||||
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) {
|
||||
$this->makeRequest("?action=".($data ? "removedata" : "remove").$this->paramImplode("&hash=", $hash), false);
|
||||
}
|
||||
}
|
198
app/Protocols/0.sample.php
Normal file
198
app/Protocols/0.sample.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* hdarea解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Hdarea implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hdarea';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'www.hdarea.co';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
#p($html);exit;
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '<td width="80" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
$arr['title'] = str_replace("\n","",$arr['title']);
|
||||
// 第二次过滤
|
||||
if ( strpos($arr['title'],'</td>') != false ) {
|
||||
$arr['title'] = str_replace('</td>',"",$arr['title']);
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
194
app/Protocols/beitai.php
Normal file
194
app/Protocols/beitai.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* www.beitai.pt解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Beitai implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'beitai';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'www.beitai.pt';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);exit;
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
195
app/Protocols/brobits.php
Normal file
195
app/Protocols/brobits.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* brobits解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Brobits implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'brobits';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'brobits.cc';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
217
app/Protocols/btschool.php
Normal file
217
app/Protocols/btschool.php
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
/**
|
||||
* pt.btschool.club解码类
|
||||
* Extreme User及以上用户会永远保留账号。必须注册至少60周,并且下载至少2TB,分享率大于3.55。[7.1TB保号]
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Btschool implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'btschool';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pt.btschool.club';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br/>';
|
||||
$h2StrEnd = '</td><td width="50" class="embedded"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
//p($temp);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$titleTemp = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
//二次过滤
|
||||
$titleTemp = selector::remove($titleTemp, "//a"); //编码标签
|
||||
$titleTemp = selector::remove($titleTemp, "//div"); //做种标签
|
||||
if ( strpos($titleTemp,'<div ') != false ) {
|
||||
$titleTemp = substr($titleTemp, 0, strpos($titleTemp,'<div '));
|
||||
}
|
||||
// 精确适配标签 begin
|
||||
$titleSpan = '';
|
||||
$title = selector::remove($titleTemp, "//span");
|
||||
$span = selector::select($titleTemp, '//span');
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
foreach ( $span as $vv ){
|
||||
if( empty($vv) ){
|
||||
continue;
|
||||
}
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}else{
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
217
app/Protocols/chdbits.php
Normal file
217
app/Protocols/chdbits.php
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
/**
|
||||
* chdbits.co解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Chdbits implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'chdbits';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'chdbits.co';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free','title="免费"');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="50" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$titleTemp = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
// 精确适配标签 begin
|
||||
$titleSpan = '';
|
||||
$title = selector::remove($titleTemp, "//div");
|
||||
$span = selector::select($titleTemp, '//div');
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
foreach ( $span as $vv ){
|
||||
if( empty($vv) || (strpos($titleTemp,'<div') != false) ){
|
||||
continue;
|
||||
}
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}else{
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
// 最后过滤
|
||||
if ( strpos($title,'<font') != false ) {
|
||||
$offset = 0;
|
||||
$offset = strpos($title,'>')+1;
|
||||
$title = substr($title, $offset);
|
||||
}
|
||||
$title = str_replace('</font>',"",$title);
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
58
app/Protocols/decodebase.php
Normal file
58
app/Protocols/decodebase.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* 定义站点解码类接口
|
||||
*/
|
||||
interface decodeBase
|
||||
{
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init();
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run();
|
||||
|
||||
/**
|
||||
* 接口方法,在类中实现
|
||||
* 请求url,获取html页面
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php');
|
||||
|
||||
/**
|
||||
* 接口方法,在类中实现
|
||||
* 解码html为种子数组
|
||||
* @param array $html
|
||||
* @return array
|
||||
* 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://hdsky.me/details.php?id=118632
|
||||
[download] => https://hdsky.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时<br />46分
|
||||
)
|
||||
[comments] => 0
|
||||
[size] => 5232.64MB
|
||||
[seeders] => 69
|
||||
[leechers] => 10
|
||||
[completed] => 93
|
||||
[percentage] => 100%
|
||||
[owner] => 匿名
|
||||
)
|
||||
*/
|
||||
public static function decode($html = array());
|
||||
}
|
195
app/Protocols/eastgame.php
Normal file
195
app/Protocols/eastgame.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* eastgame解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Eastgame implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'eastgame';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pt.eastgame.org';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
if ( strpos($arr['title'],'</a>') != false ) {
|
||||
$arr['title'] = selector::remove($arr['title'], "//a");
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
198
app/Protocols/hd4fans.php
Normal file
198
app/Protocols/hd4fans.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* hdarea解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class hd4fans implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hd4fans';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pt.hd4fans.org';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
#p($html);exit;
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
#$arr['title'] = str_replace("\n","",$arr['title']);
|
||||
// 第二次过滤
|
||||
if ( strpos($arr['title'],'</td>') != false ) {
|
||||
#$arr['title'] = str_replace('</td>',"",$arr['title']);
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
198
app/Protocols/hdarea.php
Normal file
198
app/Protocols/hdarea.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* hdarea解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Hdarea implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hdarea';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'www.hdarea.co';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
#p($html);exit;
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '<td width="80" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
$arr['title'] = str_replace("\n","",$arr['title']);
|
||||
// 第二次过滤
|
||||
if ( strpos($arr['title'],'</td>') != false ) {
|
||||
$arr['title'] = str_replace('</td>',"",$arr['title']);
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
198
app/Protocols/hdbug.php
Normal file
198
app/Protocols/hdbug.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* hdbug解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class hdbug implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hdbug';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'hdbug.best';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
#p($html);exit;
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
#$arr['title'] = str_replace("\n","",$arr['title']);
|
||||
// 第二次过滤
|
||||
if ( strpos($arr['title'],'</td>') != false ) {
|
||||
#$arr['title'] = str_replace('</td>',"",$arr['title']);
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
205
app/Protocols/hdchina.php
Normal file
205
app/Protocols/hdchina.php
Normal file
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* hdchina解码类
|
||||
* 未检测是否免费、未检测HR
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Hdchina implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hdchina';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'hdchina.org';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?hash=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='tbname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 25; // 截取长度
|
||||
// hdchina特有
|
||||
$idStrLen = strlen(self::detailsPrefix); // ID前缀长度
|
||||
$idStrEnd = '&'; // 种子地址结束标志
|
||||
$idlen = $idStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
|
||||
// 种子id[单独计算]
|
||||
$idOffset = strpos($v,self::detailsPrefix);
|
||||
$idTemp = substr($v, $idOffset, $idlen);
|
||||
$id = substr($idTemp,0,strpos($idTemp,$idStrEnd));
|
||||
$arr['id'] = substr($id,$idStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<h4>';
|
||||
$h2StrEnd = '</h4>';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
if ($h2_endOffset === false) {
|
||||
$arr['title'] = '';
|
||||
}else {
|
||||
// 方法一
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
// 副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
|
||||
// 方法二 [直取副标题]
|
||||
#$arr['title'] = selector::select($v, '//h4');
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码 【未检测是否免费】
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
194
app/Protocols/hddolby.php
Normal file
194
app/Protocols/hddolby.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* www.hddolby.com解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Hddolby implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hddolby';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'www.hddolby.com';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);exit;
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
228
app/Protocols/hdhome.php
Normal file
228
app/Protocols/hdhome.php
Normal file
@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* hdhome.org解码类
|
||||
* 特殊说明:是H&R的种子,不管是否免费都会自动过滤。
|
||||
* Nexus Master及以上用户会永远保留账号。必须注册至少10周,并且下载至少8TB,分享率大于5.50。[44TB保号]
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Hdhome implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hdhome';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'hdhome.org';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志 class="hitandrun" 或者 title="H&R"
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* 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://hdsky.me/details.php?id=118632
|
||||
[download] => https://hdsky.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时<br />46分
|
||||
)
|
||||
[comments] => 0
|
||||
[size] => 5232.64MB
|
||||
[seeders] => 69
|
||||
[leechers] => 10
|
||||
[completed] => 93
|
||||
[percentage] => 100%
|
||||
[owner] => 匿名
|
||||
)
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// H&R检测
|
||||
foreach ( self::$HR as $hrV ){
|
||||
if(strpos($v,$hrV) != false){
|
||||
self::$TorrentList[$k]['hr'] = 1;
|
||||
// 删除
|
||||
#unset( self::$TorrentList[$k] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
307
app/Protocols/hdsky.php
Normal file
307
app/Protocols/hdsky.php
Normal file
@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* hdsky.me解码类
|
||||
* 明星(Veteran User)及以上用户会永远保留账号, 必须注册至少25周,并且下载至少4TB,分享率大于4.0。[16TB保号]
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Hdsky implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hdsky';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'hdsky.me';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'POST';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* 促销时间特征
|
||||
*/
|
||||
public static $proTime = '优惠剩余时间';
|
||||
/**
|
||||
* 置顶标志
|
||||
*/
|
||||
public static $sticky = 'title="置顶"';
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data1 = selector::select($html, "//*[@class='stickbg progresstr']");
|
||||
$data2 = selector::select($html, "//*[@class='progresstr']");
|
||||
if (empty($data1)) {
|
||||
$data = $data2;
|
||||
}else{
|
||||
$data = array_merge($data1, $data2);
|
||||
}
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题
|
||||
// 偏移量
|
||||
$h2_offset = strpos($v,'<br />') + strlen('<br />');
|
||||
$h2_len = strpos($v,'</td><td width="32"',$h2_offset) - $h2_offset;
|
||||
if($h2_len > 0){
|
||||
//存在副标题
|
||||
$titleTemp = substr($v, $h2_offset, $h2_len);
|
||||
$titleSpan = '';
|
||||
$title = selector::remove($titleTemp, "//span");
|
||||
|
||||
// 精确适配标签 begin
|
||||
$span = selector::select($titleTemp, '//span');
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
// 查询促销时间特征
|
||||
if(strpos($title, self::$proTime) != false){
|
||||
$key = count($span);
|
||||
// 替换占位符
|
||||
$title = str_replace('<b></b>',$span[$key-1],$title);
|
||||
// 适配
|
||||
unset($span[$key-1]);
|
||||
}
|
||||
foreach ( $span as $vv ){
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}else{
|
||||
// 查询促销时间特征
|
||||
if(strpos($title, self::$proTime) != false){
|
||||
// 替换占位符
|
||||
$title = str_replace('<b></b>',$span,$title);
|
||||
}else {
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
#echo $arr['title'];
|
||||
}else {
|
||||
$arr['title'] = '';
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型discount
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
// 非免费,是否需要获取扩展信息
|
||||
//continue;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
|
||||
// 是否置顶sticky
|
||||
self::$TorrentList[$k]['sticky'] = strpos($v,self::$sticky)===false ? 0 : 1;
|
||||
|
||||
// 优惠剩余时间proTime(可选)
|
||||
// 存活时间added(必有)
|
||||
$added = selector::select($v, '@<span title=(.*?)</span>@', "regex");
|
||||
self::$TorrentList[$k]['time'] = $added;
|
||||
#p($added);
|
||||
/*
|
||||
Array
|
||||
(
|
||||
[0] => "2019-11-20 15:01:17">3天22时
|
||||
[1] => "2014-09-24 00:09:20">5年<br />2月
|
||||
)
|
||||
|
||||
string
|
||||
"2016-04-24 15:43:25">3年<br />7月
|
||||
*/
|
||||
|
||||
$options = selector::select($v, "//*[@class='rowfollow']");
|
||||
#p($options);
|
||||
/*
|
||||
$options = Array
|
||||
(
|
||||
[0] => <a href="comment.php?action=add&pid=118608&type=torrent" title="添加评论">0</a>
|
||||
[1] => 7.11<br/>GB
|
||||
[2] => <b><a href="details.php?id=118608&hit=1&dllist=1#seeders"><font color="#ff0000">1</font></a></b>
|
||||
[3] => <b><a href="details.php?id=118608&hit=1&dllist=1#leechers">105</a></b>
|
||||
[4] => 0
|
||||
[5] => 0%
|
||||
[6] => <span class="nowrap"><a href="userdetails.php?id=70966" class="Uploader_Name"><b>r9ruibu</b></a><img class="star" src="pic/trans.gif" alt="Donor" style="margin-left: 2pt"/></span>
|
||||
)
|
||||
|
||||
对应的:
|
||||
[0] => 评论
|
||||
[1] => 大小size
|
||||
[2] => 种子数seeders
|
||||
[3] => 下载数leechers
|
||||
[4] => 完成数
|
||||
[5] => 完成进度
|
||||
[6] => 发布者
|
||||
*/
|
||||
|
||||
// 0 评论comments
|
||||
self::$TorrentList[$k]['comments'] = selector::select($options[0], "//a");
|
||||
// 1 大小size
|
||||
self::$TorrentList[$k]['size'] = str_replace('<br/>','',$options[1]);
|
||||
// 2 种子数seeders
|
||||
if ( empty($options[2]) ) {
|
||||
$seeders = 0;
|
||||
} else {
|
||||
if( strpos($options[2],'</font>') === false ){
|
||||
if ( strpos($options[2],'</span>') === false ) {
|
||||
// 普通特征
|
||||
$seeders = selector::select($options[2], "//a");
|
||||
} else {
|
||||
// 新种 0做种特征
|
||||
$seeders = selector::select($options[2], "//span");
|
||||
}
|
||||
}else{
|
||||
// 新种 1做种特征
|
||||
$seeders = selector::select($options[2], "//font");
|
||||
}
|
||||
}
|
||||
self::$TorrentList[$k]['seeders'] = $seeders;
|
||||
|
||||
// 3 下载数leechers
|
||||
self::$TorrentList[$k]['leechers'] = empty($options[3]) ? 0 : selector::select($options[3], "//a");
|
||||
// 4 完成数completed
|
||||
self::$TorrentList[$k]['completed'] = empty($options[4]) ? 0 : selector::select($options[4], "//b");
|
||||
// 5 完成百分比percentage
|
||||
self::$TorrentList[$k]['percentage'] = strpos($options[5],'</b>') === false ? $options[5] : selector::select($options[5], "//b");
|
||||
// 6 发布者owner
|
||||
$owner = selector::select($options[6], "//b");
|
||||
self::$TorrentList[$k]['owner'] = empty($owner) ? '匿名' : $owner;
|
||||
|
||||
#exit(0);
|
||||
}
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
198
app/Protocols/hdtime.php
Normal file
198
app/Protocols/hdtime.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* hdtime解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Hdtime implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'hdtime';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'hdtime.org';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
#p($html);exit;
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="100" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
#$arr['title'] = str_replace("\n","",$arr['title']);
|
||||
// 第二次过滤
|
||||
if ( strpos($arr['title'],'</td>') != false ) {
|
||||
#$arr['title'] = str_replace('</td>',"",$arr['title']);
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
213
app/Protocols/keepfrds.php
Normal file
213
app/Protocols/keepfrds.php
Normal file
@ -0,0 +1,213 @@
|
||||
<?php
|
||||
/**
|
||||
* pt.keepfrds.com解码类
|
||||
* 保留账号:Veteran User,【3.5 TB】(注册60周,下载量1TB、分享率3.5、魔力值640000、做种率640)
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
class Keepfrds implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'keepfrds';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pt.keepfrds.com';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding;
|
||||
requests::$output_encoding = self::encoding;
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(正序算法)
|
||||
// 偏移量
|
||||
$h2_offset = strpos($v,'<br />') + strlen('<br />');
|
||||
$h2_end = strpos($v, '</td><td width="110" class="embedded"', $h2_offset);
|
||||
$h2_len = $h2_end - $h2_offset;
|
||||
if($h2_len > 0){
|
||||
//存在副标题
|
||||
$titleTemp = substr($v, $h2_offset, $h2_len);
|
||||
$titleSpan = '';
|
||||
// 精确适配标签 begin
|
||||
// 移除标签
|
||||
$title = selector::remove($titleTemp, "//b");
|
||||
if ( strpos($title, '<div') != false ) {
|
||||
// 移除下载进度框
|
||||
$title = substr($title, 0, strpos($title, '<div'));
|
||||
}
|
||||
#p($title);
|
||||
if ( strpos($title,'</font>') != false ) {
|
||||
// 匹配红色副标题
|
||||
$title = selector::select($title, '//font');
|
||||
}
|
||||
// 选取标签
|
||||
$span = selector::select($titleTemp, "//b/font");
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
foreach ( $span as $vv ){
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}else{
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
}else{
|
||||
$arr['title'] = '';
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
197
app/Protocols/leaguehd.php
Normal file
197
app/Protocols/leaguehd.php
Normal file
@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* leaguehd解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Leaguehd implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'leaguehd';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'leaguehd.com';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free','title="2X免费"');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td class="embedded"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
#p($temp);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
//二次过滤
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
230
app/Protocols/moecat.php
Normal file
230
app/Protocols/moecat.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/**
|
||||
* moecat.best解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Moecat implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'moecat';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'moecat.best';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$html = selector::select($html, "//*[@class='torrents']");
|
||||
$data = selector::select($html, "//table");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
if (strpos($arr['h1'],'&#x') != false) {
|
||||
$arr['h1'] = mb_convert_encoding($arr['h1'], 'UTF-8', 'HTML-ENTITIES');
|
||||
}
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br/>';
|
||||
$h2StrEnd = '</td><td rowspan="2" width="20"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
#p($temp);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$titleTemp = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
#p($titleTemp);
|
||||
//二次过滤
|
||||
$titleTemp = selector::remove($titleTemp, "//a"); //编码标签
|
||||
$titleTemp = selector::remove($titleTemp, "//div"); //做种标签
|
||||
$douban = '';
|
||||
if ( strpos($titleTemp,"<font ") != false ) {
|
||||
$douban = selector::select($titleTemp, '//font');
|
||||
#p($douban);
|
||||
$titleTemp = selector::remove($titleTemp, "//b"); // 移除豆瓣
|
||||
#$titleTemp = substr($titleTemp, 0, strpos($titleTemp,'<div '));
|
||||
}
|
||||
// 精确适配标签 begin
|
||||
$titleSpan = '';
|
||||
|
||||
$title = selector::remove($titleTemp, "//span");
|
||||
$span = selector::select($titleTemp, '//span');
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
foreach ( $span as $vv ){
|
||||
if( empty($vv) ){
|
||||
continue;
|
||||
}
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}else{
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
if ($douban != ''){
|
||||
// 豆瓣放前面
|
||||
$arr['title'] = $douban . $arr['title'];
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
194
app/Protocols/mteam.php
Normal file
194
app/Protocols/mteam.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* pt.m-team.cc解码类
|
||||
* 府尹/Extreme User、【14 TB】必须注册至少24周,并且下载至少2TB,分享率大于7
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Mteam implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'm-team';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pt.m-team.cc';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '&'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="80"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'].'&https=1';
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
201
app/Protocols/nanyangpt.php
Normal file
201
app/Protocols/nanyangpt.php
Normal file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
/**
|
||||
* nanyangpt解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Nanyangpt implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'nanyangpt';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'nanyangpt.com';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" target="_blank" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd1 = '</td><td width="34" class="embedded"'; // 置顶
|
||||
$h2StrEnd2 = '</td><td class="embedded" width="40px"'; // 普通
|
||||
$h2_endOffset = strpos($v,$h2StrEnd1) === false ? strpos($v,$h2StrEnd2) : strpos($v,$h2StrEnd1);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$titleTemp = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
if ( strpos($titleTemp,'<span') != false ) {
|
||||
$titleTemp = substr($titleTemp, 0, strpos($titleTemp,'<span'));
|
||||
}
|
||||
// 第二次过滤
|
||||
$arr['title'] = $titleTemp;
|
||||
|
||||
//最后过滤
|
||||
$arr['title'] = str_replace(' ',"",$arr['title']); // 过滤
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
199
app/Protocols/opencd.php
Normal file
199
app/Protocols/opencd.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?php
|
||||
/**
|
||||
* opencd解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class opencd implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'opencd';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'open.cd';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
#p($html);exit;
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="plugin_details.php') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td class="nowrap embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$temp = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
//存在副标题
|
||||
if ( strpos($temp,'</font>') != false ) {
|
||||
$arr['title'] = selector::select($temp, '//font');
|
||||
}else{
|
||||
$arr['title'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
336
app/Protocols/ourbits.php
Normal file
336
app/Protocols/ourbits.php
Normal file
@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/**
|
||||
* ourbits.club解码类
|
||||
* Veteran User及以上用户会永远保留账号。必须注册至少25周,并且下载至少2TB,分享率大于4.0。[8TB保号]
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Ourbits implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'ourbits';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'ourbits.club';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* 促销时间特征
|
||||
*/
|
||||
public static $proTime = '剩余时间:<b><span title';
|
||||
/**
|
||||
* 置顶标志
|
||||
*/
|
||||
public static $sticky = 'src="pic/sticky';
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding;
|
||||
requests::$output_encoding = self::encoding;
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
|
||||
// 一级置顶
|
||||
$data1 = selector::select($html, "//*[@class='sticky_top']");
|
||||
$data1 = is_array($data1) ? array_filter($data1, "evenFilter", ARRAY_FILTER_USE_KEY) : array();
|
||||
// 二级置顶
|
||||
$data2 = selector::select($html, "//*[@class='sticky_normal']");
|
||||
$data2 = is_array($data2) ? array_filter($data2, "evenFilter", ARRAY_FILTER_USE_KEY) : array();
|
||||
// 普通
|
||||
$data3 = selector::select($html, "//*[@class='sticky_blank']");
|
||||
$data3 = is_array($data3) ? array_filter($data3, "evenFilter", ARRAY_FILTER_USE_KEY) : array();
|
||||
$mark = 0;
|
||||
if( empty($data1) ){
|
||||
$mark = $mark + 1;
|
||||
}
|
||||
if( empty($data2) ){
|
||||
$mark = $mark + 2;
|
||||
}
|
||||
switch($mark){
|
||||
case 0:
|
||||
$data = array_merge($data1, $data2, $data3);
|
||||
break;
|
||||
case 1:
|
||||
$data = array_merge($data2, $data3);
|
||||
break;
|
||||
case 2:
|
||||
$data = array_merge($data1, $data3);
|
||||
break;
|
||||
case 3:
|
||||
$data = $data3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$br = '<br/>';
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
// 优惠时间
|
||||
$proTime = '';
|
||||
if ( strpos($v,self::$proTime)!=false ) {
|
||||
$t_offset = strpos($v, $br);
|
||||
$t_temp = substr($v, $h1_offset,$t_offset-$h1_offset);
|
||||
$proTime = selector::select($t_temp, "//span");
|
||||
$arr['h1'] = $arr['h1']. ' [优惠时间剩余:' .$proTime. ']';
|
||||
}
|
||||
|
||||
// 获取副标题
|
||||
// 偏移量
|
||||
$h2_offset = strpos($v,$br) + strlen($br);
|
||||
$h2_len = strpos($v,'</td><td class="embedded" width="30px">',$h2_offset) - $h2_offset;
|
||||
if($h2_len > 0){
|
||||
//存在副标题
|
||||
$titleTemp = substr($v, $h2_offset, $h2_len);
|
||||
$titleSpan = '';
|
||||
$title = selector::remove($titleTemp, "//div");
|
||||
// 精确适配标签 begin
|
||||
$span = selector::select($titleTemp, '//div');
|
||||
#p($span);
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
foreach ( $span as $vv ){
|
||||
if( empty($vv) ){
|
||||
continue;
|
||||
}
|
||||
if(strpos($vv, '<div') === false){
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(strpos($vv, '<div') === false){
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
#echo $arr['title']."\n\n";
|
||||
}else{
|
||||
$arr['title'] = '';
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型discount
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
// 非免费,是否需要获取扩展信息
|
||||
//continue;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
|
||||
// 是否置顶sticky
|
||||
self::$TorrentList[$k]['sticky'] = strpos($v,self::$sticky)===false ? 0 : 1;
|
||||
|
||||
// 优惠剩余时间proTime(可选)
|
||||
// 存活时间added(必有)
|
||||
$added = selector::select($v, '@<span title=(.*?)</span>@', "regex");
|
||||
self::$TorrentList[$k]['time'] = $added;
|
||||
|
||||
#p($added);
|
||||
/*
|
||||
Array
|
||||
(
|
||||
[0] => "2019-11-20 15:01:17">3天22时
|
||||
[1] => "2014-09-24 00:09:20">5年<br />2月
|
||||
)
|
||||
|
||||
string
|
||||
"2016-04-24 15:43:25">3年<br />7月
|
||||
*/
|
||||
|
||||
$options = selector::select($v, "//*[@class='rowfollow']");
|
||||
unset($options[0]);
|
||||
$options = array_values($options);
|
||||
#p($options);exit;
|
||||
/*
|
||||
$options = Array
|
||||
(
|
||||
[0] => <a href="comment.php?action=add&pid=114293&type=torrent" title="添加评论">0</a>
|
||||
[1] => 50.11<br/>GB
|
||||
[2] => <b><a href="details.php?id=114293&hit=1&dllist=1#seeders">70</a></b>
|
||||
[3] => <b><a href="details.php?id=114293&hit=1&dllist=1#leechers">24</a></b>
|
||||
[4] => <a href="viewsnatches.php?id=114293"><b>95</b></a>
|
||||
[5] => <i>匿名</i>
|
||||
)
|
||||
|
||||
|
||||
对应的:
|
||||
[0] => 评论
|
||||
[1] => 大小size
|
||||
[2] => 种子数seeders
|
||||
[3] => 下载数leechers
|
||||
[4] => 完成数
|
||||
[5] => 发布者
|
||||
*/
|
||||
|
||||
// 0 评论comments
|
||||
self::$TorrentList[$k]['comments'] = selector::select($options[0], "//a");
|
||||
// 1 大小size
|
||||
self::$TorrentList[$k]['size'] = str_replace('<br/>','',$options[1]);
|
||||
// 2 种子数seeders
|
||||
if ( empty($options[2]) ) {
|
||||
$seeders = 0;
|
||||
} else {
|
||||
if( strpos($options[2],'</font>') === false ){
|
||||
if ( strpos($options[2],'</span>') === false ) {
|
||||
// 普通特征
|
||||
$seeders = selector::select($options[2], "//a");
|
||||
} else {
|
||||
// 新种 0做种特征
|
||||
$seeders = selector::select($options[2], "//span");
|
||||
}
|
||||
}else{
|
||||
// 新种 1做种特征
|
||||
$seeders = selector::select($options[2], "//font");
|
||||
}
|
||||
}
|
||||
self::$TorrentList[$k]['seeders'] = $seeders;
|
||||
|
||||
// 3 下载数leechers
|
||||
self::$TorrentList[$k]['leechers'] = empty($options[3]) ? 0 : selector::select($options[3], "//a");
|
||||
// 4 完成数completed
|
||||
self::$TorrentList[$k]['completed'] = empty($options[4]) ? 0 : selector::select($options[4], "//b");
|
||||
// 5 完成百分比percentage
|
||||
|
||||
// 6 发布者owner
|
||||
$owner = selector::select($options[5], "//b");
|
||||
self::$TorrentList[$k]['owner'] = empty($owner) ? '匿名' : $owner;
|
||||
|
||||
#exit(0);
|
||||
}
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
198
app/Protocols/ptba.php
Normal file
198
app/Protocols/ptba.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* 1ptba解码类
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Ptba implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = '1ptba';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = '1ptba.com';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
#p($html);exit;
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
#$arr['title'] = str_replace("\n","",$arr['title']);
|
||||
// 第二次过滤
|
||||
if ( strpos($arr['title'],'</td>') != false ) {
|
||||
#$arr['title'] = str_replace('</td>',"",$arr['title']);
|
||||
}
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
217
app/Protocols/pterclub.php
Normal file
217
app/Protocols/pterclub.php
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
/**
|
||||
* pterclub.com解码类
|
||||
* 安哥拉猫(Veteran User)、【2.29 TB】、必须注册至少30周,并且下载至少750G,分享率大于3.05
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class pterclub implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'pter';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pterclub.com';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '&'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题 精确适配标签
|
||||
// 偏移量
|
||||
$h2StrStart = '<br/>';
|
||||
$h2StrEnd = '</td><td class="embedded" width="6px">';
|
||||
$h2_endoffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endoffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
//p($temp);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
//存在副标题
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
$titleTemp = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
if ( strpos($titleTemp, $h2StrStart)!=false ) {
|
||||
//过滤已下载、进行中等进度框
|
||||
$titleTemp = substr($titleTemp, 0, strpos($titleTemp, $h2StrStart));
|
||||
}
|
||||
// 精确适配标签 begin
|
||||
$titleSpan = '';
|
||||
$title = selector::remove($titleTemp, "//div");
|
||||
$span = selector::select($titleTemp, '//a');
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
foreach ( $span as $vv ){
|
||||
if( empty($vv) ){
|
||||
continue;
|
||||
}
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}else{
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
//最后过滤
|
||||
#$arr['title'] = strip_tags(str_replace('d class="embedded">',"",$arr['title'])); // 过滤
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
187
app/Protocols/pthome.php
Normal file
187
app/Protocols/pthome.php
Normal file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* www.pthome.net解码类
|
||||
* 保留账号:Veteran User、【6 TB】、必须注册至少40周,并且下载至少1000G,分享率大于6
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
class Pthome implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'pthome';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'www.pthome.net';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding;
|
||||
requests::$output_encoding = self::encoding;
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(正序算法)
|
||||
// 偏移量
|
||||
$h2_offset = strpos($v,'<br />') + strlen('<br />');
|
||||
$h2_len = strpos($v,'</td><td width="20"',$h2_offset) - $h2_offset;
|
||||
if($h2_len > 0){
|
||||
//存在副标题
|
||||
$arr['title'] = substr($v, $h2_offset, $h2_len);
|
||||
//二次过滤
|
||||
$arr['title'] = selector::remove($arr['title'], "//a");
|
||||
}else{
|
||||
$arr['title'] = '';
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
228
app/Protocols/ptmsg.php
Normal file
228
app/Protocols/ptmsg.php
Normal file
@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* pt.msg.vg解码类
|
||||
*
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Ptmsg implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'ptmsg';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pt.msg.vg';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志 class="hitandrun" 或者 title="H&R"
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* 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://hdsky.me/details.php?id=118632
|
||||
[download] => https://hdsky.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时<br />46分
|
||||
)
|
||||
[comments] => 0
|
||||
[size] => 5232.64MB
|
||||
[seeders] => 69
|
||||
[leechers] => 10
|
||||
[completed] => 93
|
||||
[percentage] => 100%
|
||||
[owner] => 匿名
|
||||
)
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '<br /></td><td width="20" class="embedded"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// H&R检测
|
||||
foreach ( self::$HR as $hrV ){
|
||||
if(strpos($v,$hrV) != false){
|
||||
self::$TorrentList[$k]['hr'] = 1;
|
||||
// 删除
|
||||
#unset( self::$TorrentList[$k] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
198
app/Protocols/ptsbao.php
Normal file
198
app/Protocols/ptsbao.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* ptsbao.club解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Ptsbao implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'ptsbao';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'ptsbao.club';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free','alt="Free"','alt="2X Free"');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '&'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="80" class="embedded"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
#p($temp);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
//二次过滤
|
||||
$arr['title'] = str_replace('</span>',"",$arr['title']);
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
195
app/Protocols/site52pt.php
Normal file
195
app/Protocols/site52pt.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* 52pt.site解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Site52pt implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = '52pt';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = '52pt.site';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
197
app/Protocols/soulvoice.php
Normal file
197
app/Protocols/soulvoice.php
Normal file
@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* soulvoice解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Soulvoice implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'soulvoice';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'pt.soulvoice.club';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free','alt="Free"','alt="2X Free"');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
#p($temp);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
//二次过滤
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
187
app/Protocols/ssd.php
Normal file
187
app/Protocols/ssd.php
Normal file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* springsunday.net解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
class Ssd implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'ssd';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'springsunday.net';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding;
|
||||
requests::$output_encoding = self::encoding;
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(正序算法)
|
||||
// 偏移量
|
||||
$h2_offset = strpos($v,'<br />') + strlen('<br />');
|
||||
$h2_len = strpos($v,'</td><td width="60" class="embedded"',$h2_offset) - $h2_offset;
|
||||
if($h2_len > 0){
|
||||
//存在副标题
|
||||
$arr['title'] = substr($v, $h2_offset, $h2_len);
|
||||
//二次过滤
|
||||
$arr['title'] = selector::remove($arr['title'], "//a");
|
||||
}else{
|
||||
$arr['title'] = '';
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
194
app/Protocols/tjupt.php
Normal file
194
app/Protocols/tjupt.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* tjupt.org解码类
|
||||
* 威震一方及以上用户会永远保留账号。必须注册至少40周,并且下载至少750G,分享率大于3.05。[2.3TB保号]
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Tjupt implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'tjupt';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'tjupt.org';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('免费</font>');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="40" class="embedded"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
$arr['title'] = selector::remove($arr['title'], "//a");
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
194
app/Protocols/torrentccf.php
Normal file
194
app/Protocols/torrentccf.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* et8.org解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Torrentccf implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'torrentccf';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'et8.org';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$data = selector::select($html, "//*[@class='torrentname']");
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<a title="') + strlen('<a title="');
|
||||
$h1_len = strpos($v, '" href="details.php?id=') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br />';
|
||||
$h2StrEnd = '</td><td width="20" class="embedded"';
|
||||
$h2_endOffset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_endOffset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$arr['title'] = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
// 第二次过滤
|
||||
#code...
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
190
app/Protocols/totheglory.php
Normal file
190
app/Protocols/totheglory.php
Normal file
@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* totheglory解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Totheglory implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'ttg';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'totheglory.im';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'dl/';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 't/{}/';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('ico_free.gif');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('hit_run.gif','title="Hit and Run"','title="Hit');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '/'.$config['passkey'] : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'browse.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$html = selector::select($html, "//*[@id='torrent_table']");
|
||||
$data = selector::select($html, "//div[@class='name_left']");
|
||||
#p($data);exit;
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
// 种子ID前缀
|
||||
$torrentIdPrefix = 'torrent="';
|
||||
$toorentIdStrLen = strlen($torrentIdPrefix);
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 种子id[单独截取]
|
||||
$idOffset = $idTemp = '';
|
||||
$idOffset = strpos($v,$torrentIdPrefix);
|
||||
$idTemp =substr($v,$idOffset + $toorentIdStrLen,10);
|
||||
$arr['id'] = substr($idTemp,0,strpos($idTemp,'"'));
|
||||
// 种子地址
|
||||
$arr['url'] = self::downloadPrefix . $arr['id'] . self::$passkey;
|
||||
#p($arr);exit;
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, 'torrentname="') + strlen('torrentname="');
|
||||
$h1_len = strpos($v, '" torrent="') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
if (strpos($arr['h1'],'&#x') != false) {
|
||||
$arr['h1'] = mb_convert_encoding($arr['h1'], 'UTF-8', 'HTML-ENTITIES');
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.str_replace('{}',$arr['id'],self::detailsPrefix);
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// H&R检测
|
||||
foreach ( self::$HR as $hrV ){
|
||||
if(strpos($v,$hrV) != false){
|
||||
self::$TorrentList[$k]['hr'] = 1;
|
||||
// 删除
|
||||
#unset( self::$TorrentList[$k] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);exit;
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
223
app/Protocols/yingk.php
Normal file
223
app/Protocols/yingk.php
Normal file
@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/**
|
||||
* yingk解码类
|
||||
*
|
||||
*/
|
||||
use phpspider\core\requests;
|
||||
use phpspider\core\selector;
|
||||
|
||||
class Yingk implements decodeBase
|
||||
{
|
||||
/**
|
||||
* 站点标志
|
||||
* @var string
|
||||
*/
|
||||
const SITE = 'yingk';
|
||||
/**
|
||||
* 域名
|
||||
* @var string
|
||||
*/
|
||||
const domain = 'yingk.com';
|
||||
const HOST = 'https://'.self::domain.'/';
|
||||
// 下载种子的请求类型
|
||||
const METHOD = 'GET';
|
||||
/**
|
||||
* 种子存放路径
|
||||
* @var string
|
||||
*/
|
||||
const TORRENT_DIR = TORRENT_PATH . self::SITE . DS;
|
||||
/**
|
||||
* 种子下载前缀
|
||||
*/
|
||||
const downloadPrefix = 'download.php?id=';
|
||||
/**
|
||||
* 种子详情页前缀
|
||||
*/
|
||||
const detailsPrefix = 'details.php?id=';
|
||||
// 网页编码
|
||||
const encoding = 'UTF-8';
|
||||
// 超时时间
|
||||
const CONNECTTIMEOUT = 30;
|
||||
const TIMEOUT = 600;
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
public static $cookies = '';
|
||||
/**
|
||||
* 浏览器 User-Agent
|
||||
*/
|
||||
public static $userAgent = '';
|
||||
/**
|
||||
* passkey
|
||||
*/
|
||||
public static $passkey = '';
|
||||
/**
|
||||
* 获取的种子标志
|
||||
*/
|
||||
public static $getTorrent = array('class="pro_free');
|
||||
/**
|
||||
* H&R 标志
|
||||
*/
|
||||
public static $HR = array('class="hitandrun"','alt="H&R"','title="H&R"');
|
||||
/**
|
||||
* 解码后种子列表数组
|
||||
*/
|
||||
public static $TorrentList = array();
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
$config = $configALL[self::SITE];
|
||||
self::$cookies = $config['cookie'];
|
||||
self::$userAgent = isset($config['userAgent']) && $config['userAgent'] ? $config['userAgent'] : $configALL['default']['userAgent'];
|
||||
self::$passkey = isset($config['passkey']) ? '&passkey='.$config['passkey'].'&https=1' : '';
|
||||
|
||||
requests::$input_encoding = self::encoding; //输入的网页编码
|
||||
requests::$output_encoding = self::encoding; //输出的网页编码
|
||||
requests::set_cookies(self::$cookies, self::domain);
|
||||
requests::set_useragent([self::$userAgent]);
|
||||
requests::set_timeout([self::CONNECTTIMEOUT,self::TIMEOUT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
Rpc::init(self::SITE, self::METHOD);
|
||||
$html = self::get();
|
||||
if ( $html === null ) {
|
||||
exit(1);
|
||||
}
|
||||
$data = self::decode($html);
|
||||
#p($data);exit;
|
||||
Rpc::call($data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求页面
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function get($url = 'torrents.php')
|
||||
{
|
||||
// 发起请求
|
||||
$html = requests::get(self::HOST.$url);
|
||||
// 获取列表页数据
|
||||
$html = selector::select($html, "//*[@class='torrents']");
|
||||
#p($html);exit;
|
||||
$data = selector::select($html, "//table");
|
||||
#p($data);exit;
|
||||
if(!$data){
|
||||
echo "登录信息过期,请重新设置! \n";
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($data = array())
|
||||
{
|
||||
$downloadStrLen = strlen(self::downloadPrefix); // 前缀长度
|
||||
$downloadStrEnd = '"'; //种子地址结束标志
|
||||
$len = $downloadStrLen + 10; // 截取长度
|
||||
foreach ( $data as $k => $v ){
|
||||
$arr = array();
|
||||
// 种子基本信息处理
|
||||
// 偏移量
|
||||
$offset = strpos($v,self::downloadPrefix);
|
||||
// 截取
|
||||
$urlTemp = substr($v,$offset,$len);
|
||||
// 种子地址
|
||||
$arr['url'] = substr($urlTemp,0,strpos($urlTemp,$downloadStrEnd));
|
||||
// 种子id
|
||||
$arr['id'] = substr($arr['url'],$downloadStrLen);
|
||||
|
||||
// 获取主标题
|
||||
// 偏移量
|
||||
$h1_offset = strpos($v, '<b>') + strlen('<b>');
|
||||
$h1_len = strpos($v, '</b>') - $h1_offset;
|
||||
$arr['h1'] = substr($v, $h1_offset, $h1_len);
|
||||
if (strpos($arr['h1'],'&#x') != false) {
|
||||
$arr['h1'] = mb_convert_encoding($arr['h1'], 'UTF-8', 'HTML-ENTITIES');
|
||||
}
|
||||
// 获取副标题(倒序算法)
|
||||
// 偏移量
|
||||
$h2StrStart = '<br/>';
|
||||
$h2StrEnd = '</td><td rowspan="2" width="20"';
|
||||
$h2_offset = strpos($v,$h2StrEnd);
|
||||
$temp = substr($v, 0, $h2_offset);
|
||||
$h2_offset = strrpos($temp,$h2StrStart);
|
||||
#p($temp);
|
||||
if ($h2_offset === false ) {
|
||||
$arr['title'] = '';
|
||||
} else {
|
||||
$h2_len = strlen($temp) - $h2_offset - strlen($h2StrStart);
|
||||
//存在副标题
|
||||
$titleTemp = substr($temp, $h2_offset + strlen($h2StrStart), $h2_len);
|
||||
#p($titleTemp);
|
||||
//二次过滤
|
||||
$title = selector::remove($titleTemp, "//b");
|
||||
$title = selector::remove($title, "//span");
|
||||
// 精确适配标签 begin
|
||||
$titleSpan = '';
|
||||
$span = selector::select($titleTemp, '//span');
|
||||
if(!empty($span)){
|
||||
if(is_array($span)){
|
||||
foreach ( $span as $vv ){
|
||||
if( empty($vv) ){
|
||||
continue;
|
||||
}
|
||||
if ( strpos($vv,"</span>") != false ) {
|
||||
continue;
|
||||
}
|
||||
$titleSpan.='['.$vv.'] ';
|
||||
}
|
||||
}else{
|
||||
$titleSpan.='['.$span.'] ';
|
||||
}
|
||||
}
|
||||
// 精确适配标签 end
|
||||
$arr['title'] = $titleSpan . $title;
|
||||
}
|
||||
|
||||
// 组合返回数组
|
||||
self::$TorrentList[$k]['id'] = $arr['id'];
|
||||
self::$TorrentList[$k]['h1'] = $arr['h1'];
|
||||
self::$TorrentList[$k]['title'] = isset( $arr['title'] ) && $arr['title'] ? $arr['title'] : '';
|
||||
self::$TorrentList[$k]['details'] = self::HOST.self::detailsPrefix.$arr['id'];
|
||||
self::$TorrentList[$k]['download'] = self::HOST.$arr['url'];
|
||||
self::$TorrentList[$k]['filename'] = $arr['id'].'.torrent';
|
||||
|
||||
// 种子促销类型解码
|
||||
if(strpos($v,self::$getTorrent[0]) === false){
|
||||
// 不免费
|
||||
self::$TorrentList[$k]['type'] = 1;
|
||||
}else{
|
||||
// 免费种子
|
||||
self::$TorrentList[$k]['type'] = 0;
|
||||
}
|
||||
// 存活时间
|
||||
// 大小
|
||||
// 种子数
|
||||
// 下载数
|
||||
// 完成数
|
||||
// 完成进度
|
||||
}
|
||||
#p(self::$TorrentList);
|
||||
return self::$TorrentList;
|
||||
}
|
||||
}
|
3
app/beitai.php
Normal file
3
app/beitai.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Beitai::run();
|
3
app/brobits.php
Normal file
3
app/brobits.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Brobits::run();
|
3
app/btschool.php
Normal file
3
app/btschool.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Btschool::run();
|
3
app/chdbits.php
Normal file
3
app/chdbits.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Chdbits::run();
|
353
app/config/config.sample.php
Normal file
353
app/config/config.sample.php
Normal file
@ -0,0 +1,353 @@
|
||||
<?php
|
||||
/**
|
||||
* 技术讨论及后续更新,请加入QQ群!!!!!!!
|
||||
群名称:IYUU自动辅种交流
|
||||
QQ群号:859882209
|
||||
*/
|
||||
return array(
|
||||
// 1.爱语飞飞 微信通知配置
|
||||
'iyuu.cn' => 'IYUU',
|
||||
// 2.server酱 微信通知配置
|
||||
'sc.ftqq.com' => '',
|
||||
// 发布员鉴权
|
||||
'secret' => '',
|
||||
// 全局默认配置
|
||||
'default' => array(
|
||||
// 4.【必须配置】浏览器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',
|
||||
// 5.【可选配置】下载软件的监控目录(下载免费种时:工作模式0 必须配置,工作模式1 不用配置)
|
||||
'watch' => '/volume3/downloads/watch/',
|
||||
// 6.【可选配置】全局工作模式:0 watch优先[默认],1 负载均衡,2 混合模式(这里保持默认即可)
|
||||
'workingMode' => 0,
|
||||
// 7.【自动辅种必须配置】全局客户端设置(条目不够可以复制,用不到的请删除)
|
||||
'clients' => array(
|
||||
// 全局客户端设置 开始
|
||||
array(
|
||||
'type' => 'transmission', // 支持:transmission、qBittorrent
|
||||
'host' => 'http://127.0.0.1:9091/transmission/rpc',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'downloadDir' => '/volume2/dawei/mt', // 这个目录是默认下载目录,与自动辅种没有任何关系。
|
||||
//'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' => '',
|
||||
'downloadDir' => '', // 这个目录是默认下载目录,与自动辅种没有任何关系。
|
||||
),
|
||||
// 全局客户端设置 结束
|
||||
),
|
||||
// 8.下载过滤规则(目前仅对天空、我堡有效)
|
||||
'filter' => array(
|
||||
// 9.是否下载HR种子:0 不下载,1 下载
|
||||
'hr'=> 0,
|
||||
// 10.种子大小
|
||||
'size'=>array(
|
||||
'min' => '1GB',
|
||||
'max' => '280GB',
|
||||
),
|
||||
// 11.做种人数
|
||||
'seeders'=>array(
|
||||
'min' => 1,
|
||||
'max' => 3,
|
||||
),
|
||||
// 12.下载人数
|
||||
'leechers'=>array(
|
||||
'min' => 0,
|
||||
'max' => 10000,
|
||||
),
|
||||
// 13.完成人数
|
||||
'completed'=>array(
|
||||
'min' => 0,
|
||||
'max' => 10000,
|
||||
),
|
||||
),
|
||||
// 适配器,暂时用不到
|
||||
'adapter' => array(
|
||||
'free' => '',
|
||||
'2x' => '',
|
||||
'2xfree'=> '',
|
||||
'30%' => '',
|
||||
'50%' => '',
|
||||
'2x50%' => '',
|
||||
),
|
||||
'url' => array(
|
||||
'torrents.php',
|
||||
),
|
||||
'CONNECTTIMEOUT'=> 60,
|
||||
'TIMEOUT' => 600,
|
||||
),
|
||||
/**
|
||||
* 以下为各站点的独立配置(互不影响、互不冲突)
|
||||
* 1、自动辅种:需要配置各站的passkey(没有配置passkey的站点会自动跳过)
|
||||
* 2、可以根据各站自己的需要,按照馒头站的完整配置示例,自己补全!
|
||||
*/
|
||||
// m-team 序号:1
|
||||
'm-team' => array(
|
||||
// 14.m-team的cookie 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => 'tp=',
|
||||
// 15.m-team的passkey 【必须配置】
|
||||
'passkey' => '',
|
||||
// 16.站点单独使用的下载客户端配置(每个站点可以独立配置,不冲突)(条目不够可以复制,用不到的请删除)
|
||||
'clients' => array(
|
||||
array(
|
||||
'type' => 'transmission', // 支持:transmission、qBittorrent
|
||||
'host' => 'http://127.0.0.1:9091/transmission/rpc',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'downloadDir' => '/volume2/dawei/mt',
|
||||
),
|
||||
array(
|
||||
'type' => 'transmission',
|
||||
'host' => 'http://baidu.com:9092/transmission/rpc',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'downloadDir' => '/media/sony/qb',
|
||||
),
|
||||
array(
|
||||
'type' => 'qBittorrent',
|
||||
'host' => 'http://www.baidu.com:8083',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'downloadDir' => '',
|
||||
),
|
||||
),
|
||||
// 17.工作模式选择:0 watch优先[默认],1 负载均衡,2 混合模式
|
||||
'workingMode' => 1,
|
||||
),
|
||||
// keepfrds 序号:2
|
||||
'keepfrds' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// ourbits 序号:3
|
||||
'ourbits' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
'is_vip' => 0, // 是否具有VIP或特殊权限?0 普通,1 VIP
|
||||
),
|
||||
// HDSky 序号:4
|
||||
'hdsky' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// pter 序号:5
|
||||
'pter' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// tjupt 序号:6
|
||||
'tjupt' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// hdhome 序号:7
|
||||
'hdhome' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// btschool 序号:8
|
||||
'btschool' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// PTHome 序号:9
|
||||
'pthome' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// hddolby 序号:10
|
||||
'hddolby' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// TorrentCCF 序号:11
|
||||
'torrentccf' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// PTMSG 序号:12
|
||||
'ptmsg' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// MoeCat 序号:13
|
||||
'moecat' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// totheglory 序号:14
|
||||
'ttg' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// nanyangpt 序号:15
|
||||
'nanyangpt' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// springsunday.net 序号:16
|
||||
'ssd' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// yingk 序号:17
|
||||
'yingk' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// hdcity 序号:18
|
||||
'hdcity' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// 52pt.site 序号:19
|
||||
'52pt' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// brobits.cc 序号:20
|
||||
'brobits' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// www.beitai.pt 序号:21
|
||||
'beitai' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// pt.eastgame.org 序号:22
|
||||
'eastgame' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// pt.soulvoice.club 序号:23
|
||||
'soulvoice' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// chdbits 序号:24
|
||||
'chdbits' => array(
|
||||
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
|
||||
'cookie' => '',
|
||||
// 如果需要自动辅种,必须配置
|
||||
'passkey' => '',
|
||||
),
|
||||
// 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' => '',
|
||||
),
|
||||
|
||||
// 配置文件结束
|
||||
);
|
1
app/config/version.php
Normal file
1
app/config/version.php
Normal file
@ -0,0 +1 @@
|
||||
<?php return '20191221.1920';
|
3
app/eastgame.php
Normal file
3
app/eastgame.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Eastgame::run();
|
3
app/hd4fans.php
Normal file
3
app/hd4fans.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
hd4fans::run();
|
3
app/hdarea.php
Normal file
3
app/hdarea.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Hdarea::run();
|
3
app/hdbug.php
Normal file
3
app/hdbug.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
hdbug::run();
|
3
app/hddolby.php
Normal file
3
app/hddolby.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Hddolby::run();
|
3
app/hdhome.php
Normal file
3
app/hdhome.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Hdhome::run();
|
3
app/hdsky.php
Normal file
3
app/hdsky.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Hdsky::run();
|
3
app/hdtime.php
Normal file
3
app/hdtime.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Hdtime::run();
|
57
app/init.php
Normal file
57
app/init.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
//----------------------------------
|
||||
// 公共入口文件
|
||||
//----------------------------------
|
||||
// 定义目录
|
||||
defined('ROOT_PATH') or define("ROOT_PATH", dirname(__DIR__));
|
||||
defined('APP_PATH') or define('APP_PATH', __DIR__);
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('TORRENT_PATH', APP_PATH.DS.'torrent'.DS);
|
||||
|
||||
// 严格开发模式
|
||||
error_reporting( E_ALL );
|
||||
#ini_set('display_errors', 1);
|
||||
|
||||
// 永不超时
|
||||
ini_set('max_execution_time', 0);
|
||||
set_time_limit(0);
|
||||
// 内存限制,如果外面设置的内存比 /etc/php/php-cli.ini 大,就不要设置了
|
||||
if (intval(ini_get("memory_limit")) < 1024)
|
||||
{
|
||||
ini_set('memory_limit', '1024M');
|
||||
}
|
||||
|
||||
if( PHP_SAPI != 'cli' )
|
||||
{
|
||||
exit("You must run the CLI environment\n");
|
||||
}
|
||||
|
||||
// 设置时区
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
// 系统配置
|
||||
if( file_exists( APP_PATH."/config/config.php" ) )
|
||||
{
|
||||
// 配置(全局变量)
|
||||
$configALL = require_once APP_PATH."/config/config.php";
|
||||
}else{
|
||||
// 示例配置
|
||||
$configALL = require_once APP_PATH . '/config/config.sample.php';
|
||||
}
|
||||
|
||||
require_once ROOT_PATH . '/vendor/autoload.php';
|
||||
require_once APP_PATH . '/Class/File.php'; // 文件操作类
|
||||
require_once APP_PATH . '/Class/Function.php'; // 函数
|
||||
require_once APP_PATH . '/Class/Rpc.php'; // RPC操作类
|
||||
require_once APP_PATH . '/Class/TransmissionRPC.class.php'; // transmission
|
||||
require_once APP_PATH . '/Class/qBittorrent.php'; // qBittorrent
|
||||
require_once APP_PATH . '/Class/uTorrent.php'; // uTorrent
|
||||
require_once APP_PATH . '/Class/Bencode.php'; // Bencode编码Bittorrent种子操作类
|
||||
|
||||
function auto_load($classname) {
|
||||
set_include_path(APP_PATH.'/Protocols/');
|
||||
spl_autoload($classname);
|
||||
}
|
||||
|
||||
spl_autoload_extensions('.php');
|
||||
spl_autoload_register('auto_load');
|
3
app/keepfrds.php
Normal file
3
app/keepfrds.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Keepfrds::run();
|
3
app/leaguehd.php
Normal file
3
app/leaguehd.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Leaguehd::run();
|
3
app/m-team.php
Normal file
3
app/m-team.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Mteam::run();
|
3
app/moecat.php
Normal file
3
app/moecat.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Moecat::run();
|
3
app/nanyangpt.php
Normal file
3
app/nanyangpt.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Nanyangpt::run();
|
3
app/opencd.php
Normal file
3
app/opencd.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
opencd::run();
|
3
app/ourbits.php
Normal file
3
app/ourbits.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Ourbits::run();
|
3
app/ptba.php
Normal file
3
app/ptba.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
ptba::run();
|
3
app/pterclub.php
Normal file
3
app/pterclub.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Pterclub::run();
|
3
app/pthome.php
Normal file
3
app/pthome.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Pthome::run();
|
3
app/ptmsg.php
Normal file
3
app/ptmsg.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Ptmsg::run();
|
3
app/ptsbao.php
Normal file
3
app/ptsbao.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Ptsbao::run();
|
3
app/site52pt.php
Normal file
3
app/site52pt.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Site52pt::run();
|
3
app/soulvoice.php
Normal file
3
app/soulvoice.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
soulvoice::run();
|
3
app/ssd.php
Normal file
3
app/ssd.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Ssd::run();
|
3
app/tjupt.php
Normal file
3
app/tjupt.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Tjupt::run();
|
3
app/torrentccf.php
Normal file
3
app/torrentccf.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Torrentccf::run();
|
3
app/totheglory.php
Normal file
3
app/totheglory.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Totheglory::run();
|
3
app/yingk.php
Normal file
3
app/yingk.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/init.php';
|
||||
Yingk::run();
|
6
composer.json
Normal file
6
composer.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"require": {
|
||||
"owner888/phpspider": "^2.1",
|
||||
"curl/curl": "^2.2"
|
||||
}
|
||||
}
|
131
composer.lock
generated
Normal file
131
composer.lock
generated
Normal file
@ -0,0 +1,131 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "32806a4860870f6306b69cf349584387",
|
||||
"packages": [
|
||||
{
|
||||
"name": "curl/curl",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-mod/curl.git",
|
||||
"reference": "d22086dd2eee5ca02e4c29b9a5bdf3645bfdbbff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-mod/curl/zipball/d22086dd2eee5ca02e4c29b9a5bdf3645bfdbbff",
|
||||
"reference": "d22086dd2eee5ca02e4c29b9a5bdf3645bfdbbff",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"php": "^5.6 | ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"squizlabs/php_codesniffer": "~2.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Curl": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Hassan Amouhzi",
|
||||
"email": "hassan@anezi.net",
|
||||
"homepage": "http://hassan.amouhzi.com"
|
||||
},
|
||||
{
|
||||
"name": "php-curl-class",
|
||||
"homepage": "https://github.com/php-curl-class"
|
||||
},
|
||||
{
|
||||
"name": "user52",
|
||||
"homepage": "https://github.com/user52"
|
||||
}
|
||||
],
|
||||
"description": "cURL class for PHP",
|
||||
"homepage": "https://github.com/php-mod/curl",
|
||||
"keywords": [
|
||||
"curl",
|
||||
"dot"
|
||||
],
|
||||
"time": "2018-12-04T19:47:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "owner888/phpspider",
|
||||
"version": "v2.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/owner888/phpspider.git",
|
||||
"reference": "e6021148adec201418c16ba26f39bc013ba5b4d9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/owner888/phpspider/zipball/e6021148adec201418c16ba26f39bc013ba5b4d9",
|
||||
"reference": "e6021148adec201418c16ba26f39bc013ba5b4d9",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcntl、ext-redis": "For better performance. "
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpspider\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Seatle Yang",
|
||||
"email": "seatle@foxmail.com",
|
||||
"homepage": "http://www.phpspider.org",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "The PHPSpider Framework.",
|
||||
"homepage": "http://www.phpspider.org",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"phpspider"
|
||||
],
|
||||
"time": "2018-08-15T08:04:29+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": []
|
||||
}
|
401
iyuu.cn.php
Normal file
401
iyuu.cn.php
Normal file
@ -0,0 +1,401 @@
|
||||
<?php
|
||||
/**
|
||||
* IYUU自动辅种脚本
|
||||
*/
|
||||
use Curl\Curl;
|
||||
require_once __DIR__ . '/app/init.php';
|
||||
iyuuAutoReseed::init();
|
||||
$hashArray = iyuuAutoReseed::get();
|
||||
if ( iyuuAutoReseed::$move != null ) {
|
||||
echo "种子移动完毕,请重新编辑配置,再尝试辅种! \n\n";
|
||||
exit;
|
||||
}
|
||||
iyuuAutoReseed::call($hashArray);
|
||||
/**
|
||||
* iyuu自动辅种类
|
||||
*/
|
||||
class iyuuAutoReseed
|
||||
{
|
||||
/**
|
||||
* 版本号
|
||||
* @var string
|
||||
*/
|
||||
const VER = '2019年12月21日20:26:48';
|
||||
// RPC连接池
|
||||
public static $links = array();
|
||||
/**
|
||||
* 客户端配置
|
||||
*/
|
||||
public static $clients = array();
|
||||
/**
|
||||
* 不辅种的站点
|
||||
*/
|
||||
public static $noReseed = ['ourbits','hdchina'];
|
||||
/**
|
||||
* 缓存路径
|
||||
*/
|
||||
public static $cacheDir = TORRENT_PATH.'cache'.DS;
|
||||
/**
|
||||
* API接口配置
|
||||
*/
|
||||
public static $apiUrl = 'http://iyuu.cn:2122';
|
||||
public static $endpoints = array(
|
||||
'add' => '/api/add',
|
||||
'update' => '/api/update',
|
||||
'reseed' => '/api/reseed',
|
||||
);
|
||||
/**
|
||||
* 退出状态码
|
||||
*/
|
||||
public static $ExitCode = 0;
|
||||
/**
|
||||
* 客户端转移做种 状态码[请把transmission配置为第一个客户端]
|
||||
*/
|
||||
public static $move = null;
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
public static function init(){
|
||||
global $configALL;
|
||||
|
||||
self::$clients = isset($configALL['default']['clients']) && $configALL['default']['clients'] ? $configALL['default']['clients'] : array();
|
||||
// 递归删除上次历史记录
|
||||
IFile::rmdir(self::$cacheDir, true);
|
||||
// 建立目录
|
||||
IFile::mkdir(self::$cacheDir);
|
||||
self::links();
|
||||
}
|
||||
/**
|
||||
* 连接远端RPC服务器
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function links()
|
||||
{
|
||||
if(empty(self::$links)){
|
||||
foreach ( self::$clients as $k => $v ){
|
||||
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;
|
||||
default:
|
||||
echo '[ERROR] '.$v['type'];
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
self::$links[$k]['type'] = $v['type'];
|
||||
#self::$links[$k]['downloadDir'] = $v['downloadDir'];
|
||||
// 检查是否转移种子的做种客户端?
|
||||
if ( isset($v['move']) && $v['move'] ) {
|
||||
self::$move = array($k,$v['type']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo '[ERROR] ' . $e->getMessage() . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 从客户端获取种子的哈希列表
|
||||
*/
|
||||
public static function get(){
|
||||
$hashArray = array();
|
||||
foreach ( self::$clients as $k => $v ){
|
||||
$result = array();
|
||||
$res = $info_hash = array();
|
||||
$json = $sha1 = '';
|
||||
try
|
||||
{
|
||||
switch($v['type']){
|
||||
case 'transmission':
|
||||
$ids = $fields = array();
|
||||
#$fields = array( "id", "status", "name", "hashString", "downloadDir", "torrentFile" );
|
||||
$fields = array( "id", "status", "hashString", "downloadDir");
|
||||
$result = self::$links[$k]['rpc']->get($ids, $fields);
|
||||
if ( empty($result->result) || $result->result != 'success' ){
|
||||
// 获取种子列表 失败
|
||||
echo "获取种子列表失败,原因可能是transmission暂时无响应,请稍后重试! \n";
|
||||
break;
|
||||
}
|
||||
if( empty($result->arguments) ){
|
||||
echo "未获取到需要辅种的数据,请多多保种,然后重试! \n";
|
||||
break;
|
||||
}
|
||||
// 对象转数组
|
||||
$res = object_array($result->arguments->torrents);
|
||||
// 过滤,只保留正常做种
|
||||
$res = array_filter($res, "filterStatus");
|
||||
// 提取数组:hashString
|
||||
$info_hash = array_column($res, 'hashString');
|
||||
// 升序排序
|
||||
sort($info_hash);
|
||||
$json = json_encode($info_hash, JSON_UNESCAPED_UNICODE);
|
||||
// 去重 应该从文件读入,防止重复提交
|
||||
$sha1 = sha1( $json );
|
||||
if ( isset($hashArray['sha1']) && (in_array($sha1, $hashArray['sha1']) != false) ) {
|
||||
break;
|
||||
}
|
||||
// 组装返回数据
|
||||
$hashArray['hash']['clients_'.$k] = $json;
|
||||
$hashArray['sha1'][] = $sha1;
|
||||
// 变换数组:hashString为键
|
||||
self::$links[$k]['hash'] = array_column($res, "downloadDir", 'hashString');
|
||||
#p(self::$links[$k]['hash']);exit;
|
||||
break;
|
||||
case 'qBittorrent':
|
||||
$result = self::$links[$k]['rpc']->torrentList();
|
||||
$res = json_decode($result,true);
|
||||
if ( empty($res) ) {
|
||||
echo "未获取到需要辅种的数据,请多多保种,然后重试! \n";
|
||||
break;
|
||||
}
|
||||
#p($res);exit;
|
||||
// 过滤,只保留正常做种
|
||||
$res = array_filter($res, "qbfilterStatus");
|
||||
// 提取数组:hashString
|
||||
$info_hash = array_column($res, 'hash');
|
||||
// 升序排序
|
||||
sort($info_hash);
|
||||
$json = json_encode($info_hash, JSON_UNESCAPED_UNICODE);
|
||||
// 去重 应该从文件读入,防止重复提交
|
||||
$sha1 = sha1( $json );
|
||||
if ( isset($hashArray['sha1']) && (in_array($sha1, $hashArray['sha1']) != false) ) {
|
||||
break;
|
||||
}
|
||||
// 组装返回数据
|
||||
$hashArray['hash']['clients_'.$k] = $json;
|
||||
$hashArray['sha1'][] = $sha1;
|
||||
// 变换数组:hash为键
|
||||
self::$links[$k]['hash'] = array_column($res, "save_path", 'hash');
|
||||
#p(self::$links[$k]['hash']);exit;
|
||||
break;
|
||||
default:
|
||||
echo '[ERROR] '.$v['type'];
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
// 是否执行转移种子做种客户端?
|
||||
if ( self::$move != null && (empty($v['move'])) ) {
|
||||
self::move($res, $v['type']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo '[ERROR] ' . $e->getMessage() . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// 写日志:文件句柄
|
||||
$resource = fopen(self::$cacheDir.'hashString.txt', "wb");
|
||||
// 成功:返回写入字节数,失败返回false
|
||||
$worldsnum = fwrite($resource, p($hashArray, false));
|
||||
fclose($resource);
|
||||
return $hashArray;
|
||||
}
|
||||
/**
|
||||
* @brief 添加下载任务
|
||||
* @param string $torrent 种子元数据
|
||||
* @param string $save_path 保存路径
|
||||
* @return bool
|
||||
*/
|
||||
public static function add($rpcKey, $torrent, $save_path = '', $extra_options = array())
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = self::$links[$rpcKey]['rpc']->add( $torrent, $save_path, $extra_options ); // 种子URL添加下载任务
|
||||
// 调试
|
||||
#p($result);
|
||||
// 下载服务器类型 判断
|
||||
switch(self::$links[$rpcKey]['type']){
|
||||
case 'transmission':
|
||||
if(isset($result->result) && $result->result == 'success'){
|
||||
$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;
|
||||
}
|
||||
print "********RPC添加下载任务成功 [{$result->result}] (id=$id) \n";
|
||||
print "种子:".$torrent. "\n";
|
||||
print "名字:".$name."\n\n";
|
||||
return true;
|
||||
}else{
|
||||
$errmsg = isset($result->result) ? $result->result : '未知错误,请稍后重试!';
|
||||
print "-----RPC添加种子任务,失败 [{$errmsg}] \n";
|
||||
print "种子:".$torrent. "\n";
|
||||
}
|
||||
break;
|
||||
case 'qBittorrent':
|
||||
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) {
|
||||
echo '[ERROR] ' . $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @brief 提交种子hash给远端API,用来获取辅种数据
|
||||
* @param array $hashArray 种子hash数组
|
||||
* @return
|
||||
*/
|
||||
public static function call($hashArray = array())
|
||||
{
|
||||
global $configALL;
|
||||
|
||||
$resArray = $sites = array();
|
||||
$curl = new Curl();
|
||||
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
|
||||
// 签名
|
||||
$hashArray['timestamp'] = time();
|
||||
$hashArray['sign'] = sign($hashArray['timestamp']);
|
||||
// 发起请求
|
||||
echo "正在提交辅种信息…… \n";
|
||||
$res = $curl->post(self::$apiUrl . self::$endpoints['reseed'], $hashArray);
|
||||
|
||||
$resArray = json_decode($res->response, true);
|
||||
// 写日志
|
||||
if(true){
|
||||
// 文件句柄
|
||||
$resource = fopen(self::$cacheDir.'reseed.txt', "wb");
|
||||
// 成功:返回写入字节数,失败返回false
|
||||
$worldsnum = fwrite($resource, p($resArray, false));
|
||||
fclose($resource);
|
||||
}
|
||||
// 判断返回值
|
||||
if ( isset($resArray['errmsg']) && ($resArray['errmsg'] == 'ok') ) {
|
||||
echo "辅种信息提交成功!!! \n\n";
|
||||
}else{
|
||||
$errmsg = isset($resArray['errmsg']) ? $resArray['errmsg'] : '远端服务器无响应,请稍后重试!';
|
||||
echo '-----辅种失败,原因:' .$errmsg. " \n\n";
|
||||
exit(1);
|
||||
}
|
||||
// 可辅种站点信息列表
|
||||
$sites = $resArray['sites'];
|
||||
#p($sites);
|
||||
foreach (self::$links as $k => $v) {
|
||||
$reseed = $infohash_Dir = array();
|
||||
if (empty($resArray['clients_'.$k])) {
|
||||
echo "clients_".$k."没有查询到可辅种数据 \n\n";
|
||||
continue;
|
||||
}
|
||||
$reseed = $resArray['clients_'.$k];
|
||||
// info_hash 对应的下载目录
|
||||
$infohash_Dir = self::$links[$k]['hash'];
|
||||
foreach ($reseed as $info_hash => $vv) {
|
||||
$downloadDir = $infohash_Dir[$info_hash];
|
||||
foreach ($vv['torrent'] as $id => $value) {
|
||||
$sitesID = $value['sid'];
|
||||
$url = $_url = '';
|
||||
$download_page = '';
|
||||
$download_page = str_replace('{}', $value['torrent_id'], $sites[$sitesID]['download_page']);
|
||||
$_url = 'https://' .$sites[$sitesID]['base_url']. '/' .$download_page;
|
||||
if (empty($configALL[$sites[$sitesID]['site']]['passkey'])) {
|
||||
echo '-------因当前' .$sites[$sitesID]['site']. '站点未设置passkey,已跳过!!' . "\n\n";
|
||||
continue;
|
||||
}
|
||||
// 种子URL组合方式区分
|
||||
switch ($sites[$sitesID]['site']) {
|
||||
case 'ttg':
|
||||
$url = $_url."/". $configALL[$sites[$sitesID]['site']]['passkey'];
|
||||
break;
|
||||
case 'm-team':
|
||||
$url = $_url."&passkey=". $configALL[$sites[$sitesID]['site']]['passkey'] ."&https=1";
|
||||
break;
|
||||
// case 'hdchina':
|
||||
// break;
|
||||
default:
|
||||
$url = $_url."&passkey=". $configALL[$sites[$sitesID]['site']]['passkey'];
|
||||
break;
|
||||
}
|
||||
// 检查不辅种的站点
|
||||
// 判断是否VIP/特殊权限?
|
||||
$is_vip = isset($configALL[$sites[$sitesID]['site']]['is_vip']) && $configALL[$sites[$sitesID]['site']]['is_vip'] ? 1 : 0;
|
||||
if ( (in_array($sites[$sitesID]['site'], self::$noReseed)==false) || $is_vip ) {
|
||||
// 可以辅种
|
||||
if ( isset($infohash_Dir[$value['info_hash']]) ) {
|
||||
// 与客户端现有种子重复
|
||||
echo '-------与客户端现有种子重复:'.$_url."\n\n";
|
||||
}else{
|
||||
// 把拼接的种子URL,推送给下载器
|
||||
self::add($k, $url, $downloadDir);
|
||||
}
|
||||
}else{
|
||||
// 不辅种
|
||||
echo '-------已跳过不辅种的站点:'.$_url."\n\n";
|
||||
// 写入日志文件,供用户手动辅种
|
||||
if ( !isset($infohash_Dir[$value['info_hash']]) ) {
|
||||
// 文件句柄
|
||||
$resource = fopen(self::$cacheDir . $sites[$sitesID]['site'].'.txt', 'a');
|
||||
// 成功:返回写入字节数,失败返回false
|
||||
$worldsnum = fwrite($resource, $downloadDir."\n".$url."\n\n");
|
||||
fclose($resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static function move($torrent=array(), $type = 'qBittorrent'){
|
||||
switch($type){
|
||||
case 'transmission':
|
||||
break;
|
||||
case 'qBittorrent':
|
||||
foreach ($torrent as $k => $v) {
|
||||
#$v['save_path'] = '/volume3' . $v['save_path']; // docker路径转换
|
||||
self::add(self::$move[0], $v['magnet_uri'], $v['save_path'] );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '[ERROR] '.$type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// transmission过滤函数,只保留正常做种
|
||||
function filterStatus( $v ){
|
||||
return isset($v['status']) && $v['status']===6;
|
||||
}
|
||||
// qBittorrent过滤函数,只保留正常做种
|
||||
function qbfilterStatus( $v ){
|
||||
if( ($v['state']=='uploading') || ($v['state'] == 'stalledUP') ){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//PHP stdClass Object转array
|
||||
function object_array($array) {
|
||||
if(is_object($array)) {
|
||||
$array = (array)$array;
|
||||
}
|
||||
if(is_array($array)) {
|
||||
foreach($array as $key=>$value) {
|
||||
$array[$key] = object_array($value);
|
||||
}
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
// 对象转数组
|
||||
function object2array(&$object) {
|
||||
return json_decode( json_encode( $object ), true );
|
||||
}
|
7
vendor/autoload.php
vendored
Normal file
7
vendor/autoload.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit902220bdd481fe56c25750cdf0255dd6::getLoader();
|
445
vendor/composer/ClassLoader.php
vendored
Normal file
445
vendor/composer/ClassLoader.php
vendored
Normal file
@ -0,0 +1,445 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
private $classMapAuthoritative = false;
|
||||
private $missingClasses = array();
|
||||
private $apcuPrefix;
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
21
vendor/composer/LICENSE
vendored
Normal file
21
vendor/composer/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
9
vendor/composer/autoload_classmap.php
vendored
Normal file
9
vendor/composer/autoload_classmap.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
10
vendor/composer/autoload_namespaces.php
vendored
Normal file
10
vendor/composer/autoload_namespaces.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Curl' => array($vendorDir . '/curl/curl/src'),
|
||||
);
|
10
vendor/composer/autoload_psr4.php
vendored
Normal file
10
vendor/composer/autoload_psr4.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'phpspider\\' => array($vendorDir . '/owner888/phpspider'),
|
||||
);
|
52
vendor/composer/autoload_real.php
vendored
Normal file
52
vendor/composer/autoload_real.php
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit902220bdd481fe56c25750cdf0255dd6
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit902220bdd481fe56c25750cdf0255dd6', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit902220bdd481fe56c25750cdf0255dd6', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit902220bdd481fe56c25750cdf0255dd6::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
42
vendor/composer/autoload_static.php
vendored
Normal file
42
vendor/composer/autoload_static.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit902220bdd481fe56c25750cdf0255dd6
|
||||
{
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'p' =>
|
||||
array (
|
||||
'phpspider\\' => 10,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'phpspider\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/owner888/phpspider',
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixesPsr0 = array (
|
||||
'C' =>
|
||||
array (
|
||||
'Curl' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/curl/curl/src',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit902220bdd481fe56c25750cdf0255dd6::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit902220bdd481fe56c25750cdf0255dd6::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInit902220bdd481fe56c25750cdf0255dd6::$prefixesPsr0;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
119
vendor/composer/installed.json
vendored
Normal file
119
vendor/composer/installed.json
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
[
|
||||
{
|
||||
"name": "curl/curl",
|
||||
"version": "2.2.0",
|
||||
"version_normalized": "2.2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-mod/curl.git",
|
||||
"reference": "d22086dd2eee5ca02e4c29b9a5bdf3645bfdbbff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-mod/curl/zipball/d22086dd2eee5ca02e4c29b9a5bdf3645bfdbbff",
|
||||
"reference": "d22086dd2eee5ca02e4c29b9a5bdf3645bfdbbff",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"php": "^5.6 | ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"squizlabs/php_codesniffer": "~2.1"
|
||||
},
|
||||
"time": "2018-12-04T19:47:03+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Curl": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Hassan Amouhzi",
|
||||
"email": "hassan@anezi.net",
|
||||
"homepage": "http://hassan.amouhzi.com"
|
||||
},
|
||||
{
|
||||
"name": "php-curl-class",
|
||||
"homepage": "https://github.com/php-curl-class"
|
||||
},
|
||||
{
|
||||
"name": "user52",
|
||||
"homepage": "https://github.com/user52"
|
||||
}
|
||||
],
|
||||
"description": "cURL class for PHP",
|
||||
"homepage": "https://github.com/php-mod/curl",
|
||||
"keywords": [
|
||||
"curl",
|
||||
"dot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "owner888/phpspider",
|
||||
"version": "v2.1.6",
|
||||
"version_normalized": "2.1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/owner888/phpspider.git",
|
||||
"reference": "e6021148adec201418c16ba26f39bc013ba5b4d9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/owner888/phpspider/zipball/e6021148adec201418c16ba26f39bc013ba5b4d9",
|
||||
"reference": "e6021148adec201418c16ba26f39bc013ba5b4d9",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcntl、ext-redis": "For better performance. "
|
||||
},
|
||||
"time": "2018-08-15T08:04:29+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpspider\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Seatle Yang",
|
||||
"email": "seatle@foxmail.com",
|
||||
"homepage": "http://www.phpspider.org",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "The PHPSpider Framework.",
|
||||
"homepage": "http://www.phpspider.org",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"phpspider"
|
||||
]
|
||||
}
|
||||
]
|
11
vendor/curl/curl/.gitignore
vendored
Normal file
11
vendor/curl/curl/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
vendor/*
|
||||
*.orig
|
||||
.buildpath
|
||||
.project
|
||||
.settings/*
|
||||
.idea/*
|
||||
composer.lock
|
||||
*~
|
||||
tests/phpunit_report/*
|
||||
/.settings/
|
||||
/.php_cs.cache
|
113
vendor/curl/curl/.gitlab-ci.yml
vendored
Normal file
113
vendor/curl/curl/.gitlab-ci.yml
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
build-test-server:
|
||||
image: docker:latest
|
||||
stage: build
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
|
||||
- docker build --pull -t "$CI_REGISTRY_IMAGE:server-test" tests/server
|
||||
- docker push "$CI_REGISTRY_IMAGE:server-test"
|
||||
only:
|
||||
changes:
|
||||
- tests/server
|
||||
|
||||
tests-php5.6:
|
||||
image: alpine:3.7
|
||||
stage: test
|
||||
services:
|
||||
- name: "$CI_REGISTRY_IMAGE:server-test"
|
||||
alias: server_test
|
||||
script:
|
||||
- apk add --no-cache php5-cli php5-curl php5-gd php5-phar php5-json php5-openssl php5-dom php5-xml php5-zlib
|
||||
- ln -s /usr/bin/php5 /usr/bin/php
|
||||
- php --version
|
||||
- if [ ! -f composer.phar ]; then DOWLOAD_COMPOSER=1 ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "if (hash_file('sha384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php composer-setup.php ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "unlink('composer-setup.php');" ; fi;
|
||||
- php composer.phar install
|
||||
- vendor/bin/phpcs --warning-severity=0 --standard=PSR2 src
|
||||
- vendor/bin/phpunit
|
||||
cache:
|
||||
key: php5.6
|
||||
paths:
|
||||
- composer.phar
|
||||
- vendor
|
||||
|
||||
tests-php7.0:
|
||||
image: alpine:3.5
|
||||
stage: test
|
||||
services:
|
||||
- name: "$CI_REGISTRY_IMAGE:server-test"
|
||||
alias: server_test
|
||||
script:
|
||||
- apk add --no-cache php7 php7-curl php7-gd php7-phar php7-json php7-openssl php7-dom php7-mbstring
|
||||
- ln -s /usr/bin/php7 /usr/bin/php
|
||||
- php --version
|
||||
- if [ ! -f composer.phar ]; then DOWLOAD_COMPOSER=1 ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "if (hash_file('sha384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php composer-setup.php ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "unlink('composer-setup.php');" ; fi;
|
||||
- php composer.phar install
|
||||
- vendor/bin/phpcs --warning-severity=0 --standard=PSR2 src
|
||||
- nohup php -S localhost:8000 -t tests/server/php-curl-test > phpd.log 2>&1 &
|
||||
- vendor/bin/phpunit
|
||||
cache:
|
||||
key: php7.0
|
||||
paths:
|
||||
- composer.phar
|
||||
- vendor
|
||||
|
||||
tests-php7.1:
|
||||
image: alpine:3.7
|
||||
stage: test
|
||||
services:
|
||||
- name: "$CI_REGISTRY_IMAGE:server-test"
|
||||
alias: server_test
|
||||
script:
|
||||
- apk add --no-cache php7-cli php7-curl php7-gd php7-phar php7-json php7-openssl php7-dom php7-simplexml php7-tokenizer php7-mbstring php7-xml
|
||||
- php --version
|
||||
- if [ ! -f composer.phar ]; then DOWLOAD_COMPOSER=1 ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "if (hash_file('sha384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php composer-setup.php ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "unlink('composer-setup.php');" ; fi;
|
||||
- php composer.phar install
|
||||
- vendor/bin/phpcs --warning-severity=0 --standard=PSR2 src
|
||||
- nohup php -S localhost:8000 -t tests/server/php-curl-test > phpd.log 2>&1 &
|
||||
- vendor/bin/phpunit
|
||||
cache:
|
||||
key: php7.1
|
||||
paths:
|
||||
- composer.phar
|
||||
- vendor
|
||||
|
||||
tests-php7.2:
|
||||
image: alpine:3.8
|
||||
stage: test
|
||||
services:
|
||||
- name: "$CI_REGISTRY_IMAGE:server-test"
|
||||
alias: server_test
|
||||
script:
|
||||
- apk add --no-cache php7-cli php7-curl php7-gd php7-phar php7-json php7-openssl php7-dom php7-simplexml php7-tokenizer php7-mbstring php7-xml
|
||||
- php --version
|
||||
- if [ ! -f composer.phar ]; then DOWLOAD_COMPOSER=1 ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "if (hash_file('sha384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php composer-setup.php ; fi;
|
||||
- if [ -n "$DOWLOAD_COMPOSER" ] ; then php -r "unlink('composer-setup.php');" ; fi;
|
||||
- php composer.phar install
|
||||
- vendor/bin/phpcs --warning-severity=0 --standard=PSR2 src
|
||||
- nohup php -S localhost:8000 -t tests/server/php-curl-test > phpd.log 2>&1 &
|
||||
- vendor/bin/phpunit
|
||||
cache:
|
||||
key: php7.2
|
||||
paths:
|
||||
- composer.phar
|
||||
- vendor
|
20
vendor/curl/curl/LICENSE
vendored
Normal file
20
vendor/curl/curl/LICENSE
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 php-mod
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
125
vendor/curl/curl/README.md
vendored
Normal file
125
vendor/curl/curl/README.md
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
# PHP Curl Class
|
||||
|
||||
This library provides an object-oriented wrapper of the PHP cURL extension.
|
||||
|
||||
If you have questions or problems with installation or usage [create an Issue](https://github.com/php-mod/curl/issues).
|
||||
|
||||
## Installation
|
||||
|
||||
In order to install this library via composer run the following command in the console:
|
||||
|
||||
```sh
|
||||
composer require curl/curl
|
||||
```
|
||||
|
||||
or add the package manually to your composer.json file in the require section:
|
||||
|
||||
```json
|
||||
"curl/curl": "^2.0"
|
||||
```
|
||||
|
||||
## Usage examples
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->get('http://www.example.com/');
|
||||
```
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->get('http://www.example.com/search', array(
|
||||
'q' => 'keyword',
|
||||
));
|
||||
```
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->post('http://www.example.com/login/', array(
|
||||
'username' => 'myusername',
|
||||
'password' => 'mypassword',
|
||||
));
|
||||
```
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->setBasicAuthentication('username', 'password');
|
||||
$curl->setUserAgent('');
|
||||
$curl->setReferrer('');
|
||||
$curl->setHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
$curl->setCookie('key', 'value');
|
||||
$curl->get('http://www.example.com/');
|
||||
|
||||
if ($curl->error) {
|
||||
echo $curl->error_code;
|
||||
}
|
||||
else {
|
||||
echo $curl->response;
|
||||
}
|
||||
|
||||
var_dump($curl->request_headers);
|
||||
var_dump($curl->response_headers);
|
||||
```
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->setOpt(CURLOPT_RETURNTRANSFER, TRUE);
|
||||
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
$curl->get('https://encrypted.example.com/');
|
||||
```
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->put('http://api.example.com/user/', array(
|
||||
'first_name' => 'Zach',
|
||||
'last_name' => 'Borboa',
|
||||
));
|
||||
```
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->patch('http://api.example.com/profile/', array(
|
||||
'image' => '@path/to/file.jpg',
|
||||
));
|
||||
```
|
||||
|
||||
```php
|
||||
$curl = new Curl\Curl();
|
||||
$curl->delete('http://api.example.com/user/', array(
|
||||
'id' => '1234',
|
||||
));
|
||||
```
|
||||
|
||||
```php
|
||||
$curl->close();
|
||||
```
|
||||
|
||||
```php
|
||||
// Example access to curl object.
|
||||
curl_set_opt($curl->curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1');
|
||||
curl_close($curl->curl);
|
||||
```
|
||||
|
||||
```php
|
||||
// Example of downloading a file or any other content
|
||||
$curl = new Curl\Curl();
|
||||
// open the file where the request response should be written
|
||||
$file_handle = fopen($target_file, 'w+');
|
||||
// pass it to the curl resource
|
||||
$curl->setOpt(CURLOPT_FILE, $file_handle);
|
||||
// do any type of request
|
||||
$curl->get('https://github.com');
|
||||
// disable writing to file
|
||||
$curl->setOpt(CURLOPT_FILE, null);
|
||||
// close the file for writing
|
||||
fclose($file_handle);
|
||||
```
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
In order to test the library:
|
||||
|
||||
1. Create a fork
|
||||
2. Clone the fork to your machine
|
||||
3. Install the depencies `composer install`
|
||||
4. Run the unit tests `./vendor/bin/phpunit tests`
|
36
vendor/curl/curl/composer.json
vendored
Normal file
36
vendor/curl/curl/composer.json
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "curl/curl",
|
||||
"description": "cURL class for PHP",
|
||||
"keywords": ["dot", "curl"],
|
||||
"homepage": "https://github.com/php-mod/curl",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "php-curl-class",
|
||||
"homepage": "https://github.com/php-curl-class"
|
||||
},
|
||||
{
|
||||
"name": "Hassan Amouhzi",
|
||||
"email": "hassan@anezi.net",
|
||||
"homepage": "http://hassan.amouhzi.com"
|
||||
},
|
||||
{
|
||||
"name": "user52",
|
||||
"homepage": "https://github.com/user52"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.6 | ^7.0",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"squizlabs/php_codesniffer": "~2.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Curl": "src/"
|
||||
}
|
||||
}
|
||||
}
|
24
vendor/curl/curl/phpunit.xml.dist
vendored
Normal file
24
vendor/curl/curl/phpunit.xml.dist
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="true"
|
||||
verbose="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
>
|
||||
<php>
|
||||
<ini name="display_errors" value="on"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="PHP MP4Box Tests Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
</phpunit>
|
719
vendor/curl/curl/src/Curl/Curl.php
vendored
Normal file
719
vendor/curl/curl/src/Curl/Curl.php
vendored
Normal file
@ -0,0 +1,719 @@
|
||||
<?php
|
||||
|
||||
namespace Curl;
|
||||
|
||||
/**
|
||||
* An object-oriented wrapper of the PHP cURL extension.
|
||||
*
|
||||
* This library requires to have the php cURL extensions installed:
|
||||
* https://php.net/manual/curl.setup.php
|
||||
*
|
||||
* Example of making a get request with parameters:
|
||||
*
|
||||
* ```php
|
||||
* $curl = new Curl\Curl();
|
||||
* $curl->get('http://www.example.com/search', array(
|
||||
* 'q' => 'keyword',
|
||||
* ));
|
||||
* ```
|
||||
*
|
||||
* Example post request with post data:
|
||||
*
|
||||
* ```php
|
||||
* $curl = new Curl\Curl();
|
||||
* $curl->post('http://www.example.com/login/', array(
|
||||
* 'username' => 'myusername',
|
||||
* 'password' => 'mypassword',
|
||||
* ));
|
||||
* ```
|
||||
*
|
||||
* @see https://php.net/manual/curl.setup.php
|
||||
*/
|
||||
class Curl
|
||||
{
|
||||
// The HTTP authentication method(s) to use.
|
||||
|
||||
/**
|
||||
* @var string Type AUTH_BASIC
|
||||
*/
|
||||
const AUTH_BASIC = CURLAUTH_BASIC;
|
||||
|
||||
/**
|
||||
* @var string Type AUTH_DIGEST
|
||||
*/
|
||||
const AUTH_DIGEST = CURLAUTH_DIGEST;
|
||||
|
||||
/**
|
||||
* @var string Type AUTH_GSSNEGOTIATE
|
||||
*/
|
||||
const AUTH_GSSNEGOTIATE = CURLAUTH_GSSNEGOTIATE;
|
||||
|
||||
/**
|
||||
* @var string Type AUTH_NTLM
|
||||
*/
|
||||
const AUTH_NTLM = CURLAUTH_NTLM;
|
||||
|
||||
/**
|
||||
* @var string Type AUTH_ANY
|
||||
*/
|
||||
const AUTH_ANY = CURLAUTH_ANY;
|
||||
|
||||
/**
|
||||
* @var string Type AUTH_ANYSAFE
|
||||
*/
|
||||
const AUTH_ANYSAFE = CURLAUTH_ANYSAFE;
|
||||
|
||||
/**
|
||||
* @var string The user agent name which is set when making a request
|
||||
*/
|
||||
const USER_AGENT = 'PHP Curl/1.9 (+https://github.com/php-mod/curl)';
|
||||
|
||||
private $_cookies = array();
|
||||
|
||||
private $_headers = array();
|
||||
|
||||
/**
|
||||
* @var resource Contains the curl resource created by `curl_init()` function
|
||||
*/
|
||||
public $curl;
|
||||
|
||||
/**
|
||||
* @var bool Whether an error occured or not
|
||||
*/
|
||||
public $error = false;
|
||||
|
||||
/**
|
||||
* @var int Contains the error code of the curren request, 0 means no error happend
|
||||
*/
|
||||
public $error_code = 0;
|
||||
|
||||
/**
|
||||
* @var string If the curl request failed, the error message is contained
|
||||
*/
|
||||
public $error_message = null;
|
||||
|
||||
/**
|
||||
* @var bool Whether an error occured or not
|
||||
*/
|
||||
public $curl_error = false;
|
||||
|
||||
/**
|
||||
* @var int Contains the error code of the curren request, 0 means no error happend.
|
||||
* @see https://curl.haxx.se/libcurl/c/libcurl-errors.html
|
||||
*/
|
||||
public $curl_error_code = 0;
|
||||
|
||||
/**
|
||||
* @var string If the curl request failed, the error message is contained
|
||||
*/
|
||||
public $curl_error_message = null;
|
||||
|
||||
/**
|
||||
* @var bool Whether an error occured or not
|
||||
*/
|
||||
public $http_error = false;
|
||||
|
||||
/**
|
||||
* @var int Contains the status code of the current processed request.
|
||||
*/
|
||||
public $http_status_code = 0;
|
||||
|
||||
/**
|
||||
* @var string If the curl request failed, the error message is contained
|
||||
*/
|
||||
public $http_error_message = null;
|
||||
|
||||
/**
|
||||
* @var string|array TBD (ensure type) Contains the request header informations
|
||||
*/
|
||||
public $request_headers = null;
|
||||
|
||||
/**
|
||||
* @var string|array TBD (ensure type) Contains the response header informations
|
||||
*/
|
||||
public $response_headers = array();
|
||||
|
||||
/**
|
||||
* @var string Contains the response from the curl request
|
||||
*/
|
||||
public $response = null;
|
||||
|
||||
/**
|
||||
* @var bool Whether the current section of response headers is after 'HTTP/1.1 100 Continue'
|
||||
*/
|
||||
protected $response_header_continue = false;
|
||||
|
||||
/**
|
||||
* Constructor ensures the available curl extension is loaded.
|
||||
*
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (!extension_loaded('curl')) {
|
||||
throw new \ErrorException('The cURL extensions is not loaded, make sure you have installed the cURL extension: https://php.net/manual/curl.setup.php');
|
||||
}
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
// private methods
|
||||
|
||||
/**
|
||||
* Initializer for the curl resource.
|
||||
*
|
||||
* Is called by the __construct() of the class or when the curl request is reseted.
|
||||
* @return self
|
||||
*/
|
||||
private function init()
|
||||
{
|
||||
$this->curl = curl_init();
|
||||
$this->setUserAgent(self::USER_AGENT);
|
||||
$this->setOpt(CURLINFO_HEADER_OUT, true);
|
||||
$this->setOpt(CURLOPT_HEADER, false);
|
||||
$this->setOpt(CURLOPT_RETURNTRANSFER, true);
|
||||
$this->setOpt(CURLOPT_HEADERFUNCTION, array($this, 'addResponseHeaderLine'));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle writing the response headers
|
||||
*
|
||||
* @param resource $curl The current curl resource
|
||||
* @param string $header_line A line from the list of response headers
|
||||
*
|
||||
* @return int Returns the length of the $header_line
|
||||
*/
|
||||
public function addResponseHeaderLine($curl, $header_line)
|
||||
{
|
||||
$trimmed_header = trim($header_line, "\r\n");
|
||||
|
||||
if ($trimmed_header === "") {
|
||||
$this->response_header_continue = false;
|
||||
} elseif (strtolower($trimmed_header) === 'http/1.1 100 continue') {
|
||||
$this->response_header_continue = true;
|
||||
} elseif (!$this->response_header_continue) {
|
||||
$this->response_headers[] = $trimmed_header;
|
||||
}
|
||||
|
||||
return strlen($header_line);
|
||||
}
|
||||
|
||||
// protected methods
|
||||
|
||||
/**
|
||||
* Execute the curl request based on the respectiv settings.
|
||||
*
|
||||
* @return int Returns the error code for the current curl request
|
||||
*/
|
||||
protected function exec()
|
||||
{
|
||||
$this->response_headers = array();
|
||||
$this->response = curl_exec($this->curl);
|
||||
$this->curl_error_code = curl_errno($this->curl);
|
||||
$this->curl_error_message = curl_error($this->curl);
|
||||
$this->curl_error = !($this->curl_error_code === 0);
|
||||
$this->http_status_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
|
||||
$this->http_error = in_array(floor($this->http_status_code / 100), array(4, 5));
|
||||
$this->error = $this->curl_error || $this->http_error;
|
||||
$this->error_code = $this->error ? ($this->curl_error ? $this->curl_error_code : $this->http_status_code) : 0;
|
||||
$this->request_headers = preg_split('/\r\n/', curl_getinfo($this->curl, CURLINFO_HEADER_OUT), null, PREG_SPLIT_NO_EMPTY);
|
||||
$this->http_error_message = $this->error ? (isset($this->response_headers['0']) ? $this->response_headers['0'] : '') : '';
|
||||
$this->error_message = $this->curl_error ? $this->curl_error_message : $this->http_error_message;
|
||||
|
||||
return $this->error_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|object|string $data
|
||||
*/
|
||||
protected function preparePayload($data)
|
||||
{
|
||||
$this->setOpt(CURLOPT_POST, true);
|
||||
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$skip = false;
|
||||
foreach ($data as $key => $value) {
|
||||
// If a value is an instance of CurlFile skip the http_build_query
|
||||
// see issue https://github.com/php-mod/curl/issues/46
|
||||
// suggestion from: https://stackoverflow.com/a/36603038/4611030
|
||||
if ($value instanceof \CurlFile) {
|
||||
$skip = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$skip) {
|
||||
$data = http_build_query($data);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setOpt(CURLOPT_POSTFIELDS, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set auth options for the current request.
|
||||
*
|
||||
* Available auth types are:
|
||||
*
|
||||
* + self::AUTH_BASIC
|
||||
* + self::AUTH_DIGEST
|
||||
* + self::AUTH_GSSNEGOTIATE
|
||||
* + self::AUTH_NTLM
|
||||
* + self::AUTH_ANY
|
||||
* + self::AUTH_ANYSAFE
|
||||
*
|
||||
* @param int $httpauth The type of authentication
|
||||
*/
|
||||
protected function setHttpAuth($httpauth)
|
||||
{
|
||||
$this->setOpt(CURLOPT_HTTPAUTH, $httpauth);
|
||||
}
|
||||
|
||||
// public methods
|
||||
|
||||
/**
|
||||
* @deprecated calling exec() directly is discouraged
|
||||
*/
|
||||
public function _exec()
|
||||
{
|
||||
return $this->exec();
|
||||
}
|
||||
|
||||
// functions
|
||||
|
||||
/**
|
||||
* Make a get request with optional data.
|
||||
*
|
||||
* The get request has no body data, the data will be correctly added to the $url with the http_build_query() method.
|
||||
*
|
||||
* @param string $url The url to make the get request for
|
||||
* @param array $data Optional arguments who are part of the url
|
||||
* @return self
|
||||
*/
|
||||
public function get($url, $data = array())
|
||||
{
|
||||
if (count($data) > 0) {
|
||||
$this->setOpt(CURLOPT_URL, $url.'?'.http_build_query($data));
|
||||
} else {
|
||||
$this->setOpt(CURLOPT_URL, $url);
|
||||
}
|
||||
$this->setOpt(CURLOPT_HTTPGET, true);
|
||||
$this->exec();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a post request with optional post data.
|
||||
*
|
||||
* @param string $url The url to make the post request
|
||||
* @param array $data Post data to pass to the url
|
||||
* @return self
|
||||
*/
|
||||
public function post($url, $data = array())
|
||||
{
|
||||
$this->setOpt(CURLOPT_URL, $url);
|
||||
$this->preparePayload($data);
|
||||
$this->exec();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a put request with optional data.
|
||||
*
|
||||
* The put request data can be either sent via payload or as get paramters of the string.
|
||||
*
|
||||
* @param string $url The url to make the put request
|
||||
* @param array $data Optional data to pass to the $url
|
||||
* @param bool $payload Whether the data should be transmitted trough payload or as get parameters of the string
|
||||
* @return self
|
||||
*/
|
||||
public function put($url, $data = array(), $payload = false)
|
||||
{
|
||||
if (! empty($data)) {
|
||||
if ($payload === false) {
|
||||
$url .= '?'.http_build_query($data);
|
||||
} else {
|
||||
$this->preparePayload($data);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setOpt(CURLOPT_URL, $url);
|
||||
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'PUT');
|
||||
$this->exec();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a patch request with optional data.
|
||||
*
|
||||
* The patch request data can be either sent via payload or as get paramters of the string.
|
||||
*
|
||||
* @param string $url The url to make the patch request
|
||||
* @param array $data Optional data to pass to the $url
|
||||
* @param bool $payload Whether the data should be transmitted trough payload or as get parameters of the string
|
||||
* @return self
|
||||
*/
|
||||
public function patch($url, $data = array(), $payload = false)
|
||||
{
|
||||
if (! empty($data)) {
|
||||
if ($payload === false) {
|
||||
$url .= '?'.http_build_query($data);
|
||||
} else {
|
||||
$this->preparePayload($data);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setOpt(CURLOPT_URL, $url);
|
||||
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'PATCH');
|
||||
$this->exec();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a delete request with optional data.
|
||||
*
|
||||
* @param string $url The url to make the delete request
|
||||
* @param array $data Optional data to pass to the $url
|
||||
* @param bool $payload Whether the data should be transmitted trough payload or as get parameters of the string
|
||||
* @return self
|
||||
*/
|
||||
public function delete($url, $data = array(), $payload = false)
|
||||
{
|
||||
if (! empty($data)) {
|
||||
if ($payload === false) {
|
||||
$url .= '?'.http_build_query($data);
|
||||
} else {
|
||||
$this->preparePayload($data);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setOpt(CURLOPT_URL, $url);
|
||||
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
$this->exec();
|
||||
return $this;
|
||||
}
|
||||
|
||||
// setters
|
||||
|
||||
/**
|
||||
* Pass basic auth data.
|
||||
*
|
||||
* If the the rquested url is secured by an httaccess basic auth mechanism you can use this method to provided the auth data.
|
||||
*
|
||||
* ```php
|
||||
* $curl = new Curl();
|
||||
* $curl->setBasicAuthentication('john', 'doe');
|
||||
* $curl->get('http://example.com/secure.php');
|
||||
* ```
|
||||
*
|
||||
* @param string $username The username for the authentification
|
||||
* @param string $password The password for the given username for the authentification
|
||||
* @return self
|
||||
*/
|
||||
public function setBasicAuthentication($username, $password)
|
||||
{
|
||||
$this->setHttpAuth(self::AUTH_BASIC);
|
||||
$this->setOpt(CURLOPT_USERPWD, $username.':'.$password);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide optional header informations.
|
||||
*
|
||||
* In order to pass optional headers by key value pairing:
|
||||
*
|
||||
* ```php
|
||||
* $curl = new Curl();
|
||||
* $curl->setHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
* $curl->get('http://example.com/request.php');
|
||||
* ```
|
||||
*
|
||||
* @param string $key The header key
|
||||
* @param string $value The value for the given header key
|
||||
* @return self
|
||||
*/
|
||||
public function setHeader($key, $value)
|
||||
{
|
||||
$this->_headers[$key] = $key.': '.$value;
|
||||
$this->setOpt(CURLOPT_HTTPHEADER, array_values($this->_headers));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a User Agent.
|
||||
*
|
||||
* In order to provide you cusomtized user agent name you can use this method.
|
||||
*
|
||||
* ```php
|
||||
* $curl = new Curl();
|
||||
* $curl->setUserAgent('My John Doe Agent 1.0');
|
||||
* $curl->get('http://example.com/request.php');
|
||||
* ```
|
||||
*
|
||||
* @param string $useragent The name of the user agent to set for the current request
|
||||
* @return self
|
||||
*/
|
||||
public function setUserAgent($useragent)
|
||||
{
|
||||
$this->setOpt(CURLOPT_USERAGENT, $useragent);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Call setReferer() instead
|
||||
*/
|
||||
public function setReferrer($referrer)
|
||||
{
|
||||
$this->setReferer($referrer);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTTP referer header.
|
||||
*
|
||||
* The $referer informations can help identify the requested client where the requested was made.
|
||||
*
|
||||
* @param string $referer An url to pass and will be set as referer header
|
||||
* @return self
|
||||
*/
|
||||
public function setReferer($referer)
|
||||
{
|
||||
$this->setOpt(CURLOPT_REFERER, $referer);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set contents of HTTP Cookie header.
|
||||
*
|
||||
* @param string $key The name of the cookie
|
||||
* @param string $value The value for the provided cookie name
|
||||
* @return self
|
||||
*/
|
||||
public function setCookie($key, $value)
|
||||
{
|
||||
$this->_cookies[$key] = $value;
|
||||
$this->setOpt(CURLOPT_COOKIE, http_build_query($this->_cookies, '', '; '));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set customized curl options.
|
||||
*
|
||||
* To see a full list of options: http://php.net/curl_setopt
|
||||
*
|
||||
* @see http://php.net/curl_setopt
|
||||
*
|
||||
* @param int $option The curl option constante e.g. `CURLOPT_AUTOREFERER`, `CURLOPT_COOKIESESSION`
|
||||
* @param mixed $value The value to pass for the given $option
|
||||
*/
|
||||
public function setOpt($option, $value)
|
||||
{
|
||||
return curl_setopt($this->curl, $option, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customized curl options.
|
||||
*
|
||||
* To see a full list of options: http://php.net/curl_getinfo
|
||||
*
|
||||
* @see http://php.net/curl_getinfo
|
||||
*
|
||||
* @param int $option The curl option constante e.g. `CURLOPT_AUTOREFERER`, `CURLOPT_COOKIESESSION`
|
||||
* @param mixed $value The value to check for the given $option
|
||||
*/
|
||||
public function getOpt($option)
|
||||
{
|
||||
return curl_getinfo($this->curl, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the endpoint set for curl
|
||||
*
|
||||
* @see http://php.net/curl_getinfo
|
||||
*
|
||||
* @return string of endpoint
|
||||
*/
|
||||
public function getEndpoint()
|
||||
{
|
||||
return $this->getOpt(CURLINFO_EFFECTIVE_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable verbositiy.
|
||||
*
|
||||
* @todo As to keep naming convention it should be renamed to `setVerbose()`
|
||||
*
|
||||
* @param string $on
|
||||
* @return self
|
||||
*/
|
||||
public function verbose($on = true)
|
||||
{
|
||||
$this->setOpt(CURLOPT_VERBOSE, $on);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all curl options.
|
||||
*
|
||||
* In order to make multiple requests with the same curl object all settings requires to be reset.
|
||||
* @return self
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->close();
|
||||
$this->_cookies = array();
|
||||
$this->_headers = array();
|
||||
$this->error = false;
|
||||
$this->error_code = 0;
|
||||
$this->error_message = null;
|
||||
$this->curl_error = false;
|
||||
$this->curl_error_code = 0;
|
||||
$this->curl_error_message = null;
|
||||
$this->http_error = false;
|
||||
$this->http_status_code = 0;
|
||||
$this->http_error_message = null;
|
||||
$this->request_headers = null;
|
||||
$this->response_headers = array();
|
||||
$this->response = null;
|
||||
$this->init();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closing the current open curl resource.
|
||||
* @return self
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if (is_resource($this->curl)) {
|
||||
curl_close($this->curl);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the connection when the Curl object will be destroyed.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Was an 'info' header returned.
|
||||
* @return bool
|
||||
*/
|
||||
public function isInfo()
|
||||
{
|
||||
return $this->http_status_code >= 100 && $this->http_status_code < 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was an 'OK' response returned.
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccess()
|
||||
{
|
||||
return $this->http_status_code >= 200 && $this->http_status_code < 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was a 'redirect' returned.
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirect()
|
||||
{
|
||||
return $this->http_status_code >= 300 && $this->http_status_code < 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was an 'error' returned (client error or server error).
|
||||
* @return bool
|
||||
*/
|
||||
public function isError()
|
||||
{
|
||||
return $this->http_status_code >= 400 && $this->http_status_code < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was a 'client error' returned.
|
||||
* @return bool
|
||||
*/
|
||||
public function isClientError()
|
||||
{
|
||||
return $this->http_status_code >= 400 && $this->http_status_code < 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was a 'server error' returned.
|
||||
* @return bool
|
||||
*/
|
||||
public function isServerError()
|
||||
{
|
||||
return $this->http_status_code >= 500 && $this->http_status_code < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific response header key or all values from the response headers array.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* ```php
|
||||
* $curl = (new Curl())->get('http://example.com');
|
||||
*
|
||||
* echo $curl->getResponseHeaders('Content-Type');
|
||||
* ```
|
||||
*
|
||||
* Or in order to dump all keys with the given values use:
|
||||
*
|
||||
* ```php
|
||||
* $curl = (new Curl())->get('http://example.com');
|
||||
*
|
||||
* var_dump($curl->getResponseHeaders());
|
||||
* ```
|
||||
*
|
||||
* @param string $headerKey Optional key to get from the array.
|
||||
* @return bool|string
|
||||
* @since 1.9
|
||||
*/
|
||||
public function getResponseHeaders($headerKey = null)
|
||||
{
|
||||
$headers = array();
|
||||
$headerKey = strtolower($headerKey);
|
||||
|
||||
foreach ($this->response_headers as $header) {
|
||||
$parts = explode(":", $header, 2);
|
||||
|
||||
$key = isset($parts[0]) ? $parts[0] : null;
|
||||
$value = isset($parts[1]) ? $parts[1] : null;
|
||||
|
||||
$headers[trim(strtolower($key))] = trim($value);
|
||||
}
|
||||
|
||||
if ($headerKey) {
|
||||
return isset($headers[$headerKey]) ? $headers[$headerKey] : false;
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
public function getErrorCode()
|
||||
{
|
||||
return $this->curl_error_code;
|
||||
}
|
||||
|
||||
public function getErrorMessage()
|
||||
{
|
||||
return $this->curl_error_message;
|
||||
}
|
||||
|
||||
public function getHttpStatus()
|
||||
{
|
||||
return $this->http_status_code;
|
||||
}
|
||||
}
|
277
vendor/curl/curl/tests/CurlTest.php
vendored
Normal file
277
vendor/curl/curl/tests/CurlTest.php
vendored
Normal file
@ -0,0 +1,277 @@
|
||||
<?php
|
||||
|
||||
namespace Curl;
|
||||
|
||||
class CurlTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
const TEST_URL = 'http://server_test';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Curl
|
||||
*/
|
||||
protected $curl;
|
||||
|
||||
function setUp() {
|
||||
$this->curl = new Curl();
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
}
|
||||
|
||||
function server($request_method, $data='') {
|
||||
$request_method = strtolower($request_method);
|
||||
$this->curl->$request_method(self::TEST_URL . '/server.php', $data);
|
||||
return $this->curl->response;
|
||||
}
|
||||
|
||||
public function testExtensionLoaded() {
|
||||
|
||||
$this->assertTrue(extension_loaded('curl'));
|
||||
}
|
||||
|
||||
public function testUserAgent() {
|
||||
|
||||
$this->curl->setUserAgent(Curl::USER_AGENT);
|
||||
$this->assertEquals(Curl::USER_AGENT, $this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_USER_AGENT',
|
||||
)));
|
||||
|
||||
}
|
||||
|
||||
public function testGet() {
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'GET');
|
||||
}
|
||||
|
||||
public function testPostRequestMethod() {
|
||||
$this->assertTrue($this->server('POST', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'POST');
|
||||
}
|
||||
|
||||
public function testPostData() {
|
||||
$this->assertTrue($this->server('POST', array(
|
||||
'test' => 'post',
|
||||
'key' => 'test',
|
||||
)) === 'post');
|
||||
}
|
||||
|
||||
public function testPostMultidimensionalData() {
|
||||
|
||||
$data = array(
|
||||
'key' => 'file',
|
||||
'file' => array(
|
||||
'wibble',
|
||||
'wubble',
|
||||
'wobble',
|
||||
),
|
||||
);
|
||||
|
||||
$this->curl->post(self::TEST_URL . '/post_multidimensional.php', $data);
|
||||
|
||||
$this->assertEquals(
|
||||
'key=file&file%5B0%5D=wibble&file%5B1%5D=wubble&file%5B2%5D=wobble',
|
||||
$this->curl->response);
|
||||
|
||||
}
|
||||
|
||||
public function testPostFilePathUpload()
|
||||
{
|
||||
|
||||
$file_path = $this->get_png();
|
||||
|
||||
$data = array(
|
||||
'key' => 'image',
|
||||
'image' => '@' . $file_path,
|
||||
);
|
||||
|
||||
$this->curl->setOpt(CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$this->curl->post(self::TEST_URL . '/post_file_path_upload.php', $data);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'request_method' => 'POST',
|
||||
'key' => 'image',
|
||||
'mime_content_type' => 'ERROR', // Temp change the image response, but assuming this is not fixing the issue indeed.
|
||||
//'mime_content_type' => 'image/png'
|
||||
),
|
||||
json_decode($this->curl->response, true));
|
||||
|
||||
unlink($file_path);
|
||||
}
|
||||
|
||||
public function testPutRequestMethod() {
|
||||
$this->assertTrue($this->server('PUT', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'PUT');
|
||||
}
|
||||
|
||||
public function testPutData() {
|
||||
$this->assertTrue($this->server('PUT', array(
|
||||
'test' => 'put',
|
||||
'key' => 'test',
|
||||
)) === 'put');
|
||||
}
|
||||
|
||||
public function testPutFileHandle() {
|
||||
$png = $this->create_png();
|
||||
$tmp_file = $this->create_tmp_file($png);
|
||||
|
||||
$this->curl->setOpt(CURLOPT_PUT, TRUE);
|
||||
$this->curl->setOpt(CURLOPT_INFILE, $tmp_file);
|
||||
$this->curl->setOpt(CURLOPT_INFILESIZE, strlen($png));
|
||||
$this->curl->put(self::TEST_URL . '/server.php', array(
|
||||
'test' => 'put_file_handle',
|
||||
));
|
||||
|
||||
fclose($tmp_file);
|
||||
|
||||
$this->assertTrue($this->curl->response === 'image/png');
|
||||
}
|
||||
|
||||
public function testDelete() {
|
||||
$this->assertTrue($this->server('DELETE', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'DELETE');
|
||||
|
||||
$this->assertTrue($this->server('DELETE', array(
|
||||
'test' => 'delete',
|
||||
'key' => 'test',
|
||||
)) === 'delete');
|
||||
}
|
||||
|
||||
public function testBasicHttpAuth() {
|
||||
|
||||
$data = array();
|
||||
|
||||
$this->curl->get(self::TEST_URL . '/http_basic_auth.php', $data);
|
||||
|
||||
$this->assertEquals('canceled', $this->curl->response);
|
||||
|
||||
$username = 'myusername';
|
||||
$password = 'mypassword';
|
||||
|
||||
$this->curl->setBasicAuthentication($username, $password);
|
||||
|
||||
$this->curl->get(self::TEST_URL . '/http_basic_auth.php', $data);
|
||||
|
||||
$this->assertEquals(
|
||||
'{"username":"myusername","password":"mypassword"}',
|
||||
$this->curl->response);
|
||||
}
|
||||
|
||||
public function testReferrer() {
|
||||
$this->curl->setReferer('myreferrer');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_REFERER',
|
||||
)) === 'myreferrer');
|
||||
}
|
||||
|
||||
public function testDeprecatedReferrer() {
|
||||
$this->curl->setReferrer('myreferrer');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_REFERER',
|
||||
)) === 'myreferrer');
|
||||
}
|
||||
|
||||
public function testCookies() {
|
||||
$this->curl->setCookie('mycookie', 'yum');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'cookie',
|
||||
'key' => 'mycookie',
|
||||
)) === 'yum');
|
||||
}
|
||||
|
||||
public function testError() {
|
||||
$this->curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000);
|
||||
$this->curl->get('http://1.2.3.4/');
|
||||
$this->assertTrue($this->curl->error === TRUE);
|
||||
$this->assertTrue($this->curl->curl_error === TRUE);
|
||||
$this->assertTrue($this->curl->curl_error_code === CURLE_OPERATION_TIMEOUTED);
|
||||
}
|
||||
|
||||
public function testHeaders() {
|
||||
$this->curl->setHeader('Content-Type', 'application/json');
|
||||
$this->curl->setHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
$this->curl->setHeader('Accept', 'application/json');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'CONTENT_TYPE',
|
||||
)) === 'application/json');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_X_REQUESTED_WITH',
|
||||
)) === 'XMLHttpRequest');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_ACCEPT',
|
||||
)) === 'application/json');
|
||||
}
|
||||
|
||||
public function testHeadersWithContinue() {
|
||||
$headers = file(dirname(__FILE__) . '/data/response_headers_with_continue.txt');
|
||||
|
||||
$this->curl->response_headers = array();
|
||||
foreach($headers as $header_line) {
|
||||
$this->curl->addResponseHeaderLine(null, $header_line);
|
||||
}
|
||||
|
||||
$expected_headers = array_values(array_filter(array_map(function($l) { return trim($l, "\r\n"); }, array_slice($headers, 1))));
|
||||
|
||||
$this->assertEquals($expected_headers, $this->curl->response_headers);
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$curl = $this->getMockBuilder(get_class($this->curl))->getMock();
|
||||
$curl->expects($this->once())->method('reset')->with();
|
||||
// lets make small request
|
||||
$curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000);
|
||||
$curl->get('http://1.2.3.4/');
|
||||
$curl->reset();
|
||||
$this->assertFalse($curl->error);
|
||||
$this->assertSame(0, $curl->error_code);
|
||||
$this->assertNull($curl->error_message);
|
||||
$this->assertFalse($curl->curl_error);
|
||||
$this->assertSame(0, $curl->curl_error_code);
|
||||
$this->assertNull($curl->curl_error_message);
|
||||
$this->assertFalse($curl->http_error);
|
||||
$this->assertSame(0, $curl->http_status_code);
|
||||
$this->assertNull($curl->http_error_message);
|
||||
$this->assertNull($curl->request_headers);
|
||||
$this->assertEmpty($curl->response_headers);
|
||||
$this->assertNull($curl->response);
|
||||
}
|
||||
|
||||
function create_png() {
|
||||
// PNG image data, 1 x 1, 1-bit colormap, non-interlaced
|
||||
ob_start();
|
||||
imagepng(imagecreatefromstring(base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7')));
|
||||
$raw_image = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $raw_image;
|
||||
}
|
||||
|
||||
function create_tmp_file($data) {
|
||||
$tmp_file = tmpfile();
|
||||
fwrite($tmp_file, $data);
|
||||
rewind($tmp_file);
|
||||
return $tmp_file;
|
||||
}
|
||||
|
||||
function get_png() {
|
||||
$tmp_filename = tempnam('/tmp', 'php-curl-class.');
|
||||
file_put_contents($tmp_filename, $this->create_png());
|
||||
return $tmp_filename;
|
||||
}
|
||||
}
|
13
vendor/curl/curl/tests/data/response_headers_with_continue.txt
vendored
Normal file
13
vendor/curl/curl/tests/data/response_headers_with_continue.txt
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
HTTP/1.1 100 Continue
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.1.19
|
||||
Date: Fri, 11 Aug 2017 13:22:00 GMT
|
||||
Content-Type: image/jpeg
|
||||
Content-Length: 62574
|
||||
Connection: close
|
||||
Cache-Control: max-age=7257600
|
||||
Expires: Fri, 03 Nov 2017 13:22:00 GMT
|
||||
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
||||
X-Frame-Option: DENY
|
||||
|
BIN
vendor/curl/curl/tests/data/test.png
vendored
Normal file
BIN
vendor/curl/curl/tests/data/test.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user