arcticaurora commited on
Commit
edb769e
·
verified ·
1 Parent(s): acd6d81

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +267 -0
app.py ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request, UploadFile, File, Form, HTTPException
2
+ from fastapi.responses import HTMLResponse, FileResponse, JSONResponse
3
+ from fastapi.staticfiles import StaticFiles
4
+ from fastapi.templating import Jinja2Templates
5
+ import os
6
+ import subprocess
7
+ import datetime
8
+ import uuid
9
+ from pathlib import Path
10
+ import logging
11
+ import shutil
12
+
13
+ # Setup logging
14
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
15
+ logger = logging.getLogger("file-test-app")
16
+
17
+ app = FastAPI(title="File System Test App")
18
+
19
+ # Setup templates and static files
20
+ templates = Jinja2Templates(directory="templates")
21
+
22
+ # Create files directory if it doesn't exist
23
+ os.makedirs("files", exist_ok=True)
24
+
25
+ # Mount files directory as static
26
+ app.mount("/files", StaticFiles(directory="files"), name="files")
27
+ app.mount("/static", StaticFiles(directory="static"), name="static")
28
+
29
+ @app.get("/", response_class=HTMLResponse)
30
+ async def home(request: Request):
31
+ """Home page"""
32
+ # Log system information
33
+ try:
34
+ whoami = subprocess.run(["whoami"], capture_output=True, text=True).stdout.strip()
35
+ file_perms = subprocess.run(["ls", "-la", "/app/files"], capture_output=True, text=True).stdout
36
+ disk_info = subprocess.run(["df", "-h"], capture_output=True, text=True).stdout
37
+
38
+ logger.info(f"Running as user: {whoami}")
39
+ logger.info(f"Files directory permissions:\n{file_perms}")
40
+ logger.info(f"Disk space:\n{disk_info}")
41
+ except Exception as e:
42
+ logger.error(f"Error getting system info: {str(e)}")
43
+
44
+ return templates.TemplateResponse("index.html", {"request": request})
45
+
46
+ @app.post("/save-file")
47
+ async def save_file(content: str = Form(...), filename: str = Form(...)):
48
+ """Save content to a file"""
49
+ try:
50
+ # Create a safe filename
51
+ safe_filename = filename.replace(" ", "_")
52
+ if not safe_filename.endswith(".txt"):
53
+ safe_filename += ".txt"
54
+
55
+ file_path = os.path.join("files", safe_filename)
56
+
57
+ # Write the file
58
+ with open(file_path, "w") as f:
59
+ f.write(content)
60
+
61
+ # Get file size
62
+ file_size = os.path.getsize(file_path)
63
+
64
+ return JSONResponse({
65
+ "success": True,
66
+ "message": "File saved successfully",
67
+ "file_path": file_path,
68
+ "file_size": file_size,
69
+ "url": f"/files/{safe_filename}"
70
+ })
71
+ except Exception as e:
72
+ logger.error(f"Error saving file: {str(e)}")
73
+ return JSONResponse({
74
+ "success": False,
75
+ "message": f"Error saving file: {str(e)}"
76
+ }, status_code=500)
77
+
78
+ @app.post("/upload-file")
79
+ async def upload_file(file: UploadFile = File(...)):
80
+ """Upload a file"""
81
+ try:
82
+ # Create a safe filename
83
+ safe_filename = file.filename.replace(" ", "_")
84
+ file_path = os.path.join("files", safe_filename)
85
+
86
+ # Save the file
87
+ with open(file_path, "wb") as f:
88
+ shutil.copyfileobj(file.file, f)
89
+
90
+ # Get file size
91
+ file_size = os.path.getsize(file_path)
92
+
93
+ return JSONResponse({
94
+ "success": True,
95
+ "message": "File uploaded successfully",
96
+ "file_path": file_path,
97
+ "file_size": file_size,
98
+ "url": f"/files/{safe_filename}"
99
+ })
100
+ except Exception as e:
101
+ logger.error(f"Error uploading file: {str(e)}")
102
+ return JSONResponse({
103
+ "success": False,
104
+ "message": f"Error uploading file: {str(e)}"
105
+ }, status_code=500)
106
+
107
+ @app.get("/list-files")
108
+ async def list_files():
109
+ """List all files in the files directory"""
110
+ try:
111
+ files_dir = Path("files")
112
+ files = []
113
+
114
+ for f in files_dir.glob("*"):
115
+ if f.is_file():
116
+ files.append({
117
+ "name": f.name,
118
+ "path": str(f),
119
+ "size": os.path.getsize(f),
120
+ "size_readable": f"{os.path.getsize(f) / 1024:.2f} KB",
121
+ "modified": datetime.datetime.fromtimestamp(os.path.getmtime(f)).strftime("%Y-%m-%d %H:%M:%S"),
122
+ "url": f"/files/{f.name}"
123
+ })
124
+
125
+ return JSONResponse({
126
+ "success": True,
127
+ "files": files
128
+ })
129
+ except Exception as e:
130
+ logger.error(f"Error listing files: {str(e)}")
131
+ return JSONResponse({
132
+ "success": False,
133
+ "message": f"Error listing files: {str(e)}"
134
+ }, status_code=500)
135
+
136
+ @app.delete("/delete-file/{filename}")
137
+ async def delete_file(filename: str):
138
+ """Delete a file"""
139
+ try:
140
+ file_path = os.path.join("files", filename)
141
+
142
+ if not os.path.exists(file_path):
143
+ return JSONResponse({
144
+ "success": False,
145
+ "message": "File not found"
146
+ }, status_code=404)
147
+
148
+ os.remove(file_path)
149
+
150
+ return JSONResponse({
151
+ "success": True,
152
+ "message": "File deleted successfully"
153
+ })
154
+ except Exception as e:
155
+ logger.error(f"Error deleting file: {str(e)}")
156
+ return JSONResponse({
157
+ "success": False,
158
+ "message": f"Error deleting file: {str(e)}"
159
+ }, status_code=500)
160
+
161
+ @app.get("/system-info")
162
+ async def system_info():
163
+ """Get system information"""
164
+ try:
165
+ whoami = subprocess.run(["whoami"], capture_output=True, text=True).stdout.strip()
166
+ file_perms = subprocess.run(["ls", "-la", "/app/files"], capture_output=True, text=True).stdout
167
+ disk_info = subprocess.run(["df", "-h"], capture_output=True, text=True).stdout
168
+ env_vars = {k: v for k, v in os.environ.items()}
169
+
170
+ # Try to create a large test file
171
+ test_file_path = os.path.join("files", "large_test_file.txt")
172
+
173
+ try:
174
+ with open(test_file_path, "w") as f:
175
+ # Write a 10MB file with repeated text
176
+ text_block = "This is a test line to check file system write capabilities.\n" * 100
177
+ for _ in range(1000): # Write 10,000 lines
178
+ f.write(text_block)
179
+
180
+ large_file_size = os.path.getsize(test_file_path)
181
+ large_file_status = f"Created large test file: {large_file_size / (1024*1024):.2f} MB"
182
+ except Exception as e:
183
+ large_file_status = f"Failed to create large test file: {str(e)}"
184
+
185
+ return JSONResponse({
186
+ "success": True,
187
+ "whoami": whoami,
188
+ "file_permissions": file_perms,
189
+ "disk_info": disk_info,
190
+ "large_file_test": large_file_status,
191
+ "env_vars": env_vars,
192
+ "python_version": subprocess.run(["python", "--version"], capture_output=True, text=True).stdout.strip(),
193
+ "pwd": subprocess.run(["pwd"], capture_output=True, text=True).stdout.strip(),
194
+ "ls_app": subprocess.run(["ls", "-la", "/app"], capture_output=True, text=True).stdout
195
+ })
196
+ except Exception as e:
197
+ logger.error(f"Error getting system info: {str(e)}")
198
+ return JSONResponse({
199
+ "success": False,
200
+ "message": f"Error getting system info: {str(e)}"
201
+ }, status_code=500)
202
+
203
+ @app.get("/test-binary-file")
204
+ async def test_binary_file():
205
+ """Create a test binary file"""
206
+ try:
207
+ file_path = os.path.join("files", "binary_test.bin")
208
+
209
+ # Create binary data
210
+ binary_data = bytearray(os.urandom(1024 * 1024)) # 1MB of random data
211
+
212
+ # Write binary file
213
+ with open(file_path, "wb") as f:
214
+ f.write(binary_data)
215
+
216
+ file_size = os.path.getsize(file_path)
217
+
218
+ return JSONResponse({
219
+ "success": True,
220
+ "message": "Binary file created successfully",
221
+ "file_path": file_path,
222
+ "file_size": file_size,
223
+ "url": f"/files/binary_test.bin"
224
+ })
225
+ except Exception as e:
226
+ logger.error(f"Error creating binary file: {str(e)}")
227
+ return JSONResponse({
228
+ "success": False,
229
+ "message": f"Error creating binary file: {str(e)}"
230
+ }, status_code=500)
231
+
232
+ # Testing command to simulate pg_dump
233
+ @app.get("/test-command-output")
234
+ async def test_command_output():
235
+ """Test running a command and saving its output"""
236
+ try:
237
+ output_file = os.path.join("files", "command_output.txt")
238
+
239
+ # Run a command and redirect output to a file
240
+ cmd = ["ls", "-la", "/"]
241
+
242
+ # Method 1: Direct redirection
243
+ with open(output_file, "w") as f:
244
+ subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, text=True)
245
+
246
+ # Method 2: Capture then write
247
+ output_file2 = os.path.join("files", "command_output2.txt")
248
+ result = subprocess.run(cmd, capture_output=True, text=True)
249
+ with open(output_file2, "w") as f:
250
+ f.write(result.stdout)
251
+
252
+ return JSONResponse({
253
+ "success": True,
254
+ "message": "Command output saved",
255
+ "file1_path": output_file,
256
+ "file1_size": os.path.getsize(output_file),
257
+ "file1_url": f"/files/command_output.txt",
258
+ "file2_path": output_file2,
259
+ "file2_size": os.path.getsize(output_file2),
260
+ "file2_url": f"/files/command_output2.txt",
261
+ })
262
+ except Exception as e:
263
+ logger.error(f"Error running command: {str(e)}")
264
+ return JSONResponse({
265
+ "success": False,
266
+ "message": f"Error running command: {str(e)}"
267
+ }, status_code=500)