wechat-media-writer 2.2.7 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md CHANGED
@@ -156,11 +156,11 @@ Token 缓存在 `~/.wechat/token_cache.json`(自动管理,2小时有效期
156
156
  <img src="{THEME_IMG_2}" style="width:100%;max-width:600px;display:block;margin:0 auto;border-radius:4px;" alt="主题配图" />
157
157
  </p>
158
158
 
159
- <!-- 金句引用块(用主题色高亮,加左侧色条) -->
159
+ <!-- 金句引用块(圆角浅背景,无左侧竖条) -->
160
160
  <p
161
- style="font-size:17px;line-height:1.9;color:{T};font-weight:bold;text-indent:2em;margin:0 0 20px;padding:14px 18px;background:{CBG};border-left:4px solid {T2};border-radius:6px;"
161
+ style="font-size:17px;line-height:1.9;color:{T};font-weight:bold;text-indent:2em;margin:0 0 20px;padding:16px 20px;background:{CBG};border-radius:8px;"
162
162
  >
163
- <span style="color:{T2};">▍</span> 金句或核心观点引用。整段用主题主色加粗,加左侧强调色条,与正文形成视觉对比。
163
+ <span>金句或核心观点引用。整段用主题主色加粗,圆角浅背景与正文形成视觉对比。</span>
164
164
  </p>
165
165
 
166
166
  <!-- 重点启发语句(行内主题色 + 强调色高亮) -->
@@ -184,7 +184,7 @@ Token 缓存在 `~/.wechat/token_cache.json`(自动管理,2小时有效期
184
184
  2. **图片URL必须用完整的 `mmbiz.qpic.cn` 硬编码URL** — 不用模板变量
185
185
  3. **`<img>` 必须包裹在 `<p>` 中**,且 `style="width:100%;display:block;border-radius:4px;"`
186
186
  4. **行高统一 `line-height:2`** — 阅读舒适
187
- 5. **引用块用 `<p>` + `background` + `border-radius:8px` + 左侧 `border-left:4px solid {T2}` 色条** 不是 `<blockquote>`
187
+ 5. **引用块用 `<p>` + `background` + `border-radius:8px`**圆角浅背景卡片样式,不要左侧竖条
188
188
  6. **章节标题不使用数字编号** — 直接用"作者背景与创作时代",不用"壹"
189
189
  7. **强调文字用 `<strong style="color:{T};">`** — 不是加粗或改色
190
190
  8. **重点语句/概念高亮**:用 `<strong style="color:{T};background:{CBG};padding:1px 6px;border-radius:3px;">` 或 `<span style="color:{T2};font-weight:bold;">` — 让主题色贯穿全文
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wechat-media-writer",
3
- "version": "2.2.7",
3
+ "version": "2.2.8",
4
4
  "description": "微信公众号书评、影评文章自动生成与发布 - Skill",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -45,7 +45,7 @@ THEME_IMG_5 = "http://mmbiz.qpic.cn/REPLACE_WITH_THEME_IMG_5"
45
45
  THEME_IMG_END = "http://mmbiz.qpic.cn/REPLACE_WITH_THEME_IMG_END"
46
46
 
47
47
  # 文章 HTML 内容(7段式,无数字编号,全文主题贴图穿插)
48
- HTML = f"""<section style="margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;color:#333;background:#FBF8FC;">
48
+ HTML = f"""<section style="margin:0;padding:0 0 48px;font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;color:#333;background:#FBF8FC;">
49
49
 
50
50
  <p style="font-size:12px;color:{T2};text-align:center;letter-spacing:4px;margin:24px 0 8px;line-height:3em;">
51
51
  <span>📖 读书拆解</span>
@@ -77,9 +77,9 @@ HTML = f"""<section style="margin:0;padding:0;font-family:-apple-system,BlinkMac
77
77
  <img src="{THEME_IMG_2}" style="width:100%;max-width:600px;display:block;margin:0 auto;border-radius:4px;" alt="主题配图"/>
78
78
  </p>
79
79
 
80
- <!-- 金句引用块(左侧色条 + 主题色加粗) -->
81
- <p style="font-size:17px;line-height:1.9;color:{T};font-weight:bold;text-indent:2em;margin:0 0 20px;padding:14px 18px;background:{CBG};border-left:4px solid {T2};border-radius:6px;">
82
- <span style="color:{T2};">▍</span> 金句或核心观点。整段用主题主色加粗,加左侧强调色条与正文形成视觉对比。
80
+ <!-- 金句引用块(圆角浅背景,无左侧竖条) -->
81
+ <p style="font-size:17px;line-height:1.9;color:{T};font-weight:bold;text-indent:2em;margin:0 0 20px;padding:16px 20px;background:{CBG};border-radius:8px;">
82
+ <span>金句或核心观点。整段用主题主色加粗,圆角浅背景与正文形成视觉对比。</span>
83
83
  </p>
84
84
 
85
85
  <!-- 全书脉络 -->
@@ -123,8 +123,8 @@ HTML = f"""<section style="margin:0;padding:0;font-family:-apple-system,BlinkMac
123
123
  </p>
124
124
 
125
125
  <!-- 金句二 -->
126
- <p style="font-size:17px;line-height:1.9;color:{T};font-weight:bold;text-indent:2em;margin:0 0 20px;padding:14px 18px;background:{CBG};border-left:4px solid {T2};border-radius:6px;">
127
- <span style="color:{T2};">▍</span> 第二个金句或关键启发。
126
+ <p style="font-size:17px;line-height:1.9;color:{T};font-weight:bold;text-indent:2em;margin:0 0 20px;padding:16px 20px;background:{CBG};border-radius:8px;">
127
+ <span>第二个金句或关键启发。</span>
128
128
  </p>
129
129
 
130
130
  <!-- 读完真正留下的东西 -->
@@ -170,15 +170,27 @@ HTML = f"""<section style="margin:0;padding:0;font-family:-apple-system,BlinkMac
170
170
  <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 8px;text-indent:2em;">
171
171
  <strong style="color:{T};">适合人群:</strong>
172
172
  </p>
173
- <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 16px;text-indent:2em;">
174
- <span>✅&nbsp;&nbsp;创业者/管理者——理解系统脆弱性和反脆弱设计<br />✅&nbsp;&nbsp;对个人成长感兴趣的读者——掌握从压力中受益的方法<br />✅&nbsp;&nbsp;对决策科学感兴趣的读者——理解非线性风险的本质</span>
173
+ <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 8px;padding-left:2em;">
174
+ <span>✅&nbsp;&nbsp;创业者/管理者——理解系统脆弱性和反脆弱设计</span>
175
+ </p>
176
+ <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 8px;padding-left:2em;">
177
+ <span>✅&nbsp;&nbsp;对个人成长感兴趣的读者——掌握从压力中受益的方法</span>
178
+ </p>
179
+ <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 16px;padding-left:2em;">
180
+ <span>✅&nbsp;&nbsp;对决策科学感兴趣的读者——理解非线性风险的本质</span>
175
181
  </p>
176
182
 
177
183
  <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 8px;text-indent:2em;">
178
184
  <strong style="color:{T};">不适合人群:</strong>
179
185
  </p>
180
- <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 16px;text-indent:2em;">
181
- <span>🚫&nbsp;&nbsp;已读过类似书籍的人——内容高度重复<br />🚫&nbsp;&nbsp;讨厌抽象论证的人——本书充满概念性思维<br />🚫&nbsp;&nbsp;寻找具体操作手册的人——本书偏哲学思辨</span>
186
+ <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 8px;padding-left:2em;">
187
+ <span>🚫&nbsp;&nbsp;已读过类似书籍的人——内容高度重复</span>
188
+ </p>
189
+ <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 8px;padding-left:2em;">
190
+ <span>🚫&nbsp;&nbsp;讨厌抽象论证的人——本书充满概念性思维</span>
191
+ </p>
192
+ <p style="font-size:16px;line-height:2;color:{BODY};margin:0 0 24px;padding-left:2em;">
193
+ <span>🚫&nbsp;&nbsp;寻找具体操作手册的人——本书偏哲学思辨</span>
182
194
  </p>
183
195
 
184
196
  <!-- 结尾页:主题配图 + 书名 + 作者 + 核心总结 -->
@@ -194,7 +206,7 @@ HTML = f"""<section style="margin:0;padding:0;font-family:-apple-system,BlinkMac
194
206
  <p style="font-size:14px;color:{BODY};text-align:center;margin:0 0 4px;line-height:1.6;">
195
207
  <span>作者 · 读书笔记</span>
196
208
  </p>
197
- <p style="font-size:14px;color:{T2};text-align:center;margin:0 0 24px;line-height:1.8;font-weight:bold;">
209
+ <p style="font-size:14px;color:{T2};text-align:center;margin:8px 0 32px;line-height:1.8;font-weight:bold;">
198
210
  <span>「 一句话总结:核心洞察 」</span>
199
211
  </p>
200
212
 
@@ -13,18 +13,21 @@ import urllib.request
13
13
  from PIL import Image, ImageStat
14
14
 
15
15
 
16
- # 精选 Pexels 候选 ID(每个主题 8-10 张,全部已测试可用)
17
- # 选择标准:构图饱满、色彩丰富、主题鲜明
16
+ # 精选 Pexels 候选 ID(每个主题 8-10 张,实地下载验证)
17
+ # 选择标准:构图饱满、色彩丰富、主题鲜明、与书评/影评审美契合
18
18
  THEME_CANDIDATES = {
19
19
  "books": [
20
- 256450, # 书与咖啡
21
- 590493, # 翻页
22
- 762687, # 书架
23
- 1029141, # 书页
24
- 3568520, # 笔记本与笔
25
- 3568521, # 笔记本俯拍
26
- 1112048, # 翻页特写
27
- 4429270, # 复古书籍
20
+ # Pexels 搜索"book"结果中精选的高质量图
21
+ 415078, # 草地上开本书(封面候选极佳)
22
+ 433333, # 书堆黑白(封面候选极佳,构图饱满)
23
+ 4861364, # 两人读书
24
+ 5913138, # 书+花+咖啡
25
+ 6001171, # 床上读书
26
+ 7034613, # 书架书+植物
27
+ 1792734, # 阳光读书
28
+ 11197155, # 古书桌上
29
+ 13580974, # 翻开的书页
30
+ 904616, # 咖啡+书+花俯拍
28
31
  ],
29
32
  "abstract": [
30
33
  1108572, # 抽象光影
@@ -45,6 +48,8 @@ THEME_CANDIDATES = {
45
48
  3551226, # 风景
46
49
  3551244, # 风景光影
47
50
  3551419, # 风景横幅
51
+ 417173, # 雪峰
52
+ 355770, # 黑白雪山
48
53
  ],
49
54
  "technology": [
50
55
  3568520, # 代码屏幕
@@ -149,31 +154,51 @@ def aesthetics_score(image_path):
149
154
  def download_theme_images(theme, output_dir, count=6):
150
155
  """根据主题下载多张精美图片
151
156
 
152
- 自动跳过 404 候选,失败时回退到主题内其他候选。
157
+ 自动跳过 404/失败候选,下载到临时文件名,再按美学评分重命名为 img_1.jpg ~ img_N.jpg
153
158
  返回: 已下载图片路径列表(按美学评分降序)
154
159
  """
160
+ os.makedirs(output_dir, exist_ok=True)
155
161
  candidates = THEME_CANDIDATES.get(theme, THEME_CANDIDATES["books"])
156
- downloaded = []
162
+ downloaded = [] # 临时文件列表
157
163
 
164
+ # 1) 全部下载到临时文件
158
165
  for i, pid in enumerate(candidates):
159
166
  if len(downloaded) >= count:
160
167
  break
161
- output_path = os.path.join(output_dir, f"img_{len(downloaded) + 1}.jpg")
162
- if download_pexels_image(pid, output_path):
163
- downloaded.append(output_path)
168
+ tmp_path = os.path.join(output_dir, f"_tmp_{theme}_{i}_{pid}.jpg")
169
+ if download_pexels_image(pid, tmp_path):
170
+ downloaded.append(tmp_path)
164
171
 
165
- # 按美学评分降序排序(封面挑选时会取第一张)
172
+ if not downloaded:
173
+ return []
174
+
175
+ # 2) 按美学评分排序
166
176
  scored = [(p, aesthetics_score(p)) for p in downloaded]
167
177
  scored.sort(key=lambda x: x[1], reverse=True)
168
178
 
169
- # 按评分重命名回 img_N.jpg
179
+ # 3) 先清空目标 img_N.jpg(避免 rename 冲突或 macOS 覆盖丢失数据)
180
+ for i in range(1, count + 1):
181
+ f = os.path.join(output_dir, f"img_{i}.jpg")
182
+ if os.path.exists(f):
183
+ os.remove(f)
184
+
185
+ # 4) 重命名到 img_N.jpg
186
+ result = []
170
187
  for new_idx, (path, score) in enumerate(scored, 1):
171
188
  new_path = os.path.join(output_dir, f"img_{new_idx}.jpg")
172
- if path != new_path:
173
- os.rename(path, new_path)
189
+ os.rename(path, new_path)
190
+ result.append(new_path)
174
191
  print(f" img_{new_idx}.jpg 评分 {score}")
175
192
 
176
- return [p for p, _ in scored]
193
+ # 5) 清理可能残留的临时文件
194
+ for fname in os.listdir(output_dir):
195
+ if fname.startswith("_tmp_"):
196
+ try:
197
+ os.remove(os.path.join(output_dir, fname))
198
+ except OSError:
199
+ pass
200
+
201
+ return result
177
202
 
178
203
 
179
204
  def pick_best_cover(theme_images_dir):