forked from prdp1137/huntPastebin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
huntPastebin.py
119 lines (107 loc) · 4.17 KB
/
huntPastebin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import argparse
import aiohttp
import asyncio
import os
class APIDownError(Exception):
pass
async def fetch(session, url):
try:
async with session.get(url) as response:
if response.status == 502:
raise APIDownError("API is down. Please try again later.")
response.raise_for_status()
return await response.json()
except aiohttp.ClientResponseError as e:
raise e
async def fetch_and_save_content(url, file_path, session, semaphore, rate_limit):
async with semaphore:
try:
content_data = await fetch(session, url)
with open(file_path, 'w', encoding='utf-8') as file:
file.write(content_data['content'])
print(f"File saved: {file_path}") # Progress reporting
except APIDownError:
# Reraise APIDownError to stop all tasks
raise
except Exception as e:
print(f"Failed to fetch content from {url}. Skipping. Error: {e}")
await asyncio.sleep(rate_limit) # Apply rate limiting
async def scrape(url, dir_name, session, semaphore, rate_limit):
print("Searching pastebin...")
try:
data = await fetch(session, url)
except APIDownError:
print("Stopping all tasks due to API downtime.")
raise
except Exception as e:
print(f"Error during search: {e}")
return
ids = [entry['id'] for entry in data]
if not ids:
print(f"No data found for {url}. No files to save.")
return
os.makedirs(dir_name, exist_ok=True)
tasks = [
fetch_and_save_content(
f"https://psbdmp.ws/api/v3/dump/{id}",
os.path.join(dir_name, f"{id}.txt"),
session,
semaphore,
rate_limit
)
for id in ids
]
try:
await asyncio.gather(*tasks)
# Optional: Remove directory if no files were saved
if not any(os.path.isfile(os.path.join(dir_name, f"{id}.txt")) for id in ids):
os.rmdir(dir_name)
except APIDownError:
print("Stopping all tasks due to API downtime.")
except Exception as e:
print(f"Error during task execution: {e}")
else:
print(f"Task completed. Content saved in '{dir_name}' directory.")
async def main(args):
semaphore = asyncio.Semaphore(args.threads) # Limit number of concurrent requests
async with aiohttp.ClientSession() as session:
rate_limit = args.rate_limit
try:
if args.general:
await scrape(
f"https://psbdmp.ws/api/search/{args.general}",
os.path.join("general", args.general),
session,
semaphore,
rate_limit
)
elif args.email:
await scrape(
f"https://psbdmp.ws/api/search/email/{args.email}",
os.path.join("email", args.email),
session,
semaphore,
rate_limit
)
elif args.domain:
await scrape(
f"https://psbdmp.ws/api/search/domain/{args.domain}",
os.path.join("domain", args.domain),
session,
semaphore,
rate_limit
)
except APIDownError:
print("API is down. Exiting.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Search for domains, emails, or perform a general search.")
parser.add_argument('-g', dest='general', metavar='TERM', help='Perform a general search')
parser.add_argument('-e', dest='email', metavar='EMAIL', help='Search for emails')
parser.add_argument('-d', dest='domain', metavar='DOMAIN', help='Search for domains')
parser.add_argument('-t', dest='threads', type=int, default=10, help='Number of threads (default: 10)')
parser.add_argument('-r', dest='rate_limit', type=float, default=0, help='Rate limit in seconds between requests (default: 0)')
args = parser.parse_args()
if not any(vars(args).values()):
parser.print_help()
exit(0)
asyncio.run(main(args))