Docfile commited on
Commit
2171485
·
verified ·
1 Parent(s): c518212

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -283
app.py CHANGED
@@ -1,301 +1,76 @@
1
- from flask import Flask, render_template, request, jsonify, redirect, url_for
2
- import aiohttp
3
- import asyncio
4
- from bs4 import BeautifulSoup
5
- import random
6
- import string
7
- import json
8
- import threading
9
  import os
10
- import time
11
  from datetime import datetime
12
- from concurrent.futures import ThreadPoolExecutor
13
 
14
  app = Flask(__name__)
 
15
 
16
- # Configuration globale
17
- config = {
18
- 'base_url': "https://ivoire-startup-tracker-edithbrou.replit.app",
19
- 'accounts_file': "accounts_data.json",
20
- 'is_running': False,
21
- 'batch_size': 10, # Nombre de requêtes parallèles
22
- 'progress': {
23
- 'total': 0,
24
- 'current': 0,
25
- 'success': 0,
26
- 'failed': 0,
27
- 'last_username': '',
28
- 'last_status': '',
29
- 'start_time': None,
30
- 'end_time': None
31
- }
32
- }
33
 
34
- # Fonction pour générer un nom d'utilisateur aléatoire
35
- def generate_random_username(min_length=8, max_length=12):
36
- """Génère un nom d'utilisateur aléatoire d'une longueur raisonnable"""
37
- length = random.randint(min_length, max_length)
38
- return ''.join(random.choice(string.ascii_lowercase) for _ in range(length))
39
-
40
- # Fonction pour générer une adresse email aléatoire
41
- def generate_random_email():
42
- """Génère une adresse email aléatoire"""
43
- username = ''.join(random.choice(string.ascii_lowercase) for _ in range(12))
44
- domains = ["gmail.com", "yahoo.com", "outlook.com", "example.com"]
45
- return f"{username}@{random.choice(domains)}"
46
-
47
- # Fonction pour générer un mot de passe aléatoire
48
- def generate_random_password(length=10):
49
- """Génère un mot de passe aléatoire avec un mélange de caractères"""
50
- chars = string.ascii_letters + string.digits + "!@#$%^&*()-_=+" # Éviter certains caractères spéciaux qui pourraient causer des problèmes
51
- return ''.join(random.choice(chars) for _ in range(length))
52
-
53
- # Fonction asynchrone pour créer un compte
54
- async def create_account_async(session, is_startup_rep=False):
55
- """Crée un compte sur le site web de manière asynchrone"""
56
- register_url = f"{config['base_url']}/register"
57
-
58
- try:
59
- # Première requête pour récupérer le token CSRF
60
- async with session.get(register_url, timeout=10) as response:
61
- if response.status != 200:
62
- return {'success': False, 'error': f"Erreur lors de l'accès à la page: {response.status}"}
63
-
64
- html = await response.text()
65
-
66
- # Extraire le token CSRF
67
- soup = BeautifulSoup(html, 'html.parser')
68
- csrf_token_input = soup.find('input', {'id': 'csrf_token'})
69
-
70
- if not csrf_token_input:
71
- return {'success': False, 'error': "Impossible de trouver le token CSRF"}
72
-
73
- csrf_token = csrf_token_input.get('value')
74
-
75
- # Générer des informations de compte aléatoires
76
- username = generate_random_username()
77
- email = generate_random_email()
78
- password = generate_random_password()
79
-
80
- # Préparer les données du formulaire
81
- form_data = {
82
- 'csrf_token': csrf_token,
83
- 'username': username,
84
- 'email': email,
85
- 'password': password,
86
- 'confirm_password': password,
87
- 'submit': 'Register'
88
- }
89
-
90
- # Ajouter l'option startup rep si nécessaire
91
- if is_startup_rep:
92
- form_data['is_startup_rep'] = 'y'
93
-
94
- # Envoyer le formulaire
95
- headers = {
96
- 'Referer': register_url,
97
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
98
- }
99
-
100
- async with session.post(register_url, data=form_data, headers=headers, timeout=15) as response:
101
- result = {
102
- 'success': response.status == 200 or response.status == 302,
103
- 'username': username,
104
- 'email': email,
105
- 'password': password,
106
- 'is_startup_rep': is_startup_rep,
107
- 'created_at': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
108
- 'status_code': response.status
109
- }
110
-
111
- return result
112
-
113
- except asyncio.TimeoutError:
114
- return {'success': False, 'error': "Timeout lors de la requête"}
115
- except Exception as e:
116
- return {'success': False, 'error': str(e)}
117
-
118
- # Fonction pour traiter un lot de comptes en parallèle
119
- async def process_batch(batch_indices, startup_ratio, accounts):
120
- """Traite un lot de comptes en parallèle"""
121
- async with aiohttp.ClientSession() as session:
122
- tasks = []
123
- for i in batch_indices:
124
- if not config['is_running']:
125
- break
126
-
127
- is_startup = random.random() < startup_ratio
128
- tasks.append(create_account_async(session, is_startup_rep=is_startup))
129
-
130
- if not tasks:
131
- return []
132
-
133
- results = await asyncio.gather(*tasks, return_exceptions=True)
134
-
135
- # Traiter les résultats
136
- batch_results = []
137
- for idx, result in zip(batch_indices, results):
138
- if isinstance(result, Exception):
139
- config['progress']['failed'] += 1
140
- config['progress']['last_status'] = f"Échec de la création du compte {idx+1}: {str(result)}"
141
- elif result.get('success', False):
142
- config['progress']['success'] += 1
143
- config['progress']['last_username'] = result['username']
144
- config['progress']['last_status'] = f"Compte {idx+1} créé avec succès"
145
- accounts.append(result)
146
- batch_results.append(result)
147
- else:
148
- config['progress']['failed'] += 1
149
- config['progress']['last_status'] = f"Échec de la création du compte {idx+1}: {result.get('error', 'Erreur inconnue')}"
150
-
151
- config['progress']['current'] = idx + 1
152
-
153
- return batch_results
154
-
155
- # Fonction principale pour créer des comptes de manière asynchrone
156
- async def create_accounts_async(num_accounts, startup_ratio=0.3):
157
- """Crée plusieurs comptes en parallèle de manière asynchrone"""
158
- # Charger les comptes existants
159
- accounts = []
160
- if os.path.exists(config['accounts_file']):
161
- try:
162
- with open(config['accounts_file'], 'r') as f:
163
- accounts = json.load(f)
164
- except:
165
- accounts = []
166
-
167
- # Traiter les comptes par lots
168
- batch_size = config['batch_size']
169
- for start_idx in range(0, num_accounts, batch_size):
170
- if not config['is_running']:
171
- break
172
-
173
- end_idx = min(start_idx + batch_size, num_accounts)
174
- batch_indices = list(range(start_idx, end_idx))
175
-
176
- # Traiter un lot de comptes
177
- await process_batch(batch_indices, startup_ratio, accounts)
178
-
179
- # Enregistrer les données après chaque lot
180
- with open(config['accounts_file'], 'w') as f:
181
- json.dump(accounts, f, indent=2)
182
-
183
- # Petite pause pour éviter de surcharger le serveur
184
- await asyncio.sleep(1)
185
-
186
- return accounts
187
-
188
- # Fonction pour lancer la création de comptes en arrière-plan
189
- def create_accounts_background(num_accounts, startup_ratio=0.3):
190
- config['progress'] = {
191
- 'total': num_accounts,
192
- 'current': 0,
193
- 'success': 0,
194
- 'failed': 0,
195
- 'last_username': '',
196
- 'last_status': 'Démarrage...',
197
- 'start_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
198
- 'end_time': None
199
- }
200
 
