Commit Diff


commit - /dev/null
commit + ceb25b5cdbe0ab0ef12adaee144fc0776650ff0f
blob - /dev/null
blob + 2672cbc8e9bc14a6d5f4e8857925a2365506f405 (mode 755)
--- /dev/null
+++ got_last_commit_file.py
@@ -0,0 +1,136 @@
+#!/usr/local/bin/python3
+"""
+CGI script to redirect to the latest version of a file in gotwebd
+URL pattern: /file/?path=<repo>&file=<filepath>
+"""
+
+import os
+import sys
+import subprocess
+import os.path
+import time
+from urllib.parse import parse_qs, unquote, urlencode
+
+
+REPO_BASE = "/got/public" # full path is /var/www/got/public
+DEBUG = 0   # from 0 to 9
+LOG_FID = open("/logs/cgi.log","a") # this will go into /var/www/logs/cgi.log
+
+def log(level, text):
+    if level <= DEBUG:
+        LOG_FID.write(f"{text}\n")
+
+def get_query_params():
+    """Parse query string parameters"""
+    query_string = os.environ.get('QUERY_STRING', '')
+    params = parse_qs(query_string)
+    
+    # Get first value for each param (parse_qs returns lists)
+    repo = params.get('path', [''])[0]
+    file_path = params.get('file', [''])[0]
+    
+    #return unquote(repo), unquote(file_path)
+    return repo, file_path
+
+def get_latest_commit(repo_path):
+    """Get the latest commit hash from a got repository"""
+    try:
+        # Use got log to get latest commit
+        result = subprocess.run(
+            ['got', 'log', '-r', repo_path, '-l', '1'],
+            capture_output=True,
+            text=True,
+            timeout=5
+        )
+        
+        if result.returncode == 0:
+            # Parse first line: "commit <hash>"
+            for line in result.stdout.split('\n'):
+                if line.startswith('commit '):
+                    return line.split()[1]
+        print("return code not null:", result.returncode)
+        return None
+    except Exception:
+        return None
+
+def send_response(status, content_type, body, location=None):
+    """Send HTTP response"""
+    print(f"Status: {status}")
+    if location:
+        print(f"Location: {location}")
+    print(f"Content-Type: {content_type}")
+    print()  # Empty line between headers and body
+    print(body)
+
+def main():
+    env = os.environ
+    log(0,f"{time.ctime()} - {env.get('REMOTE_ADDR','NA')} - {env.get('HTTP_USER_AGENT','NA')} - {env.get('REQUEST_METHOD','NA')} {env.get('SERVER_NAME','NA')}/{env.get('QUERY_STRING','NA')}")
+    # Parse parameters
+    repo, file_path = get_query_params()
+    log(1,'repo, file_path:%s %s' % (repo, file_path))
+    
+    # Validate inputs
+    if not repo or not file_path:
+        log(0, '%s - reply 400 - ERROR:missing path and/or file parameters' % (time.ctime()))
+        send_response(
+            "400 Bad Request",
+            "text/plain",
+            "Error: Missing required parameters 'path' and/or 'file'"
+        )
+        return
+    
+    # Build repository path
+    repo_path = os.path.join(REPO_BASE, repo)
+    log(1, 'repo_path:%s %s' % (repo_path, os.path.isdir(repo_path)))
+    
+    # Check if repository exists
+    if not os.path.isdir(repo_path):
+        log(0, '%s - reply 404 - ERROR:no repository found at %s' % (time.ctime(), repo_path))
+        send_response(
+            "404 Not Found",
+            "text/plain",
+            f"Error: Repository '{repo}' not found"
+        )
+        return
+    
+    # Get latest commit
+    commit = get_latest_commit(repo_path)
+    log(1, 'commit:%s' % (commit))
+    
+    if not commit:
+        log(0, '%s - reply 500 - ERROR:no "commit" found in got log for %s' % (time.ctime(), repo_path))
+        send_response(
+            "500 Internal Server Error",
+            "text/plain",
+            f"Error: Could not retrieve latest commit for repository '{repo}'"
+        )
+        return
+    
+    # Build gotwebd URL
+    folder, filename = os.path.split(file_path)
+    if folder in ("/"):
+        folder = ""
+    params = { 
+              "action": "blobraw",
+              "commit": commit,
+              "folder": folder,
+              "file": filename,
+              "path": repo
+              }
+              
+    log(1, 'params:%s' % (params))
+    gotwebd_url = "/?" + urlencode(params)
+    log(0, '%s - reply 302 - %s' % (time.ctime(), gotwebd_url))
+    #/?action=blobraw&commit={commit}&folder=&file={file_path}&path={repo}"
+    
+    # Send redirect
+    send_response(
+        "302 Found",
+        "text/plain",
+        "Redirecting to latest version...",
+        location=gotwebd_url
+    )
+    LOG_FID.close()
+
+if __name__ == "__main__":
+    main()