| 1 | import base64 |
| 2 | import os |
| 3 | from helpers.api import ApiHandler, Request, Response |
| 4 | from helpers import files |
| 5 | from helpers.print_style import PrintStyle |
| 6 | import json |
| 7 | |
| 8 | |
| 9 | class ApiFilesGet(ApiHandler): |
| 10 | @classmethod |
| 11 | def requires_auth(cls) -> bool: |
| 12 | return False |
| 13 | |
| 14 | @classmethod |
| 15 | def requires_csrf(cls) -> bool: |
| 16 | return False |
| 17 | |
| 18 | @classmethod |
| 19 | def requires_api_key(cls) -> bool: |
| 20 | return True |
| 21 | |
| 22 | @classmethod |
| 23 | def get_methods(cls) -> list[str]: |
| 24 | return ["POST"] |
| 25 | |
| 26 | async def process(self, input: dict, request: Request) -> dict | Response: |
| 27 | try: |
| 28 | # Get paths from input |
| 29 | paths = input.get("paths", []) |
| 30 | |
| 31 | if not paths: |
| 32 | return Response( |
| 33 | '{"error": "paths array is required"}', |
| 34 | status=400, |
| 35 | mimetype="application/json" |
| 36 | ) |
| 37 | |
| 38 | if not isinstance(paths, list): |
| 39 | return Response( |
| 40 | '{"error": "paths must be an array"}', |
| 41 | status=400, |
| 42 | mimetype="application/json" |
| 43 | ) |
| 44 | |
| 45 | result = {} |
| 46 | |
| 47 | for path in paths: |
| 48 | try: |
| 49 | # Convert internal paths to external paths |
| 50 | if path.startswith("/a0/tmp/uploads/"): |
| 51 | # Internal path - convert to external |
| 52 | filename = path.replace("/a0/tmp/uploads/", "") |
| 53 | external_path = files.get_abs_path("usr/uploads", filename) |
| 54 | filename = os.path.basename(external_path) |
| 55 | elif path.startswith("/a0/"): |
| 56 | # Other internal Agent Zero paths |
| 57 | relative_path = path.replace("/a0/", "") |
| 58 | external_path = files.get_abs_path(relative_path) |
| 59 | filename = os.path.basename(external_path) |
| 60 | else: |
| 61 | # Assume it's already an external/absolute path |
| 62 | external_path = path |
| 63 | filename = os.path.basename(path) |
| 64 | |
| 65 | # Check if file exists |
| 66 | if not os.path.exists(external_path): |
| 67 | PrintStyle.warning(f"File not found: {path}") |
| 68 | continue |
| 69 | |
| 70 | # Read and encode file |
| 71 | with open(external_path, "rb") as f: |
| 72 | file_content = f.read() |
| 73 | base64_content = base64.b64encode(file_content).decode('utf-8') |
| 74 | result[filename] = base64_content |
| 75 | |
| 76 | PrintStyle().print(f"Retrieved file: {filename} ({len(file_content)} bytes)") |
| 77 | |
| 78 | except Exception as e: |
| 79 | PrintStyle.error(f"Failed to read file {path}: {str(e)}") |
| 80 | continue |
| 81 | |
| 82 | # Log the retrieval |
| 83 | PrintStyle( |
| 84 | background_color="#2ECC71", font_color="white", bold=True, padding=True |
| 85 | ).print(f"API Files retrieved: {len(result)} files") |
| 86 | |
| 87 | return result |
| 88 | |
| 89 | except Exception as e: |
| 90 | PrintStyle.error(f"API files get error: {str(e)}") |
| 91 | return Response( |
| 92 | json.dumps({"error": f"Internal server error: {str(e)}"}), |
| 93 | status=500, |
| 94 | mimetype="application/json" |
| 95 | ) |