import requests from bs4 import BeautifulSoup import re from datetime import datetime def get_latest_bedrock_release(): """Get the latest Bedrock edition version by scraping minecraft.wiki. Parses the version history page to find the latest release. Returns dict with id, version, type, releaseTime, or None if scraping fails. """ print("[BEDROCK_CHECKER] Fetching bedrock version from minecraft.wiki...") try: url = "https://minecraft.wiki/w/Bedrock_Edition_version_history" response = requests.get(url, timeout=10, headers={'User-Agent': 'MinecraftUpdateBot/1.0'}) if response.status_code != 200: print(f"[BEDROCK_CHECKER] Failed to fetch wiki: {response.status_code}") return None soup = BeautifulSoup(response.content, 'html.parser') # Find the first version number mentioned in the actual content # Look for patterns like "26.3", "1.21.132", etc. page_text = soup.get_text() # The page structure has version numbers in tables # Let's look for the section with "26.x" or "1.21" which are current # Try to get version from table data tables = soup.find_all('table', {"class": "wikitable"}) if tables: for table in tables: rows = table.find_all('tr') if len(rows) > 1: # Second row (first data row) has the latest version cells = rows[1].find_all('td') if cells: version_text = cells[0].get_text(strip=True) # Clean up the version text if version_text and not version_text.lower().startswith('version'): # Extract just the version number version_match = re.match(r'^([\d.]+)', version_text) if version_match: version = version_match.group(1) print(f"[BEDROCK_CHECKER] ✓ Found version from wiki table: {version}") return { "id": version, "version": version, "type": "bedrock-windows", "source": "minecraft_wiki", "releaseTime": datetime.now().isoformat() } # Fallback: parse page text for version patterns # Look for the new versioning format (26.x, 27.x, etc.) - not old 1.21.x format # New format is major.minor (e.g., 26.3, 27.0) version_pattern = r'\b(2[6-9]|[3-9]\d)\.(\d{1,2})\b' matches = re.findall(version_pattern, page_text) if matches: # Get the first match (oldest format would be 26.x, newest would be higher) for major_str, minor_str in matches: try: major = int(major_str) minor = int(minor_str) # Accept versions 26.x and above if major >= 26 and minor >= 0: version = f"{major}.{minor}" print(f"[BEDROCK_CHECKER] ✓ Found version from wiki: {version}") return { "id": version, "version": version, "type": "bedrock-windows", "source": "minecraft_wiki", "releaseTime": datetime.now().isoformat() } except ValueError: continue print("[BEDROCK_CHECKER] ✗ Could not find version number in wiki page") return None except requests.exceptions.Timeout: print("[BEDROCK_CHECKER] ✗ Timeout fetching wiki page") return None except requests.exceptions.RequestException as e: print(f"[BEDROCK_CHECKER] ✗ Request error: {e}") return None except Exception as e: print(f"[BEDROCK_CHECKER] ✗ Error scraping wiki: {e}") return None def compare_versions(v1, v2): """ Compare two version strings (semantic versioning). Args: v1, v2: Version strings like "1.20.0" Returns: True if v1 > v2, False otherwise """ try: parts1 = [int(x) for x in v1.split('.')] parts2 = [int(x) for x in v2.split('.')] # Pad with zeros while len(parts1) < len(parts2): parts1.append(0) while len(parts2) < len(parts1): parts2.append(0) return parts1 > parts2 except: # Fallback to string comparison return v1 > v2