Skip to content

Commit 476fc98

Browse files
authored
Merge branch 'main' into add-rag-chatbot
2 parents 7ede539 + 38f59ba commit 476fc98

File tree

10 files changed

+98
-24
lines changed

10 files changed

+98
-24
lines changed

src/gitingest/clone.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77

88
async def check_repo_exists(url: str) -> bool:
99
proc = await asyncio.create_subprocess_exec(
10-
"git",
11-
"ls-remote",
10+
"curl",
11+
"-I",
1212
url,
1313
stdout=asyncio.subprocess.PIPE,
1414
stderr=asyncio.subprocess.PIPE,
1515
)
16-
await proc.communicate()
17-
return proc.returncode == 0
16+
stdout, stderr = await proc.communicate()
17+
if proc.returncode != 0:
18+
return False
19+
# Check if stdout contains "404" status code
20+
stdout_str = stdout.decode()
21+
return "HTTP/1.1 404" not in stdout_str and "HTTP/2 404" not in stdout_str
1822

1923
@async_timeout(CLONE_TIMEOUT)
2024
async def clone_repo(query: dict) -> str:

src/gitingest/tests/test_clone.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,18 @@ async def test_check_repo_exists():
6060

6161
with patch('asyncio.create_subprocess_exec', new_callable=AsyncMock) as mock_exec:
6262
mock_process = AsyncMock()
63+
mock_process.communicate.return_value = (b'HTTP/1.1 200 OK\n', b'')
64+
mock_exec.return_value = mock_process
6365

6466
# Test existing repository
6567
mock_process.returncode = 0
66-
mock_exec.return_value = mock_process
6768
assert await check_repo_exists(url) is True
6869

69-
# Test non-existing repository
70+
# Test non-existing repository (404 response)
71+
mock_process.communicate.return_value = (b'HTTP/1.1 404 Not Found\n', b'')
72+
mock_process.returncode = 0
73+
assert await check_repo_exists(url) is False
74+
75+
# Test failed request
7076
mock_process.returncode = 1
71-
mock_exec.return_value = mock_process
7277
assert await check_repo_exists(url) is False

src/gitingest/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ async def wrapper(*args, **kwargs) -> T:
1717
try:
1818
return await asyncio.wait_for(func(*args, **kwargs), timeout=seconds)
1919
except asyncio.TimeoutError:
20-
raise AsyncTimeoutError(f"Operation timed out after {seconds} seconds")
20+
raise AsyncTimeoutError(f"Clone timed out after {seconds} seconds")
2121
return wrapper
2222
return decorator

src/main.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ async def api_docs(request: Request):
5757
"api.jinja", {"request": request}
5858
)
5959

60-
@app.get('/favicon.ico')
61-
async def favicon():
62-
return FileResponse('static/favicon.ico')
63-
6460
@app.get("/robots.txt")
6561
async def robots():
6662
return FileResponse('static/robots.txt')

src/process_query.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,33 @@
44

55
from config import MAX_DISPLAY_SIZE, EXAMPLE_REPOS
66
from gitingest import ingest_from_query, clone_repo, parse_query
7-
from server_utils import logSliderToSize
7+
from server_utils import logSliderToSize, Colors
88

99
templates = Jinja2Templates(directory="templates")
1010

