Compare commits

..

296 Commits

Author SHA1 Message Date
David
945df1a9cb Merge pull request #56 from GrayXu/master
新增站点:蝴蝶
2021-09-05 16:44:36 +08:00
Gray Xu
88420c4260 新增站点:蝴蝶 2021-09-05 16:36:19 +08:00
david
136c9ee2ba 加版本号 2021-07-09 18:25:55 +08:00
david
9497cea867 优化URL替换规则,支持新站点 2021-07-09 18:22:19 +08:00
david
6f23c966e1 修改用户绑定接口地址 2021-07-01 23:58:53 +08:00
david
9d8eee73d9 新增站点:蒲公英、阿童木 2021-03-06 11:26:17 +08:00
david
d9698dfe7f 累加版本号 2021-01-13 14:11:13 +08:00
david
a6e2be82c9 加入.gitignore 2021-01-13 14:05:50 +08:00
david
e9214738c9 add 2021-01-13 13:59:11 +08:00
david
e61b47f3e8 移除、添加文件 2021-01-13 13:53:54 +08:00
david
87d9f81bad 修复entrypoint.sh权限给太高,某些情况下无法执行的问题。 2020-12-31 00:30:17 +08:00
david
7b2e82c506 修复entrypoint.sh在UNRAID中777权限无法执行问题 2020-12-31 00:23:41 +08:00
david
ae63bfca89 加入操作辅种docker容器的相关命令示例 2020-12-23 16:32:57 +08:00
david
6c1211708c v1.10.17 2020-12-22 12:04:59 +08:00
david
40387fdb5b + push.sh 2020-12-22 12:03:11 +08:00
david
e10c36295c 优化Dockerfile防止更新权限覆盖 2020-12-22 01:19:45 +08:00
david
801d7b016f 优化entrypoint.sh脚本 2020-12-22 01:14:40 +08:00
david
1ff415ea91 && chmod -R 777 /IYUU/docker/entrypoint.sh \ 2020-12-22 00:24:35 +08:00
david
849370e26a 优化docker 2020-12-22 00:14:52 +08:00
david
815156b252 修复重复注入拼接规则bug 2020-12-14 15:16:51 +08:00
david
d62be67927 修改docker定时 2020-12-14 11:47:59 +08:00
david
d513b1bedf 修改 Dockerfile 2020-12-14 02:36:38 +08:00
david
b566181968 优化辅种前置检查 2020-12-13 21:06:13 +08:00
david
60b4939aee fix 2020-12-12 15:47:08 +08:00
david
dad8afa8d4 fix 2020-12-12 15:16:54 +08:00
david
a60e5f859c 补充新规则的配置参数 2020-12-12 14:46:49 +08:00
david
59622691e1 重要更新:
1.hdhome、pthome、ourbits,加入新的辅种下载规则;
2.新增支持HDAI站点。
3.合作站验证参数,改为云端获取;
4.辅种检查参数,改为云端获取。
2020-12-12 14:29:12 +08:00
david
3a97c17e66 编辑示例配置注释 2020-12-06 21:49:33 +08:00
david
6d3b937097 新增3群号码 2020-12-01 13:54:22 +08:00
david
4277568346 新增站点:pttime 2020-11-30 16:27:49 +08:00
david
84f75ea443 移除失效站点信息,优化代码 2020-11-13 00:23:36 +08:00
david
715be0e7eb 修正注释描述 2020-11-04 15:00:54 +08:00
david
6eebc7d26c 修改ttg配置的顺序 2020-09-04 23:45:52 +08:00
david
30410735af 新增合作站点:chdbits
更新方法:依据最新示例配置,增加一行ID配置。
2020-08-31 23:54:02 +08:00
david
99a2894f37 新增站点:百川PT 2020-08-26 14:09:46 +08:00
iyuu.cn
13b176c4a1 更新readme.md 2020-08-11 19:18:39 +08:00
iyuu.cn
afca458acc 更改转移参数,默认暂停 2020-08-11 19:17:45 +08:00
iyuu.cn
b8b05ff3bf 新增辅种站点:龙之家dragonhd 2020-08-11 18:16:16 +08:00
iyuu.cn
d402d30aac 更改定时任务时间 2020-08-07 17:47:13 +08:00
iyuu.cn
11c976d2c0 增强检查,避免空参数使用backup.sh时,造成问题。 2020-08-06 23:04:33 +08:00
iyuu.cn
630dc3af92 优先检查passkey,排除用户没有的站点 2020-08-06 14:36:04 +08:00
iyuu.cn
463e45ee38 优化日志记录方式 2020-08-05 19:08:06 +08:00
iyuu.cn
b046ecc75f 示例配置新增教程 2020-08-03 22:54:15 +08:00
iyuu.cn
468813a057 编辑:更新历史.md 2020-08-02 23:10:07 +08:00
iyuu.cn
fdd5475e37 兼容qBittorrent v4.1.5【小钢炮等】 2020-08-02 15:39:25 +08:00
iyuu.cn
1f4da154fb 优化Windows批处理 2020-08-02 00:11:31 +08:00
iyuu.cn
419b6eb8cd fix 2020-08-01 22:43:44 +08:00
iyuu.cn
289df1e126 优化windows执行辅种批处理 2020-08-01 15:42:54 +08:00
iyuu.cn
4d86a9cb9f Readme.md新增Docker使用方法介绍 2020-07-31 17:09:24 +08:00
iyuu.cn
c79d5e4592 v1.10.2版本以后的docker,每5小时会自动拉取最新代码;从此,您只需要看公告更新配置就行啦。 2020-07-31 09:34:18 +08:00
iyuu.cn
c9fb5c6a6a 更改Dockerfile,每5小时自动拉取最新代码 2020-07-31 09:17:57 +08:00
iyuu.cn
a744f5e785 更改本地ARM平台打包标签为:iyuu:arm64v8 2020-07-31 07:59:55 +08:00
iyuu.cn
84394c3a71 精简配置,移除容易迷惑人的项目 2020-07-31 07:52:00 +08:00
iyuu.cn
fd61ee86a1 新增.dockerignore,排除编译不必要的文件 2020-07-31 07:47:11 +08:00
iyuu.cn
afe1a863ac 移除Arm64v8.Dockerfile 2020-07-30 21:00:10 +08:00
iyuu.cn
2a7947b9fa bash+ 2020-07-30 15:19:18 +08:00
iyuu.cn
fa6a38b7b3 移除swoft/alphp:base 2020-07-30 14:44:35 +08:00
iyuu.cn
02eb245ae0 更新Arm64v8.Dockerfile,测试自动编译。 2020-07-30 14:34:14 +08:00
iyuu.cn
3fc4e14b93 优化docker的Readme.md注释 2020-07-29 19:12:16 +08:00
iyuu.cn
6a5d375044 修复编码错误。 2020-07-29 16:00:43 +08:00
iyuu.cn
da0cb81ab2 修复笔误。 2020-07-29 15:28:48 +08:00
iyuu.cn
41ebed71c7 本地编译更改基础镜像为arm64v8/alpine:3.12,并使用国内镜像源 2020-07-29 15:26:12 +08:00
iyuu.cn
05426489f0 新增Docker自动Builds文件Arm64v8.Dockerfile; 2020-07-29 15:25:07 +08:00
iyuu.cn
8489b07b35 精简和优化readme中相关项目说明 2020-07-29 15:20:22 +08:00
iyuu.cn
3e28685731 Dockerfile使用官方源 2020-07-29 03:02:53 +08:00
iyuu.cn
2d5ab5ae9b 新增Dockerfile 2020-07-29 02:14:37 +08:00
iyuu.cn
fa61ad21e0 优化hdsky下载url后的显示效果。 2020-07-29 00:37:23 +08:00
iyuu.cn
1f95e62d95 v1.10.0 2020-07-29 00:32:47 +08:00
iyuu.cn
a84b193d14 调整hdsky流控参数20/20,适配天空辅种。 2020-07-29 00:29:54 +08:00
iyuu.cn
e2dddfdead 新增AMD64平台docker构建脚本 2020-07-28 08:33:40 +08:00
iyuu.cn
f78e9c737c 新增Docker构建amd64镜像 2020-07-28 06:49:26 +08:00
iyuu.cn
8813afbd73 新增docker镜像Arm64v8 2020-07-28 03:27:59 +08:00
iyuu.cn
8b1bd9cdb5 fix 2020-07-25 20:37:57 +08:00
iyuu.cn
5418c02227 修复缺少isset($configALL['notify_on_change'])判断警告 2020-07-24 16:03:59 +08:00
iyuu.cn
a9d9fb637d 当配置不存在时,生成配置后再延时提示。 2020-07-24 14:01:03 +08:00
iyuu.cn
4247457cb6 更新readme.md相关项目 2020-07-24 13:27:34 +08:00
iyuu.cn
0047450161 更新readme.md相关项目;修改微信通知支持条件触发:有变化才发送通知(辅种成功 + 失败 > 0)。 2020-07-24 13:16:24 +08:00
iyuu.cn
15f9905004 合并hxsf提交,修改buile.sh 2020-07-24 13:07:05 +08:00
David
63b2bfc2bc Merge pull request #17 from hxsf/master
some features
2020-07-24 13:50:37 +08:00
hxsf
c5c2feb9d3 add notify_on_change feature 2020-07-24 13:39:22 +08:00
hxsf
6c06d9fb6a add new DockerFile and docker-compose example 2020-07-24 13:36:33 +08:00
iyuu.cn
6578397ee3 更新相关项目4个。 2020-07-23 19:53:01 +08:00
iyuu.cn
29c2e43405 首次运行生成config.php;提高瓷器、城市兼容性。 2020-07-23 18:47:06 +08:00
iyuu.cn
18cdd7abed 新增pthome流控参数 2020-07-22 21:21:59 +08:00
iyuu.cn
4fbf795811 增强客户端空密码检查 2020-07-22 03:28:42 +08:00
iyuu.cn
88ebc12ce5 微信报表新增失败详情提示 2020-07-21 19:42:17 +08:00
iyuu.cn
08b4b58083 新增hddolby流控参数 2020-07-21 19:24:04 +08:00
iyuu.cn
ca02231431 加入github徽章 2020-07-21 16:43:21 +08:00
iyuu.cn
7d638eba40 新增hdhome流控参数 2020-07-19 17:20:27 +08:00
iyuu.cn
c35c23583c 新增Ourbits、SSD、hdchina、hdsky、moecat、pt等站点的流控规则 2020-07-18 14:34:07 +08:00
iyuu.cn
b2b9000a86 优化代码结构 2020-07-17 23:02:21 +08:00
iyuu.cn
b80a5b89cc 更新Readme.md 2020-07-17 20:39:45 +08:00
iyuu.cn
c2e5b4d00b 新增移动做种微信报告 2020-07-17 19:55:53 +08:00
iyuu.cn
207320ede7 fix 2020-07-16 20:59:41 +08:00
iyuu.cn
6e1653fc1e fix 2020-07-14 16:44:28 +08:00
iyuu.cn
32ec80d552 提高对旧配置的兼容性 2020-07-14 02:13:20 +08:00
iyuu.cn
2b989f9e0e 新增瓷器、城市cookie过期微信通知 2020-07-13 10:19:36 +08:00
iyuu.cn
ff16781da9 fix 2020-07-13 08:47:00 +08:00
iyuu.cn
6a01b492ce 更新公告栏 2020-07-13 07:58:39 +08:00
iyuu.cn
de41bc0131 1.优化App.Api.Sites接口带版本号请求;2.新增异步间隔流控算法:各站独立、执行时间最优;3.config.sample.php各站点新增url_replace、url_join、limitRule参数。 2020-07-13 07:32:15 +08:00
iyuu.cn
6b83e9081b fix:优化代码 2020-07-12 21:29:41 +08:00
iyuu.cn
87f06ec5c4 接口域名部署SSL证书,支持双协议http/https。如:https://api.iyuu.cn 2020-07-12 19:39:19 +08:00
iyuu.cn
8a051d4d1f fix:优化转移做种时过滤器、选择器提示顺序。 2020-07-11 20:39:09 +08:00
iyuu.cn
0e32e625a4 新增功能:转移过滤器、选择器;可以只转移指定路径的种子,也可以排除指令路径的种子,按需转移。 2020-07-11 18:09:04 +08:00
iyuu.cn
a09dacbd20 优化微信通知提示 2020-07-11 02:46:59 +08:00
iyuu.cn
e3a9c32174 微信通知增加辅种缓存位置提示。 2020-07-10 19:33:51 +08:00
iyuu.cn
c8a94bfcff 优化代码结构,美化微信通知消息,删除多余的运行提示信息等 2020-07-10 19:17:12 +08:00
iyuu.cn
fd87d07539 更新md文档 2020-07-03 17:20:25 +08:00
iyuu.cn
df7100e4e9 更新QQ群信息:859882209、931954050 2020-07-03 17:19:51 +08:00
iyuu.cn
44f5b82650 新增HDfans站点 2020-07-03 13:01:03 +08:00
iyuu.cn
f5a33843e6 v1.8.3 2020-06-18 08:45:40 +08:00
iyuu.cn
7428144aa8 移除SSD站点辅种计数器。 2020-06-18 08:44:57 +08:00
iyuu.cn
cc325dc128 删除无用.cmd批处理 2020-06-10 23:09:20 +08:00
iyuu.cn
3d675ed4bd qBittorrent下载器增加root_folder配置项:是否创建子文件夹 2020-06-10 10:31:40 +08:00
iyuu.cn
eabb51c54a fix 2020-06-01 21:51:48 +08:00
iyuu.cn
1e1a7bfc59 $configALL[$siteName]['count'] 初始化。 2020-06-01 21:48:38 +08:00
iyuu.cn
005788827d SSD加入辅种计数器(限制每次辅种10个),降低初次辅种过多ban禁IP的可能性。 2020-06-01 21:45:57 +08:00
iyuu.cn
ffb600c334 新增上报错误种子403状态码,例如:兼容杜比等站已删除种子返回403状态码的情况。 2020-05-18 12:52:57 +08:00
iyuu.cn
290bfbe5c9 优化build.sh编译脚本 2020-05-12 18:41:52 +08:00
iyuu.cn
6ecf4f1d54 更新README.MD 2020-05-06 16:37:54 +08:00
iyuu.cn
c809e8d052 v1.7.9 2020-05-06 12:38:27 +08:00
iyuu.cn
8d7dffbf3d 新增站点:海胆haidan 2020-05-06 12:37:43 +08:00
iyuu.cn
cc50804b40 优化URL获取的代码结构 2020-05-01 09:43:35 +08:00
iyuu.cn
4444aec4fb v1.7.8 2020-04-26 22:15:06 +08:00
iyuu.cn
68e128e5cd 小钢炮安装脚本添加/BT_backup目录挂载至docker 2020-04-26 22:14:14 +08:00
iyuu.cn
ec7032698d 更改文件名与Readme.md 2020-04-17 11:57:06 +08:00
iyuu.cn
5308c691b6 更新Readme.md 2020-04-11 13:59:04 +08:00
iyuu.cn
c7f4859cb7 新增支持站点伊甸园hdbd。 2020-04-11 10:16:25 +08:00
iyuu.cn
dc651174b8 v1.7.6 2020-04-07 23:19:28 +08:00
iyuu.cn
a95e579cf6 v1.7.6 2020-04-07 23:00:29 +08:00
iyuu.cn
4811937f42 优化注释 2020-04-06 15:03:19 +08:00
iyuu.cn
f9674c1898 微信报表,增加脚本版本号显示 2020-04-06 15:03:04 +08:00
iyuu.cn
2fdacc6936 更新教程 2020-04-06 15:02:06 +08:00
iyuu.cn
a2034f2840 新增合作站点MoeCat 2020-04-03 22:27:08 +08:00
iyuu.cn
4894464fdd 优化部分php环境CURLOPT_SSL_VERIFYHOST参数设置为false后,卡顿问题。 2020-04-03 21:03:58 +08:00
iyuu.cn
c90acbec6c 路径转换方法:提高替换模式的兼容性。 2020-04-03 12:19:03 +08:00
iyuu.cn
c4a8cef4ce 修改build.sh脚本,新增小钢炮专用脚本 2020-03-27 14:59:26 +08:00
iyuu.cn
cc7eb9b06a 添加、修改教程。 2020-03-27 14:58:41 +08:00
iyuu.cn
ea3f3deaa8 更新小钢炮docker脚本环境构建教程,新增小钢炮专用创建脚本。 2020-03-27 14:23:38 +08:00
iyuu.cn
44c0bcdeb4 没用$path == $key判断,是为了提高兼容性 2020-03-27 11:41:10 +08:00
iyuu.cn
d015cd56a6 fix 2020-03-26 23:49:56 +08:00
iyuu.cn
4cf1222b37 注释curl证书验证,本设置会引起部分站点的https访问失败,返回Empty reply from server错误 2020-03-26 18:31:08 +08:00
iyuu.cn
b5f4537df7 新增站点HDRoute 2020-03-25 23:49:17 +08:00
iyuu.cn
1e428a04b7 优化精简路径转换返回 2020-03-25 19:20:35 +08:00
iyuu.cn
4c7fd2cf3d 更新readme.md接口说明的部分 2020-03-25 19:02:13 +08:00
iyuu.cn
43b8bc050b 精简示例配置 2020-03-25 18:49:24 +08:00
iyuu.cn
1c1ecd33b8 提示当前脚本路径。 2020-03-25 17:44:56 +08:00
iyuu.cn
e201505dca 优化git_pull.sh脚本:自动拉取最新代码,然后执行辅种脚本。 2020-03-25 13:49:58 +08:00
iyuu.cn
e02d32b129 v1.7.1 2020-03-25 12:43:09 +08:00
iyuu.cn
01a9b71e9f 为避免多php版本带来困扰,cmd批处理内php采用环境变量调用。 2020-03-25 12:31:30 +08:00
iyuu.cn
f89b5f7325 v1.7.0 2020-03-23 13:19:45 +08:00
iyuu.cn
5880f563e8 增加通用备份脚本,可以添加进计划任务。 2020-03-23 13:05:03 +08:00
iyuu.cn
61eb8f69c9 简化辅种输出。 2020-03-22 11:29:47 +08:00
iyuu.cn
b4ca455a75 优化输出提示,未填写passkey的站点自动跳过,不提示。 2020-03-22 11:24:52 +08:00
iyuu.cn
02205e6ce3 修复transmission往qBittorrent转移种子,错误的问题。 2020-03-21 19:33:50 +08:00
iyuu.cn
818794a19b 错误提示后面增加换行符。 2020-03-19 19:58:10 +08:00
iyuu.cn
88bc79ff58 版本升级至v1.6.7 2020-03-16 15:00:00 +08:00
iyuu.cn
f9164b6e53 修改php文件夹名称,让脚本更通用 2020-03-16 14:50:33 +08:00
iyuu.cn
687a83f80d 添加公告 2020-03-15 23:20:07 +08:00
iyuu.cn
253cff0e23 增加Windows从gitee安装脚本批处理。 2020-03-15 13:12:50 +08:00
iyuu.cn
ed1d4fbe11 新增合作站点pthome,可以对使用接口的用户进行认证绑定。 2020-03-15 12:42:27 +08:00
iyuu.cn
99c2655fd4 调整配置顺序 2020-03-15 00:54:58 +08:00
iyuu.cn
7adbadd700 修复一处错误。 2020-03-14 22:55:31 +08:00
iyuu.cn
6e4c530128 减少sleep等待时间为1秒。 2020-03-14 17:21:20 +08:00
iyuu.cn
9d183d742d 优化完善转移做种客户端时,出现的错误提示。 2020-03-14 17:20:46 +08:00
iyuu.cn
f5bc84e23d 优化合作站点登录逻辑,设置登录缓存,减少请求。 2020-03-14 17:20:02 +08:00
iyuu.cn
77443896dd 更新教程 2020-03-13 23:40:04 +08:00
iyuu.cn
657f092eef 新增公告 2020-03-13 23:35:06 +08:00
iyuu.cn
59b2d5b4ca 简化docker编译文件 2020-03-13 23:30:00 +08:00
iyuu.cn
b64abe55d5 新增3篇安装教程 2020-03-13 21:29:23 +08:00
iyuu.cn
df6761bbc3 composer dump-autoload 2020-03-13 21:28:58 +08:00
iyuu.cn
880775b815 新增hdhome合作站点用户id认证配置 2020-03-13 14:51:25 +08:00
iyuu.cn
0a29e7ed2f 修复瓷器辅种显示乱码不美观的问题 2020-03-12 08:08:01 +08:00
iyuu.cn
75e66e3b0b 新增合作站点hdhome,可以对使用接口的用户进行认证绑定。 2020-03-12 00:00:53 +08:00
iyuu.cn
948e68f55b 版本号升级到:v1.6.0 2020-03-11 23:46:42 +08:00
iyuu.cn
c35bbe0c91 新增合作站点hddolby,可以对使用接口的用户进行认证绑定。 2020-03-11 23:42:39 +08:00
iyuu.cn
fb68d21589 更新最简配置wiki 2020-03-10 14:38:28 +08:00
iyuu.cn
fa31319399 增加composer一键安装批处理 2020-03-09 13:48:36 +08:00
iyuu.cn
9597182628 新增3种安装方式,并提供安装命令 2020-03-09 13:48:02 +08:00
iyuu.cn
61d3ca843d 修复因不支持站点辅种缓存引起的错误提示。 2020-03-09 13:37:59 +08:00
iyuu.cn
4a63353d27 增加git更新批处理 2020-03-03 16:43:12 +08:00
iyuu.cn
07b0b2626d 紧急修复:qBittorrent的paused自动暂停参数为字符串的bug(此问题为上次转移做种配置项添加自定义后留下来的问题。) 2020-03-02 00:32:05 +08:00
iyuu.cn
755bb1d526 优化git自动更新sh脚本,防止因手动更改文件导致更新失败。 2020-03-01 13:39:09 +08:00
iyuu.cn
9a39306990 人性化的加入vendor目录。 2020-03-01 13:36:03 +08:00
iyuu.cn
43a90f40d3 优化做种客户端转移配置的提示,更清晰易懂。 2020-02-29 21:46:57 +08:00
iyuu.cn
fa60001758 修改示例配置的注释,以免混淆 2020-02-26 21:46:36 +08:00
iyuu.cn
80ca5e9690 添加git自动更新命令 2020-02-26 17:33:45 +08:00
iyuu.cn
550e53d5e0 转移种子,设置自动开始开关 2020-02-26 16:07:51 +08:00
iyuu.cn
ccd0acd7f6 添加更新历史 2020-02-26 16:07:36 +08:00
iyuu.cn
b788ef1245 新增站点:葡萄pt 2020-02-25 23:30:15 +08:00
iyuu.cn
17e9a494ee 升级docker制作脚本,每次制作都是最新版。 2020-02-25 21:03:54 +08:00
iyuu.cn
0ccc4f6342 优化过滤transmission连接URL兼容性(修复网址后有斜杠,无法连接的问题) 2020-02-24 14:47:36 +08:00
iyuu.cn
93208b3dc3 从composer创建工程 2020-02-23 19:49:21 +08:00
iyuu.cn
082700cf5d 发布包到composer,v1.5.3 2020-02-23 19:35:47 +08:00
iyuu.cn
d2269aa1ef git@github.com:ledccn/IYUUAutoReseed.git 2020-02-23 19:26:36 +08:00
iyuu.cn
95a81499c3 创建composer包:ledccn/IYUUAutoReseed 2020-02-23 19:19:37 +08:00
iyuu.cn
2f4ad383a7 创建composer包:iyuu/IYUUAutoReseed 2020-02-23 19:12:21 +08:00
iyuu.cn
9b62e84cda 加入git自动更新脚本 2020-02-23 16:25:38 +08:00
iyuu.cn
125394ee0b 优化提高Windows平台转移做种客户端的兼容性 2020-02-23 01:19:25 +08:00
iyuu.cn
efa11d280d 更新教程 2020-02-22 20:56:13 +08:00
iyuu.cn
18f860713f 新增公告:转移做种常见错误 2020-02-22 16:35:17 +08:00
iyuu.cn
264aef754e 更新文档、新增支持站点天雪v1.5.2 2020-02-21 21:24:22 +08:00
iyuu.cn
c178046435 新增站点天雪,添加配置即可辅种。 2020-02-21 21:08:17 +08:00
iyuu.cn
397106cad9 更新公告 2020-02-21 19:07:14 +08:00
iyuu.cn
cc3a4ec1b8 删除海豚音乐配置 2020-02-21 18:14:05 +08:00
iyuu.cn
d87029c4f4 修复bug 修订版本号+1 2020-02-21 08:59:27 +08:00
iyuu.cn
7f2889ba1e 修正海豚音乐torrent_pass、authkey正确名称
紧急更新v1.5.1
2020-02-21 08:40:29 +08:00
iyuu.cn
185157a00c 添加部分,更新历史 2020-02-21 07:23:42 +08:00
iyuu.cn
9ad36efed8 更新开发计划 2020-02-21 07:23:17 +08:00
iyuu.cn
d0fc64beb1 更新wiki教程 2020-02-21 07:23:03 +08:00
iyuu.cn
426e47337d 版本号升级至1.5.0
新增海豚音乐
2020-02-21 06:46:53 +08:00
iyuu.cn
37809f7bfe 新增海豚音乐示例配置 2020-02-21 06:42:54 +08:00
iyuu.cn
721aaf217b 新增海豚音乐dicmusic,更新捐赠名单 2020-02-21 06:42:35 +08:00
iyuu.cn
aa18b23dbb 增加转移做种搜索目录命令find / -name BT_backup 2020-02-20 21:03:31 +08:00
iyuu.cn
4d452e3909 优化大于一万条做种,防止精简配置,导致超时设置无效。 2020-02-20 18:09:50 +08:00
iyuu.cn
741ccb4fb4 优化大于一万条做种时辅种失败问题。 2020-02-20 17:49:50 +08:00
iyuu.cn
e336970fca 小钢炮使用docker版qb 4.1.6 简明教程 2020-02-20 17:48:24 +08:00
iyuu.cn
0321deee01 小钢炮qBittorrent连接失败的处理办法 2020-02-20 17:05:57 +08:00
iyuu.cn
08ef3769c2 删除示例配置圣城cnscg 2020-02-20 16:33:31 +08:00
iyuu.cn
1355398f76 修复扩展参数extra_options错误 2020-02-20 16:13:15 +08:00
iyuu.cn
53533df4b9 新增两个API接口 2020-02-20 09:20:16 +08:00
iyuu.cn
53902ee878 优化https判断 2020-02-20 06:52:31 +08:00
iyuu.cn
60430f6550 代码格式化 2020-02-19 13:33:58 +08:00
iyuu.cn
9445547378 修复transmission添加任务后,ID无法显示的bug 2020-02-19 02:45:27 +08:00
iyuu.cn
8ba1ef1ff4 新增docker容器安装使用方法 2020-02-18 21:23:19 +08:00
iyuu.cn
ca148bac6b 更新忽略列表 2020-02-18 18:02:40 +08:00
iyuu.cn
3393eae7e7 新增做种列表备份功能,便于紧急恢复。 2020-02-18 16:02:16 +08:00
iyuu.cn
06c00f88dc 增加版本号,用于服务器端限定 2020-02-18 15:08:57 +08:00
iyuu.cn
854121884b 新增转移成功跳校验、转移成功删除当前做种功能。 2020-02-18 14:48:35 +08:00
iyuu.cn
da88f3e7fc 新增种子删除上报功能! 2020-02-17 16:54:27 +08:00
iyuu.cn
3abc02d660 修改示例配置 2020-02-17 16:46:59 +08:00
iyuu.cn
339f1304c6 优化日志记录 2020-02-16 20:51:39 +08:00
iyuu.cn
c4df9899c8 修复transmission添加任务成功后,获取名字和id 2020-02-16 15:10:15 +08:00
iyuu.cn
6494351ff3 修复transmission返回值判断错误 2020-02-16 14:39:23 +08:00
iyuu.cn
e01dbfd601 审查代码,删除无用接口 2020-02-16 01:26:40 +08:00
iyuu.cn
940f948f43 增加客户端文件是否存在判断 2020-02-15 22:12:12 +08:00
iyuu.cn
958bef0dfa windows大小写不敏感,新增 2020-02-15 19:24:58 +08:00
iyuu.cn
ea74b96293 windows大小写不敏感,删除 2020-02-15 19:24:10 +08:00
iyuu.cn
94948610e4 优化瓷器cookie有效性检查 2020-02-15 19:20:12 +08:00
iyuu.cn
0f1605ffca 修改transmission首字母小写 2020-02-15 16:05:05 +08:00
iyuu.cn
33ff8a991a 优化工厂模式创建客户端实例
增加新功能:本地做种客户端转移
2020-02-15 09:20:41 +08:00
iyuu.cn
877616214c 新增本地转移做种客户端示例配置 2020-02-15 09:19:20 +08:00
iyuu.cn
aa4a8c76fe 升级php版本号 2020-02-12 14:50:05 +08:00
iyuu.cn
f6870a4e95 增加瓷器的第一次下载种子检测 2020-02-12 14:16:38 +08:00
iyuu.cn
e073f165ac 优化提示信息。echo对隐私信息脱敏 2020-02-09 23:20:20 +08:00
iyuu.cn
6144b8b301 更新Readme.md 2020-02-08 11:59:30 +08:00
iyuu.cn
658d764c26 修复pathReplace方法返回值错误 2020-02-08 11:27:10 +08:00
iyuu.cn
2ce1920c51 后端API迁移至新架构,升级版本号到1.0.0 2020-02-07 18:31:51 +08:00
iyuu.cn
ea158ddd55 规范代码 2020-02-01 21:47:26 +08:00
IYUU
76c0cefca2 变更忽略列表 2020-01-31 20:55:27 +08:00
IYUU
a69a2c2955 变更忽略列表 2020-01-31 20:51:52 +08:00
IYUU
7dc0c54c56 排除列表 2020-01-31 20:50:24 +08:00
IYUU
19197d36ce 整合vendor依赖目录 2020-01-31 15:16:18 +08:00
IYUU
8561fac8c4 修改示例配置IP为本机 2020-01-31 12:28:07 +08:00
IYUU
e4911871b8 新增Windows辅种一键脚本 2020-01-31 11:18:00 +08:00
IYUU
a328f68178 完善逻辑 2020-01-31 03:00:32 +08:00
IYUU
ce65b5d1ff 规范换行符 2020-01-31 01:07:18 +08:00
IYUU
dff0c17b33 调整顺序 2020-01-31 00:35:43 +08:00
IYUU
7dcd3e55f4 更新https支持 2020-01-30 22:00:21 +08:00
IYUU
9027262f57 更新文档 2020-01-30 21:52:34 +08:00
IYUU
31d0e6ee03 优化辅种CCFBits下载种子方法。 2020-01-30 17:33:34 +08:00
IYUU
076e688e1c 修复CCFBits自动评论 2020-01-30 16:41:36 +08:00
IYUU
c649c05a3a 新增CCFBits站点支持 2020-01-30 13:57:10 +08:00
IYUU
4896e08635 CCFBits辅种时智能启用评论 2020-01-30 13:22:48 +08:00
IYUU
3b3289274b 完善转移功能:当启用转移功能时,可以设置是否辅种被转移客户端。 2020-01-30 11:33:46 +08:00
IYUU
bf65f7039d 示例配置内增加教程 2020-01-29 15:11:02 +08:00
IYUU
0a7c2120a1 修复str_replace($key, '', $path, 1);执行错误的bug 2020-01-29 14:43:30 +08:00
IYUU
04a10295c2 更新文档 2020-01-29 00:42:52 +08:00
IYUU
3e75aec9d0 减少依赖包 2020-01-29 00:08:58 +08:00
IYUU
63ce263afb 新增做种客户端移动,新增北邮人辅种 2020-01-28 23:57:18 +08:00
iyuu.cn
19df3f3cfb 格式化代码 2020-01-22 22:56:35 +08:00
iyuu.cn
66490efad7 优化错误提示,优化辅种匹配算法 2020-01-22 20:00:21 +08:00
iyuu.cn
9044d3575e 更新参数 2020-01-22 14:19:17 +08:00
iyuu.cn
69ba1ebe56 wiki加入RSS订阅使用教程 2020-01-22 12:10:32 +08:00
iyuu.cn
978295b44d 更新示例配置,支持RSS订阅 2020-01-22 12:05:08 +08:00
iyuu.cn
f3b4deae4c 标准化格式 2020-01-22 10:47:33 +08:00
iyuu.cn
fcb2384949 增加乱码解决方法 2020-01-22 09:37:21 +08:00
iyuu.cn
33b55d7598 新增更新历史信息 2020-01-22 08:50:58 +08:00
iyuu.cn
db8290fe89 新增RSS订阅新种命令 2020-01-22 08:50:35 +08:00
iyuu.cn
81083220c5 修正站点鉴权帮助文档 2020-01-22 08:50:13 +08:00
iyuu.cn
39cb00d648 新增常见问题 2020-01-22 08:49:40 +08:00
iyuu.cn
db9010cee7 新增排除文件。 2020-01-21 17:53:17 +08:00
iyuu.cn
ad6f798946 新增json支持的站点列表本地化 2020-01-21 11:00:46 +08:00
iyuu.cn
36d07a25db 新增在线查询支持站点表格显示 2020-01-21 02:18:51 +08:00
iyuu.cn
7c35291b15 新增Windows系统composer install安装依赖包命令 2020-01-21 01:17:57 +08:00
iyuu.cn
7d531a26c8 Transmission兼容支持https链接 2020-01-20 14:09:04 +08:00
iyuu.cn
385a122f02 更新捐赠名单 2020-01-19 12:56:45 +08:00
iyuu.cn
f75feeca44 更新数据清理 2020-01-19 12:35:41 +08:00
iyuu.cn
d8fc340691 修改hdbug站点示例配置信息 2020-01-18 23:11:31 +08:00
iyuu.cn
2345124ce0 更新数据 2020-01-18 21:25:31 +08:00
iyuu.cn
f9592c6b0d 新增IYUU入口文件 2020-01-18 20:13:21 +08:00
iyuu.cn
fd695e4209 更新数据清理时间 2020-01-18 12:16:56 +08:00
iyuu.cn
8ddb143485 新增wlog日志助手函数 2020-01-18 12:16:25 +08:00
iyuu.cn
ef2668ca54 完善各种日志的输出 2020-01-18 12:16:07 +08:00
iyuu.cn
51f3fa39bc 检查代码缩进规范 2020-01-18 10:27:27 +08:00
iyuu.cn
84b3f23c27 完善下载最新源码的教程 2020-01-17 21:35:36 +08:00
76 changed files with 7539 additions and 2221 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
.git
*

