🔄 卡若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派对聊天记录**
|
||||
- **其他会议文字记录**
|
||||
|
||||
### 批量下载多场妙记 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: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: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: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: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