ImjerryCo commited on
Commit
116d186
·
verified ·
1 Parent(s): fa3040f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -137
app.py CHANGED
@@ -1,152 +1,99 @@
1
- #!/usr/bin/env python3
 
 
 
2
  import os
3
- import asyncio
4
- import re
5
- from telethon import TelegramClient, events
6
- from telethon.sessions import StringSession
7
- from aiohttp import web
8
-
9
- # ================= CONFIG =================
10
- API_ID = int(os.environ["API_ID"])
11
- API_HASH = os.environ["API_HASH"]
12
- STRING_SESSION = os.environ["STRING_SESSION"] # <-- YOUR STRING SESSION (USER)
13
-
14
- BYPASS_BOT = "Nick_Bypass_Bot" # without @
15
-
16
- API_HOST = "0.0.0.0" # REQUIRED for Hugging Face
17
- API_PORT = 7860 # REQUIRED for Hugging Face
18
- API_ROUTE = "/bypass"
19
-
20
- LINK_RE = re.compile(r"https?://\S+")
21
- ORIGINAL_RE = re.compile(r"Original Link.*?(https?://\S+)", re.S)
22
- BYPASSED_RE = re.compile(r"Bypassed Link.*?(https?://\S+)", re.S)
23
- # =========================================
24
-
25
- TG_PENDING = {} # user_id -> (original_link, event)
26
- API_PENDING = {} # api_link -> future
27
-
28
-
29
- # ---------- TELEGRAM USERBOT ----------
30
- async def start_userbot(client):
31
-
32
- @client.on(events.NewMessage(incoming=True))
33
- async def on_user_message(event):
34
- if not event.is_private:
35
- return
36
-
37
- text = event.raw_text or ""
38
- m = LINK_RE.search(text)
39
- if not m:
40
- return
41
-
42
- uid = event.sender_id
43
- link = m.group(0)
44
-
45
- if uid in TG_PENDING:
46
- return
47
-
48
- TG_PENDING[uid] = (link, event)
49
- await client.send_message(BYPASS_BOT, link)
50
-
51
- @client.on(events.NewMessage(from_users=BYPASS_BOT))
52
- async def on_bypass_reply(event):
53
- text = event.raw_text or ""
54
-
55
- m_byp = BYPASSED_RE.search(text)
56
- if not m_byp:
57
- return
58
-
59
- bypassed_link = m_byp.group(1)
60
- m_org = ORIGINAL_RE.search(text)
61
- original_link = m_org.group(1) if m_org else None
62
-
63
- # Telegram replies
64
- for uid, (olink, user_event) in list(TG_PENDING.items()):
65
- if original_link and olink != original_link:
66
- continue
67
-
68
- reply = (
69
- "╭─ 🔓 **Link Unlocked**\n"
70
- "│\n"
71
- "│ 🔗 **Original**\n"
72
- f"│ ┖ {olink}\n"
73
- "│\n"
74
- "│ 🚀 **Bypassed**\n"
75
- f"│ ┖ {bypassed_link}\n"
76
- "╰───────────────"
77
- )
78
-
79
- await user_event.reply(reply)
80
- TG_PENDING.pop(uid, None)
81
- break
82
-
83
- # API replies
84
- for link, fut in list(API_PENDING.items()):
85
- if original_link and link != original_link:
86
- continue
87
- if not fut.done():
88
- fut.set_result(bypassed_link)
89
- API_PENDING.pop(link, None)
90
- break
91
-
92
- print("🤫 Telegram userbot running (StringSession)")
93
-
94
-
95
- # ---------- API ----------
96
- async def api_bypass(request):
97
- link = request.query.get("link")
98
- if not link:
99
- return web.json_response({"error": "link parameter missing"})
100
-
101
- loop = asyncio.get_event_loop()
102
- future = loop.create_future()
103
- API_PENDING[link] = future
104
 
105
- await request.app["client"].send_message(BYPASS_BOT, link)
 
 
 
 
106
 
107
- try:
108
- bypassed = await asyncio.wait_for(future, timeout=40)
109
- except asyncio.TimeoutError:
110
- API_PENDING.pop(link, None)
111
- return web.json_response({"status": "timeout"})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
- return web.json_response({
114
- "status": "success",
115
- "original": link,
116
- "bypassed": bypassed
117
- })
118
 
119
 
