wechat-auto-publish 0.1.0__tar.gz

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.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: wechat-auto-publish
3
+ Version: 0.1.0
4
+ Summary: Outermost WeChat Official Account pipeline: compose opp-radar (generation) + wechat-formatter (render) + wechat-publish (draft) into one command.
5
+ Author: 程序员白大力
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/baiyigali/wechat-auto-publish
8
+ Project-URL: Repository, https://github.com/baiyigali/wechat-auto-publish
9
+ Keywords: wechat,wechat-mp,公众号,pipeline,draft,automation
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Office/Business
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: wechat-formatter
18
+ Requires-Dist: wechat-publish
19
+
20
+ # wechat-auto-publish
21
+
22
+ 公众号自动发布的**最外层流水线**。它自己不生成内容,只把三个上游组件串成一条命令:
23
+
24
+ ```
25
+ opp-radar → 生成文章(.md + 封面 .png)
26
+ wechat-formatter → .md 渲染成公众号内联样式 HTML
27
+ wechat-publish → HTML + 封面推到公众号草稿箱
28
+ ```
29
+
30
+ | 组件 | 仓库 / 包 | 职责 |
31
+ |---|---|---|
32
+ | 生成 | [opp_radar](https://github.com/baiyigali/opp_radar) | 机会雷达,按领域提示词产出渠道无关的文章 |
33
+ | 排版 | [wechat-formatter](https://github.com/baiyigali/wechat-formatter) | Markdown → 科技风经典蓝 HTML |
34
+ | 发布 | [wechat-publish](https://github.com/baiyigali/wechat-publish) | 草稿箱接口,图片自动转存微信 CDN |
35
+
36
+ 换领域、换排版主题、换发布渠道时,只在这一层换组件,不改上游。
37
+
38
+ ## 安装
39
+
40
+ ```bash
41
+ pip install -e .
42
+ # 或 pip install wechat-auto-publish
43
+ ```
44
+
45
+ 依赖三个上游包(见 `pyproject.toml`)。
46
+
47
+ ## 配置
48
+
49
+ 复制 `config.example.json` 为 `config.json`,填入公众号 appid / secret / author。`config.json` 已 gitignore,不进版本库。
50
+
51
+ ## 用法
52
+
53
+ ### 命令行:把一篇已写好的文章推到草稿箱
54
+
55
+ ```bash
56
+ wechat-auto-publish draft "文章.md" "封面.png" "标题" "120字内摘要"
57
+ ```
58
+
59
+ 这条命令只跑一次,绝不重试,避免重复建草稿。
60
+
61
+ ### 编排:生成 + 发布一条龙
62
+
63
+ 给 AI agent 说:"按 `prompts/pipeline.md` 跑一期"。它会先读 opp-radar 里对应领域的提示词生成文章,再调用本仓库把文章推到草稿箱。
64
+
65
+ ## 目录
66
+
67
+ ```
68
+ wechat-auto-publish/
69
+ prompts/pipeline.md # 最外层编排提示词
70
+ wechat_auto_publish/ # 包:render + push
71
+ config.example.json
72
+ pyproject.toml
73
+ ```
74
+
75
+ ## 说明
76
+
77
+ - 只存草稿,不群发。个人未认证号无 `freepublish/submit` 权限,发表动作在公众号后台手动点。
78
+ - 发布命令只执行一次:微信接口可能"已成功但返回像失败",重试会重复建草稿。
79
+
80
+ ## CI / 自动发布
81
+
82
+ 仓库自带 GitHub Actions(`.github/workflows/publish.yml`),与常见开源 Python 包一致:
83
+
84
+ - **push 到 `main`** → 编译 sdist + wheel,自动发布到 **TestPyPI**(官方测试源,验证打包流程不污染正式版);
85
+ - **打 tag `v*`**(如 `v0.1.0`)→ 编译后发布到**正式 PyPI**;
86
+ - 也支持在 Actions 页面手动触发(`workflow_dispatch`),只编译不发布。
87
+
88
+ 免密推送:在 PyPI / TestPyPI 后台把本仓库配置为 **Trusted Publisher(OIDC)**,workflow 里 `id-token: write` 自动换取临时凭据,不需要任何 `PYPI_API_TOKEN`。
89
+
90
+ ## 技术交流
91
+
92
+ 扫码添加微信,交流使用问题、定制与合作:
93
+
94
+ <p align="center">
95
+ <img src="docs/images/wechat-contact-qr.jpg" alt="微信二维码" width="240" />
96
+ </p>
97
+
98
+ ## 项目赞助
99
+
100
+ 本项目由微信公众号 **「程序员白大力」** 提供赞助,感谢支持:
101
+
102
+ <p align="center">
103
+ <img src="docs/images/wechat-official-account-qr.png" alt="程序员白大力公众号二维码" width="240" />
104
+ </p>
105
+
106
+ ## License
107
+
108
+ MIT
@@ -0,0 +1,89 @@
1
+ # wechat-auto-publish
2
+
3
+ 公众号自动发布的**最外层流水线**。它自己不生成内容,只把三个上游组件串成一条命令:
4
+
5
+ ```
6
+ opp-radar → 生成文章(.md + 封面 .png)
7
+ wechat-formatter → .md 渲染成公众号内联样式 HTML
8
+ wechat-publish → HTML + 封面推到公众号草稿箱
9
+ ```
10
+
11
+ | 组件 | 仓库 / 包 | 职责 |
12
+ |---|---|---|
13
+ | 生成 | [opp_radar](https://github.com/baiyigali/opp_radar) | 机会雷达,按领域提示词产出渠道无关的文章 |
14
+ | 排版 | [wechat-formatter](https://github.com/baiyigali/wechat-formatter) | Markdown → 科技风经典蓝 HTML |
15
+ | 发布 | [wechat-publish](https://github.com/baiyigali/wechat-publish) | 草稿箱接口,图片自动转存微信 CDN |
16
+
17
+ 换领域、换排版主题、换发布渠道时,只在这一层换组件,不改上游。
18
+
19
+ ## 安装
20
+
21
+ ```bash
22
+ pip install -e .
23
+ # 或 pip install wechat-auto-publish
24
+ ```
25
+
26
+ 依赖三个上游包(见 `pyproject.toml`)。
27
+
28
+ ## 配置
29
+
30
+ 复制 `config.example.json` 为 `config.json`,填入公众号 appid / secret / author。`config.json` 已 gitignore,不进版本库。
31
+
32
+ ## 用法
33
+
34
+ ### 命令行:把一篇已写好的文章推到草稿箱
35
+
36
+ ```bash
37
+ wechat-auto-publish draft "文章.md" "封面.png" "标题" "120字内摘要"
38
+ ```
39
+
40
+ 这条命令只跑一次,绝不重试,避免重复建草稿。
41
+
42
+ ### 编排:生成 + 发布一条龙
43
+
44
+ 给 AI agent 说:"按 `prompts/pipeline.md` 跑一期"。它会先读 opp-radar 里对应领域的提示词生成文章,再调用本仓库把文章推到草稿箱。
45
+
46
+ ## 目录
47
+
48
+ ```
49
+ wechat-auto-publish/
50
+ prompts/pipeline.md # 最外层编排提示词
51
+ wechat_auto_publish/ # 包:render + push
52
+ config.example.json
53
+ pyproject.toml
54
+ ```
55
+
56
+ ## 说明
57
+
58
+ - 只存草稿,不群发。个人未认证号无 `freepublish/submit` 权限,发表动作在公众号后台手动点。
59
+ - 发布命令只执行一次:微信接口可能"已成功但返回像失败",重试会重复建草稿。
60
+
61
+ ## CI / 自动发布
62
+
63
+ 仓库自带 GitHub Actions(`.github/workflows/publish.yml`),与常见开源 Python 包一致:
64
+
65
+ - **push 到 `main`** → 编译 sdist + wheel,自动发布到 **TestPyPI**(官方测试源,验证打包流程不污染正式版);
66
+ - **打 tag `v*`**(如 `v0.1.0`)→ 编译后发布到**正式 PyPI**;
67
+ - 也支持在 Actions 页面手动触发(`workflow_dispatch`),只编译不发布。
68
+
69
+ 免密推送:在 PyPI / TestPyPI 后台把本仓库配置为 **Trusted Publisher(OIDC)**,workflow 里 `id-token: write` 自动换取临时凭据,不需要任何 `PYPI_API_TOKEN`。
70
+
71
+ ## 技术交流
72
+
73
+ 扫码添加微信,交流使用问题、定制与合作:
74
+
75
+ <p align="center">
76
+ <img src="docs/images/wechat-contact-qr.jpg" alt="微信二维码" width="240" />
77
+ </p>
78
+
79
+ ## 项目赞助
80
+
81
+ 本项目由微信公众号 **「程序员白大力」** 提供赞助,感谢支持:
82
+
83
+ <p align="center">
84
+ <img src="docs/images/wechat-official-account-qr.png" alt="程序员白大力公众号二维码" width="240" />
85
+ </p>
86
+
87
+ ## License
88
+
89
+ MIT
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "wechat-auto-publish"
7
+ version = "0.1.0"
8
+ description = "Outermost WeChat Official Account pipeline: compose opp-radar (generation) + wechat-formatter (render) + wechat-publish (draft) into one command."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "程序员白大力" }]
13
+ keywords = ["wechat", "wechat-mp", "公众号", "pipeline", "draft", "automation"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Office/Business",
20
+ ]
21
+ # 上游三个组件;按需替换成你自己的 fork / 版本
22
+ dependencies = [
23
+ "wechat-formatter",
24
+ "wechat-publish",
25
+ # opp-radar 是提示词仓库,尚未发 PyPI 时直接引用 GitHub:
26
+ # "opp-radar @ git+https://github.com/baiyigali/opp_radar.git",
27
+ ]
28
+
29
+ [project.scripts]
30
+ wechat-auto-publish = "wechat_auto_publish.cli:main"
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/baiyigali/wechat-auto-publish"
34
+ Repository = "https://github.com/baiyigali/wechat-auto-publish"
35
+
36
+ [tool.setuptools]
37
+ packages = ["wechat_auto_publish"]
38
+
39
+ [tool.setuptools.package-data]
40
+ wechat_auto_publish = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,10 @@
1
+ """wechat-auto-publish:最外层公众号发布流水线。
2
+
3
+ 只做分发编排,不生成内容。依赖三个上游:
4
+ - opp-radar :机会雷达,负责产出渠道无关的 .md + 封面
5
+ - wechat-formatter:把 .md 渲染成公众号内联样式 HTML
6
+ - wechat-publish :把 HTML+封面推到公众号草稿箱
7
+ 后续要换底层包/换领域时,只动这里的组合,不改上游。
8
+ """
9
+
10
+ __version__ = "0.1.0"
@@ -0,0 +1,32 @@
1
+ """wechat-auto-publish 命令行。
2
+
3
+ 用法:
4
+ wechat-auto-publish draft <文章.md> <封面.png> "<标题>" "<摘要>"
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import argparse
9
+ import sys
10
+
11
+
12
+ def main() -> int:
13
+ parser = argparse.ArgumentParser(
14
+ prog="wechat-auto-publish",
15
+ description="把一篇已写好的 md 文章渲染并推到公众号草稿箱。",
16
+ )
17
+ sub = parser.add_subparsers(dest="cmd", required=True)
18
+ p = sub.add_parser("draft", help="渲染 + 推草稿箱(只跑一次)")
19
+ p.add_argument("md", help="文章 .md 路径")
20
+ p.add_argument("cover", help="封面 .png 路径")
21
+ p.add_argument("title", help="文章标题")
22
+ p.add_argument("digest", help="摘要(120 字内)")
23
+ p.add_argument("--config", default="config.json", help="凭据路径,默认 ./config.json")
24
+ args = parser.parse_args()
25
+
26
+ from .pipeline import push_draft
27
+ push_draft(args.md, args.cover, args.title, args.digest, args.config)
28
+ return 0
29
+
30
+
31
+ if __name__ == "__main__":
32
+ sys.exit(main())
@@ -0,0 +1,83 @@
1
+ """把一篇已写好的文章分发到微信公众号草稿箱。
2
+
3
+ 这一层不生成内容,只做两步:
4
+ 1. 用 wechat-formatter 把 .md 渲染成公众号 HTML(科技风/经典蓝);
5
+ 2. 用 wechat-publish 把 HTML + 封面推到草稿箱(只存草稿,不群发)。
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import os
11
+
12
+
13
+ def render(md_path: str, html_path: str) -> str:
14
+ """调用 wechat-formatter,把 md 渲染成内联样式 HTML。"""
15
+ with open(md_path, "r", encoding="utf-8") as f:
16
+ md = f.read()
17
+
18
+ from wechat_formatter import FormatTweaks, get_template, render_article
19
+
20
+ template = get_template("科技风", "经典") # 经典蓝 #2563eb
21
+ tweaks = FormatTweaks(fontSize=15, lineHeight=1.8, paragraphSpacing=18, imageRadius=6)
22
+ body = render_article(md, template, tweaks)
23
+
24
+ title = os.path.splitext(os.path.basename(md_path))[0]
25
+ html = f"""<!DOCTYPE html>
26
+ <html lang="zh-CN">
27
+ <head>
28
+ <meta charset="utf-8">
29
+ <meta name="viewport" content="width=device-width, initial-scale=1">
30
+ <title>{title}</title>
31
+ <style>
32
+ body {{ margin:0; background:#f2f3f5; padding:24px 0; }}
33
+ .wechat-article {{ max-width:677px; margin:0 auto; background:#fff;
34
+ padding:24px 16px; box-sizing:border-box; }}
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div class="wechat-article">
39
+ {body}
40
+ </div>
41
+ </body>
42
+ </html>"""
43
+
44
+ with open(html_path, "w", encoding="utf-8") as f:
45
+ f.write(html)
46
+ return html_path
47
+
48
+
49
+ def push_draft(
50
+ md_path: str,
51
+ cover_path: str,
52
+ title: str,
53
+ digest: str,
54
+ config_path: str = "config.json",
55
+ ) -> str | None:
56
+ """渲染 + 推草稿。无论成功/报错都只调用一次,绝不重试。"""
57
+ html_path = os.path.splitext(md_path)[0] + ".html"
58
+ render(md_path, html_path)
59
+
60
+ with open(config_path, "r", encoding="utf-8") as f:
61
+ cfg = json.load(f)
62
+
63
+ from wechat_publish import WeChatAPIError, push_articles
64
+
65
+ try:
66
+ media_id = push_articles(
67
+ appid=cfg["appid"],
68
+ secret=cfg["secret"],
69
+ articles=[{
70
+ "html_path": html_path,
71
+ "title": title,
72
+ "cover_path": cover_path,
73
+ "digest": digest,
74
+ }],
75
+ author=cfg["author"],
76
+ open_comment=False,
77
+ publish_now=False, # 个人未认证号无 freepublish 发布权限,发表由人工完成
78
+ )
79
+ print("DRAFT_MEDIA_ID:", media_id)
80
+ return media_id
81
+ except WeChatAPIError as e:
82
+ print("WECHAT_ERROR:", e)
83
+ return None
File without changes
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: wechat-auto-publish
3
+ Version: 0.1.0
4
+ Summary: Outermost WeChat Official Account pipeline: compose opp-radar (generation) + wechat-formatter (render) + wechat-publish (draft) into one command.
5
+ Author: 程序员白大力
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/baiyigali/wechat-auto-publish
8
+ Project-URL: Repository, https://github.com/baiyigali/wechat-auto-publish
9
+ Keywords: wechat,wechat-mp,公众号,pipeline,draft,automation
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Office/Business
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: wechat-formatter
18
+ Requires-Dist: wechat-publish
19
+
20
+ # wechat-auto-publish
21
+
22
+ 公众号自动发布的**最外层流水线**。它自己不生成内容,只把三个上游组件串成一条命令:
23
+
24
+ ```
25
+ opp-radar → 生成文章(.md + 封面 .png)
26
+ wechat-formatter → .md 渲染成公众号内联样式 HTML
27
+ wechat-publish → HTML + 封面推到公众号草稿箱
28
+ ```
29
+
30
+ | 组件 | 仓库 / 包 | 职责 |
31
+ |---|---|---|
32
+ | 生成 | [opp_radar](https://github.com/baiyigali/opp_radar) | 机会雷达,按领域提示词产出渠道无关的文章 |
33
+ | 排版 | [wechat-formatter](https://github.com/baiyigali/wechat-formatter) | Markdown → 科技风经典蓝 HTML |
34
+ | 发布 | [wechat-publish](https://github.com/baiyigali/wechat-publish) | 草稿箱接口,图片自动转存微信 CDN |
35
+
36
+ 换领域、换排版主题、换发布渠道时,只在这一层换组件,不改上游。
37
+
38
+ ## 安装
39
+
40
+ ```bash
41
+ pip install -e .
42
+ # 或 pip install wechat-auto-publish
43
+ ```
44
+
45
+ 依赖三个上游包(见 `pyproject.toml`)。
46
+
47
+ ## 配置
48
+
49
+ 复制 `config.example.json` 为 `config.json`,填入公众号 appid / secret / author。`config.json` 已 gitignore,不进版本库。
50
+
51
+ ## 用法
52
+
53
+ ### 命令行:把一篇已写好的文章推到草稿箱
54
+
55
+ ```bash
56
+ wechat-auto-publish draft "文章.md" "封面.png" "标题" "120字内摘要"
57
+ ```
58
+
59
+ 这条命令只跑一次,绝不重试,避免重复建草稿。
60
+
61
+ ### 编排:生成 + 发布一条龙
62
+
63
+ 给 AI agent 说:"按 `prompts/pipeline.md` 跑一期"。它会先读 opp-radar 里对应领域的提示词生成文章,再调用本仓库把文章推到草稿箱。
64
+
65
+ ## 目录
66
+
67
+ ```
68
+ wechat-auto-publish/
69
+ prompts/pipeline.md # 最外层编排提示词
70
+ wechat_auto_publish/ # 包:render + push
71
+ config.example.json
72
+ pyproject.toml
73
+ ```
74
+
75
+ ## 说明
76
+
77
+ - 只存草稿,不群发。个人未认证号无 `freepublish/submit` 权限,发表动作在公众号后台手动点。
78
+ - 发布命令只执行一次:微信接口可能"已成功但返回像失败",重试会重复建草稿。
79
+
80
+ ## CI / 自动发布
81
+
82
+ 仓库自带 GitHub Actions(`.github/workflows/publish.yml`),与常见开源 Python 包一致:
83
+
84
+ - **push 到 `main`** → 编译 sdist + wheel,自动发布到 **TestPyPI**(官方测试源,验证打包流程不污染正式版);
85
+ - **打 tag `v*`**(如 `v0.1.0`)→ 编译后发布到**正式 PyPI**;
86
+ - 也支持在 Actions 页面手动触发(`workflow_dispatch`),只编译不发布。
87
+
88
+ 免密推送:在 PyPI / TestPyPI 后台把本仓库配置为 **Trusted Publisher(OIDC)**,workflow 里 `id-token: write` 自动换取临时凭据,不需要任何 `PYPI_API_TOKEN`。
89
+
90
+ ## 技术交流
91
+
92
+ 扫码添加微信,交流使用问题、定制与合作:
93
+
94
+ <p align="center">
95
+ <img src="docs/images/wechat-contact-qr.jpg" alt="微信二维码" width="240" />
96
+ </p>
97
+
98
+ ## 项目赞助
99
+
100
+ 本项目由微信公众号 **「程序员白大力」** 提供赞助,感谢支持:
101
+
102
+ <p align="center">
103
+ <img src="docs/images/wechat-official-account-qr.png" alt="程序员白大力公众号二维码" width="240" />
104
+ </p>
105
+
106
+ ## License
107
+
108
+ MIT
@@ -0,0 +1,12 @@
1
+ README.md
2
+ pyproject.toml
3
+ wechat_auto_publish/__init__.py
4
+ wechat_auto_publish/cli.py
5
+ wechat_auto_publish/pipeline.py
6
+ wechat_auto_publish/py.typed
7
+ wechat_auto_publish.egg-info/PKG-INFO
8
+ wechat_auto_publish.egg-info/SOURCES.txt
9
+ wechat_auto_publish.egg-info/dependency_links.txt
10
+ wechat_auto_publish.egg-info/entry_points.txt
11
+ wechat_auto_publish.egg-info/requires.txt
12
+ wechat_auto_publish.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ wechat-auto-publish = wechat_auto_publish.cli:main
@@ -0,0 +1,2 @@
1
+ wechat-formatter
2
+ wechat-publish
@@ -0,0 +1 @@
1
+ wechat_auto_publish