PandaAPI 1.0.5__tar.gz → 1.0.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PKG-INFO +1 -1
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/dark.py +62 -25
- pandaapi-1.0.7/PandaAPI/modules/media.py +1 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI.egg-info/PKG-INFO +1 -1
- {pandaapi-1.0.5 → pandaapi-1.0.7}/pyproject.toml +1 -1
- {pandaapi-1.0.5 → pandaapi-1.0.7}/setup.py +1 -1
- pandaapi-1.0.5/PandaAPI/modules/media.py +0 -35
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/__init__.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/func.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/__init__.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/ai.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/crypto.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/network.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/osint.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/telegram.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI/modules/tools.py +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI.egg-info/SOURCES.txt +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI.egg-info/dependency_links.txt +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI.egg-info/requires.txt +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/PandaAPI.egg-info/top_level.txt +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/README.md +0 -0
- {pandaapi-1.0.5 → pandaapi-1.0.7}/setup.cfg +0 -0
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import requests
|
|
2
|
-
import
|
|
3
|
-
import string
|
|
4
|
-
import time
|
|
2
|
+
import re
|
|
5
3
|
|
|
6
4
|
|
|
7
5
|
def fake_identity(country: str = "US") -> dict:
|
|
@@ -29,7 +27,6 @@ def fake_identity(country: str = "US") -> dict:
|
|
|
29
27
|
|
|
30
28
|
def temp_mail_create() -> dict:
|
|
31
29
|
try:
|
|
32
|
-
# create session with Guerrilla Mail
|
|
33
30
|
r = requests.get(
|
|
34
31
|
"https://api.guerrillamail.com/ajax.php?f=get_email_address&lang=en",
|
|
35
32
|
timeout=10,
|
|
@@ -74,10 +71,7 @@ def temp_mail_read(sid_token: str, mail_id: str) -> dict:
|
|
|
74
71
|
timeout=10,
|
|
75
72
|
).json()
|
|
76
73
|
body = r.get("mail_body", "")
|
|
77
|
-
# extract OTP - look for 4-8 digit codes
|
|
78
|
-
import re
|
|
79
74
|
otp_patterns = re.findall(r'\b\d{4,8}\b', body)
|
|
80
|
-
# extract verification links
|
|
81
75
|
links = re.findall(r'https?://[^\s<>"]+', body)
|
|
82
76
|
verify_links = [l for l in links if any(k in l.lower() for k in ['verify', 'confirm', 'activate', 'token', 'otp', 'code', 'click'])]
|
|
83
77
|
return {
|
|
@@ -114,34 +108,77 @@ def dark_joke() -> dict:
|
|
|
114
108
|
def lyrics(song: str, artist: str = "") -> dict:
|
|
115
109
|
try:
|
|
116
110
|
query = f"{artist} {song}".strip()
|
|
117
|
-
|
|
111
|
+
headers = {
|
|
112
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Method 1: lyrics.ovh (English songs)
|
|
118
116
|
if artist:
|
|
119
117
|
r = requests.get(
|
|
120
118
|
f"https://api.lyrics.ovh/v1/{requests.utils.quote(artist)}/{requests.utils.quote(song)}",
|
|
121
119
|
timeout=10,
|
|
122
120
|
)
|
|
123
121
|
if r.status_code == 200:
|
|
124
|
-
|
|
125
|
-
lyr
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
lyr = r.json().get("lyrics", "")
|
|
123
|
+
if lyr:
|
|
124
|
+
return {"song": song, "artist": artist, "lyrics": lyr, "source": "lyrics.ovh", "success": True}
|
|
125
|
+
|
|
126
|
+
# Method 2: Genius search scrape
|
|
127
|
+
search_r = requests.get(
|
|
128
|
+
f"https://api.genius.com/search?q={requests.utils.quote(query)}",
|
|
129
|
+
headers={**headers, "Authorization": "Bearer alXE5K2_D2ZJVMWKW7pWAbsOaOFWlEAzHmDNJY3CyGRTMh5z3HKFqSBJaWrHK2T9"},
|
|
130
|
+
timeout=10,
|
|
131
|
+
)
|
|
132
|
+
if search_r.status_code == 200:
|
|
133
|
+
hits = search_r.json().get("response", {}).get("hits", [])
|
|
134
|
+
if hits:
|
|
135
|
+
top = hits[0]["result"]
|
|
136
|
+
song_title = top.get("title", song)
|
|
137
|
+
artist_name = top.get("primary_artist", {}).get("name", artist)
|
|
138
|
+
song_url = top.get("url", "")
|
|
139
|
+
# scrape lyrics from genius page
|
|
140
|
+
page = requests.get(song_url, headers=headers, timeout=10)
|
|
141
|
+
from bs4 import BeautifulSoup
|
|
142
|
+
soup = BeautifulSoup(page.text, "html.parser")
|
|
143
|
+
# remove scripts
|
|
144
|
+
for s in soup.find_all("script"):
|
|
145
|
+
s.decompose()
|
|
146
|
+
containers = soup.find_all("div", attrs={"data-lyrics-container": "true"})
|
|
147
|
+
if containers:
|
|
148
|
+
lyr_parts = []
|
|
149
|
+
for c in containers:
|
|
150
|
+
for br in c.find_all("br"):
|
|
151
|
+
br.replace_with("\n")
|
|
152
|
+
lyr_parts.append(c.get_text())
|
|
153
|
+
lyr = "\n".join(lyr_parts).strip()
|
|
154
|
+
return {
|
|
155
|
+
"song": song_title,
|
|
156
|
+
"artist": artist_name,
|
|
157
|
+
"lyrics": lyr,
|
|
158
|
+
"genius_url": song_url,
|
|
159
|
+
"source": "genius",
|
|
160
|
+
"success": True,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# Method 3: lyrics.ovh suggest fallback
|
|
128
164
|
rs = requests.get(
|
|
129
165
|
f"https://api.lyrics.ovh/suggest/{requests.utils.quote(query)}",
|
|
130
166
|
timeout=10,
|
|
131
167
|
).json()
|
|
132
168
|
results = rs.get("data", [])
|
|
133
|
-
if
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
169
|
+
if results:
|
|
170
|
+
top = results[0]
|
|
171
|
+
artist_name = top.get("artist", {}).get("name", "")
|
|
172
|
+
title = top.get("title", "")
|
|
173
|
+
r2 = requests.get(
|
|
174
|
+
f"https://api.lyrics.ovh/v1/{requests.utils.quote(artist_name)}/{requests.utils.quote(title)}",
|
|
175
|
+
timeout=10,
|
|
176
|
+
)
|
|
177
|
+
if r2.status_code == 200:
|
|
178
|
+
lyr = r2.json().get("lyrics", "")
|
|
179
|
+
if lyr:
|
|
180
|
+
return {"song": title, "artist": artist_name, "lyrics": lyr, "source": "lyrics.ovh", "success": True}
|
|
181
|
+
|
|
182
|
+
return {"success": False, "error": "Lyrics not found — try English song name or add artist name"}
|
|
146
183
|
except Exception as e:
|
|
147
184
|
return {"success": False, "error": str(e)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aW1wb3J0IHJlcXVlc3RzCgoKZGVmIHl0X3NlYXJjaChxdWVyeTogc3RyKSAtPiBsaXN0OgogICAgdHJ5OgogICAgICAgIGltcG9ydCB5dF9kbHAKICAgICAgICB5ZGxfb3B0cyA9IHsKICAgICAgICAgICAgInF1aWV0IjogVHJ1ZSwKICAgICAgICAgICAgInNraXBfZG93bmxvYWQiOiBUcnVlLAogICAgICAgICAgICAiZXh0cmFjdF9mbGF0IjogVHJ1ZSwKICAgICAgICB9CiAgICAgICAgd2l0aCB5dF9kbHAuWW91dHViZURMKHlkbF9vcHRzKSBhcyB5ZGw6CiAgICAgICAgICAgIGluZm8gPSB5ZGwuZXh0cmFjdF9pbmZvKGYieXRzZWFyY2g1OntxdWVyeX0iLCBkb3dubG9hZD1GYWxzZSkKICAgICAgICAgICAgZW50cmllcyA9IGluZm8uZ2V0KCJlbnRyaWVzIiwgW10pCiAgICAgICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgInRpdGxlIjogZS5nZXQoInRpdGxlIiksCiAgICAgICAgICAgICAgICAgICAgInVybCI6IGYiaHR0cHM6Ly95b3V0dWJlLmNvbS93YXRjaD92PXtlLmdldCgnaWQnKX0iLAogICAgICAgICAgICAgICAgICAgICJkdXJhdGlvbiI6IGUuZ2V0KCJkdXJhdGlvbiIpLAogICAgICAgICAgICAgICAgICAgICJjaGFubmVsIjogZS5nZXQoImNoYW5uZWwiKSwKICAgICAgICAgICAgICAgICAgICAiaWQiOiBlLmdldCgiaWQiKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciBlIGluIGVudHJpZXMKICAgICAgICAgICAgXQogICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgIHJldHVybiBbeyJlcnJvciI6ICJ5dF9kbHAgbm90IGluc3RhbGxlZCIsICJzdWNjZXNzIjogRmFsc2V9XQoKCmRlZiB5dF90aHVtYih2aWRlb19pZDogc3RyKSAtPiBzdHI6CiAgICByZXR1cm4gZiJodHRwczovL2ltZy55b3V0dWJlLmNvbS92aS97dmlkZW9faWR9L21heHJlc2RlZmF1bHQuanBnIgoKCmRlZiBseXJpY3MoYXJ0aXN0OiBzdHIsIHRpdGxlOiBzdHIpIC0+IGRpY3Q6CiAgICAjIC0tLSBQcmltYXJ5OiBseXJpY3Mub3ZoIC0tLQogICAgdHJ5OgogICAgICAgIHVybCA9IGYiaHR0cHM6Ly9hcGkubHlyaWNzLm92aC92MS97YXJ0aXN0fS97dGl0bGV9IgogICAgICAgIHIgPSByZXF1ZXN0cy5nZXQodXJsLCB0aW1lb3V0PTgpCiAgICAgICAgaWYgci5zdGF0dXNfY29kZSA9PSAyMDA6CiAgICAgICAgICAgIGRhdGEgPSByLmpzb24oKQogICAgICAgICAgICBpZiBkYXRhLmdldCgibHlyaWNzIik6CiAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICJzdWNjZXNzIjogVHJ1ZSwKICAgICAgICAgICAgICAgICAgICAiYXJ0aXN0IjogYXJ0aXN0LAogICAgICAgICAgICAgICAgICAgICJ0aXRsZSI6IHRpdGxlLAogICAgICAgICAgICAgICAgICAgICJseXJpY3MiOiBkYXRhWyJseXJpY3MiXSwKICAgICAgICAgICAgICAgICAgICAic3luY2VkIjogRmFsc2UsCiAgICAgICAgICAgICAgICAgICAgInNvdXJjZSI6ICJseXJpY3Mub3ZoIiwKICAgICAgICAgICAgICAgIH0KICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwoKICAgICMgLS0tIEZhbGxiYWNrOiBscmNsaWIubmV0IC0tLQogICAgdHJ5OgogICAgICAgIHVybCA9ICJodHRwczovL2xyY2xpYi5uZXQvYXBpL2dldCIKICAgICAgICBwYXJhbXMgPSB7ImFydGlzdF9uYW1lIjogYXJ0aXN0LCAidHJhY2tfbmFtZSI6IHRpdGxlfQogICAgICAgIHIgPSByZXF1ZXN0cy5nZXQodXJsLCBwYXJhbXM9cGFyYW1zLCB0aW1lb3V0PTgpCiAgICAgICAgaWYgci5zdGF0dXNfY29kZSA9PSAyMDA6CiAgICAgICAgICAgIGRhdGEgPSByLmpzb24oKQogICAgICAgICAgICBzeW5jZWQgPSBkYXRhLmdldCgic3luY2VkTHlyaWNzIikKICAgICAgICAgICAgcGxhaW4gPSBkYXRhLmdldCgicGxhaW5MeXJpY3MiKQogICAgICAgICAgICBpZiBzeW5jZWQgb3IgcGxhaW46CiAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICJzdWNjZXNzIjogVHJ1ZSwKICAgICAgICAgICAgICAgICAgICAiYXJ0aXN0IjogYXJ0aXN0LAogICAgICAgICAgICAgICAgICAgICJ0aXRsZSI6IHRpdGxlLAogICAgICAgICAgICAgICAgICAgICJseXJpY3MiOiBzeW5jZWQgb3IgcGxhaW4sCiAgICAgICAgICAgICAgICAgICAgInN5bmNlZCI6IGJvb2woc3luY2VkKSwKICAgICAgICAgICAgICAgICAgICAic291cmNlIjogImxyY2xpYi5uZXQiLAogICAgICAgICAgICAgICAgfQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBwYXNzCgogICAgcmV0dXJuIHsic3VjY2VzcyI6IEZhbHNlLCAiZXJyb3IiOiAiTHlyaWNzIG5vdCBmb3VuZCBvbiBhbnkgc291cmNlIn0K
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def yt_search(query: str) -> list:
|
|
5
|
-
"""
|
|
6
|
-
Uses yt-dlp's ytsearch via a simple scrape-free approach.
|
|
7
|
-
Returns list of dicts with title, url, duration, channel.
|
|
8
|
-
"""
|
|
9
|
-
try:
|
|
10
|
-
import yt_dlp
|
|
11
|
-
|
|
12
|
-
ydl_opts = {
|
|
13
|
-
"quiet": True,
|
|
14
|
-
"skip_download": True,
|
|
15
|
-
"extract_flat": True,
|
|
16
|
-
}
|
|
17
|
-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
18
|
-
info = ydl.extract_info(f"ytsearch5:{query}", download=False)
|
|
19
|
-
entries = info.get("entries", [])
|
|
20
|
-
return [
|
|
21
|
-
{
|
|
22
|
-
"title": e.get("title"),
|
|
23
|
-
"url": f"https://youtube.com/watch?v={e.get('id')}",
|
|
24
|
-
"duration": e.get("duration"),
|
|
25
|
-
"channel": e.get("channel"),
|
|
26
|
-
"id": e.get("id"),
|
|
27
|
-
}
|
|
28
|
-
for e in entries
|
|
29
|
-
]
|
|
30
|
-
except ImportError:
|
|
31
|
-
return [{"error": "yt_dlp not installed", "success": False}]
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def yt_thumb(video_id: str) -> str:
|
|
35
|
-
return f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|