Skip to content

Commit 19d8d17

Browse files
committed
rm: printer; added: formatter
1 parent e705310 commit 19d8d17

File tree

8 files changed

+130
-257
lines changed

8 files changed

+130
-257
lines changed

tests/test_formatter.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from user_scanner.core.formatter import into_csv, into_json, indentate, INDENT
2+
from user_scanner.core.result import Result
3+
4+
5+
def test_indentate():
6+
assert indentate("", -1) == ""
7+
assert indentate("", 0) == ""
8+
assert indentate("", 2) == 2 * INDENT
9+
10+
msg = ("This is a test message\n"
11+
"made to test the identation\n"
12+
"and shouldn't be changed.")
13+
14+
for i in range(0, 4):
15+
new = indentate(msg, i)
16+
for line in new.split("\n"):
17+
assert line.find(INDENT * i) == 0
18+
19+
20+
def test_get_result_output_formats():
21+
res = Result.available(
22+
username="alice", site_name="ExampleSite", category="Cat")
23+
24+
out_console = res.get_console_output()
25+
assert "Available" in out_console
26+
assert "ExampleSite" in out_console
27+
assert "alice" in out_console
28+
29+
out_json = into_json([res])
30+
assert '"username": "alice"' in out_json
31+
assert '"site_name": "ExampleSite"' in out_json
32+
33+
out_csv = into_csv([res])
34+
assert "alice" in out_csv
35+
assert "ExampleSite" in out_csv

tests/test_orchestrator.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import types
22
from types import SimpleNamespace
33
from user_scanner.core import orchestrator
4-
from user_scanner.cli.printer import Printer
54
from user_scanner.core.result import Result
65

76

@@ -44,16 +43,10 @@ def validate_testsite(username):
4443

4544
setattr(module, "validate_testsite", validate_testsite)
4645

47-
p_json = Printer("json")
48-
orchestrator.run_module_single(module, "bob", p_json, last=True)
46+
orchestrator.run_module_single(module, "bob")
4947
out = capsys.readouterr().out
50-
assert '"username": "bob"' in out
48+
assert 'bob' in out #Needs to be improved
5149

52-
p_csv = Printer("csv")
53-
orchestrator.run_module_single(module, "bob", p_csv, last=True)
54-
out2 = capsys.readouterr().out
55-
assert "bob" in out2
56-
assert "Testsite" in out2 or "testsite" in out2
5750

5851

5952
def test_run_checks_category_threaded(monkeypatch, tmp_path):
@@ -70,8 +63,7 @@ def validate(username):
7063
monkeypatch.setattr(orchestrator, "load_modules", lambda p: [module])
7164
monkeypatch.setattr(orchestrator, "get_site_name", lambda m: "Testsite")
7265

73-
p = Printer("console")
74-
results = orchestrator.run_checks_category(tmp_path, "someone", p, last=True)
66+
results = orchestrator.run_checks_category(tmp_path, "someone")
7567
assert isinstance(results, list)
7668
assert len(results) == 1
7769
assert results[0].to_number() == 0 # TAKEN

tests/test_printer.py

Lines changed: 0 additions & 64 deletions
This file was deleted.

user_scanner/__main__.py

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
import time
33
import sys
44
import re
5-
from user_scanner.cli import printer
6-
from user_scanner.core.orchestrator import generate_permutations, load_categories
5+
from user_scanner.core.orchestrator import generate_permutations, load_categories, load_modules
76
from colorama import Fore, Style
87
from user_scanner.cli.banner import print_banner
98
from typing import List
109
from user_scanner.core.result import Result
1110
from user_scanner.core.version import load_local_version
1211
from user_scanner.core.helpers import is_last_value
12+
from user_scanner.core import formatter
1313
from user_scanner.utils.updater_logic import check_for_updates
1414
from user_scanner.utils.update import update_self
1515

@@ -21,7 +21,7 @@
2121
X = Fore.RESET
2222

2323

24-
MAX_PERMUTATIONS_LIMIT = 100 # To prevent excessive generation
24+
MAX_PERMUTATIONS_LIMIT = 100 # To prevent excessive generation
2525

2626

2727
def main():
@@ -53,13 +53,13 @@ def main():
5353
"-v", "--verbose", action="store_true", help="Enable verbose output"
5454
)
5555
parser.add_argument(
56-
"-p", "--permute",type=str,help="Generate username permutations using a string pattern (e.g -p 234)"
56+
"-p", "--permute", type=str, help="Generate username permutations using a string pattern (e.g -p 234)"
5757
)
5858
parser.add_argument(
59-
"-s", "--stop",type=int,default=MAX_PERMUTATIONS_LIMIT,help="Limit the number of username permutations generated"
59+
"-s", "--stop", type=int, default=MAX_PERMUTATIONS_LIMIT, help="Limit the number of username permutations generated"
6060
)
6161
parser.add_argument(
62-
"-d", "--delay",type=float,default=0,help="Delay in seconds between requests (recommended: 1-2 seconds)"
62+
"-d", "--delay", type=float, default=0, help="Delay in seconds between requests (recommended: 1-2 seconds)"
6363
)
6464
parser.add_argument(
6565
"-f", "--format", choices=["console", "csv", "json"], default="console", help="Specify the output format (default: console)"
@@ -75,15 +75,21 @@ def main():
7575
)
7676
args = parser.parse_args()
7777

