commit - /dev/null
commit + ceb25b5cdbe0ab0ef12adaee144fc0776650ff0f
blob - /dev/null
blob + 2672cbc8e9bc14a6d5f4e8857925a2365506f405 (mode 755)
--- /dev/null
+++ got_last_commit_file.py
+#!/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()