81
.gitignore vendored
View File

@@ -1,8 +1,79 @@
/torrent
/composer
/config/config.php
/php-7.2.12-nts
/config/*.json
/php
/torrent
/runtime
/*.bat
/*.sh
/vendor
/composer.lock
.idea
.php_cs.cache
.php_cs.cache
composer.phar
.fuse_hidden*
.directory
.Trash-*
.nfs*
### OSX ###
# General
.DS_Store
.AppleDouble
.LSOverride
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/osx,linux,windows,visualstudiocode,composer

4
1.Windows辅种.cmd Normal file
View File

@@ -0,0 +1,4 @@
@echo off
chcp 65001
%~dp0php\php %~dp0iyuu.php
pause

View File

@@ -0,0 +1,6 @@
@echo off
chcp 65001
git fetch --all
git reset --hard origin/master
php %~dp0iyuu.php
pause

View File

@@ -0,0 +1,4 @@
@echo off
chcp 65001
php %~dp0iyuu.php
pause

114
Dockerfile Normal file
View File

@@ -0,0 +1,114 @@
#FROM alpine:latest
#FROM alpine:3.12
FROM alpine:3.8
#FROM swoft/alphp:base
#FROM swoft/alphp:cli
LABEL maintainer="david <367013672@qq.com>" version="1.0"
##
# ---------- env settings ----------
##
# --build-arg timezone=Asia/Shanghai
ARG timezone
# prod pre test dev
ARG app_env=prod
# default use www-data user
# ARG add_user=www-data
ENV APP_ENV=${app_env:-"prod"} \
TIMEZONE=${timezone:-"Asia/Shanghai"} \
cron="3 */10 * * *"
##
# ---------- building ----------
##
RUN set -ex \
# change apk source repo
#&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories \
&& apk update \
&& apk add --no-cache \
# Install base packages ('ca-certificates' will install 'nghttp2-libs')
# ca-certificates \
# curl \
# tar \
# xz \
# libressl \
# openssh \
# openssl \
git \
tzdata \
# pcre \
# install php7 and some extensions
php7 \
# php7-common \
# php7-bcmath \
php7-curl \
# php7-ctype \
php7-dom \
# php7-fileinfo \
# php7-gettext \
# php7-gd \
# php7-iconv \
# php7-imagick \
php7-json \
php7-mbstring \
#php7-mongodb \
# php7-mysqlnd \
# php7-openssl \
# php7-opcache \
# php7-pdo \
# php7-pdo_mysql \
# php7-pdo_sqlite \
# php7-phar \
# php7-pcntl \
# php7-posix \
# php7-redis \
php7-simplexml \
# php7-sockets \
# php7-sodium \
# php7-sqlite \
# php7-session \
# php7-sysvshm \
# php7-sysvmsg \
# php7-sysvsem \
# php7-tokenizer \
php7-zip \
# php7-zlib \
php7-xml \
&& git clone https://gitee.com/ledc/IYUUAutoReseed.git /IYUU \
&& cp /IYUU/config/config.sample.php /IYUU/config/config.php \
&& ln -sf /IYUU/config/config.php /config.php \
&& cp /IYUU/docker/entrypoint.sh /entrypoint.sh \
&& chmod +x /entrypoint.sh \
&& apk del --purge *-dev \
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man /usr/share/php7 \
# ---------- some config,clear work ----------
&& cd /etc/php7 \
# - config PHP
&& { \
echo "upload_max_filesize=100M"; \
echo "post_max_size=108M"; \
echo "memory_limit=1024M"; \
echo "date.timezone=${TIMEZONE}"; \
} | tee conf.d/99-overrides.ini \
# - config timezone
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo "${TIMEZONE}" > /etc/timezone \
&& echo '2 */5 * * * cd /IYUU && git fetch --all && git reset --hard origin/master' >> /etc/crontabs/root \
#&& echo "${cron} /usr/bin/php /IYUU/iyuu.php &> /dev/null" >> /etc/crontabs/root \
# ---------- some config work ----------
# - ensure 'www-data' user exists(82 is the standard uid/gid for "www-data" in Alpine)
# && addgroup -g 82 -S ${add_user} \
# && adduser -u 82 -D -S -G ${add_user} ${add_user} \
# # - create user dir
# && mkdir -p /data \
# && chown -R ${add_user}:${add_user} /data \
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
# EXPOSE 9000
# VOLUME ["/IYUU", "/data"]
WORKDIR /IYUU
ENTRYPOINT ["/entrypoint.sh"]

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,769 +0,0 @@
<?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)
*/
namespace IYUU\Client\Transmission;
use IYUU\Client\AbstractClientInterface;
/**
* A friendly little version check...
*/
if (version_compare(PHP_VERSION, '5.2.10', '<')) {
die("The TransmissionRPC class requires PHP version 5.2.10 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 implements AbstractClientInterface
{
/**
* 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;
/**
* 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;
}
/**
* Start one or more torrents
*
* @param int|array ids A list of transmission torrent ids
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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
* }
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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 string $torrent_location The URL or path to the torrent file
* @param string $save_path Folder to save torrent in
* @param array $extra_options Optional extra torrent options
* @return mixed
* @throws TransmissionRPCException
*/
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 string $torrent_metainfo The raw, unencoded contents (metainfo) of a torrent
* @param string $save_path Folder to save torrent in
* @param array $extra_options Optional extra torrent options
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return mixed
* @throws TransmissionRPCException
*/
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
* @return string
*/
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
* @return array|null
*/
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
* @return array|object
*/
protected function cleanResultObject($object)
{
// Prepare and cast object to array
$return_as_array = false;
$array = $object;
if (!is_array($array)) {
$array = (array)$array;
}
foreach ($array as $index => $value) {
if (is_array($array[$index]) || is_object($array[$index])) {
$array[$index] = $this->cleanResultObject($array[$index]); // Recursion
}
if (strstr($index, '-')) {
$valid_index = str_replace('-', '_', $index);
$array[$valid_index] = $array[$index];
unset($array[$index]);
$index = $valid_index;
}
// Might be an array, check index for digits, if so, an array should be returned
if (ctype_digit((string)$index)) {
$return_as_array = true;
}
if (empty($value)) {
unset($array[$index]);
}
}
// Return array cast to object
return $return_as_array ? $array : (object)$array;
}
/**
* 执行 rpc 请求
*
* @param string $method 请求类型/方法, 详见 $this->allowMethods
* @param array $arguments 附加参数, 可选
* @return mixed
* @throws TransmissionRPCException
*/
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_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT, 600);
$content = curl_exec($ch);
curl_close($ch);
if (!$content) {
$content = json_encode(array('result' => 'failed'));
}
return $this->return_as_array ? json_decode($content, true) : $this->cleanResultObject(json_decode($content)); // Return the sanitized result
}
/**
* Performs an empty GET on the Transmission RPC to get the X-Transmission-Session-Id
* and store it in $this->session_id
*
* @return string
* @throws TransmissionRPCException
*/
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;
}
/**
* @inheritDoc
*/
public function status()
{
return isset($this->sstats()->result) ? $this->sstats()->result : 'error';
}
}

View File

@@ -1,48 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 1/17/2020
* Time: 2020
*/
namespace IYUU\Client\Transmission;
/**
* 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);
}
}
}

View File

@@ -1,310 +0,0 @@
<?php
namespace IYUU\Client\qBittorrent;
use Curl\Curl;
use IYUU\Client\AbstractClientInterface;
/**
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation
*/
class qBittorrent implements AbstractClientInterface
{
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); // 不检查证书
$this->curl->setOpt(CURLOPT_CONNECTTIMEOUT, 60); // 超时
$this->curl->setOpt(CURLOPT_TIMEOUT, 600); // 超时
// 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;
#$extra_options['skip_checking'] = 'true'; //跳校验
// 关键 上传文件流 multipart/form-data【严格按照api文档编写】
$post_data = $this->buildData($extra_options);
#p($post_data);
// 设置请求头
$this->curl->setHeader('Content-Type', 'multipart/form-data; boundary='.$this->delimiter);
$this->curl->setHeader('Content-Length', strlen($post_data));
return $this->postData('torrent_add', $post_data);
}
public function torrentDelete($hash='', $deleteFiles = false)
{
return $this->postData('torrent_delete', ['hashes' => $hash, 'deleteFiles' => $deleteFiles ? 'true':'false']);
}
public function torrentDeleteAll($deleteFiles = false)
{
$torrents = json_decode($this->torrentList());
$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. '"' . $eol . $eol;
$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 = '';
// 拼接文件流
$data .= "--" . $this->delimiter . $eol;
$data .= 'Content-Disposition: form-data; name="' .$param['name']. '"; filename="'.$param['filename'].'"' . $eol;
$data .= 'Content-Type: application/x-bittorrent' . $eol . $eol;
$data .= $param['torrents'] . $eol;
unset($param['name']);
unset($param['filename']);
unset($param['torrents']);
if (!empty($param)) {
foreach ($param as $name => $content) {
$data .= "--" . $this->delimiter . $eol;
$data .= 'Content-Disposition: form-data; name="' . $name . '"' . $eol . $eol;
$data .= $content . $eol;
}
}
$data .= "--" . $this->delimiter . "--" . $eol;
return $data;
}
/**
* @inheritDoc
*/
public function status()
{
return $this->appVersion();
}
}

View File

