mirror of
https://github.com/luongnv89/claude-howto.git
synced 2026-04-26 09:56:01 +02:00
Add Vietnamese (Tiếng Việt) Localization (#42)
* feat(i18n): add Vietnamese localization infrastructure Add comprehensive infrastructure for Vietnamese translation of the claude-howto documentation: Features: - Parallel vi/ directory structure for Vietnamese content - Modified build_epub.py with --lang flag for Vietnamese EPUB - Vietnamese-specific pre-commit hooks for quality checks - Translation support files (glossary, style guide, queue tracker) - sync_translations.py script to detect outdated translations Infrastructure: - vi/ directory with all 10 module subdirectories - TRANSLATION_NOTES.md: comprehensive glossary and style guide - TRANSLATION_QUEUE.md: progress tracking for 66+ files - vi/README.md: Vietnamese landing page EPUB Build: - Added --lang CLI flag (en/vi) to build_epub.py - Language-specific metadata (title, subtitle) - Automatic root path adjustment for vi/ directory - Dynamic output filename (claude-howto-guide-vi.epub) Quality Assurance: - Vietnamese markdown linting - Vietnamese cross-reference checking - Vietnamese Mermaid syntax validation - Vietnamese link checking - Vietnamese EPUB build validation Ready for translation work to begin. * feat(vi): translate INDEX.md to Vietnamese Complete Vietnamese translation of INDEX.md - the comprehensive index of all example files in the repository. Translation follows vi/TRANSLATION_NOTES.md guidelines: - Technical terms kept per glossary (slash command → "lệnh slash") - File paths and code blocks preserved in English - Table structure and formatting maintained - All 882 lines translated Content includes: - Complete file tree (10 modules, 100+ files) - Feature coverage matrix - Quick start guides by use case - Learning path progression - Search by keyword sections Progress: 1/5 core documents completed * feat(vi): translate CATALOG.md to Vietnamese Complete Vietnamese translation of CATALOG.md - the quick reference guide to all Claude Code features. Translation follows vi/TRANSLATION_NOTES.md guidelines: - Technical terms kept per glossary (slash command → "lệnh slash") - All command names preserved (/help, /optimize, etc.) - Code blocks, JSON examples, and bash commands unchanged - All tables and formatting maintained - 517 lines translated with complete feature coverage Content includes: - Summary statistics (99 built-in + 43 examples = 117 total) - Complete built-in commands reference (55+ commands) - Custom commands examples (8 commands) - Permission modes (6 modes) - Subagents (6 built-in + 10 custom) - Skills (5 bundled + 4 custom) - Plugins (3 complete plugins) - MCP servers (1 built-in + 8 common servers) - Hooks (25 events + 7 example hooks) - Memory files (7 types) - New features (March 2026) - 17 new features - Installation priority guide - Complete one-command installation Progress: 2/5 core documents completed * docs(vi): translate learning roadmap to Vietnamese - Add complete Vietnamese translation of LEARNING-ROADMAP.md (747 lines) - Include self-assessment quiz for level determination - Translate three learning levels: Beginner, Intermediate, Advanced - Translate all milestones (1A, 1B, 2A, 2B, 3A, 3B) with hands-on exercises - Preserve Mermaid diagram for learning path visualization - Maintain progress tracking checklists and learning tips * docs(vi): translate quick reference guide to Vietnamese - Add complete Vietnamese translation of QUICK_REFERENCE.md (507 lines) - Include installation quick commands for all features - Translate feature cheat sheet with usage examples - Translate common use cases (code review, documentation, DevOps, etc.) - Preserve all code snippets, commands, and file paths in English - Maintain file locations reference diagram - Include learning path and new features (March 2026) sections - Keep tips & tricks, feature matrix, and checklist intact * docs(vi): translate module 01 - slash commands to Vietnamese - Add complete Vietnamese translation of 01-slash-commands/README.md (553 lines) - Translate slash commands overview and architecture - Include 55+ built-in commands reference table with Vietnamese descriptions - Translate bundled skills section (5 skills) - Document custom commands (now skills) migration path - Include frontmatter reference, arguments, and dynamic context sections - Preserve all command names, code examples, and Mermaid diagrams - Translate 8 available commands in folder with usage examples - Include installation, troubleshooting, and best practices sections * docs(vi): update translation queue progress - Module 01 README done - Mark 01-slash-commands/README.md as completed (2026-04-02) - Update Module 01 progress: 1/9 files (11%) - Update overall progress: 6/66 files (9%) - Update Priority 2 progress: 1/31 files (3%) - Add recent completion note to queue header * docs(vi): translate slash command - commit to Vietnamese - Translate commit.md slash command to Vietnamese - Keep all git commands and technical syntax intact - Translate instructions and descriptions - Maintain conventional commits format documentation * docs(vi): translate slash command - doc-refactor to Vietnamese - Translate doc-refactor.md slash command to Vietnamese - Keep all technical terms and file paths intact - Translate documentation refactoring instructions - Maintain structure and numbering * docs(vi): translate slash command - generate-api-docs to Vietnamese - Translate generate-api-docs.md slash command to Vietnamese - Keep all technical terms and file paths intact - Translate API documentation generation instructions - Maintain output format specifications * docs(vi): translate slash command - optimize to Vietnamese - Translate optimize.md slash command to Vietnamese - Keep all technical terms and code concepts intact - Translate code optimization instructions - Maintain issue priority and response format * docs(vi): translate slash command - pr to Vietnamese - Translate pr.md slash command to Vietnamese - Keep all commands and technical syntax intact - Translate PR preparation checklist instructions - Maintain conventional commits format documentation * docs(vi): translate slash command - push-all to Vietnamese - Translate push-all.md slash command to Vietnamese (153 lines) - Keep all git commands and technical syntax intact - Translate comprehensive workflow with safety checks - Maintain API key validation patterns and error handling - Preserve when to use/avoid sections and alternatives * docs(vi): translate slash command - setup-ci-cd to Vietnamese - Translate setup-ci-cd.md slash command to Vietnamese - Keep all tool names and technical terms intact - Translate CI/CD pipeline implementation instructions - Maintain pre-commit hooks and GitHub Actions sections * docs(vi): translate slash command - unit-test-expand to Vietnamese - Translate unit-test-expand.md slash command to Vietnamese - Keep all framework names and technical terms intact - Translate test coverage expansion instructions - Maintain testing frameworks and scenario sections * docs(vi): update translation queue - Module 01 complete (100%) - Mark all 9 Module 01 files as completed (2026-04-02) - Update Module 01 progress: 9/9 files (100%) ✅ - Update overall progress: 14/66 files (21%) - Update Priority 2 progress: 9/31 files (29%) - Update header with Module 01 completion milestone Module 01: Slash Commands - All files translated: ✅ README.md (overview, built-in commands, skills) ✅ commit.md (git commit with context) ✅ doc-refactor.md (documentation restructuring) ✅ generate-api-docs.md (API documentation generator) ✅ optimize.md (code optimization analysis) ✅ pr.md (pull request preparation) ✅ push-all.md (stage, commit, push with safety) ✅ setup-ci-cd.md (CI/CD pipeline implementation) ✅ unit-test-expand.md (test coverage expansion) * docs(vi): translate module 02 - memory guide to Vietnamese - Add complete Vietnamese translation of 02-memory/README.md (1162 lines) - Translate memory system overview and architecture - Include quick reference for memory commands (/init, /memory, #) - Document complete memory hierarchy (8 levels with precedence) - Translate auto memory section with architecture diagrams - Include practical examples (project, directory-specific, personal memory) - Add best practices, installation instructions, and troubleshooting - Preserve all code examples, file paths, and technical terms - Maintain Mermaid diagrams and tables * docs(vi): translate example project CLAUDE.md to Vietnamese - Translate project-CLAUDE.md example memory file - Keep all technical terms, commands, and code style intact - Translate descriptions and explanations - Maintain project configuration structure * docs(vi): translate example personal CLAUDE.md to Vietnamese - Translate personal-CLAUDE.md example memory file - Keep all technical terms, tools, and preferences intact - Translate descriptions and explanations - Maintain personal preferences structure * docs(vi): translate example directory-specific CLAUDE.md to Vietnamese - Translate directory-api-CLAUDE.md example memory file - Keep all technical terms, API standards, and code examples intact - Translate descriptions and explanations - Maintain API module standards structure * docs(vi): update translation queue - Module 02 complete (100%) - Mark all 4 Module 02 files as completed (2026-04-02) - Update Module 02 progress: 4/4 files (100%) ✅ - Update overall progress: 18/66 files (27%) - Update Priority 2 progress: 13/31 files (42%) - Update header with Module 02 completion milestone Module 02: Memory - All files translated: ✅ README.md (1162 lines - comprehensive memory guide) ✅ project-CLAUDE.md (example project memory) ✅ personal-CLAUDE.md (example personal preferences) ✅ directory-api-CLAUDE.md (example directory-specific rules) * docs(vi): translate module 03 - skills guide to Vietnamese - Add complete Vietnamese translation of 03-skills/README.md (805 lines) - Translate Agent Skills overview and architecture - Include progressive disclosure loading mechanism (3 levels) - Document skill types, locations, and automatic discovery - Translate skill creation process and SKILL.md format - Include required and optional frontmatter fields - Document skill content types (reference vs task) - Translate controlling skill invocation and string substitutions - Include dynamic context injection with shell commands - Document running skills in subagents with context: fork - Translate 6 practical examples with directory structures - Add supporting files, management, and best practices sections - Preserve all code examples, YAML frontmatter, and Mermaid diagrams - Maintain tables, troubleshooting guides, and security considerations * docs(vi): translate skill - blog-draft to Vietnamese - Translate blog-draft/SKILL.md to Vietnamese (275 lines) - Keep all workflow steps and technical structure intact - Translate instructions and descriptions - Maintain version tracking and file structure - Preserve all markdown formatting and code examples * docs(vi): translate skill - brand-voice to Vietnamese - Translate brand-voice/SKILL.md to Vietnamese (73 lines) - Keep brand identity, tone, and vocabulary intact - Translate writing guidelines and examples - Maintain preferred/avoided terms sections - Preserve good/bad examples with explanations * docs(vi): translate skill - claude-md to Vietnamese - Translate claude-md/SKILL.md to Vietnamese (213 lines) - Keep all golden rules and core principles intact - Translate execution flow and content strategy - Maintain WHAT/WHY/HOW structure - Preserve quality constraints and validation checklist - Keep anti-patterns and output format sections * docs(vi): translate skill - code-review to Vietnamese - Translate code-review/SKILL.md to Vietnamese (71 lines) - Keep all review categories and template intact - Translate security, performance, quality, maintainability sections - Maintain review template structure - Preserve version history * docs(vi): translate skill - refactor to Vietnamese - Translate refactor/SKILL.md to Vietnamese (427 lines) - Keep all Martin Fowler refactoring methodology intact - Translate 6-phase workflow with detailed steps - Maintain core principles and safety rules - Preserve code smell catalog and refactoring techniques - Keep quick start example with before/after code - Maintain version history and references sections * docs(vi): update translation queue - Module 03 complete (100%) - Mark all 6 Module 03 files as completed (2026-04-02) - Update Module 03 progress: 6/6 files (100%) ✅ - Update overall progress: 24/66 files (36%) - Update Priority 2 progress: 19/31 files (61%) - Update header with Module 03 completion milestone Module 03: Skills - All files translated: ✅ README.md (805 lines - comprehensive skills guide) ✅ blog-draft/SKILL.md (275 lines - blog post creation workflow) ✅ brand-voice/SKILL.md (73 lines - brand voice consistency) ✅ claude-md/SKILL.md (213 lines - CLAUDE.md best practices) ✅ code-review/SKILL.md (71 lines - comprehensive code review) ✅ refactor/SKILL.md (427 lines - Fowler refactoring methodology) * docs(vi): translate Module 04 Subagents README Complete Vietnamese translation of subagents reference guide: - Configuration and built-in subagents (general-purpose, Plan, Explore, Bash, statusline-setup, Claude Code Guide) - Agent management with /agents command - Automatic delegation vs explicit invocation - Resumable agents and chaining - Persistent memory across agent sessions - Background subagents for parallel work - Worktree isolation for safe experimentation - Agent Teams (experimental feature) - Best practices and usage patterns * docs(vi): complete Module 04 Subagents translation Translate all 6 subagent example definitions: - code-reviewer.md: Expert code review specialist - debugger.md: Root cause analysis and debugging - documentation-writer.md: Technical documentation creation - implementation-agent.md: Full-stack feature implementation - secure-reviewer.md: Security-focused code review - test-engineer.md: Comprehensive test coverage Update translation queue progress: - Module 04: 7/7 files (100%) ✅ - Overall: 31/66 files (47%) - Next: Module 05 (MCP) * docs(vi): complete Module 05 MCP translation Translate comprehensive MCP (Model Context Protocol) guide: - Overview and architecture diagrams - Installation methods (HTTP, Stdio, SSE, WebSocket) - OAuth 2.0 authentication support - MCP tool search and dynamic updates - Elicitation and prompt slash commands - Configuration management (local, project, user scopes) - Practical examples (GitHub, Database, Filesystem, Slack MCPs) - MCP vs Memory decision matrix - Code execution approach for solving context bloat - MCPorter runtime reference - Security best practices and troubleshooting Translate 4 MCP configuration JSON examples: - filesystem-mcp.json: File operations - github-mcp.json: GitHub integration - database-mcp.json: SQL queries - multi-mcp.json: Multiple servers configuration Update translation queue progress: - Module 05: 5/5 files (100%) ✅ - Overall: 36/66 files (55%) - Next: Module 06 (Hooks) * docs(vi): complete Module 06 Hooks translation Translate comprehensive Hooks guide: - Overview and architecture - Configuration structure (user, project, local scopes) - Four hook types: command, HTTP, prompt, agent - 25 hook events with matcher patterns - Component-scoped hooks and subagent frontmatter - JSON input/output format and exit codes - Environment variables and best practices - Security considerations and debugging - Installation instructions Copy 9 hook example files (code, no translation needed): - format-code.sh: Auto-format code after write/edit - log-bash.sh: Bash command logging - notify-team.sh: Team notifications - pre-commit.sh: Pre-commit validation - security-scan.sh: Security scanning - validate-prompt.sh: Prompt validation - context-tracker.py: Token usage tracking - context-tracker-tiktoken.py: Accurate token counting Update translation queue progress: - Module 06: 9/9 files (100%) ✅ - Overall: 45/67 files (67%) - Next: Module 07 (Plugins) * docs(vi): complete Module 07 Plugins translation Translate comprehensive Plugins guide: - Overview and architecture diagrams - Plugin loading process and lifecycle - Plugin types (Official, Community, Organization, Personal) - Plugin definition structure and manifest - Plugin structure example with all directories - LSP server configuration and examples - Plugin options (v2.1.83+) with userConfig - Persistent plugin data via CLAUDE_PLUGIN_DATA - Inline plugins via settings (v2.1.80+) - Standalone vs Plugin approach comparison - Practical examples (PR Review, DevOps, Documentation plugins) - Plugin marketplace and distribution - Marketplace configuration and definition schema - Plugin source types and distribution methods - Plugin CLI commands and installation methods - Plugin features comparison table - Testing, hot-reload, and managed settings - Plugin security restrictions - Publishing workflow and best practices - Complete troubleshooting guide Copy all plugin subdirectories (code, no translation needed): - devops-automation/: Deployment workflows, incident management - documentation/: API docs, README generation, templates - pr-review/: Pull request review automation Update translation queue progress: - Module 07: 10+/10+ files (100%) ✅ - Overall: 55+/67 files (82%) - Next: Module 08-10 (Checkpoints, Advanced Features, CLI) * docs(vi): complete Modules 08-10 translation Module 08: Checkpoints and Rewind (2 files) - Overview and architecture - Access methods (keyboard shortcut, slash command) - Five rewind options (restore code+conversation, conversation, code, summarize, cancel) - Automatic checkpoints and retention policies - Use cases and practical examples - Integration with git and best practices Module 09: Advanced Features (3 files) - Planning Mode: Two-phase implementation approach - Extended Thinking: Deep reasoning for complex problems - Auto Mode: Background safety classifier - Background Tasks, Scheduled Tasks - Permission Modes (default, acceptEdits, plan, auto, dontAsk, bypassPermissions) - Print Mode, Session Management - Voice Dictation, Channels, Remote Control - Web Sessions, Desktop App, Task List - Git Worktrees, Sandboxing, Managed Settings Module 10: CLI Reference (1 file) - CLI commands reference - Core flags and options - Interactive vs Print Mode - Model selection and configuration - System prompt customization - Tool & permission management - Output formats and scripting Update translation queue progress: - Modules 08-10: 6/6 files (100%) ✅ - All Modules 01-10: 61+/61+ files (100%) ✅ - Overall: 61+/67 files (91%) - Remaining: Supporting docs (6 files) * docs(vi): complete supporting documentation translation Translate all 5 supporting documents: - CONTRIBUTING.md: Contribution guidelines - SECURITY.md: Security policy and vulnerability reporting - CODE_OF_CONDUCT.md: Community standards and harassment policy - STYLE_GUIDE.md: Documentation formatting conventions - CHANGELOG.md: Version history (v2.2.0, v2.1.1, v2.1.0, v2.0.0) Update translation queue to 100% completion: - All Modules 01-10: 61+ files (100%) ✅ - Supporting Docs: 5/5 files (100%) ✅ - Overall: 67+/67 files (100%) ✅ - Status: HOÀN THÀNH ✅ * fix(vi): fix mermaid syntax and broken cross-references in Vietnamese translation Fix invalid `#` comment in mermaid block (use `%%` instead) and update cross-reference script to support Unicode/Vietnamese diacritics in anchor generation. Fix broken anchor links across vi/ documentation files. * fix(vi): remove inline mermaid comment causing parse error Inline %% comments on node definition lines are not supported by the mermaid parser. The surrounding HTML comment already explains this is an incorrect example.
This commit is contained in:
+30
-6
@@ -116,6 +116,12 @@ class EPUBConfig:
|
||||
language: str = "en"
|
||||
author: str = "Claude Code Community"
|
||||
|
||||
# Language-specific metadata
|
||||
vi_title: str = "Hướng Dẫn Claude Code"
|
||||
vi_subtitle: str = "Làm chủ Claude Code trong một cuối tuần"
|
||||
en_title: str = "Claude Code How-To Guide"
|
||||
en_subtitle: str = "Master Claude Code in a Weekend"
|
||||
|
||||
# Cover Settings
|
||||
cover_width: int = 600
|
||||
cover_height: int = 900
|
||||
@@ -1029,23 +1035,41 @@ def main() -> int:
|
||||
default=10,
|
||||
help="Maximum concurrent API requests (default: 10)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lang",
|
||||
type=str,
|
||||
default="en",
|
||||
choices=["en", "vi"],
|
||||
help="Language code: 'en' for English, 'vi' for Vietnamese (default: en)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Determine root path
|
||||
root = args.root
|
||||
if root is None:
|
||||
# Default to parent of scripts directory (repo root)
|
||||
root = Path(__file__).parent.parent
|
||||
# Determine root path and language-specific settings
|
||||
repo_root = args.root if args.root else Path(__file__).parent.parent
|
||||
repo_root = repo_root.resolve()
|
||||
|
||||
# Set language-specific paths and metadata
|
||||
if args.lang == "vi":
|
||||
root = repo_root / "vi"
|
||||
output = args.output or (repo_root / "claude-howto-guide-vi.epub")
|
||||
title = EPUBConfig.vi_title
|
||||
language = "vi"
|
||||
else:
|
||||
root = repo_root
|
||||
output = args.output or (repo_root / "claude-howto-guide.epub")
|
||||
title = EPUBConfig.en_title
|
||||
language = "en"
|
||||
|
||||
root = root.resolve()
|
||||
output = args.output or (root / "claude-howto-guide.epub")
|
||||
output = output.resolve()
|
||||
|
||||
logger = setup_logging(args.verbose)
|
||||
config = EPUBConfig(
|
||||
root_path=root,
|
||||
output_path=output,
|
||||
language=language,
|
||||
title=title,
|
||||
request_timeout=args.timeout,
|
||||
max_concurrent_requests=args.max_concurrent,
|
||||
)
|
||||
|
||||
@@ -27,10 +27,27 @@ def iter_md_files():
|
||||
|
||||
|
||||
def heading_to_anchor(heading: str) -> str:
|
||||
# Match GitHub's anchor generation: strip non-ASCII (emoji), strip punctuation,
|
||||
# lowercase, replace spaces with hyphens, strip leading/trailing hyphens.
|
||||
heading_ascii = heading.encode("ascii", "ignore").decode()
|
||||
return re.sub(r"[^\w\s-]", "", heading_ascii.lower()).replace(" ", "-").rstrip("-")
|
||||
# Match GitHub's anchor generation: strip emoji and special punctuation,
|
||||
# keep Unicode letters (including Vietnamese diacritics), lowercase,
|
||||
# replace spaces with hyphens, strip leading/trailing hyphens.
|
||||
# 1. Remove emoji (characters outside BMP or in known emoji ranges)
|
||||
heading = re.sub(
|
||||
r"[\U0001F000-\U0001FFFF" # Supplementary Multilingual Plane symbols
|
||||
r"\U00002702-\U000027B0" # Dingbats
|
||||
r"\U0000FE00-\U0000FE0F" # Variation selectors
|
||||
r"\U0000200D" # Zero-width joiner
|
||||
r"\U000000A9\U000000AE" # (C) (R)
|
||||
r"\U00002000-\U0000206F" # General punctuation (some emoji-adjacent)
|
||||
r"]",
|
||||
"",
|
||||
heading,
|
||||
)
|
||||
# 2. Remove punctuation but keep Unicode word chars, spaces, and hyphens
|
||||
anchor = re.sub(r"[^\w\s-]", "", heading.lower(), flags=re.UNICODE)
|
||||
# 3. Replace spaces with hyphens
|
||||
anchor = anchor.replace(" ", "-")
|
||||
# 4. Strip trailing hyphens (keep leading hyphens for emoji-prefixed headings)
|
||||
return anchor.rstrip("-")
|
||||
|
||||
|
||||
def strip_code_blocks(content: str) -> str:
|
||||
|
||||
Executable
+251
@@ -0,0 +1,251 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Detect outdated Vietnamese translations compared to English version.
|
||||
|
||||
This script compares modification times between English and Vietnamese
|
||||
documentation files to identify which translations need updating.
|
||||
|
||||
Usage:
|
||||
python scripts/sync_translations.py
|
||||
python scripts/sync_translations.py --verbose
|
||||
"""
|
||||
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def check_translation_status(root_path: Path = None, verbose: bool = False) -> list[dict]:
|
||||
"""
|
||||
Compare modification times between English and Vietnamese files.
|
||||
|
||||
Args:
|
||||
root_path: Root directory of the repository (default: script parent parent)
|
||||
verbose: Print detailed information
|
||||
|
||||
Returns:
|
||||
List of outdated files with metadata
|
||||
"""
|
||||
if root_path is None:
|
||||
root_path = Path(__file__).parent.parent
|
||||
|
||||
# Get all English markdown files (excluding vi/ directory)
|
||||
en_files = [
|
||||
f for f in root_path.rglob("*.md")
|
||||
if "vi/" not in str(f) and ".claude" not in str(f)
|
||||
]
|
||||
|
||||
# Get all Vietnamese markdown files
|
||||
vi_dir = root_path / "vi"
|
||||
vi_files = list(vi_dir.rglob("*.md")) if vi_dir.exists() else []
|
||||
|
||||
# Build modification time mapping
|
||||
en_mtime = {f: f.stat().st_mtime for f in en_files}
|
||||
vi_mtime = {f: f.stat().st_mtime for f in vi_files}
|
||||
|
||||
outdated = []
|
||||
not_translated = []
|
||||
|
||||
for en_file, en_time in sorted(en_mtime.items()):
|
||||
# Find corresponding Vietnamese file
|
||||
try:
|
||||
rel_path = en_file.relative_to(root_path)
|
||||
except ValueError:
|
||||
# File is not relative to root (shouldn't happen)
|
||||
if verbose:
|
||||
print(f"⚠️ Skipping non-relative file: {en_file}")
|
||||
continue
|
||||
|
||||
vi_file = root_path / "vi" / rel_path
|
||||
|
||||
if vi_file in vi_mtime:
|
||||
vi_time = vi_mtime[vi_file]
|
||||
if en_time > vi_time:
|
||||
outdated.append({
|
||||
"file": rel_path,
|
||||
"en_mtime": datetime.fromtimestamp(en_time),
|
||||
"vi_mtime": datetime.fromtimestamp(vi_time),
|
||||
"days_diff": (en_time - vi_time) / 86400, # Convert to days
|
||||
})
|
||||
else:
|
||||
not_translated.append({
|
||||
"file": rel_path,
|
||||
"status": "NOT_TRANSLATED",
|
||||
})
|
||||
|
||||
# Sort outdated by days difference (most outdated first)
|
||||
outdated.sort(key=lambda x: x["days_diff"], reverse=True)
|
||||
|
||||
return outdated, not_translated
|
||||
|
||||
|
||||
def format_outdated_table(outdated: list[dict]) -> str:
|
||||
"""Format outdated files as a Markdown table."""
|
||||
if not outdated:
|
||||
return "✅ **No outdated translations found!** All files are up to date.\n"
|
||||
|
||||
table = "### 🕰️ Outdated Translations (Need Update)\n\n"
|
||||
table += "| File | Last EN Update | Last VI Update | Days Behind |\n"
|
||||
table += "|------|----------------|----------------|-------------|\n"
|
||||
|
||||
for item in outdated:
|
||||
file_path = str(item["file"])
|
||||
en_date = item["en_mtime"].strftime("%Y-%m-%d")
|
||||
vi_date = item["vi_mtime"].strftime("%Y-%m-%d")
|
||||
days = int(item["days_diff"])
|
||||
|
||||
# Truncate long paths for display
|
||||
if len(file_path) > 50:
|
||||
file_path = "..." + file_path[-47:]
|
||||
|
||||
table += f"| `{file_path}` | {en_date} | {vi_date} | 🔴 **{days} days** |\n"
|
||||
|
||||
return table
|
||||
|
||||
|
||||
def format_not_translated_table(not_translated: list[dict]) -> str:
|
||||
"""Format not translated files as a Markdown table."""
|
||||
if not not_translated:
|
||||
return "\n✅ **All files have been translated!**\n"
|
||||
|
||||
table = "\n### 📝 Not Translated Yet\n\n"
|
||||
table += "| File | Status |\n"
|
||||
table += "|------|--------|\n"
|
||||
|
||||
for item in not_translated:
|
||||
file_path = str(item["file"])
|
||||
|
||||
# Truncate long paths for display
|
||||
if len(file_path) > 60:
|
||||
file_path = "..." + file_path[-57:]
|
||||
|
||||
table += f"| `{file_path}` | ⏳ **Not translated** |\n"
|
||||
|
||||
return table
|
||||
|
||||
|
||||
def format_summary(outdated: list[dict], not_translated: list[dict]) -> str:
|
||||
"""Format summary statistics."""
|
||||
total_outdated = len(outdated)
|
||||
total_not_translated = len(not_translated)
|
||||
total_files = total_outdated + total_not_translated
|
||||
|
||||
summary = "## 📊 Summary\n\n"
|
||||
summary += f"- **Total files needing attention:** {total_files}\n"
|
||||
summary += f"- **Outdated translations:** {total_outdated}\n"
|
||||
summary += f"- **Not translated yet:** {total_not_translated}\n"
|
||||
|
||||
if total_outdated > 0:
|
||||
most_outdated = max(outdated, key=lambda x: x["days_diff"])
|
||||
summary += f"- **Most outdated file:** {most_outdated['file']} ({int(most_outdated['days_diff'])} days behind)\n"
|
||||
|
||||
summary += "\n---\n\n"
|
||||
|
||||
return summary
|
||||
|
||||
|
||||
def update_translation_queue(
|
||||
root_path: Path,
|
||||
outdated: list[dict],
|
||||
not_translated: list[dict]
|
||||
) -> None:
|
||||
"""
|
||||
Update vi/TRANSLATION_QUEUE.md with current status.
|
||||
|
||||
Note: This is a placeholder for future implementation.
|
||||
Currently, the queue is manually maintained.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Check Vietnamese translation status against English version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--verbose", "-v",
|
||||
action="store_true",
|
||||
help="Print detailed information"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--root", "-r",
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Root directory of repository (default: auto-detect)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--update-queue",
|
||||
action="store_true",
|
||||
help="Update TRANSLATION_QUEUE.md with current status (experimental)"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Detect root path if not provided
|
||||
root_path = args.root or Path(__file__).parent.parent
|
||||
|
||||
if args.verbose:
|
||||
print(f"🔍 Checking translations in: {root_path}")
|
||||
print()
|
||||
|
||||
# Check translation status
|
||||
outdated, not_translated = check_translation_status(root_path, args.verbose)
|
||||
|
||||
# Print summary to console
|
||||
print("=" * 60)
|
||||
print("🌏 Vietnamese Translation Status Report")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
total_outdated = len(outdated)
|
||||
total_not_translated = len(not_translated)
|
||||
|
||||
if total_outdated == 0 and total_not_translated == 0:
|
||||
print("✅ **Congratulations!** All files are up to date.")
|
||||
print()
|
||||
return
|
||||
|
||||
print(f"📊 Found {total_outdated} outdated + {total_not_translated} not translated files")
|
||||
print()
|
||||
|
||||
if args.verbose and outdated:
|
||||
print("🕰️ OUTDATED FILES (need update):")
|
||||
print("-" * 60)
|
||||
for i, item in enumerate(outdated, 1):
|
||||
print(f"{i}. {item['file']}")
|
||||
print(f" EN: {item['en_mtime'].strftime('%Y-%m-%d %H:%M')}")
|
||||
print(f" VI: {item['vi_mtime'].strftime('%Y-%m-%d %H:%M')}")
|
||||
print(f" Behind by: {int(item['days_diff'])} days")
|
||||
print()
|
||||
|
||||
if args.verbose and not_translated:
|
||||
print("📝 NOT TRANSLATED FILES:")
|
||||
print("-" * 60)
|
||||
for i, item in enumerate(not_translated[:20], 1): # Limit to 20
|
||||
print(f"{i}. {item['file']}")
|
||||
|
||||
if len(not_translated) > 20:
|
||||
print(f"... and {len(not_translated) - 20} more files")
|
||||
print()
|
||||
|
||||
# Print Markdown-formatted report
|
||||
print("=" * 60)
|
||||
print("📄 Markdown Report (copy to TRANSLATION_QUEUE.md)")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
report = format_summary(outdated, not_translated)
|
||||
report += format_outdated_table(outdated)
|
||||
report += format_not_translated_table(not_translated)
|
||||
|
||||
print(report)
|
||||
|
||||
# Optionally update TRANSLATION_QUEUE.md
|
||||
if args.update_queue:
|
||||
if args.verbose:
|
||||
print("⚠️ --update-queue is experimental and not yet implemented")
|
||||
print(" Please manually update TRANSLATION_QUEUE.md")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user