Akwbw commited on
Commit
510e54a
·
verified ·
1 Parent(s): 4d7f4fb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -176
app.py CHANGED
@@ -2,192 +2,124 @@ import streamlit as st
2
  import os
3
  import time
4
  import base64
5
- import threading
6
- import requests
7
- import json
8
- from flask import Flask, request, jsonify
9
  from playwright.sync_api import sync_playwright
10
 
11
- # --- PART 1: BACKGROUND FLASK SERVER (THE ENGINE) ---
12
- # Ye server browser ko sambhalega taake Streamlit crash na ho
13
-
14
- server = Flask(__name__)
15
- PORT = 5000
16
- API_URL = f"http://127.0.0.1:{PORT}"
17
-
18
- # Global Browser State
19
- backend_state = {
20
- "playwright": None,
21
- "browser": None,
22
- "context": None,
23
- "page": None,
24
- "logs": []
25
- }
26
-
27
- def add_log(msg):
28
- backend_state["logs"].append(msg)
29
- if len(backend_state["logs"]) > 20: backend_state["logs"].pop(0)
30
-
31
- @server.route('/start', methods=['POST'])
32
- def start_browser():
33
- s = backend_state
34
- if s["browser"]: return jsonify({"status": "Already running"})
35
-
36
- try:
37
- s["playwright"] = sync_playwright().start()
38
- s["browser"] = s["playwright"].chromium.launch(
39
- headless=True,
40
- args=['--no-sandbox', '--disable-blink-features=AutomationControlled']
41
- )
42
- s["context"] = s["browser"].new_context(
43
- viewport={'width': 375, 'height': 812},
44
- user_agent='Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
45
- is_mobile=True, has_touch=True
46
- )
47
- s["page"] = s["context"].new_page()
48
- s["page"].goto("https://www.coinpayu.com/login", timeout=60000)
49
- add_log("Browser Started. On Login Page.")
50
- return jsonify({"status": "Started"})
51
- except Exception as e:
52
- return jsonify({"error": str(e)}), 500
53
-
54
- @server.route('/interact', methods=['POST'])
55
- def interact():
56
- s = backend_state
57
- if not s["page"]: return jsonify({"error": "No Browser"}), 400
58
-
59
- data = request.json
60
- action = data.get("action")
61
-
62
- try:
63
- if action == "type":
64
- # Clear field if needed? No, just type.
65
- text = data.get("text")
66
- s["page"].keyboard.type(text)
67
- add_log(f"Typed: {text}")
68
-
69
- elif action == "enter":
70
- s["page"].keyboard.press("Enter")
71
- add_log("Pressed Enter")
72
-
73
- elif action == "click":
74
- # Tap center of screen if no coordinates (generic tap)
75
- # But better to tap active element or just rely on 'Type' focus
76
- pass
77
-
78
- elif action == "scroll":
79
- s["page"].evaluate("window.scrollBy(0, 300)")
80
-
81
- # Capture Screenshot immediately
82
- b64 = base64.b64encode(s["page"].screenshot(type='jpeg', quality=50)).decode('utf-8')
83
- return jsonify({"status": "ok", "image": b64, "logs": s["logs"]})
84
 
85
- except Exception as e:
86
- return jsonify({"error": str(e)}), 500
87
-
88
- @server.route('/status', methods=['GET'])
89
- def status():
90
- s = backend_state
91
- img = ""
92
- if s["page"]:
93
  try:
94
- img = base64.b64encode(s["page"].screenshot(type='jpeg', quality=50)).decode('utf-8')
95
- except: pass
96
- return jsonify({"image": img, "logs": s["logs"]})
97
-
98
- # Run Flask in Background Thread
99
- def run_flask():
100
- server.run(host='0.0.0.0', port=PORT, use_reloader=False)
101
-
102
- if "server_thread" not in st.session_state:
103
- t = threading.Thread(target=run_flask, daemon=True)
104
- t.start()
105
- st.session_state.server_thread = True
106
- time.sleep(2) # Wait for server to start
107
-
108
- # --- PART 2: STREAMLIT UI (THE FRONTEND) ---
109
-
110
- st.set_page_config(layout="wide", page_title="CoinPayU Controller")
111
-
112
- st.title("📱 CoinPayU Remote")
113
-
114
- # Initialize Session State
115
- if "image" not in st.session_state: st.session_state.image = None
116
- if "logs" not in st.session_state: st.session_state.logs = []
117
 
118
- # --- API HELPER ---
119
- def api_call(endpoint, data=None):
120
- try:
121
- if data:
122
- r = requests.post(f"{API_URL}/{endpoint}", json=data)
123
- else:
124
- r = requests.get(f"{API_URL}/{endpoint}")
125
-
126
- if r.status_code == 200:
127
- res = r.json()
128
- if "image" in res and res["image"]:
129
- st.session_state.image = res["image"]
130
- if "logs" in res:
131
- st.session_state.logs = res["logs"]
132
- return True
133
- except:
134
- st.error("Backend Sleeping. Click Start.")
135
- return False
136
-
137
- # --- LAYOUT ---
138
- col1, col2 = st.columns([1, 1])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
  with col1:
141
- st.subheader("Live View")
142
-
143
- # Auto Refresh Logic
144
- if st.button("🔄 Refresh Screen"):
145
- api_call("status")
146
-
147
- if st.session_state.image:
148
- st.image(base64.b64decode(st.session_state.image), caption="Live Browser", use_column_width=True)
149
- else:
150
- st.info("Browser OFF. Click 'Start Engine'.")
151
 
152
  with col2:
153
- st.subheader("Controls")
154
-
155
- if st.button("🚀 Start Engine"):
156
- with st.spinner("Starting Browser..."):
157
- requests.post(f"{API_URL}/start")
158
- time.sleep(3)
159
- api_call("status")
160
- st.rerun()
161
-
162
- # --- TYPING FIX ---
163
- st.write("### ⌨️ Keyboard")
164
- # Form use karne se Enter dabane par submit hota hai
165
- with st.form(key='type_form'):
166
- user_text = st.text_input("Type Email / Password here:", key="input_text")
167
- c1, c2 = st.columns(2)
168
- with c1:
169
- submit_type = st.form_submit_button("Type Text")
170
- with c2:
171
- submit_enter = st.form_submit_button("Press Enter")
172
-
173
- if submit_type and user_text:
174
- api_call("interact", {"action": "type", "text": user_text})
175
- st.rerun()
176
-
177
- if submit_enter:
178
- api_call("interact", {"action": "enter"})
179
- st.rerun()
180
-
181
- st.write("### 🖱️ Navigation")
182
- c3, c4 = st.columns(2)
183
- if c3.button("⬇ Scroll Down"):
184
- api_call("interact", {"action": "scroll"})
185
  st.rerun()
 
 
 
 
 
 
186
 
187
- if c4.button("Login Button (Enter)"):
188
- api_call("interact", {"action": "enter"})
189
  st.rerun()
190
 
191
- st.markdown("---")
192
- st.write("Logs:")
193
- st.code("\n".join(st.session_state.logs))
 
 
 
 
 
 
 
2
  import os
3
  import time
4
  import base64
5
+ from datetime import datetime
 
 
 
6
  from playwright.sync_api import sync_playwright
7
 
8
+ # --- GLOBAL BOT CLASS (CACHED) ---
9
+ # Ye decorator browser ko restart hone se rokta hai
10
+ @st.cache_resource
11
+ class BrowserBot:
12
+ def __init__(self):
13
+ self.playwright = None
14
+ self.browser = None
15
+ self.context = None
16
+ self.page = None
17
+ self.logs = []
18
+ self.add_log("Bot initialized.")
19
+
20
+ def add_log(self, msg):
21
+ ts = datetime.now().strftime("%H:%M:%S")
22
+ self.logs.insert(0, f"[{ts}] {msg}")
23
+ if len(self.logs) > 20: self.logs.pop()
24
+
25
+ def start(self):
26
+ if self.browser: return # Already running
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
 
 
 
 
 
 
 
 
28
  try:
29
+ self.playwright = sync_playwright().start()
30
+ self.browser = self.playwright.chromium.launch(
31
+ headless=True,
32
+ args=['--no-sandbox', '--disable-blink-features=AutomationControlled']
33
+ )
34
+ self.context = self.browser.new_context(
35
+ viewport={'width': 375, 'height': 812}, # Mobile View
36
+ user_agent='Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
37
+ is_mobile=True, has_touch=True
38
+ )
39
+ self.page = self.context.new_page()
40
+ self.page.goto("https://www.coinpayu.com/login", timeout=60000)
41
+ self.add_log("Browser Started. On Login Page.")
42
+ except Exception as e:
43
+ self.add_log(f"Start Error: {e}")
44
+
45
+ def get_screenshot(self):
46
+ if not self.page: return None
47
+ try:
48
+ return self.page.screenshot(type='jpeg', quality=50)
49
+ except: return None
 
 
50
 
51
+ def interact(self, action, text=None):
52
+ if not self.page: return
53
+ try:
54
+ if action == "type":
55
+ self.page.keyboard.type(text)
56
+ self.add_log(f"Typed: {text}")
57
+ elif action == "enter":
58
+ self.page.keyboard.press("Enter")
59
+ self.add_log("Pressed Enter")
60
+ elif action == "scroll":
61
+ self.page.mouse.wheel(0, 300)
62
+ self.add_log("Scrolled Down")
63
+ elif action == "refresh":
64
+ self.page.reload()
65
+ self.add_log("Page Refreshed")
66
+ except Exception as e:
67
+ self.add_log(f"Error: {e}")
68
+
69
+ # --- INITIALIZE ---
70
+ bot = BrowserBot()
71
+
72
+ # --- UI LAYOUT ---
73
+ st.set_page_config(layout="centered", page_title="CoinPayU Bot")
74
+
75
+ st.title("📱 CoinPayU Manager")
76
+
77
+ # 1. LIVE VIEW
78
+ st.subheader("Live Screen")
79
+ screenshot = bot.get_screenshot()
80
+
81
+ if screenshot:
82
+ st.image(screenshot, caption="Live Browser Feed", use_column_width=True)
83
+ else:
84
+ st.info("Browser is OFF. Click 'Start Browser' below.")
85
+
86
+ # 2. CONTROLS
87
+ col1, col2 = st.columns(2)
88
 
89
  with col1:
90
+ if st.button("🚀 Start Browser", use_container_width=True):
91
+ bot.start()
92
+ st.rerun()
93
+
94
+ if st.button("🔄 Refresh Page", use_container_width=True):
95
+ bot.interact("refresh")
96
+ st.rerun()
 
 
 
97
 
98
  with col2:
99
+ if st.button("⬇ Scroll Down", use_container_width=True):
100
+ bot.interact("scroll")
101
+ st.rerun()
102
+
103
+ if st.button("↵ Press Enter", use_container_width=True):
104
+ bot.interact("enter")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  st.rerun()
106
+
107
+ # 3. TYPING AREA
108
+ st.markdown("### ⌨️ Keyboard")
109
+ with st.form("type_form", clear_on_submit=True):
110
+ user_text = st.text_input("Enter Email / Password here:")
111
+ submitted = st.form_submit_button("Type Text")
112
 
113
+ if submitted and user_text:
114
+ bot.interact("type", user_text)
115
  st.rerun()
116
 
117
+ # 4. LOGS
118
+ st.markdown("---")
119
+ st.text("Logs:")
120
+ st.code("\n".join(bot.logs))
121
+
122
+ # Auto Refresh hack (keeps image live)
123
+ if bot.page:
124
+ time.sleep(1)
125
+ st.rerun()