@@ -1,9 +1,4 @@
<?php
/**
* @brief 文件处理
* @version 0.6
*/
namespace IYUU\Library;
/**
@@ -13,7 +8,6 @@ namespace IYUU\Library;
class IFile
{
private $resource = null; //文件资源句柄
/**
* @brief 构造函数,打开资源流,并独占锁定
* @param String $fileName 文件路径名
@@ -106,9 +100,10 @@ class IFile
/**
* @brief 创建文件夹
* @param String $path 路径
* @param int $chmod 文件夹权限
* @param String $path 路径
* @param int $chmod 文件夹权限
* @note $chmod 参数不能是字符串(加引号)否则linux会出现权限问题
* @return bool
*/
public static function mkdir($path, $chmod=0777)
{
@@ -119,7 +114,7 @@ class IFile
* @brief 复制文件
* @param String $from 源文件路径
* @param String $to 目标文件路径
* @param String $mod 操作模式c:复制(默认); x:剪切(删除$from文件)
* @param String $mode 操作模式c:复制(默认); x:剪切(删除$from文件)
* @return bool 操作结果 true:成功; false:失败;
*/
public static function copy($from, $to, $mode = 'c')
@@ -184,7 +179,7 @@ class IFile
/**
* @brief 获取文件类型
* @param String $fileName 文件名
* @return String $filetype 文件类型
* @return String|array $filetype 文件类型
* @note 如果文件不存在返回false,如果文件后缀名不在识别列表之内返回NULL对于docx及elsx格式文档识别在会出现识别为ZIP格式的错误这是office2007的bug目前尚未修复请谨慎使用
*/
public static function getFileType($fileName)

View File

@@ -1,78 +1,101 @@
<?php
/**
* IYUU用户注册、认证
*/
namespace IYUU\Library;
use Curl\Curl;
/**
* IYUU用户注册、认证
*/
class Oauth
{
// 合作的站点
public static $sites = ['ourbits'];
// 爱语飞飞token
public static $token = '';
// 合作站点用户id
public static $user_id = 0;
// 合作站点密钥
public static $passkey = '';
// 合作站名字
public static $site = '';
/**
* 初始化配置
*/
public static function init()
{
global $configALL;
foreach (self::$sites as $name) {
if (isset($configALL[$name]['passkey']) && $configALL[$name]['passkey'] && isset($configALL[$name]['id']) && $configALL[$name]['id']) {
self::$token = self::getSign();
self::$user_id = $configALL[$name]['id'];
self::$passkey = sha1($configALL[$name]['passkey']); // 避免泄露用户passkey秘钥
self::$site = $name;
return true;
}
}
echo "-----缺少合作站点登录参数token, user_id, passkey, site \n";
echo "-----当前正在使用测试接口,功能可能会受到限制! \n\n";
return false;
}
// 登录缓存路径
const SiteLoginCache = ROOT_PATH.DS.'config'.DS.'siteLoginCache_{}.json';
/**
* 从配置文件内读取爱语飞飞token作为鉴权参数
*/
public static function getSign()
{
global $configALL;
// 爱语飞飞
$token = isset($configALL['iyuu.cn']) && $configALL['iyuu.cn'] ? $configALL['iyuu.cn'] : '';
if (empty($token) || strlen($token)<46) {
echo "缺少辅种接口请求参数爱语飞飞token \n";
echo "请访问https://iyuu.cn 用微信扫码申请并填入配置文件config.php内。\n\n";
$token = empty($configALL['iyuu.cn']) ? '' : $configALL['iyuu.cn'];
if (empty($token) || strlen($token) < 46) {
echo "缺少辅种接口请求参数爱语飞飞token ".PHP_EOL;
echo "请访问https://iyuu.cn 用微信扫码申请并填入配置文件config.php内。".PHP_EOL.PHP_EOL;
exit(1);
}
return $token;
}
/**
* 用户注册与登录
* 作用在服务器端实现微信用户与合作站点用户id的关联
* 参数爱语飞飞token + 合作站点用户id + sha1(合作站点密钥passkey) + 合作站点标识
* @param string $apiUrl
* @param array $sites
* @return bool
* @throws \ErrorException
*/
public static function login($apiUrl = '')
public static function login($apiUrl = '', $sites = array())
{
$is_oauth = self::init();
if ($is_oauth) {
$curl = new Curl();
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
$data = [
'token' => self::$token,
'id' => self::$user_id,
'passkey'=> self::$passkey,
'site' => self::$site,
];
$res = $curl->get($apiUrl, $data);
p($res->response);
return true;
global $configALL;
// 云端下发合作的站点标识
if (empty($sites)) {
die('云端下发合作站点信息失败,请稍后重试');
}
return false;
$_sites = array_column($sites, 'site');
$ret = false;
$token = self::getSign();
foreach ($_sites as $k => $site) {
if (is_file(str_replace('{}', $site, self::SiteLoginCache))) {
// 存在鉴权缓存
$ret = true;
continue;
}
if (isset($configALL[$site]['passkey']) && $configALL[$site]['passkey'] && isset($configALL[$site]['id']) && $configALL[$site]['id']) {
$user_id = $configALL[$site]['id'];
$passkey = $configALL[$site]['passkey'];
$curl = new Curl();
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
$data = [
'token' => $token,
'id' => $user_id,
'passkey'=> sha1($passkey), // 避免泄露用户passkey秘钥
'site' => $site,
];
$res = $curl->get($apiUrl, $data);
p($res->response);
$rs = json_decode($res->response, true);
if (isset($rs['ret']) && ($rs['ret'] === 200) && isset($rs['data']['success']) && $rs['data']['success']) {
self::setSiteLoginCache($site, $rs);
$ret = true;
} else {
$msg = !empty($rs['msg']) ? $rs['msg'] : '远端服务器无响应,请稍后重试!';
$msg = !empty($rs['data']['errmsg']) ? $rs['data']['errmsg'] : $msg;
echo $msg . PHP_EOL;
}
} else {
echo $site.'合作站点参数配置不完整请同时填写passkey和用户id。' . PHP_EOL;
echo '合作站点鉴权配置请查阅https://www.iyuu.cn/archives/337/'. PHP_EOL. PHP_EOL;
}
}
return $ret;
}
/**
* 写鉴权成功缓存
* @desc 作用:减少对服务器请求,跳过鉴权提示信息;
* @param string $site
* @param array $array
* @return bool|int
*/
private static function setSiteLoginCache($site = '', $array = [])
{
$json = json_encode($array, JSON_UNESCAPED_UNICODE);
$myfile = str_replace('{}', $site, self::SiteLoginCache);
$file_pointer = @fopen($myfile, "w");
$worldsnum = @fwrite($file_pointer, $json);
@fclose($file_pointer);
return $worldsnum;
}
}

269
app/Library/Table.php Normal file
View File

@@ -0,0 +1,269 @@
<?php
namespace IYUU\Library;
/**
* Created by PhpStorm.
* User: 大卫
* Date: 2020-1-19
* Time: 17:44
*/
class Table
{
const ALIGN_LEFT = 1;
const ALIGN_RIGHT = 0;
const ALIGN_CENTER = 2;
/**
* 头信息数据
* @var array
*/
protected $header = [];
/**
* 头部对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
* @var int
*/
protected $headerAlign = 1;
/**
* 表格数据(二维数组)
* @var array
*/
protected $rows = [];
/**
* 单元格对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
* @var int
*/
protected $cellAlign = 1;
/**
* 单元格宽度信息
* @var array
*/
protected $colWidth = [];
/**
* 表格输出样式
* @var string
*/
protected $style = 'default';
/**
* 表格样式定义
* @var array
*/
protected $format = [
'compact' => [],
'default' => [
'top' => ['+', '-', '+', '+'],
'cell' => ['|', ' ', '|', '|'],
'middle' => ['+', '-', '+', '+'],
'bottom' => ['+', '-', '+', '+'],
'cross-top' => ['+', '-', '-', '+'],
'cross-bottom' => ['+', '-', '-', '+'],
],
'markdown' => [
'top' => [' ', ' ', ' ', ' '],
'cell' => ['|', ' ', '|', '|'],
'middle' => ['|', '-', '|', '|'],
'bottom' => [' ', ' ', ' ', ' '],
'cross-top' => ['|', ' ', ' ', '|'],
'cross-bottom' => ['|', ' ', ' ', '|'],
],
'borderless' => [
'top' => ['=', '=', ' ', '='],
'cell' => [' ', ' ', ' ', ' '],
'middle' => ['=', '=', ' ', '='],
'bottom' => ['=', '=', ' ', '='],
'cross-top' => ['=', '=', ' ', '='],
'cross-bottom' => ['=', '=', ' ', '='],
],
'box' => [
'top' => ['┌', '─', '┬', '┐'],
'cell' => ['│', ' ', '│', '│'],
'middle' => ['├', '─', '┼', '┤'],
'bottom' => ['└', '─', '┴', '┘'],
'cross-top' => ['├', '─', '┴', '┤'],
'cross-bottom' => ['├', '─', '┬', '┤'],
],
'box-double' => [
'top' => ['╔', '═', '╤', '╗'],
'cell' => ['║', ' ', '│', '║'],
'middle' => ['╠', '─', '╪', '╣'],
'bottom' => ['╚', '═', '╧', '╝'],
'cross-top' => ['╠', '═', '╧', '╣'],
'cross-bottom' => ['╠', '═', '╤', '╣'],
],
];
/**
* 设置表格头信息 以及对齐方式
* @access public
* @param array $header 要输出的Header信息
* @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
* @return void
*/
public function setHeader($header, $align = self::ALIGN_LEFT)
{
$this->header = $header;
$this->headerAlign = $align;
$this->checkColWidth($header);
}
/**
* 设置输出表格数据 及对齐方式
* @access public
* @param array $rows 要输出的表格数据(二维数组)
* @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
* @return void
*/
public function setRows($rows, $align = self::ALIGN_LEFT)
{
$this->rows = $rows;
$this->cellAlign = $align;
foreach ($rows as $row) {
$this->checkColWidth($row);
}
}
/**
* 检查列数据的显示宽度
* @access public
* @param mixed $row 行数据
* @return void
*/
protected function checkColWidth($row)
{
if (is_array($row)) {
foreach ($row as $key => $cell) {
if (!isset($this->colWidth[$key]) || strlen($cell) > $this->colWidth[$key]) {
$this->colWidth[$key] = strlen($cell);
}
}
}
}
/**
* 增加一行表格数据
* @access public
* @param mixed $row 行数据
* @param bool $first 是否在开头插入
* @return void
*/
public function addRow($row, $first = false)
{
if ($first) {
array_unshift($this->rows, $row);
} else {
$this->rows[] = $row;
}
$this->checkColWidth($row);
}
/**
* 设置输出表格的样式
* @access public
* @param string $style 样式名
* @return void
*/
public function setStyle($style)
{
$this->style = isset($this->format[$style]) ? $style : 'default';
}
/**
* 输出分隔行
* @access public
* @param string $pos 位置
* @return string
*/
protected function renderSeparator($pos)
{
$style = $this->getStyle($pos);
$array = [];
foreach ($this->colWidth as $width) {
$array[] = str_repeat($style[1], $width + 2);
}
return $style[0] . implode($style[2], $array) . $style[3] . PHP_EOL;
}
/**
* 输出表格头部
* @access public
* @return string
*/
protected function renderHeader()
{
$style = $this->getStyle('cell');
$content = $this->renderSeparator('top');
foreach ($this->header as $key => $header) {
$array[] = ' ' . str_pad($header, $this->colWidth[$key], $style[1], $this->headerAlign);
}
if (!empty($array)) {
$content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL;
if ($this->rows) {
$content .= $this->renderSeparator('middle');
}
}
return $content;
}
protected function getStyle($style)
{
if ($this->format[$this->style]) {
$style = $this->format[$this->style][$style];
} else {
$style = [' ', ' ', ' ', ' '];
}
return $style;
}
/**
* 输出表格
* @access public
* @param array $dataList 表格数据
* @return string
*/
public function render($dataList = [])
{
if ($dataList) {
$this->setRows($dataList);
}
// 输出头部
$content = $this->renderHeader();
$style = $this->getStyle('cell');
if ($this->rows) {
foreach ($this->rows as $row) {
if (is_string($row) && '-' === $row) {
$content .= $this->renderSeparator('middle');
} elseif (is_scalar($row)) {
$content .= $this->renderSeparator('cross-top');
$array = str_pad($row, 3 * (count($this->colWidth) - 1) + array_reduce($this->colWidth, function ($a, $b) {
return $a + $b;
}));
$content .= $style[0] . ' ' . $array . ' ' . $style[3] . PHP_EOL;
$content .= $this->renderSeparator('cross-bottom');
} else {
$array = [];
foreach ($row as $key => $val) {
$array[] = ' ' . str_pad($val, $this->colWidth[$key], ' ', $this->cellAlign);
}
$content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL;
}
}
}
$content .= $this->renderSeparator('bottom');
return $content;
}
}

View File

@@ -1,4 +1,7 @@
<?php
use IYUU\Library\IFile;
use IYUU\Library\Table;
/**
* 调试函数
* @param $data
@@ -136,7 +139,7 @@ function send($site = '', $torrent = array())
* @param string $method
* @return mixed 返回的数据
*/
function download($url, $cookies, $useragent, $method = 'GET')
function download($url, $cookies='', $useragent='', $method = 'GET')
{
$header = array(
"Content-Type:application/x-www-form-urlencoded",
@@ -145,7 +148,7 @@ function download($url, $cookies, $useragent, $method = 'GET')
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
}
if (stripos($url, 'https://') !== false) {
if (stripos($url, 'https://') === 0) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
@@ -192,6 +195,38 @@ function convertToMB($from)
}
}
/**
* 字节数Byte转换为KB、MB、GB、TB
* @param $num
* @return string
*/
function getFilesize($num)
{
$p = 0;
$format='bytes';
if ($num>0 && $num<1024) {
return number_format($num).' '.$format;
}
if ($num>=1024 && $num<pow(1024, 2)) {
$p = 1;
$format = 'KB';
}
if ($num>=pow(1024, 2) && $num<pow(1024, 3)) {
$p = 2;
$format = 'MB';
}
if ($num>=pow(1024, 3) && $num<pow(1024, 4)) {
$p = 3;
$format = 'GB';
}
if ($num>=pow(1024, 4) && $num<pow(1024, 5)) {
$p = 3;
$format = 'TB';
}
$num /= pow(1024, $p);
return number_format($num, 2).$format;
}
/**
* @brief 种子过滤器
* @param string $site 站点标识
@@ -286,22 +321,26 @@ function filter($site = '', $torrent = array())
}
/**
* transmission过滤函数只保留正常做种
* 日志记录函数
*/
function filterStatus($v)
function wlog($data='', $name = '', $path = '')
{
return isset($v['status']) && $v['status']===6;
}
/**
* qBittorrent过滤函数只保留正常做种
*/
function qbfilterStatus($v)
{
if (isset($v['state']) && in_array($v['state'], array('uploading','stalledUP','pausedUP','queuedUP','checkingUP','forcedUP'))) {
return true;
// 数据转换
if (is_bool($data)) {
$show_data=$data ? 'true' : 'false';
} elseif (is_null($data)) {
$show_data='null';
} else {
$show_data=print_r($data, true);
}
return false;
// 写入日志
$dir = $path===''? TORRENT_PATH . 'cache' . DS : $path;
IFile::mkdir($dir);
$myfile = $dir.$name.'.txt';
$file_pointer = @fopen($myfile, "a");
$worldsnum = @fwrite($file_pointer, $show_data);
@fclose($file_pointer);
return $worldsnum;
}
//PHP stdClass Object转array
@@ -317,3 +356,113 @@ function object_array($array)
}
return $array;
}
/**
* 奇数
*/
function oddFilter($var)
{
// 返回$var最后一个二进制位
// 为1则保留奇数的二进制的最后一位肯定是1
return($var & 1);
}
/**
* 偶数
*/
function evenFilter($var)
{
// 返回$var最后一个二进制位
// 为0则保留偶数的二进制的最后一位肯定是0
return(!($var & 1));
}
/**
* 发布员签名
* 注意同时配置iyuu.cn与secret时优先使用secret。
*/
function sign($timestamp)
{
global $configALL;
// 爱语飞飞
$token = isset($configALL['iyuu.cn']) && $configALL['iyuu.cn'] ? $configALL['iyuu.cn'] : '';
// 鉴权
$token = isset($configALL['secret']) && $configALL['secret'] ? $configALL['secret'] : $token;
return sha1($timestamp . $token);
}
/**
* @brief 分离token中的用户uid
* @desc token算法IYUU + uid + T + sha1(openid+time+盐)
* @param string $token 用户请求token
* @return bool|string
*/
function getUid($token)
{
//验证是否IYUU开头strpos($token,'T')<15,token总长度小于60(40+10+5)
return (strlen($token)<60)&&(strpos($token, 'IYUU')===0)&&(strpos($token, 'T')<15) ? substr($token, 4, strpos($token, 'T')-4): false;
}
/**
* 显示支持的站点列表
*/
function ShowTableSites($dir = 'Protocols', $filter = array())
{
// 过滤的文件
switch ($dir) {
case 'Protocols':
$filter = ['axxxx','decodeBase'];
break;
case 'Rss':
$filter = ['AbstractRss'];
break;
default:
# code...
break;
}
$data = [];
$i = $j = $k = 0; //i列、j序号、k行
foreach (glob(APP_PATH.$dir.DS.'*.php') as $key => $start_file) {
$start_file = str_replace("\\", "/", $start_file);
$offset = strripos($start_file, '/');
if ($offset===false) {
$start_file = substr($start_file, 0, -4);
} else {
$start_file = substr($start_file, $offset+1, -4);
}
// 过滤示例、过滤解码接口
if (in_array($start_file, $filter)) {
continue;
}
// 控制多少列
if ($i > 4) {
$k++;
$i = 0;
}
$i++;
$j++;
$data[$k][] = $j.". ".$start_file;
}
//输出表格
$table = new Table();
$table->setRows($data);
echo($table->render());
}
/**
* 是否win平台
* @return bool
*/
function isWin()
{
return (DIRECTORY_SEPARATOR == '\\') ? true : false;
}
function sleepIYUU($t, $msg)
{
echo $msg . PHP_EOL;
do {
echo microtime(true).$msg.' '.$t.'秒后继续...'.PHP_EOL;
sleep(1);
} while (--$t > 0);
}

30
backup.sh Normal file
View File

@@ -0,0 +1,30 @@
#!/bin/sh
# 传入的种子备份参数
if [ $1 ]; then
AppName=$1
else
echo 'AppName not null'
exit 1
fi
if [ $2 ]; then
torrentDir=$2
else
echo 'torrentDir not null'
exit 2
fi
# 脚本当前目录
pwddir=$(cd $(dirname $0); pwd)
# 当前日期
DATE=$(date +%Y%m%d)
# 备份在当前目录
backupdir=$pwddir"/"$AppName$DATE
echo "种子备份目录:"$backupdir
mkdir $backupdir -p
# 种子目录
torrentDir=$torrentDir"/*"
# 备份
cp -rf $torrentDir $backupdir
# 成功提示
echo "ok";

View File

@@ -1,10 +1,20 @@
{
"name": "ledccn/iyuuautoreseed",
"description": "IYUU自动辅种工具目前能对国内大部分的PT站点自动辅种支持下载器集群支持多盘位支持多下载目录支持远程连接等。",
"type": "project",
"keywords": ["iyuu", "reseed"],
"homepage": "https://github.com/ledccn/IYUUAutoReseed",
"authors": [
{
"name": "David"
}
],
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"ext-curl": "*",
"owner888/phpspider": "^2.1",
"curl/curl": "^2.2"
"curl/curl": "^2.3",
"ledccn/bittorrentclient": "dev-master"
},
"autoload": {
"psr-4": {

131
composer.lock generated
View File

@@ -1,131 +0,0 @@
{
"_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": []
}

View File

@@ -2,361 +2,696 @@
/**
* 技术讨论及后续更新请加入QQ群
群名称IYUU自动辅种交流
QQ群号859882209
* 手动配置方法,请查看:https://www.iyuu.cn/archives/324/
QQ群号859882209、931954050
* IYUU自动辅种工具-【安装篇】如何下载最新源码? https://www.iyuu.cn/archives/338/
* IYUU自动辅种工具-【安装篇】Windows之git https://www.iyuu.cn/archives/367/
* IYUU自动辅种工具-【安装篇】群晖Linux之git https://www.iyuu.cn/archives/372/
* IYUU自动辅种工具-【安装篇】小钢炮手把手教程 https://www.iyuu.cn/archives/386/
* IYUU自动辅种工具-【安装篇】全平台Docker安装方式 https://www.iyuu.cn/archives/401/
* IYUU自动辅种工具--最简配置(所有平台通用教程) https://www.iyuu.cn/archives/324/
* IYUU自动辅种工具--合作站点鉴权配置说明 https://www.iyuu.cn/archives/337/
* IYUU自动下载种子--之RSS订阅使用教程 https://www.iyuu.cn/archives/349/
* IYUU自动转移做种客户端--使用教程 https://www.iyuu.cn/archives/351/
脚本仓库GIT下载法
git clone https://gitee.com/ledc/IYUUAutoReseed.git
cd IYUUAutoReseed
php ./iyuu.php
*/
return array(
// 有变化才发送通知(辅种成功 + 失败 > 0
'notify_on_change' => false,
// 1.【必须配置】爱语飞飞 微信通知请访问https://iyuu.cn 用微信扫码申请
'iyuu.cn' => 'IYUU',
// 2.server酱 微信通知配置
'sc.ftqq.com' => '',
// 3.发布员鉴权
'secret' => '',
// 4.全局默认配置
// 2.全局默认配置
'default' => array(
// 5.【必须配置】浏览器UA打开http://demo.iyuu.cn 复制过来即可
'userAgent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
// 6.【自动辅种必须配置】全局客户端设置(条目不够可以复制)
// 3.【必须配置】浏览器UA打开http://demo.iyuu.cn 复制过来即可
'userAgent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.1303.189 Safari/537.36',
// 4.【自动辅种必须配置】全局客户端设置(条目不够可以复制)
'clients' => array(
// 全局客户端设置 开始
# 开始
array(
'type' => 'transmission', // 支持transmission、qBittorrent
'host' => 'http://127.0.0.1:9091/transmission/rpc', // 警告注意transmission/rpc这段别动你只需要修改 127.0.0.1:9091
'username' => '',
'password' => '',
'username' => '', // 没有用户名请填写null
'password' => '', // 没有密码 请填写null
'BT_backup' => '/torrents', // 移动做种:如果脚本与当前客户端不在一台机器,必须配置
'move' => 0, // 0不移动1移动并辅种2移动且只在当前客户端辅种
),
# 结束
# 开始
array(
'type' => 'qBittorrent', // 支持transmission、qBittorrent
'host' => 'http://www.baidu.com:8083',
'username' => '',
'host' => 'http://127.0.0.1:8083',
'username' => 'admin',
'password' => '',
'root_folder'=> 1, // 创建多文件子目录0不创建1创建(下载器默认1)【此处必须与下载器真实配置相同,否则添加任务不会校验!】
'BT_backup' => '/BT_backup', // 移动做种必须配置Linux搜索方法find / -name BT_backup
'move' => 0, // 0不移动1移动并辅种2移动且只在当前客户端辅种
),
# 结束
// 全局客户端设置 结束
),
// 5.移动做种必须配置
'move' =>array(
'type' => 2, // 0保持不变1减2加 3直接替换
'type' => 0, // 0保持不变1减2加3替换
'path' =>array(
'/sda1' => '/volume1',
// 当前路径 => 目标路径
'/downloads' => '/volume1',
),
'path_filter'=> array(), //转移过滤器:不转移此路径内文件
'path_selector' => array(), //转移选择器:只转移此路径内文件(为空时,全转移) 【优先级:过滤器 选择器】
'paused' => 1, //转移成功自动开始任务0开始1暂停
'skip_check' => 0, //转移成功跳校验0不跳、1跳校验
'delete_torrent' => 0, //转移成功删除当前做种0不删除、1删除
),
// 6.RSS工作模式
'workingMode' => 0,
// 7.监控目录
'watch' => '/volume1/watch',
// 8.RSS过滤参数配置
'filter' => array(
'size'=>array(
'min' => '1GB',
'max' => '280GB',
),
'seeders'=>array(
'min' => 1,
'max' => 3,
),
'leechers'=>array(
'min' => 0,
'max' => 10000,
),
'completed'=>array(
'min' => 0,
'max' => 10000,
),
),
'CONNECTTIMEOUT'=> 60,
'TIMEOUT' => 600,
),
// 9.server酱 微信通知配置
'sc.ftqq.com' => '',
// 10.发布员鉴权
'secret' => '',
/**
* 以下为各站点的独立配置(互不影响、互不冲突)
* 自动辅种需要配置各站的passkey没有配置passkey的站点会自动跳过
*/
// m-team 序号1
'm-team' => array(
// 14.m-team的cookie 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => 'tp=',
// 15.m-team的passkey 【必须配置】
'passkey' => '',
// 种子Tracker的IP地址选择 可选ipv4ipv6
'ip_type' => 'ipv4',
),
// keepfrds 序号2
'keepfrds' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// ourbits 序号3
// 【合作站点用户鉴权】ourbits
'ourbits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'id' => 0, // 用户ID
'is_vip' => 0, // 是否具有VIP或特殊权限0 普通1 VIP
'id' => 0, // 用户ID(不是用户名)
'url_replace' => array(),
'url_join' => array(
//'ipv6=1', // 种子Tracker的IP地址选择 可选ipv4ipv6
//'https=1',
),
'limitRule' => array(
'count' => 20, // 每次辅种20个
'sleep' => 15, // 最少休眠15秒
),
'workingMode' => 0,
'watch' => '/root/downloads',
'filter' => array(
'size'=>array(
'min' => '1GB',
'max' => '280GB',
),
),
),
// 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
'hddolby' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
// 如果需要辅种,必须配置
'rss' => '',
'id' => 0, // 用户ID(不是用户名)
'url_replace' => array(),
'url_join' => array(),
'limitRule' => array(
'count' => 20, // 每次辅种20个
'sleep' => 5, // 最少休眠5秒
),
),
// TorrentCCF 序号11
'torrentccf' => array(
// 【合作站点用户鉴权】hdhome
'hdhome' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
// 如果需要辅种,必须配置
'rss' => '',
'id' => 0, // 用户ID(不是用户名)
'url_replace' => array(),
'url_join' => array(),
'limitRule' => array(
'count' => 20, // 每次辅种20个
'sleep' => 5, // 最少休眠5秒
),
),
// PTMSG 序号12
'ptmsg' => array(
// 【合作站点用户鉴权】PTHome
'pthome' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
// 如果需要辅种,必须配置
'rss' => '',
'id' => 0, // 用户ID(不是用户名)
'url_replace' => array(),
'url_join' => array(),
'limitRule' => array(
'count' => 20, // 每次辅种20个
'sleep' => 5, // 最少休眠5秒
),
),
// MoeCat 序号13
'moecat' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
// 种子Tracker的IP地址选择 可选ipv4ipv6
'ip_type' => 'ipv4',
),
// 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' => '',
// 如果需要自动辅种必须配置cuhash
'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
'chdbits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'id' => 0, // 用户ID(不是用户名)
'url_replace' => array(),
'url_join' => array(),
),
// leaguehd 序号25
// HDAI
'hdai' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'id' => 0, // 用户ID(不是用户名)
'url_replace' => array(),
'url_join' => array(),
),
// m-team
'm-team' => array(
// 14.m-team的cookie 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => 'tp=',
// 15.m-team的passkey 【必须配置】
'passkey' => '',
'url_replace' => array(),
'url_join' => array(
//'ipv6=1', // 种子Tracker的IP地址选择 可选ipv4ipv6
'https=1',
),
),
// keepfrds
'keepfrds' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
'workingMode' => 1,
'watch' => '',
'filter' => array(
'size'=>array(
'min' => '1GB',
'max' => '280GB',
),
),
),
// pter
'pter' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// tjupt
'tjupt' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// btschool
'btschool' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// HDSky
'hdsky' => array(
// 如果需要自动辅种,必须配置此项
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'limitRule' => array(
'count' => 20, // 每次辅种20个
'sleep' => 20, // 最少休眠20秒
),
'url_replace' => array(),
'url_join' => array(),
),
// TorrentCCF
'torrentccf' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// PTMSG
'ptmsg' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// totheglory
'ttg' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
// 如果需要rss订阅必须配置
'rss' => '',
'url_replace' => array(),
'url_join' => array(),
),
// nanyangpt
'nanyangpt' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// springsunday.net
'ssd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
'limitRule' => array(
'count' => 20, // 每次辅种20个
'sleep' => 15, // 最少休眠15秒
),
),
// yingk
'yingk' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdcity
'hdcity' => array(
// 必须配置
'cookie' => '',
// 如果需要自动辅种必须配置cuhash
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// 52pt.site
'52pt' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// brobits
'brobits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// beitai
'beitai' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// eastgame
'eastgame' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// soulvoice
'soulvoice' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// leaguehd
'leaguehd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// ptsbao.club 序号26
// ptsbao
'ptsbao' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdchina 序号27
// hdchina
'hdchina' => array(
// 必须配置
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
'limitRule' => array(
'count' => 10, // 每次辅种10个
'sleep' => 5, // 最少休眠15秒
),
),
// hdarea 序号28
// hdarea
'hdarea' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdtime 序号29
// hdtime
'hdtime' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// 1ptba 序号30
// 1ptba
'1ptba' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hd4fans 序号31
// hd4fans
'hd4fans' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdbug 序号32
// hddisk.life
'hdbug' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// opencd 序号33 皇后
// opencd皇后
'opencd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdstreet 序号34
// hdstreet
'hdstreet' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// joyhd 序号35
// joyhd
'joyhd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// dmhy 序号36 幼儿园
// dmhy幼儿园
'dmhy' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// upxin 序号37
// hdu
'upxin' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// oshen 序号38
// oshen
'oshen' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// discfan 序号39 港知堂
// discfan港知堂
'discfan' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdzone 序号40
// hdzone
'hdzone' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// cnscg 序号41 圣城
'cnscg' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// nicept 序号42 老师
// nicept老师
'nicept' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdbd 序号43 伊甸园
// hdbd伊甸园
'hdbd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(
//'ipv6=1', // 种子Tracker的IP地址选择 可选ipv4ipv6
//'https=1',
),
),
// 配置文件结束
// byr北邮
'byr' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// CCFBits
'ccfbits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdbits
'hdbits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// PTPBD
'ptpbd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// HD-T
'hd-torrents' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// skyeysnow天雪
'skyeysnow' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// pt.sjtu葡萄
'pt' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
'limitRule' => array(
'count' => 20, // 每次辅种20个
'sleep' => 20, // 最少休眠20秒
),
),
// hdroute
'hdroute' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// haidan
'haidan' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// hdfans
'hdfans' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// dragonhd
'dragonhd' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// hitpt 百川
'hitpt' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// pttime PT时间
'pttime' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// npupt 蒲公英
'npupt' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
// hdatmos 阿童木
'hdatmos' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
),
'greatposterwall' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '', // torrent_pass
'torrent_pass' => '', // torrent_pass
'authkey' => '', // authkey
),
// hudbt 华科蝴蝶
'hudbt' => array(
'cookie' => '',
'passkey' => '',
'url_replace' => array(),
'url_join' => array(),
),
// 配置结束,后面的一行不能删除,必须保留!!!
);

