public static function getSrcSeedURL($btih) { global $USER_AGENT; /// 1. 从数据库中查询原始页面链接 $res = get_by_btih($btih); if (!$res) { LOGW("BTIH 为 {$btih} 的资源在数据库中不存在"); return FALSE; } /// 2. 获取 link 页面内容 LOGI("正在获取动漫花园的资源页面内容: {$res['link']}"); $content = NULL; $ch = curl_init($res['link']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_USERAGENT, $USER_AGENT); $content = curl_exec($ch); if (!$content) { LOGE("无法抓取动漫花园的资源页面: {$res['link']}'"); return FALSE; } /// 3. 解析 BT 地址 $matches = []; $pattern = '/\\/\\/.+[a-f0-9]{40}\\.torrent/'; $ret = preg_match($pattern, $content, $matches); if ($ret >= 1) { return 'http:' . $matches[0]; } else { return FALSE; } }
/** * 下载 RSS 内容 */ protected function _fetchRss($url) { global $USER_AGENT; LOGI("正在获取 {$url}"); $content = NULL; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_USERAGENT, $USER_AGENT); $content = curl_exec($ch); if (!$content) { LOGE("无法抓取 RSS:`{$RSS_FEED}'"); return FALSE; } /// 2. 归档原始数据 LOGI("正在归档数据"); /// FIXME: 将 archive_raw 做成类成员函数 archive_raw($content); return $content; }
$title = $mysqli->real_escape_string($res['title']); $guid = $mysqli->real_escape_string($res['guid']); $link = $mysqli->real_escape_string($res['link']); $description = $mysqli->real_escape_string($res['description']); $pubDate = $res['pubDate']; $btih = $mysqli->real_escape_string($res['btih']); $magnet = $mysqli->real_escape_string($res['magnet']); $src = $mysqli->real_escape_string($src); $ctime = time(); $mysqli->query('start transaction'); $sql = "SELECT * FROM b_resource WHERE btih='{$btih}' LIMIT 1"; $result = $mysqli->query($sql); if (!$result) { LOGE("数据库查询失败: " . $mysqli->error); continue; } if ($result->num_rows > 0) { LOGI("{$res['title']} 已存在 (因为已存在相同的 btih,btih={$btih}, src={$res['src']})"); $mysqli->query('rollback'); continue; } LOGI("保存来自 {$src} 的数据:{$res['title']}"); $sql = "INSERT INTO b_resource(title, guid, link, description, btih, pubDate, src, magnet, ctime)\n VALUES('{$title}', '{$guid}', '{$link}', '{$description}', '{$btih}', {$pubDate}, '{$src}', '{$magnet}', {$ctime})"; $ret = $mysqli->query($sql); if ($ret === FALSE) { LOGE("无法保存数据: " . $mysqli->error . ",原 SQL: " . $sql); } $mysqli->query('commit'); } } LOGI("索引完成");
$url = ""; $res = get_by_btih($btih); if (!$res) { LOGW("BTIH 为 {$btih} 的资源不存在"); header('HTTP/1.1 404 Not Found'); die('<h1>404 Not Found</h1> <h2>BTIH not exists</h2>'); } switch ($res['src']) { case 'popgo': $url = Indexer_Popgo::getSrcSeedURL($btih); break; case 'dmhy': $url = Indexer_DMHY::getSrcSeedURL($btih); break; default: LOGE("代码不应执行到此处"); $url = FALSE; break; } if (!$url) { LOGW("无法获得 BTIH 为 {$btih} 的资源原始种子地址"); header('HTTP/1.1 404 Not Found'); die('<h1>404 Not Found</h1> <h2>Could not get source torrent URL</h2>'); } /// 2.2 开始下载 $content = NULL; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_USERAGENT, $USER_AGENT); curl_setopt($ch, CURLOPT_REFERER, '');
$mysqli->query($sql); LOGI("已保存磁力链接: {$magnet}"); /// 3. 下载 BT 种子文件 $r = rand() % 20 + 10; LOGI("等待 {$r} 秒后去下载种子文件"); sleep($r); $content = NULL; $ch = curl_init($res['guid']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_USERAGENT, $USER_AGENT); curl_setopt($ch, CURLOPT_REFERER, $res['link']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); $content = curl_exec($ch); if (!$content) { LOGE("无法下载种子文件:`{$res['guid']}'"); die(''); } $btih = $res['btih']; if ($btih == '') { $match = array(); preg_match('([0-9a-f]{40})', $res['link'], $match); $btih = $match[0]; } if ($btih == '') { LOGE('无法获得种子文件的 BTIH,无法保存种子文件'); die(''); } archive_torrent($content, $btih); LOGI("“{$res['title']}”处理完毕");
/** * 进行一次 SQL 查询,如果连接断开,则自动重新尝试 */ function db_query($sql) { global $mysqli; global $DB_HOST; global $DB_USER; global $DB_PASSWORD; global $DB_DATABASE; $result = $mysqli->query($sql); if (!$result) { LOGN("第一次查询 MySQL 失败,重试后准备继续: " . $mysqli->error . ". SQL: {$sql}"); /// 重连 MySQL /// FIXME: 连接 MySQL 应该独立成一个函数 $ret = $mysqli->real_connect($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_DATABASE); if (!$ret) { LOGE('无法创建 MySQL 连接: ' . $mysqli->error); return FALSE; } $mysqli->query("set NAMES 'utf8'"); $result = $mysqli->query($sql); if (!$result) { LOGW("第二次查询 MySQL 失败: " . $mysqli->error . ". SQL: {$sql}"); return FALSE; } } return $result; }
<?php $__t1 = microtime(TRUE); if (!file_exists(__DIR__ . '/config.php')) { die("缺少 config.php 文件,可以尝试 mv config.sample.php config.php"); } else { require_once __DIR__ . '/config.php'; } /// 创建数据库连接 $mysqli = new Mysqli($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_DATABASE); if (!$mysqli) { LOGE('无法创建 MySQL 连接: ' . $mysqli->error); die; } $mysqli->query("set NAMES 'utf8'"); $CSP_NONCE = uniqid() . 'X' . rand(); require_once __DIR__ . '/func.php';