commit 36e490a1144f10da3357b14591204ca319121526 Author: XIGE <710062962@qq.com> Date: Mon Feb 23 17:13:52 2026 +0800 1.0 diff --git a/Plugin.php b/Plugin.php new file mode 100644 index 0000000..d43accd --- /dev/null +++ b/Plugin.php @@ -0,0 +1,1861 @@ +contentEx = array('BookInfo_Plugin', 'parse'); + Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('BookInfo_Plugin', 'parse'); + Typecho_Plugin::factory('admin/write-post.php')->bottom = array('BookInfo_Plugin', 'renderButton'); + Typecho_Plugin::factory('admin/write-page.php')->bottom = array('BookInfo_Plugin', 'renderButton'); + + $cacheDir = dirname(__FILE__) . '/cache/'; + if (!file_exists($cacheDir)) mkdir($cacheDir, 0755, true); + + return '插件激活成功!'; + } + + /** + * 禁用插件 + */ + public static function deactivate() + { + return '插件已禁用'; + } + + /** + * 配置面板 + */ + public static function config(Typecho_Widget_Helper_Form $form) + { + $cacheEnable = new Typecho_Widget_Helper_Form_Element_Radio('cacheEnable', + array('1' => '启用', '0' => '禁用'), + '1', '启用缓存', '缓存图书信息,提升访问速度'); + $form->addInput($cacheEnable); + + $cacheTime = new Typecho_Widget_Helper_Form_Element_Text('cacheTime', NULL, '30', + '缓存时间(天)', '图书信息缓存保留天数'); + $cacheTime->addRule('isInteger', '请输入整数'); + $form->addInput($cacheTime); + + $imageProxy = new Typecho_Widget_Helper_Form_Element_Text('imageProxy', NULL, + 'https://images.weserv.nl/?url=', '图片代理', '用于加载豆瓣图片'); + $form->addInput($imageProxy); + + $defaultCover = new Typecho_Widget_Helper_Form_Element_Text('defaultCover', NULL, + 'https://img9.doubanio.com/f/shire/5522dd1f5b742d1e1394a17f44d590646b63871d/pics/book-default-lpic.gif', + '默认封面', '当无法获取封面时显示的图片'); + $form->addInput($defaultCover); + + $summaryLength = new Typecho_Widget_Helper_Form_Element_Text('summaryLength', NULL, '200', + '简介显示长度', '简介默认显示的最大字符数,超出部分可展开查看'); + $summaryLength->addRule('isInteger', '请输入整数'); + $form->addInput($summaryLength); + + $expandText = new Typecho_Widget_Helper_Form_Element_Text('expandText', NULL, '展开', + '"展开"文字', '点击展开完整简介的文字'); + $form->addInput($expandText); + + $collapseText = new Typecho_Widget_Helper_Form_Element_Text('collapseText', NULL, '收起', + '"收起"文字', '点击收起简介的文字'); + $form->addInput($collapseText); + + $expandColor = new Typecho_Widget_Helper_Form_Element_Text('expandColor', NULL, '#0073aa', + '展开按钮颜色', '展开/收起按钮的文字颜色'); + $form->addInput($expandColor); + + // 新增:独立页面每页显示条数设置 + $pageSize = new Typecho_Widget_Helper_Form_Element_Text('pageSize', NULL, '10', + '独立页面每页显示条数', '在独立页面中每页显示的图书数量(1-50)'); + $pageSize->addRule('isInteger', '请输入整数'); + $pageSize->addRule(array(new BookInfo_Plugin, 'validatePageSize'), '请输入1-50之间的整数'); + $form->addInput($pageSize); + } + + /** + * 验证页面显示条数 + */ + public static function validatePageSize($value) + { + $value = intval($value); + if ($value < 1 || $value > 50) { + throw new Typecho_Widget_Exception('请输入1-50之间的整数'); + } + return true; + } + + /** + * 个人配置面板 + */ + public static function personalConfig(Typecho_Widget_Helper_Form $form) + { + } + + /** + * 解析短代码 + */ + public static function parse($content, $widget, $lastResult) + { + $content = empty($lastResult) ? $content : $lastResult; + + // 如果是独立页面,且内容中包含[all_books]标记,则显示所有图书 + if ($widget instanceof Widget_Archive && $widget->is('page')) { + // 支持[all_books]和[all_books:page=1]格式 + $pattern = '/\[all_books(?::page=(\d+))?\]/i'; + if (preg_match_all($pattern, $content, $matches)) { + foreach ($matches[0] as $key => $match) { + $page = isset($matches[1][$key]) ? intval($matches[1][$key]) : 1; + $allBooksHtml = self::renderAllBooks($page); + $content = str_replace($match, $allBooksHtml, $content); + } + } + } + + // 如果是单篇文章,解析图书短代码 + if ($widget instanceof Widget_Archive && $widget->is('single')) { + // 匹配 [book:数字] 或 [book:数字:短评] 格式 + $pattern = '/\[book:(\d+)(?::([^\]]+))?\]/i'; + if (preg_match_all($pattern, $content, $matches)) { + foreach ($matches[0] as $key => $match) { + $bookId = $matches[1][$key]; + $reviewWithCustom = isset($matches[2][$key]) ? trim($matches[2][$key]) : ''; + + $review = ''; + $customData = array(); + + // 解码短评和自定义数据 + if (!empty($reviewWithCustom)) { + // 分离短评和自定义数据 + if (strpos($reviewWithCustom, '|CUSTOM:') !== false) { + list($review, $customJson) = explode('|CUSTOM:', $reviewWithCustom, 2); + + // 解码自定义数据 + if (!empty($customJson)) { + // URL解码 + $decodedJson = urldecode($customJson); + // 解析JSON + $customData = json_decode($decodedJson, true); + if (!is_array($customData)) { + $customData = array(); + } + } + } else { + // 检查是否是纯自定义数据(没有短评) + if (preg_match('/^\(自定义:(.*)\)$/', $reviewWithCustom, $customMatch)) { + // 这是旧格式的自定义数据,需要转换 + $review = ''; + $customData = self::parseLegacyCustomData($customMatch[1]); + } else { + // 重要修复:处理中文自定义数据(如:短评(自定义:开始阅读:2025.12.03)) + // 检查是否包含中文括号格式的自定义数据 + if (preg_match('/^(.*?)(自定义:(.*))$/u', $reviewWithCustom, $customMatch)) { + // 第一部分是短评 + $review = trim($customMatch[1]); + // 第二部分是自定义数据 + $customData = self::parseLegacyCustomData($customMatch[2]); + } else { + // 没有自定义数据,只有短评 + $review = $reviewWithCustom; + } + } + } + + // 解码短评(处理特殊字符)- 修复:只解码真正的短评部分 + if (!empty($review)) { + // 处理HTML实体转义 + $review = str_replace(array('[', ']'), array('[', ']'), $review); + } + } + + // 获取图书数据(包含短评和自定义数据) + $bookHtml = self::renderBook($bookId, $review, $customData); + $content = str_replace($match, $bookHtml, $content); + } + } + } + + return $content; + } + + /** + * 解析旧格式的自定义数据 + */ + private static function parseLegacyCustomData($customText) + { + $customData = array(); + + // 解析旧格式:开始阅读:2025.12.03,结束阅读:2025.12.07,阅读方法:速读,图书分类:小说,推荐指数:★★ + $pairs = explode(',', $customText); + foreach ($pairs as $pair) { + if (strpos($pair, ':') !== false) { + list($key, $value) = explode(':', $pair, 2); + switch (trim($key)) { + case '开始阅读': + $customData['startDate'] = trim($value); + break; + case '结束阅读': + $customData['readDate'] = trim($value); + break; + case '阅读方法': + $customData['readMethod'] = trim($value); + break; + case '图书分类': + $customData['bookCategory'] = trim($value); + break; + case '推荐指数': + // 计算星星数量 + $starCount = substr_count($value, '★'); + $customData['recommendation'] = $starCount; + break; + } + } + } + + return $customData; + } + + /** + * 渲染单本图书信息 + */ + private static function renderBook($bookId, $review = '', $customData = array()) + { + // 获取图书数据(包含短评和自定义数据) + $bookData = self::getBookData($bookId, $review, $customData); + + if (!$bookData || empty($bookData['title'])) { + return '
暂无图书数据
+请先在文章中使用[book:ID]短代码添加图书
+已读' . $total . '本图书,本数据2025.12.08开始统计
'; + $html .= '标签)
+ $intro = preg_replace('/]*>.*?<\/a>/', '', $intro);
+
+ // 清理多余的空白字符但保留HTML标签
+ $intro = preg_replace('/\s+/', ' ', $intro);
+ $intro = trim($intro);
+
+ // 解码HTML实体,但保留HTML标签
+ $intro = html_entity_decode($intro, ENT_QUOTES, 'UTF-8');
+
+ // 确保 标签正确闭合
+ $intro = preg_replace('/ \s*<\/p>/', '', $intro);
+ $intro = preg_replace('/ \s+/', ' ', $intro);
+ $intro = preg_replace('/\s+<\/p>/', '
《神探伽利略2:预知梦》深夜,陌生男子闯入16岁少女的房间中,发现有人闯入的母亲拿起猎枪开了枪。遭警方擒住的男子主张,17年前,他曾经做过一个与少女结合的梦。究其证据,便是男子念小学四年级时写下的一篇作文。这一切究竟是偶然,还是妄想?……天才物理学者——汤川出马了解这常识中不可能发生的案件。人气推理小说《神探伽利略》(第二季)!<\/p>
东野圭吾笔下最意气风发名侦探——“汤川学”系列第二作!<\/p>
《神探伽利略》(第二季)!《嫌疑人X的献身》之前传!<\/p>
首次东野圭吾授权未删节完整中译版!<\/p>
福山雅治领衔主演《神探伽利略》(第二季)登场!<\/p>
神探伽利略VS预知梦<\/p>", + "author": [ + "[日] 东野圭吾" + ], + "publisher": "化学工业出版社", + "pubdate": "2013-5-1", + "pages": "221", + "isbn": "未知", + "rating": 7.2, + "rating_count": 2393, + "review": "神秘与推理结合的杀人小说,全都比较怪异,吸引人,结局出人意料,比较推荐。", + "review_updated": 1771315138, + "custom_start_date": "2026.01.07", + "custom_read_date": "2026.01.14", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 5, + "fetched_at": 1771315138 +} \ No newline at end of file diff --git a/cache/26911126.json b/cache/26911126.json new file mode 100644 index 0000000..8624ec0 --- /dev/null +++ b/cache/26911126.json @@ -0,0 +1,22 @@ +{ + "title": "那时的某人", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29324836.jpg", + "summary": "
东野圭吾中短篇小说集,作者出道25年珍藏作品首次结集出版。八个故事涵盖了东野不同时期的创作风格,篇篇精巧,各具特色。女律师好心收留了一个雨夜迷路的失忆少女,却在少女的随身手帕里发现了一把带血的匕首;车祸中幸存的女儿,苏醒后居然附上了妻子的灵魂;一对夫妇幸运领养了一个刚出生的婴儿,婴儿天使般的面孔后却隐藏了一个悲凉的复仇计划……<\/p>
书中《REIKO和玲子》《再生魔术的女人》《二十年后的约定》被改编为剧集收入日本富士电视台推理悬疑剧《东野圭吾•悬疑故事》。<\/p>", + "author": [ + "[日] 东野圭吾" + ], + "publisher": "译林出版社", + "pubdate": "2017-3", + "pages": "211", + "isbn": "未知", + "rating": 6.4, + "rating_count": 3560, + "review": "八篇短篇小说,涉及多个社会热点主题,有后记记录每个故事的创作灵感。", + "review_updated": 1771513875, + "custom_start_date": "2025.12.14", + "custom_read_date": "2025.12.16", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 3, + "fetched_at": 1771513875 +} \ No newline at end of file diff --git a/cache/26935572.json b/cache/26935572.json new file mode 100644 index 0000000..875121e --- /dev/null +++ b/cache/26935572.json @@ -0,0 +1,22 @@ +{ + "title": "浪花少年侦探团", + "image": "https:\/\/img1.doubanio.com\/view\/subject\/l\/public\/s29234529.jpg", + "summary": "
◇你今天的心情不好吗?<\/p>
读完东野圭吾的这本书,一定会好起来!<\/p>
◇这样元气满满的可爱女生,<\/p>
在东野圭吾的其他小说中从未见过<\/p>
◇原以为是以孩子为中心的故事而不想读,但试着读下来,发现故事节奏很棒,很有趣,读完后心情明快了起来。——日本亚马逊读者<\/p>
------------------------------------------------------------------------------<\/p>
平安夜,一个女人死在自家浴室,墙上留有“蛋糕”字样。警方判定自杀可能性很小,但现场既没有别人出入的痕迹,也没发现凶器。侦查陷入困境。<\/p>
女老师竹内忍没想到自己竟会和这个案子有关。她打算带着学生一起过圣诞节,买来了蛋糕,却在里面发现了一把刀,上面的血迹和遇害女人的血型一致。凶器究竟来自哪里?忍老师偶然看到遇害女人的一张照片,不禁眼前一亮:照片上四个人看似正常,表情却大有玄机,解谜的关键就在这里。<\/p>", + "author": [ + "[日] 东野圭吾" + ], + "publisher": "南海出版公司", + "pubdate": "2017-3", + "pages": "224", + "isbn": "未知", + "rating": 6.9, + "rating_count": 6774, + "review": "一位小学老师,带着几个调皮的孩子总是能阴差阳错的卷入杀人案,又出奇的为推理提供新的线索,甚至完成推理,很有意思的人物设置,剧情也很反转。", + "review_updated": 1770035217, + "custom_start_date": "", + "custom_read_date": "2026.01.19", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 5, + "fetched_at": 1770035217 +} \ No newline at end of file diff --git a/cache/26958385.json b/cache/26958385.json new file mode 100644 index 0000000..a8176af --- /dev/null +++ b/cache/26958385.json @@ -0,0 +1,22 @@ +{ + "title": "理想的家", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29293864.jpg", + "summary": "
什么样的房子是理想的家?把你对生活的爱与理解融入设计的房子,也许就是理想的家。如果你热爱旅行,如何用你从世界各地带回来的“战利品”打造你的家?如果你热爱美食与厨房,如何设计一个充满人间烟火味的家?如果你爱淘各种小玩意儿,如何布置一个杂货风的家?如果你的家就是你的办公室,如何在10秒钟之内从生活区转到工作区?你将在本书中看到来自东京脑洞大开的定制家居设计故事,探索房子与家之间的场域。<\/p>", + "author": [ + "[日] 蓝色工作室" + ], + "publisher": "化学工业出版社", + "pubdate": "2017-1-1", + "pages": "227", + "isbn": "未知", + "rating": 7.3, + "rating_count": 593, + "review": "相当精美的设计类图书,好看爱看,但是边AI写代码边看,有点断断续续,看杂志的感觉;", + "review_updated": 1771513872, + "custom_start_date": "2025.12.04", + "custom_read_date": "2025.12.08", + "custom_read_method": "精读", + "custom_book_category": "家居", + "custom_recommendation": 5, + "fetched_at": 1771513872 +} \ No newline at end of file diff --git a/cache/26981115.json b/cache/26981115.json new file mode 100644 index 0000000..651edf2 --- /dev/null +++ b/cache/26981115.json @@ -0,0 +1,22 @@ +{ + "title": "让大象飞", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29389296.jpg", + "summary": "
这是一本为中国创业者量身定做的创业指南,将帮助创业者理解创新的基本方法、模式和硅谷的创业理念。作者霍夫曼频繁地穿梭于中美两地,与不同的创业者、投资人、政府负责人进行对话,积累了大量的来自中国创业者的第一手经验。在这本书里,从创业团队的人员配备到创业融资的成败再到团队的高效管理,从创业者的心理素质到创业者的独到眼光再到企业赖以生存的根本,360度无死角地呈现了一家公司从初创到惊艳到立足再到稳定的全过程,可谓《从0到1》的实践版。<\/p>
这更是来自硅谷的创业教父在创业寒冬时要对创业者说的话,当人人都在感叹创业不易、创新更难时,他却说,资本寒冬正好能让市场回归理性。霍夫曼从一个白手起家的创业者角度,也从一个资深投资人的角度,重新审视创新,有力地向我们证明了,对所有企业来说,创新不再是一种选择,而是进入商业世界的敲门砖。<\/p>
没有一本书详细解析了在硅谷孵化期内的创业公司的整个创新过程以及它们所使用的方法论,也没有任何一本书讲到了该如何将这些创新技巧应用于大到全球性的跨国公司、小到那些在车库里的初创企业,《让大象飞》做到了。<\/p>
当创业环境好的时候,风口之上,一切皆有可能;当风口没了的时候,大象还能飞吗?<\/p>
这本书是给当下创业者最好的解答。<\/p>", + "author": [ + "[美] 史蒂文·霍夫曼" + ], + "publisher": "中信出版社", + "pubdate": "2017-3", + "pages": "448", + "isbn": "未知", + "rating": 7.7, + "rating_count": 1006, + "review": "屋顶咖啡书架取读,因孩子闹腾,快速阅读,临走时还剩十几页没读。", + "review_updated": 1771513870, + "custom_start_date": "2025.12.01", + "custom_read_date": "2025.12.01", + "custom_read_method": "速读", + "custom_book_category": "创业", + "custom_recommendation": 3, + "fetched_at": 1771513870 +} \ No newline at end of file diff --git a/cache/26997273.json b/cache/26997273.json new file mode 100644 index 0000000..5a92ec0 --- /dev/null +++ b/cache/26997273.json @@ -0,0 +1,22 @@ +{ + "title": "我的宝贝", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29401684.jpg", + "summary": "
她以一支笔坚持看守个人文字上的简单和朴素<\/p>
从遥远的撒哈拉到敦煌戈壁,她不随波逐流,也不诠释人生,只做生活的见证者<\/p>
她是我们心中浪漫、洒脱、真性情的永远的三毛,永恒的传奇<\/p>
《我的宝贝》一书中,三毛向读者们展示了一件件珍藏多年的宝贝,广东来的老茶壶、腓尼基人的宝瓶、小船ECHO号、第一匹白马……每一样宝贝来历的背后,都躲藏着一个不同的故事,见证了三毛经历过的爱情、亲情和友情,以及走遍世界各地的奇妙旅程。这些宝贝并非价值连城,但因为有了人的缘故,才被接纳,成了三毛生命中的印记,让她爱不释手。<\/p>", + "author": [ + "三毛" + ], + "publisher": "北京十月文艺出版社", + "pubdate": "2017-3", + "pages": "272", + "isbn": "未知", + "rating": 8.6, + "rating_count": 1737, + "review": "配图介绍作者淘到和收藏的各种物件,讲述故事及意义", + "review_updated": 1769984188, + "custom_start_date": "", + "custom_read_date": "2025.12.31", + "custom_read_method": "精读", + "custom_book_category": "散文", + "custom_recommendation": 5, + "fetched_at": 1769984188 +} \ No newline at end of file diff --git a/cache/30317423.json b/cache/30317423.json new file mode 100644 index 0000000..be4a1fd --- /dev/null +++ b/cache/30317423.json @@ -0,0 +1,22 @@ +{ + "title": "我杀了他", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s32313104.jpg", + "summary": "
★东野圭吾烧脑悬疑长篇,《恶意》系列作<\/p>
★读完《我杀了他》,99%的人都找不到凶手,你会不会是那1%?<\/p>
★与《白夜行》一起入选年度本格推理BEST10榜单<\/p>
★一个人究竟活成什么样,才会让身边的每个人都想杀了他?<\/p>
★《谁杀了她》难度升级,三个嫌疑人,三种犯罪视角,但真凶只有一个,答案就写在书里!<\/p>
★东野圭吾说:“《我杀了他》延续了《谁杀了她》的模式,只是这次嫌疑人增到了三个。有关《我杀了他》的推理论战愈演愈烈,身为作者,我真的很高兴。”<\/p>
----------------------<\/p>
内容简介:<\/p>
作家穗高在自己的婚礼上中毒身亡,他的经纪人、编辑和新娘的哥哥都以为是自己成功杀掉了他,并为此沾沾自喜。婚礼一周后,一封邀请函让三个嫌疑人聚到穗高家,等待着他们的是刑警加贺和新娘。案情逐渐清晰,谁把毒药混入穗高的鼻炎药是解谜的关键,但每个人为了自保而给出的证词,却出乎意料地成为另外两人无罪的证明。加贺听完证词,坚定地说“答案已经出来”,而只有凶手才能听懂他接下来要说的一番话。<\/p>", + "author": [ + "[日]东野圭吾" + ], + "publisher": "南海出版公司", + "pubdate": "2019-5", + "pages": "297", + "isbn": "未知", + "rating": 7.3, + "rating_count": 9835, + "review": "加贺探案集5,复杂的情感关系引发的复仇杀人案,从多个嫌疑人第一视角来叙述蛮有意思的,最后还留了悬念。", + "review_updated": 1771315140, + "custom_start_date": "", + "custom_read_date": "2026.01.07", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 0, + "fetched_at": 1771315140 +} \ No newline at end of file diff --git a/cache/36367660.json b/cache/36367660.json new file mode 100644 index 0000000..400d689 --- /dev/null +++ b/cache/36367660.json @@ -0,0 +1,22 @@ +{ + "title": "吃透小红书文案:从模仿、创新到超越", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s34547196.jpg", + "summary": "
“写作太难”“我不是写作这块料”……当你看见朋友们在自媒体赚得盆满钵满时,你也曾跃跃欲试。<\/p>
当越来越多的人都在做小红书时,你也曾偷偷发过几篇笔记,可是发出来后点赞寥寥无几,涨粉更是太难,所以你就不想做了。<\/p>
其实,小红书平台对新人友爱而包容,只需要你认真运营,有一定的写作能力即可做出远超预期的成绩。<\/p>
本书从具体案例着手,详细剖析爆款背后的文案思维,创新性设计了文案吸引力模型、总结出提升笔记互动的三感一力,还以真实笔记做案例帮助你实现文案的模仿、创新和超越。<\/p>
本书从最简单实用的角度,提出了修复人设缺点的文案技巧,帮助博主打造“人设”、塑造人格魅力。<\/p>
本书从不同需求出发,结合作者独创的写作经验,实操展示提升文笔的五个技巧;<\/p>
本书从真正有用的角度出发,深度讲解了九种爆款笔记的创作技巧、优质文案的四象限法。<\/p>