user-scanner 1.0.1.4__py3-none-any.whl → 1.0.5.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 +1 -0
- user_scanner/__main__.py +19 -10
- user_scanner/cli/__init__.py +0 -0
- user_scanner/cli/banner.py +32 -0
- user_scanner/community/coderlegion.py +5 -26
- user_scanner/core/orchestrator.py +98 -50
- user_scanner/creator/devto.py +3 -23
- user_scanner/creator/itch_io.py +22 -0
- user_scanner/creator/kaggle.py +3 -22
- user_scanner/creator/patreon.py +2 -24
- user_scanner/creator/producthunt.py +40 -0
- user_scanner/dev/codeberg.py +3 -23
- user_scanner/dev/cratesio.py +9 -24
- user_scanner/dev/dockerhub.py +7 -25
- user_scanner/dev/github.py +16 -31
- user_scanner/dev/gitlab.py +8 -22
- user_scanner/dev/launchpad.py +9 -24
- user_scanner/dev/replit.py +3 -23
- user_scanner/donation/__init__.py +0 -0
- user_scanner/donation/buymeacoffee.py +21 -0
- user_scanner/gaming/chess_com.py +6 -19
- user_scanner/gaming/monkeytype.py +6 -19
- user_scanner/gaming/osu.py +2 -24
- user_scanner/gaming/roblox.py +5 -18
- user_scanner/gaming/steam.py +30 -0
- user_scanner/social/bluesky.py +6 -19
- user_scanner/social/instagram.py +12 -27
- user_scanner/social/mastodon.py +2 -24
- user_scanner/social/pinterest.py +4 -20
- user_scanner/social/reddit.py +4 -20
- user_scanner/social/snapchat.py +5 -20
- user_scanner/social/telegram.py +4 -11
- user_scanner/social/threads.py +13 -28
- user_scanner/utils/version.py +20 -0
- user_scanner/version.json +4 -0
- {user_scanner-1.0.1.4.dist-info → user_scanner-1.0.5.0.dist-info}/METADATA +45 -10
- user_scanner-1.0.5.0.dist-info/RECORD +52 -0
- user_scanner-1.0.1.4.dist-info/RECORD +0 -43
- {user_scanner-1.0.1.4.dist-info → user_scanner-1.0.5.0.dist-info}/WHEEL +0 -0
- {user_scanner-1.0.1.4.dist-info → user_scanner-1.0.5.0.dist-info}/entry_points.txt +0 -0
- {user_scanner-1.0.1.4.dist-info → user_scanner-1.0.5.0.dist-info}/licenses/LICENSE +0 -0
user_scanner/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
user_scanner/__main__.py
CHANGED
|
@@ -2,23 +2,27 @@ import argparse
|
|
|
2
2
|
import re
|
|
3
3
|
from user_scanner.core.orchestrator import run_checks, load_modules
|
|
4
4
|
from colorama import Fore, Style
|
|
5
|
+
from .cli import banner
|
|
6
|
+
from .cli.banner import print_banner
|
|
5
7
|
|
|
6
8
|
CATEGORY_MAPPING = {
|
|
7
9
|
"dev": "dev",
|
|
8
10
|
"social": "social",
|
|
9
11
|
"creator": "creator",
|
|
10
12
|
"community": "community",
|
|
11
|
-
"gaming": "gaming"
|
|
13
|
+
"gaming": "gaming",
|
|
14
|
+
"donation": "donation"
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
def list_modules(category=None):
|
|
15
|
-
from user_scanner import dev, social, creator, community, gaming
|
|
18
|
+
from user_scanner import dev, social, creator, community, gaming, donation
|
|
16
19
|
packages = {
|
|
17
20
|
"dev": dev,
|
|
18
21
|
"social": social,
|
|
19
22
|
"creator": creator,
|
|
20
23
|
"community": community,
|
|
21
|
-
"gaming": gaming
|
|
24
|
+
"gaming": gaming,
|
|
25
|
+
"donation": donation
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
categories_to_list = [category] if category else packages.keys()
|
|
@@ -37,7 +41,7 @@ def main():
|
|
|
37
41
|
description="Scan usernames across multiple platforms."
|
|
38
42
|
)
|
|
39
43
|
parser.add_argument(
|
|
40
|
-
"-u", "--username",
|
|
44
|
+
"-u", "--username", help="Username to scan across platforms"
|
|
41
45
|
)
|
|
42
46
|
parser.add_argument(
|
|
43
47
|
"-c", "--category", choices=CATEGORY_MAPPING.keys(),
|
|
@@ -55,13 +59,13 @@ def main():
|
|
|
55
59
|
|
|
56
60
|
args = parser.parse_args()
|
|
57
61
|
|
|
62
|
+
if args.module and "." in args.module:
|
|
63
|
+
args.module = args.module.replace(".", "_")
|
|
64
|
+
|
|
58
65
|
if args.list:
|
|
59
66
|
list_modules(args.category)
|
|
60
67
|
return
|
|
61
68
|
|
|
62
|
-
if not args.username:
|
|
63
|
-
print(Fore.RED + "[!] Please provide a username with -u or --username." + Style.RESET_ALL)
|
|
64
|
-
return
|
|
65
69
|
|
|
66
70
|
# Special username checks before run
|
|
67
71
|
if (args.module == "x" or args.category == "social"):
|
|
@@ -70,13 +74,18 @@ def main():
|
|
|
70
74
|
if (args.module == "bluesky" or args.category == "social"):
|
|
71
75
|
if re.search(r"[^a-zA-Z0-9\.-]", args.username):
|
|
72
76
|
print(Fore.RED + f"[!] Username '{args.username}' contains unsupported special characters. Bluesky will throw error. (Supported: only hyphens and digits)" + Style.RESET_ALL +"\n")
|
|
77
|
+
if not args.username:
|
|
78
|
+
parser.print_help()
|
|
79
|
+
return
|
|
80
|
+
else:
|
|
81
|
+
print_banner()
|
|
73
82
|
|
|
74
83
|
|
|
75
|
-
from user_scanner import dev, social, creator, community, gaming
|
|
84
|
+
from user_scanner import dev, social, creator, community, gaming, donation
|
|
76
85
|
|
|
77
86
|
if args.module:
|
|
78
87
|
# Single module search across all categories
|
|
79
|
-
packages = [dev, social, creator, community, gaming]
|
|
88
|
+
packages = [dev, social, creator, community, gaming, donation]
|
|
80
89
|
found = False
|
|
81
90
|
for package in packages:
|
|
82
91
|
modules = load_modules(package)
|
|
@@ -98,4 +107,4 @@ def main():
|
|
|
98
107
|
run_checks(args.username)
|
|
99
108
|
|
|
100
109
|
if __name__ == "__main__":
|
|
101
|
-
main()
|
|
110
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from colorama import Fore, Style, init
|
|
3
|
+
from ..utils.version import load_local_version
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
version, version_type = load_local_version()
|
|
7
|
+
init(autoreset=True)
|
|
8
|
+
C_RED = Fore.RED + Style.BRIGHT
|
|
9
|
+
C_CYAN = Fore.CYAN + Style.BRIGHT
|
|
10
|
+
C_GREEN = Fore.GREEN + Style.BRIGHT
|
|
11
|
+
C_WHITE = Fore.WHITE + Style.BRIGHT
|
|
12
|
+
C_MAGENTA = Fore.MAGENTA + Style.BRIGHT
|
|
13
|
+
BANNER_ASCII = fr"""{C_CYAN} _ _ ___ ___ _ __ ___ ___ __ _ _ __ _ __ ___ _ __
|
|
14
|
+
| | | / __|/ _ \ '__|____/ __|/ __/ _` | '_ \| '_ \ / _ \ '__|
|
|
15
|
+
| |_| \__ \ __/ | |_____\__ \ (_| (_| | | | | | | | __/ |
|
|
16
|
+
\__,_|___/\___|_| |___/\___\__,_|_| |_|_| |_|\___|_| Version: {version}
|
|
17
|
+
{Style.RESET_ALL}""".strip()
|
|
18
|
+
|
|
19
|
+
INFO_BOX = f"""{C_MAGENTA} ╔════════════════════════════════════════╗
|
|
20
|
+
║ {C_RED}♚ {C_GREEN}Project Name{C_WHITE} : UserScanner {C_MAGENTA}║
|
|
21
|
+
║ {C_RED}♚ {C_GREEN}Author{C_WHITE} : Kaif {C_MAGENTA}║
|
|
22
|
+
║ {C_RED}♚ {C_GREEN}Github{C_WHITE} : github.com/kaifcodec {C_MAGENTA}║
|
|
23
|
+
║ {C_RED}♚ {C_GREEN}Email{C_WHITE} : kaifcodec@gmail.com {C_MAGENTA}║
|
|
24
|
+
══════════════════════════════════════════{Style.RESET_ALL}""".strip()
|
|
25
|
+
|
|
26
|
+
def print_banner():
|
|
27
|
+
print(BANNER_ASCII)
|
|
28
|
+
print(INFO_BOX)
|
|
29
|
+
print(" ")
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
print_banner()
|
|
@@ -1,30 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
from httpx import ConnectError, TimeoutException
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
3
2
|
|
|
4
|
-
def validate_coderlegion(user):
|
|
5
|
-
|
|
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
|
|
23
|
-
|
|
24
|
-
except (ConnectError, TimeoutException):
|
|
25
|
-
return 2
|
|
26
|
-
except Exception:
|
|
27
|
-
return 2
|
|
3
|
+
def validate_coderlegion(user):
|
|
4
|
+
url = f"https://coderlegion.com/user/{user}"
|
|
5
|
+
|
|
6
|
+
return status_validate(url, 404, 200, timeout = 15.0)
|
|
28
7
|
|
|
29
8
|
if __name__ == "__main__":
|
|
30
9
|
user = input ("Username?: ").strip()
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import importlib
|
|
2
2
|
import pkgutil
|
|
3
3
|
from colorama import Fore, Style
|
|
4
|
+
import threading
|
|
5
|
+
|
|
6
|
+
import httpx
|
|
7
|
+
from httpx import ConnectError, TimeoutException
|
|
8
|
+
|
|
9
|
+
lock = threading.Condition()
|
|
10
|
+
#Basically which thread is the one to print
|
|
11
|
+
print_queue = 0
|
|
4
12
|
|
|
5
13
|
def load_modules(package):
|
|
6
14
|
|
|
@@ -13,80 +21,120 @@ def load_modules(package):
|
|
|
13
21
|
print(f"Failed to import {name}: {e}")
|
|
14
22
|
return modules
|
|
15
23
|
|
|
16
|
-
def
|
|
24
|
+
def worker_single(module, username, i):
|
|
25
|
+
global print_queue
|
|
17
26
|
|
|
18
27
|
func = next((getattr(module, f) for f in dir(module)
|
|
19
28
|
if f.startswith("validate_") and callable(getattr(module, f))), None)
|
|
20
|
-
site_name = module.__name__.split('.')[-1].capitalize()
|
|
29
|
+
site_name = module.__name__.split('.')[-1].capitalize().replace("_",".")
|
|
21
30
|
if site_name == "X":
|
|
22
31
|
site_name = "X (Twitter)"
|
|
23
32
|
|
|
33
|
+
output = ""
|
|
24
34
|
if func:
|
|
25
35
|
try:
|
|
26
36
|
result = func(username)
|
|
27
37
|
if result == 1:
|
|
28
|
-
|
|
38
|
+
output = f" {Fore.GREEN}[✔] {site_name}: Available{Style.RESET_ALL}"
|
|
29
39
|
elif result == 0:
|
|
30
|
-
|
|
40
|
+
output = f" {Fore.RED}[✘] {site_name}: Taken{Style.RESET_ALL}"
|
|
31
41
|
else:
|
|
32
|
-
|
|
42
|
+
output = f" {Fore.YELLOW}[!] {site_name}: Error{Style.RESET_ALL}"
|
|
33
43
|
except Exception as e:
|
|
34
|
-
|
|
44
|
+
output = f" {Fore.YELLOW}[!] {site_name}: Exception - {e}{Style.RESET_ALL}"
|
|
35
45
|
else:
|
|
36
|
-
|
|
46
|
+
output = f" {Fore.YELLOW}[!] {site_name} has no validate_ function{Style.RESET_ALL}"
|
|
37
47
|
|
|
48
|
+
with lock:
|
|
49
|
+
#Waits for in-order printing
|
|
50
|
+
while i != print_queue:
|
|
51
|
+
lock.wait()
|
|
52
|
+
|
|
53
|
+
print(output)
|
|
54
|
+
print_queue += 1
|
|
55
|
+
lock.notify_all()
|
|
56
|
+
|
|
57
|
+
def run_module_single(module, username):
|
|
58
|
+
#Just executes as if it was a thread
|
|
59
|
+
worker_single(module, username, print_queue)
|
|
60
|
+
|
|
38
61
|
def run_checks_category(package, username, verbose=False):
|
|
62
|
+
global print_queue
|
|
63
|
+
|
|
39
64
|
modules = load_modules(package)
|
|
40
65
|
category_name = package.__name__.split('.')[-1].capitalize()
|
|
41
66
|
print(f"{Fore.MAGENTA}== {category_name} SITES =={Style.RESET_ALL}")
|
|
42
67
|
|
|
43
|
-
|
|
44
|
-
run_module_single(module, username)
|
|
68
|
+
print_queue = 0
|
|
45
69
|
|
|
46
|
-
|
|
70
|
+
threads = []
|
|
71
|
+
for i, module in enumerate(modules):
|
|
72
|
+
t = threading.Thread(target=worker_single, args=(module, username, i))
|
|
73
|
+
threads.append(t)
|
|
74
|
+
t.start()
|
|
47
75
|
|
|
48
|
-
|
|
76
|
+
for t in threads:
|
|
77
|
+
t.join()
|
|
49
78
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
("SOCIAL", social),
|
|
53
|
-
("CREATOR", creator),
|
|
54
|
-
("COMMUNITY", community),
|
|
55
|
-
("GAMING", gaming)
|
|
56
|
-
]
|
|
79
|
+
def run_checks(username):
|
|
80
|
+
from user_scanner import dev, social, creator, community, gaming, donation
|
|
57
81
|
|
|
58
|
-
|
|
82
|
+
packages = [dev, social, creator, community, gaming, donation]
|
|
59
83
|
|
|
60
|
-
|
|
61
|
-
try:
|
|
62
|
-
modules = load_modules(package)
|
|
63
|
-
except ModuleNotFoundError:
|
|
64
|
-
continue
|
|
65
|
-
|
|
66
|
-
print(f"{Fore.MAGENTA}== {cat_name} SITES =={Style.RESET_ALL}")
|
|
67
|
-
|
|
68
|
-
for module in modules:
|
|
69
|
-
# Find the first function starting with "validate_"
|
|
70
|
-
func = None
|
|
71
|
-
for f in dir(module):
|
|
72
|
-
if f.startswith("validate_") and callable(getattr(module, f)):
|
|
73
|
-
func = getattr(module, f)
|
|
74
|
-
break
|
|
75
|
-
if not func:
|
|
76
|
-
continue
|
|
77
|
-
|
|
78
|
-
site_name = module.__name__.split('.')[-1].capitalize()
|
|
79
|
-
if site_name == "X":
|
|
80
|
-
site_name = "X (Twitter)"
|
|
81
|
-
try:
|
|
82
|
-
result = func(username)
|
|
83
|
-
if result == 1:
|
|
84
|
-
print(f" {Fore.GREEN}[✔] {site_name}: Available{Style.RESET_ALL}")
|
|
85
|
-
elif result == 0:
|
|
86
|
-
print(f" {Fore.RED}[✘] {site_name}: Taken{Style.RESET_ALL}")
|
|
87
|
-
else:
|
|
88
|
-
print(f" {Fore.YELLOW}[!] {site_name}: Error{Style.RESET_ALL}")
|
|
89
|
-
except Exception as e:
|
|
90
|
-
print(f" {Fore.YELLOW}[!] {site_name}: Exception - {e}{Style.RESET_ALL}")
|
|
84
|
+
print(f"\n{Fore.CYAN} Checking username: {username}{Style.RESET_ALL}\n")
|
|
91
85
|
|
|
86
|
+
for package in packages:
|
|
87
|
+
run_checks_category(package, username)
|
|
92
88
|
print()
|
|
89
|
+
|
|
90
|
+
def make_get_request(url, **kwargs):
|
|
91
|
+
"""Simple wrapper to **httpx.get** that predefines headers and timeout"""
|
|
92
|
+
if not "headers" in kwargs:
|
|
93
|
+
kwargs["headers"] = {
|
|
94
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
|
|
95
|
+
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
96
|
+
'Accept-Encoding': "gzip, deflate, br",
|
|
97
|
+
'Accept-Language': "en-US,en;q=0.9",
|
|
98
|
+
'sec-fetch-dest': "document",
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if not "timeout" in kwargs:
|
|
102
|
+
kwargs["timeout"] = 5.0
|
|
103
|
+
|
|
104
|
+
return httpx.get(url, **kwargs)
|
|
105
|
+
|
|
106
|
+
def generic_validate(url, func, **kwargs):
|
|
107
|
+
"""
|
|
108
|
+
A generic validate function that makes a request and executes the provided function on the response.
|
|
109
|
+
"""
|
|
110
|
+
try:
|
|
111
|
+
response = make_get_request(url, **kwargs)
|
|
112
|
+
return func(response)
|
|
113
|
+
except (ConnectError, TimeoutException):
|
|
114
|
+
return 2
|
|
115
|
+
except Exception:
|
|
116
|
+
return 2
|
|
117
|
+
|
|
118
|
+
def status_validate(url, available, taken, **kwargs):
|
|
119
|
+
"""
|
|
120
|
+
Function that takes a **url** and **kwargs** for the request and
|
|
121
|
+
checks if the request status matches the availabe or taken.
|
|
122
|
+
**Available** and **Taken** must either be whole numbers or lists of whole numbers.
|
|
123
|
+
"""
|
|
124
|
+
def inner(response):
|
|
125
|
+
#Checks if a number is equal or is contained inside
|
|
126
|
+
contains = lambda a,b: (isinstance(a,list) and b in a) or (a == b)
|
|
127
|
+
|
|
128
|
+
status = response.status_code
|
|
129
|
+
available_value = contains(available, status)
|
|
130
|
+
taken_value = contains(taken, status)
|
|
131
|
+
|
|
132
|
+
if available_value and taken_value:
|
|
133
|
+
return 2 # Can't be both available and taken
|
|
134
|
+
elif available_value:
|
|
135
|
+
return 1
|
|
136
|
+
elif taken_value:
|
|
137
|
+
return 0
|
|
138
|
+
return 2
|
|
139
|
+
|
|
140
|
+
return generic_validate(url, inner, **kwargs)
|
user_scanner/creator/devto.py
CHANGED
|
@@ -1,29 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
from httpx import ConnectError, TimeoutException
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
3
2
|
|
|
4
3
|
def validate_devto(user):
|
|
5
|
-
|
|
4
|
+
url = f"https://dev.to/{user}"
|
|
6
5
|
|
|
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
|
|
22
|
-
|
|
23
|
-
except (ConnectError, TimeoutException):
|
|
24
|
-
return 2
|
|
25
|
-
except Exception:
|
|
26
|
-
return 2
|
|
6
|
+
return status_validate(url, 404, 200, follow_redirects = True)
|
|
27
7
|
|
|
28
8
|
if __name__ == "__main__":
|
|
29
9
|
user = input ("Username?: ").strip()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
2
|
+
|
|
3
|
+
def validate_itch_io(user):
|
|
4
|
+
"""
|
|
5
|
+
Checks if a itch.io username is available.
|
|
6
|
+
Returns: 1 -> available, 0 -> taken, 2 -> error
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
url = f"https://{user}.itch.io"
|
|
10
|
+
|
|
11
|
+
return status_validate(url, 404, 200, follow_redirects = True)
|
|
12
|
+
|
|
13
|
+
if __name__ == "__main__":
|
|
14
|
+
user = input ("Username?: ").strip()
|
|
15
|
+
result = validate_itch_io(user)
|
|
16
|
+
|
|
17
|
+
if result == 1:
|
|
18
|
+
print("Available!")
|
|
19
|
+
elif result == 0:
|
|
20
|
+
print("Unavailable!")
|
|
21
|
+
else:
|
|
22
|
+
print("Error occurred!")
|
user_scanner/creator/kaggle.py
CHANGED
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
from httpx import ConnectError, TimeoutException
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
3
2
|
|
|
4
3
|
def validate_kaggle(user):
|
|
5
|
-
|
|
4
|
+
url = f"https://www.kaggle.com/{user}"
|
|
6
5
|
|
|
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
|
-
}
|
|
6
|
+
return status_validate(url, 404, 200, follow_redirects=True)
|
|
11
7
|
|
|
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
|
|
22
|
-
|
|
23
|
-
except (ConnectError, TimeoutException):
|
|
24
|
-
return 2
|
|
25
|
-
except Exception:
|
|
26
|
-
return 2
|
|
27
8
|
|
|
28
9
|
if __name__ == "__main__":
|
|
29
10
|
user = input ("Username?: ").strip()
|
user_scanner/creator/patreon.py
CHANGED
|
@@ -1,31 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
from httpx import ConnectError, TimeoutException
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
3
2
|
|
|
4
3
|
def validate_patreon(user):
|
|
5
4
|
url = f"https://www.patreon.com/{user}"
|
|
6
5
|
|
|
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
|
|
24
|
-
|
|
25
|
-
except (ConnectError, TimeoutException):
|
|
26
|
-
return 2
|
|
27
|
-
except Exception:
|
|
28
|
-
return 2
|
|
6
|
+
return status_validate(url, 404, 200, timeout = 15.0, follow_redirects=True)
|
|
29
7
|
|
|
30
8
|
if __name__ == "__main__":
|
|
31
9
|
try:
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from httpx import ConnectError, TimeoutException
|
|
3
|
+
|
|
4
|
+
def validate_producthunt(user):
|
|
5
|
+
url = f"https://www.producthunt.com/@{user}"
|
|
6
|
+
|
|
7
|
+
headers = {
|
|
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 = 3.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
|
|
24
|
+
|
|
25
|
+
except (ConnectError, TimeoutException):
|
|
26
|
+
return 2
|
|
27
|
+
except Exception:
|
|
28
|
+
return 2
|
|
29
|
+
|
|
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
|
+
|
user_scanner/dev/codeberg.py
CHANGED
|
@@ -1,29 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
from httpx import ConnectError, TimeoutException
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
3
2
|
|
|
4
3
|
def validate_codeberg(user):
|
|
5
|
-
|
|
4
|
+
url = f"https://codeberg.org/{user}"
|
|
6
5
|
|
|
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.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
|
|
22
|
-
|
|
23
|
-
except (ConnectError, TimeoutException):
|
|
24
|
-
return 2
|
|
25
|
-
except Exception:
|
|
26
|
-
return 2
|
|
6
|
+
return status_validate(url, 404, 200, follow_redirects = True)
|
|
27
7
|
|
|
28
8
|
if __name__ == "__main__":
|
|
29
9
|
user = input ("Username?: ").strip()
|
user_scanner/dev/cratesio.py
CHANGED
|
@@ -1,31 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
from httpx import ConnectError, TimeoutException
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
3
2
|
|
|
4
3
|
def validate_cratesio(user):
|
|
5
|
-
|
|
4
|
+
url = f"https://crates.io/api/v1/users/{user}"
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
headers = {
|
|
7
|
+
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Mobile Safari/537.36",
|
|
8
|
+
'Accept': "application/json",
|
|
9
|
+
'Referer': "https://crates.io/",
|
|
10
|
+
'sec-fetch-mode': "cors",
|
|
11
|
+
}
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
response = httpx.head(url, headers=headers, timeout=5.0)
|
|
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
|
|
24
|
-
|
|
25
|
-
except (ConnectError, TimeoutException):
|
|
26
|
-
return 2
|
|
27
|
-
except Exception:
|
|
28
|
-
return 2
|
|
13
|
+
return status_validate(url, 404, 200, headers = headers)
|
|
29
14
|
|
|
30
15
|
if __name__ == "__main__":
|
|
31
16
|
user = input ("Username?: ").strip()
|
user_scanner/dev/dockerhub.py
CHANGED
|
@@ -1,32 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
from httpx import ConnectError, TimeoutException
|
|
1
|
+
from ..core.orchestrator import status_validate
|
|
3
2
|
|
|
4
3
|
def validate_dockerhub(user):
|
|
5
|
-
|
|
4
|
+
url = f"https://hub.docker.com/v2/users/{user}/"
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
headers = {
|
|
7
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
|
|
8
|
+
'Accept': "application/json",
|
|
9
|
+
}
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
response = httpx.get(url, headers=headers, timeout=3.0)
|
|
14
|
-
status = response.status_code
|
|
15
|
-
|
|
16
|
-
# UNAVAILABLE (return 0) if the user API endpoint returns 200 OK
|
|
17
|
-
if status == 200:
|
|
18
|
-
return 0
|
|
19
|
-
# AVAILABLE (return 1) if the user API endpoint returns 404 Not Found
|
|
20
|
-
elif status == 404:
|
|
21
|
-
return 1
|
|
22
|
-
# Other status codes are errors
|
|
23
|
-
else:
|
|
24
|
-
return 2
|
|
25
|
-
|
|
26
|
-
except (ConnectError, TimeoutException):
|
|
27
|
-
return 2
|
|
28
|
-
except Exception:
|
|
29
|
-
return 2
|
|
11
|
+
return status_validate(url, 404, 200, headers = headers)
|
|
30
12
|
|
|
31
13
|
if __name__ == "__main__":
|
|
32
14
|
user = input ("Username?: ").strip()
|