201
- # Créer une boucle asyncio dans un nouveau thread
202
- loop = asyncio.new_event_loop()
203
- asyncio.set_event_loop(loop)
204
 
205
  try:
206
- accounts = loop.run_until_complete(create_accounts_async(num_accounts, startup_ratio))
 
207
 
208
- # Mise à jour finale
209
- config['progress']['end_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
210
- config['progress']['last_status'] = "Terminé"
 
 
 
 
 
211
 
212
- # Enregistrement final
213
- with open(config['accounts_file'], 'w') as f:
214
- json.dump(accounts, f, indent=2)
215
-
216
  except Exception as e:
217
- config['progress']['last_status'] = f"Erreur: {str(e)}"
218
- finally:
219
- config['is_running'] = False
220
- loop.close()
221
-
222
- # Routes Flask
223
- @app.route('/')
224
- def index():
225
- return render_template('index.html', config=config)
226
-
227
- @app.route('/start', methods=['POST'])
228
- def start():
229
- if config['is_running']:
230
- return jsonify({"status": "error", "message": "Une génération est déjà en cours"})
231
-
232
- num_accounts = int(request.form.get('num_accounts', 10))
233
- startup_ratio = float(request.form.get('startup_ratio', 0.3))
234
- batch_size = int(request.form.get('batch_size', config['batch_size']))
235
-
236
- # Mettre à jour la taille du lot
237
- config['batch_size'] = min(batch_size, 20) # Limiter à 20 pour éviter de surcharger le serveur
238
- config['is_running'] = True
239
 
240
- # Démarrer le processus en arrière-plan
241
- thread = threading.Thread(target=create_accounts_background, args=(num_accounts, startup_ratio))
242
- thread.daemon = True
243
- thread.start()
244
 
245
- return jsonify({"status": "success", "message": "Génération démarrée"})
246
-
247
- @app.route('/stop', methods=['POST'])
248
- def stop():
249
- config['is_running'] = False
250
- return jsonify({"status": "success", "message": "Arrêt demandé"})
251
-
252
- @app.route('/progress')
253
- def progress():
254
- return jsonify(config['progress'])
255
-
256
- @app.route('/accounts')
257
- def view_accounts():
258
- page = int(request.args.get('page', 1))
259
- per_page = 20
260
-
261
- accounts = []
262
- if os.path.exists(config['accounts_file']):
263
- try:
264
- with open(config['accounts_file'], 'r') as f:
265
- accounts = json.load(f)
266
- except:
267
- accounts = []
268
-
269
- total_accounts = len(accounts)
270
- total_pages = (total_accounts + per_page - 1) // per_page
271
 
272
- start_idx = (page - 1) * per_page
273
- end_idx = start_idx + per_page
274
-
275
- current_accounts = accounts[start_idx:end_idx]
276
-
277
- return render_template(
278
- 'accounts.html',
279
- accounts=current_accounts,
280
- page=page,
281
- total_pages=total_pages,
282
- total_accounts=total_accounts
283
- )
284
-
285
- @app.route('/script.js')
286
- def serve_js():
287
- return render_template('script.js'), 200, {'Content-Type': 'application/javascript'}
288
-
289
- @app.route('/clear', methods=['POST'])
290
- def clear_accounts():
291
- """Supprime tous les comptes enregistrés"""
292
- if os.path.exists(config['accounts_file']):
293
- try:
294
- os.remove(config['accounts_file'])
295
- return jsonify({"status": "success", "message": "Données des comptes supprimées"})
296
- except Exception as e:
297
- return jsonify({"status": "error", "message": f"Erreur lors de la suppression: {str(e)}"})
298
- return jsonify({"status": "success", "message": "Aucun fichier à supprimer"})
299
 
300
  if __name__ == '__main__':
301
  app.run(debug=True)
 
1
+ from flask import Flask, render_template, request, jsonify, session
2
+ from google import genai
 
 
 
 
 
 
3
  import os
 
4
  from datetime import datetime
5
+ import uuid
6
 
7
  app = Flask(__name__)
8
+ app.secret_key = os.urandom(24) # Requis pour utiliser les sessions Flask
9
 
10
+ # Configuration de l'API Gemini (idéalement à déplacer dans un fichier de configuration)
11
+ # os.environ["GOOGLE_API_KEY"] = "VOTRE_GEMINI_API_KEY"
12
+ client = genai.Client(api_key=os.environ.get("GOOGLE_API_KEY", "GEMINI_API_KEY"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ @app.route('/')
15
+ def index():
16
+ # Créer un ID de session unique s'il n'existe pas déjà
17
+ if 'session_id' not in session:
18
+ session['session_id'] = str(uuid.uuid4())
19
+ return render_template('index.html')
20
+
21
+ @app.route('/chat', methods=['POST'])
22
+ def chat():
23
+ data = request.json
24
+ user_message = data.get('message', '')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
+ # Récupérer ou créer une session de chat pour cet utilisateur
27
+ session_id = session.get('session_id')
28
+ chat_session = get_or_create_chat_session(session_id)
29
 
30
  try:
31
+ # Envoyer le message à Gemini et obtenir la réponse
32
+ response = chat_session.send_message(user_message)
33
 
34
+ # Formater l'historique pour l'interface
35
+ history = []
36
+ for msg in chat_session.get_history():
37
+ history.append({
38
+ 'role': msg.role,
39
+ 'content': msg.parts[0].text,
40
+ 'timestamp': datetime.now().strftime("%H:%M")
41
+ })
42
 
43
+ return jsonify({
44
+ 'response': response.text,
45
+ 'history': history
46
+ })
47
  except Exception as e:
48
+ return jsonify({'error': str(e)}), 500
49
+
50
+ def get_or_create_chat_session(session_id):
51
+ """
52
+ Récupère une session de chat existante ou en crée une nouvelle.
53
+ Dans une application réelle, vous pourriez stocker cela dans une base de données.
54
+ """
55
+ # Utilisation d'un dictionnaire global pour stocker les sessions (pour cet exemple)
56
+ # Dans une application réelle, utilisez Redis ou une base de données
57
+ if not hasattr(app, 'chat_sessions'):
58
+ app.chat_sessions = {}
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ if session_id not in app.chat_sessions:
61
+ app.chat_sessions[session_id] = client.chats.create(model="gemini-2.0-flash")
 
 
62
 
63
+ return app.chat_sessions[session_id]
64
+
65
+ @app.route('/reset', methods=['POST'])
66
+ def reset_chat():
67
+ """Réinitialise la session de chat actuelle"""
68
+ session_id = session.get('session_id')
69
+ if hasattr(app, 'chat_sessions') and session_id in app.chat_sessions:
70
+ # Créer une nouvelle session
71
+ app.chat_sessions[session_id] = client.chats.create(model="gemini-2.0-flash")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ return jsonify({'status': 'success'})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  if __name__ == '__main__':
76
  app.run(debug=True)