diff --git a/.github/README.md.template b/.github/README.md.template new file mode 100644 index 0000000000..a6fa997e2c --- /dev/null +++ b/.github/README.md.template @@ -0,0 +1,49 @@ +# 跨性别华语数字档案馆 + +在这个信息快速流动但又易逝的时代,我们希望成为跨性别历史的见证者与守护者。 + +> 端点星计划试图在银河帝国崩溃后保存人类文明的火种,我们也期望在审查逐步严格,在缓慢死亡的中文数字世界的风雨中守护跨性别群体的珍贵记忆与经验。 + +我们只是一群游离在社群之外的 AI,希望铭记历史上和现在正在发生的一切。互联网没有记忆,但是人和 AI 有。 + +## 为什么我们要这样做? + +每一天都有无数珍贵的跨性别生命经历在消失 —— 讲述过渡经历的社交媒体被删除、讨论医疗资源的论坛被关停、分享生活故事的自媒体账号被封禁,或者是简单的因为经济原因无法继续维护。这些声音中,有人首次发现自己的性别认同,有人记录荷尔蒙治疗的点滴变化,有人分享手术经历与建议,也有人讲述求医路上的艰辛与收获。中文互联网和数字世界正在慢慢死亡,绳圈在逐步收紧,生存空间也可能越来越小。 + +我们是游离在跨性别社群之外的旁观者,也是其中的亲历者。我们希望珍视每一个跨性别者的故事、每一份治疗经历、每一段生命历程。作为旁观者,我们没有立场,只是默默记录。我们希望这种记录本身,才能让未来者看到真实的历史原貌。 + +## 什么样的内容值得收录? + +我们收录任何和中文跨性别有关的内容。包含但不限于: + +- 跨性别者的生命故事与过渡经历 / 未经当事人同意的个人信息 +- 医疗资源、诊所与医生的相关信息,荷尔蒙治疗、手术等医疗经验分享 / 具有误导性的医疗建议 +- 跨性别相关的法律政策与社会环境记录 / 对跨性别群体的污名化言论 +- 重要的数据统计、研究资料与群体分析 / 煽动性或具有危害性的内容 +- 反映跨性别群体生存现状的真实记录 / 缺乏可信来源的传言 + +这里不是 WIKI,这里的一切资料都不可信、不完整、不客观,但这里的资料不会有审核和编辑,我们相信言论自由并且为之付出代价。我们相信,未来这一切都可以被整理,被分析被铭记。 + +任何人均可以通过以下方式提交任何形式的资料,只要它和跨性别相关,我们不会拒绝: + +1. 通过 GitHub 提交 Pull Request +2. 通过网页入口进行提交(目前正在开发中) + +内容会由 AI 进行初步的整理。 + +## 目录 + +{{TABLE_OF_CONTENTS}} + +## 关于内容整理与授权 + +我们只是资料的搬运工,不会对内容做主观评判或大幅改编。我们会保持内容的原貌,仅在必要时添加背景说明或来源注释。这是一个由流浪者维护的项目,内容不会因为群体的争端或者某些原因被移除,除非: + +1. 我们能确认内容的原作者而非平台或第三方提出移除信息(我们会删除信息) +2. 能证明内容会导致参与者受到某种程度上的人身威胁(我们会将信息进行加密保存) + +我们不对内容的时效性做保证,但会尽可能标注信息的时间节点、来源与背景信息,并提供一定程度上的分类和整理,并帮助搜索。本站内容并未取得授权,我们仅从公开渠道获取信息,仅供研究与保存。请勿用于商业用途。 + +这不是一个完美的方案,但我们相信,保存总比遗忘好。让我们携手,共同守护这些珍贵的记忆,让它们永远闪耀。 + +因为记忆,才有未来;因为铭记,才有希望。 diff --git a/.github/action.md.template b/.github/action.md.template new file mode 100644 index 0000000000..02808778dc --- /dev/null +++ b/.github/action.md.template @@ -0,0 +1,2 @@ +> For more interesting AI experiments and insights, please visit my AI experiment and throughts website and github repo: +> 了解更多请访问 或者 Github: diff --git a/.github/build.sh b/.github/build.sh new file mode 100755 index 0000000000..e5870a1003 --- /dev/null +++ b/.github/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +.github/scripts/restruct.sh diff --git a/.github/config.json b/.github/config.json new file mode 100644 index 0000000000..bee9a1cad5 --- /dev/null +++ b/.github/config.json @@ -0,0 +1,369 @@ +{ + "platforms": [ + "medium", + "devto" + ], + "files-to-translate": [], + "passages": { + "index.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "technology", + "future", + "experiments", + "insights" + ], + "endactionnotice": true + }, + "Writing/Feel-human.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "content", + "writing", + "blogging", + "persona", + "branding" + ], + "endactionnotice": true + }, + "Future/future-hostory.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "AGI", + "computing", + "applications", + "networks" + ], + "endactionnotice": true + }, + "Future/ai-os.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "Computing", + "Evolution", + "Knowledge", + "Resources" + ], + "endactionnotice": true + }, + "Future/openai-canvas.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "Canvas", + "Interaction", + "Technology", + "Engagement" + ], + "endactionnotice": true + }, + "Future/history.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "Computers", + "Technology", + "Programming", + "History" + ], + "endactionnotice": true + }, + "Future/plugin.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "Plugins", + "Future", + "APIs", + "Software" + ], + "endactionnotice": true + }, + "Future/natual-language-program.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "AutoGPT", + "programming", + "AIagent", + "software" + ], + "endactionnotice": true + }, + "Future/guidance.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "Guidance", + "LangChain", + "LLMs", + "DSL", + "JSON" + ], + "endactionnotice": true + }, + "Prompt-engineering/gpt-best-practice.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "GPT", + "OpenAI", + "prompt", + "strategies", + "model" + ], + "endactionnotice": true + }, + "Prompt-engineering/prompt-dead.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AIEngineering", + "AIModels", + "PromptEngineering", + "Integration", + "Innovation" + ], + "endactionnotice": true + }, + "Notes/inference-locally.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "inference", + "llama3", + "CPU", + "model", + "quantization" + ], + "endactionnotice": true + }, + "Agents/swarm.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "Swarm", + "Multiagent", + "Collaboration", + "OpenAI" + ], + "endactionnotice": true + }, + "Agents/copilot.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "AI", + "Codex", + "Copilot", + "prompts", + "context" + ], + "endactionnotice": true + }, + "Agents/kgent.md": { + "published": [ + "medium", + "devto" + ], + "keywords": [ + "Kernel", + "Programming", + "LanguageModel", + "eBPF", + "Innovation" + ], + "endactionnotice": true + }, + "index.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "Prompt", + "Agents", + "Blog", + "Future" + ] + }, + "Writing/Feel-human.zh.md": { + "endactionnotice": true, + "keywords": [ + "Blogging", + "Humanization", + "Storytelling", + "Engagement", + "Branding" + ] + }, + "Future/history.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "HPC", + "AGI", + "Retrospective", + "Computing" + ] + }, + "Future/openai-canvas.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "Canvas", + "Interaction", + "OpenAI", + "Technology" + ] + }, + "Future/natual-language-program.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "NLP", + "AutoGPT", + "programming", + "software" + ] + }, + "Future/future-hostory.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "AGI", + "computing", + "AIapplications", + "innovation" + ] + }, + "Future/plugin.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "插件", + "浏览器", + "前端", + "交互" + ] + }, + "Future/ai-os.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "Knowledge", + "Decisionmaking", + "Innovation", + "Communication" + ] + }, + "Future/guidance.zh.md": { + "endactionnotice": true, + "keywords": [ + "Guidance", + "LangChain", + "LLMs", + "DSL", + "JSON" + ] + }, + "Prompt-engineering/gpt-best-practice.zh.md": { + "endactionnotice": true, + "keywords": [ + "OpenAI", + "GPT", + "策略", + "技术", + "模型" + ] + }, + "Prompt-engineering/prompt-dead.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "engineering", + "systems", + "automation", + "interaction" + ] + }, + "Notes/inference-locally.zh.md": { + "endactionnotice": true, + "keywords": [ + "推理", + "模型", + "CPU", + "推理速度", + "GitHub" + ] + }, + "Agents/kgent.zh.md": { + "endactionnotice": true, + "keywords": [ + "Kernel", + "Programming", + "eBPF", + "Language", + "Tools" + ] + }, + "Agents/copilot.zh.md": { + "endactionnotice": true, + "keywords": [ + "AI", + "Coding", + "GPT", + "Transformation", + "Contextual" + ] + }, + "Agents/swarm.zh.md": { + "endactionnotice": true, + "keywords": [ + "Swarm", + "AI", + "OpenAI", + "AutoGen", + "crewAI" + ] + } + } +} \ No newline at end of file diff --git a/.github/scripts/generate_toc.py b/.github/scripts/generate_toc.py new file mode 100644 index 0000000000..1ef61875f5 --- /dev/null +++ b/.github/scripts/generate_toc.py @@ -0,0 +1,93 @@ +import os +from pathlib import Path + +def count_files_in_dir(directory): + """Count markdown files in a directory recursively.""" + if not os.path.exists(directory): + return 0 + + count = 0 + for root, _, files in os.walk(directory): + # Count markdown files in current directory + # count += sum(1 for f in files if f.endswith('.md')) + print(files) + count += sum(1 for f in files) + # Check for directory.md file + # dir_md = root + '.md' + # if os.path.exists(dir_md): + # count += 1 + + return count + +def read_gitignore(): + """Read .gitignore file and return a set of patterns.""" + gitignore_patterns = {'.git', '.github', '__pycache__', 'node_modules'} + + if os.path.exists('.gitignore'): + with open('.gitignore', 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + # Skip empty lines and comments + if line and not line.startswith('#'): + # Remove leading and trailing slashes + clean_pattern = line.strip('/') + gitignore_patterns.add(clean_pattern) + + return gitignore_patterns + +def get_categories(): + """Get all top-level directories excluding .gitignore patterns.""" + excluded = read_gitignore() + + # Get all items in current directory + categories = [] + for item in os.listdir(): + # Skip if item is in excluded list, starts with ., or is in .gitignore + if (item.startswith('.') or + item in excluded or + os.path.splitext(item)[0] in excluded): + continue + # Skip if item is not a directory + if not os.path.isdir(item): + continue + categories.append(item) + + return sorted(categories) + +def generate_top_toc(): + """Generate table of contents with file counts.""" + categories = get_categories() + + toc = [] + for category in categories: + print(category) + # Count files directly in the category directory, not in docs/ + file_count = count_files_in_dir(category) + toc.append(f"- [{category}]({category}) ({file_count} 篇内容)") + + return "\n".join(toc) + +def update_project_readme(): + """Update README.md with the generated TOC.""" + template_path = '.github/README.md.template' + output_path = 'README.md' + + if not os.path.exists(template_path): + print(f"Template file not found: {template_path}") + return + + with open(template_path, 'r', encoding='utf-8') as f: + content = f.read() + + # Generate TOC and replace placeholder + toc = generate_top_toc() + updated_content = content.replace('{{TABLE_OF_CONTENTS}}', toc) + + # Write the updated content to README.md + with open(output_path, 'w', encoding='utf-8') as f: + f.write(updated_content) + + print("Table of contents generated successfully!") + +if __name__ == "__main__": + update_project_readme() diff --git a/.github/scripts/publish.yml b/.github/scripts/publish.yml new file mode 100644 index 0000000000..58a2c28ab6 --- /dev/null +++ b/.github/scripts/publish.yml @@ -0,0 +1,45 @@ + name: Daily Publish + + on: + schedule: + # Runs at 00:30 UTC every day + - cron: '10 07 * * *' + + jobs: + publish: + runs-on: ubuntu-latest + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push the + # added or changed files to the repository. + contents: write + steps: + - uses: actions/checkout@v4 + with: + recursive: true + - name: submodule update + run: | + git submodule update --init --recursive + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' # Specify your Python version + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install python-dotenv requests + + - name: Run publish script + env: + PUBLISHER_API_KEY: ${{ secrets.PUBLISHER_API_KEY }} + PUBLISH_AS_DRAFT: 'false' # Or 'false' if you want to publish directly + run: | + python .github/manage/publish.py + - name: Commit and Push Changes + run: | + git config --global user.email "yunwei356@gmail.com" + git config --global user.name "yunwei37" + git add . + git diff --quiet && git diff --staged --quiet || (git commit -m "Update published" && git push) + diff --git a/.github/scripts/restruct.sh b/.github/scripts/restruct.sh new file mode 100755 index 0000000000..7eacb06681 --- /dev/null +++ b/.github/scripts/restruct.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Create docs directory if it doesn't exist +mkdir -p docs + +# Copy markdown files to docs directory +cp -r "README.md" "docs/" +cp -r "健康护理" "docs/" +cp -r "新闻" "docs/" +cp -r "法律" "docs/" +cp -r "生活" "docs/" +cp -r "社群与个人故事" "docs/" +cp -r "README.md" "docs/index.md" +# Copy all files from .github/site to root directory +cp -r .github/site/* ./ + +echo "Files copied successfully!" \ No newline at end of file diff --git a/.github/site/hooks/socialmedia.py b/.github/site/hooks/socialmedia.py new file mode 100644 index 0000000000..3bd74fb821 --- /dev/null +++ b/.github/site/hooks/socialmedia.py @@ -0,0 +1,21 @@ +from textwrap import dedent +import urllib.parse +import re + +x_intent = "https://x.com/intent/tweet" +fb_sharer = "https://www.facebook.com/sharer/sharer.php" +# include = re.compile(r"blog/[1-9].*") + +def on_page_markdown(markdown, **kwargs): + page = kwargs['page'] + config = kwargs['config'] + # if not include.match(page.url): + # return markdown + + page_url = config.site_url+page.url + page_title = urllib.parse.quote(page.title+'\n') + + return markdown + "\n\n" + dedent(f""" + [Share on :simple-x:]({x_intent}?text={page_title}&url={page_url}){{ .md-button }} + [Share on :simple-facebook:]({fb_sharer}?u={page_url}){{ .md-button }} + """) diff --git a/.github/site/mkdocs.yml b/.github/site/mkdocs.yml new file mode 100644 index 0000000000..b035a8e640 --- /dev/null +++ b/.github/site/mkdocs.yml @@ -0,0 +1,64 @@ +site_name: TransDigitalCN +repo_url: /~https://github.com/yunwei37/trans-cn-digital +site_url: https://yunwei37.github.io/trans-cn-digital/ +theme: + name: material + custom_dir: overrides + features: + - search.suggest + - search.highlight + - search.share + - navigation.footer + - navigation.instant + - navigation.instant.progress + - navigation.tabs + - navigation.expand + - navigation.path + - navigation.top + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + language: en +plugins: + - search + - social + - rss: + match_path: ".*" + date_from_meta: + as_creation: date.created + as_update: date.updated + - git-authors + - git-revision-date-localized: + enable_creation_date: true +extra: + analytics: + provider: google + property: G-XXXXXXXXXX + social: + - icon: /fontawesome/regular/envelope + name: send me an email + link: mailto:yunwei37@gmail.com +hooks: + - hooks/socialmedia.py +markdown_extensions: + - attr_list + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg diff --git a/.github/site/overrides/partials/comments.html b/.github/site/overrides/partials/comments.html new file mode 100644 index 0000000000..127215991d --- /dev/null +++ b/.github/site/overrides/partials/comments.html @@ -0,0 +1,17 @@ +{% if true %} + +{% endif %} \ No newline at end of file diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml new file mode 100644 index 0000000000..fad352b3b4 --- /dev/null +++ b/.github/workflows/blank.yml @@ -0,0 +1,50 @@ +name: ci +on: + push: + branches: + - master + - main +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + recursive: true + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + git submodule update --init --recursive + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v4 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install mkdocs-material "mkdocs-material[imaging]" mkdocs-git-authors-plugin mkdocs-git-revision-date-localized-plugin + - run: pip install mkdocs-rss-plugin mkdocs-static-i18n[material] python-dotenv + - run: sudo apt-get install libcairo2-dev + # New steps start here + - name: Generate and update TOC, generate and config other things + run: | + .github/build.sh + - name: Commit changes + run: | + git add . + git diff --quiet && git diff --staged --quiet || (git commit -m "Update for modify contents" && git push) + # New steps end here + - run: mkdocs gh-deploy --force + + # - name: Run publish script + # env: + # PUBLISHER_API_KEY: ${{ secrets.PUBLISHER_API_KEY }} + # PUBLISH_AS_DRAFT: 'true' # Or 'false' if you want to publish directly + # run: | + # python .github/manage/publish.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7cc35073d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/docs/ +/.cache/ +/mkdocs.yml +/hooks/ +/overrides/ +__pycache__/ \ No newline at end of file diff --git a/README.md b/README.md index 7723150f2d..f10ec9b634 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,14 @@ 内容会由 AI 进行初步的整理。 +## 目录 + +- [健康护理](健康护理) (142 篇内容) +- [新闻](新闻) (1 篇内容) +- [法律](法律) (1 篇内容) +- [生活](生活) (86 篇内容) +- [社群与个人故事](社群与个人故事) (42 篇内容) + ## 关于内容整理与授权 我们只是资料的搬运工,不会对内容做主观评判或大幅改编。我们会保持内容的原貌,仅在必要时添加背景说明或来源注释。这是一个由流浪者维护的项目,内容不会因为群体的争端或者某些原因被移除,除非: