Example #1
0
 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;
     }
 }
Example #2
0
 /**
  * 下载 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;
 }
Example #3
0
        $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("索引完成");
        if (!$result) {
            LOGW("数据库查询出错,跳过这个资源:" . $mysqli->error);
            continue;
        }
        $row = $result->fetch_assoc();
        if ($row['cnt'] > 0) {
            LOGI("数据库中已经存在相同 btih 的资源了,跳过这个资源");
            continue;
        }
        /// 3. 将这个资源添加到数据库中
        LOGI("将“{$title}”保存到数据库中");
        $guid = $mysqli->real_escape_string($res['guid']);
        $link = $mysqli->real_escape_string($res['link']);
        $pubDate = (int) $res['pubDate'];
        $description = '';
        $ctime = time();
        $sql = "INSERT INTO b_resource(title, guid, link, description, btih, pubDate, ctime)\n            VALUES('{$title}', '{$guid}', '{$link}', '{$description}', '{$btih}', {$pubDate}, {$ctime})";
        $ret = $mysqli->query($sql);
        if ($ret === FALSE) {
            LOGW("数据库查询出错:" . $mysqli->error);
        } else {
            $cnt_new++;
        }
    }
}
if ($DRY_RUN) {
    LOGI("目前运行在测试模式,将回滚数据库");
    $mysqli->rollback();
}
LOGI("资源索引完成,分析得到 {$cnt_count} 个资源,共新添加了 {$cnt_new} 个资源");
Example #5
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;
Example #6
0
/**
 * 处理announce_peer请求
 * @param  array $msg     接收到的announce_peer请求数据
 * @param  array $address 对端链接信息
 * @return void
 */
function on_announce_peer($msg, $address)
{
    global $nid;
    // 获取infohash
    $infohash = $msg['a']['info_hash'];
    // 获取token
    $token = $msg['a']['token'];
    // 获取node id
    $id = $msg['a']['id'];
    // 验证token是否正确
    if (substr($infohash, 0, 2) == $token) {
        /*$txt = array(
              'action' => 'announce_peer',
              'msg' => array(
                  'ip' => $address[0],
                  'port1' => $address[1],
                  'port2' => $msg['a']['port'],
                  'infohash' => $infohash
              )
          );
          var_dump($txt);*/
        $nodeid = bin2hex($id);
        LOGI("(node_id={$nodeid}) 获取到info_hash: " . strtoupper(bin2hex($infohash)));
        logDHTAnnouncePeer($nodeid, bin2hex($infohash));
    }
    // 生成回复数据
    $msg = array('t' => $msg['t'], 'y' => 'r', 'r' => array('id' => $nid));
    // 发送请求回复
    send_response($msg, $address);
}
Example #7
0
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']}”处理完毕");
Example #8
0
/**
 * 保存一个 announce_peer 数据,同时更新资源的 7 日下载数
 */
function logDHTAnnouncePeer($node_id, $btih)
{
    /// 1. 检验数据合法性
    $pattern = '/^[0-9a-f]{40}$/i';
    if (!preg_match($pattern, $node_id)) {
        LOGW("传入的 node_id({$node_id}) 格式不合法");
        return FALSE;
    }
    if (!preg_match($pattern, $btih)) {
        LOGW("传入的 btih({$btih}) 格式不合法");
        return FALSE;
    }
    /// 2. 记录此次 announce_peer
    $ctime = time();
    $sql = "INSERT INTO b_dht_log (node_id, btih, ctime) VALUES (UNHEX('{$node_id}'), UNHEX('{$btih}'), {$ctime})";
    $result = db_query($sql);
    if (!$result) {
        LOGE("数据库查询失败");
        return FALSE;
    }
    /// 3. 更新资源热度(如果对应的 btih 存在)
    $sql = "SELECT * FROM b_resource WHERE btih='{$btih}'";
    $result = db_query($sql);
    if ($result->num_rows <= 0) {
        /// 资源不存在,无需更新
        return TRUE;
    } else {
        $res = $result->fetch_assoc();
        if ($res['popularity'] < 0) {
            LOGI("初始化资源 {$btih} 的热度");
            init_popularity($btih);
        }
        return update_popularity($res, $ctime);
    }
}
<?php

/**
 * popgo-gone 版本之后,b_resource 表中的 btih 字段变为 UNIQUE 索引,该脚本用于更新 btih 为空的行,以便修改 btih 索引为 UNIQUE 索引
 */
require_once '../header.php';
$sql = "SELECT * FROM b_resource WHERE src='popgo' AND btih=''";
$res = $mysqli->query($sql) or die($mysqli->error);
if (!$res) {
    LOGI("已经没有需要更新的资源了");
    exit(0);
}
LOGI(sprintf("需要更新 %d 个资源", $res->num_rows));
while ($row = $res->fetch_assoc()) {
    $btih = popgo_get_btih_from_link($row['guid']);
    $sql = "UPDATE b_resource SET btih='{$btih}' WHERE resource_id={$row['resource_id']}";
    $mysqli->query($sql) or die($mysqli->error);
}