feat: daily collection 6/12 - new docs, industry report, .gitignore cleanup

- Collected 9 new messages from dc group and innovation group
- Fetched 6 new Feishu docs (黄静雯/陈楚真/韦译/夏莲/莫润麟/张家振)
- Downloaded 狱国争霸分析拆解.html file attachment
- Saved 6/12 game industry daily report from 韩丹
- Updated .gitignore to exclude temp scripts, images, downloaded files
- Added utility scripts (group members extraction, invitation generation)
This commit is contained in:
Evilom
2026-06-12 10:32:24 +08:00
parent 3b77605591
commit 64ac71a8ed
9 changed files with 1453 additions and 9 deletions
+97
View File
@@ -0,0 +1,97 @@
"""批量生成邀请函图片:读取 invitation_config.json 模板 + group_members_with_account.csv"""
import csv
import json
import os
import sys
from PIL import Image, ImageDraw, ImageFont
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "data")
BG_PATH = os.path.join(DATA_DIR, "bg.png")
FONT_DIR = DATA_DIR
CONFIG_PATH = os.path.join(DATA_DIR, "invitation_config.json")
CSV_PATH = os.path.join(DATA_DIR, "group_members_with_account.csv")
OUTPUT_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "output", "invitations")
def hex_to_rgb(h):
h = h.lstrip('#')
return tuple(int(h[i:i+2], 16) for i in (0, 2, 4))
def resolve_font(name):
local = os.path.join(FONT_DIR, name)
if os.path.isfile(local):
return local
sys_font = os.path.join(r"C:\Windows\Fonts", name)
if os.path.isfile(sys_font):
return sys_font
return os.path.join(FONT_DIR, "WenDaoGeTeSong.ttf")
def generate_image(cfg, name, account, password):
img = Image.open(BG_PATH).copy()
draw = ImageDraw.Draw(img)
font_path = resolve_font(cfg.get("font", "WenDaoGeTeSong.ttf"))
sw = cfg.get("stroke_width", 3)
sc = hex_to_rgb(cfg.get("stroke_color", "#000000"))
size = cfg.get("size", 30)
font = ImageFont.truetype(font_path, size)
color = hex_to_rgb(cfg.get("color", "#ffffff"))
x = cfg.get("x", 510)
y = cfg.get("y", 1055)
text = cfg.get("text", "")
text = text.replace("{name}", name).replace("{account}", account).replace("{password}", password)
line_height = cfg.get("line_height", 1.5)
spacing = int(size * (line_height - 1.0))
align = cfg.get("align", "center")
anchor_map = {"left": "lt", "center": "mt", "right": "rt"}
anchor = anchor_map.get(align, "mt")
lines = text.split("\n")
cur_y = y
for line in lines:
draw.text(
(x, cur_y), line, fill=color, font=font, anchor=anchor,
stroke_width=sw, stroke_fill=sc
)
cur_y += size + spacing
return img
def main():
with open(CONFIG_PATH, encoding="utf-8") as f:
cfg = json.load(f)
with open(CSV_PATH, encoding="utf-8") as f:
rows = list(csv.DictReader(f))
os.makedirs(OUTPUT_DIR, exist_ok=True)
total = 0
skipped = 0
for row in rows:
name = row.get("姓名", "").strip()
account = row.get("账号", "").strip()
password = row.get("密码", "").strip()
if not account or not password:
skipped += 1
continue
img = generate_image(cfg, name, account, password)
output_path = os.path.join(OUTPUT_DIR, f"invite_{account}.jpg")
img.convert("RGB").save(output_path, format="JPEG", quality=75)
total += 1
print(f"Done. Generated {total} images, skipped {skipped} (missing account/password).")
print(f"Output: {OUTPUT_DIR}")
if __name__ == "__main__":
main()