114
docker/AMD64/Dockerfile Normal file
View File

@@ -0,0 +1,114 @@
#FROM alpine:latest
#FROM alpine:3.12
FROM alpine:3.8
#FROM swoft/alphp:base
#FROM swoft/alphp:cli
LABEL maintainer="david <367013672@qq.com>" version="1.0"
##
# ---------- env settings ----------
##
# --build-arg timezone=Asia/Shanghai
ARG timezone
# prod pre test dev
ARG app_env=prod
# default use www-data user
# ARG add_user=www-data
ENV APP_ENV=${app_env:-"prod"} \
TIMEZONE=${timezone:-"Asia/Shanghai"} \
cron="3 */10 * * *"
##
# ---------- building ----------
##
RUN set -ex \
# change apk source repo
#&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories \
&& apk update \
&& apk add --no-cache \
# Install base packages ('ca-certificates' will install 'nghttp2-libs')
# ca-certificates \
# curl \
# tar \
# xz \
# libressl \
# openssh \
# openssl \
git \
tzdata \
# pcre \
# install php7 and some extensions
php7 \
# php7-common \
# php7-bcmath \
php7-curl \
# php7-ctype \
php7-dom \
# php7-fileinfo \
# php7-gettext \
# php7-gd \
# php7-iconv \
# php7-imagick \
php7-json \
php7-mbstring \
#php7-mongodb \
# php7-mysqlnd \
# php7-openssl \
# php7-opcache \
# php7-pdo \
# php7-pdo_mysql \
# php7-pdo_sqlite \
# php7-phar \
# php7-pcntl \
# php7-posix \
# php7-redis \
php7-simplexml \
# php7-sockets \
# php7-sodium \
# php7-sqlite \
# php7-session \
# php7-sysvshm \
# php7-sysvmsg \
# php7-sysvsem \
# php7-tokenizer \
php7-zip \
# php7-zlib \
php7-xml \
&& git clone https://gitee.com/ledc/IYUUAutoReseed.git /IYUU \
&& cp /IYUU/config/config.sample.php /IYUU/config/config.php \
&& ln -sf /IYUU/config/config.php /config.php \
&& cp /IYUU/docker/entrypoint.sh /entrypoint.sh \
&& chmod +x /entrypoint.sh \
&& apk del --purge *-dev \
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man /usr/share/php7 \
# ---------- some config,clear work ----------
&& cd /etc/php7 \
# - config PHP
&& { \
echo "upload_max_filesize=100M"; \
echo "post_max_size=108M"; \
echo "memory_limit=1024M"; \
echo "date.timezone=${TIMEZONE}"; \
} | tee conf.d/99-overrides.ini \
# - config timezone
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo "${TIMEZONE}" > /etc/timezone \
&& echo '2 */5 * * * cd /IYUU && git fetch --all && git reset --hard origin/master' >> /etc/crontabs/root \
#&& echo "${cron} /usr/bin/php /IYUU/iyuu.php &> /dev/null" >> /etc/crontabs/root \
# ---------- some config work ----------
# - ensure 'www-data' user exists(82 is the standard uid/gid for "www-data" in Alpine)
# && addgroup -g 82 -S ${add_user} \
# && adduser -u 82 -D -S -G ${add_user} ${add_user} \
# # - create user dir
# && mkdir -p /data \
# && chown -R ${add_user}:${add_user} /data \
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
# EXPOSE 9000
# VOLUME ["/IYUU", "/data"]
WORKDIR /IYUU
ENTRYPOINT ["/entrypoint.sh"]

4
docker/AMD64/build.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
docker build -t iyuu:latest .
docker run -it -v /root/config.php:/config.php --network bridge --name IYUUAutoReseed --restart always -d iyuu:latest
docker exec -it IYUUAutoReseed php iyuu.php

32
docker/Arm64v8/Dockerfile Normal file
View File

@@ -0,0 +1,32 @@
# FROM arm64v8/alpine
# FROM arm64v8/alpine:latest
FROM arm64v8/alpine:3.12
ENV TZ Asia/Shanghai
ENV cron="3 */10 * * *"
RUN set -ex \
&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories \
# && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.cn/' /etc/apk/repositories \
&& apk update \
&& apk add --no-cache \
tzdata \
php7 php7-curl php7-json php7-mbstring php7-dom php7-simplexml php7-xml php7-zip \
git \
&& git clone https://gitee.com/ledc/IYUUAutoReseed.git /IYUU \
&& cp /IYUU/config/config.sample.php /IYUU/config/config.php \
&& ln -sf /IYUU/config/config.php /config.php \
&& cp /IYUU/docker/entrypoint.sh /entrypoint.sh \
&& chmod +x /entrypoint.sh \
&& apk del --purge *-dev \
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
&& echo "${TZ}" > /etc/timezone \
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
# && echo '* * * * * echo "iyuu.cn" >/dev/null 2>&1' >> /etc/crontabs/root \
&& echo '3 */6 * * * cd /IYUU && git fetch --all && git reset --hard origin/master' >> /etc/crontabs/root \
# && echo "${cron} /usr/bin/php /IYUU/iyuu.php >/dev/null 2>&1" >> /etc/crontabs/root \
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
WORKDIR /IYUU
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -0,0 +1,4 @@
#!/bin/sh
docker build -t iyuu:arm64v8 .
docker run -it -v /root/config.php:/config.php -v /var/lib/transmission/torrents:/torrents -v /var/lib/qbittorrent/.local/share/data/qBittorrent/BT_backup:/BT_backup --network bridge --name IYUUAutoReseed --restart always -d iyuu:arm64v8
docker exec -it IYUUAutoReseed php iyuu.php

4
docker/Arm64v8/build.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
docker build -f Dockerfile -t iyuu:arm64v8 .
docker run -it -v /root/config.php:/config.php --network bridge --name IYUUAutoReseed --restart always -d iyuu:arm64v8
docker exec -it IYUUAutoReseed php iyuu.php

2
docker/Arm64v8/push.sh Normal file
View File

@@ -0,0 +1,2 @@
docker image tag iyuu:arm64v8 iyuucn/iyuuautoreseed:arm64v8
docker image push iyuucn/iyuuautoreseed:arm64v8

137
docker/Readme.md Normal file
View File

@@ -0,0 +1,137 @@
# 使用方法:
### 1.拉取镜像、创建容器,运行
#### ARM平台通用方法
```
docker run -d \
--name IYUUAutoReseed \
-e cron='0 9 * * 0' \
-v /root/config.php:/config.php \
--restart=always \
iyuucn/iyuuautoreseed:arm64v8
```
#### 小钢炮方法:
```
docker run -d \
--name IYUUAutoReseed \
-e cron='0 8 * * 0' \
-v /root/config.php:/config.php \
-v /var/lib/transmission/torrents:/torrents \
-v /var/lib/qbittorrent/.local/share/data/qBittorrent/BT_backup:/BT_backup \
--restart always \
iyuucn/iyuuautoreseed:arm64v8
```
#### AMD64平台MAC OS、台式、服务器、NAS等
```
docker run -d \
--name IYUUAutoReseed \
-e cron='0 9 * * 0' \
-v /root/config.php:/config.php \
--restart=always \
iyuucn/iyuuautoreseed:latest
```
**命令解释**
| 参数 | 解释 |
| ----------- | ------------------------------------------------------------ |
| `--name` | 容器名字 |
| `-e` | 环境变量,定时任务执行时间 |
| `-v` | 本地目录或文件:容器目录文件,资源挂载到容器。<br />请把你的配置文件放在/root/config.php会把你的配置映射进容器内。 |
| `--restart` | 启动模式 |
------
### 2.停止
```
docker stop IYUUAutoReseed
```
### 3.运行
```
docker start IYUUAutoReseed
```
### 4.删除容器
```
docker rm IYUUAutoReseed
```
### 5.删除镜像
```
docker rmi iyuucn/iyuuautoreseed:arm64v8
```
------
#### 功能
IYUU自动辅种工具功能分为两大块自动辅种、自动转移。
- 自动辅种目前能对国内大部分的PT站点自动辅种支持下载器集群支持多盘位支持多下载目录支持远程连接等
- 自动转移:可以实现各下载器之间自动转移做种客户端,让下载器各司其职(专职的保种、专职的下载)。
#### 原理
IYUU自动辅种工具英文名IYUUAutoReseed是一款PHP语言编写的Private Tracker辅种脚本通过计划任务或常驻内存按指定频率调用transmission、qBittorrent下载软件的API接口提取正在做种的info_hash提交到辅种服务器API接口辅种过程和PT站没有任何交互根据API接口返回的数据拼接种子连接提交给下载器自动辅种各个站点。
#### 优势
- 全程自动化,无需人工干预;
- 支持多盘位,多做种目录,多下载器,支持远程下载器;
- 辅种精确度高,精度可配置;
- 支持微信通知,消息即时达;
- 自动对合集包,进行拆包辅种(暂未开发)
- 安全:所有隐私信息只在本地存储,绝不发送给第三方。
- 拥有专业的问答社区和交流群
#### 支持的下载器
1. transmission
2. qBittorrent
#### 运行环境
具备PHP运行环境的所有平台例如Linux、Windows、MacOS
官方下载的记得开启curl、json、mbstring这3个扩展。
1. Windows安装php环境https://www.php.net/downloads
#### 源码仓库
- github仓库https://github.com/ledccn/IYUUAutoReseed
- 码云仓库https://gitee.com/ledc/IYUUAutoReseed
#### 使用方法
- 博客https://www.iyuu.cn/
#### 接口开发文档
如果您懂得其他语言的开发可以基于接口做成任何您喜欢的样子比如手机APP二进制包Windows的GUI程序浏览器插件等。欢迎分享您的作品
实时更新的接口文档http://api.iyuu.cn/docs.php
#### 需求提交/错误反馈
- QQ群859882209[2000人.入门群]931954050[1000人.进阶群]
- 问答社区http://wenda.iyuu.cn
- 博客https://www.iyuu.cn/
- issues https://gitee.com/ledc/IYUUAutoReseed/issues

8
docker/entrypoint.sh Normal file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
DEFAULT_CRON="9 */6 * * *"
cron=${cron:-$DEFAULT_CRON}
set -e
echo "$cron /usr/bin/php /IYUU/iyuu.php" | crontab -
cd /IYUU && git fetch --all && git reset --hard origin/master
/usr/bin/php /IYUU/iyuu.php
/usr/sbin/crond -f

20
docker/iyuu.sh Normal file
View File

@@ -0,0 +1,20 @@
#!/bin/sh
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
## 相关命令
# 1. 手动执行辅种
docker exec IYUUAutoReseed php iyuu.php
# 2. 手动删除辅种缓存
docker exec -it IYUUAutoReseed rm -rf ./torrent/cachehash
# 3. 手动删除转移缓存
docker exec -it IYUUAutoReseed rm -rf ./torrent/cachemove
# 4. 查看当前定时任务
docker exec -it IYUUAutoReseed crontab -l
# 5. 修改定时任务推荐修改docker容器的环境变量参数cron
docker exec -it IYUUAutoReseed crontab -e
# 6. 进入容器内交互终端
docker exec -it IYUUAutoReseed sh

8
git_pull.sh Normal file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
#脚本功能从git拉取最新代码然后执行辅种
pwddir=$(cd $(dirname $0); pwd)
echo $pwddir
cd $(dirname $0)
git fetch --all
git reset --hard origin/master
php ./iyuu.php

View File

