| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #!/usr/bin/env python3
- """Publish a CSV/XLS/XLSX file as a Feishu online spreadsheet."""
- from __future__ import annotations
- import argparse
- import json
- import os
- import sys
- from pathlib import Path
- from feishu_client import FeishuPublisher
- def build_parser() -> argparse.ArgumentParser:
- parser = argparse.ArgumentParser(
- description=(
- "将 CSV/XLS/XLSX 导入飞书在线表格,设置任何人可编辑,"
- "并可发送到群聊。"
- )
- )
- parser.add_argument("file", nargs="?", help="待发布的数据文件")
- parser.add_argument("--title", help="在线表格和消息卡片标题")
- parser.add_argument("--message", default="数据查询结果已生成,请点击查看。")
- target = parser.add_mutually_exclusive_group()
- target.add_argument("--chat-id", help="目标飞书群 chat_id")
- target.add_argument("--chat-name", help="机器人可见群中的精确群名")
- parser.add_argument("--no-notify", action="store_true", help="只创建表格,不发群消息")
- parser.add_argument("--dry-run", action="store_true", help="仅校验本地输入,不调用飞书 API")
- parser.add_argument("--list-chats", action="store_true", help="只读列出机器人可见群聊")
- parser.add_argument("--name", default="", help="配合 --list-chats 按名称模糊过滤")
- return parser
- def print_json(value: object) -> None:
- print(json.dumps(value, ensure_ascii=False, indent=2))
- def main() -> int:
- args = build_parser().parse_args()
- try:
- if args.list_chats:
- with FeishuPublisher.from_env() as publisher:
- token = publisher.tenant_access_token()
- print_json(publisher.list_chats(token, args.name))
- return 0
- if not args.file:
- raise ValueError("必须提供结果文件,或使用 --list-chats")
- file_path = Path(args.file).expanduser().resolve()
- extension = FeishuPublisher.validate_file(file_path)
- title = (args.title or file_path.stem).strip()
- if not title:
- raise ValueError("表格标题不能为空")
- chat_id = (
- args.chat_id
- if args.chat_id is not None
- else os.getenv("FEISHU_TARGET_CHAT_ID", "")
- ).strip()
- chat_name = (
- args.chat_name
- if args.chat_name is not None
- else os.getenv("FEISHU_TARGET_CHAT_NAME", "")
- ).strip()
- notify = not args.no_notify
- if notify and not chat_id and not chat_name:
- raise ValueError(
- "未配置目标群;请使用 --chat-id/--chat-name 或设置 "
- "FEISHU_TARGET_CHAT_ID/FEISHU_TARGET_CHAT_NAME"
- )
- if args.dry_run:
- print_json(
- {
- "dry_run": True,
- "file": str(file_path),
- "file_extension": extension,
- "title": title,
- "permission": "anyone_editable",
- "notify": notify,
- "target": chat_id or chat_name,
- }
- )
- return 0
- with FeishuPublisher.from_env() as publisher:
- result = publisher.publish(
- file_path,
- title=title,
- message=args.message,
- chat_id=chat_id,
- chat_name=chat_name,
- notify=notify,
- )
- print_json(result)
- return 0
- except Exception as exc:
- print(f"发布失败:{exc}", file=sys.stderr)
- return 1
- if __name__ == "__main__":
- raise SystemExit(main())
|