2026-03-11 23:29:13 +00:00
|
|
|
import requests
|
2026-03-12 21:45:01 +00:00
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
import re
|
2026-03-11 23:29:13 +00:00
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
|
|
|
2026-03-12 21:45:01 +00:00
|
|
|
def get_latest_bedrock_release():
|
|
|
|
|
"""Get the latest Bedrock edition version by scraping minecraft.wiki.
|
2026-03-11 23:29:13 +00:00
|
|
|
|
2026-03-12 21:45:01 +00:00
|
|
|
Parses the version history page to find the latest release.
|
|
|
|
|
Returns dict with id, version, type, releaseTime, or None if scraping fails.
|
2026-03-11 23:29:13 +00:00
|
|
|
"""
|
2026-03-12 21:45:01 +00:00
|
|
|
print("[BEDROCK_CHECKER] Fetching bedrock version from minecraft.wiki...")
|
2026-03-11 23:29:13 +00:00
|
|
|
|
|
|
|
|
try:
|
2026-03-12 21:45:01 +00:00
|
|
|
url = "https://minecraft.wiki/w/Bedrock_Edition_version_history"
|
|
|
|
|
response = requests.get(url, timeout=10, headers={'User-Agent': 'MinecraftUpdateBot/1.0'})
|
2026-03-11 23:29:13 +00:00
|
|
|
|
2026-03-12 21:45:01 +00:00
|
|
|
if response.status_code != 200:
|
|
|
|
|
print(f"[BEDROCK_CHECKER] Failed to fetch wiki: {response.status_code}")
|
2026-03-11 23:29:13 +00:00
|
|
|
return None
|
|
|
|
|
|
2026-03-12 21:45:01 +00:00
|
|
|
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}")
|
2026-03-11 23:29:13 +00:00
|
|
|
return None
|
|
|
|
|
except Exception as e:
|
2026-03-12 21:45:01 +00:00
|
|
|
print(f"[BEDROCK_CHECKER] ✗ Error scraping wiki: {e}")
|
2026-03-11 23:29:13 +00:00
|
|
|
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
|