evolver-tools 1.4.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.
Files changed (69) hide show
  1. evolver_tools/__init__.py +2 -0
  2. evolver_tools/__main__.py +3 -0
  3. evolver_tools/cli.py +89 -0
  4. evolver_tools/vendor/b64/__init__.py +2 -0
  5. evolver_tools/vendor/b64/b64.py +176 -0
  6. evolver_tools/vendor/cal_tool/__init__.py +1 -0
  7. evolver_tools/vendor/cal_tool/cli.py +234 -0
  8. evolver_tools/vendor/chart_cli/__init__.py +444 -0
  9. evolver_tools/vendor/chart_cli/__main__.py +3 -0
  10. evolver_tools/vendor/colors/__init__.py +5 -0
  11. evolver_tools/vendor/colors/__main__.py +97 -0
  12. evolver_tools/vendor/csv_stats/__init__.py +5 -0
  13. evolver_tools/vendor/csv_stats/__main__.py +4 -0
  14. evolver_tools/vendor/csv_stats/analyzer.py +258 -0
  15. evolver_tools/vendor/csv_stats/cli.py +45 -0
  16. evolver_tools/vendor/dirsize/__init__.py +183 -0
  17. evolver_tools/vendor/envcheck/__init__.py +426 -0
  18. evolver_tools/vendor/ff/__init__.py +427 -0
  19. evolver_tools/vendor/ff/__main__.py +3 -0
  20. evolver_tools/vendor/find_dups/__init__.py +7 -0
  21. evolver_tools/vendor/find_dups/cli.py +392 -0
  22. evolver_tools/vendor/hashsum/__init__.py +211 -0
  23. evolver_tools/vendor/hashsum/__main__.py +5 -0
  24. evolver_tools/vendor/http_live/__init__.py +265 -0
  25. evolver_tools/vendor/http_live/__main__.py +2 -0
  26. evolver_tools/vendor/ipinfo/__init__.py +3 -0
  27. evolver_tools/vendor/ipinfo/__main__.py +30 -0
  28. evolver_tools/vendor/jq_lite/__init__.py +257 -0
  29. evolver_tools/vendor/jq_lite/__main__.py +5 -0
  30. evolver_tools/vendor/json2csv/__init__.py +3 -0
  31. evolver_tools/vendor/json2csv/__main__.py +82 -0
  32. evolver_tools/vendor/jsonql/__init__.py +326 -0
  33. evolver_tools/vendor/jsonql/__main__.py +5 -0
  34. evolver_tools/vendor/license_cli/__init__.py +1 -0
  35. evolver_tools/vendor/license_cli/__main__.py +4 -0
  36. evolver_tools/vendor/license_cli/cli.py +289 -0
  37. evolver_tools/vendor/markdown_check/__init__.py +211 -0
  38. evolver_tools/vendor/nb/__init__.py +319 -0
  39. evolver_tools/vendor/nb/__main__.py +3 -0
  40. evolver_tools/vendor/passgen/__init__.py +224 -0
  41. evolver_tools/vendor/portcheck/__init__.py +2 -0
  42. evolver_tools/vendor/portcheck/__main__.py +66 -0
  43. evolver_tools/vendor/project_doctor/__init__.py +412 -0
  44. evolver_tools/vendor/project_doctor/__main__.py +3 -0
  45. evolver_tools/vendor/ren/__init__.py +283 -0
  46. evolver_tools/vendor/ren/__main__.py +3 -0
  47. evolver_tools/vendor/siege_lite/__init__.py +250 -0
  48. evolver_tools/vendor/siege_lite/__main__.py +3 -0
  49. evolver_tools/vendor/smellfinder/__init__.py +376 -0
  50. evolver_tools/vendor/smellfinder/__main__.py +3 -0
  51. evolver_tools/vendor/sqlite_cli/__init__.py +326 -0
  52. evolver_tools/vendor/sqlite_cli/__main__.py +5 -0
  53. evolver_tools/vendor/sysmon/__init__.py +299 -0
  54. evolver_tools/vendor/sysmon/__main__.py +3 -0
  55. evolver_tools/vendor/timer/__init__.py +127 -0
  56. evolver_tools/vendor/treedir/__init__.py +2 -0
  57. evolver_tools/vendor/treedir/__main__.py +128 -0
  58. evolver_tools/vendor/urlparse_tool/__init__.py +3 -0
  59. evolver_tools/vendor/urlparse_tool/cli.py +212 -0
  60. evolver_tools/vendor/web_summary/__init__.py +341 -0
  61. evolver_tools/vendor/web_summary/__main__.py +3 -0
  62. evolver_tools/vendor/wordcount/__init__.py +2 -0
  63. evolver_tools/vendor/wordcount/__main__.py +101 -0
  64. evolver_tools-1.4.0.dist-info/METADATA +107 -0
  65. evolver_tools-1.4.0.dist-info/RECORD +69 -0
  66. evolver_tools-1.4.0.dist-info/WHEEL +5 -0
  67. evolver_tools-1.4.0.dist-info/entry_points.txt +34 -0
  68. evolver_tools-1.4.0.dist-info/licenses/LICENSE +21 -0
  69. evolver_tools-1.4.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,224 @@
