mint-osint 1.0.2__tar.gz

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.
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: mint-osint
3
+ Version: 1.0.2
4
+ Summary: MINT — The Unified OSINT & Media Command Center
5
+ Author: sayfalse
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: colorama>=0.4.6
9
+
10
+ <p align="center">
11
+ <img src="logo.png" alt="MINT Logo" width="400">
12
+ </p>
13
+
14
+ <h1 align="center">MINT — The Unified OSINT & Media Command Center</h1>
15
+
16
+ **MINT** is an interactive, terminal-based command center that unifies industry-standard OSINT (Open Source Intelligence) tools and a robust media archiver into a single, cohesive interface. Built for researchers, security analysts, and developers, MINT simplifies target intelligence gathering, social media investigation, and media preservation under a clean, keyboard-driven environment.
17
+
18
+ ---
19
+
20
+ ## Key Features
21
+
22
+ 1. **Sherlock (Username Scanner)**
23
+ - Scans and locates target social media accounts by username across over 300 platforms simultaneously.
24
+ 2. **Holehe (Email Checker)**
25
+ - Analyzes email address registrations across more than 120 websites using password recovery endpoints, identifying registered accounts without alerting the target.
26
+ 3. **SpiderFoot (OSINT Web Server)**
27
+ - Launches a local web server interface to automate security audits, domain reconnaissance, and threat intelligence gathering.
28
+ 4. **Toutatis (Instagram Extractor)**
29
+ - Extracts associated emails, phone numbers, and detailed profile metadata from Instagram accounts.
30
+ 5. **MINT Social Tool (Social Downloader)**
31
+ - A native, interactive downloader to archive photos, videos, stories, and highlights from major platforms (Instagram, TikTok, Facebook, and X/Twitter). Powered by high-speed `gallery-dl` and `yt-dlp` engines.
32
+ 6. **One-Click Update Manager**
33
+ - Automatically pulls the latest updates directly from the official GitHub repositories for all 4 external OSINT tools and installs any updated dependencies.
34
+
35
+ ---
36
+
37
+ ## Smart Path-Resolution Installer
38
+
39
+ The MINT installer (`setup.bat` / `setup.sh`) is designed to protect your file system from clutter. It prompts you once for a parent directory and automatically structures the installation cleanly:
40
+ * **Tools Directory:** Recreated as `<parent_folder>\MINT_Tools\` to hold all cloned OSINT scanners.
41
+ * **Media Directory:** Recreated as `<parent_folder>\mint-social\` to store downloaded media, profile logs, and cookies.
42
+ * **Global Wrappers:** Automatically registers a global `mint` command wrapper in your system path, allowing you to launch the Command Center from any terminal window.
43
+
44
+ ---
45
+
46
+ ## Installation & Setup
47
+
48
+ MINT automatically manages the environment checks, directory structures, tool cloning, and dependency installations.
49
+
50
+ ### Prerequisites
51
+ * **Python 3.10+** (Windows, macOS, or Linux)
52
+ * **Git** (recommended for cloning and updates; falls back to ZIP downloads if Git is missing)
53
+
54
+ ### Windows Installation (Recommended)
55
+ 1. Clone this repository to your system:
56
+ ```bash
57
+ git clone https://github.com/sayfalse/mint.git
58
+ cd mint
59
+ ```
60
+ 2. Run the interactive installer by double-clicking `setup.bat` or executing:
61
+ ```cmd
62
+ setup.bat
63
+ ```
64
+ 3. Enter your preferred parent directory (e.g., `E:\mint` or `G:\`). The installer will automatically configure and build the directory tree.
65
+
66
+ ### macOS / Linux Installation
67
+ 1. Clone the repository and navigate into it:
68
+ ```bash
69
+ git clone https://github.com/sayfalse/mint.git
70
+ cd mint
71
+ ```
72
+ 2. Run the setup script:
73
+ ```bash
74
+ chmod +x setup.sh
75
+ ./setup.sh
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Package Managers
81
+
82
+ ```bash
83
+ # YOLO
84
+ curl -fsSL https://raw.githubusercontent.com/sayfalse/mint/main/setup.sh | bash
85
+
86
+ # Package managers
87
+ pip install mint-osint # or pip install . (local install)
88
+ scoop install mint-osint # Windows
89
+ choco install mint-osint # Windows
90
+ brew install sayfalse/tap/mint # macOS and Linux (recommended, always up to date)
91
+ brew install mint-osint # macOS and Linux (official brew formula, updated less)
92
+ sudo pacman -S mint-osint # Arch Linux (Stable)
93
+ paru -S mint-osint-bin # Arch Linux (Latest from AUR)
94
+ nix run nixpkgs#mint-osint # or github:sayfalse/mint for latest dev branch
95
+ ```
96
+
97
+ ---
98
+
99
+ ## How to Run
100
+
101
+ Once setup is complete, you can launch the Command Center globally:
102
+
103
+ 1. Open a new terminal window.
104
+ 2. Type **`mint`** and press **Enter**.
105
+ 3. Use the **Up/Down arrow keys** to navigate the menu, and **Enter** to launch your selected tool.
106
+ 4. Alternatively, use the quick keyboard hotkeys (**1 to 7**) to jump directly to options.
107
+
108
+ ---
109
+
110
+ ## Cookie Configuration for Media Downloader
111
+
112
+ To download content from private profiles or bypass rate limits on social networks, the MINT Social Tool utilizes session cookies. The installer automatically generates 4 empty template cookie files in the correct path:
113
+ * `<parent_folder>\mint-social\cookies\facebook.com_cookies.txt`
114
+ * `<parent_folder>\mint-social\cookies\instagram.com_cookies.txt`
115
+ * `<parent_folder>\mint-social\cookies\tiktok.com_cookies.txt`
116
+ * `<parent_folder>\mint-social\cookies\x.com_cookies.txt`
117
+
118
+ ### How to export and use cookies:
119
+ 1. Install a browser extension like **Get cookies.txt LOCALLY** or **EditThisCookie** (available for Chrome/Firefox).
120
+ 2. Log into your account on the target social network (e.g., Instagram or X).
121
+ 3. Open the extension and export the cookies in **Netscape format**.
122
+ 4. Open the corresponding cookie file in a text editor (e.g., `instagram.com_cookies.txt`) and paste the exported content.
123
+ 5. Save the file. The MINT Social Tool will automatically load these cookies on subsequent runs.
124
+
125
+ ---
126
+
127
+ ## Configuration File (`config.json`)
128
+
129
+ The installer generates a `config.json` file in the MINT root directory to map all system paths dynamically. You can edit this file manually to update paths if you move directories:
130
+ ```json
131
+ {
132
+ "tools_dir": "E:\\mint\\MINT_Tools",
133
+ "social_dir": "E:\\mint\\mint-social",
134
+ "mint_dir": "E:\\mint",
135
+ "mint_py_path": "E:\\mint\\mint.py",
136
+ "sherlock_path": "E:\\mint\\MINT_Tools\\sherlock",
137
+ "holehe_path": "E:\\mint\\MINT_Tools\\holehe",
138
+ "spiderfoot_path": "E:\\mint\\MINT_Tools\\spiderfoot",
139
+ "toutatis_path": "E:\\mint\\MINT_Tools\\toutatis"
140
+ }
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Troubleshooting & Console Setup
146
+
147
+ * **Unicode Display Issues:** If block characters or box-drawing lines appear distorted in your Windows console, MINT automatically attempts to force UTF-8 encoding on startup. If issues persist, run the following command in your terminal before launching MINT:
148
+ ```cmd
149
+ chcp 65001
150
+ ```
151
+ * **Git Credential Conflicts:** If the update manager fails to pull tools due to account conflicts, MINT operates a fallback mechanism that automatically downloads the latest zip archives from official repositories and extracts them cleanly, preserving your configuration.
152
+ * **Dependencies Failed to Install:** Ensure your terminal is running with sufficient write permissions for the target installation folders, and that Python is added to your system's PATH variable.
@@ -0,0 +1,143 @@
1
+ <p align="center">
2
+ <img src="logo.png" alt="MINT Logo" width="400">
3
+ </p>
4
+
5
+ <h1 align="center">MINT — The Unified OSINT & Media Command Center</h1>
6
+
7
+ **MINT** is an interactive, terminal-based command center that unifies industry-standard OSINT (Open Source Intelligence) tools and a robust media archiver into a single, cohesive interface. Built for researchers, security analysts, and developers, MINT simplifies target intelligence gathering, social media investigation, and media preservation under a clean, keyboard-driven environment.
8
+
9
+ ---
10
+
11
+ ## Key Features
12
+
13
+ 1. **Sherlock (Username Scanner)**
14
+ - Scans and locates target social media accounts by username across over 300 platforms simultaneously.
15
+ 2. **Holehe (Email Checker)**
16
+ - Analyzes email address registrations across more than 120 websites using password recovery endpoints, identifying registered accounts without alerting the target.
17
+ 3. **SpiderFoot (OSINT Web Server)**
18
+ - Launches a local web server interface to automate security audits, domain reconnaissance, and threat intelligence gathering.
19
+ 4. **Toutatis (Instagram Extractor)**
20
+ - Extracts associated emails, phone numbers, and detailed profile metadata from Instagram accounts.
21
+ 5. **MINT Social Tool (Social Downloader)**
22
+ - A native, interactive downloader to archive photos, videos, stories, and highlights from major platforms (Instagram, TikTok, Facebook, and X/Twitter). Powered by high-speed `gallery-dl` and `yt-dlp` engines.
23
+ 6. **One-Click Update Manager**
24
+ - Automatically pulls the latest updates directly from the official GitHub repositories for all 4 external OSINT tools and installs any updated dependencies.
25
+
26
+ ---
27
+
28
+ ## Smart Path-Resolution Installer
29
+
30
+ The MINT installer (`setup.bat` / `setup.sh`) is designed to protect your file system from clutter. It prompts you once for a parent directory and automatically structures the installation cleanly:
31
+ * **Tools Directory:** Recreated as `<parent_folder>\MINT_Tools\` to hold all cloned OSINT scanners.
32
+ * **Media Directory:** Recreated as `<parent_folder>\mint-social\` to store downloaded media, profile logs, and cookies.
33
+ * **Global Wrappers:** Automatically registers a global `mint` command wrapper in your system path, allowing you to launch the Command Center from any terminal window.
34
+
35
+ ---
36
+
37
+ ## Installation & Setup
38
+
39
+ MINT automatically manages the environment checks, directory structures, tool cloning, and dependency installations.
40
+
41
+ ### Prerequisites
42
+ * **Python 3.10+** (Windows, macOS, or Linux)
43
+ * **Git** (recommended for cloning and updates; falls back to ZIP downloads if Git is missing)
44
+
45
+ ### Windows Installation (Recommended)
46
+ 1. Clone this repository to your system:
47
+ ```bash
48
+ git clone https://github.com/sayfalse/mint.git
49
+ cd mint
50
+ ```
51
+ 2. Run the interactive installer by double-clicking `setup.bat` or executing:
52
+ ```cmd
53
+ setup.bat
54
+ ```
55
+ 3. Enter your preferred parent directory (e.g., `E:\mint` or `G:\`). The installer will automatically configure and build the directory tree.
56
+
57
+ ### macOS / Linux Installation
58
+ 1. Clone the repository and navigate into it:
59
+ ```bash
60
+ git clone https://github.com/sayfalse/mint.git
61
+ cd mint
62
+ ```
63
+ 2. Run the setup script:
64
+ ```bash
65
+ chmod +x setup.sh
66
+ ./setup.sh
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Package Managers
72
+
73
+ ```bash
74
+ # YOLO
75
+ curl -fsSL https://raw.githubusercontent.com/sayfalse/mint/main/setup.sh | bash
76
+
77
+ # Package managers
78
+ pip install mint-osint # or pip install . (local install)
79
+ scoop install mint-osint # Windows
80
+ choco install mint-osint # Windows
81
+ brew install sayfalse/tap/mint # macOS and Linux (recommended, always up to date)
82
+ brew install mint-osint # macOS and Linux (official brew formula, updated less)
83
+ sudo pacman -S mint-osint # Arch Linux (Stable)
84
+ paru -S mint-osint-bin # Arch Linux (Latest from AUR)
85
+ nix run nixpkgs#mint-osint # or github:sayfalse/mint for latest dev branch
86
+ ```
87
+
88
+ ---
89
+
90
+ ## How to Run
91
+
92
+ Once setup is complete, you can launch the Command Center globally:
93
+
94
+ 1. Open a new terminal window.
95
+ 2. Type **`mint`** and press **Enter**.
96
+ 3. Use the **Up/Down arrow keys** to navigate the menu, and **Enter** to launch your selected tool.
97
+ 4. Alternatively, use the quick keyboard hotkeys (**1 to 7**) to jump directly to options.
98
+
99
+ ---
100
+
101
+ ## Cookie Configuration for Media Downloader
102
+
103
+ To download content from private profiles or bypass rate limits on social networks, the MINT Social Tool utilizes session cookies. The installer automatically generates 4 empty template cookie files in the correct path:
104
+ * `<parent_folder>\mint-social\cookies\facebook.com_cookies.txt`
105
+ * `<parent_folder>\mint-social\cookies\instagram.com_cookies.txt`
106
+ * `<parent_folder>\mint-social\cookies\tiktok.com_cookies.txt`
107
+ * `<parent_folder>\mint-social\cookies\x.com_cookies.txt`
108
+
109
+ ### How to export and use cookies:
110
+ 1. Install a browser extension like **Get cookies.txt LOCALLY** or **EditThisCookie** (available for Chrome/Firefox).
111
+ 2. Log into your account on the target social network (e.g., Instagram or X).
112
+ 3. Open the extension and export the cookies in **Netscape format**.
113
+ 4. Open the corresponding cookie file in a text editor (e.g., `instagram.com_cookies.txt`) and paste the exported content.
114
+ 5. Save the file. The MINT Social Tool will automatically load these cookies on subsequent runs.
115
+
116
+ ---
117
+
118
+ ## Configuration File (`config.json`)
119
+
120
+ The installer generates a `config.json` file in the MINT root directory to map all system paths dynamically. You can edit this file manually to update paths if you move directories:
121
+ ```json
122
+ {
123
+ "tools_dir": "E:\\mint\\MINT_Tools",
124
+ "social_dir": "E:\\mint\\mint-social",
125
+ "mint_dir": "E:\\mint",
126
+ "mint_py_path": "E:\\mint\\mint.py",
127
+ "sherlock_path": "E:\\mint\\MINT_Tools\\sherlock",
128
+ "holehe_path": "E:\\mint\\MINT_Tools\\holehe",
129
+ "spiderfoot_path": "E:\\mint\\MINT_Tools\\spiderfoot",
130
+ "toutatis_path": "E:\\mint\\MINT_Tools\\toutatis"
131
+ }
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Troubleshooting & Console Setup
137
+
138
+ * **Unicode Display Issues:** If block characters or box-drawing lines appear distorted in your Windows console, MINT automatically attempts to force UTF-8 encoding on startup. If issues persist, run the following command in your terminal before launching MINT:
139
+ ```cmd
140
+ chcp 65001
141
+ ```
142
+ * **Git Credential Conflicts:** If the update manager fails to pull tools due to account conflicts, MINT operates a fallback mechanism that automatically downloads the latest zip archives from official repositories and extracts them cleanly, preserving your configuration.
143
+ * **Dependencies Failed to Install:** Ensure your terminal is running with sufficient write permissions for the target installation folders, and that Python is added to your system's PATH variable.
@@ -0,0 +1,692 @@
1
+ import os
2
+ import sys
3
+ import time
4
+ import subprocess
5
+ import msvcrt
6
+ import json
7
+ import shutil
8
+ import urllib.request
9
+ import zipfile
10
+ import io
11
+
12
+ # Force UTF-8 encoding on Windows to prevent UnicodeEncodeErrors with box-drawing characters
13
+ if sys.platform.startswith('win'):
14
+ import io
15
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
16
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
17
+
18
+ from colorama import init, Fore, Back, Style
19
+
20
+ # Initialize colorama
21
+ init(autoreset=True)
22
+
23
+ OPTIONS = [
24
+ {"name": "Sherlock (Username Scanner)", "desc": "Hunts down social media accounts by username across 300+ sites"},
25
+ {"name": "Holehe (Email Checker)", "desc": "Checks if an email address is registered on 120+ different websites"},
26
+ {"name": "SpiderFoot (OSINT Web Server)", "desc": "Automates intelligence gathering via a local web interface"},
27
+ {"name": "Toutatis (Instagram Extractor)", "desc": "Extracts associated emails and phone numbers from Instagram profiles"},
28
+ {"name": "MINT Social Tool (Social Downloader)", "desc": "Downloads photos, videos, stories, and highlights from profiles"},
29
+ {"name": "Update Tools (GitHub Pull)", "desc": "Pull the latest updates for all 4 external OSINT tools from their official repositories"},
30
+ {"name": "Exit", "desc": "Close the MINT Command Center"}
31
+ ]
32
+
33
+ # Constants and Paths for MINT Social Tool (dynamically resolved from config.json if available)
34
+ config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config.json")
35
+
36
+ # Dynamic defaults based on user's home directory (standard writeable location across Windows users)
37
+ user_home = os.path.expanduser("~")
38
+ BASE = os.path.join(user_home, "mint-social")
39
+ COOKIES_DIR = os.path.join(BASE, "cookies")
40
+
41
+ if os.path.exists(config_path):
42
+ try:
43
+ with open(config_path, "r", encoding="utf-8") as f:
44
+ config_data = json.load(f)
45
+ if "social_dir" in config_data:
46
+ BASE = config_data["social_dir"]
47
+ COOKIES_DIR = os.path.join(BASE, "cookies")
48
+ except:
49
+ pass
50
+
51
+ BROWSER = "chrome"
52
+ PYTHON = sys.executable
53
+ UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
54
+
55
+ PHOTO_FILTER = "extension in ('jpg','jpeg','png','gif','webp','bmp','jfif','heic','avif','tiff','svg')"
56
+ VIDEO_FILTER = "extension in ('mp4','webm','mkv','mov','avi','m4v','flv','wmv','3gp','mpeg','mpg','ts','f4v','mts','m2ts')"
57
+ MEDIA_EXTS = ["jpg", "jpeg", "png", "gif", "webp", "bmp", "jfif", "heic", "avif", "tiff", "svg", "mp4", "webm", "mkv", "mov", "avi", "m4v", "flv", "wmv", "3gp", "mpeg", "mpg", "ts", "f4v", "mts", "m2ts"]
58
+
59
+ def clear_screen():
60
+ os.system('cls' if os.name == 'nt' else 'clear')
61
+
62
+ def get_terminal_width():
63
+ try:
64
+ width = os.get_terminal_size().columns
65
+ return width if width > 20 else 80
66
+ except:
67
+ return 80
68
+
69
+ def print_centered(text, visible_len, color=""):
70
+ width = get_terminal_width()
71
+ padding = max(0, (width - visible_len) // 2)
72
+ print(" " * padding + color + text)
73
+
74
+ def wrap_text(text, max_len=52):
75
+ words = text.split()
76
+ lines = []
77
+ current_line = []
78
+ current_len = 0
79
+ for word in words:
80
+ if current_len + len(word) + len(current_line) > max_len:
81
+ lines.append(" ".join(current_line))
82
+ current_line = [word]
83
+ current_len = len(word)
84
+ else:
85
+ current_line.append(word)
86
+ current_len += len(word)
87
+ if current_line:
88
+ lines.append(" ".join(current_line))
89
+ return lines
90
+
91
+ def draw_header(subtitle="Select a tool to launch from the menu below:"):
92
+ logo_lines = [
93
+ " ▄ ",
94
+ " ▄█▀█▄ ",
95
+ " ▄██ ██▄ ",
96
+ " ████ ████ ",
97
+ " ▄████ ████▄ ",
98
+ " ██████ ██████ ",
99
+ " ▀████ ████▀ ",
100
+ " ▄█████ █████▄ ",
101
+ " ▀████ ████▀ ",
102
+ " ▀██ ██▀ ",
103
+ " █ █ ",
104
+ " ▀ ▀ "
105
+ ]
106
+
107
+ current_workspace = os.getcwd()
108
+
109
+ for line in logo_lines:
110
+ print_centered(line, 26, Fore.GREEN)
111
+
112
+ print()
113
+ print_centered("M I N T v1.0", 14, Fore.GREEN + Style.BRIGHT)
114
+ print_centered("─" * 50, 50, Fore.LIGHTBLACK_EX)
115
+ print_centered("The Unified OSINT & Media Command Center", 40, Fore.WHITE + Style.BRIGHT)
116
+ print_centered(f"Workspace: {current_workspace}", len(f"Workspace: {current_workspace}"), Fore.LIGHTBLACK_EX)
117
+ print_centered(Fore.LIGHTBLACK_EX + "GitHub: " + Fore.BLUE + "https://github.com/sayfalse", 36)
118
+ print_centered("Environment: Windows • Python: 3.14", 37, Fore.LIGHTBLACK_EX)
119
+ print()
120
+ print_centered(subtitle, len(subtitle), Fore.WHITE)
121
+ print()
122
+
123
+ def draw_menu(selected_index):
124
+ clear_screen()
125
+ draw_header()
126
+
127
+ menu_width = 43
128
+ width = get_terminal_width()
129
+ menu_padding = max(0, (width - menu_width) // 2)
130
+
131
+ for i, opt in enumerate(OPTIONS):
132
+ if i == selected_index:
133
+ print(" " * menu_padding + Fore.GREEN + Style.BRIGHT + " ❯ " + Back.GREEN + Fore.BLACK + f" {opt['name'].ljust(38)} " + Style.RESET_ALL)
134
+ else:
135
+ print(" " * menu_padding + Fore.WHITE + f" {opt['name']}")
136
+ print()
137
+
138
+ desc_width = 50
139
+ desc_padding = max(0, (width - desc_width) // 2)
140
+
141
+ print(" " * desc_padding + Fore.LIGHTBLACK_EX + "─" * 50)
142
+ current_desc = OPTIONS[selected_index]['desc']
143
+ wrapped_desc = wrap_text(current_desc, 44)
144
+ for idx, d_line in enumerate(wrapped_desc):
145
+ if idx == 0:
146
+ print(" " * desc_padding + Fore.YELLOW + "Info: " + Fore.WHITE + d_line)
147
+ else:
148
+ print(" " * desc_padding + " " + Fore.WHITE + d_line)
149
+ print(" " * desc_padding + Fore.LIGHTBLACK_EX + "─" * 50)
150
+ print()
151
+
152
+ print_centered(Fore.BLACK + Back.LIGHTBLACK_EX + " ↑/↓: Move • Enter: Run • 1-7: Hotkey • Esc: Exit ", 58)
153
+ print()
154
+
155
+ def get_key():
156
+ ch = msvcrt.getch()
157
+ if ch in (b'\x00', b'\xe0'):
158
+ ch = msvcrt.getch()
159
+ if ch == b'H': return 'up'
160
+ if ch == b'P': return 'down'
161
+ elif ch == b'\r':
162
+ return 'enter'
163
+ elif ch == b'\x1b':
164
+ return 'esc'
165
+ else:
166
+ try:
167
+ return ch.decode('utf-8')
168
+ except:
169
+ return None
170
+
171
+ def prompt_input(label):
172
+ print(Fore.GREEN + f" ❯ {label}: " + Fore.WHITE, end="")
173
+ sys.stdout.flush()
174
+ return input().strip()
175
+
176
+ def run_command(cmd_string):
177
+ try:
178
+ subprocess.run(cmd_string, shell=True)
179
+ except KeyboardInterrupt:
180
+ print(Fore.YELLOW + "\n [!] Process stopped by user.")
181
+ except Exception as e:
182
+ print(Fore.RED + f"\n [!] Error executing command: {e}")
183
+
184
+ def parse_profile_url(url, platform):
185
+ url = url.strip()
186
+ if not url:
187
+ return None
188
+ if not url.lower().startswith("http"):
189
+ url = "https://" + url
190
+ t = url.replace("http://", "").replace("https://", "")
191
+ if t.startswith("/"):
192
+ t = t[1:]
193
+ parts = t.split("/")
194
+ if len(parts) < 2:
195
+ return None
196
+ dom = parts[0].replace("www.", "").lower()
197
+ usr = parts[1]
198
+
199
+ if platform == "instagram" and dom != "instagram.com": return None
200
+ if platform == "tiktok" and dom != "tiktok.com": return None
201
+ if platform == "facebook" and dom != "facebook.com": return None
202
+ if platform == "x" and dom not in ["x.com", "twitter.com"]: return None
203
+
204
+ username = usr.replace("@", "")
205
+ for char in ["?", "#", "/"]:
206
+ username = username.split(char)[0]
207
+ return username if username else None
208
+
209
+ def get_cookies_arg(platform):
210
+ if platform == "tiktok":
211
+ return f"--cookies-from-browser {BROWSER}"
212
+
213
+ possible_dirs = [d for d in [COOKIES_DIR, BASE] if d and os.path.exists(d)]
214
+ possible_names = [
215
+ f"{platform}.com_cookies.txt",
216
+ f"{platform}_cookies.txt",
217
+ f"{platform}.com_cookies.txt"
218
+ ]
219
+
220
+ possible_paths = [os.path.join(d, name) for d in possible_dirs for name in possible_names]
221
+ for path in possible_paths:
222
+ if os.path.exists(path):
223
+ return f'--cookies "{path}"'
224
+
225
+ return ""
226
+
227
+ def check_archive(directory, archive_path):
228
+ if not os.path.exists(directory):
229
+ if os.path.exists(archive_path):
230
+ try: os.remove(archive_path)
231
+ except: pass
232
+ return
233
+
234
+ media_count = 0
235
+ for root, _, files in os.walk(directory):
236
+ for file in files:
237
+ ext = file.split(".")[-1].lower()
238
+ if ext in MEDIA_EXTS:
239
+ media_count += 1
240
+
241
+ archive_lines = 0
242
+ if os.path.exists(archive_path):
243
+ try:
244
+ with open(archive_path, "r", encoding="utf-8", errors="ignore") as f:
245
+ archive_lines = len(f.readlines())
246
+ except:
247
+ pass
248
+
249
+ if media_count == 0:
250
+ if os.path.exists(archive_path):
251
+ try:
252
+ os.remove(archive_path)
253
+ print(" Empty, archive cleared.")
254
+ except:
255
+ pass
256
+ elif archive_lines == 0:
257
+ print(f" {media_count} files, rebuilding...")
258
+ else:
259
+ print(f" {media_count} files, archive ok.")
260
+
261
+ def run_gallery_dl(gdir, gfil, gck, gurl):
262
+ os.makedirs(gdir, exist_ok=True)
263
+ archive_path = os.path.join(gdir, "archive.txt")
264
+ cmd = f'"{PYTHON}" -m gallery_dl -D "{gdir}" --filter "{gfil}" {gck} -o "user-agent={UA}" --download-archive "{archive_path}" --sleep-request 5 "{gurl}"'
265
+ return subprocess.run(cmd, shell=True).returncode
266
+
267
+ def run_yt_dlp(ydir, yck, yurl):
268
+ os.makedirs(ydir, exist_ok=True)
269
+ cmd = f'"{PYTHON}" -m yt_dlp -o "{ydir}\\%(title)s.%(ext)s" {yck} --no-playlist --user-agent "{UA}" "{yurl}"'
270
+ return subprocess.run(cmd, shell=True).returncode
271
+
272
+ def download_photos(dest_dir, cookies_arg, url):
273
+ check_archive(os.path.join(dest_dir, "Photos"), os.path.join(dest_dir, "Photos", "archive.txt"))
274
+ print(" [Photos]")
275
+ ret = run_gallery_dl(os.path.join(dest_dir, "Photos"), PHOTO_FILTER, cookies_arg, url)
276
+ if ret != 0:
277
+ print(" [ERROR]")
278
+
279
+ def download_videos(dest_dir, cookies_arg, url):
280
+ check_archive(os.path.join(dest_dir, "Videos"), os.path.join(dest_dir, "Videos", "archive.txt"))
281
+ print(" [Videos]")
282
+ ret = run_gallery_dl(os.path.join(dest_dir, "Videos"), VIDEO_FILTER, cookies_arg, url)
283
+ if ret != 0:
284
+ print(" Trying yt-dlp...")
285
+ ret_yt = run_yt_dlp(os.path.join(dest_dir, "Videos"), cookies_arg, url)
286
+ if ret_yt != 0:
287
+ print(" [ERROR]")
288
+
289
+ def download_stories(dest_dir, cookies_arg, platform, username):
290
+ if platform != "instagram":
291
+ return
292
+ check_archive(os.path.join(dest_dir, "Stories"), os.path.join(dest_dir, "Stories", "archive.txt"))
293
+ print(" [Stories]")
294
+ url = f"https://www.instagram.com/stories/{username}/"
295
+ ret = run_gallery_dl(os.path.join(dest_dir, "Stories"), "true", cookies_arg, url)
296
+ if ret != 0:
297
+ print(" [ERROR]")
298
+
299
+ def download_highlights(dest_dir, cookies_arg, platform, username):
300
+ if platform != "instagram":
301
+ return
302
+ check_archive(os.path.join(dest_dir, "Highlights"), os.path.join(dest_dir, "Highlights", "archive.txt"))
303
+ print(" [Highlights]")
304
+ url = f"https://www.instagram.com/{username}/highlights/"
305
+ ret = run_gallery_dl(os.path.join(dest_dir, "Highlights"), "true", cookies_arg, url)
306
+ if ret != 0:
307
+ print(" [ERROR]")
308
+
309
+ def download_profile(username, dest_dir, platform, original_url, media_choice):
310
+ cookies_arg = get_cookies_arg(platform)
311
+ url = original_url.strip()
312
+ while url.endswith("/"):
313
+ url = url[:-1]
314
+
315
+ if media_choice in ["1", "5", "7"]:
316
+ download_photos(dest_dir, cookies_arg, url)
317
+ if media_choice in ["2", "5", "7"]:
318
+ download_videos(dest_dir, cookies_arg, url)
319
+ if media_choice in ["3", "6", "7"]:
320
+ download_stories(dest_dir, cookies_arg, platform, username)
321
+ if media_choice in ["4", "6", "7"]:
322
+ download_highlights(dest_dir, cookies_arg, platform, username)
323
+
324
+ def run_social_tool_downloads(media_choice):
325
+ os.makedirs(BASE, exist_ok=True)
326
+ os.makedirs(COOKIES_DIR, exist_ok=True)
327
+
328
+ platforms = ["instagram", "tiktok", "facebook", "x"]
329
+ for platform in platforms:
330
+ profile_file = os.path.join(BASE, f"{platform}_profiles.txt")
331
+ if os.path.exists(profile_file):
332
+ if platform == "x":
333
+ print(Fore.CYAN + "\n [X/TWITTER]")
334
+ else:
335
+ print(Fore.CYAN + f"\n [{platform.upper()}]")
336
+
337
+ try:
338
+ with open(profile_file, "r", encoding="utf-8", errors="ignore") as f:
339
+ lines = f.readlines()
340
+ except Exception as e:
341
+ print(Fore.RED + f" [!] Error reading profiles: {e}")
342
+ continue
343
+
344
+ for line in lines:
345
+ line = line.strip()
346
+ if not line:
347
+ continue
348
+ if line.startswith("#") or line.startswith(";"):
349
+ continue
350
+
351
+ username = parse_profile_url(line, platform)
352
+ if username and username != "INVALID_URL":
353
+ print(Fore.WHITE + f" --- {username}")
354
+ dest_dir = os.path.join(BASE, platform, username)
355
+ download_profile(username, dest_dir, platform, line, media_choice)
356
+
357
+ def draw_social_menu(selected_index):
358
+ clear_screen()
359
+ draw_header("Running: MINT Social Tool (Social Downloader)")
360
+
361
+ print_centered("=== MINT Social Tool ===", 24, Fore.GREEN + Style.BRIGHT)
362
+ print()
363
+ print_centered("What do you want to download?", 29, Fore.WHITE + Style.BRIGHT)
364
+ print()
365
+
366
+ menu_options = [
367
+ "Photos only",
368
+ "Videos only",
369
+ "Stories only",
370
+ "Highlights only",
371
+ "Photos + Videos",
372
+ "Stories + Highlights",
373
+ "All",
374
+ "Back to Main Menu"
375
+ ]
376
+
377
+ menu_width = 30
378
+ width = get_terminal_width()
379
+ menu_padding = max(0, (width - menu_width) // 2)
380
+
381
+ for i, opt in enumerate(menu_options):
382
+ if i == selected_index:
383
+ print(" " * menu_padding + Fore.GREEN + Style.BRIGHT + f" ❯ " + Back.GREEN + Fore.BLACK + f" [{i+1}] {opt.ljust(20)} " + Style.RESET_ALL)
384
+ else:
385
+ print(" " * menu_padding + Fore.WHITE + f" [{i+1}] {opt}")
386
+
387
+ print()
388
+ print_centered(" ↑/↓: Move • Enter: Select • 1-8: Hotkey ", 48, Fore.BLACK + Back.LIGHTBLACK_EX)
389
+ print()
390
+
391
+ def run_social_tool_tui():
392
+ selected_index = 0
393
+ while True:
394
+ draw_social_menu(selected_index)
395
+ key = get_key()
396
+
397
+ if key == 'up':
398
+ selected_index = (selected_index - 1) % 8
399
+ elif key == 'down':
400
+ selected_index = (selected_index + 1) % 8
401
+ elif key == 'esc':
402
+ break
403
+ elif key in ['1', '2', '3', '4', '5', '6', '7', '8']:
404
+ selected_index = int(key) - 1
405
+ key = 'enter'
406
+
407
+ if key == 'enter':
408
+ if selected_index == 7:
409
+ break
410
+
411
+ clear_screen()
412
+ media_choice = str(selected_index + 1)
413
+ draw_header(f"Running: MINT Social Tool - Mode [{media_choice}]")
414
+
415
+ print(Fore.GREEN + Style.BRIGHT + f" === MINT Social Tool - Mode [{media_choice}] ===")
416
+ print()
417
+ print(Fore.YELLOW + f" [+] Starting downloads in mode [{media_choice}]...")
418
+ print(Fore.LIGHTBLACK_EX + " " + "─" * 50)
419
+
420
+ try:
421
+ run_social_tool_downloads(media_choice)
422
+ except KeyboardInterrupt:
423
+ print(Fore.YELLOW + "\n [!] Downloads interrupted by user.")
424
+ except Exception as e:
425
+ print(Fore.RED + f"\n [!] Error running downloads: {e}")
426
+
427
+ print(Fore.LIGHTBLACK_EX + "\n " + "─" * 50)
428
+ print(Fore.GREEN + " [+] Done.")
429
+ print()
430
+ input(" Press Enter to return to MINT Social Tool menu...")
431
+
432
+ def update_single_tool(key, name, path):
433
+ if os.path.exists(os.path.join(path, ".git")):
434
+ try:
435
+ print(Fore.LIGHTBLACK_EX + " Running git pull...")
436
+ subprocess.run(["git", "-C", path, "pull"], check=True)
437
+
438
+ req_file = os.path.join(path, "requirements.txt")
439
+ if os.path.exists(req_file):
440
+ if key == "spiderfoot":
441
+ try:
442
+ with open(req_file, "r", encoding="utf-8") as f:
443
+ content = f.read()
444
+ if "lxml>=4.9.2,<5" in content:
445
+ content = content.replace("lxml>=4.9.2,<5", "lxml>=4.9.2")
446
+ with open(req_file, "w", encoding="utf-8") as f:
447
+ f.write(content)
448
+ except Exception as e:
449
+ print(Fore.RED + f" [!] Warning: Failed to patch SpiderFoot requirements: {e}")
450
+
451
+ print(Fore.LIGHTBLACK_EX + " Upgrading dependencies...")
452
+ subprocess.run([sys.executable, "-m", "pip", "install", "-r", req_file], check=True)
453
+
454
+ print(Fore.GREEN + f" [+] {name} updated successfully.")
455
+ except Exception as e:
456
+ print(Fore.RED + f" [!] Error updating {name}: {e}")
457
+ return
458
+
459
+ print(Fore.LIGHTBLACK_EX + " Not a git repo. Attempting re-download from GitHub...")
460
+ try:
461
+ repos = {
462
+ "sherlock": "sherlock-project/sherlock",
463
+ "holehe": "megadose/holehe",
464
+ "spiderfoot": "smicallef/spiderfoot",
465
+ "toutatis": "leogout/toutatis"
466
+ }
467
+
468
+ repo = repos.get(key)
469
+ if not repo:
470
+ return
471
+
472
+ zip_url = f"https://github.com/{repo}/archive/refs/heads/master.zip"
473
+ try:
474
+ req = urllib.request.Request(zip_url, headers={'User-Agent': 'Mozilla/5.0'})
475
+ with urllib.request.urlopen(req) as response:
476
+ zip_data = response.read()
477
+ except:
478
+ zip_url = f"https://github.com/{repo}/archive/refs/heads/main.zip"
479
+ req = urllib.request.Request(zip_url, headers={'User-Agent': 'Mozilla/5.0'})
480
+ with urllib.request.urlopen(req) as response:
481
+ zip_data = response.read()
482
+
483
+ temp_dir = os.path.join(os.path.dirname(path), f"{key}_temp_update")
484
+ if os.path.exists(temp_dir):
485
+ shutil.rmtree(temp_dir)
486
+ os.makedirs(temp_dir, exist_ok=True)
487
+
488
+ with zipfile.ZipFile(io.BytesIO(zip_data)) as zip_ref:
489
+ zip_ref.extractall(temp_dir)
490
+
491
+ extracted_folder = None
492
+ for folder in os.listdir(temp_dir):
493
+ if folder.startswith(key) or folder.startswith(name.lower()):
494
+ extracted_folder = os.path.join(temp_dir, folder)
495
+ break
496
+
497
+ if extracted_folder:
498
+ for item in os.listdir(extracted_folder):
499
+ s = os.path.join(extracted_folder, item)
500
+ d = os.path.join(path, item)
501
+ if os.path.isdir(s):
502
+ if os.path.exists(d):
503
+ shutil.rmtree(d)
504
+ shutil.copytree(s, d)
505
+ else:
506
+ shutil.copy2(s, d)
507
+
508
+ req_file = os.path.join(path, "requirements.txt")
509
+ if os.path.exists(req_file):
510
+ if key == "spiderfoot":
511
+ try:
512
+ with open(req_file, "r", encoding="utf-8") as f:
513
+ content = f.read()
514
+ if "lxml>=4.9.2,<5" in content:
515
+ content = content.replace("lxml>=4.9.2,<5", "lxml>=4.9.2")
516
+ with open(req_file, "w", encoding="utf-8") as f:
517
+ f.write(content)
518
+ except Exception as e:
519
+ print(Fore.RED + f" [!] Warning: Failed to patch SpiderFoot requirements: {e}")
520
+ subprocess.run([sys.executable, "-m", "pip", "install", "-r", req_file], check=True)
521
+
522
+ print(Fore.GREEN + f" [+] {name} re-downloaded and updated successfully.")
523
+ else:
524
+ print(Fore.RED + f" [!] Could not locate extracted files in zip.")
525
+
526
+ if os.path.exists(temp_dir):
527
+ shutil.rmtree(temp_dir)
528
+ except Exception as e:
529
+ print(Fore.RED + f" [!] Error downloading update: {e}")
530
+
531
+ def run_tools_update():
532
+ clear_screen()
533
+ draw_header("Updating OSINT Tools from GitHub")
534
+
535
+ print(Fore.GREEN + Style.BRIGHT + " === Update OSINT Tools ===")
536
+ print()
537
+
538
+ config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config.json")
539
+ if not os.path.exists(config_path):
540
+ print(Fore.RED + " [!] Configuration file (config.json) not found.")
541
+ print(Fore.YELLOW + " [+] Please run setup.py/setup.bat first to configure and install the tools.")
542
+ print()
543
+ input(" Press Enter to return to menu...")
544
+ return
545
+
546
+ try:
547
+ with open(config_path, "r", encoding="utf-8") as f:
548
+ config = json.load(f)
549
+ except Exception as e:
550
+ print(Fore.RED + f" [!] Error reading config.json: {e}")
551
+ print()
552
+ input(" Press Enter to return to menu...")
553
+ return
554
+
555
+ tools = {
556
+ "sherlock": ("Sherlock", config.get("sherlock_path")),
557
+ "holehe": ("Holehe", config.get("holehe_path")),
558
+ "spiderfoot": ("SpiderFoot", config.get("spiderfoot_path")),
559
+ "toutatis": ("Toutatis", config.get("toutatis_path"))
560
+ }
561
+
562
+ print(Fore.YELLOW + " [+] Checking for updates from official GitHub repositories...\n")
563
+
564
+ for key, (name, path) in tools.items():
565
+ if not path or not os.path.exists(path):
566
+ print(Fore.RED + f" [!] {name} path not configured or directory does not exist.")
567
+ continue
568
+
569
+ print(Fore.WHITE + f" ❯ Updating {name} at {path}...")
570
+ update_single_tool(key, name, path)
571
+ print()
572
+
573
+ print(Fore.GREEN + Style.BRIGHT + " [+] Update process finished.")
574
+ print()
575
+ input(" Press Enter to return to menu...")
576
+
577
+ def main():
578
+ if len(sys.argv) > 1:
579
+ if sys.argv[1] == "--social":
580
+ run_social_tool_tui()
581
+ sys.exit(0)
582
+ elif sys.argv[1] == "--update":
583
+ run_tools_update()
584
+ sys.exit(0)
585
+
586
+ selected_index = 0
587
+
588
+ while True:
589
+ draw_menu(selected_index)
590
+ key = get_key()
591
+
592
+ if key == 'up':
593
+ selected_index = (selected_index - 1) % len(OPTIONS)
594
+ elif key == 'down':
595
+ selected_index = (selected_index + 1) % len(OPTIONS)
596
+ elif key == 'esc':
597
+ break
598
+ elif key in ['1', '2', '3', '4', '5', '6', '7']:
599
+ idx = int(key) - 1
600
+ selected_index = idx
601
+ key = 'enter'
602
+
603
+ if key == 'enter':
604
+ clear_screen()
605
+
606
+ if selected_index == 0: # Sherlock
607
+ draw_header("Running: Sherlock (Username Scanner)")
608
+ print(Fore.GREEN + Style.BRIGHT + " === Sherlock (Username Scanner) ===")
609
+ print()
610
+ username = prompt_input("Enter target username")
611
+ if not username:
612
+ continue
613
+ if username.lower() == "/update":
614
+ run_tools_update()
615
+ continue
616
+
617
+ print(Fore.YELLOW + f"\n [+] Querying 300+ platforms for '{username}'...\n")
618
+ run_command(f"sherlock {username}")
619
+ print()
620
+ input(" Press Enter to return to menu...")
621
+
622
+ elif selected_index == 1: # Holehe
623
+ draw_header("Running: Holehe (Email Checker)")
624
+ print(Fore.GREEN + Style.BRIGHT + " === Holehe (Email Checker) ===")
625
+ print()
626
+ email = prompt_input("Enter target email address")
627
+ if not email:
628
+ continue
629
+ if email.lower() == "/update":
630
+ run_tools_update()
631
+ continue
632
+
633
+ print(Fore.YELLOW + f"\n [+] Querying registration endpoints for '{email}'...\n")
634
+ run_command(f"holehe {email}")
635
+ print()
636
+ input(" Press Enter to return to menu...")
637
+
638
+ elif selected_index == 2: # SpiderFoot
639
+ draw_header("Running: SpiderFoot (OSINT Web Server)")
640
+ print(Fore.GREEN + Style.BRIGHT + " === SpiderFoot (OSINT Web Server) ===")
641
+ print()
642
+ print(Fore.GREEN + " [+] Starting SpiderFoot local web server...")
643
+ print(Fore.YELLOW + " [+] Dashboard URL: http://127.0.0.1:5001")
644
+ print(Fore.RED + " [+] Press Ctrl+C inside this window to stop the server.")
645
+ print()
646
+ run_command("spiderfoot")
647
+ print()
648
+ input(" Press Enter to return to menu...")
649
+
650
+ elif selected_index == 3: # Toutatis
651
+ draw_header("Running: Toutatis (Instagram Extractor)")
652
+ print(Fore.GREEN + Style.BRIGHT + " === Toutatis (Instagram Extractor) ===")
653
+ print()
654
+ username = prompt_input("Enter target Instagram username")
655
+ if not username:
656
+ continue
657
+ if username.lower() == "/update":
658
+ run_tools_update()
659
+ continue
660
+
661
+ sessionid = prompt_input("Enter Instagram Session ID (optional - press Enter to skip)")
662
+ if sessionid:
663
+ cmd = f"toutatis -u {username} -s {sessionid}"
664
+ else:
665
+ cmd = f"toutatis -u {username}"
666
+ print(Fore.YELLOW + f"\n [+] Querying Instagram API for '{username}'...\n")
667
+ run_command(cmd)
668
+ print()
669
+ input(" Press Enter to return to menu...")
670
+
671
+ elif selected_index == 4: # MINT Social Tool (Social Downloader)
672
+ run_social_tool_tui()
673
+
674
+ elif selected_index == 5: # Update Tools
675
+ run_tools_update()
676
+
677
+ elif selected_index == 6: # Exit
678
+ break
679
+
680
+ clear_screen()
681
+ print(Fore.GREEN + Style.BRIGHT + "========================================")
682
+ print(Fore.GREEN + Style.BRIGHT + " Thank you for using MINT. Goodbye! ")
683
+ print(Fore.GREEN + Style.BRIGHT + "========================================")
684
+ time.sleep(1)
685
+
686
+ if __name__ == "__main__":
687
+ try:
688
+ main()
689
+ except KeyboardInterrupt:
690
+ clear_screen()
691
+ print(Fore.GREEN + "\nGoodbye!")
692
+ sys.exit(0)
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: mint-osint
3
+ Version: 1.0.2
4
+ Summary: MINT — The Unified OSINT & Media Command Center
5
+ Author: sayfalse
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: colorama>=0.4.6
9
+
10
+ <p align="center">
11
+ <img src="logo.png" alt="MINT Logo" width="400">
12
+ </p>
13
+
14
+ <h1 align="center">MINT — The Unified OSINT & Media Command Center</h1>
15
+
16
+ **MINT** is an interactive, terminal-based command center that unifies industry-standard OSINT (Open Source Intelligence) tools and a robust media archiver into a single, cohesive interface. Built for researchers, security analysts, and developers, MINT simplifies target intelligence gathering, social media investigation, and media preservation under a clean, keyboard-driven environment.
17
+
18
+ ---
19
+
20
+ ## Key Features
21
+
22
+ 1. **Sherlock (Username Scanner)**
23
+ - Scans and locates target social media accounts by username across over 300 platforms simultaneously.
24
+ 2. **Holehe (Email Checker)**
25
+ - Analyzes email address registrations across more than 120 websites using password recovery endpoints, identifying registered accounts without alerting the target.
26
+ 3. **SpiderFoot (OSINT Web Server)**
27
+ - Launches a local web server interface to automate security audits, domain reconnaissance, and threat intelligence gathering.
28
+ 4. **Toutatis (Instagram Extractor)**
29
+ - Extracts associated emails, phone numbers, and detailed profile metadata from Instagram accounts.
30
+ 5. **MINT Social Tool (Social Downloader)**
31
+ - A native, interactive downloader to archive photos, videos, stories, and highlights from major platforms (Instagram, TikTok, Facebook, and X/Twitter). Powered by high-speed `gallery-dl` and `yt-dlp` engines.
32
+ 6. **One-Click Update Manager**
33
+ - Automatically pulls the latest updates directly from the official GitHub repositories for all 4 external OSINT tools and installs any updated dependencies.
34
+
35
+ ---
36
+
37
+ ## Smart Path-Resolution Installer
38
+
39
+ The MINT installer (`setup.bat` / `setup.sh`) is designed to protect your file system from clutter. It prompts you once for a parent directory and automatically structures the installation cleanly:
40
+ * **Tools Directory:** Recreated as `<parent_folder>\MINT_Tools\` to hold all cloned OSINT scanners.
41
+ * **Media Directory:** Recreated as `<parent_folder>\mint-social\` to store downloaded media, profile logs, and cookies.
42
+ * **Global Wrappers:** Automatically registers a global `mint` command wrapper in your system path, allowing you to launch the Command Center from any terminal window.
43
+
44
+ ---
45
+
46
+ ## Installation & Setup
47
+
48
+ MINT automatically manages the environment checks, directory structures, tool cloning, and dependency installations.
49
+
50
+ ### Prerequisites
51
+ * **Python 3.10+** (Windows, macOS, or Linux)
52
+ * **Git** (recommended for cloning and updates; falls back to ZIP downloads if Git is missing)
53
+
54
+ ### Windows Installation (Recommended)
55
+ 1. Clone this repository to your system:
56
+ ```bash
57
+ git clone https://github.com/sayfalse/mint.git
58
+ cd mint
59
+ ```
60
+ 2. Run the interactive installer by double-clicking `setup.bat` or executing:
61
+ ```cmd
62
+ setup.bat
63
+ ```
64
+ 3. Enter your preferred parent directory (e.g., `E:\mint` or `G:\`). The installer will automatically configure and build the directory tree.
65
+
66
+ ### macOS / Linux Installation
67
+ 1. Clone the repository and navigate into it:
68
+ ```bash
69
+ git clone https://github.com/sayfalse/mint.git
70
+ cd mint
71
+ ```
72
+ 2. Run the setup script:
73
+ ```bash
74
+ chmod +x setup.sh
75
+ ./setup.sh
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Package Managers
81
+
82
+ ```bash
83
+ # YOLO
84
+ curl -fsSL https://raw.githubusercontent.com/sayfalse/mint/main/setup.sh | bash
85
+
86
+ # Package managers
87
+ pip install mint-osint # or pip install . (local install)
88
+ scoop install mint-osint # Windows
89
+ choco install mint-osint # Windows
90
+ brew install sayfalse/tap/mint # macOS and Linux (recommended, always up to date)
91
+ brew install mint-osint # macOS and Linux (official brew formula, updated less)
92
+ sudo pacman -S mint-osint # Arch Linux (Stable)
93
+ paru -S mint-osint-bin # Arch Linux (Latest from AUR)
94
+ nix run nixpkgs#mint-osint # or github:sayfalse/mint for latest dev branch
95
+ ```
96
+
97
+ ---
98
+
99
+ ## How to Run
100
+
101
+ Once setup is complete, you can launch the Command Center globally:
102
+
103
+ 1. Open a new terminal window.
104
+ 2. Type **`mint`** and press **Enter**.
105
+ 3. Use the **Up/Down arrow keys** to navigate the menu, and **Enter** to launch your selected tool.
106
+ 4. Alternatively, use the quick keyboard hotkeys (**1 to 7**) to jump directly to options.
107
+
108
+ ---
109
+
110
+ ## Cookie Configuration for Media Downloader
111
+
112
+ To download content from private profiles or bypass rate limits on social networks, the MINT Social Tool utilizes session cookies. The installer automatically generates 4 empty template cookie files in the correct path:
113
+ * `<parent_folder>\mint-social\cookies\facebook.com_cookies.txt`
114
+ * `<parent_folder>\mint-social\cookies\instagram.com_cookies.txt`
115
+ * `<parent_folder>\mint-social\cookies\tiktok.com_cookies.txt`
116
+ * `<parent_folder>\mint-social\cookies\x.com_cookies.txt`
117
+
118
+ ### How to export and use cookies:
119
+ 1. Install a browser extension like **Get cookies.txt LOCALLY** or **EditThisCookie** (available for Chrome/Firefox).
120
+ 2. Log into your account on the target social network (e.g., Instagram or X).
121
+ 3. Open the extension and export the cookies in **Netscape format**.
122
+ 4. Open the corresponding cookie file in a text editor (e.g., `instagram.com_cookies.txt`) and paste the exported content.
123
+ 5. Save the file. The MINT Social Tool will automatically load these cookies on subsequent runs.
124
+
125
+ ---
126
+
127
+ ## Configuration File (`config.json`)
128
+
129
+ The installer generates a `config.json` file in the MINT root directory to map all system paths dynamically. You can edit this file manually to update paths if you move directories:
130
+ ```json
131
+ {
132
+ "tools_dir": "E:\\mint\\MINT_Tools",
133
+ "social_dir": "E:\\mint\\mint-social",
134
+ "mint_dir": "E:\\mint",
135
+ "mint_py_path": "E:\\mint\\mint.py",
136
+ "sherlock_path": "E:\\mint\\MINT_Tools\\sherlock",
137
+ "holehe_path": "E:\\mint\\MINT_Tools\\holehe",
138
+ "spiderfoot_path": "E:\\mint\\MINT_Tools\\spiderfoot",
139
+ "toutatis_path": "E:\\mint\\MINT_Tools\\toutatis"
140
+ }
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Troubleshooting & Console Setup
146
+
147
+ * **Unicode Display Issues:** If block characters or box-drawing lines appear distorted in your Windows console, MINT automatically attempts to force UTF-8 encoding on startup. If issues persist, run the following command in your terminal before launching MINT:
148
+ ```cmd
149
+ chcp 65001
150
+ ```
151
+ * **Git Credential Conflicts:** If the update manager fails to pull tools due to account conflicts, MINT operates a fallback mechanism that automatically downloads the latest zip archives from official repositories and extracts them cleanly, preserving your configuration.
152
+ * **Dependencies Failed to Install:** Ensure your terminal is running with sufficient write permissions for the target installation folders, and that Python is added to your system's PATH variable.
@@ -0,0 +1,9 @@
1
+ README.md
2
+ mint.py
3
+ pyproject.toml
4
+ mint_osint.egg-info/PKG-INFO
5
+ mint_osint.egg-info/SOURCES.txt
6
+ mint_osint.egg-info/dependency_links.txt
7
+ mint_osint.egg-info/entry_points.txt
8
+ mint_osint.egg-info/requires.txt
9
+ mint_osint.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mint = mint:main
@@ -0,0 +1 @@
1
+ colorama>=0.4.6
@@ -0,0 +1,20 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "mint-osint"
7
+ version = "1.0.2"
8
+ description = "MINT — The Unified OSINT & Media Command Center"
9
+ readme = "README.md"
10
+ authors = [{ name = "sayfalse" }]
11
+ requires-python = ">=3.10"
12
+ dependencies = [
13
+ "colorama>=0.4.6"
14
+ ]
15
+
16
+ [project.scripts]
17
+ mint = "mint:main"
18
+
19
+ [tool.setuptools]
20
+ py-modules = ["mint"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+