@@ -1,17 +1,33 @@
<?php
//----------------------------------
// 公共入口文件
//----------------------------------
// 定义目录
use IYUU\AutoReseed;
/**
IIIIIIIIIIYYYYYYY YYYYYYYUUUUUUUU UUUUUUUUUUUUUUUU UUUUUUUU
I::::::::IY:::::Y Y:::::YU::::::U U::::::UU::::::U U::::::U
I::::::::IY:::::Y Y:::::YU::::::U U::::::UU::::::U U::::::U
II::::::IIY::::::Y Y::::::YUU:::::U U:::::UUUU:::::U U:::::UU
I::::I YYY:::::Y Y:::::YYY U:::::U U:::::U U:::::U U:::::U
I::::I Y:::::Y Y:::::Y U:::::D D:::::U U:::::D D:::::U
I::::I Y:::::Y:::::Y U:::::D D:::::U U:::::D D:::::U
I::::I Y:::::::::Y U:::::D D:::::U U:::::D D:::::U
I::::I Y:::::::Y U:::::D D:::::U U:::::D D:::::U
I::::I Y:::::Y U:::::D D:::::U U:::::D D:::::U
I::::I Y:::::Y U:::::D D:::::U U:::::D D:::::U
I::::I Y:::::Y U::::::U U::::::U U::::::U U::::::U
II::::::II Y:::::Y U:::::::UUU:::::::U U:::::::UUU:::::::U
I::::::::I YYYY:::::YYYY UU:::::::::::::UU UU:::::::::::::UU
I::::::::I Y:::::::::::Y UU:::::::::UU UU:::::::::UU
IIIIIIIIII YYYYYYYYYYYYY UUUUUUUUU UUUUUUUUU
*/
// 定义目录
defined('ROOT_PATH') or define("ROOT_PATH", __DIR__);
define('DS', DIRECTORY_SEPARATOR);
defined('APP_PATH') or define('APP_PATH', ROOT_PATH.DS.'app'.DS);
define('TORRENT_PATH', ROOT_PATH.DS.'torrent'.DS);
// 严格开发模式
error_reporting(E_ALL);
#ini_set('display_errors', 1);
ini_set('display_errors', 1);
// 永不超时
ini_set('max_execution_time', 0);
@@ -28,23 +44,38 @@ if (PHP_SAPI != 'cli') {
// 设置时区
date_default_timezone_set('Asia/Shanghai');
echo microtime(true).' 环境变量初始化完成!'.PHP_EOL;
// 系统配置
if (file_exists(ROOT_PATH."/config/config.php")) {
// 配置(全局变量)
$configALL = require_once ROOT_PATH . "/config/config.php";
} else {
// 第一次会生成
@copy(ROOT_PATH . '/config/config.sample.php', ROOT_PATH . '/config/config.php');
// 示例配置
$configALL = require_once ROOT_PATH . '/config/config.sample.php';
}
require_once ROOT_PATH . '/vendor/autoload.php';
AutoReseed::init();
$hashArray = AutoReseed::get();
if (AutoReseed::$move != null) {
echo "种子移动完毕,请重新编辑配置,再尝试辅种! \n\n";
echo microtime(true).' 缺少config.php已载入config.sample.php示例配置。'.PHP_EOL;
echo microtime(true).' 请编辑配置文件config.php以免后续版本升级覆盖配置'.PHP_EOL;
$t = 30;
do {
echo microtime(true)." 请编辑配置文件config.php{$t}秒后退出...".PHP_EOL;
sleep(1);
} while (--$t > 0);
exit;
}
AutoReseed::call($hashArray);
AutoReseed::wechatMessage();
echo microtime(true).' 全局配置载入完成!'.PHP_EOL;
// 读取支持列表
if (is_file(ROOT_PATH . "/config/sites.json")) {
$sitesJson = file_get_contents(ROOT_PATH . "/config/sites.json");
$configALL['sitesALL'] = json_decode($sitesJson, true);
echo microtime(true).' 支持站点JSON载入完成'.PHP_EOL;
}
echo microtime(true).' 正在加载composer包管理器...'.PHP_EOL;
require_once ROOT_PATH . '/vendor/autoload.php';
echo microtime(true).' composer依赖载入完成'.PHP_EOL;
echo microtime(true).' 当前脚本运行环境:'.PHP_OS.PHP_EOL;
global $argv;
$start_file = str_replace("\\", "/", trim($argv[0]));
if (substr($start_file, -8)==="init.php") {
require_once __DIR__ . '/iyuu.php';
}

31
iyuu.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
/**
_____ _____ _____ _____
/\ \ |\ \ /\ \ /\ \
/::\ \ |:\____\ /::\____\ /::\____\
\:::\ \ |::| | /:::/ / /:::/ /
\:::\ \ |::| | /:::/ / /:::/ /
\:::\ \ |::| | /:::/ / /:::/ /
\:::\ \ |::| | /:::/ / /:::/ /
/::::\ \ |::| | /:::/ / /:::/ /
____ /::::::\ \ |::|___|______ /:::/ / _____ /:::/ / _____
/\ \ /:::/\:::\ \ /::::::::\ \ /:::/____/ /\ \ /:::/____/ /\ \
/::\ \/:::/ \:::\____\ /::::::::::\____\|:::| / /::\____\|:::| / /::\____\
\:::\ /:::/ \::/ / /:::/~~~~/~~ |:::|____\ /:::/ /|:::|____\ /:::/ /
\:::\/:::/ / \/____/ /:::/ / \:::\ \ /:::/ / \:::\ \ /:::/ /
\::::::/ / /:::/ / \:::\ \ /:::/ / \:::\ \ /:::/ /
\::::/____/ /:::/ / \:::\ /:::/ / \:::\ /:::/ /
\:::\ \ \::/ / \:::\__/:::/ / \:::\__/:::/ /
\:::\ \ \/____/ \::::::::/ / \::::::::/ /
\:::\ \ \::::::/ / \::::::/ /
\:::\____\ \::::/ / \::::/ /
\::/ / \::/____/ \::/____/
\/____/ ~~ ~~
*/
require_once __DIR__ . '/init.php';
echo '当前脚本路径:'.__FILE__.PHP_EOL;
use IYUU\AutoReseed;
AutoReseed::init();
AutoReseed::call();

116
readme.md
View File

@@ -10,43 +10,93 @@
第三您使用IYUU工具造成的一切损失与IYUU无关。如不接受此条款请不要使用IYUUAutoReseed并立刻删除已经下载的源码。
![stars](https://img.shields.io/github/stars/ledccn/IYUUAutoReseed)![forks](https://img.shields.io/github/forks/ledccn/IYUUAutoReseed)![release](https://img.shields.io/github/release/ledccn/IYUUAutoReseed.svg)
## 获取脚本,四种方式皆可
1. 通过git命令安装
`git clone https://github.com/ledccn/IYUUAutoReseed.git`
2. 通过composer命令安装
`composer create-project ledccn/iyuuautoreseed:dev-master`
3. 直接下载zip源码包
`https://github.com/ledccn/IYUUAutoReseed/archive/master.zip`
4. Docker使用
[https://gitee.com/ledc/IYUUAutoReseed/tree/master/docker](https://gitee.com/ledc/IYUUAutoReseed/tree/master/docker)
## 功能
IYUU自动辅种工具目前能对国内大部分的PT站点自动辅种支持下载器集群支持多盘位支持多下载目录支持远程连接等
IYUU自动辅种工具功能分为两大块:自动辅种、自动转移
- 自动辅种目前能对国内大部分的PT站点自动辅种支持下载器集群支持多盘位支持多下载目录支持远程连接等
- 自动转移:可以实现各下载器之间自动转移做种客户端,让下载器各司其职(专职的保种、专职的下载)。
## 原理
IYUU自动辅种工具英文名IYUUAutoReseed是一款PHP语言编写的Private Tracker辅种脚本通过计划任务或常驻内存按指定频率调用transmission、qBittorrent下载软件的API接口提取正在做种的info_hash提交到服务器API接口根据API接口返回的数据拼接种子连接提交给下载器自动辅种各个站点。
IYUU自动辅种工具英文名IYUUAutoReseed是一款PHP语言编写的Private Tracker辅种脚本通过计划任务或常驻内存按指定频率调用transmission、qBittorrent下载软件的API接口提取正在做种的info_hash提交到辅种服务器API接口辅种过程和PT站没有任何交互根据API接口返回的数据拼接种子连接提交给下载器自动辅种各个站点。
## 优势
- 全程自动化,无需人工干预;
- 支持多盘位,多做种目录,多下载器,支持远程连接下载器;
- 支持多盘位,多做种目录,多下载器,支持远程下载器;
- 辅种精确度高,精度可配置;
- 支持微信通知,消息即时达;
- 自动对合集包,进行拆包辅种(暂未开发)
- 安全:所有隐私信息只在本地存储,绝不发送给第三方。
- 拥有专业的问答社区和交流群
## 支持的下载器
1. transmission
2. qBittorrent
## 支持自动辅种的站点
学校、杜比、家园、天空、朋友、馒头、萌猫、我堡、猫站、铂金家、烧包、北洋、TCCF、南洋、TTG、映客、城市、52pt、brobits、备胎、SSD、CHD、ptmsg、leaguehd、聆音、瓷器、hdarea、eastgame(TLF)、1ptba、hdtime、hd4fans、opencd、hdbug、hdstreet、joyhd、u2、upxin(HDU)、oshen、discfan(GZT)、cnscg圣城。
学校、杜比、家园、天空、朋友、馒头、萌猫、我堡、猫站、铂金家、烧包、北洋、TCCF、南洋、TTG、映客、城市、52pt、brobits、备胎、SSD、CHD、ptmsg、leaguehd、聆音、瓷器、hdarea、eastgame(TLF)、1ptba、hdtime、hd4fans、opencd、hdbug、hdstreet、joyhd、u2、upxin(HDU)、oshen、discfan(GZT)、cnscg圣城(已删除)、北邮、CCFBits、dicmusic、天雪、葡萄、HDRoute、伊甸园hdbd、海胆haidan、HDfans、龙之家、百川PT、HDAI、蒲公英、阿童木、蝴蝶
## 运行环境
所有具备PHP运行环境的所有平台官方下载的记得开启crul、fileinfo、mbstring这3个扩展。
例如Linux、Windows、MacOS
1. Windows下安装php环境https://www.php.net/downloads
具备PHP运行环境的所有平台例如Linux、Windows、MacOS
官方下载的记得开启curl、json、mbstring这3个扩展。
1. Windows安装php环境https://www.php.net/downloads
## 下载源码
- github仓库https://github.com/ledccn/IYUUAutoReseed
- 码云仓库https://gitee.com/ledc/IYUUAutoReseed
## 使用方法
详见Wiki https://gitee.com/ledc/IYUUAutoReseed/wikis
- 详见Wikihttps://gitee.com/ledc/IYUUAutoReseed/tree/master/wiki
- 博客https://www.iyuu.cn/
## 接口开发文档
如果您懂得其他语言的开发可以基于接口做成任何您喜欢的样子比如手机APP二进制包Windows的GUI程序浏览器插件等。欢迎分享您的作品
实时更新的接口文档http://api.iyuu.cn/docs.php
## 相关项目
| 项目名| 简介|
| - | --- |
| [IYUU GUI](https://github.com/Rhilip/IYUU-GUI) | 这是一个基于IYUU提供的API产生一个可视化操作项目。目的是为了降低直接上手PHP版IYUUAutoReseed的困难。 |
| [IYUU-Fly](https://github.com/PlexPt/iyuu-fly) | 带GUI的iyuu自动辅种程序。 |
| [goreseed](https://github.com/gaoluhua99/goreseed) | golang编写调用IYUU接口的CLI辅种程序。 |
| [IYUUAutoReseed-web](https://github.com/goveeta/IYUUAutoReseed-web) | |
| [AutoPT](https://github.com/lyssssssss/AutoPT) | 此程序用于自动下载PT免费种子并自动辅种和一体化管理。开发目的为了释放双手专注观影 |
| [flexget_qbittorrent_mod](https://github.com/IvonWei/flexget_qbittorrent_mod) | Flexget qBittorrent插件实现全自动化辅种删除种免费种筛选签到等。|
## 需求提交/错误反馈
- 点击链接加入群聊【IYUU自动辅种交流】[https://jq.qq.com/?_wv=1027&k=5JOfOlM][1]
- QQ群859882209
- QQ群859882209[2000人群]931954050[1000人群],924099912[2000人群]
- 问答社区http://wenda.iyuu.cn
- 博客https://www.iyuu.cn/
- issues https://gitee.com/ledc/IYUUAutoReseed/issues
## 捐助开发者
@@ -54,11 +104,9 @@ IYUU自动辅种工具英文名IYUUAutoReseed是一款PHP语言编
如果喜欢,请帮忙在[Github](https://github.com/ledccn/IYUUAutoReseed)或[码云](https://gitee.com/ledc/IYUUAutoReseed)给个Star也可以对IYUUAutoReseed进行[捐赠](https://gitee.com/ledc/IYUUAutoReseed#%E6%8D%90%E5%8A%A9%E5%BC%80%E5%8F%91%E8%80%85)哦 ^_^。
**您所有的打赏将用于服务器续期,增加服务的延续性。**
**您所有的打赏将用于服务器维护及续期,增加服务的延续性。**
![微信打赏.png][2]
## 捐赠者列表
感谢以下捐赠者,排名不分先后!
@@ -100,6 +148,43 @@ IYUU自动辅种工具英文名IYUUAutoReseed是一款PHP语言编
| 寒山先生 | ¥100元 | 2020年1月9日11:51 |
| 王浩淼 | ¥50元 | 2020年1月9日11:53 |
| 寒山先生 | ¥100元 | 2020年1月11日11:47 |
| 天空(感谢远程指导小意思) | ¥20元 | 2020年1月14日23:11 |
| 寒山先生 | ¥200元 | 2020年1月18日12:37 |
| 小城流水 | ¥5元 | 2020年1月22日22:14 |
| 国旗(未署名) | ¥8.8元 | 2020年1月22日23:28 |
| Alpha | ¥10.81元 | 2020年1月24日20:23 |
| 羽生 | ¥88.88元 | 2020年1月24日21:06 |
| 当下丶 | ¥100元 | 2020年1月28日1:45 |
| 陈君政 | ¥10元 | 2020年2月3日11:32 |
| 不寐夜游 | ¥10元 | 2020年2月8日17:17 |
| Jack | ¥10元 | 2020年2月13日08:05 |
| 陈伟平 | ¥28.88元 | 2020年2月13日12:35 |
| PhalApi Pro商业授权 | ¥-950元 | 2020年2月14日21:56 |
| jonnaszheng | ¥10元 | 2020年2月15日10:25 |
| weekendsd54zdk | ¥10元 | 2020年2月17日14:31 |
| 寒山先生 | ¥200元 | 2020年2月17日17:00 |
| PLC组态远程服务 | ¥8.88元 | 2020年2月18日02:14 |
| JeSsiE杰西 | ¥66元 | 2020年2月20日19:38 |
| 黄叶梓(炮王) | ¥10元 | 2020年2月20日21:10 |
| 里奥龙 | ¥88.8元 | 2020年2月20日21:48 |
| 寒山先生 | ¥200元 | 2020年2月21日17:32 |
| 李永超 | ¥10元 | 2020年2月22日16:24 |
| Always | ¥5元 | 2020年2月22日21:31 |
| 车站 | ¥30元 | 2020年2月22日21:32 |
| 寒山先生 | ¥200元 | 2020年2月23日22:21 |
| 莫凡 | ¥10元 | 2020年2月24日19:43 |
| 未署名 | ¥200元 | 2020年2月25日14:36 |
| 锦年 | ¥6.66元 | 2020年2月25日19:00 |
| 金力 | ¥10元 | 2020年2月26日22:45 |
| 飞翔鱼 | ¥100元 | 2020年2月24日17:58 |
| 团 | ¥1元 | 2020年2月29日1:12 |
| 沙鸥 | ¥10元 | 2020年2月29日17:03 |
| lsy | ¥229.5元 | 2020年3月1日15:15 |
| 慧宇 | ¥30元 | 2020年3月3日16:39 |
| sz贺贺 | ¥100元 | 2020年3月7日14:40 |
| 一介凡人 | ¥8.88元 | 2020年3月9日22:34 |
| | | |
补充说明:
@@ -107,8 +192,3 @@ IYUU自动辅种工具英文名IYUUAutoReseed是一款PHP语言编
2. 所捐赠的资源不属于任何个人,而应作为项目或者开发团队的所需开销;
3. 如果捐赠了却不希望您的名字出现在这里,可以联系我们进行相应处理;
4. 更新有延时,如未能及时更新,可联系我。
[1]: https://jq.qq.com/?_wv=1027&k=5JOfOlM
[2]: https://www.iyuu.cn/usr/uploads/2019/12/801558607.png

7
vendor/autoload.php vendored Normal file
View File

@@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit7e764d8cfe0bacfc97fde5b65088dcb3::getLoader();

445
vendor/composer/ClassLoader.php vendored Normal file
View 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
View 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
View 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_files.php vendored Normal file
View File

@@ -0,0 +1,10 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'45702aba72a3d88d5dd1a153f5231b73' => $baseDir . '/app/helper.php',
);

10
vendor/composer/autoload_namespaces.php vendored Normal file
View 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'),
);

11
vendor/composer/autoload_psr4.php vendored Normal file
View File

@@ -0,0 +1,11 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'IYUU\\Client\\' => array($vendorDir . '/ledccn/bittorrentclient/src'),
'IYUU\\' => array($baseDir . '/app'),
);

70
vendor/composer/autoload_real.php vendored Normal file
View File

@@ -0,0 +1,70 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit7e764d8cfe0bacfc97fde5b65088dcb3
{
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('ComposerAutoloaderInit7e764d8cfe0bacfc97fde5b65088dcb3', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit7e764d8cfe0bacfc97fde5b65088dcb3', '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\ComposerStaticInit7e764d8cfe0bacfc97fde5b65088dcb3::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);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit7e764d8cfe0bacfc97fde5b65088dcb3::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire7e764d8cfe0bacfc97fde5b65088dcb3($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire7e764d8cfe0bacfc97fde5b65088dcb3($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

51
vendor/composer/autoload_static.php vendored Normal file
View File

@@ -0,0 +1,51 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit7e764d8cfe0bacfc97fde5b65088dcb3
{
public static $files = array (
'45702aba72a3d88d5dd1a153f5231b73' => __DIR__ . '/../..' . '/app/helper.php',
);
public static $prefixLengthsPsr4 = array (
'I' =>
array (
'IYUU\\Client\\' => 12,
'IYUU\\' => 5,
),
);
public static $prefixDirsPsr4 = array (
'IYUU\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/ledccn/bittorrentclient/src',
),
'IYUU\\' =>
array (
0 => __DIR__ . '/../..' . '/app',
),
);
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 = ComposerStaticInit7e764d8cfe0bacfc97fde5b65088dcb3::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit7e764d8cfe0bacfc97fde5b65088dcb3::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit7e764d8cfe0bacfc97fde5b65088dcb3::$prefixesPsr0;
}, null, ClassLoader::class);
}
}

118
vendor/composer/installed.json vendored Normal file
View File

@@ -0,0 +1,118 @@
[
{
"name": "curl/curl",
"version": "2.3.0",
"version_normalized": "2.3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-mod/curl.git",
"reference": "3ad560b1fc1bbdf5c7681356ab953fb961f255e5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-mod/curl/zipball/3ad560b1fc1bbdf5c7681356ab953fb961f255e5",
"reference": "3ad560b1fc1bbdf5c7681356ab953fb961f255e5",
"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": "2020-03-19T20:07:26+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Curl": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"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"
}
],
"description": "cURL class for PHP",
"homepage": "https://github.com/php-mod/curl",
"keywords": [
"curl",
"dot"
]
},
{
"name": "ledccn/bittorrentclient",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/ledccn/BittorrentClient.git",
"reference": "d8302133ee50f5bc2f4e95531562cd54dcee6b50"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ledccn/BittorrentClient/zipball/d8302133ee50f5bc2f4e95531562cd54dcee6b50",
"reference": "d8302133ee50f5bc2f4e95531562cd54dcee6b50",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"curl/curl": "^2.3",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"php": "^5.6 | ^7.0"
},
"time": "2021-01-13T05:14:10+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"IYUU\\Client\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0-or-later"
],
"authors": [
{
"name": "David",
"email": "367013672@qq.com"
}
],
"description": "实现对下载服务器管理的代码库",
"homepage": "https://github.com/ledccn/BittorrentClient",
"keywords": [
"qbittorrent",
"transmission"
]
}
]

11
vendor/curl/curl/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
vendor/*
*.orig
.buildpath
.project
.settings/*
.idea/*
composer.lock
*~
tests/phpunit_report/*
/.settings/
/.php_cs.cache

121
vendor/curl/curl/.gitlab-ci.yml vendored Normal file
View File

@@ -0,0 +1,121 @@
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 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:
- 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 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 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.9
stage: test
services:
- name: "$CI_REGISTRY_IMAGE:server-test"
alias: server_test
script:
- apk add --no-cache composer php7-cli php7-curl php7-gd php7-phar php7-json php7-openssl php7-dom php7-simplexml php7-tokenizer php7-mbstring php7-xml
- php --version
- composer 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:
- vendor
tests-php7.3:
image: alpine:3.11
stage: test
services:
- name: "$CI_REGISTRY_IMAGE:server-test"
alias: server_test
script:
- apk add --no-cache composer php7-cli php7-curl php7-gd php7-phar php7-json php7-openssl php7-dom php7-simplexml php7-tokenizer php7-mbstring php7-xml
- php --version
- composer 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.3
paths:
- vendor

20
vendor/curl/curl/LICENSE vendored Normal file
View 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
View 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
View 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
View 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>

766
vendor/curl/curl/src/Curl/Curl.php vendored Normal file
View File

@@ -0,0 +1,766 @@
<?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 occurred or not
*/
public $error = false;
/**
* @var int Contains the error code of the current request, 0 means no error happened
*/
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 occurred or not
*/
public $curl_error = false;
/**
* @var int Contains the error code of the current request, 0 means no error happened.
* @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 occurred 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 information
*/
public $request_headers = null;
/**
* @var string|array TBD (ensure type) Contains the response header information
*/
public $response_headers = array();
/**
* @var string|false|null 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 \RuntimeException
*/
public function __construct()
{
if (!extension_loaded('curl')) {
throw new \RuntimeException('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 reset.
* @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 respective 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->getErrorCode() === 0);
$this->http_status_code = intval(curl_getinfo($this->curl, CURLINFO_HTTP_CODE));
$this->http_error = $this->isError();
$this->error = $this->curl_error || $this->http_error;
$this->error_code = $this->error ? ($this->curl_error ? $this->getErrorCode() : $this->getHttpStatus()) : 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->getErrorMessage() : $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 the json payload informations to the postfield curl option.
*
* @param array $data The data to be sent.
* @return void
*/
protected function prepareJsonPayload(array $data)
{
$this->setOpt(CURLOPT_POST, true);
$this->setOpt(CURLOPT_POSTFIELDS, json_encode($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
* @param boolean $asJson Whether the data should be passed as json or not. {@insce 2.2.1}
* @return self
*/
public function post($url, $data = array(), $asJson = false)
{
$this->setOpt(CURLOPT_URL, $url);
if ($asJson) {
$this->prepareJsonPayload($data);
} else {
$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 parameters 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 parameters 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 requested url is secured by an htaccess 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 authentication
* @param string $password The password for the given username for the authentication
* @return self
*/
public function setBasicAuthentication($username, $password)
{
$this->setHttpAuth(self::AUTH_BASIC);
$this->setOpt(CURLOPT_USERPWD, $username.':'.$password);
return $this;
}
/**
* Provide optional header information.
*
* 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 customized 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
*
* @param $referrer
* @return self
*/
public function setReferrer($referrer)
{
$this->setReferer($referrer);
return $this;
}
/**
* Set the HTTP referer header.
*
* The $referer Information 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 constant e.g. `CURLOPT_AUTOREFERER`, `CURLOPT_COOKIESESSION`
* @param mixed $value The value to pass for the given $option
* @return bool
*/
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 constant e.g. `CURLOPT_AUTOREFERER`, `CURLOPT_COOKIESESSION`
* @param mixed The value to check for the given $option
* @return mixed
*/
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 verbosity.
*
* @param bool $on
* @return self
*/
public function setVerbose($on = true)
{
$this->setOpt(CURLOPT_VERBOSE, $on);
return $this;
}
/**
* @deprecated Call setVerbose() instead
*
* @param bool $on
* @return self
*/
public function verbose($on = true)
{
return $this->setVerbose($on);
}
/**
* 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 = false;
$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->getHttpStatus() >= 100 && $this->getHttpStatus() < 200;
}
/**
* Was an 'OK' response returned.
* @return bool
*/
public function isSuccess()
{
return $this->getHttpStatus() >= 200 && $this->getHttpStatus() < 300;
}
/**
* Was a 'redirect' returned.
* @return bool
*/
public function isRedirect()
{
return $this->getHttpStatus() >= 300 && $this->getHttpStatus() < 400;
}
/**
* Was an 'error' returned (client error or server error).
* @return bool
*/
public function isError()
{
return $this->getHttpStatus() >= 400 && $this->getHttpStatus() < 600;
}
/**
* Was a 'client error' returned.
* @return bool
*/
public function isClientError()
{
return $this->getHttpStatus() >= 400 && $this->getHttpStatus() < 500;
}
/**
* Was a 'server error' returned.
* @return bool
*/
public function isServerError()
{
return $this->getHttpStatus() >= 500 && $this->getHttpStatus() < 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|array
* @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;
}
/**
* Get response from the curl request
* @return string|false
*/
public function getResponse()
{
return $this->response;
}
/**
* Get curl error code
* @return string
*/
public function getErrorCode()
{
return $this->curl_error_code;
}
/**
* Get curl error message
* @return string
*/
public function getErrorMessage()
{
return $this->curl_error_message;
}
/**
* Get http status code from the curl request
* @return int
*/
public function getHttpStatus()
{
return $this->http_status_code;
}
}

277
vendor/curl/curl/tests/CurlTest.php vendored Normal file
View 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;
}
}

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,9 @@
FROM alpine:3.7
RUN apk add --no-cache php5-cli php5-curl php5-gd php5-phar php5-json php5-openssl php5-dom
COPY php-curl-test php-curl-test
EXPOSE 80
CMD ["php5", "-S", "0.0.0.0:80", "-t", "php-curl-test"]

View File

@@ -0,0 +1,37 @@
<?php
// The commands
$commands = array(
'cd ../../.. && git pull',
);
// Run the commands for output
$output = '';
foreach($commands AS $command){
// Run it
$tmp = shell_exec($command);
// Output
$output .= "<span style=\"color: #6BE234;\">\$</span> <span style=\"color: #729FCF;\">{$command}\n</span>";
$output .= htmlentities(trim($tmp)) . "\n";
}
// Make it pretty for manual user access (and why not?)
?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>GIT DEPLOYMENT SCRIPT</title>
</head>
<body style="background-color: #000000; color: #FFFFFF; font-weight: bold; padding: 0 10px;">
<pre>
. ____ . ____________________________
|/ \| | |
[| <span style="color: #FF0000;">&hearts; &hearts;</span> |] | Git Deployment Script v0.1 |
|___==___| / &copy; oodavid 2012 |
|____________________________|
<?php echo $output; ?>
</pre>
</body>
</html>

View File

@@ -0,0 +1,14 @@
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'canceled';
exit;
}
header('Content-Type: application/json');
echo json_encode(array(
'username' => $_SERVER['PHP_AUTH_USER'],
'password' => $_SERVER['PHP_AUTH_PW'],
));

View File

@@ -0,0 +1,21 @@
<?php
$request_method = isset($_SERVER['REQUEST_METHOD']) ?
$_SERVER['REQUEST_METHOD'] : '';
$data_values = $request_method === 'POST' ? $_POST : $_GET;
$key = isset($data_values['key']) ? $data_values['key'] : '';
$response = array();
$response['request_method'] = $request_method;
$response['key'] = $key;
if(isset($_FILES[$key])) {
$response['mime_content_type'] = mime_content_type($_FILES[$key]['tmp_name']);
} else {
$response['mime_content_type'] = 'ERROR';
}
echo json_encode($response);

View File

@@ -0,0 +1,4 @@
<?php
$http_raw_post_data = file_get_contents('php://input');
echo $http_raw_post_data;

View File

@@ -0,0 +1,31 @@
<?php
$request_method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '';
$data_values = $request_method === 'POST' ? $_POST : $_GET;
$test = isset($data_values['test']) ? $data_values['test'] : '';
$key = isset($data_values['key']) ? $data_values['key'] : '';
if ($test === 'put_file_handle') {
$tmp_filename = tempnam('/tmp', 'php-curl-class.');
file_put_contents($tmp_filename, file_get_contents('php://input'));
echo mime_content_type($tmp_filename);
unlink($tmp_filename);
exit;
}
header('Content-Type: text/plain');
$data_mapping = array(
'cookie' => '_COOKIE',
'delete' => '_GET',
'post' => '_POST',
'put' => '_GET',
'server' => '_SERVER',
);
if(isset($data_mapping[$test])) {
$data = ${$data_mapping[$test]};
$value = isset($data[$key]) ? $data[$key] : '';
echo $value;
} else {
echo "Error.";
}

View File

@@ -0,0 +1,6 @@
/.git
composer.lock
vendor
vendor/
.idea
.idea/

View File

@@ -0,0 +1,26 @@
{
"name": "ledccn/bittorrentclient",
"description": "实现对下载服务器管理的代码库",
"type": "library",
"keywords": ["transmission", "qBittorrent"],
"homepage": "https://github.com/ledccn/BittorrentClient",
"license": "GPL-3.0-or-later",
"authors": [
{
"name": "David",
"email": "367013672@qq.com"
}
],
"require": {
"php": "^5.6 | ^7.0",
"curl/curl": "^2.3",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*"
},
"autoload": {
"psr-4": {
"IYUU\\Client\\": "src"
}
}
}

View File

@@ -0,0 +1,23 @@
## 项目简介
下载服务器的支持库,目前支持
- transmission
- qBittorrent
## 使用方法
https://packagist.org/packages/ledccn/bittorrentclient
```php
composer require ledccn/bittorrentclient:dev-master
```
## 其他项目
| 名称 | 简介 |
| ---------------------------------------------------------- | ------------------------------------------------------------ |
| [IYUUAutoReseed](https://github.com/ledccn/IYUUAutoReseed) | IYUU自动辅种工具功能分为两大块自动辅种、自动转移。目前能对支持的PT站点自动辅种支持下载器集群支持多盘位支持多下载目录支持远程连接等可以实现各下载器之间自动转移做种客户端让下载器各司其职专职的保种、专职的下载。 |

View File

@@ -0,0 +1,145 @@
<?php
/**
* 下载服务器抽象类
* Created by PhpStorm
* User: David <367013672@qq.com>
* Date: 2020-1-11
*/
namespace IYUU\Client;
abstract class AbstractClient
{
/**
* 完整的下载服务器地址
* @var string
*/
protected $url = '';
/**
* 下载服务器用户名
* @var string
*/
protected $username = '';
/**
* 密码
* @var string
*/
protected $password = '';
/**
* 调试开关
* @var bool
*/
public $debug = false;
/**
* 公共方法:创建客户端实例
* @param array $config
* array(
* 'type' => '',
* 'host' => '',
* 'endpoint' => '',
* 'username' => '',
* 'password' => '',
* )
* @return mixed 客户端实例
* @throws \IYUU\Client\ClientException
*/
public static function create($config = [])
{
// 下载服务器类型
$type = isset($config['type']) ? $config['type'] : '';
$file = __DIR__ . DIRECTORY_SEPARATOR . $type . DIRECTORY_SEPARATOR . $type .'.php';
if (!is_file($file)) {
throw new ClientException($file.' 文件不存在');
}
$className = "IYUU\\Client\\" . $type . "\\" . $type;
if (class_exists($className)) {
echo $type." 客户端正在实例化!".PHP_EOL;
return new $className($config);
} else {
throw new ClientException($className.' 客户端class不存在');
}
}
/**
* 初始化必须的参数
* @descr 子类调用
* @param array $config
*/
protected function initialize($config = [])
{
$host = isset($config['host']) ? $config['host'] : ''; // 地址端口
$endpoint = isset($config['endpoint']) ? $config['endpoint'] : ''; // 接入点
$username = isset($config['username']) ? $config['username'] : ''; // 用户名
$password = isset($config['password']) ? $config['password'] : ''; // 密码
$debug = isset($config['debug']) ? $this->booleanParse($config['debug']) : false; // 调试开关
$this->url = rtrim($host, '/') . $endpoint;
$this->username = $username;
$this->password = $password;
$this->debug = $debug;
}
/**
* 对布尔型进行格式化
* @param mixed $value 变量值
* @return boolean/string 格式化后的变量
*/
public function booleanParse($value)
{
$rs = $value;
if (!is_bool($value)) {
if (is_numeric($value)) {
$rs = $value > 0 ? true : false;
} elseif (is_string($value)) {
$rs = in_array(strtolower($value), ['ok', 'true', 'success', 'on', 'yes', '(ok)', '(true)', '(success)', '(on)', '(yes)']) ? true : false;
} else {
$rs = $value ? true : false;
}
}
return $rs;
}
/**
* 查询Bittorrent客户端状态
* @return string
*/
abstract public function status();
/**
* 获取所有种子的列表
* @param array $move
* @return array(
* 'hash' => string json,
* 'sha1' => string,
* 'hashString '=> array
* )
*/
abstract public function all(&$move = array());
/**
* 添加种子连接
* @param string $torrent_url
* @param string $save_path
* @param array $extra_options
*/
abstract public function add($torrent_url, $save_path = '', $extra_options = array());
/**
* 添加种子原数据
* @param string $torrent_metainfo
* @param string $save_path
* @param array $extra_options
*/
abstract public function add_metainfo($torrent_metainfo, $save_path = '', $extra_options = array());
/**
* 删除种子
* @param $torrent
* @param bool $deleteFiles
*/
abstract public function delete($torrent, $deleteFiles = false);
}

View File

@@ -0,0 +1,12 @@
<?php
namespace IYUU\Client;
use Exception;
/**
* Class ClientException
*/
class ClientException extends Exception
{
}

View File

@@ -0,0 +1,11 @@
{
"name": "qBittorrent",
"author": "David",
"homepage": "https://github.com/qbittorrent/qBittorrent",
"version": "1.0",
"icon": "https://www.iyuu.cn/usr/uploads/client/qBittorrent.ico",
"allowCustomPath": true,
"pathDescription": "当前目录列表配置是指定硬盘上的绝对路径,如 /volume1/music/ 或 D:\\download\\music\\",
"description": "当前支持 qBittorrent v4.1+,由于浏览器限制,需要禁用 qBittorrent 的『启用跨站请求伪造(CSRF)保护』功能才能正常使用",
"warning": "注意:由于 qBittorrent 验证机制限制,第一次测试连接成功后,后续测试无论密码正确与否都会提示成功。"
}

View File

@@ -0,0 +1,674 @@
<?php
namespace IYUU\Client\qBittorrent;
use Curl\Curl;
use IYUU\Client\AbstractClient;
use IYUU\Client\ClientException;
/**
* qBittorrent下载服务器的API操作类
* 开源项目地址https://github.com/qbittorrent/qBittorrent
* API文档https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation
*/
class qBittorrent extends AbstractClient
{
/**
* API主版本号
* @var int|mixed|string
*/
private $api_version = '';
/**
* CSRF使用的Session或者Cookie
* @var string
*/
private $session_id = '';
/**
* curl实例
* @var Curl
*/
private $curl;
/**
* 分隔符
* @var string
*/
protected $delimiter = '';
/**
* 各版的API接入点
* @var array
*/
private $endpoints = [
'login' => [
'1' => '/login',
'2' => '/api/v2/auth/login'
],
'logout'=> [
'1' => null,
'2' => '/api/v2/auth/logout'
],
'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'
],
'downloadLimit' => [
'1' => null,
'2' => '/api/v2/transfer/downloadLimit'
],
'setDownloadLimit' => [
'1' => null,
'2' => '/api/v2/transfer/setDownloadLimit'
],
'uploadLimit' => [
'1' => null,
'2' => '/api/v2/transfer/uploadLimit'
],
'setUploadLimit' => [
'1' => null,
'2' => '/api/v2/transfer/setUploadLimit'
],
'torrent_list' => [
'1' => null,
'2' => '/api/v2/torrents/info'
],
'torrent_properties' => [
'1' => null,
'2' => '/api/v2/torrents/properties'
],
'torrent_trackers' => [
'1' => null,
'2' => '/api/v2/torrents/trackers'
],
'torrent_files' => [
'1' => null,
'2' => '/api/v2/torrents/files'
],
'torrent_pieceStates' => [
'1' => null,
'2' => '/api/v2/torrents/pieceStates'
],
'torrent_pieceHashes' => [
'1' => null,
'2' => '/api/v2/torrents/pieceHashes'
],
'torrent_pause' => [
'1' => null,
'2' => '/api/v2/torrents/pause'
],
'torrent_resume' => [
'1' => null,
'2' => '/api/v2/torrents/resume'
],
'torrent_delete' => [
'1' => null,
'2' => '/api/v2/torrents/delete'
],
'torrent_recheck' => [
'1' => null,
'2' => '/api/v2/torrents/recheck' // 重新校验种子
],
'torrent_reannounce' => [
'1' => null,
'2' => '/api/v2/torrents/reannounce' // 重新宣告种子
],
'torrent_add' => [
'1' => null,
'2' => '/api/v2/torrents/add'
],
'torrent_addTrackers' => [
'1' => null,
'2' => '/api/v2/torrents/addTrackers'
],
'torrent_editTracker' => [
'1' => null,
'2' => '/api/v2/torrents/editTracker'
],
'torrent_removeTrackers' => [
'1' => null,
'2' => '/api/v2/torrents/removeTrackers'
],
'torrent_addPeers' => [
'1' => null,
'2' => '/api/v2/torrents/addPeers'
],
'torrent_increasePrio' => [
'1' => null,
'2' => '/api/v2/torrents/increasePrio'
],
'torrent_decreasePrio' => [
'1' => null,
'2' => '/api/v2/torrents/decreasePrio'
],
'torrent_downloadLimit' => [
'1' => null,
'2' => '/api/v2/torrents/downloadLimit'
],
'torrent_setDownloadLimit' => [
'1' => null,
'2' => '/api/v2/torrents/setDownloadLimit'
],
'torrent_setShareLimits' => [
'1' => null,
'2' => '/api/v2/torrents/setShareLimits'
],
'torrent_uploadLimit' => [
'1' => null,
'2' => '/api/v2/torrents/uploadLimit'
],
'torrent_setUploadLimit' => [
'1' => null,
'2' => '/api/v2/torrents/setUploadLimit'
],
'torrent_setLocation' => [
'1' => null,
'2' => '/api/v2/torrents/setLocation'
],
'torrent_rename' => [
'1' => null,
'2' => '/api/v2/torrents/rename'
],
'torrent_setCategory' => [
'1' => null,
'2' => '/api/v2/torrents/setCategory'
],
'torrent_categories' => [
'1' => null,
'2' => '/api/v2/torrents/categories'
],
'torrent_createCategory' => [
'1' => null,
'2' => '/api/v2/torrents/createCategory'
],
'torrent_editCategory' => [
'1' => null,
'2' => '/api/v2/torrents/editCategory'
],
'torrent_removeCategories' => [
'1' => null,
'2' => '/api/v2/torrents/removeCategories'
],
'torrent_addTags' => [
'1' => null,
'2' => '/api/v2/torrents/addTags'
],
'torrent_removeTags' => [
'1' => null,
'2' => '/api/v2/torrents/removeTags'
],
'torrent_tags' => [
'1' => null,
'2' => '/api/v2/torrents/tags'
],
'torrent_createTags' => [
'1' => null,
'2' => '/api/v2/torrents/createTags'
],
'torrent_deleteTags' => [
'1' => null,
'2' => '/api/v2/torrents/deleteTags'
],
'torrent_setAutoManagement' => [
'1' => null,
'2' => '/api/v2/torrents/setAutoManagement'
],
'torrent_toggleSequentialDownload' => [
'1' => null,
'2' => '/api/v2/torrents/toggleSequentialDownload'
],
'torrent_toggleFirstLastPiecePrio' => [
'1' => null,
'2' => '/api/v2/torrents/toggleFirstLastPiecePrio'
],
'torrent_setForceStart' => [
'1' => null,
'2' => '/api/v2/torrents/setForceStart'
],
'torrent_setSuperSeeding' => [
'1' => null,
'2' => '/api/v2/torrents/setSuperSeeding'
],
'torrent_renameFile' => [
'1' => null,
'2' => '/api/v2/torrents/renameFile'
],
'maindata' => [
'1' => null,
'2' => '/api/v2/sync/maindata'
],
];
/**
* 构造函数
* @param array $config
* @throws ClientException
*/
public function __construct($config = [])
{
$this->initialize($config);
$this->api_version = isset($config['api_version']) && $config['api_version'] ? $config['api_version'] : 2;
$this->curl = new Curl();
$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false); // 禁止验证证书
$this->curl->setOpt(CURLOPT_SSL_VERIFYHOST, 2); // 不检查证书
$this->curl->setOpt(CURLOPT_CONNECTTIMEOUT, 60); // 超时
$this->curl->setOpt(CURLOPT_TIMEOUT, 600); // 超时
if (!$this->login()) {
throw new ClientException("qBittorrent Unable to authenticate with Web Api.");
}
}
/**
* app编译版本
* @return string
*/
public function appVersion()
{
return $this->getData('app_version');
}
/**
* api版本
* @return string
*/
public function apiVersion()
{
return $this->getData('api_version');
}
/**
* 编译信息
* @return array
*/
public function buildInfo()
{
return $this->getData('build_info');
}
/**
* 下载器验证
* @return bool
*/
public function login()
{
$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->session_id = $matches[0];
$qb415 = '; QB_'.$matches[0]; // 兼容qBittorrent v4.1.5[小钢炮等]
$this->curl->setHeader('Cookie', $matches[0].$qb415);
return true;
}
};
return false;
}
/**
* 退出登录
* @return mixed
*/
public function logout()
{
$this->session_id = '';
$this->getData('logout');
$this->curl->reset();
return $this;
}
/**
* 获取下载器首选项
* @return mixed
*/
public function preferences()
{
return $this->getData('preferences');
}
/**
* 设置下载器首选项
* @param array $data
* @return array|mixed
*/
public function setPreferences($data = [])
{
if (!empty($data)) {
return $this->postData('setPreferences', ['json' => json_encode($data)]);
}
return [];
}
/**
* 获取种子列表
* @return mixed
*/
public function torrentList()
{
return $this->getData('torrent_list');
}
/**
* 添加种子链接
* @param $torrent_url
* @param string $save_path
* @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);
}
/**
* 添加种子元数据
* @param string $torrent_metainfo
* @param string $save_path
* @param array $extra_options
* @return false|string|null
*/
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;
#$extra_options['skip_checking'] = 'true'; //跳校验
// 关键 上传文件流 multipart/form-data【严格按照api文档编写】
$post_data = $this->buildData($extra_options);
// 设置请求头
$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);
}
/**
* 删除所有种子
* @param bool $deleteFiles
* @return string
*/
public function deleteAll($deleteFiles = false)
{
$torrents = json_decode($this->torrentList());
$response = '';
foreach ($torrents as $torrent) {
$response .= $this->delete($torrent->hash, $deleteFiles);
}
return $response;
}
/**
* 暂停种子
* @param string $hash info_hash可以|分隔删除多个种子也可以传入all删除所有种子
* @return false|string|null
*/
public function pause($hash)
{
return $this->postData('torrent_pause', ['hashes' => $hash]);
}
/**
* 恢复做种
* @param string $hash info_hash可以|分隔删除多个种子也可以传入all删除所有种子
* @return false|string|null
*/
public function resume($hash)
{
return $this->postData('torrent_resume', ['hashes' => $hash]);
}
/**
* 抽象方法,子类实现
* 删除种子
* @param string $hash info_hash可以|分隔删除多个种子也可以传入all删除所有种子
* @param bool $deleteFiles 是否同时删除数据
* @return false|string|null
*/
public function delete($hash = '', $deleteFiles = false)
{
return $this->postData('torrent_delete', ['hashes' => $hash, 'deleteFiles' => $deleteFiles ? 'true':'false']);
}
/**
* 重新校验种子
* @param string $hash info_hash可以|分隔删除多个种子也可以传入all删除所有种子
* @return false|string|null
*/
public function recheck($hash)
{
return $this->postData('torrent_recheck', ['hashes' => $hash]);
}
/**
* 重新宣告种子
* @param string $hash info_hash可以|分隔删除多个种子也可以传入all删除所有种子
* @return false|string|null
*/
public function reannounce($hash)
{
return $this->postData('torrent_reannounce', ['hashes' => $hash]);
}
/**
* @param $hash
* @param $location
* @return false|string|null
*/
public function setTorrentLocation($hash, $location)
{
return $this->postData('torrent_setLocation', ['hashes' => $hash, 'location' => $location]);
}
/**
* 获取当前Curl对象
* @return Curl
*/
public function curl()
{
return $this->curl;
}
/**
* 基本get方法
* @param $endpoint
* @return mixed
*/
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);
var_dump($this->curl->response);
}
if ($this->curl->error) {
return $this->errorMessage();
}
return $this->curl->response;
}
/**
* 基本post方法
* @param $endpoint
* @param $data
* @return mixed
*/
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);
var_dump($this->curl->response);
}
if ($this->curl->error) {
return $this->errorMessage();
}
return $this->curl->response;
}
/**
* 返回错误信息
* @return string
*/
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
* @param array $param
* @return string
*/
public 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. '"' . $eol . $eol;
$data .= $content . $eol;
}
$data .= "--" . $this->delimiter . "--" . $eol;
return $data;
}
/**
* 拼接种子上传文件流 multipart/form-data
* https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation#add-new-torrent
* @param array $param
* @return string
*/
public function buildData($param)
{
$this->delimiter = uniqid();
$eol = "\r\n";
$data = '';
// 拼接文件流
$data .= "--" . $this->delimiter . $eol;
$data .= 'Content-Disposition: form-data; name="' .$param['name']. '"; filename="'.$param['filename'].'"' . $eol;
$data .= 'Content-Type: application/x-bittorrent' . $eol . $eol;
$data .= $param['torrents'] . $eol;
unset($param['name']);
unset($param['filename']);
unset($param['torrents']);
if (!empty($param)) {
foreach ($param as $name => $content) {
$data .= "--" . $this->delimiter . $eol;
$data .= 'Content-Disposition: form-data; name="' . $name . '"' . $eol . $eol;
$data .= $content . $eol;
}
}
$data .= "--" . $this->delimiter . "--" . $eol;
return $data;
}
/**
* 抽象方法,子类实现
*/
public function status()
{
return $this->appVersion();
}
/**
* 抽象方法,子类实现
* @param array $torrentList
* @return array
*/
public function all(&$torrentList = array())
{
$result = $this->getData('torrent_list');
$res = json_decode($result, true);
if (empty($res)) {
echo "获取种子列表失败可能qBittorrent暂时无响应请稍后重试".PHP_EOL;
return array();
}
// 过滤,只保留正常做种
$res = array_filter($res, function ($v) {
if (isset($v['state']) && in_array($v['state'], array('uploading','stalledUP','pausedUP','queuedUP','checkingUP','forcedUP'))) {
return true;
}
return false;
}, ARRAY_FILTER_USE_BOTH);
if (empty($res)) {
echo "未获取到正常做种数据,请多保种,然后重试!".PHP_EOL;
return array();
}
// 提取数组hashString
$info_hash = array_column($res, 'hash');
// 升序排序
sort($info_hash);
$json = json_encode($info_hash, JSON_UNESCAPED_UNICODE);
// 去重 应该从文件读入,防止重复提交
$sha1 = sha1($json);
// 组装返回数据
$hashArray['hash'] = $json;
$hashArray['sha1'] = $sha1;
// 变换数组hashString键名、目录为键值
$hashArray['hashString'] = array_column($res, "save_path", 'hash');
$torrentList = array_column($res, null, 'hash');
return $hashArray;
}
}

