diff --git a/Action.php b/Action.php index ffa7e6b..9e8f266 100644 --- a/Action.php +++ b/Action.php @@ -5,7 +5,8 @@ * 获取、更新缓存,返回书单、影单 * * @author 熊猫小A | AlanDecode - * @version 0.1 + * @modified Leslie Lee + * @version 0.6 */ if (!defined('__TYPECHO_ROOT_DIR__')) exit; @@ -32,16 +33,59 @@ function curl_file_get_contents($_url, $type='www') class DoubanAPI { /** - * 从豆瓣接口获取书单数据 + * 从豆瓣网页解析书单数据 * * @access private * @param string $UserID 豆瓣ID - * @return array 返回 JSON 解码后的 array + * @return array 返回格式化 array + */ + private static function __getBookRawDataHelper($UserID, $Type='collect') + { + $api = 'https://book.douban.com/people/' . $UserID . '/' . $Type; + $data = array(); + while ($api != null) { + $raw = curl_file_get_contents($api, 'book'); + error_log(print_r($raw, true)); + + if ($raw == null || $raw == "") { + break; + } + + $doc = str_get_html($raw); + + $itemArray = $doc->find("li.subject-item"); + foreach ($itemArray as $v) { + $t = $v->find("div.info h2", 0); + $book_name = str_replace(array(" ", " ", "\t", "\n", "\r"), + array("", "", "", "", ""), $t->text()); + $book_img = $v->find("div.pic a img", 0)->src; + + // 使用 wp 接口解决防盗链 + $book_img = 'https://i0.wp.com/' . str_replace(array('http://', 'https://'), '', $book_img); + + $book_url = $t->find("a", 0)->href; + $data[] = array("name" => $book_name, "img" => $book_img, "url" => $book_url); + } + $url = $doc->find("span.next a", 0); + if ($url) { + $api = "https://book.douban.com" . $url->href; + } else { + $api = null; + } + } + return $data; + } + + /** + * 从豆瓣网页获取想看、已看、在看信息 */ private static function __getBookRawData($UserID) { - $api = 'https://api.douban.com/v2/book/user/' . $UserID . '/collections?apikey=054022eaeae0b00e0fc068c0c0a2102a&count=100'; - return json_decode(curl_file_get_contents($api, 'book'), true); + $data = array(); + $data['reading'] = self::__getBookRawDataHelper($UserID, 'do'); + $data['wish'] = self::__getBookRawDataHelper($UserID, 'wish'); + $data['read'] = self::__getBookRawDataHelper($UserID, 'collect'); + return $data; } /** @@ -62,7 +106,7 @@ private static function __getMovieRawDataHelper($UserID, $Type='collect') } $doc = str_get_html($raw); - + $itemArray = $doc->find("div.item"); foreach ($itemArray as $v) { $t = $v->find("li.title", 0); @@ -160,7 +204,7 @@ private static function __isCacheExpired($FilePath, $ValidTimeSpan) * @param int $ValidTimeSpan 有效时间,Unix 时间戳,s * @return json 返回格式化书单 */ - public static function updateBookCacheAndReturn($UserID, $PageSize, $From, $ValidTimeSpan, $status) + public static function updateBookCacheAndReturn($UserID, $PageSize, $From, $ValidTimeSpan, $status='read') { if (!$UserID) { return json_encode(array()); @@ -171,42 +215,21 @@ public static function updateBookCacheAndReturn($UserID, $PageSize, $From, $Vali if ($cache == -1 || $cache == 1) { // 缓存无效或者过期,重新请求,重新写入 $raw = self::__getBookRawData($UserID); - $data_read = array(); - $data_reading = array(); - $data_wish = array(); - foreach ($raw['collections'] as $value) { - $item = array("img" => str_replace("/view/subject/m/public/", "/lpic/", $value['book']['image']), - "title" => $value['book']['title'], - "rating" => $value['book']['rating']['average'], - "author" => $value['book']['author'][0], - "link" => $value['book']['alt'], - "summary" => $value['book']['summary']); - - $item['img'] = 'https://i0.wp.com/' . str_replace(array('http://', 'https://'), '', $item['img']); - - if ($value['status'] == 'read') { - array_push($data_read, $item); - } elseif ($value['status'] == 'reading') { - array_push($data_reading, $item); - } elseif ($value['status'] == 'wish') { - array_push($data_wish, $item); - } - } - - $cache = array('time' => time(), - 'data' => array('read' => $data_read, 'reading' => $data_reading, 'wish' => $data_wish)); + $cache = array('time' => time(), 'data' => $raw); + file_put_contents(__DIR__ . '/cache/book.json', json_encode($cache)); + } - // 如果 cache 全空,很可能没有获取到数据,时间戳置 1 - if (count($data_read) == 0 && count($data_reading) == 0 && count($data_wish) == 0) { - $cache['time'] = 1; - } + $data = $cache['data']; + // 没有数据,需要在下次刷新 + if (count($data['reading'])==0 && count($data['wish'])==0 && count($data['read'])==0) { + $cache['time'] = 1; file_put_contents(__DIR__ . '/cache/book.json', json_encode($cache)); + return json_encode(array()); } - $data = $cache['data'][$status]; + $data = $data[$status]; $total = count($data); - if ($From < 0 || $From > $total - 1) { echo json_encode(array()); } else { @@ -316,7 +339,7 @@ public static function updateSingleCacheAndReturn($ID, $Type, $ValidTimeSpan) // if($needUpdate) // file_put_contents($FilePath, json_encode($cache)); - + if ($needUpdate) { $cache[$Type][$ID]['time'] = time(); if ($Type == 'book') { @@ -326,7 +349,7 @@ public static function updateSingleCacheAndReturn($ID, $Type, $ValidTimeSpan) } file_put_contents($FilePath, json_encode($cache)); } - + return json_encode($cache[$Type][$ID]['data']); } } @@ -368,4 +391,4 @@ public function action() } } } -?> \ No newline at end of file +?> diff --git a/Plugin.php b/Plugin.php index cd86489..d152f65 100644 --- a/Plugin.php +++ b/Plugin.php @@ -6,11 +6,12 @@ * * @package DoubanBoard * @author 熊猫小A - * @version 0.5 + * @modified Leslie Lee + * @version 0.6 * @link https://www.imalan.cn */ -define('DoubanBoard_Plugin_VERSION', '0.5'); +define('DoubanBoard_Plugin_VERSION', '0.6'); class DoubanBoard_Plugin implements Typecho_Plugin_Interface { @@ -111,4 +112,4 @@ public static function footer() Helper::options()->pluginUrl('DoubanBoard/assets/DoubanBoard.07.js'); echo '?v='.DoubanBoard_Plugin_VERSION.'">'; } -} \ No newline at end of file +} diff --git a/README.md b/README.md index 64dc89b..207525a 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ ### 日志 +**Ver 0.6** + +* 修改book list的获取方式 + **Ver 0.5** * 增加电影在看、想看列表 @@ -32,4 +36,4 @@ * 增加了单部展示的缓存,防止因访问量过大被豆瓣限制 IP * 书单列表支持分别展示已读、想读、在读 -下载新版的插件覆盖原插件,手动删除 `插件目录/cache` 下的缓存文件即可。 \ No newline at end of file +下载新版的插件覆盖原插件,手动删除 `插件目录/cache` 下的缓存文件即可。 diff --git a/assets/DoubanBoard.07.js b/assets/DoubanBoard.07.js index 4025833..075d86b 100644 --- a/assets/DoubanBoard.07.js +++ b/assets/DoubanBoard.07.js @@ -1,7 +1,8 @@ // Author: 熊猫小A // Link: https://www.imalan.cn +// Modified by: Leslie Lee -console.log(`%c DoubanBoard 0.5 %c https://blog.imalan.cn/archives/168/`, `color: #fadfa3; background: #23b7e5; padding:5px 0;`, `background: #1c2b36; padding:5px 0;`); +console.log(`%c DoubanBoard 0.6 %c https://blog.imalan.cn/archives/168/`, `color: #fadfa3; background: #23b7e5; padding:5px 0;`, `background: #1c2b36; padding:5px 0;`); var curBooks_read = 0; @@ -70,34 +71,23 @@ DoubanBoard = { loadBooks: function (status) { if ($(`.douban-book-list[data-status="` + status + `"]`).length < 1) return; - $(`#loadMoreBooks_` + status).html("加载中..."); + $("#loadMoreBooks_" + status).html("加载中..."); + var curBooks; if (status == 'read') curBooks = curBooks_read; else if (status == 'reading') curBooks = curBooks_reading; else curBooks = curBooks_wish; - var api = window.DoubanAPI + "?type=book&from=" + String(curBooks) + "&status=" + status; - $.getJSON(api, function (result) { - $(`#loadMoreBooks_` + status).html("加载更多"); + + $.getJSON(window.DoubanAPI + "?type=book&from=" + String(curBooks) + "&status=" + status, function (result) { + $("#loadMoreBooks_" + status).html("加载更多"); if (result.length < DoubanPageSize) { - $(`#loadMoreBooks_` + status).html("没有啦"); + $("#loadMoreBooks_" + status).html("没有啦"); } $.each(result, function (i, item) { - var html = `
- 书名:`+ item.title + `
- 评分:`+ item.rating + `
- 作者:`+ item.author + `
- 链接:豆瓣阅读
- 简介:
-
- `+ item.summary + ` -
-