Exemple #1
0
}
/// 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);
Exemple #3
0
/**
 * 重新(初始化)计算一个资源的热度
 */
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);
}