View File

@@ -0,0 +1,10 @@
{
"name": "Transmission",
"author": "David",
"homepage": "https://github.com/transmission/transmission",
"version": "1.0",
"icon": "https://www.iyuu.cn/usr/uploads/client/transmission.ico",
"allowCustomPath": true,
"pathDescription": "当前目录列表配置是指定硬盘上的绝对路径,如 /volume1/music/",
"description": "默认情况下,系统会请求 http://ip:port/transmission/rpc 这个路径,如果无法连接,请确认 `settings.json` 文件的 `rpc-url` 值;"
}

View File

@@ -0,0 +1,990 @@
<?php
namespace IYUU\Client\transmission;
use Curl\Curl;
use IYUU\Client\AbstractClient;
use IYUU\Client\ClientException;
/**
* Transmission下载服务器的RPC操作类
* 开源项目地址https://github.com/transmission/transmission
* API文档https://github.com/transmission/transmission/blob/master/extras/rpc-spec.txt
*/
class transmission extends AbstractClient
{
/**
* UserAgent
*/
const UA = 'TransmissionRPC for PHP/7.0.0';
/**
* Transmission RPC version
* @var int
*/
protected $rpc_version = 0;
/**
* CSRF使用的Session或者Cookie
* @var string
*/
protected $session_id = '';
/**
* 种子状态码 torrent status
*/
const TR_STATUS_STOPPED = 0; // Torrent is stopped
const TR_STATUS_CHECK_WAIT = 1; // Queued to check files
const TR_STATUS_CHECK = 2; // Checking files
const TR_STATUS_DOWNLOAD_WAIT = 3; // Queued to download
const TR_STATUS_DOWNLOAD = 4; // Downloading
const TR_STATUS_SEED_WAIT = 5; // Queued to seed
const TR_STATUS_SEED = 6; // Seeding
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;
/**
* 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;
/**
* Curl实例
* @var
*/
private $curl;
/**
* 构造函数
* @param array $config
*/
public function __construct($config = [])
{
$this->initialize($config);
$this->curl = new Curl();
$this->curl->setOpt(CURLOPT_CONNECTTIMEOUT, 60); // 超时
$this->curl->setOpt(CURLOPT_TIMEOUT, 600); // 超时
}
/**
* 开始一个或多个种子
* Start one or more torrents
* @param int|array ids A list of transmission torrent ids
* @return mixed
* @throws ClientException
*/
public function start($ids)
{
if (!is_array($ids)) {
$ids = array($ids);
}
$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
* @return mixed
* @throws ClientException
*/
public function stop($ids)
{
if (!is_array($ids)) {
$ids = array($ids);
}
$request = array("ids" => $ids);
return $this->request("torrent-stop", $request);
}
/**
* 校验一个或多个种子
* Verify one or more torrents
*
* @param int|array ids A list of transmission torrent ids
* @return mixed
* @throws ClientException
*/
public function verify($ids)
{
if (!is_array($ids)) {
$ids = array($ids);
}
$request = array("ids" => $ids);
return $this->request("torrent-verify", $request);
}
/**
* 删除一个或多个种子
* Remove torrent from transmission
* @param int|array ids A list of transmission torrent ids
* @param bool $delete_local_data 是否删除数据
* @return mixed
* @throws ClientException
*/
public function delete($ids, $delete_local_data = false)
{
if (!is_array($ids)) {
$ids = array($ids);
}
$request = array(
"ids" => $ids,
"delete-local-data" => $delete_local_data
);
return $this->request("torrent-remove", $request);
}
/**
* 从announce获取一个或多个种子的更多Peer
* Reannounce one or more torrents
* @param int|array ids A list of transmission torrent ids
* @return mixed
* @throws ClientException
*/
public function reannounce($ids)
{
if (!is_array($ids)) {
$ids = array($ids);
}
$request = array("ids" => $ids);
return $this->request("torrent-reannounce", $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".
* key | type | source
----------------------------+-----------------------------+---------
activityDate | number | tr_stat
addedDate | number | tr_stat
bandwidthPriority | number | tr_priority_t
comment | string | tr_info
corruptEver | number | tr_stat
creator | string | tr_info
dateCreated | number | tr_info
desiredAvailable | number | tr_stat
doneDate | number | tr_stat
downloadDir | string | tr_torrent
downloadedEver | number | tr_stat
downloadLimit | number | tr_torrent
downloadLimited | boolean | tr_torrent
error | number | tr_stat
errorString | string | tr_stat
eta | number | tr_stat
etaIdle | number | tr_stat
files | array (see below) | n/a
fileStats | array (see below) | n/a
hashString | string | tr_info
haveUnchecked | number | tr_stat
haveValid | number | tr_stat
honorsSessionLimits | boolean | tr_torrent
id | number | tr_torrent
isFinished | boolean | tr_stat
isPrivate | boolean | tr_torrent
isStalled | boolean | tr_stat
leftUntilDone | number | tr_stat
magnetLink | string | n/a
manualAnnounceTime | number | tr_stat
maxConnectedPeers | number | tr_torrent
metadataPercentComplete | double | tr_stat
name | string | tr_info
peer-limit | number | tr_torrent
peers | array (see below) | n/a
peersConnected | number | tr_stat
peersFrom | object (see below) | n/a
peersGettingFromUs | number | tr_stat
peersSendingToUs | number | tr_stat
percentDone | double | tr_stat
pieces | string (see below) | tr_torrent
pieceCount | number | tr_info
pieceSize | number | tr_info
priorities | array (see below) | n/a
queuePosition | number | tr_stat
rateDownload (B/s) | number | tr_stat
rateUpload (B/s) | number | tr_stat
recheckProgress | double | tr_stat
secondsDownloading | number | tr_stat
secondsSeeding | number | tr_stat
seedIdleLimit | number | tr_torrent
seedIdleMode | number | tr_inactvelimit
seedRatioLimit | double | tr_torrent
seedRatioMode | number | tr_ratiolimit
sizeWhenDone | number | tr_stat
startDate | number | tr_stat
status | number | tr_stat
trackers | array (see below) | n/a
trackerStats | array (see below) | n/a
totalSize | number | tr_info
torrentFile | string | tr_info
uploadedEver | number | tr_stat
uploadLimit | number | tr_torrent
uploadLimited | boolean | tr_torrent
uploadRatio | double | tr_stat
wanted | array (see below) | n/a
webseeds | array (see below) | n/a
webseedsSendingToUs | number | tr_stat
| |
-------------------+--------+-----------------------------+
files | array of objects, each containing: |
+-------------------------+------------+
| bytesCompleted | number | tr_torrent
| length | number | tr_info
| name | string | tr_info
-------------------+--------------------------------------+
fileStats | a file's non-constant properties. |
| array of tr_info.filecount objects, |
| each containing: |
+-------------------------+------------+
| bytesCompleted | number | tr_torrent
| wanted | boolean | tr_info
| priority | number | tr_info
-------------------+--------------------------------------+
peers | array of objects, each containing: |
+-------------------------+------------+
| address | string | tr_peer_stat
| clientName | string | tr_peer_stat
| clientIsChoked | boolean | tr_peer_stat
| clientIsInterested | boolean | tr_peer_stat
| flagStr | string | tr_peer_stat
| isDownloadingFrom | boolean | tr_peer_stat
| isEncrypted | boolean | tr_peer_stat
| isIncoming | boolean | tr_peer_stat
| isUploadingTo | boolean | tr_peer_stat
| isUTP | boolean | tr_peer_stat
| peerIsChoked | boolean | tr_peer_stat
| peerIsInterested | boolean | tr_peer_stat
| port | number | tr_peer_stat
| progress | double | tr_peer_stat
| rateToClient (B/s) | number | tr_peer_stat
| rateToPeer (B/s) | number | tr_peer_stat
-------------------+--------------------------------------+
peersFrom | an object containing: |
+-------------------------+------------+
| fromCache | number | tr_stat
| fromDht | number | tr_stat
| fromIncoming | number | tr_stat
| fromLpd | number | tr_stat
| fromLtep | number | tr_stat
| fromPex | number | tr_stat
| fromTracker | number | tr_stat
-------------------+--------------------------------------+
pieces | A bitfield holding pieceCount flags | tr_torrent
| which are set to 'true' if we have |
| the piece matching that position. |
| JSON doesn't allow raw binary data, |
| so this is a base64-encoded string. |
-------------------+--------------------------------------+
priorities | an array of tr_info.filecount | tr_info
| numbers. each is the tr_priority_t |
| mode for the corresponding file. |
-------------------+--------------------------------------+
trackers | array of objects, each containing: |
+-------------------------+------------+
| announce | string | tr_tracker_info
| id | number | tr_tracker_info
| scrape | string | tr_tracker_info
| tier | number | tr_tracker_info
-------------------+--------------------------------------+
trackerStats | array of objects, each containing: |
+-------------------------+------------+
| announce | string | tr_tracker_stat
| announceState | number | tr_tracker_stat
| downloadCount | number | tr_tracker_stat
| hasAnnounced | boolean | tr_tracker_stat
| hasScraped | boolean | tr_tracker_stat
| host | string | tr_tracker_stat
| id | number | tr_tracker_stat
| isBackup | boolean | tr_tracker_stat
| lastAnnouncePeerCount | number | tr_tracker_stat
| lastAnnounceResult | string | tr_tracker_stat
| lastAnnounceStartTime | number | tr_tracker_stat
| lastAnnounceSucceeded | boolean | tr_tracker_stat
| lastAnnounceTime | number | tr_tracker_stat
| lastAnnounceTimedOut | boolean | tr_tracker_stat
| lastScrapeResult | string | tr_tracker_stat
| lastScrapeStartTime | number | tr_tracker_stat
| lastScrapeSucceeded | boolean | tr_tracker_stat
| lastScrapeTime | number | tr_tracker_stat
| lastScrapeTimedOut | boolean | tr_tracker_stat
| leecherCount | number | tr_tracker_stat
| nextAnnounceTime | number | tr_tracker_stat
| nextScrapeTime | number | tr_tracker_stat
| scrape | string | tr_tracker_stat
| scrapeState | number | tr_tracker_stat
| seederCount | number | tr_tracker_stat
| tier | number | tr_tracker_stat
-------------------+-------------------------+------------+
wanted | an array of tr_info.fileCount | tr_info
| 'booleans' true if the corresponding |
| file is to be downloaded. |
-------------------+--------------------------------------+
webseeds | an array of strings: |
+-------------------------+------------+
| webseed | string | tr_info
+-------------------------+------------+
*
* @param array fields An array of return fields
* @param int|array ids A list of transmission torrent ids
* 示例 Example:
Say we want to get the name and total size of torrents #7 and #10.
请求 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
}
*
* @return mixed
* @throws ClientException
*/
public function get($ids = [], $fields = [])
{
$default = ["id", "name", "status", "doneDate", "haveValid", "totalSize"];
if (!is_array($ids)) {
$ids = array($ids);
}
if (empty($fields)) {
$fields = $default;
} else {
$fields = is_array($fields) ? array_merge($default, $fields) : $default;
}
$request = array(
"fields" => $fields,
"ids" => $ids
);
return $this->request("torrent-get", $request);
}
/**
* 设置一个或多个种子的参数
* Set properties on one or more torrents, available fields are:
* string | value type & description
----------------------+-------------------------------------------------
"bandwidthPriority" | number this torrent's bandwidth tr_priority_t
"downloadLimit" | number maximum download speed (KBps)
"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)
"queuePosition" | number position of this torrent in its queue [0...n)
"seedIdleLimit" | number torrent-level number of minutes of seeding inactivity
"seedIdleMode" | number which seeding inactivity to use. See tr_idlelimit
"seedRatioLimit" | double torrent-level seeding ratio
"seedRatioMode" | number which ratio to use. See tr_ratiolimit
"trackerAdd" | array strings of announce URLs to add
"trackerRemove" | array ids of trackers to remove
"trackerReplace" | array pairs of <trackerId/new announce URLs>
"uploadLimit" | number maximum upload speed (KBps)
"uploadLimited" | boolean true if "uploadLimit" is honored
*
* @param array arguments An associative array of arguments to set
* @param int|array ids A list of transmission torrent ids
* @return mixed
* @throws ClientException
*/
public function set($ids = array(), $arguments = array())
{
if (!is_array($ids)) {
$ids = array($ids);
}
if (!isset($arguments['ids'])) {
$arguments['ids'] = $ids;
}
return $this->request("torrent-set", $arguments);
}
/**
* 添加新种子 (URL)
* Add a new torrent
*
* Request arguments:
* key | value type & description
---------------------+-------------------------------------------------
"cookies" | string pointer to a string of one or more cookies.
"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)
*
* 参数内必须包含"filename"或"metainfo"字段,其他字段都可选。
* Either "filename" OR "metainfo" MUST be included.
All other arguments are optional.
*
* @param string $filename 字符串文件名或种子urlThe URL or path to the torrent file
* @param string $save_path Folder to save torrent in
* @param array $extra_options Optional extra torrent options
* @return mixed
* @throws ClientException
*/
public function add($filename, $save_path = '', $extra_options = array())
{
if (!empty($save_path)) {
$extra_options['download-dir'] = $save_path;
}
$extra_options['filename'] = $filename;
return $this->request("torrent-add", $extra_options);
}
/**
* 添加新种子 (元数据)
* Add a torrent using the raw torrent data
* @param string $torrent_metainfo The raw, unencoded contents (metainfo) of a torrent
* @param string $save_path Folder to save torrent in
* @param array $extra_options Optional extra torrent options
* @return mixed
* @throws ClientException
*/
public function add_metainfo($torrent_metainfo, $save_path = '', $extra_options = array())
{
if (!empty($save_path)) {
$extra_options['download-dir'] = $save_path;
}
$extra_options['metainfo'] = base64_encode($torrent_metainfo);
return $this->request("torrent-add", $extra_options);
}
/**
* 变更数据保存目录
* Move local storage location
*
* Request arguments:
string | value type & description
---------------------------------+-------------------------------------------------
"ids" | array torrent list, as described in 3.1
"location" | string the new torrent location
"move" | boolean if true, move from previous location.
| otherwise, search "location" for files
| (default: false)
*
* @param int|array $ids A list of transmission torrent ids
* @param string $target_location The new storage location
* @param boolean $move_existing_data Move existing data or scan new location for available data
* @return mixed
* @throws ClientException
*/
public function move($ids, $target_location, $move_existing_data = true)
{
if (!is_array($ids)) {
$ids = array($ids);
}
$request = array(
"ids" => $ids,
"location" => $target_location,
"move" => $move_existing_data
);
return $this->request("torrent-set-location", $request);
}
/**
* 修改种子文件或目录名称
* Renaming a Torrent's 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
* @return mixed
* @throws ClientException
*/
public function rename($ids, $path, $name)
{
if (!is_array($ids)) {
$ids = array($ids);
}
if (count($ids) !== 1) {
throw new ClientException('A single id is accepted', self::E_INVALIDARG);
}
$request = array(
"ids" => $ids,
"path" => $path,
"name" => $name
);
return $this->request("torrent-rename-path", $request);
}
/**
* Session 请求
* (4.1) Session 参数
* string | value type | description
* ---------------------------------+------------+-------------------------------------
* "alt-speed-down" | number | max global download speed (KBps)
* "alt-speed-enabled" | boolean | true means use the alt speeds
* "alt-speed-time-begin" | number | when to turn on alt speeds (units: minutes after midnight)
* "alt-speed-time-enabled" | boolean | true means the scheduled on/off times are used
* "alt-speed-time-end" | number | when to turn off alt speeds (units: same)
* "alt-speed-time-day" | number | what day(s) to turn on alt speeds (look at tr_sched_day)
* "alt-speed-up" | number | max global upload speed (KBps)
* "blocklist-url" | string | location of the blocklist to use for "blocklist-update"
* "blocklist-enabled" | boolean | true means enabled
* "blocklist-size" | number | number of rules in the blocklist
* "cache-size-mb" | number | maximum size of the disk cache (MB)
* "config-dir" | string | location of transmission's configuration directory
* "download-dir" | string | default path to download torrents
* "download-queue-size" | number | max number of torrents to download at once (see download-queue-enabled)
* "download-queue-enabled" | boolean | if true, limit how many torrents can be downloaded at once
* "dht-enabled" | boolean | true means allow dht in public torrents
* "encryption" | string | "required", "preferred", "tolerated"
* "idle-seeding-limit" | number | torrents we're seeding will be stopped if they're idle for this long
* "idle-seeding-limit-enabled" | boolean | true if the seeding inactivity limit is honored by default
* "incomplete-dir" | string | path for incomplete torrents, when enabled
* "incomplete-dir-enabled" | boolean | true means keep torrents in incomplete-dir until done
* "lpd-enabled" | boolean | true means allow Local Peer Discovery in public torrents
* "peer-limit-global" | number | maximum global number of peers
* "peer-limit-per-torrent" | number | maximum global number of peers
* "pex-enabled" | boolean | true means allow pex in public torrents
* "peer-port" | number | port number
* "peer-port-random-on-start" | boolean | true means pick a random peer port on launch
* "port-forwarding-enabled" | boolean | true means enabled
* "queue-stalled-enabled" | boolean | whether or not to consider idle torrents as stalled
* "queue-stalled-minutes" | number | torrents that are idle for N minuets aren't counted toward seed-queue-size or download-queue-size
* "rename-partial-files" | boolean | true means append ".part" to incomplete files
* "rpc-version" | number | the current RPC API version 当前RPC版本号
* "rpc-version-minimum" | number | the minimum RPC API version supported 支持RPC的最小版本号
* "script-torrent-done-filename" | string | filename of the script to run
* "script-torrent-done-enabled" | boolean | whether or not to call the "done" script
* "seedRatioLimit" | double | the default seed ratio for torrents to use
* "seedRatioLimited" | boolean | true if seedRatioLimit is honored by default
* "seed-queue-size" | number | max number of torrents to uploaded at once (see seed-queue-enabled)
* "seed-queue-enabled" | boolean | if true, limit how many torrents can be uploaded at once
* "speed-limit-down" | number | max global download speed (KBps)
* "speed-limit-down-enabled" | boolean | true means enabled
* "speed-limit-up" | number | max global upload speed (KBps)
* "speed-limit-up-enabled" | boolean | true means enabled
* "start-added-torrents" | boolean | true means added torrents will be started right away
* "trash-original-torrent-files" | boolean | true means the .torrent file of added torrents will be deleted
* "units" | object | see below
* "utp-enabled" | boolean | true means allow utp
* "version" | string | long version string "$version ($revision)"
* ---------------------------------+------------+-----------------------------+
* units | object containing: |
+--------------+--------+------------------+
| speed-units | array | 4 strings: KB/s, MB/s, GB/s, TB/s
| speed-bytes | number | number of bytes in a KB (1000 for kB; 1024 for KiB)
| size-units | array | 4 strings: KB/s, MB/s, GB/s, TB/s
| size-bytes | number | number of bytes in a KB (1000 for kB; 1024 for KiB)
| memory-units | array | 4 strings: KB/s, MB/s, GB/s, TB/s
| memory-bytes | number | number of bytes in a KB (1000 for kB; 1024 for KiB)
+--------------+--------+------------------+
*
* 当前RPC版本号"rpc-version" indicates the RPC interface version supported by the RPC server.
* It is incremented when a new version of Transmission changes the RPC interface.
*
* 支持RPC的最小版本号"rpc-version-minimum" indicates the oldest API supported by the RPC server.
* It is changes when a new version of Transmission changes the RPC interface
* in a way that is not backwards compatible. There are no plans for this
* to be common behavior.
*/
/**
* 获取会话
* Retrieve all session variables
* Method name: "session-get"
Request arguments: an optional "fields" array of keys (see 4.1)
Response arguments: key/value pairs matching the request's "fields"
argument if present, or all supported fields (see 4.1) otherwise.
*
* @returns array of session information
* @throws ClientException
*/
public function sessionGet()
{
return $this->request("session-get", array());
}
/**
* 设置会话
* Set session variable(s)
* Method name: "session-set"
Request arguments: one or more of 4.1's arguments, except: "blocklist-size",
"config-dir", "rpc-version", "rpc-version-minimum",
"version", and "session-id"
Response arguments: none
*
* @param array of session variables to set
* @return mixed
* @throws ClientException
*/
public function sessionSet($arguments)
{
return $this->request("session-set", $arguments);
}
/**
* 会话状态统计
* Retrieve session statistics
*
* Method name: "session-stats"
Request arguments: none
Response arguments:
string | value type
---------------------------+-------------------------------------------------
"activeTorrentCount" | number
"downloadSpeed" | number
"pausedTorrentCount" | number
"torrentCount" | number
"uploadSpeed" | number
---------------------------+-------------------------------+
"cumulative-stats" | object, containing: |
+------------------+------------+
| uploadedBytes | number | tr_session_stats
| downloadedBytes | number | tr_session_stats
| filesAdded | number | tr_session_stats
| sessionCount | number | tr_session_stats
| secondsActive | number | tr_session_stats
---------------------------+-------------------------------+
"current-stats" | object, containing: |
+------------------+------------+
| uploadedBytes | number | tr_session_stats
| downloadedBytes | number | tr_session_stats
| filesAdded | number | tr_session_stats
| sessionCount | number | tr_session_stats
| secondsActive | number | tr_session_stats
*
* @returns array of statistics
* @throws ClientException
*/
public function sessionStats()
{
return $this->request("session-stats", array());
}
/**
* Return the interpretation of the torrent status
*
* @param int The integer "torrent status"
* @returns string The translated meaning
* @return string
*/
public function getStatusString($intstatus)
{
if ($this->rpc_version < 14) {
if ($intstatus == self::RPC_LT_14_TR_STATUS_CHECK_WAIT) {
return "Waiting to verify local files";
}
if ($intstatus == self::RPC_LT_14_TR_STATUS_CHECK) {
return "Verifying local files";
}
if ($intstatus == self::RPC_LT_14_TR_STATUS_DOWNLOAD) {
return "Downloading";
}
if ($intstatus == self::RPC_LT_14_TR_STATUS_SEED) {
return "Seeding";
}
if ($intstatus == self::RPC_LT_14_TR_STATUS_STOPPED) {
return "Stopped";
}
} else {
if ($intstatus == self::TR_STATUS_CHECK_WAIT) {
return "Waiting to verify local files";
}
if ($intstatus == self::TR_STATUS_CHECK) {
return "Verifying local files";
}
if ($intstatus == self::TR_STATUS_DOWNLOAD) {
return "Downloading";
}
if ($intstatus == self::TR_STATUS_SEED) {
return "Seeding";
}
if ($intstatus == self::TR_STATUS_STOPPED) {
return "Stopped";
}
if ($intstatus == self::TR_STATUS_SEED_WAIT) {
return "Queued for seeding";
}
if ($intstatus == self::TR_STATUS_DOWNLOAD_WAIT) {
return "Queued for download";
}
}
return "Unknown";
}
/**
* 对请求数据预处理
* Clean up the request array. Removes any empty fields from the request
*
* @param array array The request associative array to clean
* @returns array The cleaned array
* @return array|null
*/
protected function cleanRequestData($array)
{
if (!is_array($array) || count($array) == 0) {
return null;
}
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 || $value !== false)) { // 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)) {
$type = mb_detect_encoding($value, 'auto');
if ($type !== 'UTF-8') {
$array[$index] = mb_convert_encoding($value, 'UTF-8');
}
}
}
return $array;
}
/**
* 获取当前Curl对象
* @return Curl
*/
public function curl()
{
return $this->curl;
}
/**
* 执行 rpc 请求
* @param string $method 请求类型/方法, 详见 $this->allowMethods
* @param array $arguments 附加参数, 可选
* @return array
* @throws ClientException
*/
protected function request($method, $arguments = array())
{
if (!is_scalar($method)) {
throw new ClientException('Method name has no scalar value', self::E_INVALIDARG);
}
if (!is_array($arguments)) {
throw new ClientException('Arguments must be given as array', self::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 ClientException('Unable to acquire X-Transmission-Session-Id', self::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
);
$curl = $this->curl;
if (stripos($this->url, 'https://') === 0) {
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false); // 禁止验证证书
$curl->setOpt(CURLOPT_SSL_VERIFYHOST, 2); // 不检查证书
}
foreach ($header as $key => $value) {
$curl->setHeader($key, $value);
}
$curl->setUserAgent(self::UA);
$curl->setBasicAuthentication($this->username, $this->password);
$curl->post($this->url, $data, true);
$content = $curl->response;
if ($this->debug) {
var_dump($curl->request_headers);
var_dump($curl->response_headers);
var_dump($curl->response);
}
if (!$content) {
$content = array('result' => 'failed');
}
return json_decode($content, true);
}
/**
* 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()
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->url);
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_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$content = curl_exec($ch);
$error_code = curl_errno($ch);
$error_message = curl_error($ch);
$http_status_code = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
if ($this->debug) {
var_dump($http_status_code);
var_dump($error_message);
var_dump($error_code);
var_dump($content);
}
// 401 Invalid username/password
// 409 成功
// 其他 Unexpected response from Transmission RPC
curl_close($ch);
if($content && preg_match("/<code>X-Transmission-Session-Id: (.*?)<\/code>/", $content, $match)) {
$this->session_id = isset($match[1]) ? $match[1] : null;
}
return $this->session_id;
}
/**
* 抽象方法,子类实现
* 获取下载器链接状态
* @throws ClientException
*/
public function status()
{
$rs = $this->sessionStats();
return isset($rs['result']) ? $rs['result'] : 'error';
}
/**
* 抽象方法,子类实现
* 获取所有种子的列表
* @param array $torrentList
* @return array
* array(
* 'hash' => string json,
* 'sha1' => string,
* 'hashString '=> array
* )
* @throws ClientException
*/
public function all(&$torrentList = array())
{
$ids = array();
$fields = array( "id", "status", "name", "hashString", "downloadDir", "torrentFile" );
$res = $this->get($ids, $fields);
if (isset($res['result']) && $res['result'] === 'success') {
// 成功
} else {
// 失败
echo "从客户端获取种子列表失败可能transmission暂时无响应请稍后重试".PHP_EOL;
return array();
}
if (empty($res['arguments']['torrents'])) {
echo "从客户端未获取到数据,请稍后重试!".PHP_EOL;
return array();
}
$res = $res['arguments']['torrents'];
// 过滤,只保留正常做种
$res = array_filter($res, function ($v) {
return isset($v['status']) && $v['status'] === 6;
}, ARRAY_FILTER_USE_BOTH);
if (empty($res)) {
echo "从客户端未获取到正常做种数据,请多保种,然后重试!".PHP_EOL;
return array();
}
// 提取数组hashString
$info_hash = array_column($res, 'hashString');
// 升序排序
sort($info_hash);
$json = json_encode($info_hash, JSON_UNESCAPED_UNICODE);
// 去重 应该从文件读入,防止重复提交
$sha1 = sha1($json);
// 组装返回数据
$hashArray['hash'] = $json;
$hashArray['sha1'] = $sha1;
// 变换数组hashString为键名、目录为键值
$hashArray['hashString'] = array_column($res, "downloadDir", 'hashString');
$torrentList = array_column($res, null, 'hashString');
return $hashArray;
}
}