120
- async def start_api(client):
121
- app = web.Application()
122
- app["client"] = client
123
- app.router.add_get(API_ROUTE, api_bypass)
124
 
125
- runner = web.AppRunner(app)
126
- await runner.setup()
127
- site = web.TCPSite(runner, API_HOST, API_PORT)
128
- await site.start()
129
 
130
- print(f"🌐 API RUNNING → https://<your-space>.hf.space{API_ROUTE}?link=")
 
131
 
132
 
133
- # ---------- MAIN ----------
134
- async def main():
135
- client = TelegramClient(
136
- StringSession(STRING_SESSION),
137
- API_ID,
138
- API_HASH
139
- )
140
 
141
- await client.connect()
142
- if not await client.is_user_authorized():
143
- raise RuntimeError("❌ String session is invalid or expired")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
- await start_api(client)
146
- await start_userbot(client)
 
147
 
148
- await client.run_until_disconnected()
 
 
149
 
 
 
150
 
151
- if __name__ == "__main__":
152
- asyncio.run(main())
 
 
1
+ from fastapi import FastAPI, UploadFile, File, Query, HTTPException
2
+ import shutil
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ import tempfile
5
  import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ from utils import (
8
+ check_image_nsfw,
9
+ check_video_nsfw,
10
+ download_file
11
+ )
12
 
13
+ app = FastAPI()
14
+
15
+ app.add_middleware(
16
+ CORSMiddleware,
17
+ allow_origins=["*"], # 🔥 allow all (change later if needed)
18
+ allow_credentials=True,
19
+ allow_methods=["*"],
20
+ allow_headers=["*"],
21
+ )
22
+
23
+ MAX_SIZE_MB = 25
24
+
25
+
26
+ @app.get("/health")
27
+ def health():
28
+ return {"status": "ok", "api": "live", "creator": "JerryCoder"}
29
+
30
+
31
+ def save_upload(file: UploadFile):
32
+ tmp = tempfile.NamedTemporaryFile(delete=False)
33
+
34
+ size = 0
35
+ with open(tmp.name, "wb") as buffer:
36
+ while chunk := file.file.read(1024 * 1024):
37
+ size += len(chunk)
38
+ if size > MAX_SIZE_MB * 1024 * 1024:
39
+ buffer.close()
40
+ os.remove(tmp.name)
41
+ raise HTTPException(status_code=413, detail="File too large (max 25MB)")
42
+ buffer.write(chunk)
43
 
44
+ return tmp.name
 
 
 
 
45
 
46
 
47
+ def is_video(filename):
48
+ return filename.lower().endswith((".mp4", ".mov", ".avi", ".mkv", ".webm"))
 
 
49
 
 
 
 
 
50
 
51
+ def is_image(filename):
52
+ return filename.lower().endswith((".jpg", ".jpeg", ".png", ".webp"))
53
 
54
 
55
+ @app.post("/detect")
56
+ async def detect(file: UploadFile = File(...)):
57
+ path = save_upload(file)
 
 
 
 
58
 
59
+ try:
60
+ if is_image(file.filename):
61
+ nsfw = check_image_nsfw(path)
62
+ return {"type": "image", "nsfw": nsfw}
63
+
64
+ elif is_video(file.filename):
65
+ nsfw = check_video_nsfw(path)
66
+ return {"type": "video", "nsfw": nsfw}
67
+
68
+ else:
69
+ raise HTTPException(status_code=400, detail="Unsupported file type")
70
+
71
+ finally:
72
+ if os.path.exists(path):
73
+ os.remove(path)
74
+
75
+
76
+ @app.get("/detect")
77
+ async def detect_url(url: str = Query(...)):
78
+ path = download_file(url)
79
+
80
+ try:
81
+ size_mb = os.path.getsize(path) / (1024 * 1024)
82
+ if size_mb > MAX_SIZE_MB:
83
+ os.remove(path)
84
+ raise HTTPException(status_code=413, detail="File too large (max 25MB)")
85
 
86
+ if is_image(url):
87
+ nsfw = check_image_nsfw(path)
88
+ return {"type": "image", "nsfw": nsfw}
89
 
90
+ elif is_video(url):
91
+ nsfw = check_video_nsfw(path)
92
+ return {"type": "video", "nsfw": nsfw}
93
 
94
+ else:
95
+ raise HTTPException(status_code=400, detail="Unsupported file type")
96
 
97
+ finally:
98
+ if os.path.exists(path):
99
+ os.remove(path)