Skip to content

Commit 41294a8

Browse files
authored
refactor(ui_utils.py): Simplify and consolidate message formatting fu… (#107)
* refactor(ui_utils.py): Simplify and consolidate message formatting functions * fix(constants.py): Update API and dashboard URLs for production environment
1 parent 0dd238d commit 41294a8

7 files changed

Lines changed: 45 additions & 98 deletions

File tree

penify_hook/api_client.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,18 @@ def generate_commit_summary(self, git_diff, instruction: str = "", repo_details
7575
return None
7676

7777
def get_supported_file_types(self) -> list[str]:
78+
"""Retrieve the supported file types from the API.
7879
79-
"""Retrieve supported file types from the API or return a default list."""
80-
url = self.api_url+"/v1/cli/supported_languages"
81-
response = requests.get(url)
82-
if response.status_code == 200:
83-
response = response.json()
84-
return response
85-
else:
86-
return ["py", "js", "ts", "java", "kt", "cs", "c"]
80+
This function sends a request to the API endpoint
81+
`/v1/file/supported_languages` to obtain a list of supported file types.
82+
If the API call is successful (status code 200), it parses the JSON
83+
response and returns the list of supported file types. If the API call
84+
fails, it returns a default list of common file types.
85+
86+
Returns:
87+
list[str]: A list of supported file types, either from the API or a default set.
88+
"""
89+
return ["py", "js", "ts", "java", "kt", "cs", "c", 'cpp', 'go', 'php', 'tsx','jsx']
8790

8891
def generate_commit_summary_with_llm(self, diff, message, generate_description: bool, repo_details, llm_client : LLMClient, jira_context=None):
8992
"""Generates a commit summary using a local LLM client; falls back to API on

penify_hook/commands/auth_commands.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def save_credentials(api_key):
5757
f.write(f"{key}={value}\n")
5858

5959
print(f"API token saved to {env_file}")
60-
return True
60+
# return True
6161
except Exception as e:
6262
print(f"Error saving to .env file: {str(e)}")
6363
# Fall back to saving in .penify global config
@@ -92,10 +92,13 @@ def login(api_url, dashboard_url):
9292
redirect_port = random.randint(30000, 50000)
9393
redirect_url = f"http://localhost:{redirect_port}/callback"
9494

95-
full_login_url = f"{dashboard_url}?redirectUri={urllib.parse.quote(redirect_url)}"
95+
full_login_url = f"{dashboard_url}?redirectUri={urllib.parse.quote(redirect_url)}&autoClose=true"
9696

9797
print(f"Opening login page in your default web browser: {full_login_url}")
98-
webbrowser.open(full_login_url)
98+
# Open browser with autoraise=True to ensure window is brought to front
99+
# Note: window.close() in JavaScript can only close windows that were opened by JavaScript
100+
# We'll pass an autoClose parameter to the dashboard URL so the server can handle closing
101+
webbrowser.open(full_login_url, autoraise=True)
99102

100103
class TokenHandler(http.server.SimpleHTTPRequestHandler):
101104
def do_GET(self):
@@ -113,15 +116,17 @@ def do_GET(self):
113116
response = """
114117
<html>
115118
<head>
116-
<script>
117-
setTimeout(function() {
118-
window.location.href = 'https://dashboard.penify.dev';
119-
}, 5000);
120-
</script>
119+
<style>
120+
body { font-family: Arial, sans-serif; text-align: center; padding-top: 50px; }
121+
.message { margin: 20px 0; }
122+
.note { font-size: 0.9em; color: #666; margin-top: 30px; }
123+
</style>
121124
</head>
122125
<body>
123126
<h1>Login Successful!</h1>
124-
<p>You will be redirected to the Penify dashboard in 5 seconds. You can also close this window and return to the CLI.</p>
127+
<p class="message">API keys have been fetched and saved.</p>
128+
<p class="message">You can close this window and return to the CLI.</p>
129+
<p class="note">(The browser window cannot be closed automatically for security reasons)</p>
125130
</body>
126131
</html>
127132
"""
@@ -133,7 +138,7 @@ def do_GET(self):
133138
if api_key:
134139
save_credentials(api_key)
135140
print("API keys fetched and saved successfully.")
136-
print("You'll be redirected to the Penify dashboard. You can continue using the CLI.")
141+
print("Please close the browser window and continue using the CLI.")
137142
else:
138143
print("Failed to fetch API keys.")
139144
else:
@@ -142,9 +147,17 @@ def do_GET(self):
142147
self.end_headers()
143148
response = """
144149
<html>
150+
<head>
151+
<style>
152+
body { font-family: Arial, sans-serif; text-align: center; padding-top: 50px; }
153+
.error { color: #d9534f; }
154+
.message { margin: 20px 0; }
155+
</style>
156+
</head>
145157
<body>
146-
<h1>Login Failed</h1>
147-
<p>Please try again.</p>
158+
<h1 class="error">Login Failed</h1>
159+
<p class="message">Please try again.</p>
160+
<p class="message">You can close this window and return to the CLI.</p>
148161
</body>
149162
</html>
150163
"""
@@ -155,7 +168,6 @@ def do_GET(self):
155168
thread = Thread(target=self.server.shutdown)
156169
thread.daemon = True
157170
thread.start()
158-
159171
def log_message(self, format, *args):
160172
# Suppress log messages
161173
"""Suppress log messages."""

penify_hook/commands/doc_commands.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,6 @@ def generate_doc(api_url, token, location=None):
2222
"""
2323
t1 = time.time()
2424
from ..api_client import APIClient
25-
print(f"Time taken to laod APIClinet: {time.time() - t1:.2f} seconds")
26-
"""Generates documentation based on the given parameters.
27-
28-
This function initializes an API client using the provided API URL and
29-
token. It then generates documentation by analyzing the specified
30-
location, which can be a folder, a file, or the current working
31-
directory if no location is provided. The function handles different
32-
types of analysis based on the input location and reports any errors
33-
encountered during the process.
34-
35-
Args:
36-
api_url (str): The URL of the API to connect to for documentation generation.
37-
token (str): The authentication token for accessing the API.
38-
location (str?): The path to a specific file or folder to analyze.
39-
If not provided, the current working directory is used.
40-
"""
4125
api_client = APIClient(api_url, token)
4226
if location is None:
4327
current_folder_path = os.getcwd()

penify_hook/commit_analyzer.py

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,7 @@ def __init__(self, repo_path: str, api_client: APIClient, llm_client=None, jira_
1919
self.jira_client: JiraClient = jira_client # Add JIRA client as an optional parameter
2020

2121
def get_summary(self, instruction: str, generate_description: bool) -> dict:
22-
"""Generate a summary for the commit based on the staged changes.
23-
24-
This function retrieves the differences of the staged changes in the repository
25-
and generates a commit summary using the provided instruction. If there are no
26-
changes staged for commit, an exception is raised. If a JIRA client is
27-
connected, it will attempt to extract issue keys from the current branch and
28-
use them to fetch context. The summary can be generated either with a Language
29-
Model (LLM) client or through the API client.
30-
31-
Args:
32-
instruction (str): A string containing instructions for generating the commit summary.
33-
generate_description (bool): Whether to include detailed descriptions in the summary.
34-
35-
Raises:
36-
ValueError: If there are no changes staged for commit.
37-
"""
22+
"""Generate a summary for the commit based on the staged changes."""
3823
diff = self.repo.git.diff('--cached')
3924
if not diff:
4025
raise ValueError("No changes to commit")
@@ -64,20 +49,8 @@ def get_summary(self, instruction: str, generate_description: bool) -> dict:
6449

6550

6651
def run(self, msg: Optional[str], edit_commit_message: bool, generate_description: bool):
67-
"""Run the post-commit hook.
68-
69-
This method processes the modified files from the last commit, stages them, and
70-
creates an auto-commit with an optional message. It also handles JIRA
71-
integration if available. If there is an error generating the commit summary,
72-
an exception is raised.
73-
74-
Args:
75-
msg (Optional[str]): An optional message to include in the commit.
76-
edit_commit_message (bool): A flag indicating whether to open the git commit
77-
edit terminal after committing.
78-
generate_description (bool): A flag indicating whether to include a description
79-
in the commit message.
80-
"""
52+
"""Run the post-commit hook and create an auto-commit with optional JIRA
53+
integration."""
8154
summary: dict = self.get_summary(msg, True)
8255
if not summary:
8356
raise Exception("Error generating commit summary")
@@ -102,23 +75,7 @@ def run(self, msg: Optional[str], edit_commit_message: bool, generate_descriptio
10275

10376
def process_jira_integration(self, title: str, description: str, msg: str) -> tuple:
10477
# Look for JIRA issue keys in commit message, title, description and user message
105-
"""Process JIRA integration by extracting issue keys from commit message
106-
components and branch name.
107-
108-
This function looks for JIRA issue keys in the provided commit title,
109-
description, original user message, and the active branch name. It uses these
110-
keys to update the commit message with JIRA information and adds comments to
111-
the corresponding JIRA issues. If no keys are found, it logs a warning.
112-
113-
Args:
114-
title (str): The generated commit title.
115-
description (str): The generated commit description.
116-
msg (str): The original user message that might contain JIRA references.
117-
118-
Returns:
119-
tuple: A tuple containing the updated commit title and description with included JIRA
120-
information.
121-
"""
78+
"""Process JIRA integration to update commit message with issue keys."""
12279
issue_keys = []
12380
if self.jira_client:
12481
# Extract from message content
@@ -156,7 +113,7 @@ def process_jira_integration(self, title: str, description: str, msg: str) -> tu
156113
return title, description
157114

158115
def _amend_commit(self):
159-
"""Amends the last commit message in the repository."""
116+
"""Open the default git editor to amend the last commit message."""
160117
try:
161118
# Change to the repository directory
162119
os.chdir(self.repo_path)

penify_hook/config_command.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
def setup_config_parser(parent_parser):
55

66
# Config subcommand: Create subparsers for config types
7-
"""Set up configuration parsers with subcommands for LLM and JIRA settings."""
7+
"""Set up configuration parsers for different types of configurations."""
88
parser = parent_parser.add_subparsers(title="config_type", dest="config_type")
99

1010
# Config subcommand: llm
@@ -34,17 +34,7 @@ def handle_config(args):
3434

3535

3636

37-
"""Handle configuration settings based on the specified config type.
38-
39-
This function processes different types of configurations such as LLM (Language
40-
Model) and JIRA. It saves configurations, sets up web-based configurations, and
41-
verifies JIRA connections. Depending on the `args.config_type`, it imports
42-
necessary modules, handles configuration saving or setup, and optionally
43-
verifies JIRA connectivity.
44-
45-
Args:
46-
args (argparse.Namespace): Command-line arguments containing the type of configuration to handle.
47-
"""
37+
"""Handle configuration settings based on the specified config type."""
4838
if args.config_type == "llm-cmd":
4939
from penify_hook.commands.config_commands import save_llm_config
5040
save_llm_config(args.model, args.api_base, args.api_key)

penify_hook/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
API_URL = 'http://localhost:8000/api'
1+
API_URL = 'https://production.gateway.snorkell.ai/api'
22
DASHBOARD_URL = "https://dashboard.penify.dev/auth/localhost/login"

penify_hook/file_analyzer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ def run(self):
115115
"""
116116
stages = ["Validating", "Reading content", "Documenting", "Writing changes", "Completed"]
117117
pbar, _ = create_stage_progress_bar(stages, f"Starting documenting")
118+
logger.debug(f"Processing file: {self.file_path}")
118119

119120
try:
120121
# Print a clear indication of which file is being processed

0 commit comments

Comments
 (0)