Akwbw commited on
Commit
0511a46
·
verified ·
1 Parent(s): 138c8a0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -74
app.py CHANGED
@@ -1,14 +1,17 @@
1
  import os
2
  import time
3
- # Display Setup
 
4
  os.environ["DISPLAY"] = ":99"
5
- os.environ["XAUTHORITY"] = "/root/.Xauthority"
6
 
7
  import base64
8
- import subprocess
9
- from flask import Flask, request, jsonify, Response
10
  from flask_cors import CORS
11
  import pyautogui
 
 
 
12
 
13
  app = Flask(__name__)
14
  CORS(app)
@@ -16,99 +19,64 @@ CORS(app)
16
  SCREEN_WIDTH = 1024
17
  SCREEN_HEIGHT = 768
18
 
19
- # PyAutoGUI Config
20
  pyautogui.FAILSAFE = False
21
  pyautogui.PAUSE = 0.1
22
 
23
- # --- EMBEDDED UI ---
24
- HTML_TEMPLATE = """
25
- <!DOCTYPE html>
26
- <html>
27
- <head>
28
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
29
- <title>Cloud PC</title>
30
- <style>
31
- body { margin: 0; background: #111; height: 100vh; display: flex; flex-direction: column; overflow: hidden; user-select: none; }
32
- .screen-container { flex: 1; display: flex; justify-content: center; background: black; }
33
- #desktop { width: 100%; height: 100%; object-fit: contain; }
34
- .toolbar { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); background: rgba(255,255,255,0.2); padding: 10px; border-radius: 30px; display: flex; gap: 15px; }
35
- .btn { width: 40px; height: 40px; border-radius: 50%; background: #333; color: white; display: flex; align-items: center; justify-content: center; cursor: pointer; }
36
- </style>
37
- </head>
38
- <body>
39
- <div class="screen-container">
40
- <img id="desktop" draggable="false">
41
- <div class="toolbar">
42
- <div class="btn" onclick="sendKey('win')">⊞</div>
43
- <div class="btn" onclick="sendKey('enter')">↵</div>
44
- <div class="btn" onclick="launchApp('chrome')">🌐</div>
45
- <div class="btn" onclick="launchApp('terminal')">_></div>
46
- </div>
47
- </div>
48
- <script>
49
- const img = document.getElementById('desktop');
50
- function refresh() { img.src = '/snapshot?' + new Date().getTime(); }
51
- setInterval(refresh, 800);
52
-
53
- img.addEventListener('click', async (e) => {
54
- const rect = img.getBoundingClientRect();
55
- if (e.clientX < rect.left || e.clientX > rect.right) return;
56
- const x = (e.clientX - rect.left) / rect.width;
57
- const y = (e.clientY - rect.top) / rect.height;
58
- await fetch('/interact', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({action: 'tap', x: x, y: y}) });
59
- refresh();
60
- });
61
-
62
- async function sendKey(k) {
63
- await fetch('/interact', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({action: 'key', key: k}) });
64
- refresh();
65
- }
66
- async function launchApp(app) {
67
- await fetch('/interact', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({action: 'launch', app: app}) });
68
- }
69
- </script>
70
- </body>
71
- </html>
72
- """
73
 
74
  @app.route('/')
75
- def home(): return HTML_TEMPLATE
 
76
 
77
  @app.route('/snapshot', methods=['GET'])
78
  def get_snapshot():
79
  try:
80
- subprocess.run(["scrot", "/tmp/screen.jpg", "-q", "20", "-o"], check=True)
81
- with open("/tmp/screen.jpg", "rb") as image_file:
82
- return Response(image_file.read(), mimetype='image/jpeg')
83
- except: return "Error", 500
 
 
 
 
 
 
 
 
84
 
85
  @app.route('/interact', methods=['POST'])
86
  def interact():
87
  data = request.json
88
  action = data.get('action')
 
89
  try:
90
  if action == 'tap':
91
  x = int(data.get('x') * SCREEN_WIDTH)
