Pattern generation and URL handling for AppImage files.
This module contains functions for parsing GitHub URLs, normalizing repository URLs,
generating regex patterns for AppImage file matching, and detecting prerelease-only
repositories.
create_pattern_from_filenames(filenames, include_both_formats=False)
Create a regex pattern from actual AppImage/ZIP filenames.
Source code in src/appimage_updater/core/pattern_generator.py
| @deprecated("Use repository-specific pattern generation methods instead")
def create_pattern_from_filenames(filenames: list[str], include_both_formats: bool = False) -> str:
"""Create a regex pattern from actual AppImage/ZIP filenames."""
if not filenames:
return _build_pattern("", include_both_formats, empty_ok=True)
base_filenames = _strip_extensions_list(filenames)
common_prefix = _derive_common_prefix(base_filenames, filenames)
common_prefix = _generalize_pattern_prefix(common_prefix)
pattern = _build_pattern(common_prefix, include_both_formats)
fmt = "both ZIP and AppImage" if include_both_formats else "AppImage"
logger.debug(f"Created {fmt} pattern '{pattern}' from {len(filenames)} files: {filenames[:3]}...")
return pattern
|
detect_source_type(url)
Detect the source type based on the URL.
Source code in src/appimage_updater/core/pattern_generator.py
| def detect_source_type(url: str) -> str:
"""Detect the source type based on the URL."""
return detect_repository_type(url)
|
fetch_appimage_pattern_from_github(url)
async
Legacy function name - now redirects to repository-agnostic version.
Source code in src/appimage_updater/core/pattern_generator.py
| async def fetch_appimage_pattern_from_github(url: str) -> str | None:
"""Legacy function name - now redirects to repository-agnostic version."""
return await generate_appimage_pattern_async("temp", url)
|
find_common_prefix(strings)
Find the longest common prefix among a list of strings.
Source code in src/appimage_updater/core/pattern_generator.py
| def find_common_prefix(strings: list[str]) -> str:
"""Find the longest common prefix among a list of strings."""
if not strings:
return ""
# Start with the first string
prefix = strings[0]
for string in strings[1:]:
# Find common prefix with current string
common_len = _find_common_length(prefix, string)
prefix = prefix[:common_len]
# If prefix becomes too short, stop
if len(prefix) < 2:
break
return prefix
|
generate_appimage_pattern_async(app_name, url)
async
Repository-agnostic pattern generation for use in async contexts.
an accurate pattern. Works with GitHub, GitLab, and other repository types.
Falls back to intelligent defaults if that fails.
Source code in src/appimage_updater/core/pattern_generator.py
| async def generate_appimage_pattern_async(app_name: str, url: str) -> str | None:
"""Repository-agnostic pattern generation for use in async contexts.
an accurate pattern. Works with GitHub, GitLab, and other repository types.
Falls back to intelligent defaults if that fails.
"""
try:
# Create a minimal config for the repository service
temp_config = ApplicationConfig(
name=app_name,
source_type="dynamic_download",
url=url,
download_dir=Path(tempfile.gettempdir()),
pattern="",
prerelease=False,
)
# Try to get pattern from centralized repository service
pattern = await version_service.generate_pattern_from_repository(temp_config)
if pattern:
logger.debug(f"Generated pattern from repository releases: {pattern}")
return pattern
# Fallback to old method if centralized service fails
logger.debug("Centralized service failed, falling back to legacy method")
return await _legacy_fetch_pattern(url)
except Exception as e:
logger.debug(f"Error generating pattern from repository: {e}")
return None
|
normalize_github_url(url)
Normalize GitHub URL to repository format and detect if it was corrected.
Detects GitHub download URLs (releases/download/...) and converts them to repository URLs.
Returns (normalized_url, was_corrected) tuple.
Source code in src/appimage_updater/core/pattern_generator.py
| def normalize_github_url(url: str) -> tuple[str, bool]:
"""Normalize GitHub URL to repository format and detect if it was corrected.
Detects GitHub download URLs (releases/download/...) and converts them to repository URLs.
Returns (normalized_url, was_corrected) tuple.
"""
try:
if not _is_github_url(url):
return url, False
path_parts = _extract_url_path_parts(url)
if len(path_parts) < 2:
return url, False
owner, repo = path_parts[0], path_parts[1]
return _normalize_github_path(path_parts, owner, repo, url)
except (ValueError, AttributeError) as e:
logger.debug(f"Failed to normalize GitHub URL {url}: {e}")
return url, False
|
should_enable_prerelease(url)
async
Check if prerelease should be automatically enabled for a repository.
Returns True if the repository only has prerelease versions (like continuous builds)
and no stable releases, indicating that prerelease support should be enabled.
Parameters:
Name |
Type |
Description |
Default |
url
|
str
|
|
required
|
Returns:
Name | Type |
Description |
bool |
bool
|
True if only prereleases are found, False if stable releases exist or on error
|
Source code in src/appimage_updater/core/pattern_generator.py
| async def should_enable_prerelease(url: str) -> bool:
"""Check if prerelease should be automatically enabled for a repository.
Returns True if the repository only has prerelease versions (like continuous builds)
and no stable releases, indicating that prerelease support should be enabled.
Args:
url: Repository URL
Returns:
bool: True if only prereleases are found, False if stable releases exist or on error
"""
try:
releases = await _fetch_releases_for_prerelease_check(url)
if not releases:
return False
valid_releases = _filter_valid_releases(releases, url)
if not valid_releases:
return False
return _analyze_prerelease_status(valid_releases, url)
except (RepositoryError, ValueError, AttributeError) as e:
# Don't fail the add command if prerelease detection fails
logger.debug(f"Failed to check prerelease status for {url}: {e}")
return False
|