1
+ #!/usr/bin/env python3
2
+ """passgen — 密码生成器 / Password & passphrase generator.
3
+
4
+ Zero-dependency CLI for generating secure passwords and memorable passphrases.
5
+ Shows entropy estimation for each generated secret.
6
+ """
7
+
8
+ import sys
9
+ import os
10
+ import math
11
+ import argparse
12
+ import string
13
+
14
+
15
+ # Word list for passphrases (from EFF's short word list, ~1296 words)
16
+ WORDS = [
17
+ "acid", "acorn", "actor", "agree", "algae", "alien", "alpha", "angel",
18
+ "apple", "april", "arena", "aroma", "arrow", "attic", "audio", "aurora",
19
+ "axiom", "azure", "bacon", "badge", "bagel", "baker", "basin", "batch",
20
+ "beach", "beard", "beast", "berry", "blade", "blast", "blaze", "blend",
21
+ "blimp", "bliss", "blitz", "bloom", "blues", "bluff", "blunt", "board",
22
+ "bonus", "boost", "booth", "bound", "brain", "brand", "brave", "bread",
23
+ "break", "brick", "bride", "bring", "broad", "brook", "brown", "brush",
24
+ "buddy", "build", "bulge", "bully", "bunch", "cabin", "cable", "camel",
25
+ "candy", "cargo", "carol", "catch", "cause", "cave", "cedar", "chain",
26
+ "chair", "chaos", "charm", "chart", "cheek", "chess", "chest", "chief",
27
+ "child", "chill", "china", "choir", "chord", "chunk", "cigar", "civic",
28
+ "cider", "claim", "clash", "clean", "clear", "click", "cliff", "cling",
29
+ "clock", "cloud", "clown", "coach", "coast", "cocoa", "coil", "coral",
30
+ "couch", "cough", "count", "cover", "crack", "craft", "crane", "crash",
31
+ "crawl", "crazy", "cream", "creek", "crisp", "cross", "crown", "crush",
32
+ "cubic", "curry", "curse", "curve", "cycle", "dairy", "dance", "decoy",
33
+ "delay", "delta", "demon", "dense", "depot", "depth", "derby", "desert",
34
+ "devil", "diesel", "digit", "diner", "dirty", "ditch", "dodge", "doing",
35
+ "donor", "doubt", "dough", "draft", "drain", "drama", "drank", "drape",
36
+ "drawn", "dread", "dream", "dress", "dried", "drift", "drill", "drown",
37
+ "drums", "drunk", "dryer", "dunes", "dwarf", "eager", "eagle", "early",
38
+ "earth", "easel", "eaten", "eater", "ebony", "eclat", "edge", "eight",
39
+ "elder", "elect", "elite", "elope", "emoji", "empty", "enemy", "enjoy",
40
+ "enter", "entry", "equal", "error", "essay", "even", "event", "every",
41
+ "evoke", "exact", "exert", "exile", "exist", "extra", "fable", "facet",
42
+ "faith", "fancy", "fault", "feast", "fence", "ferry", "fetch", "fever",
43
+ "fiber", "field", "fifty", "fight", "final", "finch", "fleet", "flesh",
44
+ "flint", "flock", "flood", "floor", "floss", "flour", "fluid", "flush",
45
+ "flyer", "focal", "focus", "force", "forge", "forth", "forum", "found",
46
+ "frame", "frank", "fraud", "fresh", "front", "frost", "fruit", "fully",
47
+ "ghost", "giant", "given", "glass", "glide", "globe", "gloom", "glory",
48
+ "glove", "glued", "going", "gold", "good", "goose", "grain", "grand",
49
+ "grant", "grape", "graph", "grasp", "grass", "grave", "great", "green",
50
+ "greet", "grief", "grill", "grind", "gross", "group", "grove", "grown",
51
+ "guard", "guess", "guest", "guide", "guild", "guilt", "gully", "guy",
52
+ "habit", "hairy", "happy", "harsh", "haste", "haven", "heart", "heavy",
53
+ "hedge", "hello", "hence", "heron", "hobby", "honey", "honor", "horse",
54
+ "hotel", "house", "hover", "human", "humor", "hurry", "ideal", "image",
55
+ "imply", "index", "indie", "infer", "inner", "input", "irony", "ivory",
56
+ "jazz", "jeans", "jelly", "jewel", "joint", "joker", "joule", "judge",
57
+ "juice", "juicy", "jumbo", "jump", "junior", "junta", "karma", "kayak",
58
+ "kazoo", "keen", "kebab", "ketch", "kiosk", "kitty", "knack", "knew",
59
+ "knife", "knight", "knock", "knot", "known", "koala", "label", "labor",
60
+ "lager", "lance", "lapse", "large", "laser", "lasso", "latch", "later",
61
+ "latin", "laugh", "layer", "learn", "lease", "leave", "legal", "lemon",
62
+ "level", "lever", "light", "limit", "liver", "local", "logic", "login",
63
+ "loose", "lopez", "lords", "loser", "lotto", "loving", "lower", "loyal",
64
+ "lucky", "lunar", "lunch", "lying", "macro", "magic", "major", "maker",
65
+ "maple", "march", "marsh", "mason", "match", "mayor", "media", "mercy",
66
+ "merge", "merit", "merry", "metal", "meter", "might", "minor", "minus",
67
+ "mixed", "model", "mocha", "money", "month", "moral", "motor", "mount",
68
+ "mouse", "mouth", "movie", "music", "naive", "nanny", "nasty", "navel",
69
+ "needs", "nerve", "never", "night", "noble", "noise", "north", "noted",
70
+ "novel", "nudge", "nurse", "nylon", "oasis", "occur", "ocean", "offer",
71
+ "often", "olive", "onion", "onset", "open", "opera", "orbit", "order",
72
+ "organ", "other", "otter", "outer", "owner", "oxide", "ozone", "paddle",
73
+ "paint", "panel", "panic", "paper", "party", "pasta", "paste", "patch",
74
+ "pause", "peace", "peach", "pearl", "pedal", "penny", "perch", "peril",
75
+ "phase", "phone", "photo", "piano", "piece", "pilot", "pixel", "pizza",
76
+ "place", "plain", "plane", "plant", "plate", "plaza", "plead", "pluck",
77
+ "plumb", "plume", "plush", "point", "polar", "pouch", "pound", "power",
78
+ "press", "price", "pride", "prime", "prism", "prize", "probe", "prone",
79
+ "proof", "proud", "prove", "proxy", "psalm", "pulse", "punch", "pupil",
80
+ "purse", "queen", "query", "quest", "quick", "quiet", "quite", "quota",
81
+ "quote", "racer", "radar", "radio", "rally", "ranch", "range", "rapid",
82
+ "ratio", "reach", "react", "ready", "realm", "rebel", "refer", "reign",
83
+ "relax", "reply", "rerun", "resin", "retro", "rider", "ridge", "rifle",
84
+ "right", "rigid", "riley", "risky", "rival", "river", "robin", "robot",
85
+ "rocky", "rogue", "roman", "rouge", "rough", "route", "royal", "rufus",
86
+ "rugby", "ruler", "rural", "sadly", "saint", "salad", "salon", "sandy",
87
+ "satin", "sauce", "scale", "scare", "scene", "scent", "scope", "score",
88
+ "sense", "serve", "setup", "seven", "shade", "shaft", "shake", "shall",
89
+ "shame", "shape", "share", "shark", "sharp", "sheep", "sheer", "sheet",
90
+ "shelf", "shell", "shift", "shine", "shirt", "shock", "shore", "short",
91
+ "shout", "sight", "sigma", "silent", "silly", "since", "sixth", "sixty",
92
+ "sized", "skill", "skull", "slash", "sleep", "slice", "slide", "slope",
93
+ "small", "smart", "smell", "smile", "smoke", "snack", "snake", "solar",
94
+ "solid", "solve", "sorry", "sound", "south", "space", "spare", "spark",
95
+ "speak", "speed", "spell", "spend", "spice", "spill", "spine", "spite",
96
+ "split", "spoke", "spoon", "sport", "spray", "squad", "stack", "staff",
97
+ "stage", "stain", "stake", "stale", "stall", "stamp", "stand", "stark",
98
+ "start", "state", "stays", "steady", "steam", "steel", "steep", "steer",
99
+ "stern", "stick", "stiff", "still", "stock", "stone", "stood", "store",
100
+ "storm", "story", "stout", "stove", "strap", "straw", "strip", "stuck",
101
+ "study", "stuff", "style", "sugar", "suite", "sunny", "super", "surge",
102
+ "swamp", "swarm", "sweet", "swift", "swing", "swirl", "sword", "syrup",
103
+ "table", "taste", "teach", "teeth", "tempt", "terra", "thank", "theme",
104
+ "there", "thick", "thing", "think", "third", "thorn", "those", "three",
105
+ "throw", "thumb", "tiger", "tight", "timer", "title", "token", "total",
106
+ "touch", "towel", "tower", "toxic", "trace", "track", "trade", "train",
107
+ "trait", "trash", "treat", "trend", "trial", "tribe", "trick", "tried",
108
+ "troop", "truck", "truly", "trump", "trunk", "trust", "truth", "tumor",
109
+ "tuned", "twice", "twin", "twist", "ultra", "uncle", "under", "union",
110
+ "unite", "unity", "until", "upper", "upset", "urban", "usage", "usual",
111
+ "utter", "valid", "value", "vapor", "vault", "venue", "verse", "video",
112
+ "vigor", "viral", "virus", "visit", "vista", "vital", "vivid", "vocal",
113
+ "vodka", "voice", "voter", "wager", "wagon", "waist", "watch", "water",
114
+ "waved", "weary", "weave", "wedge", "weird", "whale", "wheat", "wheel",
115
+ "where", "which", "while", "white", "whole", "whose", "wider", "witch",
116
+ "woman", "world", "worry", "worse", "worst", "worth", "would", "wound",
117
+ "wreck", "wrist", "write", "wrong", "wrote", "yacht", "yield", "young",
118
+ "youth", "zebra", "zesty", "zones",
119
+ ]
120
+
121
+
122
+ def entry():
123
+ args = parse_args()
124
+
125
+ if args.passphrase:
126
+ result = generate_passphrase(args.count, args.separator, args.capitalize)
127
+ elif args.pin:
128
+ result = generate_pin(args.count, args.length)
129
+ else:
130
+ result = generate_password(args.count, args.length, args.no_symbols)
131
+
132
+ for secret, entropy in result:
133
+ print(f"{secret} ({entropy:.1f} bits)")
134
+
135
+
136
+ def generate_password(count: int, length: int, no_symbols: bool) -> list[tuple[str, float]]:
137
+ """Generate random passwords."""
138
+ chars = string.ascii_letters + string.digits
139
+ if not no_symbols:
140
+ chars += "!@#$%^&*()_+-=[]{}|;:,.<>?"
141
+ bits_per_char = math.log2(len(chars))
142
+ entropy = bits_per_char * length
143
+
144
+ results = []
145
+ for _ in range(count):
146
+ password = "".join(chars[os.urandom(1)[0] % len(chars)] for _ in range(length))
147
+ results.append((password, entropy))
148
+
149
+ return results
150
+
151
+
152
+ def generate_passphrase(count: int, separator: str, capitalize: bool) -> list[tuple[str, float]]:
153
+ """Generate passphrases from word list."""
154
+ bits_per_word = math.log2(len(WORDS))
155
+ entropy = bits_per_word * 4 # default 4 words
156
+
157
+ results = []
158
+ for _ in range(count):
159
+ words = []
160
+ for _ in range(4):
161
+ idx = int.from_bytes(os.urandom(2), "big") % len(WORDS)
162
+ word = WORDS[idx]
163
+ if capitalize:
164
+ word = word.capitalize()
165
+ words.append(word)
166
+ passphrase = separator.join(words)
167
+ results.append((passphrase, entropy))
168
+
169
+ return results
170
+
171
+
172
+ def generate_pin(count: int, length: int) -> list[tuple[str, float]]:
173
+ """Generate numeric PINs."""
174
+ entropy = math.log2(10) * length
175
+
176
+ results = []
177
+ for _ in range(count):
178
+ pin = "".join(str(os.urandom(1)[0] % 10) for _ in range(length))
179
+ results.append((pin, entropy))
180
+
181
+ return results
182
+
183
+
184
+ def parse_args():
185
+ parser = argparse.ArgumentParser(
186
+ description="passgen — 密码生成器 / Password & passphrase generator",
187
+ formatter_class=argparse.RawDescriptionHelpFormatter,
188
+ epilog="""Examples:
189
+ passgen # 4 random passwords (16 chars)
190
+ passgen -l 24 # 4 passwords, 24 chars each
191
+ passgen -c 10 # 10 passwords
192
+ passgen --pin # 4 PINs (6 digits)
193
+ passgen --pin -l 8 # 4 PINs, 8 digits
194
+ passgen --passphrase # 4 passphrases (4 words each)
195
+ passgen --passphrase --separator - # Passphrases with '-' separator
196
+ passgen --passphrase --capitalize # Capitalized words
197
+ passgen --no-symbols # Alphanumeric only
198
+ """)
199
+ parser.add_argument("-l", "--length", type=int, default=16,
200
+ help="Password length / digit count (default: 16)")
201
+ parser.add_argument("-c", "--count", type=int, default=4,
202
+ help="Number of passwords to generate (default: 4)")
203
+ parser.add_argument("--pin", action="store_true",
204
+ help="Generate numeric PINs instead of passwords")
205
+ parser.add_argument("--passphrase", action="store_true",
206
+ help="Generate memorable passphrases")
207
+ parser.add_argument("--separator", type=str, default=" ",
208
+ help="Word separator for passphrases (default: space)")
209
+ parser.add_argument("--capitalize", action="store_true",
210
+ help="Capitalize words in passphrase")
211
+ parser.add_argument("--no-symbols", action="store_true",
212
+ help="Alphanumeric only (no special chars)")
213
+
214
+ args = parser.parse_args()
215
+
216
+ if args.passphrase and args.length != 16:
217
+ # For passphrases, length= number of words
218
+ pass
219
+
220
+ return args
221
+
222
+
223
+ if __name__ == "__main__":
224
+ entry()
@@ -0,0 +1,2 @@
1
+ """portcheck — 端口检查工具"""
2
+ __version__ = "1.0.0"
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env python3
2
+ """portcheck — 端口检查与查找工具。零外部依赖。"""
3
+ import socket
4
+ import sys
5
+
6
+ def check_port(port, host="127.0.0.1"):
7
+ """检查端口是否被占用"""
8
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
9
+ s.settimeout(1)
10
+ try:
11
+ s.connect((host, port))
12
+ s.close()
13
+ return True
14
+ except (ConnectionRefusedError, OSError):
15
+ return False
16
+
17
+ def find_free_port(start, end=None):
18
+ """查找空闲端口"""
19
+ end = end or start + 100
20
+ for port in range(start, end + 1):
21
+ if not check_port(port):
22
+ return port
23
+ return None
24
+
25
+ def format_output(port, in_use):
26
+ status = "🔴 已占用" if in_use else "🟢 空闲"
27
+ return f"Port {port:<5} {status}"
28
+
29
+ def main():
30
+ args = sys.argv[1:]
31
+ if not args or args[0] in ("-h", "--help"):
32
+ print("用法:")
33
+ print(" portcheck <port> — 检查指定端口")
34
+ print(" portcheck --free [start] [end] — 查找空闲端口")
35
+ print(" portcheck --list <start>-<end> — 列出端口状态范围")
36
+ print("示例:")
37
+ print(" portcheck 3000")
38
+ print(" portcheck --free 3000 3100")
39
+ print(" portcheck --list 3000-3010")
40
+ return
41
+
42
+ if args[0] == "--free":
43
+ start = int(args[1]) if len(args) > 1 else 3000
44
+ end = int(args[2]) if len(args) > 2 else start + 100
45
+ port = find_free_port(start, end)
46
+ if port:
47
+ print(f"✅ 空闲端口: {port}")
48
+ else:
49
+ print(f"❌ 在 {start}-{end} 范围内未找到空闲端口")
50
+ elif args[0] == "--list":
51
+ parts = args[1].split("-") if len(args) > 1 else []
52
+ start = int(parts[0]) if parts else 3000
53
+ end = int(parts[1]) if len(parts) > 1 else start + 10
54
+ for port in range(start, end + 1):
55
+ print(format_output(port, check_port(port)))
56
+ else:
57
+ port = int(args[0])
58
+ if port < 1 or port > 65535:
59
+ print(f"❌ 端口号必须在 1-65535 范围内: {port}", file=sys.stderr)
60
+ sys.exit(1)
61
+ in_use = check_port(port)
62
+ print(format_output(port, in_use))
63
+ sys.exit(0 if not in_use else 1)
64
+
65
+ if __name__ == "__main__":
66
+ main()