92
  y = int(data.get('y') * SCREEN_HEIGHT)
93
  pyautogui.click(x, y)
94
 
 
 
 
95
  elif action == 'key':
96
- k = data.get('key')
97
- if k == 'win': pyautogui.press('super')
98
- else: pyautogui.press(k)
99
 
100
- elif action == 'launch':
101
- app_name = data.get('app')
102
- if app_name == 'chrome':
103
- # FIXED: Use google-chrome instead of chromium-browser
104
- subprocess.Popen("google-chrome --no-sandbox --start-maximized &", shell=True)
105
- elif app_name == 'terminal':
106
- subprocess.Popen("xfce4-terminal &", shell=True)
107
-
 
108
  return jsonify({"status": "ok"})
109
- except Exception as e:
110
- print(e)
111
- return jsonify({"error": "err"}), 500
112
 
113
  if __name__ == '__main__':
114
  app.run(host='0.0.0.0', port=7860, threaded=True)
 
1
  import os
2
  import time
3
+
4
+ # --- CRITICAL FIX: Set Display before importing PyAutoGUI ---
5
  os.environ["DISPLAY"] = ":99"
 
6
 
7
  import base64
8
+ import threading
9
+ from flask import Flask, request, jsonify, send_file
10
  from flask_cors import CORS
11
  import pyautogui
12
+ import mss
13
+ from PIL import Image
14
+ import io
15
 
16
  app = Flask(__name__)
17
  CORS(app)
 
19
  SCREEN_WIDTH = 1024
20
  SCREEN_HEIGHT = 768
21
 
22
+ # PyAutoGUI Settings
23
  pyautogui.FAILSAFE = False
24
  pyautogui.PAUSE = 0.1
25
 
26
+ sct = mss.mss()
27
+ monitor = {"top": 0, "left": 0, "width": SCREEN_WIDTH, "height": SCREEN_HEIGHT}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  @app.route('/')
30
+ def home():
31
+ return "Cloud PC Ready. Connect via HTML."
32
 
33
  @app.route('/snapshot', methods=['GET'])
34
  def get_snapshot():
35
  try:
36
+ sct_img = sct.grab(monitor)
37
+ img = Image.frombytes("RGB", sct_img.size, sct_img.bgra, "raw", "BGRX")
38
+ img.thumbnail((600, 600)) # Resize for speed
39
+
40
+ buffer = io.BytesIO()
41
+ img.save(buffer, format="JPEG", quality=50)
42
+ b64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
43
+
44
+ return jsonify({"screenshot": b64})
45
+ except Exception as e:
46
+ print(f"Snapshot Error: {e}")
47
+ return jsonify({"error": str(e)}), 500
48
 
49
  @app.route('/interact', methods=['POST'])
50
  def interact():
51
  data = request.json
52
  action = data.get('action')
53
+
54
  try:
55
  if action == 'tap':
56
  x = int(data.get('x') * SCREEN_WIDTH)
57
  y = int(data.get('y') * SCREEN_HEIGHT)
58
  pyautogui.click(x, y)
59
 
60
+ elif action == 'type':
61
+ pyautogui.write(data.get('text'))
62
+
63
  elif action == 'key':
64
+ k = data.get('key').lower()
65
+ if k == 'enter': pyautogui.press('enter')
66
+ elif k == 'backspace': pyautogui.press('backspace')
67
 
68
+ elif action == 'scroll':
69
+ pyautogui.scroll(-5)
70
+
71
+ elif action == 'open_terminal':
72
+ os.system("xfce4-terminal &")
73
+
74
+ elif action == 'open_browser':
75
+ os.system("chromium-browser --no-sandbox &")
76
+
77
  return jsonify({"status": "ok"})
78
+ except Exception as e:
79
+ return jsonify({"error": str(e)}), 500
 
80
 
81
  if __name__ == '__main__':
82
  app.run(host='0.0.0.0', port=7860, threaded=True)