mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-07 13:56:01 +01:00
158 lines
5.3 KiB
Python
158 lines
5.3 KiB
Python
|
|
#!/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()}")
|