import requests import json import os import subprocess import sys from datetime import datetime from dotenv import load_dotenv load_dotenv() lang_list = ['en','zh-TW','ja', 'ko', 'fr', 'de', 'es', 'it', 'nl', 'pl', 'pt', 'ru', 'tr', 'vi', 'zh-CN'] def run_git_command(command): try: result = subprocess.run(command, shell=True, capture_output=True, text=True, cwd="/app") if result.returncode != 0: print(f"Git command failed: {command}") print(f"Error: {result.stderr}") return False return True except Exception as e: print(f"Error running git command: {e}") return False def clean_untracked_files(): print("Cleaning up untracked files that might cause conflicts...") try: status_result = subprocess.run("git status --porcelain", shell=True, capture_output=True, text=True, cwd="/app") if status_result.stdout.strip(): untracked_files = [] for line in status_result.stdout.strip().split('\n'): if line.startswith('??'): untracked_files.append(line[3:]) if untracked_files: print(f"Found {len(untracked_files)} untracked files, removing them...") for file_path in untracked_files: if os.path.exists(file_path): os.remove(file_path) print(f"Removed: {file_path}") return True except Exception as e: print(f"Error cleaning untracked files: {e}") return False def setup_git_repo(): git_repo_url = os.environ.get('GIT_REPO_URL') git_username = os.environ.get('GIT_USERNAME') git_email = os.environ.get('GIT_EMAIL') git_branch = os.environ.get('GIT_BRANCH', 'main') github_token = os.environ.get('GITHUB_TOKEN') if not all([git_repo_url, git_username, git_email]): print("Git environment variables not set. Skipping Git operations.") return False if not os.path.exists("/app/.git"): print("Initializing Git repository...") if not run_git_command("git init"): return False if github_token and git_repo_url.startswith('https://'): print("Using GitHub Personal Access Token for authentication...") auth_url = git_repo_url.replace('https://', f'https://{git_username}:{github_token}@') if not run_git_command(f"git remote add origin {auth_url}"): return False else: if not run_git_command(f"git remote add origin {git_repo_url}"): return False if not run_git_command(f"git checkout -b {git_branch}"): return False print("Checking if remote repository has content...") fetch_result = subprocess.run("git fetch origin", shell=True, capture_output=True, text=True, cwd="/app") if fetch_result.returncode == 0: print("Remote repository found, checking for conflicts...") ls_remote = subprocess.run("git ls-remote --heads origin main", shell=True, capture_output=True, text=True, cwd="/app") if ls_remote.stdout.strip(): print("Remote main branch exists, resetting to remote state...") clean_untracked_files() run_git_command("git fetch origin") run_git_command("git reset --hard origin/main") else: print("Remote main branch doesn't exist, creating initial commit...") run_git_command("git add .") run_git_command("git commit -m 'Initial commit'") else: print("Could not fetch from remote, creating initial commit...") run_git_command("git add .") run_git_command("git commit -m 'Initial commit'") else: if github_token and git_repo_url.startswith('https://'): print("Updating remote URL with authentication...") auth_url = git_repo_url.replace('https://', f'https://{git_username}:{github_token}@') if not run_git_command(f"git remote set-url origin {auth_url}"): return False print("Repository already exists, fetching latest changes...") if not run_git_command("git fetch origin"): print("Warning: Could not fetch from remote") else: print("Checking if we need to reset to remote state...") local_commit = subprocess.run("git rev-parse HEAD", shell=True, capture_output=True, text=True, cwd="/app") remote_commit = subprocess.run("git rev-parse origin/main", shell=True, capture_output=True, text=True, cwd="/app") if local_commit.returncode == 0 and remote_commit.returncode == 0: if local_commit.stdout.strip() != remote_commit.stdout.strip(): print("Local and remote are different, resetting to remote state...") clean_untracked_files() run_git_command("git reset --hard origin/main") run_git_command(f"git config user.name '{git_username}'") run_git_command(f"git config user.email '{git_email}'") if github_token: run_git_command("git config credential.helper store") return True def verify_git_remote(): result = subprocess.run("git remote -v", shell=True, capture_output=True, text=True, cwd="/app") if result.returncode != 0: print("Error checking Git remote configuration") return False remote_output = result.stdout.strip() if not remote_output: print("No Git remote configured") return False print(f"Git remote configuration: {remote_output}") return True def handle_git_conflicts(): print("Handling potential Git conflicts...") try: print("Fetching latest changes from remote...") if not run_git_command("git fetch origin"): print("Warning: Could not fetch from remote") return False print("Resetting to remote state to resolve conflicts...") if not run_git_command("git reset --hard origin/main"): print("Warning: Could not reset to remote state") return False print("Re-applying language file changes...") return True except Exception as e: print(f"Error handling Git conflicts: {e}") return False def commit_and_push_changes(): if not os.path.exists("/app/.git"): return False if not verify_git_remote(): print("Git remote not properly configured") return False try: run_git_command("git add .") run_git_command("git commit -m 'Update language files'") github_token = os.environ.get('GITHUB_TOKEN') if github_token: git_repo_url = os.environ.get('GIT_REPO_URL') git_username = os.environ.get('GIT_USERNAME') if git_repo_url.startswith('https://'): auth_url = git_repo_url.replace('https://', f'https://{git_username}:{github_token}@') print(f"Setting authenticated remote URL: {auth_url}") run_git_command(f"git remote set-url origin {auth_url}") print("Updated Git remote configuration:") run_git_command("git remote -v") print("Attempting to push changes...") push_result = subprocess.run("git push origin HEAD", shell=True, capture_output=True, text=True, cwd="/app") if push_result.returncode == 0: print("Changes committed and pushed to Git repository") return True else: print(f"Push failed: {push_result.stderr}") if "rejected" in push_result.stderr and "fetch first" in push_result.stderr: print("Remote has changes, attempting to resolve conflicts...") if handle_git_conflicts(): print("Retrying push after resolving conflicts...") if run_git_command("git push origin HEAD"): print("Changes successfully pushed after resolving conflicts") return True return False except Exception as e: print(f"Error pushing to Git: {e}") return False def download_and_compare_json(lang): url = f"https://highschool.stg.g123-cpp.com/1/g123/i18n/{lang}/texts/source_schooltest_1.json" try: response = requests.get(url) response.raise_for_status() new_data = response.json() except requests.RequestException as e: print(f"Error downloading JSON: {e}") return except json.JSONDecodeError as e: print(f"Error parsing JSON: {e}") return old_data = {} if os.path.exists(f"{lang}.json"): try: with open(f"{lang}.json", "r", encoding="utf-8") as f: old_data = json.load(f) except (json.JSONDecodeError, FileNotFoundError): print(f"Warning: Could not read existing {lang}.json, treating as empty") diff_lines = [] diff_lines.append(f"--- {lang}.json") diff_lines.append(f"+++ {lang}.json") diff_lines.append("") all_keys = sorted(set(old_data.keys()) | set(new_data.keys())) for key in all_keys: if key not in old_data: diff_lines.append(f"+{key}: {json.dumps(new_data[key], ensure_ascii=False)}") elif key not in new_data: diff_lines.append(f"-{key}: {json.dumps(old_data[key], ensure_ascii=False)}") elif old_data[key] != new_data[key]: diff_lines.append(f"-{key}: {json.dumps(old_data[key], ensure_ascii=False)}") diff_lines.append(f"+{key}: {json.dumps(new_data[key], ensure_ascii=False)}") with open(f"{lang}.json", "w", encoding="utf-8") as f: json.dump(new_data, f, indent=2, ensure_ascii=False) if len(diff_lines) > 3: with open(f"{lang}.diff", "w", encoding="utf-8") as f: f.write("\n".join(diff_lines)) print(f"Changes detected: {len(diff_lines) - 3} lines affected") print(f"Diff saved to {lang}.diff") else: print("No changes detected") print(f"New data saved to {lang}.json ({len(new_data)} keys)") if __name__ == "__main__": git_enabled = setup_git_repo() for lang in lang_list: download_and_compare_json(lang) if git_enabled: commit_and_push_changes()