Skip to content

Commit 01ce3ff

Browse files
committed
fix and improve GitHub code search
1 parent a993595 commit 01ce3ff

File tree

3 files changed

+211
-169
lines changed

3 files changed

+211
-169
lines changed

dumpdork.py

Lines changed: 105 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
init(autoreset=True)
1313

14+
# Configuration Directory and File
1415
CONFIG_DIR = os.path.expanduser("~/.config/dumpdork")
1516
CONFIG_FILE = os.path.join(CONFIG_DIR, "config.yaml")
1617

18+
# Providers Configuration
1719
PROVIDERS = {
1820
"google": {
1921
"host": "google-search74.p.rapidapi.com",
@@ -25,7 +27,8 @@
2527
},
2628
"github": {
2729
"is_official": True,
28-
"url_pattern": "https://api.github.com/search/repositories"
30+
"repo_search": "https://api.github.com/search/repositories",
31+
"code_search": "https://api.github.com/search/code"
2932
}
3033
}
3134

@@ -37,7 +40,7 @@ def print_banner():
3740
{Fore.CYAN} | |_| | |_| | | | | | | |_) | |_| | (_) | | | <
3841
{Fore.CYAN} |____/ \__,_|_| |_| |_| .__/|____/ \___/|_| |_|\_\
3942
{Fore.CYAN} |_|
40-
{Fore.YELLOW} Advanced Dorking Tool v1.0
43+
{Fore.YELLOW} Advanced Dorking Tool v1.2
4144
{Fore.WHITE} Created by: Mateo Fumis (hackermater)
4245
"""
4346
print(banner)
@@ -67,6 +70,7 @@ def save_config(config_file, keys_dict):
6770
print(f"{Fore.GREEN}Configuration saved to '{config_file}'")
6871

6972
def get_github_commits(repo_full_name, key, limit=3):
73+
"""Fetch recent commits for a specific GitHub repository."""
7074
url = f"https://api.github.com/repos/{repo_full_name}/commits"
7175
headers = {
7276
'Accept': "application/vnd.github.v3+json",
@@ -92,7 +96,9 @@ def perform_search(source, query, limit, key):
9296
params = {}
9397

9498
if source == "github":
95-
url = provider["url_pattern"]
99+
is_code_search = any(x in query for x in ["filename:", "extension:", "path:", "content:"])
100+
url = provider["code_search"] if is_code_search else provider["repo_search"]
101+
96102
params = {'q': query, 'per_page': limit}
97103
if key and key.strip() != "" and key != "Not configured":
98104
headers['Authorization'] = f"token {key}"
@@ -118,11 +124,16 @@ def perform_search(source, query, limit, key):
118124
try:
119125
response = requests.get(url, headers=headers, params=params)
120126
if response.status_code == 200:
121-
return response.json()
127+
data = response.json()
128+
if source == "github" and not data.get('items') and url == provider["code_search"]:
129+
response = requests.get(provider["repo_search"], headers=headers, params=params)
130+
if response.status_code == 200:
131+
return response.json()
132+
return data
122133
elif response.status_code == 401:
123134
print(f"{Fore.RED}Error 401: Unauthorized. Your {source} token/key is invalid.")
124135
elif response.status_code == 403:
125-
print(f"{Fore.RED}Error 403: Forbidden for {source}.")
136+
print(f"{Fore.RED}Error 403: Forbidden for {source}. Code search may require an API Token.")
126137
else:
127138
print(f"{Fore.RED}Error {response.status_code} from {source}")
128139
except Exception as e:
@@ -161,94 +172,104 @@ def wizard_setup():
161172
save_config(CONFIG_FILE, keys_dict)
162173

163174
def main():
164-
parser = argparse.ArgumentParser(description='Perform a search using Dorks across multiple platforms', prog='dumpdork.py')
165-
parser.add_argument('query', nargs='?', type=str, help='Search query or dork')
166-
parser.add_argument('-s', '--source', type=str, default='google', choices=['google', 'github', 'brave'], help='Search engine source')
167-
parser.add_argument('-l', '--limit', type=int, default=50, help='Maximum number of results')
168-
parser.add_argument('-o', '--output', type=str, help='Save results to a JSON file')
169-
parser.add_argument('-w', '--wizard', action='store_true', help='Run API configuration wizard')
170-
171-
print_banner()
172-
173-
if len(sys.argv) == 1:
174-
parser.print_usage()
175-
print(f"\nUse {Fore.YELLOW}-h{Fore.RESET} or {Fore.YELLOW}--help{Fore.RESET} for full details.\n")
176-
sys.exit(0)
175+
try:
176+
parser = argparse.ArgumentParser(description='Perform a search using Dorks across multiple platforms', prog='dumpdork.py')
177+
parser.add_argument('query', nargs='?', type=str, help='Search query or dork')
178+
parser.add_argument('-s', '--source', type=str, default='google', choices=['google', 'github', 'brave'], help='Search engine source')
179+
parser.add_argument('-l', '--limit', type=int, default=50, help='Maximum number of results')
180+
parser.add_argument('-o', '--output', type=str, help='Save results to a JSON file')
181+
parser.add_argument('-w', '--wizard', action='store_true', help='Run API configuration wizard')
177182

178-
args = parser.parse_args()
183+
print_banner()
179184

180-
if args.wizard:
181-
wizard_setup()
182-
sys.exit(0)
185+
if len(sys.argv) == 1:
186+
parser.print_usage()
187+
print(f"\nUse {Fore.YELLOW}-h{Fore.RESET} or {Fore.YELLOW}--help{Fore.RESET} for full details.\n")
188+
sys.exit(0)
183189

184-
if args.query is None:
185-
parser.print_usage()
186-
print(f"{Fore.RED}Error: A search query is required unless using -w.")
187-
sys.exit(1)
190+
args = parser.parse_args()
188191

189-
config = load_config(CONFIG_FILE)
190-
keys_dict = config.get('rapidapi', {}).get('keys', {})
191-
api_key = keys_dict.get(args.source)
192+
if args.wizard:
193+
wizard_setup()
194+
sys.exit(0)
192195

193-
if not api_key and args.source != "github":
194-
print(f"{Fore.RED}Error: No API key found for {args.source}. Run with -w to setup.")
195-
sys.exit(1)
196+
if args.query is None:
197+
parser.print_usage()
198+
print(f"{Fore.RED}Error: A search query is required unless using -w.")
199+
sys.exit(1)
200+
201+
config = load_config(CONFIG_FILE)
202+
keys_dict = config.get('rapidapi', {}).get('keys', {})
203+
api_key = keys_dict.get(args.source)
196204

197-
print(f"{Fore.YELLOW}Searching {args.source} for: {args.query}...\n")
198-
results = perform_search(args.source, args.query, args.limit, api_key)
205+
if not api_key and args.source != "github":
206+
print(f"{Fore.RED}Error: No API key found for {args.source}. Run with -w to setup.")
207+
sys.exit(1)
199208

200-
if results:
201-
items = []
202-
if args.source == "github":
203-
items = results.get('items', [])
204-
elif args.source == "brave":
205-
items = results.get('results', []) or results.get('web', {}).get('results', [])
206-
else: # Google
207-
items = results.get('results', [])
209+
print(f"{Fore.YELLOW}Searching {args.source} for: {args.query}...\n")
210+
results = perform_search(args.source, args.query, args.limit, api_key)
208211

209-
for item in items:
212+
if results:
213+
items = []
210214
if args.source == "github":
211-
full_name = item.get('full_name') or 'No Name'
212-
url = item.get('html_url') or 'No URL'
213-
desc = item.get('description') or 'No Description'
214-
owner = item.get('owner', {}).get('login', 'Unknown')
215-
216-
if desc and len(desc) > 150:
217-
desc = desc[:147] + "..."
218-
219-
print(f"{Fore.CYAN}Repo: {Style.BRIGHT}{full_name} ({Fore.WHITE}by @{owner}{Fore.CYAN})")
220-
print(f"{Fore.GREEN}URL: {Style.BRIGHT}{urllib.parse.unquote(url)}")
221-
print(f"{Fore.MAGENTA}Description: {Style.BRIGHT}{desc}")
222-
223-
commits = get_github_commits(full_name, api_key)
224-
if commits:
225-
print(f"{Fore.YELLOW}Recent Commits:")
226-
for c in commits:
227-
msg = c.get('commit', {}).get('message', '').split('\n')[0]
228-
date = c.get('commit', {}).get('author', {}).get('date', '')[:10]
229-
print(f" {Fore.WHITE}- [{date}] {msg[:80]}")
230-
print("")
231-
else:
232-
title = item.get('title') or 'No Title'
233-
url = item.get('url') or item.get('link') or 'No URL'
234-
desc = item.get('description') or item.get('snippet') or 'No Description'
235-
236-
if desc and len(desc) > 150:
237-
desc = desc[:147] + "..."
238-
239-
print(f"{Fore.CYAN}Title: {Style.BRIGHT}{title}")
240-
print(f"{Fore.GREEN}URL: {Style.BRIGHT}{urllib.parse.unquote(url)}")
241-
print(f"{Fore.MAGENTA}Description: {Style.BRIGHT}{desc}\n")
242-
243-
print(f"{Fore.YELLOW}{Style.BRIGHT}Execution finished. Total results found: {len(items)}")
244-
245-
if args.output:
246-
with open(args.output, 'w', encoding='utf-8') as json_file:
247-
json.dump(results, json_file, ensure_ascii=False, indent=4)
248-
print(f"{Fore.YELLOW}Results saved to '{args.output}'")
249-
else:
250-
print(f"{Fore.RED}No results found.")
251-
print(f"{Fore.YELLOW}{Style.BRIGHT}Execution finished. Total results found: 0")
215+
items = results.get('items', [])
216+
elif args.source == "brave":
217+
items = results.get('results', []) or results.get('web', {}).get('results', [])
218+
else: # Google
219+
items = results.get('results', [])
220+
221+
for item in items:
222+
if args.source == "github":
223+
repository = item.get('repository', {}) if 'repository' in item else item
224+
full_name = repository.get('full_name') or item.get('full_name') or 'No Name'
225+
url = item.get('html_url') or repository.get('html_url') or 'No URL'
226+
desc = item.get('description') or repository.get('description') or 'No Description'
227+
owner = repository.get('owner', {}).get('login') or item.get('owner', {}).get('login', 'Unknown')
228+
229+
if desc and len(desc) > 150:
230+
desc = desc[:147] + "..."
231+
232+
if 'path' in item:
233+
print(f"{Fore.CYAN}File: {Style.BRIGHT}{item.get('path')} {Fore.WHITE}in {full_name}")
234+
else:
235+
print(f"{Fore.CYAN}Repo: {Style.BRIGHT}{full_name} ({Fore.WHITE}by @{owner}{Fore.CYAN})")
236+
237+
print(f"{Fore.GREEN}URL: {Style.BRIGHT}{urllib.parse.unquote(url)}")
238+
print(f"{Fore.MAGENTA}Description: {Style.BRIGHT}{desc}")
239+
240+
commits = get_github_commits(full_name, api_key)
241+
if commits:
242+
print(f"{Fore.YELLOW}Recent Commits:")
243+
for c in commits:
244+
msg = c.get('commit', {}).get('message', '').split('\n')[0]
245+
date = c.get('commit', {}).get('author', {}).get('date', '')[:10]
246+
print(f" {Fore.WHITE}- [{date}] {msg[:80]}")
247+
print("")
248+
else:
249+
title = item.get('title') or 'No Title'
250+
url = item.get('url') or item.get('link') or 'No URL'
251+
desc = item.get('description') or item.get('snippet') or 'No Description'
252+
253+
if desc and len(desc) > 150:
254+
desc = desc[:147] + "..."
255+
256+
print(f"{Fore.CYAN}Title: {Style.BRIGHT}{title}")
257+
print(f"{Fore.GREEN}URL: {Style.BRIGHT}{urllib.parse.unquote(url)}")
258+
print(f"{Fore.MAGENTA}Description: {Style.BRIGHT}{desc}\n")
259+
260+
print(f"{Fore.YELLOW}{Style.BRIGHT}Execution finished. Total results found: {len(items)}")
261+
262+
if args.output:
263+
with open(args.output, 'w', encoding='utf-8') as json_file:
264+
json.dump(results, json_file, ensure_ascii=False, indent=4)
265+
print(f"{Fore.YELLOW}Results saved to '{args.output}'")
266+
else:
267+
print(f"{Fore.RED}No results found.")
268+
print(f"{Fore.YELLOW}{Style.BRIGHT}Execution finished. Total results found: 0")
269+
270+
except KeyboardInterrupt:
271+
print(f"\n{Fore.RED}[!] Process interrupted by user. Exiting...")
272+
sys.exit(0)
252273

253274
if __name__ == "__main__":
254275
main()

0 commit comments

Comments
 (0)