View File

@@ -0,0 +1,177 @@
# IYUU新推出RSS订阅功能
## 功能
自动订阅站点的新种,自动添加下载任务,支持大小过滤。
## 优势
1.弥补部分下载器没有RSS订阅的缺陷
2.与下载器本身的RSS功能相比IYUU自动RSS订阅支持远程连接下载器支持下载器多盘位、支持多目录支持筛选支持下载器集群
## 需要配置什么?
1.必须配置各站的`passkey`秘钥,从各站点的`控制面板`复制到配置文件内对应站点`passkey`处即可;
2.TTG的密钥比较特殊请从RSS链接处复制并给站点配置加一个`rss`配置项详情参考示例配置文件TTG配置
前期如果你正确使用了`IYUUAutoReseed自动辅种工具`的话,本部分就非常简单了。
----------
## 如何配置`workingMode`工作模式、`watch`监控目录、`cliects`下载器?
### 第一步完善全局配置
```php
'default' => array(
// 5.【必须配置】浏览器UA打开http://demo.iyuu.cn 复制过来即可
'userAgent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
// 6.【自动辅种必须配置】全局客户端设置(条目不够可以复制)
'clients' => array(
// 全局客户端设置 开始
# 开始
array(
'type' => 'transmission', // 支持transmission、qBittorrent
'host' => 'http://127.0.0.1:9091/transmission/rpc', // 警告注意transmission/rpc这段别动你只需要修改 127.0.0.1:9091
'username' => '',
'password' => '',
),
# 结束
# 开始
array(
'type' => 'qBittorrent', // 支持transmission、qBittorrent
'host' => 'http://www.baidu.com:8083',
'username' => '',
'password' => '',
),
# 结束
// 全局客户端设置 结束
),
'move' =>array(
'type' => 2, // 0保持不变1减2加 3直接替换
'path' =>array(
'/sda1' => '/volume1',
),
),
'workingMode' => 0,
'watch' => '/volume1/downloads',
'filter' => array(
'size'=>array(
'min' => '10GB',
'max' => '280GB',
),
'seeders'=>array(
'min' => 1,
'max' => 3,
),
'leechers'=>array(
'min' => 0,
'max' => 10000,
),
'completed'=>array(
'min' => 0,
'max' => 10000,
),
),
'CONNECTTIMEOUT'=> 60,
'TIMEOUT' => 600,
),
```
----------
### 第二步完善站点配置示例配置m-team
本部分以馒头为例,讲解`工作模式1负载均衡`
关键地方:`clients``workingMode``watch``filter`
- 全局已经配置clients两个用来辅种站点单独配置clients一个用来下载在RSS订阅添加下载任务时**以站点单独配置的clients为准**。
- `workingMode=>1,` 代表当前站点将会工作在模式1
- `watch=>''` 因为站点工作在模式1配置了也无效**留空即可**
- 全局和站点都配置filter该站点RSS订阅添加下载任务时**过滤规则以站点配置为准**
下面是m-team的示例配置代码。
```php
'm-team' => array(
// 14.m-team的cookie 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => 'tp=',
// 15.m-team的passkey 【必须配置】
'passkey' => '',
// 种子Tracker的IP地址选择 可选ipv4ipv6
'ip_type' => 'ipv4',
'clients' => array(
array(
'type' => 'transmission', // 支持transmission、qBittorrent
'host' => 'http://127.0.0.1:9091/transmission/rpc', // 警告注意transmission/rpc这段别动你只需要修改 127.0.0.1:9091
'username' => '',
'password' => '',
),
),
'workingMode' => 1,
'watch' => '',
'filter' => array(
'size'=>array(
'min' => '1GB',
'max' => '280GB',
),
),
),
```
----------
### 第三步完善站点配置示例配置keepfrds
本部分以朋友为例讲解工作模式1负载均衡
关键地方:`clients``workingMode``watch``filter`
- 全局已经配置clients两个用来辅种**站点没有单独配置clients在RSS订阅添加下载任务时以全局配置的clients为准**。
- `workingMode=>1,` 代表当前站点将会工作在模式1
- `watch=>''` 因为站点工作在模式1配置了也无效**留空即可**
- 全局和站点都配置filter该站点RSS订阅添加下载任务时**过滤规则以站点配置为准**
下面是keepfrds的示例配置代码。
```php
'keepfrds' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'workingMode' => 1,
'watch' => '',
'filter' => array(
'size'=>array(
'min' => '1GB',
'max' => '280GB',
),
),
),
```
----------
### 第四步完善站点配置示例配置ourbits
本部分以我堡为例讲解工作模式0watch监控目录
关键地方:`workingMode``watch``filter`
- `workingMode=>0,` 代表当前站点将会工作在模式0**脚本会往指定的watch目录内下载种子**,由下载器添加下载任务;
- `watch=>'/root/downloads'` 脚本会往`/root/downloads`目录内下载种子,由下载器添加下载任务;
- 全局和站点都配置filter该站点RSS订阅添加下载任务时**过滤规则以站点配置为准**
下面是ourbits的示例配置代码。
```php
'ourbits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'id' => 0, // 用户ID
'is_vip' => 0, // 是否具有VIP或特殊权限0 普通1 VIP
'workingMode' => 0,
'watch' => '/root/downloads',
'filter' => array(
'size'=>array(
'min' => '1GB',
'max' => '280GB',
),
),
),
```
## RSS订阅脚本名字`rss.php`
配置好后,执行命令:`php rss.php`即可查看支持RSS的站点列表。
![IYUU1.png][1]
**总结以上详细讲解了RSS订阅下载、下载免费种时的各种配置的情况请仔细阅读务必理解**
其他站点设置RSS订阅同样道理
[1]: https://www.iyuu.cn/usr/uploads/2020/01/3194879294.png

104
wiki/公告栏.md Normal file
View File