11+
def print_query(query, request, max_file_size, pattern_type, pattern):
12+
print(f"{Colors.WHITE}{query['url']:<20}{Colors.END}", end="")
13+
if int(max_file_size/1024) != 50:
14+
print(f" | {Colors.YELLOW}Size: {int(max_file_size/1024)}kb{Colors.END}", end="")
15+
if pattern_type == "include" and pattern != "":
16+
print(f" | {Colors.YELLOW}Include {pattern}{Colors.END}", end="")
17+
elif pattern_type == "exclude" and pattern != "":
18+
print(f" | {Colors.YELLOW}Exclude {pattern}{Colors.END}", end="")
19+
20+
21+
def print_error(query, request, e, max_file_size, pattern_type, pattern):
22+
print(f"{Colors.BROWN}WARN{Colors.END}: {Colors.RED}<- {Colors.END}", end="")
23+
print_query(query, request, max_file_size, pattern_type, pattern)
24+
print(f" | {Colors.RED}{e}{Colors.END}")
25+
26+
def print_success(query, request, max_file_size, pattern_type, pattern, summary):
27+
estimated_tokens = summary[summary.index("Estimated tokens:") + len("Estimated ") :]
28+
print(f"{Colors.GREEN}INFO{Colors.END}: {Colors.GREEN}<- {Colors.END}", end="")
29+
print_query(query, request, max_file_size, pattern_type, pattern)
30+
print(f" | {Colors.PURPLE}{estimated_tokens}{Colors.END}")
31+
32+
33+
1134
async def process_query(request: Request, input_text: str, slider_position: int, pattern_type: str = "exclude", pattern: str = "", is_index: bool = False) -> str:
1235
template = "index.jinja" if is_index else "github.jinja"
1336
max_file_size = logSliderToSize(slider_position)
@@ -23,11 +46,16 @@ async def process_query(request: Request, input_text: str, slider_position: int,
2346
summary, tree, content = ingest_from_query(query)
2447
with open(f"{query['local_path']}.txt", "w") as f:
2548
f.write(tree + "\n" + content)
26-
print(f"{query['slug']:<20}", end="")
27-
if pattern and pattern != "":
28-
print(f"{pattern_type}[{pattern}]", end="")
29-
print(f"\n{query['url']}")
49+
50+
51+
3052
except Exception as e:
53+
#hack to print error message when query is not defined
54+
if 'query' in locals() and query is not None and isinstance(query, dict):
55+
print_error(query, request, e, max_file_size, pattern_type, pattern)
56+
else:
57+
print(f"{Colors.BROWN}WARN{Colors.END}: {Colors.RED}<- {Colors.END}", end="")
58+
print(f"{Colors.RED}{e}{Colors.END}")
3159
return templates.TemplateResponse(
3260
template,
3361
{
@@ -43,7 +71,7 @@ async def process_query(request: Request, input_text: str, slider_position: int,
4371

4472
if len(content) > MAX_DISPLAY_SIZE:
4573
content = f"(Files content cropped to {int(MAX_DISPLAY_SIZE/1000)}k characters, download full ingest to see more)\n" + content[:MAX_DISPLAY_SIZE]
46-
74+
print_success(query, request, max_file_size, pattern_type, pattern, summary)
4775
return templates.TemplateResponse(
4876
template,
4977
{

src/server_utils.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
## Rate Limiter
32
from slowapi import Limiter
43
from slowapi.util import get_remote_address
@@ -12,4 +11,32 @@ def logSliderToSize(position):
1211
minv = math.log(1)
1312
maxv = math.log(102400)
1413

15-
return round(math.exp(minv + (maxv - minv) * pow(position / maxp, 1.5))) * 1024
14+
return round(math.exp(minv + (maxv - minv) * pow(position / maxp, 1.5))) * 1024
15+
16+
## Color printing utility
17+
class Colors:
18+
"""ANSI color codes"""
19+
BLACK = "\033[0;30m"
20+
RED = "\033[0;31m"
21+
GREEN = "\033[0;32m"
22+
BROWN = "\033[0;33m"
23+
BLUE = "\033[0;34m"
24+
PURPLE = "\033[0;35m"
25+
CYAN = "\033[0;36m"
26+
LIGHT_GRAY = "\033[0;37m"
27+
DARK_GRAY = "\033[1;30m"
28+
LIGHT_RED = "\033[1;31m"
29+
LIGHT_GREEN = "\033[1;32m"
30+
YELLOW = "\033[1;33m"
31+
LIGHT_BLUE = "\033[1;34m"
32+
LIGHT_PURPLE = "\033[1;35m"
33+
LIGHT_CYAN = "\033[1;36m"
34+
WHITE = "\033[1;37m"
35+
BOLD = "\033[1m"
36+
FAINT = "\033[2m"
37+
ITALIC = "\033[3m"
38+
UNDERLINE = "\033[4m"
39+
BLINK = "\033[5m"
40+
NEGATIVE = "\033[7m"
41+
CROSSED = "\033[9m"
42+
END = "\033[0m"

src/static/apple-touch-icon.png

3.2 KB
Loading

src/static/favicon-64.png

1019 Bytes
Loading

src/static/favicon.svg

Lines changed: 1 addition & 0 deletions
Loading

src/templates/base.jinja

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,26 @@
99
<meta name="description" content="Replace 'hub' with 'ingest' in any Github Url for a prompt-friendly text">
1010
<meta name="keywords" content="GitIngest, AI tools, LLM integration, Ingest, Digest, Context, Prompt, Git workflow, codebase extraction, Git repository, Git automation, Summarize, prompt-friendly">
1111
<meta name="robots" content="index, follow">
12+
13+
<!-- Favicons -->
14+
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
15+
<link rel="icon" type="image/png" sizes="64x64" href="/static/favicon-64.png">
16+
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
17+
18+
<!-- Web App Meta -->
19+
<meta name="apple-mobile-web-app-title" content="GitIngest">
20+
<meta name="application-name" content="GitIngest">
21+
<meta name="theme-color" content="#FCA847">
22+
<meta name="apple-mobile-web-app-capable" content="yes">
23+
<meta name="apple-mobile-web-app-status-bar-style" content="default">
24+
1225

1326
<!-- OpenGraph Meta Tags -->
14-
<meta property="og:title" content="{% block og_title %}Git ingest{% endblock %}">
15-
<meta property="og:description" content="{% block og_description %}Replace 'hub' with 'ingest' in any Github Url for a prompt-friendly text{% endblock %}">
16-
<meta property="og:type" content="{% block og_type %}website{% endblock %}">
27+
<meta property="og:title" content="Git ingest">
28+
<meta property="og:description" content="Replace 'hub' with 'ingest' in any Github Url for a prompt-friendly text">
29+
<meta property="og:type" content="website">
1730
<meta property="og:url" content="{{ request.url }}">
18-
<meta property="og:image" content="{% block og_image %}/static/og-image.png{% endblock %}">
31+
<meta property="og:image" content="/static/og-image.png">
1932

2033
<title>{% block title %}Git ingest{% endblock %}</title>
2134

0 commit comments

Comments
 (0)