-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathsearch_flatpak.py
More file actions
142 lines (119 loc) · 5.88 KB
/
Copy pathsearch_flatpak.py
File metadata and controls
142 lines (119 loc) · 5.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# search_flatpak.py
"""Flatpak search module with standardized error handling and consistent source naming.
IMPROVEMENTS: Standardized source name to lowercase, used config timeouts, unified exception handling."""
import subprocess
from typing import List, Tuple, Optional
from archpkg.config import TIMEOUTS
from archpkg.exceptions import PackageManagerNotFound, PackageSearchException, TimeoutError, ValidationError
from archpkg.logging_config import get_logger, PackageHelperLogger
logger = get_logger(__name__)
def search_flatpak(query: str, cache_manager: Optional[object] = None) -> List[Tuple[str, str, str]]:
"""Search for packages using the Flatpak package manager.
Args:
query: Search query string
cache_manager: Optional cache manager for storing/retrieving results
Returns:
List[Tuple[str, str, str]]: List of (name, description, source) tuples
Raises:
ValidationError: When query is empty or invalid
PackageManagerNotFound: When Flatpak is not available
TimeoutError: When search times out
PackageSearchException: For other search-related errors
"""
logger.info(f"Starting Flatpak search for query: '{query}'")
if not query or not query.strip():
logger.error("Empty search query provided to Flatpak search")
raise ValidationError("Empty search query provided")
# Check cache first if available
if cache_manager:
cached_results = cache_manager.get(query, 'flatpak')
if cached_results is not None:
logger.info(f"Retrieved {len(cached_results)} Flatpak results from cache")
return cached_results
# Check if flatpak is available and working
logger.debug("Checking Flatpak availability")
try:
subprocess.run(
['flatpak', '--version'],
capture_output=True,
check=True,
timeout=TIMEOUTS['command_check']
)
logger.debug("Flatpak is available and responsive")
except FileNotFoundError:
logger.error("flatpak command not found")
raise PackageManagerNotFound("flatpak command not found. Install flatpak first.")
except subprocess.CalledProcessError as e:
logger.error(f"Flatpak version check failed with return code {e.returncode}")
raise PackageSearchException("flatpak is installed but not working properly.")
except subprocess.TimeoutExpired:
logger.warning("Flatpak version check timed out")
raise TimeoutError("flatpak is not responding. Check if the service is running.")
try:
logger.debug(f"Executing flatpak search with timeout {TIMEOUTS['flatpak']}s")
# IMPROVED: Use config timeout value
result = subprocess.run(
['flatpak', 'search', query.strip()],
capture_output=True,
text=True,
timeout=TIMEOUTS['flatpak'],
check=False
)
logger.debug(f"Flatpak search completed with return code: {result.returncode}")
# Handle exit codes
if result.returncode == 1:
logger.info("Flatpak search found no matches (normal result)")
return []
elif result.returncode != 0:
error_msg = result.stderr.strip()
logger.error(f"Flatpak search failed with error: {error_msg}")
if "No remotes found" in error_msg:
logger.warning("No Flatpak remotes configured")
raise PackageSearchException(
"No Flatpak remotes configured. Run: "
"flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo"
)
else:
logger.error(f"Flatpak search failed with unknown error: {error_msg}")
raise PackageSearchException(f"flatpak search failed: {error_msg or 'Unknown error'}")
output = result.stdout.strip()
if not output:
logger.info("Flatpak search returned empty output")
return []
logger.debug("Parsing Flatpak search results")
# Parse search results (tab-separated format)
lines = output.split('\n')
if len(lines) < 2:
logger.warning("Flatpak search returned insufficient output lines")
return []
packages = []
lines_processed = 0
for line in lines[1:]: # skip header row
if not line.strip():
continue
lines_processed += 1
cols = line.split()
if len(cols) >= 3:
name = cols[0].strip()
description = cols[1].strip()
app_id = cols[2].strip()
# IMPROVED: Standardized source name to lowercase
packages.append((app_id, f"{name} - {description}", "flatpak"))
logger.debug(f"Found Flatpak package: {app_id}")
else:
logger.debug(f"Skipping malformed Flatpak result line: {line}")
logger.info(f"Flatpak search completed: {len(packages)} packages found from {lines_processed} lines")
# Cache results if cache manager is available
if cache_manager and packages:
cache_manager.set(query, 'flatpak', packages)
logger.debug(f"Cached {len(packages)} Flatpak results")
return packages
except subprocess.TimeoutExpired:
logger.error(f"Flatpak search timed out after {TIMEOUTS['flatpak']}s")
raise TimeoutError("Flatpak search timed out. Check your internet connection.")
except (ValidationError, PackageManagerNotFound, TimeoutError, PackageSearchException):
# Re-raise our specific exceptions
raise
except Exception as e:
PackageHelperLogger.log_exception(logger, "Unexpected error during Flatpak search", e)
raise PackageSearchException(f"Unexpected error during flatpak search: {str(e)}")