@@ -0,0 +1,104 @@
# 公告栏
### 2020年7月31日09:25:55
1. IYUUAutoReseed正式建立了docke镜像自动编译2个版本ARM64【iyuucn/iyuuautoreseed:arm64v8】、AMD64【iyuucn/iyuuautoreseed:latest】使用方法[点击查看](https://gitee.com/ledc/IYUUAutoReseed/tree/master/docker)
2. 优化默认流控参数单次最多20个间隔20秒。天空辅种请配置cookie必须更新至最新版本并配置浏览器UA获取UA请访问[http://demo.iyuu.cn](http://demo.iyuu.cn/)
3. v1.10.2版本以后的docker每5小时会自动拉取最新代码从此您只需要看公告更新配置就行啦。
### 2020年7月13日08:00:00
【更新提醒】v1.9.1
优化App.Api.Sites接口请求时携带版本号版本为空或低于v1.9.1会返回旧数据);
新增:异步间隔流控算法,适用所有站点;各站独立、执行时间最优;
【升级方法】
1.异步间隔流控使用方法参考v1.9.1版本的config.sample.php[第242-245行]把他复制到你想应用流控的站点配置项内解释count表示每次辅种的最大数量sleep表示当前站点每次下载种子最小间隔多少秒。
2.url_replace和url_join是为了最大化兼容未来各种类型站点提前准备的可以自定义URL
解释url_replace是替换下载链接时使用让下载链接支持替换任意参数。举例'url_replace'=>array('{passkey}'=>'123456789'), 下载链接https://pt.baidu.com/download.php?id={}&passkey={passkey}替换后变为https://pt.baidu.com/download.php?id={}&passkey=123456789
解释url_join是拼接下载链接是使用让下载链接支持任意自定义参数。举例
'url_join' => array('ipv6=1','https=1'), 下载链接https://pt.baidu.com/download.php?id={}&passkey=123456789拼接后变为https://pt.baidu.com/download.php?id={}&passkey=123456789&ipv6=1&https=1
### 2020年7月12日19:34:03
【新增功能】v1.9.0
转移过滤器、选择器;可以只转移指定路径的种子,也可以排除指定路径的种子,按需转移。
【升级方法】
1.主脚本可以通过git pull或覆盖更新
2.然后对照最新config.sample.php把59行60行手动加入到你的config.php对应位置。
【重要提醒】域名部署SSL证书接口域名支持双协议访问http/https如下
https://api.iyuu.cn
http://api.iyuu.cn
### 2020年4月10日17:43:50
针对多合作站点绑定的优化!
1.没有更新到v1.7.5以上版本的群友,尽快更新!
2.正在使用v1.7.5以上版本的群友请删除config目录下的siteLoginCache_*.json文件重新运行辅种即可同时绑定多个合作站点。
### 2020年4月4日00:57:36
v1.7.5版本发布新增合作站点moecat合作站点有Ourbits、 HD Dolby、HDHome、PTHome、moecat。【更新提醒】手动升级可以直接覆盖git安装的可通过git pull命令升级脚本升级后然后对比config.sample.php手动在config.php增加用户id配置项辅种时会自动进行验证。
如果有问题,可以群内@我或私聊或到问答社区http://wenda.iyuu.cn/提问,必回。
### 2020年4月1日00:56:31
IYUUAutoReseed自动辅种备忘录gitee代码仓库https://gitee.com/ledc/IYUUAutoReseed
github代码仓库https://github.com/ledccn/IYUUAutoReseed
爱语飞飞:[https://iyuu.cn](https://iyuu.cn/)
大卫博客:[https://www.iyuu.cn](https://www.iyuu.cn/)
问答社区:[http://wenda.iyuu.cn](http://wenda.iyuu.cn/)
接口文档http://api.iyuu.cn/docs.php
### 2020年3月14日22:03:02
时光如梭转眼至v1.6.3感谢一路走来陪伴的朋友们为了共同的爱好我们相聚在这里本版本上线了合作站点认证系统合作站点有Ourbits、 HD Dolby、HDHome。
【更新提醒】手动更新的可以直接覆盖升级git安装脚本的会自动升级脚本然后对比config.sample.php手动添加用户id配置项启动辅种时会自动进行验证。
如果有问题,可以群内@我或到问答社区http://wenda.iyuu.cn/提问,必回。
### 2020年3月13日14:52:32
【重要提醒】IYUUAutoReseed自动辅种工具合作站点有OurBits、HD Dolby、HDHome可以对使用辅种工具的用户进行认证与绑定。
请大家及时根据新的示例配置config.sample.php增加用户id配置项及时认证。
### 2020年3月9日22:52:11
【喜报】辅种服务器顺利迁移阿里云。辅种接口域名api.iyuu.cn
问答社区wenda.iyuu.cn
### 2020年2月22日12:28:55
转移做种常见错误:
1.Windows下运行脚本却填写Linux路径正确应该填写映射的路径
2.Docker运行脚本却填写实际路径正确应该填写Docker内可读的路径
请勿犯此类常识错误。
另外,跳校验和删除当前做种的配置(第二次转移再用)。
### 2020年2月21日18:14:21
由于与海豚管理组沟通时,支持确认度上出现问题,现调整如下: 使用IYUUAutoReseed自动辅种海豚的小伙伴私聊提供海豚UID所有收集到的UID会提交海豚官方备案提供UID不是为了ban但也请遵守海豚的规则。请在配置内删除海豚passkey、authkey。
后续情况待定。
### 2020年2月21日07:42:14
【新增站点】dicmusic海豚音乐版本升级v1.5.0
【支持辅种】学校、杜比、家园、天空、朋友、馒头、萌猫、我堡、猫站、铂金家、烧包、北洋、TCCF、南洋、TTG、映客、城市、52pt、brobits、备胎、SSD、CHD、ptmsg、leaguehd、聆音、瓷器、hdarea、eastgame(TLF)、1ptba、hdtime、hd4fans、opencd、hdbug、hdstreet、joyhd、u2、upxin(HDU)、oshen、discfan(GZT)、北邮、CCFBits、dicmusic。
【重要提醒】Api/Reseed接口是合并所有客户端发起的请求当做种超过10000时存在失败可能预备10天后停止。v1.3.0以上版本不受此影响。
【升级方法】15号之后的版本直接覆盖。
### 2020年1月9日12:06:03
使用IYUUAutoReseed自动化辅种工具本身是非常安全的辅种过程不会跟PT站点服务器产生任何关系只是会把下载种子链接推送给下载器。也就是说任何站点、任何技术都无法检测你是否使用了IYUU。建议不要自己手动跳校验任何因为跳校验ban号别怪我没提醒也请出事不要怪到IYUU或者Reseed的头上。

View File

@@ -1,4 +1,12 @@
## 重点讲解Ourbits站点的鉴权配置
## 支持用户验证的合作站点:`ourbits`,`hddolby`,`hdhome`,`pthome`,`moecat`
截止2020年7月17日20:30:53【文档更新有延迟最终以gitee、github为准】
----------
## 以讲解Ourbits站点的鉴权配置为例
博客链接https://www.iyuu.cn/archives/337/
IYUU自动辅种工具、Ourbits双方达成合作可以对使用接口的用户实现认证。
### 申请爱语飞飞微信通知token新用户访问http://iyuu.cn 申请!
@@ -6,22 +14,21 @@ IYUU自动辅种工具、Ourbits双方达成合作可以对使用接口的用
![微信通知1.png][1]
![微信通知2.png][2]
![微信通知3.png][3]
2.复制您的token令牌到`/app/config/config.php`文件内的`iyuu.cn`对应的配置字段,保存。如图:
2.复制您的token令牌到`/config/config.php`文件内的`iyuu.cn`对应的配置字段,保存。如图:
![微信通知4.png][4]
### 设置Ourbits
![编辑配置4.png][5]
`passkey`,在你的控制面板 - 密钥
`is_vip`,根据你的实际情况填写,因站点有下载种子的流控,如果你不在限制之列,可以`设置为1`
`id`,为用户中心打开后,浏览器地址栏**http://xxxxx.xxx/userdetails.php?id=`46880`**等号=后面的几个数字,如图:
![编辑配置6.png][6]
到此,配置文件编辑完毕,请记得保存。
如果提示保存格式请保存为UTF8无BOM格式。
[1]: https://www.iyuu.cn/usr/uploads/2019/12/2331433923.png
[2]: https://www.iyuu.cn/usr/uploads/2019/12/3324442680.png
[3]: https://www.iyuu.cn/usr/uploads/2019/12/3181272964.png
[4]: https://www.iyuu.cn/usr/uploads/2019/12/3669828008.png
[5]: https://www.iyuu.cn/usr/uploads/2019/12/3696916642.png
[6]: https://www.iyuu.cn/usr/uploads/2019/12/1230288911.png
[1]: https://www.iyuu.cn/usr/uploads/2019/12/2331433923.png
[2]: https://www.iyuu.cn/usr/uploads/2019/12/3324442680.png
[3]: https://www.iyuu.cn/usr/uploads/2019/12/3181272964.png
[4]: https://www.iyuu.cn/usr/uploads/2019/12/3669828008.png
[5]: https://www.iyuu.cn/usr/uploads/2019/12/3696916642.png
[6]: https://www.iyuu.cn/usr/uploads/2019/12/1230288911.png

View File

@@ -3,7 +3,13 @@ php命令与脚本路径之间是有个空格请注意请注意请注
## IYUU自动辅种命令
`php ./init.php`
`php ./iyuu.php`
## IYUU自动下载种子之RSS订阅
`php ./rss.php 站点名`

View File

@@ -28,24 +28,6 @@
按站内说明修改下载器所在设备的HOST或者在具备修改HOST功能的路由器内修改。
#### 问:我拥有辅种时自动跳过站点的特殊权限,如何设置为可以辅种呢?
答:在站点的独立配置区域,添加一行代码`'is_vip' => 1,`即可。例如Ourbits
```php
// ourbits
'ourbits' => array(
// 如果需要用下载免费种脚本,须配置(只是自动辅种,可以不配置此项)
'cookie' => '',
// 如果需要自动辅种,必须配置
'passkey' => '',
'id' => 46880, // 用户ID
'is_vip' => 1, // 是否具有VIP或特殊权限0 普通1 VIP
),
```
#### 问:如何升级到最新版本?
从github或码云仓库下载最新的源码覆盖到本地即可。
@@ -81,11 +63,33 @@
请退出登录在登录时勾选下面两个SSL的选项登录后复制cookie重新配置。
#### 问IYUU自动辅种失败怎么排查问题
1.输入种子链接,手动方法,看看种子是否还在?
2.手动下载种子,看看是否出现了下载种子的提示页?
3.瓷器、城市需要cookie辅种请检查cookie是否配置正确如果下载出现提示页面需要更新配置内的cookie、更新cookie
如果整个站都失败,请按以上步骤排查。
#### 问Windows下执行脚本时乱码
用cmd和powershell执行脚本中文输出乱码由于我是写php脚本的非常喜欢国际化的uft8编码。注册表修改有些可以有些不可以直接在控制面板修改。
控制面板\时钟和区域\区域\管理\更改系统区域设置\勾选beta版:使用unicode-utf8全球语言支持,保存重启即可仅支持win10
#### 问小钢炮qBittorrent原装v4.1.5版本无法连接的解决办法?
请按照这篇文章升级种子不用重新校验数据不丢失。小钢炮使用docker版qb 4.1.6 简明教程http://nanodm.net:8092/archives/43/
#### 问:如何反馈问题?
1、点击链接加入群聊【IYUU自动辅种交流】[https://jq.qq.com/?_wv=1027&k=5JOfOlM][1]
1、QQ群859882209[2000人.入门群]931954050[1000人.进阶群]
2、QQ群859882209
2、问答社区http://wenda.iyuu.cn
3、issues https://gitee.com/ledc/IYUUAutoReseed/issues
3、博客https://www.iyuu.cn
4、issues https://gitee.com/ledc/IYUUAutoReseed/issues

View File

@@ -6,10 +6,14 @@
| m-team IPv4、IPv6自定义配置 | 已完成 | 2019年12月25日 | 2019年12月25日 |
| 未配置客户端智能过滤 | 已完成 | 2019年12月25日 | 2019年12月25日 |
| 自动辅种结束微信通知 | 已完成 | 2019年12月25日 | 2019年12月27日 |
| 做种客户端间转移 | 已完成 | 2019年12月25日 | 2020年1月14日 |
| 做种客户端间转移(需联网) | 已完成 | 2019年12月25日 | 2020年1月14日 |
| 手动辅种按目录分组 | 已完成 | 2019年12月26日 | 2020年1月14日 |
| WEB页面生成配置 | 暂未开始 | | |
| 自动转移客户端 | 暂未开始 | | |
| 脚本docker容器化 | 暂未开始 | | |
| 自动转移客户端 | 已完成 | 2020年1月27日 | 2020年1月29日 |
| 做种客户端本地转移 | 已完成 | 2020年2月21日 | 2020年2月21日 |
| Google身份验证器谷歌动态口令 | 开发中 | 2020年2月21日 | |
| 自动更新 | 开发中 | 2020年2月21日 | |
| WEB页面生成配置 | 开发中 | 2020年2月21日 | |
| 种子删除自动同步 | 已完成 | 2020年2月21日 | 2020年5月6日 |
| 脚本docker容器化测试版 | 已完成 | 2020年2月21日 | 2020年2月21日 |
| 浏览器插件 | 暂未开始 | | |
| 合集自动拆包辅种 | 暂未开始 | | |

View File

@@ -1,46 +0,0 @@
## 404数据最后清理时间
|标志 | 最后清理时间 | 状态 |
| :-: | :-: | ---- |
| 兽 | | |
|老师 | | |
|伊甸园 | | |
|CHD | | |
|hdzone | | |
|港知堂(discfan) | | |
|海豚 | | |
|oshen | | |
|HDU(upxin) | | |
|U2 | | |
|joyhd | | |
|高清街 | | |
|HDTIME | | |
|hddisk(hdbug) | | |
|HDArea | | |
|1ptba | | |
|烧包 | | |
|LeagueHD | | |
|聆音 | | |
|TLFBits | | |
|备胎 | | |
|Brobits | | |
|52pt | | |
| 南洋 | | 已完成 |
|映客 | | 已完成 |
| ttg | | |
|城市 | 2020年1月17日01:48:27 | 已完成 |
|萌猫 | 2020年1月16日12:07:12 | 已完成 |
|ptmsg | 2020年1月16日12:07:17 | 已完成 |
|瓷器 | | |
|杜比 | 2020年1月16日11:34:19 | 已完成 |
|tccf | 2020年1月17日01:48:36 | 已完成 |
|馒头 | | |
|春天 | 2020年1月16日00:23:05 | 已完成 |
|北洋 | 2020年1月16日00:23:05 | 已完成 |
|猫站 | 2020年1月17日01:48:43 | 已完成 |
|朋友 | 2020年1月16日00:23:05 | 已完成 |
|铂金家 | 2020年1月16日00:23:05 | 已完成 |
|家园 | 2020年1月16日00:23:05 | 已完成 |
|学校 | 2020年1月16日00:19:24 | 已完成 |
| 我堡 | 2020年1月15日13:56:22 | 已完成 |
| 天空 | 2020年1月15日20:49:33 | 已完成 |

View File

@@ -1,3 +1,88 @@
### 更多日志请查看:
### https://gitee.com/ledc/IYUUAutoReseed/commits/master
------
### 2020年8月2日
- v1.10.2版本以后的docker每5小时会自动拉取最新代码从此您只需要看公告更新配置就行啦。
- IYUUAutoReseed正式建立了docke镜像自动编译2个版本ARM64【iyuucn/iyuuautoreseed:arm64v8】、AMD64【iyuucn/iyuuautoreseed:latest】使用方法[点击查看](https://gitee.com/ledc/IYUUAutoReseed/tree/master/docker)
- 辅种天空的用户,必须更新至最新版本。
优化了默认流控参数单次最多20个间隔20秒。
天空辅种请配置cookie并配置浏览器UA获取UA请访问[http://demo.iyuu.cn](http://demo.iyuu.cn/)
- v1.10.4版本支持qBittorrent v4.1.5 (小钢炮等)
### 2020年7月3日
1. 优化windows的辅种批处理采用环境变量调用
2. 新增站点HDRoute、hdbd、haidan、HDfans
3. 优化curl的连接参数
4. 新增小钢炮专用的docker脚本
5. 新增合作站点MoeCat
6. 微信报表增加版本号提示
7. qBittorrent下载器增加root_folder配置项是否创建子文件夹
### 2020年3月22日
1. 转移种子,设置自动开始开关
2. 添加git自动更新.cmd
3. 优化做种客户端转移配置的提示
4. 人性化加入vendor目录
5. 修复因不支持站点缓存引起的错误提示
6. 新增合作站点hddolby、hdhome、pthome
7. 修复瓷器辅种乱码不美观的问题
8. 简化docker编译文件
9. 优化合作站点登录缓存,检索请求
10. 优化输出提示未填写passkey的站点只提示一次后续自动跳过
11. 增加通用备份脚本
### 2020年2月26日
1. 新增葡萄pt
2. 升级docker制作脚本每次制作都是最新版。
3. 优化过滤transmission连接URL兼容性修复网址后有斜杠无法连接的问题
4. 发布包到composer支持composer安装
5. 加入git自动更新脚本
6. 优化提高Windows平台转移做种客户端的兼容性
7. 更新文档、新增支持站点天雪
### 2020年2月21日
发行版v1.5.0
1. 新增做种列表备份功能,便于紧急恢复。
2. 新增docker容器安装使用方法
3. 修复transmission添加任务后ID无法显示的bug
4. 优化https判断
5. 新增通知接口
6. 修复扩展参数extra_options错误
7. 删除示例配置圣城cnscg
8. 新增教程小钢炮qBittorrent连接失败的处理办法
9. 优化大于一万条做种,防止因精简配置,可能导致的超时设置无效。
10. 增加转移做种搜索目录命令find / -name BT_backup
11. 新增海豚音乐dicmusic
### 2020年1月30日
新增CCFBits站点辅种
### 2020年1月28日
新增:北邮站点辅种
新增:做种客户端转移功能
优化:删除用不到的依赖包
### 2020年1月21日
新增支持的站点列表json本地化
新增:在线查询支持站点控制台显示
新增Windows系统composer install安装依赖包命令
### 2020年1月17日
优化:文件结构,辅种脚本前置检查;

View File

@@ -1,102 +1,162 @@
以下教程以windows为基础进行讲解其他系统同理
博客链接https://www.iyuu.cn/archives/324/
以下教程以windows为基础进行讲解通用威联通、群晖、铁威马等Linux系统
# 重要提示:请先完整阅读完再动手操作!
## 第一步 下载压缩包
从[码云仓库][1]下载最新源码解压缩到D盘的根目录下。
**特殊说明新手第一次使用建议去群内下载zip压缩包。**
## 第二步 复制一份配置文件
打开`D:\IYUUAutoReseed\config`目录,复制一份`config.sample.php`存为`config.php`
打开`D:\IYUUAutoReseed\config`目录,复制一份`config.sample.php`存为`config.php`这样操作后,需要升级新版本时,直接覆盖即可,不会影响到配置。
这样操作后,需要升级新版本时,直接覆盖即可,不会影响到配置。
## 第三步 编辑配置文件
提醒千万不要用windows记事本来编辑配置文件(会导致乱码)
提醒千万不要用windows记事本来编辑配置文件
推荐编辑软件:`VS code``EditPlus``SublimeText``Notepad++`保存格式选UTF8 无BOM
配置文件内容较多,新手往往很迷茫,不知道改哪里,在这里我重点强调2个步骤:
`1.编辑全局客户端; 2.编辑各站的秘钥,即passkey`
配置文件内容较多,新手往往很迷茫,不知道改哪里,在这里我重点强调3个步骤:
`1.申请爱语飞飞token2.编辑全局客户端; 3.编辑各站的密钥即passkey4.配置合作站点的passkey用户id`
其他配置,如果不懂也没有关系;先保持默认,等脚本运行起来,再修改也不迟。另外,修改时一定要细心,仔细看教程。
打开`D:\IYUUAutoReseed\config\config.php`文件,如下图:
![编辑配置1.png][2]
**下面开始详细步骤!!!!**
### 填写全局客户端
上图红框内的是`transmission`的示例配置,绿框是`qBittorrent`的示例配置;
IYUU自动辅种工具目前支持这两种下载器支持多盘位辅种时全自动对应资源的下载目录。
1编辑`transmission`下载器
`http://127.0.0.1:9091/transmission/rpc`是下载器的连接参数,你要修改的部分是`127.0.0.1:9091`改成你的IP与端口本机使用无需修改局域网内的机器请填写局域网IP与端口远程使用请填写DDNS的远程连接域名与端口。
username是用户名、password是密码。
如果你没有用到`transmission`下载器,请把红框的内容都删除。
2编辑`qBittorrent`下载器
方法与上一步相同只需填写ip、端口、用户名、密码即可。如果您是windows下的qBittorrent请参考下图打开`WEB用户界面`
![qb设置WEB用户界面.png][3]
因为我两个下载器都在用,编辑好后,如图:
![编辑配置2.png][4]
### 填写各站秘钥passkey
IYUU自动辅种需要您配置各站的passkey没有配置passkey的站点会自动跳过
从各站点的控制面板,找到您的`秘钥`复制粘贴过来即可。
配置好后如图:
![编辑配置3.png][5]
----------
## 第四步重点讲解Ourbits站点的配置
IYUU自动辅种工具、Ourbits双方达成合作可以对使用接口的用户实现认证。
### 申请爱语飞飞微信通知token新用户访问http://iyuu.cn 申请!
1.点击`开始使用`,出现二维码,用`微信扫码`
![微信通知1.png][6]
![微信通知2.png][7]
![微信通知3.png][8]
2.复制您的token令牌到`/app/config/config.php`文件内的`iyuu.cn`对应的配置字段,保存。如图:
![微信通知4.png][9]
![微信通知1.png][2]
![微信通知2.png][3]
![微信通知3.png][4]
2.复制您的token令牌到`/config/config.php`文件内的`iyuu.cn`对应的配置字段,保存。如图:
![微信通知4.png][5]
### 设置Ourbits
----------
### 填写全局客户端
打开`D:\IYUUAutoReseed\config\config.php`文件,如下图:
![编辑配置1.png][6]
上图红框内的是`transmission`的示例配置,绿框是`qBittorrent`的示例配置;
IYUU自动辅种工具目前支持这两种下载器支持多盘位辅种时全自动对应资源的下载目录。
#### 1编辑`transmission`下载器
`http://127.0.0.1:9091/transmission/rpc`是下载器的连接参数,你要修改的部分是`127.0.0.1:9091`改成你的IP与端口本机使用IP无需修改,端口改成你的局域网内的机器请填写局域网IP与端口远程使用请填写DDNS的远程连接域名与端口。
username是用户名、password是密码。没有用户名和密码的都填写`null`
如果你没有用到`transmission`下载器,红框内不要做任何改动,也无需删除(脚本内会自动处理)。
#### 2编辑`qBittorrent`下载器
方法与上一步相同只需填写ip、端口、用户名、密码即可。如果您是windows下的qBittorrent请打开`WEB用户界面`,设置如下图:
![qb设置WEB用户界面.png][7]
因为我两个下载器都在用,编辑好后,如图:
![编辑配置2.png][8]
----------
### 填写各站秘钥passkey
IYUU自动辅种需要您配置各站的passkey目前支持40多个站点的自动辅种没有配置passkey的站点会自动跳过。注2019年12月28日补充辅种hdcity、hdchina需要配置cookie。
从各站点的控制面板或对应地方,找到您的`密钥`复制粘贴过来即可。
配置好后如图:
![编辑配置3.png][9]
----------
## 第四步,合作站点的配置
此处配置也可以参考这里https://www.iyuu.cn/archives/337/
IYUU自动辅种工具与站点达成合作可以对使用接口的用户实现认证。以Ourbits为例进行讲解
![编辑配置4.png][10]
`passkey`,在你的控制面板 - 密钥
`is_vip`,根据你的实际情况填写,因站点有下载种子的流控,如果你不在限制之列,可以`设置为1`
`id`,为用户中心打开后,浏览器地址栏**http://xxxxx.xxx/userdetails.php?id=`46880`**等号=后面的几个数字,如图:
![编辑配置6.png][11]
到此,配置文件编辑完毕,请记得保存。
如果提示保存格式请保存为UTF8无BOM格式。
如果有多个合作站账号,请全部配置,如图:
![合作站点ID.png][12]
------
到此配置文件编辑完毕请记得保存如果提示保存格式请保存为UTF8无BOM格式。
## 群晖、铁威马、威联通等Linux环境
----------
## 群晖、铁威马、威联通等Linux的php环境
**群晖、铁威马、威联通自带php运行环境非常简单。**
经过上面步骤其实已经完成了配置只需要把脚本复制到设备内用php命令运行脚本即可。
下面是各系统运行php的命令
群晖php`php`
威联通php `/mnt/ext/opt/apache/bin/php`
铁威马php`php`
群晖php命令`php`
威联通php命令`/mnt/ext/opt/apache/bin/php`
----------
铁威马php命令`php`
**威联通补充几个命令,找到辅种脚本:**
```sh
#查看php版本
/mnt/ext/opt/apache/bin/php -v
#切换admin
sudo -i
#搜索iyuu.php或IYUUAutoReseed
find / -name iyuu.php
#根据上一行命令搜索结果,组成辅种命令:
/mnt/ext/opt/apache/bin/php 找到的路径/iyuu.php
```
----------
## Windows安装PHP运行环境
也可以去官方下载【https://www.php.net/downloads】,官方下载的记得开启`curl、fileinfo、mbstring`这3个扩展。
另外我打包了一份,下载地址:
微云链接https://share.weiyun.com/5EiXLfn 密码ezsvnb
也可以去官方下载【https://www.php.net/downloads】
**特别提醒:官方下载的记得开启`curl、json、mbstring`这3个扩展。**
**特别提醒:官方下载的记得开启`curl、json、mbstring`这3个扩展。**
**特别提醒:官方下载的记得开启`curl、json、mbstring`这3个扩展。**
![php开启扩展.png][13]
**另外我打包了一份【扩展已开启】,下载地址:**
!!!
<a href="http://www.dawei.hk:81/php-7.4.2-nts-Win32-vc15-x86.zip" target="_blank"><h3><code>http://www.dawei.hk:81/php-7.4.2-nts-Win32-vc15-x86.zip</code></h3></a>
<a href="http://www.dawei.hk:81/php-7.4.2-nts-Win32-vc15-x64.zip" target="_blank"><h3><code>http://www.dawei.hk:81/php-7.4.2-nts-Win32-vc15-x64.zip</code></h3></a>
!!!
----------
链接https://share.weiyun.com/5I13dek 密码utcjsx
链接https://share.weiyun.com/57uYFrn 密码gurkdc
下载回来是一个ZIP压缩包解压到`D:\IYUUAutoReseed\`目录内,文件结构如图:
![编辑配置7.png][12]
点击红框内`执行辅种`即可。
![编辑配置7.png][14]
重点根据你下载的版本不同、路径不同请把你解压的php环境的路径添加进系统的环境变量内。比如我下载的是`php-7.4.2-nts-Win32-vc15-x86.zip`解压到了D盘根目录下可以这样添加
![请输入图片描述][15]
然后,点击红框内`执行辅种`即可,也可以运行命令:`php iyuu.php`
> 提示新手第一次请去群内下载打包好的Windows版本双击运行即可。
如果你前期严格按照配置一步步操作,这里会正常显示跑动的辅种列表。正常如图:
![编辑配置8.png][13]
![编辑配置8.png][16]
[1]: https://gitee.com/ledc/IYUUAutoReseed
[2]: https://www.iyuu.cn/usr/uploads/2019/12/2720183833.png
[3]: https://www.iyuu.cn/usr/uploads/2019/12/405587689.png
[4]: https://www.iyuu.cn/usr/uploads/2019/12/441257656.png
[5]: https://www.iyuu.cn/usr/uploads/2019/12/890327305.png
[6]: https://www.iyuu.cn/usr/uploads/2019/12/2331433923.png
[7]: https://www.iyuu.cn/usr/uploads/2019/12/3324442680.png
[8]: https://www.iyuu.cn/usr/uploads/2019/12/3181272964.png
[9]: https://www.iyuu.cn/usr/uploads/2019/12/3669828008.png
[10]: https://www.iyuu.cn/usr/uploads/2019/12/3696916642.png
[11]: https://www.iyuu.cn/usr/uploads/2019/12/1230288911.png
[12]: https://www.iyuu.cn/usr/uploads/2019/12/3189986236.png
[13]: https://www.iyuu.cn/usr/uploads/2019/12/2523845772.png
[1]: https://gitee.com/ledc/IYUUAutoReseed
[2]: https://www.iyuu.cn/usr/uploads/2019/12/2331433923.png
[3]: https://www.iyuu.cn/usr/uploads/2019/12/3324442680.png
[4]: https://www.iyuu.cn/usr/uploads/2019/12/3181272964.png
[5]: https://www.iyuu.cn/usr/uploads/2019/12/3669828008.png
[6]: https://www.iyuu.cn/usr/uploads/2019/12/2720183833.png
[7]: https://www.iyuu.cn/usr/uploads/2019/12/405587689.png
[8]: https://www.iyuu.cn/usr/uploads/2019/12/441257656.png
[9]: https://www.iyuu.cn/usr/uploads/2019/12/890327305.png
[10]: https://www.iyuu.cn/usr/uploads/2019/12/3696916642.png
[11]: https://www.iyuu.cn/usr/uploads/2019/12/1230288911.png
[12]: https://www.iyuu.cn/usr/uploads/2020/04/712430028.png
[13]: https://www.iyuu.cn/usr/uploads/2019/12/3007415838.png
[14]: https://www.iyuu.cn/usr/uploads/2019/12/3189986236.png
[15]: https://www.iyuu.cn/usr/uploads/2020/03/686511859.png
[16]: https://www.iyuu.cn/usr/uploads/2019/12/2523845772.png