user-scanner 1.0.4.2__py3-none-any.whl → 1.0.6.0__py3-none-any.whl
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.
- user_scanner/__init__.py +0 -1
- user_scanner/__main__.py +24 -17
- user_scanner/cli/banner.py +2 -0
- user_scanner/community/coderlegion.py +11 -31
- user_scanner/core/orchestrator.py +72 -15
- user_scanner/creator/devto.py +11 -29
- user_scanner/creator/hashnode.py +19 -17
- user_scanner/creator/itch_io.py +12 -33
- user_scanner/creator/kaggle.py +11 -29
- user_scanner/creator/medium.py +11 -10
- user_scanner/creator/patreon.py +18 -38
- user_scanner/creator/producthunt.py +16 -14
- user_scanner/dev/codeberg.py +11 -29
- user_scanner/dev/cratesio.py +11 -24
- user_scanner/dev/dockerhub.py +11 -27
- user_scanner/dev/github.py +23 -36
- user_scanner/dev/gitlab.py +18 -30
- user_scanner/dev/launchpad.py +11 -24
- user_scanner/dev/npmjs.py +22 -19
- user_scanner/dev/replit.py +11 -29
- user_scanner/donation/__init__.py +0 -0
- user_scanner/donation/buymeacoffee.py +22 -0
- user_scanner/donation/liberapay.py +36 -0
- user_scanner/gaming/chess_com.py +23 -34
- user_scanner/gaming/minecraft.py +24 -0
- user_scanner/gaming/monkeytype.py +6 -18
- user_scanner/gaming/osu.py +14 -34
- user_scanner/gaming/roblox.py +21 -31
- user_scanner/gaming/steam.py +15 -29
- user_scanner/social/bluesky.py +21 -32
- user_scanner/social/discord.py +12 -13
- user_scanner/social/instagram.py +11 -24
- user_scanner/social/mastodon.py +18 -38
- user_scanner/social/pinterest.py +16 -30
- user_scanner/social/reddit.py +16 -30
- user_scanner/social/snapchat.py +24 -37
- user_scanner/social/telegram.py +13 -18
- user_scanner/social/threads.py +11 -24
- user_scanner/social/x.py +14 -12
- user_scanner/social/youtube.py +37 -34
- user_scanner/utils/version.py +2 -0
- user_scanner/version.json +1 -1
- {user_scanner-1.0.4.2.dist-info → user_scanner-1.0.6.0.dist-info}/METADATA +12 -53
- user_scanner-1.0.6.0.dist-info/RECORD +55 -0
- user_scanner-1.0.4.2.dist-info/RECORD +0 -51
- {user_scanner-1.0.4.2.dist-info → user_scanner-1.0.6.0.dist-info}/WHEEL +0 -0
- {user_scanner-1.0.4.2.dist-info → user_scanner-1.0.6.0.dist-info}/entry_points.txt +0 -0
- {user_scanner-1.0.4.2.dist-info → user_scanner-1.0.6.0.dist-info}/licenses/LICENSE +0 -0
user_scanner/__init__.py
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
user_scanner/__main__.py
CHANGED
|
@@ -10,17 +10,20 @@ CATEGORY_MAPPING = {
|
|
|
10
10
|
"social": "social",
|
|
11
11
|
"creator": "creator",
|
|
12
12
|
"community": "community",
|
|
13
|
-
"gaming": "gaming"
|
|
13
|
+
"gaming": "gaming",
|
|
14
|
+
"donation": "donation"
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
|
|
16
18
|
def list_modules(category=None):
|
|
17
|
-
from user_scanner import dev, social, creator, community, gaming
|
|
19
|
+
from user_scanner import dev, social, creator, community, gaming, donation
|
|
18
20
|
packages = {
|
|
19
21
|
"dev": dev,
|
|
20
22
|
"social": social,
|
|
21
23
|
"creator": creator,
|
|
22
24
|
"community": community,
|
|
23
|
-
"gaming": gaming
|
|
25
|
+
"gaming": gaming,
|
|
26
|
+
"donation": donation
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
categories_to_list = [category] if category else packages.keys()
|
|
@@ -28,11 +31,13 @@ def list_modules(category=None):
|
|
|
28
31
|
for cat_name in categories_to_list:
|
|
29
32
|
package = packages[cat_name]
|
|
30
33
|
modules = load_modules(package)
|
|
31
|
-
print(Fore.MAGENTA +
|
|
34
|
+
print(Fore.MAGENTA +
|
|
35
|
+
f"\n== {cat_name.upper()} SITES =={Style.RESET_ALL}")
|
|
32
36
|
for module in modules:
|
|
33
37
|
site_name = module.__name__.split(".")[-1]
|
|
34
38
|
print(f" - {site_name}")
|
|
35
39
|
|
|
40
|
+
|
|
36
41
|
def main():
|
|
37
42
|
parser = argparse.ArgumentParser(
|
|
38
43
|
prog="user-scanner",
|
|
@@ -58,32 +63,32 @@ def main():
|
|
|
58
63
|
args = parser.parse_args()
|
|
59
64
|
|
|
60
65
|
if args.module and "." in args.module:
|
|
61
|
-
|
|
66
|
+
args.module = args.module.replace(".", "_")
|
|
62
67
|
|
|
63
68
|
if args.list:
|
|
64
69
|
list_modules(args.category)
|
|
65
70
|
return
|
|
66
71
|
|
|
67
|
-
|
|
68
72
|
# Special username checks before run
|
|
69
73
|
if (args.module == "x" or args.category == "social"):
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
if re.search(r"[^a-zA-Z0-9._-]", args.username):
|
|
75
|
+
print(
|
|
76
|
+
Fore.RED + f"[!] Username '{args.username}' contains unsupported special characters. X (Twitter) doesn't support these." + Style.RESET_ALL)
|
|
72
77
|
if (args.module == "bluesky" or args.category == "social"):
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
if re.search(r"[^a-zA-Z0-9\.-]", args.username):
|
|
79
|
+
print(
|
|
80
|
+
Fore.RED + f"[!] Username '{args.username}' contains unsupported special characters. Bluesky will throw error. (Supported: only hyphens and digits)" + Style.RESET_ALL + "\n")
|
|
75
81
|
if not args.username:
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
parser.print_help()
|
|
83
|
+
return
|
|
78
84
|
else:
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
print_banner()
|
|
81
86
|
|
|
82
|
-
from user_scanner import dev, social, creator, community, gaming
|
|
87
|
+
from user_scanner import dev, social, creator, community, gaming, donation
|
|
83
88
|
|
|
84
89
|
if args.module:
|
|
85
90
|
# Single module search across all categories
|
|
86
|
-
packages = [dev, social, creator, community, gaming]
|
|
91
|
+
packages = [dev, social, creator, community, gaming, donation]
|
|
87
92
|
found = False
|
|
88
93
|
for package in packages:
|
|
89
94
|
modules = load_modules(package)
|
|
@@ -94,7 +99,8 @@ def main():
|
|
|
94
99
|
run_module_single(module, args.username)
|
|
95
100
|
found = True
|
|
96
101
|
if not found:
|
|
97
|
-
print(
|
|
102
|
+
print(
|
|
103
|
+
Fore.RED + f"[!] Module '{args.module}' not found in any category." + Style.RESET_ALL)
|
|
98
104
|
elif args.category:
|
|
99
105
|
# Category-wise scan
|
|
100
106
|
category_package = eval(CATEGORY_MAPPING[args.category])
|
|
@@ -104,5 +110,6 @@ def main():
|
|
|
104
110
|
# Full scan
|
|
105
111
|
run_checks(args.username)
|
|
106
112
|
|
|
113
|
+
|
|
107
114
|
if __name__ == "__main__":
|
|
108
115
|
main()
|
user_scanner/cli/banner.py
CHANGED
|
@@ -23,10 +23,12 @@ INFO_BOX = f"""{C_MAGENTA} ╔═══════════════
|
|
|
23
23
|
║ {C_RED}♚ {C_GREEN}Email{C_WHITE} : kaifcodec@gmail.com {C_MAGENTA}║
|
|
24
24
|
══════════════════════════════════════════{Style.RESET_ALL}""".strip()
|
|
25
25
|
|
|
26
|
+
|
|
26
27
|
def print_banner():
|
|
27
28
|
print(BANNER_ASCII)
|
|
28
29
|
print(INFO_BOX)
|
|
29
30
|
print(" ")
|
|
30
31
|
|
|
32
|
+
|
|
31
33
|
if __name__ == "__main__":
|
|
32
34
|
print_banner()
|
|
@@ -1,39 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from user_scanner.core.orchestrator import status_validate
|
|
2
|
+
|
|
3
3
|
|
|
4
4
|
def validate_coderlegion(user):
|
|
5
5
|
url = f"https://coderlegion.com/user/{user}"
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
|
|
9
|
-
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
10
|
-
'Accept-Encoding': "gzip, deflate, br",
|
|
11
|
-
'Accept-Language': "en-US,en;q=0.9",
|
|
12
|
-
}
|
|
13
|
-
try:
|
|
14
|
-
response = httpx.get(url, headers=headers, timeout = 15.0)
|
|
15
|
-
status = response.status_code
|
|
16
|
-
|
|
17
|
-
if status == 200:
|
|
18
|
-
return 0
|
|
19
|
-
elif status == 404:
|
|
20
|
-
return 1
|
|
21
|
-
else:
|
|
22
|
-
return 2
|
|
7
|
+
return status_validate(url, 404, 200, timeout=15.0)
|
|
23
8
|
|
|
24
|
-
except (ConnectError, TimeoutException):
|
|
25
|
-
return 2
|
|
26
|
-
except Exception:
|
|
27
|
-
return 2
|
|
28
9
|
|
|
29
10
|
if __name__ == "__main__":
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if result == 1:
|
|
34
|
-
print("Available!")
|
|
35
|
-
elif result == 0:
|
|
36
|
-
print("Unavailable!")
|
|
37
|
-
else:
|
|
38
|
-
print("Error occured!")
|
|
11
|
+
user = input("Username?: ").strip()
|
|
12
|
+
result = validate_coderlegion(user)
|
|
39
13
|
|
|
14
|
+
if result == 1:
|
|
15
|
+
print("Available!")
|
|
16
|
+
elif result == 0:
|
|
17
|
+
print("Unavailable!")
|
|
18
|
+
else:
|
|
19
|
+
print("Error occured!")
|
|
@@ -3,10 +3,14 @@ import pkgutil
|
|
|
3
3
|
from colorama import Fore, Style
|
|
4
4
|
import threading
|
|
5
5
|
|
|
6
|
+
import httpx
|
|
7
|
+
from httpx import ConnectError, TimeoutException
|
|
8
|
+
|
|
6
9
|
lock = threading.Condition()
|
|
7
|
-
#Basically which thread is the one to print
|
|
10
|
+
# Basically which thread is the one to print
|
|
8
11
|
print_queue = 0
|
|
9
12
|
|
|
13
|
+
|
|
10
14
|
def load_modules(package):
|
|
11
15
|
|
|
12
16
|
modules = []
|
|
@@ -18,12 +22,13 @@ def load_modules(package):
|
|
|
18
22
|
print(f"Failed to import {name}: {e}")
|
|
19
23
|
return modules
|
|
20
24
|
|
|
25
|
+
|
|
21
26
|
def worker_single(module, username, i):
|
|
22
27
|
global print_queue
|
|
23
28
|
|
|
24
29
|
func = next((getattr(module, f) for f in dir(module)
|
|
25
30
|
if f.startswith("validate_") and callable(getattr(module, f))), None)
|
|
26
|
-
site_name = module.__name__.split('.')[-1].capitalize().replace("_",".")
|
|
31
|
+
site_name = module.__name__.split('.')[-1].capitalize().replace("_", ".")
|
|
27
32
|
if site_name == "X":
|
|
28
33
|
site_name = "X (Twitter)"
|
|
29
34
|
|
|
@@ -43,7 +48,7 @@ def worker_single(module, username, i):
|
|
|
43
48
|
output = f" {Fore.YELLOW}[!] {site_name} has no validate_ function{Style.RESET_ALL}"
|
|
44
49
|
|
|
45
50
|
with lock:
|
|
46
|
-
#Waits for in-order printing
|
|
51
|
+
# Waits for in-order printing
|
|
47
52
|
while i != print_queue:
|
|
48
53
|
lock.wait()
|
|
49
54
|
|
|
@@ -51,13 +56,15 @@ def worker_single(module, username, i):
|
|
|
51
56
|
print_queue += 1
|
|
52
57
|
lock.notify_all()
|
|
53
58
|
|
|
59
|
+
|
|
54
60
|
def run_module_single(module, username):
|
|
55
|
-
#Just executes as if it was a thread
|
|
61
|
+
# Just executes as if it was a thread
|
|
56
62
|
worker_single(module, username, print_queue)
|
|
57
|
-
|
|
63
|
+
|
|
64
|
+
|
|
58
65
|
def run_checks_category(package, username, verbose=False):
|
|
59
66
|
global print_queue
|
|
60
|
-
|
|
67
|
+
|
|
61
68
|
modules = load_modules(package)
|
|
62
69
|
category_name = package.__name__.split('.')[-1].capitalize()
|
|
63
70
|
print(f"{Fore.MAGENTA}== {category_name} SITES =={Style.RESET_ALL}")
|
|
@@ -73,19 +80,69 @@ def run_checks_category(package, username, verbose=False):
|
|
|
73
80
|
for t in threads:
|
|
74
81
|
t.join()
|
|
75
82
|
|
|
83
|
+
|
|
76
84
|
def run_checks(username):
|
|
77
|
-
from user_scanner import dev, social, creator, community, gaming
|
|
85
|
+
from user_scanner import dev, social, creator, community, gaming, donation
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
("DEV", dev),
|
|
81
|
-
("SOCIAL", social),
|
|
82
|
-
("CREATOR", creator),
|
|
83
|
-
("COMMUNITY", community),
|
|
84
|
-
("GAMING", gaming)
|
|
85
|
-
]
|
|
87
|
+
packages = [dev, social, creator, community, gaming, donation]
|
|
86
88
|
|
|
87
89
|
print(f"\n{Fore.CYAN} Checking username: {username}{Style.RESET_ALL}\n")
|
|
88
90
|
|
|
89
|
-
for
|
|
91
|
+
for package in packages:
|
|
90
92
|
run_checks_category(package, username)
|
|
91
93
|
print()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def make_get_request(url, **kwargs):
|
|
97
|
+
"""Simple wrapper to **httpx.get** that predefines headers and timeout"""
|
|
98
|
+
if not "headers" in kwargs:
|
|
99
|
+
kwargs["headers"] = {
|
|
100
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
|
|
101
|
+
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
102
|
+
'Accept-Encoding': "gzip, deflate, br",
|
|
103
|
+
'Accept-Language': "en-US,en;q=0.9",
|
|
104
|
+
'sec-fetch-dest': "document",
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if not "timeout" in kwargs:
|
|
108
|
+
kwargs["timeout"] = 5.0
|
|
109
|
+
|
|
110
|
+
return httpx.get(url, **kwargs)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def generic_validate(url, func, **kwargs):
|
|
114
|
+
"""
|
|
115
|
+
A generic validate function that makes a request and executes the provided function on the response.
|
|
116
|
+
"""
|
|
117
|
+
try:
|
|
118
|
+
response = make_get_request(url, **kwargs)
|
|
119
|
+
return func(response)
|
|
120
|
+
except (ConnectError, TimeoutException):
|
|
121
|
+
return 2
|
|
122
|
+
except Exception:
|
|
123
|
+
return 2
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def status_validate(url, available, taken, **kwargs):
|
|
127
|
+
"""
|
|
128
|
+
Function that takes a **url** and **kwargs** for the request and
|
|
129
|
+
checks if the request status matches the availabe or taken.
|
|
130
|
+
**Available** and **Taken** must either be whole numbers or lists of whole numbers.
|
|
131
|
+
"""
|
|
132
|
+
def inner(response):
|
|
133
|
+
# Checks if a number is equal or is contained inside
|
|
134
|
+
def contains(a, b): return (isinstance(a, list) and b in a) or (a == b)
|
|
135
|
+
|
|
136
|
+
status = response.status_code
|
|
137
|
+
available_value = contains(available, status)
|
|
138
|
+
taken_value = contains(taken, status)
|
|
139
|
+
|
|
140
|
+
if available_value and taken_value:
|
|
141
|
+
return 2 # Can't be both available and taken
|
|
142
|
+
elif available_value:
|
|
143
|
+
return 1
|
|
144
|
+
elif taken_value:
|
|
145
|
+
return 0
|
|
146
|
+
return 2
|
|
147
|
+
|
|
148
|
+
return generic_validate(url, inner, **kwargs)
|
user_scanner/creator/devto.py
CHANGED
|
@@ -1,37 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from user_scanner.core.orchestrator import status_validate
|
|
2
|
+
|
|
3
3
|
|
|
4
4
|
def validate_devto(user):
|
|
5
5
|
url = f"https://dev.to/{user}"
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
|
|
9
|
-
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
try:
|
|
13
|
-
response = httpx.head(url, headers=headers, timeout=3.0, follow_redirects=True)
|
|
14
|
-
status = response.status_code
|
|
15
|
-
|
|
16
|
-
if status == 200:
|
|
17
|
-
return 0
|
|
18
|
-
elif status == 404:
|
|
19
|
-
return 1
|
|
20
|
-
else:
|
|
21
|
-
return 2
|
|
7
|
+
return status_validate(url, 404, 200, follow_redirects=True)
|
|
22
8
|
|
|
23
|
-
except (ConnectError, TimeoutException):
|
|
24
|
-
return 2
|
|
25
|
-
except Exception:
|
|
26
|
-
return 2
|
|
27
9
|
|
|
28
10
|
if __name__ == "__main__":
|
|
29
|
-
|
|
30
|
-
|
|
11
|
+
user = input("Username?: ").strip()
|
|
12
|
+
result = validate_devto(user)
|
|
31
13
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
if result == 1:
|
|
15
|
+
print("Available!")
|
|
16
|
+
elif result == 0:
|
|
17
|
+
print("Unavailable!")
|
|
18
|
+
else:
|
|
19
|
+
print("Error occurred!")
|
user_scanner/creator/hashnode.py
CHANGED
|
@@ -2,20 +2,21 @@ import httpx
|
|
|
2
2
|
import json
|
|
3
3
|
from httpx import ConnectError, TimeoutException
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
def validate_hashnode(user):
|
|
6
7
|
url = "https://hashnode.com/utility/ajax/check-username"
|
|
7
8
|
|
|
8
9
|
payload = {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
"username": user,
|
|
11
|
+
"name": "Dummy Dummy"
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
headers = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Mobile Safari/537.36",
|
|
16
|
+
'Accept': "application/json",
|
|
17
|
+
'Content-Type': "application/json",
|
|
18
|
+
'Origin': "https://hashnode.com",
|
|
19
|
+
'Referer': "https://hashnode.com/signup",
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
try:
|
|
@@ -33,7 +34,7 @@ def validate_hashnode(user):
|
|
|
33
34
|
return 2
|
|
34
35
|
|
|
35
36
|
else:
|
|
36
|
-
|
|
37
|
+
return 2
|
|
37
38
|
|
|
38
39
|
except (ConnectError, TimeoutException):
|
|
39
40
|
return 2
|
|
@@ -42,13 +43,14 @@ def validate_hashnode(user):
|
|
|
42
43
|
except Exception:
|
|
43
44
|
return 2
|
|
44
45
|
|
|
46
|
+
|
|
45
47
|
if __name__ == "__main__":
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
user = input("Username?: ").strip()
|
|
49
|
+
result = validate_hashnode(user)
|
|
50
|
+
|
|
51
|
+
if result == 1:
|
|
52
|
+
print("Available!")
|
|
53
|
+
elif result == 0:
|
|
54
|
+
print("Unavailable!")
|
|
55
|
+
else:
|
|
56
|
+
print("Error occurred!")
|
user_scanner/creator/itch_io.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from user_scanner.core.orchestrator import status_validate
|
|
2
|
+
|
|
3
3
|
|
|
4
4
|
def validate_itch_io(user):
|
|
5
5
|
"""
|
|
@@ -9,37 +9,16 @@ def validate_itch_io(user):
|
|
|
9
9
|
|
|
10
10
|
url = f"https://{user}.itch.io"
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
|
|
14
|
-
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
15
|
-
'Accept-Encoding': "gzip, deflate, br",
|
|
16
|
-
'Accept-Language': "en-US,en;q=0.9",
|
|
17
|
-
'sec-fetch-dest': "document",
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
try:
|
|
21
|
-
response = httpx.get(url, headers = headers, timeout = 5, follow_redirects=True)
|
|
22
|
-
status = response.status_code
|
|
12
|
+
return status_validate(url, 404, 200, follow_redirects=True)
|
|
23
13
|
|
|
24
|
-
if status == 200:
|
|
25
|
-
return 0
|
|
26
|
-
elif status == 404:
|
|
27
|
-
return 1
|
|
28
|
-
else:
|
|
29
|
-
return 2
|
|
30
|
-
|
|
31
|
-
except (ConnectError, TimeoutException):
|
|
32
|
-
return 2
|
|
33
|
-
except Exception as e:
|
|
34
|
-
return 2
|
|
35
14
|
|
|
36
15
|
if __name__ == "__main__":
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
16
|
+
user = input("Username?: ").strip()
|
|
17
|
+
result = validate_itch_io(user)
|
|
18
|
+
|
|
19
|
+
if result == 1:
|
|
20
|
+
print("Available!")
|
|
21
|
+
elif result == 0:
|
|
22
|
+
print("Unavailable!")
|
|
23
|
+
else:
|
|
24
|
+
print("Error occurred!")
|
user_scanner/creator/kaggle.py
CHANGED
|
@@ -1,37 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from user_scanner.core.orchestrator import status_validate
|
|
2
|
+
|
|
3
3
|
|
|
4
4
|
def validate_kaggle(user):
|
|
5
5
|
url = f"https://www.kaggle.com/{user}"
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Mobile Safari/537.36",
|
|
9
|
-
'Accept': "text/html",
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
try:
|
|
13
|
-
response = httpx.get(url, headers=headers, timeout=3.0, follow_redirects=True)
|
|
14
|
-
status = response.status_code
|
|
15
|
-
|
|
16
|
-
if status == 200:
|
|
17
|
-
return 0
|
|
18
|
-
elif status == 404:
|
|
19
|
-
return 1
|
|
20
|
-
else:
|
|
21
|
-
return 2
|
|
7
|
+
return status_validate(url, 404, 200, follow_redirects=True)
|
|
22
8
|
|
|
23
|
-
except (ConnectError, TimeoutException):
|
|
24
|
-
return 2
|
|
25
|
-
except Exception:
|
|
26
|
-
return 2
|
|
27
9
|
|
|
28
10
|
if __name__ == "__main__":
|
|
29
|
-
|
|
30
|
-
|
|
11
|
+
user = input("Username?: ").strip()
|
|
12
|
+
result = validate_kaggle(user)
|
|
31
13
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
if result == 1:
|
|
15
|
+
print("Available!")
|
|
16
|
+
elif result == 0:
|
|
17
|
+
print("Unavailable!")
|
|
18
|
+
else:
|
|
19
|
+
print("Error occurred!")
|
user_scanner/creator/medium.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import httpx
|
|
2
2
|
from httpx import ConnectError, TimeoutException
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
def validate_medium(user):
|
|
5
6
|
url = f"https://medium.com/@{user}"
|
|
6
7
|
|
|
@@ -15,7 +16,6 @@ def validate_medium(user):
|
|
|
15
16
|
if response.status_code == 200:
|
|
16
17
|
html_text = response.text
|
|
17
18
|
|
|
18
|
-
|
|
19
19
|
username_tag = f'property="profile:username" content="{user}"'
|
|
20
20
|
|
|
21
21
|
if username_tag in html_text:
|
|
@@ -29,13 +29,14 @@ def validate_medium(user):
|
|
|
29
29
|
except Exception:
|
|
30
30
|
return 2
|
|
31
31
|
|
|
32
|
+
|
|
32
33
|
if __name__ == "__main__":
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
user = input("Username?: ").strip()
|
|
35
|
+
result = validate_medium(user)
|
|
36
|
+
|
|
37
|
+
if result == 1:
|
|
38
|
+
print("Available!")
|
|
39
|
+
elif result == 0:
|
|
40
|
+
print("Unavailable!")
|
|
41
|
+
else:
|
|
42
|
+
print("Error occurred!")
|
user_scanner/creator/patreon.py
CHANGED
|
@@ -1,45 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from user_scanner.core.orchestrator import status_validate
|
|
2
|
+
|
|
3
3
|
|
|
4
4
|
def validate_patreon(user):
|
|
5
5
|
url = f"https://www.patreon.com/{user}"
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
|
|
9
|
-
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
10
|
-
'Accept-Encoding': "gzip, deflate, br",
|
|
11
|
-
'Accept-Language': "en-US,en;q=0.9",
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
try:
|
|
15
|
-
response = httpx.get(url, headers=headers, timeout = 15.0, follow_redirects=True)
|
|
16
|
-
status = response.status_code
|
|
17
|
-
|
|
18
|
-
if status == 200:
|
|
19
|
-
return 0
|
|
20
|
-
elif status == 404:
|
|
21
|
-
return 1
|
|
22
|
-
else:
|
|
23
|
-
return 2
|
|
7
|
+
return status_validate(url, 404, 200, timeout=15.0, follow_redirects=True)
|
|
24
8
|
|
|
25
|
-
except (ConnectError, TimeoutException):
|
|
26
|
-
return 2
|
|
27
|
-
except Exception:
|
|
28
|
-
return 2
|
|
29
9
|
|
|
30
10
|
if __name__ == "__main__":
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
11
|
+
try:
|
|
12
|
+
import httpx
|
|
13
|
+
except ImportError:
|
|
14
|
+
print("Error: 'httpx' library is not installed.")
|
|
15
|
+
exit()
|
|
16
|
+
|
|
17
|
+
user = input("Username?: ").strip()
|
|
18
|
+
result = validate_patreon(user)
|
|
19
|
+
|
|
20
|
+
if result == 1:
|
|
21
|
+
print("Available!")
|
|
22
|
+
elif result == 0:
|
|
23
|
+
print("Unavailable!")
|
|
24
|
+
else:
|
|
25
|
+
print("Error occured!")
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import httpx
|
|
2
2
|
from httpx import ConnectError, TimeoutException
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
def validate_producthunt(user):
|
|
5
6
|
url = f"https://www.producthunt.com/@{user}"
|
|
6
7
|
|
|
@@ -12,29 +13,30 @@ def validate_producthunt(user):
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
try:
|
|
15
|
-
response = httpx.get(url, headers=headers,
|
|
16
|
+
response = httpx.get(url, headers=headers,
|
|
17
|
+
timeout=3.0, follow_redirects=True)
|
|
16
18
|
status = response.status_code
|
|
17
19
|
|
|
18
20
|
if status == 200:
|
|
19
|
-
|
|
21
|
+
return 0
|
|
20
22
|
elif status == 404:
|
|
21
|
-
|
|
23
|
+
return 1
|
|
22
24
|
else:
|
|
23
|
-
|
|
25
|
+
return 2
|
|
24
26
|
|
|
25
27
|
except (ConnectError, TimeoutException):
|
|
26
28
|
return 2
|
|
27
29
|
except Exception:
|
|
28
30
|
return 2
|
|
29
31
|
|
|
30
|
-
if __name__ == "__main__":
|
|
31
|
-
user = input ("Username?: ").strip()
|
|
32
|
-
result = validate_producthunt(user)
|
|
33
|
-
|
|
34
|
-
if result == 1:
|
|
35
|
-
print("Available!")
|
|
36
|
-
elif result == 0:
|
|
37
|
-
print("Unavailable!")
|
|
38
|
-
else:
|
|
39
|
-
print("Error occured!")
|
|
40
32
|
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
user = input("Username?: ").strip()
|
|
35
|
+
result = validate_producthunt(user)
|
|
36
|
+
|
|
37
|
+
if result == 1:
|
|
38
|
+
print("Available!")
|
|
39
|
+
elif result == 0:
|
|
40
|
+
print("Unavailable!")
|
|
41
|
+
else:
|
|
42
|
+
print("Error occured!")
|