neop3 commited on
Commit
b4e5fe0
Β·
verified Β·
1 Parent(s): fbb5abb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -337
app.py CHANGED
@@ -1,344 +1,19 @@
1
- import collections
2
- import collections.abc
3
- if not hasattr(collections, "Iterable"):
4
- collections.Iterable = collections.abc.Iterable
5
-
6
- import os
7
- import sys
8
- import json
9
- import logging
10
- import tempfile
11
- import asyncio
12
- import threading
13
- import time
14
- import traceback
15
  from http.server import HTTPServer, BaseHTTPRequestHandler
16
- from datetime import datetime, timedelta
17
 
18
- # ──────────────────────────────────────────────
19
- # LOGGING - En başta olsun
20
- # ──────────────────────────────────────────────
21
- logging.basicConfig(
22
- format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
23
- level=logging.INFO,
24
- )
25
  logger = logging.getLogger(__name__)
26
 
27
- # ──────────────────────────────────────────────
28
- # HEALTH CHECK - HER ŞEYDEN Γ–NCE BAŞLAT
29
- # ──────────────────────────────────────────────
30
- bot_status = "starting"
31
-
32
- class HealthHandler(BaseHTTPRequestHandler):
33
  def do_GET(self):
34
  self.send_response(200)
35
- self.send_header("Content-Type", "text/html")
36
- self.end_headers()
37
- html = f"""
38
- <html>
39
- <head><title>Bot Status</title></head>
40
- <body>
41
- <h1>Bot Status: {bot_status}</h1>
42
- <p>Time: {datetime.now().isoformat()}</p>
43
- </body>
44
- </html>
45
- """
46
- self.wfile.write(html.encode())
47
-
48
- def do_HEAD(self):
49
- self.send_response(200)
50
  self.end_headers()
