pup-py commited on
Commit
9dc6849
1 Parent(s): 8083ca2
Files changed (2) hide show
  1. Dockerfile +1 -1
  2. main.py +46 -61
Dockerfile CHANGED
@@ -30,7 +30,7 @@ RUN $PUP
30
 
31
  RUN pup py3.11
32
 
33
- RUN pup fetch appenv fastapi uvicorn
34
 
35
  COPY --chown=user main.py .
36
 
 
30
 
31
  RUN pup py3.11
32
 
33
+ RUN pup fetch appenv fastapi uvicorn itables
34
 
35
  COPY --chown=user main.py .
36
 
main.py CHANGED
@@ -1,64 +1,49 @@
1
- from fastapi import FastAPI, WebSocket
 
2
  from fastapi.responses import HTMLResponse
3
- import subprocess
 
 
4
 
5
- app = FastAPI()
6
-
7
- # HTML template for the terminal interface
8
- index_html = """
9
- <!DOCTYPE html>
10
- <html lang="en">
11
- <head>
12
- <meta charset="UTF-8">
13
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
- <title>Web Terminal</title>
15
- <style>
16
- /* Add CSS styles to customize the appearance of the terminal */
17
- </style>
18
- </head>
19
- <body>
20
- <div id="terminal"></div>
21
- <script>
22
- const terminal = document.getElementById("terminal");
23
- const ws = new WebSocket("ws://" + window.location.host + "/terminal");
24
-
25
- ws.onmessage = function(event) {
26
- terminal.innerText += event.data + "\\n";
27
- };
28
-
29
- function sendCommand() {
30
- const command = prompt("Enter command:");
31
- ws.send(command);
32
- }
33
- </script>
34
- </body>
35
- </html>
36
- """
37
 
38
- # Store active websocket connections
39
- connections = []
40
-
41
- @app.websocket("/terminal")
42
- async def terminal(websocket: WebSocket):
43
- await websocket.accept()
44
- connections.append(websocket)
45
- try:
46
- while True:
47
- data = await websocket.receive_text()
48
- # Execute the command and send the result back to the client
49
- result = await execute_command(data)
50
- await websocket.send_text(result)
51
- finally:
52
- connections.remove(websocket)
53
-
54
- async def execute_command(command: str) -> str:
55
- try:
56
- # Execute the command using subprocess
57
- result = subprocess.check_output(command, shell=True, text=True)
58
- except subprocess.CalledProcessError as e:
59
- result = f"Error: {e.output}"
60
- return result
61
-
62
- @app.get("/")
63
- async def index():
64
- return HTMLResponse(content=index_html, status_code=200)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request
2
+ from fastapi.staticfiles import StaticFiles
3
  from fastapi.responses import HTMLResponse
4
+ from itables import to_html_datatable
5
+ from pathlib import Path
6
+ import pandas as pd
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ ROOT = Path(".")
10
+ app = FastAPI()
11
+ app.mount(path="/", app=StaticFiles(directory=ROOT), name="HOME")
12
+
13
+
14
+ @app.middleware("http")
15
+ async def file_system(request: Request, call_next):
16
+ url = request.url
17
+ if url.path.endswith("/"):
18
+ return HTMLResponse(content=files_in_folder(url.path.lstrip("/")))
19
+ response = await call_next(request)
20
+ return response
21
+
22
+
23
+ def files_in_folder(path: str):
24
+ """List files to render as file index."""
25
+ folder = ROOT / path
26
+ print(folder)
27
+ path_glob = folder.glob("*")
28
+ res = pd.DataFrame(
29
+ [
30
+ (
31
+ f.name,
32
+ f.stat().st_size,
33
+ pd.Timestamp(int(f.stat().st_mtime), unit="s"),
34
+ f.stat().st_nlink > 1,
35
+ )
36
+ for f in path_glob
37
+ ],
38
+ columns=["path", "size", "mtime", "folder"],
39
+ ).sort_values(["folder"], ascending=False)
40
+
41
+ res["path"] = res.apply(
42
+ lambda x: f"<a href=/{path}{x.path}{'/' if x.folder else ''}>{x.path}</a>",
43
+ axis=1,
44
+ )
45
+ return f"<h1>{folder}</h1><br>" + to_html_datatable(
46
+ df=res.drop(columns="folder"),
47
+ classes="display compact",
48
+ showIndex=False,
49
+ )