Replace magic numbers with named constants
This commit is contained in:
parent
ad80ea66f1
commit
c4795b4508
@ -17,6 +17,34 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
# UI Layout Constants
|
||||||
|
UI_PANE_REQUEST_RESPONSE_POSITION = 510 # Initial position for request/response split
|
||||||
|
UI_PANE_RESPONSE_DETAILS_POSITION = 400 # Initial position for response body/headers split
|
||||||
|
UI_PANE_RESULTS_PANEL_POSITION = 120 # Initial position for script results panel
|
||||||
|
UI_PANE_SCRIPTS_POSITION = 300 # Initial position for scripts tab panes
|
||||||
|
UI_SCRIPT_RESULTS_PANEL_HEIGHT = 150 # Height reserved for script results panel
|
||||||
|
UI_TOAST_TIMEOUT_SECONDS = 3 # Duration to show toast notifications
|
||||||
|
|
||||||
|
# Debounce/Delay Timeouts (milliseconds)
|
||||||
|
DEBOUNCE_VARIABLE_INDICATORS_MS = 500 # Delay before updating variable indicators
|
||||||
|
DELAY_TAB_CREATION_MS = 50 # Delay before creating new tab after last one closes
|
||||||
|
|
||||||
|
# Data Display Limits
|
||||||
|
DISPLAY_VARIABLE_MAX_LENGTH = 50 # Max characters to display for variable values
|
||||||
|
DISPLAY_VARIABLE_TRUNCATE_SUFFIX = "..." # Suffix for truncated variable values
|
||||||
|
DISPLAY_URL_NAME_MAX_LENGTH = 30 # Max characters for URL in generated tab names
|
||||||
|
|
||||||
|
# Data Storage Limits
|
||||||
|
HISTORY_MAX_ENTRIES = 100 # Maximum number of history entries to keep
|
||||||
|
PROJECT_NAME_MAX_LENGTH = 100 # Maximum length for project names
|
||||||
|
REQUEST_NAME_MAX_LENGTH = 200 # Maximum length for request names
|
||||||
|
|
||||||
|
# HTTP Client Settings
|
||||||
|
HTTP_DEFAULT_TIMEOUT_SECONDS = 30 # Default timeout for HTTP requests
|
||||||
|
|
||||||
|
# Script Execution Settings
|
||||||
|
SCRIPT_EXECUTION_TIMEOUT_SECONDS = 5 # Maximum execution time for scripts
|
||||||
|
|
||||||
# 36 symbolic icons for projects (6x6 grid)
|
# 36 symbolic icons for projects (6x6 grid)
|
||||||
PROJECT_ICONS = [
|
PROJECT_ICONS = [
|
||||||
# Row 1: Folders & Organization
|
# Row 1: Folders & Organization
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import gi
|
|||||||
gi.require_version('GLib', '2.0')
|
gi.require_version('GLib', '2.0')
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
from .models import HistoryEntry
|
from .models import HistoryEntry
|
||||||
|
from .constants import HISTORY_MAX_ENTRIES
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -77,8 +78,8 @@ class HistoryManager:
|
|||||||
entries = self.load_history()
|
entries = self.load_history()
|
||||||
entries.insert(0, entry) # Most recent first
|
entries.insert(0, entry) # Most recent first
|
||||||
|
|
||||||
# Limit history size to 100 entries
|
# Limit history size
|
||||||
entries = entries[:100]
|
entries = entries[:HISTORY_MAX_ENTRIES]
|
||||||
|
|
||||||
self.save_history(entries)
|
self.save_history(entries)
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,16 @@ from typing import Optional, Set, Dict, List
|
|||||||
import logging
|
import logging
|
||||||
from .models import HttpRequest, HttpResponse
|
from .models import HttpRequest, HttpResponse
|
||||||
from .widgets.header_row import HeaderRow
|
from .widgets.header_row import HeaderRow
|
||||||
|
from .constants import (
|
||||||
|
UI_PANE_REQUEST_RESPONSE_POSITION,
|
||||||
|
UI_PANE_RESPONSE_DETAILS_POSITION,
|
||||||
|
UI_PANE_RESULTS_PANEL_POSITION,
|
||||||
|
UI_PANE_SCRIPTS_POSITION,
|
||||||
|
UI_SCRIPT_RESULTS_PANEL_HEIGHT,
|
||||||
|
DEBOUNCE_VARIABLE_INDICATORS_MS,
|
||||||
|
DISPLAY_VARIABLE_MAX_LENGTH,
|
||||||
|
DISPLAY_VARIABLE_TRUNCATE_SUFFIX,
|
||||||
|
)
|
||||||
import json
|
import json
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|
||||||
@ -118,7 +128,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
# Horizontal Split: Request | Response
|
# Horizontal Split: Request | Response
|
||||||
split_pane = Gtk.Paned(orientation=Gtk.Orientation.HORIZONTAL)
|
split_pane = Gtk.Paned(orientation=Gtk.Orientation.HORIZONTAL)
|
||||||
split_pane.set_vexpand(True)
|
split_pane.set_vexpand(True)
|
||||||
split_pane.set_position(510)
|
split_pane.set_position(UI_PANE_REQUEST_RESPONSE_POSITION)
|
||||||
split_pane.set_shrink_start_child(False)
|
split_pane.set_shrink_start_child(False)
|
||||||
split_pane.set_shrink_end_child(False)
|
split_pane.set_shrink_end_child(False)
|
||||||
split_pane.set_resize_start_child(True)
|
split_pane.set_resize_start_child(True)
|
||||||
@ -164,7 +174,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
# Create a vertical paned for response stack and result panels
|
# Create a vertical paned for response stack and result panels
|
||||||
self.response_main_paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
self.response_main_paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
||||||
self.response_main_paned.set_vexpand(True)
|
self.response_main_paned.set_vexpand(True)
|
||||||
self.response_main_paned.set_position(400)
|
self.response_main_paned.set_position(UI_PANE_RESPONSE_DETAILS_POSITION)
|
||||||
self.response_main_paned.set_shrink_start_child(False)
|
self.response_main_paned.set_shrink_start_child(False)
|
||||||
# Don't allow results panels to shrink below their minimum size
|
# Don't allow results panels to shrink below their minimum size
|
||||||
self.response_main_paned.set_shrink_end_child(False)
|
self.response_main_paned.set_shrink_end_child(False)
|
||||||
@ -228,7 +238,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
# Create a second paned for preprocessing and script results
|
# Create a second paned for preprocessing and script results
|
||||||
self.results_paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
self.results_paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
||||||
self.results_paned.set_vexpand(True)
|
self.results_paned.set_vexpand(True)
|
||||||
self.results_paned.set_position(120)
|
self.results_paned.set_position(UI_PANE_RESULTS_PANEL_POSITION)
|
||||||
# Don't allow children to shrink below their minimum size
|
# Don't allow children to shrink below their minimum size
|
||||||
self.results_paned.set_shrink_start_child(False)
|
self.results_paned.set_shrink_start_child(False)
|
||||||
self.results_paned.set_shrink_end_child(False)
|
self.results_paned.set_shrink_end_child(False)
|
||||||
@ -474,7 +484,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
|
|
||||||
# Vertical paned to separate preprocessing and postprocessing
|
# Vertical paned to separate preprocessing and postprocessing
|
||||||
paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
||||||
paned.set_position(300)
|
paned.set_position(UI_PANE_SCRIPTS_POSITION)
|
||||||
paned.set_vexpand(True)
|
paned.set_vexpand(True)
|
||||||
|
|
||||||
# Preprocessing Section
|
# Preprocessing Section
|
||||||
@ -942,7 +952,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
output_text += "\n--- Variables Set ---"
|
output_text += "\n--- Variables Set ---"
|
||||||
for var_name, var_value in script_result.variable_updates.items():
|
for var_name, var_value in script_result.variable_updates.items():
|
||||||
# Truncate long values for display
|
# Truncate long values for display
|
||||||
display_value = var_value if len(var_value) <= 50 else var_value[:47] + "..."
|
display_value = var_value if len(var_value) <= DISPLAY_VARIABLE_MAX_LENGTH else var_value[:DISPLAY_VARIABLE_MAX_LENGTH - 3] + DISPLAY_VARIABLE_TRUNCATE_SUFFIX
|
||||||
output_text += f"\n>>> {var_name} = '{display_value}'"
|
output_text += f"\n>>> {var_name} = '{display_value}'"
|
||||||
|
|
||||||
# Append warnings to output
|
# Append warnings to output
|
||||||
@ -983,14 +993,14 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
main_height = self.response_main_paned.get_height()
|
main_height = self.response_main_paned.get_height()
|
||||||
if main_height > 200:
|
if main_height > 200:
|
||||||
# Set position to show ~150px of results at the bottom
|
# Set position to show ~150px of results at the bottom
|
||||||
self.response_main_paned.set_position(main_height - 150)
|
self.response_main_paned.set_position(main_height - UI_SCRIPT_RESULTS_PANEL_HEIGHT)
|
||||||
|
|
||||||
# Adjust results paned to show script output (bottom panel)
|
# Adjust results paned to show script output (bottom panel)
|
||||||
results_height = self.results_paned.get_height()
|
results_height = self.results_paned.get_height()
|
||||||
if results_height > 150:
|
if results_height > 150:
|
||||||
# If preprocessing is visible, share space
|
# If preprocessing is visible, share space
|
||||||
if self.preprocessing_results_container.get_visible():
|
if self.preprocessing_results_container.get_visible():
|
||||||
self.results_paned.set_position(120) # Give preprocessing minimal space
|
self.results_paned.set_position(UI_PANE_RESULTS_PANEL_POSITION) # Give preprocessing minimal space
|
||||||
# If only script results, the paned will show it automatically
|
# If only script results, the paned will show it automatically
|
||||||
|
|
||||||
return False # Don't repeat
|
return False # Don't repeat
|
||||||
@ -1023,7 +1033,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
output_text += "\n--- Variables Set ---"
|
output_text += "\n--- Variables Set ---"
|
||||||
for var_name, var_value in preprocessing_result.variable_updates.items():
|
for var_name, var_value in preprocessing_result.variable_updates.items():
|
||||||
# Truncate long values for display
|
# Truncate long values for display
|
||||||
display_value = var_value if len(var_value) <= 50 else var_value[:47] + "..."
|
display_value = var_value if len(var_value) <= DISPLAY_VARIABLE_MAX_LENGTH else var_value[:DISPLAY_VARIABLE_MAX_LENGTH - 3] + DISPLAY_VARIABLE_TRUNCATE_SUFFIX
|
||||||
output_text += f"\n>>> {var_name} = '{display_value}'"
|
output_text += f"\n>>> {var_name} = '{display_value}'"
|
||||||
|
|
||||||
# Append warnings to output
|
# Append warnings to output
|
||||||
@ -1071,7 +1081,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
main_height = self.response_main_paned.get_height()
|
main_height = self.response_main_paned.get_height()
|
||||||
if main_height > 200:
|
if main_height > 200:
|
||||||
# Set position to show ~150px of results at the bottom
|
# Set position to show ~150px of results at the bottom
|
||||||
self.response_main_paned.set_position(main_height - 150)
|
self.response_main_paned.set_position(main_height - UI_SCRIPT_RESULTS_PANEL_HEIGHT)
|
||||||
|
|
||||||
# Adjust results paned to show preprocessing output (top panel)
|
# Adjust results paned to show preprocessing output (top panel)
|
||||||
results_height = self.results_paned.get_height()
|
results_height = self.results_paned.get_height()
|
||||||
@ -1283,7 +1293,7 @@ class RequestTabWidget(Gtk.Box):
|
|||||||
GLib.source_remove(self._update_indicators_timeout_id)
|
GLib.source_remove(self._update_indicators_timeout_id)
|
||||||
|
|
||||||
# Schedule new update after 500ms
|
# Schedule new update after 500ms
|
||||||
self._update_indicators_timeout_id = GLib.timeout_add(500, self._update_variable_indicators_timeout)
|
self._update_indicators_timeout_id = GLib.timeout_add(DEBOUNCE_VARIABLE_INDICATORS_MS, self._update_variable_indicators_timeout)
|
||||||
|
|
||||||
def _update_variable_indicators_timeout(self):
|
def _update_variable_indicators_timeout(self):
|
||||||
"""Timeout callback for updating indicators."""
|
"""Timeout callback for updating indicators."""
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import re
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Tuple, Optional, Dict, List, TYPE_CHECKING
|
from typing import Tuple, Optional, Dict, List, TYPE_CHECKING
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
from .constants import SCRIPT_EXECUTION_TIMEOUT_SECONDS
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .project_manager import ProjectManager
|
from .project_manager import ProjectManager
|
||||||
@ -52,7 +53,7 @@ class ScriptContext:
|
|||||||
class ScriptExecutor:
|
class ScriptExecutor:
|
||||||
"""Executes JavaScript code using gjs (GNOME JavaScript)."""
|
"""Executes JavaScript code using gjs (GNOME JavaScript)."""
|
||||||
|
|
||||||
TIMEOUT_SECONDS = 5
|
TIMEOUT_SECONDS = SCRIPT_EXECUTION_TIMEOUT_SECONDS
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def execute_postprocessing_script(
|
def execute_postprocessing_script(
|
||||||
|
|||||||
@ -23,6 +23,13 @@ from gi.repository import Adw, Gtk, GLib, Gio, GtkSource
|
|||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
import logging
|
import logging
|
||||||
from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab
|
from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab
|
||||||
|
from .constants import (
|
||||||
|
UI_TOAST_TIMEOUT_SECONDS,
|
||||||
|
DELAY_TAB_CREATION_MS,
|
||||||
|
DISPLAY_URL_NAME_MAX_LENGTH,
|
||||||
|
PROJECT_NAME_MAX_LENGTH,
|
||||||
|
REQUEST_NAME_MAX_LENGTH,
|
||||||
|
)
|
||||||
from .http_client import HttpClient
|
from .http_client import HttpClient
|
||||||
from .history_manager import HistoryManager
|
from .history_manager import HistoryManager
|
||||||
from .project_manager import ProjectManager
|
from .project_manager import ProjectManager
|
||||||
@ -239,7 +246,7 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
remaining_tabs = len(self.page_to_tab)
|
remaining_tabs = len(self.page_to_tab)
|
||||||
if remaining_tabs == 0:
|
if remaining_tabs == 0:
|
||||||
# Schedule creating exactly one new tab
|
# Schedule creating exactly one new tab
|
||||||
GLib.timeout_add(50, self._create_new_tab_once)
|
GLib.timeout_add(DELAY_TAB_CREATION_MS, self._create_new_tab_once)
|
||||||
|
|
||||||
# Close the page
|
# Close the page
|
||||||
tab_view.close_page_finish(page, True)
|
tab_view.close_page_finish(page, True)
|
||||||
@ -601,7 +608,7 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
# Generate name from method and URL
|
# Generate name from method and URL
|
||||||
url_parts = request.url.split('/')
|
url_parts = request.url.split('/')
|
||||||
url_name = url_parts[-1] if url_parts else request.url
|
url_name = url_parts[-1] if url_parts else request.url
|
||||||
name = f"{request.method} {url_name[:30]}" if url_name else f"{request.method} Request"
|
name = f"{request.method} {url_name[:DISPLAY_URL_NAME_MAX_LENGTH]}" if url_name else f"{request.method} Request"
|
||||||
|
|
||||||
# Check if current tab is an empty "New Request"
|
# Check if current tab is an empty "New Request"
|
||||||
if self._is_empty_new_request_tab():
|
if self._is_empty_new_request_tab():
|
||||||
@ -756,7 +763,7 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
"""Show a toast notification."""
|
"""Show a toast notification."""
|
||||||
toast = Adw.Toast()
|
toast = Adw.Toast()
|
||||||
toast.set_title(message)
|
toast.set_title(message)
|
||||||
toast.set_timeout(3)
|
toast.set_timeout(UI_TOAST_TIMEOUT_SECONDS)
|
||||||
self.toast_overlay.add_toast(toast)
|
self.toast_overlay.add_toast(toast)
|
||||||
|
|
||||||
# Project Management Methods
|
# Project Management Methods
|
||||||
@ -775,9 +782,9 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
if not name or not name.strip():
|
if not name or not name.strip():
|
||||||
return False, "Project name cannot be empty"
|
return False, "Project name cannot be empty"
|
||||||
|
|
||||||
# Check length (max 100 characters)
|
# Check length
|
||||||
if len(name) > 100:
|
if len(name) > PROJECT_NAME_MAX_LENGTH:
|
||||||
return False, "Project name is too long (max 100 characters)"
|
return False, f"Project name is too long (max {PROJECT_NAME_MAX_LENGTH} characters)"
|
||||||
|
|
||||||
# Check for invalid characters (file system unsafe characters)
|
# Check for invalid characters (file system unsafe characters)
|
||||||
invalid_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|', '\0']
|
invalid_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|', '\0']
|
||||||
@ -805,9 +812,9 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
if not name or not name.strip():
|
if not name or not name.strip():
|
||||||
return False, "Request name cannot be empty"
|
return False, "Request name cannot be empty"
|
||||||
|
|
||||||
# Check length (max 200 characters)
|
# Check length
|
||||||
if len(name) > 200:
|
if len(name) > REQUEST_NAME_MAX_LENGTH:
|
||||||
return False, "Request name is too long (max 200 characters)"
|
return False, f"Request name is too long (max {REQUEST_NAME_MAX_LENGTH} characters)"
|
||||||
|
|
||||||
# Check for invalid characters (file system unsafe characters)
|
# Check for invalid characters (file system unsafe characters)
|
||||||
invalid_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|', '\0']
|
invalid_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|', '\0']
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user