Files
CyberPanel/plogical/versionFetcher.py

158 lines
5.3 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import requests
import json
import re
import logging
from typing import Optional, Tuple
class VersionFetcher:
"""
Utility class to fetch latest versions of components from GitHub API
"""
# GitHub API endpoints for different components
GITHUB_API_BASE = "https://api.github.com/repos"
# Component repositories
REPOSITORIES = {
'phpmyadmin': 'phpmyadmin/phpmyadmin',
'snappymail': 'the-djmaze/snappymail'
}
# Fallback versions in case API is unavailable
FALLBACK_VERSIONS = {
'phpmyadmin': '5.2.2',
'snappymail': '2.38.2'
}
@staticmethod
def get_latest_version(component: str) -> str:
"""
Get the latest version of a component from GitHub
Args:
component (str): Component name ('phpmyadmin' or 'snappymail')
Returns:
str: Latest version number or fallback version
"""
try:
if component not in VersionFetcher.REPOSITORIES:
logging.warning(f"Unknown component: {component}")
return VersionFetcher.FALLBACK_VERSIONS.get(component, "unknown")
repo = VersionFetcher.REPOSITORIES[component]
url = f"{VersionFetcher.GITHUB_API_BASE}/{repo}/releases/latest"
logging.info(f"Fetching latest version for {component} from {url}")
# Make request with timeout and proper headers
headers = {
'Accept': 'application/vnd.github.v3+json',
'User-Agent': 'CyberPanel-VersionFetcher/1.0'
}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
version = data.get('tag_name', '')
# Clean version string (remove 'v' prefix if present)
version = re.sub(r'^v', '', version)
if version and VersionFetcher._is_valid_version(version):
logging.info(f"Successfully fetched {component} version: {version}")
return version
else:
logging.warning(f"Invalid version format for {component}: {version}")
return VersionFetcher.FALLBACK_VERSIONS[component]
except requests.exceptions.RequestException as e:
logging.error(f"Failed to fetch {component} version: {e}")
return VersionFetcher.FALLBACK_VERSIONS[component]
except Exception as e:
logging.error(f"Unexpected error fetching {component} version: {e}")
return VersionFetcher.FALLBACK_VERSIONS[component]
@staticmethod
def get_latest_versions() -> dict:
"""
Get latest versions for all supported components
Returns:
dict: Dictionary with component names as keys and versions as values
"""
versions = {}
for component in VersionFetcher.REPOSITORIES.keys():
versions[component] = VersionFetcher.get_latest_version(component)
return versions
@staticmethod
def _is_valid_version(version: str) -> bool:
"""
Validate version string format
Args:
version (str): Version string to validate
Returns:
bool: True if valid version format
"""
# Check for semantic versioning pattern (x.y.z)
pattern = r'^\d+\.\d+\.\d+$'
return bool(re.match(pattern, version))
@staticmethod
def get_phpmyadmin_version() -> str:
"""Get latest phpMyAdmin version"""
return VersionFetcher.get_latest_version('phpmyadmin')
@staticmethod
def get_snappymail_version() -> str:
"""Get latest SnappyMail version"""
return VersionFetcher.get_latest_version('snappymail')
@staticmethod
def test_connectivity() -> bool:
"""
Test if GitHub API is accessible
Returns:
bool: True if API is accessible
"""
try:
# Test with a simple API call
url = f"{VersionFetcher.GITHUB_API_BASE}/octocat/Hello-World"
headers = {
'Accept': 'application/vnd.github.v3+json',
'User-Agent': 'CyberPanel-VersionFetcher/1.0'
}
response = requests.get(url, headers=headers, timeout=5)
return response.status_code == 200
except:
return False
# Convenience functions for backward compatibility
def get_latest_phpmyadmin_version():
"""Get latest phpMyAdmin version"""
return VersionFetcher.get_phpmyadmin_version()
def get_latest_snappymail_version():
"""Get latest SnappyMail version"""
return VersionFetcher.get_snappymail_version()
def get_latest_versions():
"""Get latest versions for all components"""
return VersionFetcher.get_latest_versions()
if __name__ == "__main__":
# Test the version fetcher
print("Testing version fetcher...")
print(f"GitHub API accessible: {VersionFetcher.test_connectivity()}")
print(f"Latest phpMyAdmin: {get_latest_phpmyadmin_version()}")
print(f"Latest SnappyMail: {get_latest_snappymail_version()}")
print(f"All versions: {get_latest_versions()}")