} /// 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, ''); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); $content = curl_exec($ch); if (!$content || curl_error($ch)) { LOGD("无法从漫游下载种子({$url}):" . curl_error($ch)); header('HTTP/1.1 500 Internal Error'); die('<h1>500 Internal Error</h1>'); } LOGI("保存种子“{$btih}”,并将用户跳转到下载地址"); $path = archive_torrent($content, $btih); /// 3. 检查下载的内容是否是种子,漫游在发生错误的时候仍会返回 HTTP 200,所以我们需要通过 MIME 来进行检查 if (!$path || mime_content_type($path) != 'application/x-bittorrent') { if ($path) { unlink($path); } LOGD("从漫游下载到的种子不是合法的 ({$url}):" . curl_error($ch)); header('HTTP/1.1 500 Internal Error'); die('<h1>500 Internal Error</h1>'); } header("Content-Disposition: attachment; filename={$btih}.torrent"); header('Content-Type: application/x-bittorrent'); ob_clean(); echo $content;
/// 是否仅测试运行(即不修改数据库) require_once 'header.php'; if ($DRY_RUN) { LOGI("目前运行在测试模式,所有的操作都不会保存"); $mysqli->autocommit(0); } $cnt_new = 0; $cnt_count = 0; for ($i = 1; file_exists("{$popgo_html_archive_dir}/{$i}.html"); $i++) { $path = "{$popgo_html_archive_dir}/{$i}.html"; $content = file_get_contents($path); if (!$content) { LOGW("无法读取 `{$path}' 文件的内容,跳过该文件"); continue; } LOGD("解析文件:`{$path}'"); $resources = popgo_parse_html($content); if (empty($resources)) { LOGW("无法解析 `{$path}' 文件的内容,跳过该文件"); continue; } LOGI("`{$path}' 中共有 " . count($resources) . " 个资源"); $cnt_count += count($resources); foreach ($resources as $res) { LOGI("检查“{$res['title']}”是否已经在数据库中"); /// 1. 检查数据库中是否有同名,且 btih 为空的资源 $title = $mysqli->real_escape_string($res['title']); $sql = "SELECT COUNT(*) AS cnt FROM b_resource WHERE title='{$title}' AND btih=''"; $result = $mysqli->query($sql); if (!$result) { LOGW("数据库查询出错,跳过这个资源:" . $mysqli->error);
/** * 重新(初始化)计算一个资源的热度 */ function init_popularity($btih) { global $POPULARITY_HALFLIFE_DAYS; /// 0. 检验数据合法性 $pattern = '/^[0-9a-f]{40}$/i'; if (!preg_match($pattern, $btih)) { LOGW("传入的 btih({$btih}) 格式不合法"); return FALSE; } /// 1. 查询数据 $ts = time() - $POPULARITY_HALFLIFE_DAYS * 20 * 86400; /// 只查询 20 个半衰期之内的数据,避免数据量过大 $sql = "SELECT node_id, ctime FROM b_dht_log WHERE btih=UNHEX('{$btih}') AND ctime>{$ts} ORDER BY ctime ASC"; $result = db_query($sql); if (!$result) { LOGW("数据库查询出错"); return FALSE; } $popularity = 0; $nodes = []; $pmtime = time(); while ($row = $result->fetch_assoc()) { if (isset($nodes[$row['node_id']]) && $row['ctime'] - $nodes[$row['node_id']]['ctime'] < 60) { /// 1 分钟之内的相同 node_id 请求的相同的资源认为是同一次下载,不予记录 /// 什么都不用做 } else { $days = (time() - $row['ctime']) / 86400; $popularity += pow(2, -1 * ($days / $POPULARITY_HALFLIFE_DAYS)); $pmtime = $row['ctime']; } $nodes[$row['node_id']] = $row; } /// 3. 更新数据库 LOGD("资源 {$btih} 初始化的热度为 {$popularity}"); $sql = "UPDATE b_resource SET popularity={$popularity}, pmtime={$pmtime} WHERE btih='{$btih}'"; return db_query($sql); }