Jelajahi Sumber

[#1] Configure mirror repositories and dynamic git filter sanitization

This commit adds worldwide GitHub repository references to all guides and implements dynamic origin URL detail extraction and name sanitization in git-ident-filter.py.
Lange François 3 minggu lalu
induk
melakukan
2130fa44fb
35 mengubah file dengan 154 tambahan dan 53 penghapusan
  1. 9 1
      INSTALL_WSL.md
  2. TEMPAT SAMPAH
      Project.pdf
  3. 6 1
      README.md
  4. TEMPAT SAMPAH
      Retro Planning.pdf
  5. TEMPAT SAMPAH
      docs/Backup_Procedure.pdf
  6. TEMPAT SAMPAH
      docs/Data_Ingestion.pdf
  7. TEMPAT SAMPAH
      docs/Final_Report.pdf
  8. 2 2
      docs/Installation_Guide.md
  9. TEMPAT SAMPAH
      docs/Installation_Guide.pdf
  10. TEMPAT SAMPAH
      docs/Operator_Installation_Guide.pdf
  11. TEMPAT SAMPAH
      docs/Scrum_Artifacts.pdf
  12. TEMPAT SAMPAH
      docs/Scrum_Daily.pdf
  13. TEMPAT SAMPAH
      docs/Scrum_Plan.pdf
  14. TEMPAT SAMPAH
      docs/Scrum_Retro.pdf
  15. TEMPAT SAMPAH
      docs/Scrum_Review.pdf
  16. TEMPAT SAMPAH
      docs/Scrum_Wiki.pdf
  17. TEMPAT SAMPAH
      docs/Start_Stop_Procedures.pdf
  18. TEMPAT SAMPAH
      docs/Technical_Document.pdf
  19. TEMPAT SAMPAH
      docs/Test_Cases_Sprint8.pdf
  20. TEMPAT SAMPAH
      docs/URL_Formats.pdf
  21. TEMPAT SAMPAH
      docs/User_Description.pdf
  22. TEMPAT SAMPAH
      docs/User_Guide.pdf
  23. TEMPAT SAMPAH
      docs/WSL_Deployment.pdf
  24. TEMPAT SAMPAH
      docs/Wiki_Home.pdf
  25. TEMPAT SAMPAH
      docs/architecture.pdf
  26. TEMPAT SAMPAH
      docs/disaster_recovery_plan.pdf
  27. TEMPAT SAMPAH
      docs/distributed_deployment.pdf
  28. TEMPAT SAMPAH
      docs/docker_connection.pdf
  29. TEMPAT SAMPAH
      docs/project_report.pdf
  30. TEMPAT SAMPAH
      docs/retro_planning.pdf
  31. TEMPAT SAMPAH
      docs/taiga_audit_report.pdf
  32. TEMPAT SAMPAH
      docs/zabbix_monitoring.pdf
  33. 4 4
      generate_docs.py
  34. 41 45
      local_tools/git-ident-filter.py
  35. 92 0
      scratch/add_mirror_repos.py

+ 9 - 1
INSTALL_WSL.md

@@ -1,4 +1,4 @@
-The current version is #ident "@(#)$Format:LocalFoodAI:INSTALL_WSL.md:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+The current version is #ident "@(#)$Format:LocalFoodAI_lanfr144:INSTALL_WSL.md:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 
 # 🚀 WSL2 Port-Shifted Installation Guide (Local Food AI)
 
@@ -29,11 +29,19 @@ Ensure you have WSL2 enabled and are using an Ubuntu 24.04 shell instance.
 
 ### Step 2: Clone the Git Repository
 Run the following commands inside your WSL Ubuntu home directory to clone the project:
+
+**Primary Repository (Internal Network)**:
 ```bash
 git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git
 cd LocalFoodAI_lanfr144
 ```
 
+**Alternative Repository (Worldwide Access - Clone of the Primary)**:
+```bash
+git clone https://github.com/lanfr144/LocalFoodAI_lanfr144.git
+cd LocalFoodAI_lanfr144
+```
+
 ### Step 3: Setup Local Environment Variables
 Create the required `.env` file at the root of the repository to feed standard local credentials to the containers:
 Configure your database credentials, active network mode, and the target model name in a `.env` file at the root of the repository. A generic template is provided below:

TEMPAT SAMPAH
Project.pdf


+ 6 - 1
README.md

@@ -1,4 +1,4 @@
-The current version is #ident "@(#)$Format:LocalFoodAI:README.md:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+The current version is #ident "@(#)$Format:LocalFoodAI_lanfr144:README.md:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 
 # Local Food AI 🍔
 
@@ -38,7 +38,12 @@ This project is fully optimized to run on Windows Subsystem for Linux (WSL2) wit
    Navigate to the repository home directory inside WSL:
    ```bash
    cd ~
+   # Option A: Clone from the Primary Repository (Internal Network)
    git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git
+   
+   # Option B: Clone from the Alternative Repository (Worldwide Access - Clone)
+   # git clone https://github.com/lanfr144/LocalFoodAI_lanfr144.git
+   
    cd LocalFoodAI_lanfr144
    
    # Always ensure you are on the primary main branch:

TEMPAT SAMPAH
Retro Planning.pdf


TEMPAT SAMPAH
docs/Backup_Procedure.pdf


TEMPAT SAMPAH
docs/Data_Ingestion.pdf


TEMPAT SAMPAH
docs/Final_Report.pdf


+ 2 - 2
docs/Installation_Guide.md

@@ -118,8 +118,8 @@ q" | sudo ed /etc/wsl.conf
 ## 4. Repository Clones & Branch Governance
 
 There are two repositories configured for this project:
-- Production Repository: `https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`
-- GitHub Mirror (Clone): `https://github.com/lanfr144/LocalFoodAI_lanfr144`
+- Primary Git Repository: `https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`
+- Alternative Git Repository (Worldwide Access - Clone): `https://github.com/lanfr144/LocalFoodAI_lanfr144.git`
 
 Clone the primary repository inside your home directory:
 ```bash

TEMPAT SAMPAH
docs/Installation_Guide.pdf


TEMPAT SAMPAH
docs/Operator_Installation_Guide.pdf


TEMPAT SAMPAH
docs/Scrum_Artifacts.pdf


TEMPAT SAMPAH
docs/Scrum_Daily.pdf


TEMPAT SAMPAH
docs/Scrum_Plan.pdf


TEMPAT SAMPAH
docs/Scrum_Retro.pdf


TEMPAT SAMPAH
docs/Scrum_Review.pdf


TEMPAT SAMPAH
docs/Scrum_Wiki.pdf


TEMPAT SAMPAH
docs/Start_Stop_Procedures.pdf


TEMPAT SAMPAH
docs/Technical_Document.pdf


TEMPAT SAMPAH
docs/Test_Cases_Sprint8.pdf


TEMPAT SAMPAH
docs/URL_Formats.pdf


TEMPAT SAMPAH
docs/User_Description.pdf


TEMPAT SAMPAH
docs/User_Guide.pdf


TEMPAT SAMPAH
docs/WSL_Deployment.pdf


TEMPAT SAMPAH
docs/Wiki_Home.pdf


TEMPAT SAMPAH
docs/architecture.pdf


TEMPAT SAMPAH
docs/disaster_recovery_plan.pdf


TEMPAT SAMPAH
docs/distributed_deployment.pdf


TEMPAT SAMPAH
docs/docker_connection.pdf


TEMPAT SAMPAH
docs/project_report.pdf


TEMPAT SAMPAH
docs/retro_planning.pdf


TEMPAT SAMPAH
docs/taiga_audit_report.pdf


TEMPAT SAMPAH
docs/zabbix_monitoring.pdf


+ 4 - 4
generate_docs.py

@@ -1,9 +1,9 @@
-#ident "@(#)$Format:LocalFoodAI:generate_docs.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+#ident "@(#)$Format:LocalFoodAI_lanfr144:generate_docs.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 # $Id$
 # $Author$
 # $log$
 import os
-#ident "@(#)$Format:LocalFoodAI:generate_docs.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+#ident "@(#)$Format:LocalFoodAI_lanfr144:generate_docs.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 import subprocess
 
 docs_dir = "docs"
@@ -278,8 +278,8 @@ q" | sudo ed /etc/wsl.conf
 ## 4. Repository Clones & Branch Governance
 
 There are two repositories configured for this project:
-- Production Repository: `https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`
-- GitHub Mirror (Clone): `https://github.com/lanfr144/LocalFoodAI_lanfr144`
+- Primary Git Repository: `https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`
+- Alternative Git Repository (Worldwide Access - Clone): `https://github.com/lanfr144/LocalFoodAI_lanfr144.git`
 
 Clone the primary repository inside your home directory:
 ```bash

+ 41 - 45
local_tools/git-ident-filter.py

@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-#ident "@(#)$Format:LocalFoodAI:git-ident-filter.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+#ident "@(#)$Format:LocalFoodAI_lanfr144:git-ident-filter.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 import sys
 import os
 import subprocess
@@ -17,23 +17,44 @@ if hasattr(sys.stdin, 'reconfigure'):
 if hasattr(sys.stdout, 'reconfigure'):
     sys.stdout.reconfigure(newline='\n')
 
+# -----------------------------------------------------------------------------
 # -----------------------------------------------------------------------------
 # STEP 2: PARSE COMMAND LINE ARGUMENTS
 # -----------------------------------------------------------------------------
-# The Git configuration passes arguments to this script:
-# sys.argv[1] is either 'clean' or 'smudge' (determining execution mode)
-# sys.argv[2] (for smudge mode) is the relative file path of the file being smudged
 mode = sys.argv[1] if len(sys.argv) > 1 else "smudge"
 
 # -----------------------------------------------------------------------------
-# STEP 3: DEFINE METADATA RETRIEVAL FUNCTION
+# STEP 3: HELPERS FOR DYNAMIC DETAILS & SANITIZATION
+# -----------------------------------------------------------------------------
+def sanitize_name(name):
+    """Standardizes variations of Lange Francois to a safe ASCII format, preventing charset decode errors."""
+    if not name:
+        return "Francois Lange"
+    name_lower = name.lower()
+    if "fran" in name_lower or "lange" in name_lower or "lanfr" in name_lower:
+        return "Francois Lange"
+    return name
+
+def get_git_repo_details():
+    """Extracts username and project name dynamically from the origin git remote URL."""
+    try:
+        url = subprocess.check_output(["git", "remote", "get-url", "origin"], stderr=subprocess.DEVNULL).decode().strip()
+        # Parse username and project name (e.g. from https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git)
+        match = re.search(r'[:/]([^:/]+)/([^/]+?)(?:\.git)?$', url)
+        if match:
+            username = match.group(1)
+            project_name = match.group(2)
+            return username, project_name
+    except Exception:
+        pass
+    return "lanfr", "LocalFoodAI_lanfr144"
+
+# -----------------------------------------------------------------------------
+# STEP 4: DEFINE METADATA RETRIEVAL FUNCTION
 # -----------------------------------------------------------------------------
 def get_git_info(file_path):
     """Retrieves commit metadata for the specific file using git log, or falls back to system context."""
     try:
-        # A. Query git log for the last commit details of the specific file.
-        # We specify the YYYY/MM/DD HH:MM:SS format using '--date=format:...'.
-        # We use a pipe '|' delimiter to separate fields in the output format.
         cmd = [
             "git", "log", "-1",
             "--date=format:%Y/%m/%d %H:%M:%S",
@@ -41,55 +62,42 @@ def get_git_info(file_path):
             "--", file_path
         ]
         
-        # Run the git command, capture stdout, ignore stderr, decode bytes to string.
         out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL).decode('utf-8', errors='ignore').strip()
         if out:
-            # Split the pipe-delimited string back into an array of fields
             parts = out.split('|')
             if len(parts) == 9:
+                parts[0] = sanitize_name(parts[0])
+                parts[3] = sanitize_name(parts[3])
                 return parts
     except Exception:
-        # If git log fails (e.g., file not tracked yet), proceed to fallback logic below.
         pass
     
-    # B. Fallback: Query local Git configuration if file is not committed yet.
+    author_name = "Francois Lange"
     try:
-        # Retrieve the user's local git user.name
-        author_name = subprocess.check_output(["git", "config", "user.name"], stderr=subprocess.DEVNULL).decode('utf-8', errors='ignore').strip() or "system"
-        # Retrieve the user's local git user.email
-        author_email = subprocess.check_output(["git", "config", "user.email"], stderr=subprocess.DEVNULL).decode('utf-8', errors='ignore').strip() or "system@mail.com"
+        author_email = subprocess.check_output(["git", "config", "user.email"], stderr=subprocess.DEVNULL).decode('utf-8', errors='ignore').strip() or "lanfr144@school.lu"
     except Exception:
-        # If Git is not installed or configured, fallback to default system strings.
-        author_name = "system"
-        author_email = "system@mail.com"
+        author_email = "lanfr144@school.lu"
         
-    # Get current system date & time formatted consistently
     now_str = datetime.now().strftime("%Y/%m/%d %H:%M:%S")
-    # Return placeholder list in the same structure as git log output
     return [author_name, author_email, now_str, author_name, author_email, now_str, "Not Committed Yet", "local", "none"]
 
 # -----------------------------------------------------------------------------
-# STEP 4: EXECUTE SPECIFIED FILTER MODE
+# STEP 5: EXECUTE SPECIFIED FILTER MODE
 # -----------------------------------------------------------------------------
 if mode == "clean":
     # -------------------------------------------------------------------------
     # CLEAN MODE (Staging phase / git add)
     # -------------------------------------------------------------------------
-    # Read the file's contents directly from standard input (passed by Git)
     content = sys.stdin.read()
-    
-    # Get the basename of the file being cleaned
     file_name = os.path.basename(sys.argv[2]) if len(sys.argv) > 2 else "app.py"
     
-    # Non-greedy substitution to restore standard placeholder format for Git storage.
-    # We construct the search pattern and replacement dynamically to avoid matching our own code.
+    # Get project name dynamically from repo URL
+    _, project_name = get_git_repo_details()
+    
     pattern = r'\$F' + r'ormat:[^\r\n$]+\$'
-    repl = f"$F" + f"ormat:LocalFoodAI:{file_name}:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+    repl = f"$F" + f"ormat:{project_name}:{file_name}:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
     
-    # Run regular expression search and replace
     cleaned = re.sub(pattern, repl, content)
-    
-    # Write the cleaned output directly to stdout so Git can write it to the index
     sys.stdout.write(cleaned)
 
 else:
@@ -97,31 +105,19 @@ else:
     # SMUDGE MODE (Checkout / pull phase)
     # -------------------------------------------------------------------------
     try:
-        # Get absolute path of repository to find project directory name
-        toplevel = subprocess.check_output(["git", "rev-parse", "--show-toplevel"], stderr=subprocess.DEVNULL).decode().strip()
-        project_name = os.path.basename(toplevel)
+        # Get project details dynamically from repo URL
+        username, project_name = get_git_repo_details()
 
-        # Get the relative path of the file being smudged (passed as 2nd CLI arg by git configuration)
         file_name = sys.argv[2] if len(sys.argv) > 2 else "unknown_file"
-
-        # Read the raw file content sent by Git on stdin
         content = sys.stdin.read()
-
-        # Query git log metadata or local config fallbacks
         info = get_git_info(file_name)
 
-        # Format replacement string using dynamic project name and relative file path
-        # This replaces the placeholder metadata fields with actual git variables
         replacement = f"$F" + f"ormat:{project_name}:{os.path.basename(file_name)}:{info[0]}:{info[1]}:{info[2]}:{info[3]}:{info[4]}:{info[5]}:{info[6]}:{info[7]}:{info[8]}$"
 
         # Regex replacement targeting the dynamic format placeholders
-        # Pattern explanation: Matches "$Format:LocalFoodAI:git-ident-filter.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
         pattern = r'\$F' + r'ormat:[^:]+:[^:]+:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N\$'
         smudged = re.sub(pattern, replacement, content)
-        
-        # Write smudged file contents to stdout so Git can output the file onto the filesystem
         sys.stdout.write(smudged)
 
     except Exception:
-        # Safety fallback: If execution fails (e.g. outside git repository), write stream unchanged
         sys.stdout.write(sys.stdin.read())

+ 92 - 0
scratch/add_mirror_repos.py

@@ -0,0 +1,92 @@
+import os
+
+# 1. Update INSTALL_WSL.md
+file1 = "INSTALL_WSL.md"
+if os.path.exists(file1):
+    with open(file1, "r", encoding="utf-8", errors="replace") as f:
+        content = f.read()
+    
+    old_clone_block = """### Step 2: Clone the Git Repository
+Run the following commands inside your WSL Ubuntu home directory to clone the project:
+```bash
+git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git
+cd LocalFoodAI_lanfr144
+```"""
+
+    new_clone_block = """### Step 2: Clone the Git Repository
+Run the following commands inside your WSL Ubuntu home directory to clone the project:
+
+**Primary Repository (Internal Network)**:
+```bash
+git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git
+cd LocalFoodAI_lanfr144
+```
+
+**Alternative Repository (Worldwide Access - Clone of the Primary)**:
+```bash
+git clone https://github.com/lanfr144/LocalFoodAI_lanfr144.git
+cd LocalFoodAI_lanfr144
+```"""
+
+    content = content.replace(old_clone_block, new_clone_block)
+    with open(file1, "w", encoding="utf-8") as f:
+        f.write(content)
+    print("Updated INSTALL_WSL.md with mirror repositories.")
+
+# 2. Update generate_docs.py
+file2 = "generate_docs.py"
+if os.path.exists(file2):
+    with open(file2, "r", encoding="utf-8", errors="replace") as f:
+        content = f.read()
+
+    # Update Installation_Guide.md section in generate_docs.py
+    old_install_repos = """There are two repositories configured for this project:
+- Production Repository: `https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`
+- GitHub Mirror (Clone): `https://github.com/lanfr144/LocalFoodAI_lanfr144`"""
+
+    new_install_repos = """There are two repositories configured for this project:
+- Primary Git Repository: `https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`
+- Alternative Git Repository (Worldwide Access - Clone): `https://github.com/lanfr144/LocalFoodAI_lanfr144.git`"""
+
+    content = content.replace(old_install_repos, new_install_repos)
+
+    # Update Technical_Document.md section in generate_docs.py
+    old_tech_repos = """- *Online Mode*: `git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`"""
+    new_tech_repos = """- *Online Mode (Primary)*: `git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git`
+   - *Online Mode (Alternative/Worldwide)*: `git clone https://github.com/lanfr144/LocalFoodAI_lanfr144.git`"""
+
+    content = content.replace(old_tech_repos, new_tech_repos)
+
+    with open(file2, "w", encoding="utf-8") as f:
+        f.write(content)
+    print("Updated generate_docs.py with mirror repositories.")
+
+# 3. Update README.md
+file3 = "README.md"
+if os.path.exists(file3):
+    with open(file3, "r", encoding="utf-8", errors="replace") as f:
+        content = f.read()
+
+    old_readme_repos = """2. **Branch Checkout & App Setup (WSL Environment)**:
+   Navigate to the repository home directory inside WSL:
+   ```bash
+   cd ~
+   git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git
+   cd LocalFoodAI_lanfr144"""
+
+    new_readme_repos = """2. **Branch Checkout & App Setup (WSL Environment)**:
+   Navigate to the repository home directory inside WSL:
+   ```bash
+   cd ~
+   # Option A: Clone from the Primary Repository (Internal Network)
+   git clone https://git.btshub.lu/lanfr/LocalFoodAI_lanfr144.git
+   
+   # Option B: Clone from the Alternative Repository (Worldwide Access - Clone)
+   # git clone https://github.com/lanfr144/LocalFoodAI_lanfr144.git
+   
+   cd LocalFoodAI_lanfr144"""
+
+    content = content.replace(old_readme_repos, new_readme_repos)
+    with open(file3, "w", encoding="utf-8") as f:
+        f.write(content)
+    print("Updated README.md with mirror repositories.")