🔄 卡若AI 同步 2026-02-16 06:02 | 变更 6 个文件 | 排除 >20MB: 4 个
Some checks failed
Sync GitHub to CKB NAS Gitea / sync (push) Has been cancelled
Some checks failed
Sync GitHub to CKB NAS Gitea / sync (push) Has been cancelled
This commit is contained in:
@@ -172,6 +172,35 @@ python3 scripts/fetch_feishu_minutes.py --file "导出.txt" --title "产研团
|
|||||||
- **Soul派对聊天记录**
|
- **Soul派对聊天记录**
|
||||||
- **其他会议文字记录**
|
- **其他会议文字记录**
|
||||||
|
|
||||||
|
### 批量下载多场妙记 TXT(如「派对」「受」100 场)
|
||||||
|
|
||||||
|
飞书没有「妙记列表」API,需先拿到**妙记链接列表**,再批量拉取 TXT。
|
||||||
|
|
||||||
|
**步骤 1:得到 URL 列表文件 `urls.txt`**
|
||||||
|
|
||||||
|
- **方式 A(推荐)**:在飞书客户端或网页打开 **视频会议 → 妙记**,在列表里用搜索框输入「派对」或「受」(或「soul 派对」),得到筛选结果后,逐条点开每条记录,复制浏览器地址栏链接(形如 `https://cunkebao.feishu.cn/minutes/xxxxx`),每行一个粘贴到 `urls.txt`。
|
||||||
|
- **方式 B**:若列表页支持「复制链接」或导出,可一次性整理成每行一个 URL 的文本。
|
||||||
|
|
||||||
|
**步骤 2:批量下载 TXT**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/karuo/Documents/个人/卡若AI/02_卡人(水)/_团队成员/水桥/智能纪要/scripts
|
||||||
|
|
||||||
|
# 从 urls.txt 批量下载,TXT 保存到默认 output 目录
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt
|
||||||
|
|
||||||
|
# 指定输出目录(如 soul 派对 100 场)
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --output ./soul_party_100_txt
|
||||||
|
|
||||||
|
# 已下载过的跳过,避免重复
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --output ./soul_party_100_txt --skip-existing
|
||||||
|
|
||||||
|
# 先试跑前 3 条
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --limit 3
|
||||||
|
```
|
||||||
|
|
||||||
|
**说明**:脚本内部调用飞书妙记 API 拉取文字记录;若某条无「妙记文字记录」权限,该条会保存为仅含标题+时长的占位 TXT,可后续在妙记页手动「导出文字记录」后替换。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📤 飞书集成配置
|
## 📤 飞书集成配置
|
||||||
|
|||||||
57
02_卡人(水)/_团队成员/水桥/智能纪要/references/飞书妙记批量下载TXT说明.md
Normal file
57
02_卡人(水)/_团队成员/水桥/智能纪要/references/飞书妙记批量下载TXT说明.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# 飞书妙记批量下载 TXT 说明
|
||||||
|
|
||||||
|
> 场景:飞书妙记里已有多场带「派对」「受」等关键字的视频会议(如 soul 派对 100 场),需要把这批会议的文字记录**全部下载为 TXT**。
|
||||||
|
|
||||||
|
## 一、为什么不能「一键筛 100 场再导出」
|
||||||
|
|
||||||
|
- 飞书开放平台**没有**「妙记列表」或「按标题筛选妙记」的 API,只能通过**已知的妙记链接(minute_token)**逐条拉取。
|
||||||
|
- 因此流程是:**先拿到这批妙记的 URL 列表 → 再用脚本批量拉取 TXT**。
|
||||||
|
|
||||||
|
## 二、如何拿到 URL 列表(urls.txt)
|
||||||
|
|
||||||
|
### 方法 1:在飞书妙记列表里手动收集(推荐)
|
||||||
|
|
||||||
|
1. 打开飞书(客户端或网页)→ **视频会议** → **妙记**。
|
||||||
|
2. 在列表页的**搜索框**输入关键字,例如:`派对`、`受`、`soul 派对`,得到筛选后的列表。
|
||||||
|
3. 逐条点开每条记录,在浏览器地址栏复制链接(形如 `https://xxx.feishu.cn/minutes/xxxxxxxxxx`),粘贴到文本文件,**每行一个链接**,保存为 `urls.txt`。
|
||||||
|
4. 若使用飞书客户端,可尝试「在浏览器中打开」当前妙记,再复制地址栏。
|
||||||
|
|
||||||
|
### 方法 2:只写 minute_token(也可以)
|
||||||
|
|
||||||
|
若链接形式是 `https://cunkebao.feishu.cn/minutes/obcnjnsx2mz7vj5q843172p8`,脚本也支持在 `urls.txt` 里只写后半段 token,例如一行写 `obcnjnsx2mz7vj5q843172p8` 即可。
|
||||||
|
|
||||||
|
## 三、批量下载命令
|
||||||
|
|
||||||
|
在智能纪要脚本目录下执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/karuo/Documents/个人/卡若AI/02_卡人(水)/_团队成员/水桥/智能纪要/scripts
|
||||||
|
|
||||||
|
# 批量下载,输出到默认 output
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt
|
||||||
|
|
||||||
|
# 输出到指定目录(如 soul 派对 100 场)
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --output ./soul_party_100_txt
|
||||||
|
|
||||||
|
# 已存在同名 TXT 则跳过(断点续跑)
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --output ./soul_party_100_txt --skip-existing
|
||||||
|
|
||||||
|
# 先试跑 3 条
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --limit 3
|
||||||
|
```
|
||||||
|
|
||||||
|
## 四、输出说明
|
||||||
|
|
||||||
|
- 每条妙记会生成一个 TXT,文件名格式:`标题_日期.txt`(非法字符会替换为下划线)。
|
||||||
|
- 若应用没有「妙记文字记录」权限,该条会保存为仅含标题+时长的占位内容;可在飞书妙记页对该条手动「…」→「导出文字记录」后,用导出的文件覆盖或合并。
|
||||||
|
|
||||||
|
## 五、相关脚本
|
||||||
|
|
||||||
|
| 脚本 | 作用 |
|
||||||
|
|:---|:---|
|
||||||
|
| `batch_download_minutes_txt.py` | 从 urls.txt 批量拉取 TXT |
|
||||||
|
| `fetch_feishu_minutes.py` | 单条妙记链接 → 拉取并保存 TXT(被批量脚本复用) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**版本**:2026-02-16 | 归属:水桥 · 智能纪要
|
||||||
169
02_卡人(水)/_团队成员/水桥/智能纪要/scripts/batch_download_minutes_txt.py
Normal file
169
02_卡人(水)/_团队成员/水桥/智能纪要/scripts/batch_download_minutes_txt.py
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
飞书妙记批量下载 TXT 文字记录
|
||||||
|
|
||||||
|
从「URL 列表文件」批量拉取飞书妙记,将每场的文字记录保存为 TXT。
|
||||||
|
适用于:派对、受 等关键字筛选后的 100 场妙记一次性下载。
|
||||||
|
|
||||||
|
用法:
|
||||||
|
# 从 urls.txt 批量下载(每行一个妙记链接)
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt
|
||||||
|
|
||||||
|
# 指定输出目录
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --output ./soul_party_txt
|
||||||
|
|
||||||
|
# 跳过已存在的 TXT(按标题+日期判断)
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --skip-existing
|
||||||
|
|
||||||
|
# 仅试跑前 3 条
|
||||||
|
python3 batch_download_minutes_txt.py --list urls.txt --limit 3
|
||||||
|
|
||||||
|
如何得到 urls.txt:
|
||||||
|
1) 在飞书妙记列表页搜索「派对」「受」或「soul 派对」,逐个打开每条记录,复制地址栏链接到文本,每行一个。
|
||||||
|
2) 或用浏览器自动化在列表页抓取所有卡片的链接(需在已登录飞书的前提下)。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
SCRIPT_DIR = Path(__file__).parent
|
||||||
|
ROOT = SCRIPT_DIR.parent
|
||||||
|
OUTPUT_DIR = ROOT / "output"
|
||||||
|
|
||||||
|
# 导入单条拉取逻辑
|
||||||
|
sys.path.insert(0, str(SCRIPT_DIR))
|
||||||
|
from fetch_feishu_minutes import (
|
||||||
|
extract_minute_token,
|
||||||
|
fetch_and_save,
|
||||||
|
get_tenant_access_token,
|
||||||
|
get_minutes_info,
|
||||||
|
get_minutes_transcript,
|
||||||
|
get_minutes_speakers,
|
||||||
|
transcripts_to_text,
|
||||||
|
save_transcript,
|
||||||
|
format_timestamp,
|
||||||
|
OUTPUT_DIR as DEFAULT_OUTPUT_DIR,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def load_url_list(path: Path) -> list[str]:
|
||||||
|
"""从文件读取 URL 列表,每行一个,去掉空行和重复"""
|
||||||
|
if not path.exists():
|
||||||
|
return []
|
||||||
|
lines = path.read_text(encoding="utf-8", errors="ignore").strip().splitlines()
|
||||||
|
urls = []
|
||||||
|
seen = set()
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
# 兼容只写 minute_token 的情况
|
||||||
|
if line not in seen:
|
||||||
|
seen.add(line)
|
||||||
|
urls.append(line)
|
||||||
|
return urls
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="飞书妙记批量下载 TXT:从 URL 列表文件批量拉取文字记录"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--list", "-l",
|
||||||
|
type=str,
|
||||||
|
required=True,
|
||||||
|
help="URL 列表文件路径,每行一个妙记链接或 minute_token",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--output", "-o",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help=f"TXT 输出目录(默认: {OUTPUT_DIR})",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--skip-existing",
|
||||||
|
action="store_true",
|
||||||
|
help="若输出目录已存在同名 TXT 则跳过该条",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--limit", "-n",
|
||||||
|
type=int,
|
||||||
|
default=0,
|
||||||
|
help="仅处理前 N 条(0 表示全部)",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
list_path = Path(args.list)
|
||||||
|
if not list_path.is_absolute():
|
||||||
|
list_path = (Path.cwd() / args.list).resolve()
|
||||||
|
if not list_path.exists():
|
||||||
|
print(f"❌ 列表文件不存在: {list_path}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
output_dir = Path(args.output).resolve() if args.output else OUTPUT_DIR
|
||||||
|
output_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
print(f"📂 输出目录: {output_dir}")
|
||||||
|
|
||||||
|
urls = load_url_list(list_path)
|
||||||
|
if not urls:
|
||||||
|
print("❌ 列表文件中没有有效 URL")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if args.limit:
|
||||||
|
urls = urls[: args.limit]
|
||||||
|
print(f"⚠️ 仅处理前 {len(urls)} 条(--limit {args.limit})")
|
||||||
|
print(f"📋 共 {len(urls)} 条妙记待下载\n")
|
||||||
|
|
||||||
|
ok_count = 0
|
||||||
|
skip_count = 0
|
||||||
|
fail_count = 0
|
||||||
|
token = get_tenant_access_token()
|
||||||
|
if not token:
|
||||||
|
print("❌ 无法获取飞书访问令牌")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for i, url_or_token in enumerate(urls, 1):
|
||||||
|
minute_token = extract_minute_token(url_or_token)
|
||||||
|
print(f"[{i}/{len(urls)}] 妙记 token: {minute_token[:20]}...")
|
||||||
|
|
||||||
|
if args.skip_existing:
|
||||||
|
# 用 API 先取标题再判断文件是否已存在(避免重复请求)
|
||||||
|
info = get_minutes_info(token, minute_token)
|
||||||
|
if info:
|
||||||
|
title = info.get("title", "妙记")
|
||||||
|
safe_title = re.sub(r'[\\/*?:"<>|]', "_", title)
|
||||||
|
create_time = info.get("create_time", "")
|
||||||
|
if create_time:
|
||||||
|
try:
|
||||||
|
# 飞书 API 可能返回秒或毫秒时间戳,>1e10 视为毫秒
|
||||||
|
ts = int(create_time)
|
||||||
|
if ts > 1e10:
|
||||||
|
ts = ts // 1000
|
||||||
|
date_str = datetime.fromtimestamp(ts).strftime("%Y%m%d")
|
||||||
|
except Exception:
|
||||||
|
date_str = datetime.now().strftime("%Y%m%d")
|
||||||
|
else:
|
||||||
|
date_str = datetime.now().strftime("%Y%m%d")
|
||||||
|
existing = output_dir / f"{safe_title}_{date_str}.txt"
|
||||||
|
if existing.exists():
|
||||||
|
print(f" ⏭️ 已存在,跳过: {existing.name}")
|
||||||
|
skip_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
out = fetch_and_save(url_or_token, output_dir)
|
||||||
|
if out and out.exists():
|
||||||
|
ok_count += 1
|
||||||
|
else:
|
||||||
|
fail_count += 1
|
||||||
|
print("")
|
||||||
|
|
||||||
|
print("=" * 50)
|
||||||
|
print(f"✅ 成功: {ok_count} | ⏭️ 跳过: {skip_count} | ❌ 失败: {fail_count}")
|
||||||
|
print(f"📂 所有 TXT 保存在: {output_dir}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
33
_共享模块/scripts/wiki_init_ssh.sh
Executable file
33
_共享模块/scripts/wiki_init_ssh.sh
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 百科 SSH 初始化:在 NAS 上创建 karuo-ai.wiki.git 并推送 wiki_source 内容
|
||||||
|
# 当 API/HTTPS 无法初始化时用此脚本。需能 SSH 到 Gitea 所在主机。
|
||||||
|
|
||||||
|
REPO_DIR="/Users/karuo/Documents/个人/卡若AI"
|
||||||
|
WIKI_SRC="$REPO_DIR/_共享模块/wiki_source"
|
||||||
|
SSH_HOST="open.quwanzhi.com"
|
||||||
|
SSH_PORT="22201"
|
||||||
|
SSH_USER="fnvtk"
|
||||||
|
WIKI_PATH="/volume1/git/github/fnvtk/karuo-ai.wiki.git"
|
||||||
|
SSH_REMOTE="ssh://${SSH_USER}@${SSH_HOST}:${SSH_PORT}/${WIKI_PATH}"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
cd "$REPO_DIR"
|
||||||
|
|
||||||
|
# 1. SSH 创建 wiki bare 仓库(若不存在)
|
||||||
|
echo "在 NAS 上创建 wiki 仓库..."
|
||||||
|
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=15 -p "$SSH_PORT" "${SSH_USER}@${SSH_HOST}" \
|
||||||
|
"mkdir -p $WIKI_PATH && (test -f $WIKI_PATH/HEAD || (cd $WIKI_PATH && git init --bare))"
|
||||||
|
|
||||||
|
# 2. 本地建临时仓库并推送
|
||||||
|
TMP_WIKI=$(mktemp -d)
|
||||||
|
trap "rm -rf $TMP_WIKI" EXIT
|
||||||
|
cd "$TMP_WIKI"
|
||||||
|
git init -q
|
||||||
|
cp -f "$WIKI_SRC"/*.md . 2>/dev/null || true
|
||||||
|
git add -A
|
||||||
|
git commit -m "wiki init $(date '+%Y-%m-%d %H:%M')" --allow-empty -q
|
||||||
|
git remote add origin "$SSH_REMOTE"
|
||||||
|
git push -u origin master 2>/dev/null || { git branch -M main; git push -u origin main; }
|
||||||
|
|
||||||
|
echo "百科已通过 SSH 初始化并推送完成。"
|
||||||
|
exit 0
|
||||||
@@ -10,3 +10,4 @@
|
|||||||
| 2026-02-15 23:34:04 | 🔄 卡若AI 同步 2026-02-15 23:34 | 变更 7 个文件 | 排除 >20MB: 4 个 |
|
| 2026-02-15 23:34:04 | 🔄 卡若AI 同步 2026-02-15 23:34 | 变更 7 个文件 | 排除 >20MB: 4 个 |
|
||||||
| 2026-02-15 23:38:04 | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 7 个文件 | 排除 >20MB: 4 个 |
|
| 2026-02-15 23:38:04 | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 7 个文件 | 排除 >20MB: 4 个 |
|
||||||
| 2026-02-15 23:38:29 | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 4 个文件 | 排除 >20MB: 4 个 |
|
| 2026-02-15 23:38:29 | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 4 个文件 | 排除 >20MB: 4 个 |
|
||||||
|
| 2026-02-15 23:43:11 | 🔄 卡若AI 同步 2026-02-15 23:43 | 变更 5 个文件 | 排除 >20MB: 4 个 |
|
||||||
|
|||||||
@@ -13,3 +13,4 @@
|
|||||||
| 2026-02-15 23:34:04 | 成功 | 失败(百科未初始化或网络) | 🔄 卡若AI 同步 2026-02-15 23:34 | 变更 7 个文件 | 排除 >20MB: 4 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
| 2026-02-15 23:34:04 | 成功 | 失败(百科未初始化或网络) | 🔄 卡若AI 同步 2026-02-15 23:34 | 变更 7 个文件 | 排除 >20MB: 4 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||||
| 2026-02-15 23:38:04 | 成功 | 失败(百科未初始化或网络) | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 7 个文件 | 排除 >20MB: 4 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
| 2026-02-15 23:38:04 | 成功 | 失败(百科未初始化或网络) | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 7 个文件 | 排除 >20MB: 4 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||||
| 2026-02-15 23:38:29 | 成功 | 失败(百科未初始化或网络) | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 4 个文件 | 排除 >20MB: 4 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
| 2026-02-15 23:38:29 | 成功 | 失败(百科未初始化或网络) | 🔄 卡若AI 同步 2026-02-15 23:38 | 变更 4 个文件 | 排除 >20MB: 4 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||||
|
| 2026-02-15 23:43:11 | 成功 | 失败(百科未初始化或网络) | 🔄 卡若AI 同步 2026-02-15 23:43 | 变更 5 个文件 | 排除 >20MB: 4 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||||
|
|||||||
Reference in New Issue
Block a user