78-
Printer = printer.Printer(args.format)
79-
8078
if args.update is True:
8179
update_self()
8280
print(f"[{G}+{X}] {G}Update successful. Please restart the tool.{X}")
8381
sys.exit(0)
8482

8583
if args.list:
86-
Printer.print_modules(args.category)
84+
categories = load_categories()
85+
for cat_name, cat_path in categories.items():
86+
modules = load_modules(cat_path)
87+
print(Fore.MAGENTA +
88+
f"\n== {cat_name.upper()} SITES =={Style.RESET_ALL}")
89+
for module in modules:
90+
site_name = module.__name__.split(".")[-1].capitalize()
91+
print(f" - {site_name}")
92+
8793
return
8894

8995
if args.version:
@@ -93,57 +99,53 @@ def main():
9399
check_for_updates()
94100

95101
if not (args.username or args.email):
96-
parser.print_help()
97-
return
102+
parser.print_help()
103+
return
98104

99-
if Printer.is_console:
100-
print_banner()
105+
print_banner()
101106

102107
is_email = args.email is not None
103108
if is_email and not re.findall(r"^[^@\s]+@[^@\s]+\.[^@\s]+$", args.email):
104109
print(R + "[✘] Error: Invalid email." + X)
105110
sys.exit(1)
106111

107-
if args.permute and args.delay == 0 and Printer.is_console:
112+
if args.permute and args.delay == 0:
108113
print(
109-
Y
110-
+ "[!] Warning: You're generating multiple usernames with NO delay between requests. "
111-
"This may trigger rate limits or IP bans. Use --delay 1 or higher. (Use only if the sites throw errors otherwise ignore)\n"
112-
+ Style.RESET_ALL)
114+
Y
115+
+ "[!] Warning: You're generating multiple usernames with NO delay between requests. "
116+
"This may trigger rate limits or IP bans. Use --delay 1 or higher. (Use only if the sites throw errors otherwise ignore)\n"
117+
+ Style.RESET_ALL)
113118

114-
name = args.username or args.email #Username or email
119+
name = args.username or args.email # Username or email
115120
usernames = [name] # Default single username list
116121

117122
# Added permutation support , generate all possible permutation of given sequence.
118123
if args.permute:
119-
usernames = generate_permutations(name, args.permute , args.stop, is_email)
120-
if Printer.is_console:
121-
print(
122-
C + f"[+] Generated {len(usernames)} username permutations" + Style.RESET_ALL)
124+
usernames = generate_permutations(
125+
name, args.permute, args.stop, is_email)
126+
print(
127+
C + f"[+] Generated {len(usernames)} username permutations" + Style.RESET_ALL)
123128

124129
if args.module and "." in args.module:
125130
args.module = args.module.replace(".", "_")
126131

127-
def run_all_usernames(func, arg = None) -> List[Result]:
132+
def run_all_usernames(func, arg=None) -> List[Result]:
128133
"""
129134
Executes a function for all given usernames.
130135
Made in order to simplify main()
131136
"""
132137
results = []
133-
print(Printer.get_start())
134138
for i, name in enumerate(usernames):
135-
is_last = i == len(usernames) - 1
139+
is_last = is_last_value(usernames, i)
136140
if arg is None:
137-
results.extend(func(name, Printer, is_last))
141+
results.extend(func(name))
138142
else:
139-
results.extend(func(arg, name, Printer, is_last))
143+
results.extend(func(arg, name))
140144
if args.delay > 0 and not is_last:
141145
time.sleep(args.delay)
142-
if Printer.is_json:
143-
print(Printer.get_end())
144146
return results
145147

146-
results = []
148+
results = []
147149

148150
if args.module:
149151
# Single module search across all categories
@@ -171,22 +173,16 @@ def run_all_usernames(func, arg = None) -> List[Result]:
171173
if not args.output:
172174
return
173175

174-
if args.output and Printer.is_console:
176+
if args.output and args.format == "console":
175177
msg = (
176178
"\n[!] The console format cannot be "
177179
f"written to file: '{args.output}'."
178180
)
179181
print(R + msg + Style.RESET_ALL)
180182
return
181183

182-
content = Printer.get_start()
183-
184-
for i,result in enumerate(results):
185-
char = "" if Printer.is_csv or is_last_value(results, i) else ","
186-
content += "\n" + Printer.get_result_output(result) + char
187-
188-
if Printer.is_json:
189-
content += "\n" + Printer.get_end()
184+
185+
content = formatter.into_csv(results) if args.format == "csv" else formatter.into_json(results)
190186

191187
with open(args.output, "a", encoding="utf-8") as f:
192188
f.write(content)

0 commit comments

Comments
 (0)