51
-
52
- def log_message(self, format, *args):
53
- pass # Sustur
54
-
55
- def start_health_server():
56
- port = int(os.environ.get("PORT", 7860))
57
- server = HTTPServer(("0.0.0.0", port), HealthHandler)
58
- logger.info(f"Health check server started on 0.0.0.0:{port}")
59
- server.serve_forever()
60
-
61
- # β˜…β˜…β˜… HEALTH SERVER'I HEMEN BAŞLAT β˜…β˜…β˜…
62
- # Bu satır modül yüklenirken çalışır - HF bunu gârür ve "Running" yapar
63
- health_thread = threading.Thread(target=start_health_server, daemon=True)
64
- health_thread.start()
65
- time.sleep(1) # Bind olmasΔ±nΔ± garantile
66
- logger.info("βœ… Health check server is UP")
67
-
68
- # ──────────────────────────────────────────────
69
- # ŞİMDİ GERİ KALAN İMPORTLAR
70
- # ──────────────────────────────────────────────
71
- try:
72
- from pySmartDL import SmartDL
73
- from pydrive2.auth import GoogleAuth
74
- from pydrive2.drive import GoogleDrive
75
- from oauth2client.service_account import ServiceAccountCredentials
76
- from telegram import Update
77
- from telegram.ext import (
78
- ApplicationBuilder,
79
- CommandHandler,
80
- MessageHandler,
81
- filters,
82
- ContextTypes,
83
- )
84
- from apscheduler.schedulers.asyncio import AsyncIOScheduler
85
- logger.info("βœ… All imports successful")
86
- except Exception as e:
87
- logger.error(f"❌ Import error: {e}")
88
- traceback.print_exc()
89
- # Health server hala çalışıyor, en azından HF "Running" gâsterir
90
- bot_status = f"import_error: {e}"
91
- while True:
92
- time.sleep(3600)
93
-
94
- # ──────────────────────────────────────────────
95
- # ENV VARIABLES
96
- # ──────────────────────────────────────────────
97
- BOT_TOKEN = os.getenv("BOT_TOKEN")
98
- GDRIVE_SERVICE_ACCOUNT_JSON = os.getenv("GDRIVE_SERVICE_ACCOUNT_JSON")
99
- GDRIVE_FOLDER_ID = os.getenv("GDRIVE_FOLDER_ID")
100
- AUTHORIZED_USER_ID = os.getenv("AUTHORIZED_USER_ID")
101
-
102
- if AUTHORIZED_USER_ID:
103
- try:
104
- AUTHORIZED_USER_ID = int(AUTHORIZED_USER_ID)
105
- except ValueError:
106
- logger.error("AUTHORIZED_USER_ID is not a valid integer")
107
- AUTHORIZED_USER_ID = None
108
-
109
- logger.info(f"BOT_TOKEN set: {bool(BOT_TOKEN)}")
110
- logger.info(f"GDRIVE_SERVICE_ACCOUNT_JSON set: {bool(GDRIVE_SERVICE_ACCOUNT_JSON)}")
111
- logger.info(f"GDRIVE_FOLDER_ID set: {bool(GDRIVE_FOLDER_ID)}")
112
- logger.info(f"AUTHORIZED_USER_ID: {AUTHORIZED_USER_ID}")
113
-
114
- # ──────────────────────────────────────────────
115
- # GLOBALS
116
- # ──────────────────────────────────────────────
117
- drive_client = None
118
- processing_lock = None
119
- scheduler = None
120
-
121
- # ───────────────────────────────────────���──────
122
- # GOOGLE DRIVE AUTH
123
- # ──────────────────────────────────────────────
124
- def get_gdrive_client():
125
- global drive_client
126
-
127
- if not GDRIVE_SERVICE_ACCOUNT_JSON:
128
- logger.error("GDRIVE_SERVICE_ACCOUNT_JSON is empty")
129
- return None
130
-
131
- try:
132
- with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json") as tmp:
133
- tmp.write(GDRIVE_SERVICE_ACCOUNT_JSON)
134
- tmp_path = tmp.name
135
-
136
- scope = ["https://www.googleapis.com/auth/drive"]
137
- gauth = GoogleAuth()
138
- gauth.auth_method = "service"
139
- gauth.credentials = ServiceAccountCredentials.from_json_keyfile_name(tmp_path, scope)
140
- drive_client = GoogleDrive(gauth)
141
-
142
- os.unlink(tmp_path)
143
- logger.info("βœ… Google Drive authenticated")
144
- return drive_client
145
- except Exception as e:
146
- logger.error(f"❌ Google Drive auth error: {e}")
147
- traceback.print_exc()
148
- return None
149
-
150
- # ──────────────────────────────────────────────
151
- # AUTO DELETE
152
- # ──────────────────────────────────────────────
153
- async def delete_from_drive(file_id: str):
154
- try:
155
- global drive_client
156
- if not drive_client:
157
- drive_client = await asyncio.to_thread(get_gdrive_client)
158
- if drive_client:
159
- gfile = await asyncio.to_thread(drive_client.CreateFile, {"id": file_id})
160
- await asyncio.to_thread(gfile.Delete)
161
- logger.info(f"πŸ—‘ Deleted {file_id} from Drive")
162
- except Exception as e:
163
- logger.error(f"Delete error ({file_id}): {e}")
164
-
165
- # ──────────────────────────────────────────────
166
- # DOWNLOAD & UPLOAD
167
- # ──────────────────────────────────────────────
168
- def download_file(url, dest_dir):
169
- obj = SmartDL(url, dest_dir, progress_bar=False, timeout=120)
170
- obj.start()
171
- return obj
172
-
173
- def upload_file(file_path, file_name):
174
- global drive_client
175
- if not drive_client:
176
- drive_client = get_gdrive_client()
177
- if not drive_client:
178
- raise RuntimeError("Drive client not available")
179
-
180
- metadata = {"title": file_name}
181
- if GDRIVE_FOLDER_ID:
182
- metadata["parents"] = [{"id": GDRIVE_FOLDER_ID}]
183
-
184
- gfile = drive_client.CreateFile(metadata)
185
- gfile.SetContentFile(file_path)
186
- gfile.Upload()
187
- return gfile
188
-
189
- # ──────────────────────────────────────────────
190
- # TELEGRAM HANDLERS
191
- # ──────────────────────────────────────────────
192
- async def cmd_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
193
- if AUTHORIZED_USER_ID and update.effective_user.id != AUTHORIZED_USER_ID:
194
- return
195
- await update.message.reply_text(
196
- "Merhaba! Bana bir direkt indirme linki gΓΆnder, "
197
- "senin iΓ§in Google Drive'a yΓΌkleyeyim. πŸš€"
198
- )
199
-
200
- async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
201
- global processing_lock, scheduler
202
-
203
- if AUTHORIZED_USER_ID and update.effective_user.id != AUTHORIZED_USER_ID:
204
- return
205
-
206
- url = update.message.text.strip()
207
- if not url.startswith(("http://", "https://")):
208
- await update.message.reply_text("β›” GeΓ§ersiz link.")
209
- return
210
-
211
- async with processing_lock:
212
- status_msg = await update.message.reply_text("⏳ Başlatılıyor...")
213
- file_path = None
214
-
215
- try:
216
- dest = os.path.join(os.getcwd(), "downloads")
217
- os.makedirs(dest, exist_ok=True)
218
-
219
- await status_msg.edit_text("πŸ“₯ Δ°ndiriliyor...")
220
- obj = await asyncio.to_thread(download_file, url, dest)
221
-
222
- if not obj.isSuccessful():
223
- await status_msg.edit_text("❌ İndirme başarısız.")
224
- return
225
-
226
- file_path = obj.get_dest()
227
- file_name = os.path.basename(file_path)
228
- file_size = os.path.getsize(file_path)
229
-
230
- if file_size > 5 * 1024 * 1024 * 1024:
231
- await status_msg.edit_text(
232
- f"⚠️ Dosya çok büyük ({file_size / (1024**3):.2f} GB). Max 5GB."
233
- )
234
- os.remove(file_path)
235
- file_path = None
236
- return
237
-
238
- size_str = (
239
- f"{file_size / (1024**2):.1f} MB"
240
- if file_size > 1024 * 1024
241
- else f"{file_size / 1024:.1f} KB"
242
- )
243
-
244
- await status_msg.edit_text(
245
- f"βœ… Δ°ndirildi: `{file_name}` ({size_str})\nπŸ“€ Drive'a yΓΌkleniyor...",
246
- parse_mode="Markdown",
247
- )
248
-
249
- gfile = await asyncio.to_thread(upload_file, file_path, file_name)
250
-
251
- file_id = gfile["id"]
252
- drive_link = gfile.get(
253
- "alternateLink",
254
- f"https://drive.google.com/file/d/{file_id}/view",
255
- )
256
-
257
- await status_msg.edit_text(
258
- f"πŸš€ YΓΌkleme başarΔ±lΔ±!\n\n"
259
- f"πŸ“ `{file_name}`\n"
260
- f"πŸ“¦ {size_str}\n"
261
- f"πŸ”— {drive_link}\n\n"
262
- f"⏱ 2 saat sonra otomatik silinecek.",
263
- parse_mode="Markdown",
264
- )
265
-
266
- if file_path and os.path.exists(file_path):
267
- os.remove(file_path)
268
- file_path = None
269
-
270
- run_date = datetime.now() + timedelta(hours=2)
271
- scheduler.add_job(delete_from_drive, "date", run_date=run_date, args=[file_id])
272
-
273
- except Exception as e:
274
- logger.error(f"Processing error: {e}", exc_info=True)
275
- try:
276
- await status_msg.edit_text(f"❌ Hata: `{e}`", parse_mode="Markdown")
277
- except Exception:
278
- pass
279
- finally:
280
- if file_path and os.path.exists(file_path):
281
- try:
282
- os.remove(file_path)
283
- except OSError:
284
- pass
285
-
286
- # ──────────────────────────────────────────────
287
- # MAIN
288
- # ──────────────────────────────────────────────
289
- def main():
290
- global processing_lock, scheduler, bot_status
291
-
292
- if not BOT_TOKEN:
293
- logger.error("❌ BOT_TOKEN not set!")
294
- bot_status = "error: no BOT_TOKEN"
295
- while True:
296
- time.sleep(3600)
297
-
298
- try:
299
- # Google Drive
300
- get_gdrive_client()
301
-
302
- # Telegram app
303
- application = (
304
- ApplicationBuilder()
305
- .token(BOT_TOKEN)
306
- .connect_timeout(30)
307
- .read_timeout(30)
308
- .write_timeout(30)
309
- .build()
310
- )
311
-
312
- application.add_handler(CommandHandler("start", cmd_start))
313
- application.add_handler(
314
- MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message)
315
- )
316
-
317
- # post_init: event loop hazır, lock ve scheduler başlat
318
- async def post_init(app):
319
- global processing_lock, scheduler, bot_status
320
- processing_lock = asyncio.Lock()
321
- scheduler = AsyncIOScheduler()
322
- scheduler.start()
323
- bot_status = "running"
324
- logger.info("βœ… Bot fully initialized - scheduler & lock ready")
325
-
326
- application.post_init = post_init
327
-
328
- logger.info("πŸ€– Starting polling...")
329
- bot_status = "polling"
330
- application.run_polling(
331
- allowed_updates=Update.ALL_TYPES,
332
- drop_pending_updates=True,
333
- )
334
-
335
- except Exception as e:
336
- logger.error(f"❌ Fatal error: {e}", exc_info=True)
337
- bot_status = f"fatal_error: {e}"
338
- # Health server hala çalışıyor, container âlmesin
339
- while True:
340
- time.sleep(3600)
341
-
342
-
343
- if __name__ == "__main__":
344
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from http.server import HTTPServer, BaseHTTPRequestHandler
2
+ import logging
3
 
4
+ logging.basicConfig(level=logging.INFO)
 
 
 
 
 
 
5
  logger = logging.getLogger(__name__)
6
 
7
+ class Handler(BaseHTTPRequestHandler):
 
 
 
 
 
8
  def do_GET(self):
9
  self.send_response(200)
10
+ self.send_header("Content-Type", "text/plain")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  self.end_headers()
12
+ self.wfile.write(b"OK")
13
+ def log_message(self, *args):
14
+ pass
15
+
16
+ logger.info("Starting server on 7860...")
17
+ server = HTTPServer(("0.0.0.0", 7860), Handler)
18
+ logger.info("Server is running!")
19
+ server.serve_forever()