Updating game data to mid season patch and made card gallery nicer
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
# Configuration
|
||||
DOCS_DIR = r"..\chrono.docs"
|
||||
CLOUD_CARDS_DIR = r"Cloud\wwwroot\cards"
|
||||
STANDALONE_CARDS_DIR = r"Standalone\wwwroot\cards"
|
||||
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
|
||||
|
||||
def get_card_names():
|
||||
card_names = []
|
||||
# Search for all .md files in chrono.docs
|
||||
for root, dirs, files in os.walk(DOCS_DIR):
|
||||
for file in files:
|
||||
if file.endswith(".md"):
|
||||
# Remove .md extension
|
||||
card_names.append(file[:-3])
|
||||
return card_names
|
||||
|
||||
def slugify(card_name):
|
||||
# Manual overrides for slugs that don't follow the standard pattern
|
||||
overrides = {
|
||||
"APEX Starcruise": "apex-starcruiser",
|
||||
"Consummate Conspirator": "consomme-conspirator",
|
||||
"Librarian's Assistant": "librarian-assistant",
|
||||
"Violet Inquisitioner": "violet-inquisitor",
|
||||
"Breakdown": "break-down",
|
||||
"Da'Kad, Heretic Crusher": "da-kad-heretic-crusher",
|
||||
"Shae'Fan, Remembered": "shae-fan-remembered",
|
||||
"Possessed Prawn": "possessed-prawn-card",
|
||||
"P.O.G.O": "p-o-g-o",
|
||||
"A'kon, Starry Diviner": "a-kon-starry-diviner",
|
||||
"B.O.O.F.": "b-o-o-f",
|
||||
"Raiz, Pacifist's Conclusion": "raiz-pacifists-conclusion",
|
||||
"Spirit's Lament": "spirits-lament",
|
||||
"Overmind's Guilt": "overminds-guilt",
|
||||
"Entropy's End": "entropys-end",
|
||||
"Vor’kon, Eternal Source": "vor-kon-eternal-source",
|
||||
"Ta'kan the Tattle": "ta-kan-the-tattle",
|
||||
}
|
||||
|
||||
# Fix potential encoding issues in card_name (e.g. smart quotes)
|
||||
# If the script is run in an environment where the filenames were read as mangled
|
||||
# we want to ensure we use the correct name for the filename and slug lookup.
|
||||
# Note: '’' is the UTF-8 bytes for '’' interpreted as Windows-1252
|
||||
if isinstance(card_name, str):
|
||||
card_name = card_name.replace("’", "'").replace("’", "'")
|
||||
|
||||
if card_name in overrides:
|
||||
return overrides[card_name]
|
||||
|
||||
# Convert to lowercase, replace spaces/special chars with hyphens
|
||||
slug = card_name.lower()
|
||||
slug = re.sub(r'[^a-z0-9]+', '-', slug)
|
||||
slug = slug.strip('-')
|
||||
return slug
|
||||
|
||||
def download_full_art(card_name):
|
||||
# Fix potential encoding issues in card_name (e.g. smart quotes)
|
||||
if isinstance(card_name, str):
|
||||
card_name = card_name.replace("’", "'").replace("’", "'")
|
||||
|
||||
slug = slugify(card_name)
|
||||
url = f"https://www.playchrono.com/card/{slug}"
|
||||
|
||||
print(f"Processing {card_name} ({url})...")
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=10)
|
||||
if response.status_code != 200:
|
||||
print(f" [ERROR] Failed to fetch page for {card_name}: {response.status_code}")
|
||||
return
|
||||
|
||||
# Look for all data-lightbox-src and data-lightbox-alt pairs
|
||||
# We want the ones that end with "Full Art" and match our card name
|
||||
pattern = r'data-lightbox-src="([^"]+)"\s+data-lightbox-alt="([^"]+)"'
|
||||
matches = re.findall(pattern, response.text)
|
||||
|
||||
full_art_url = None
|
||||
for src, alt in matches:
|
||||
if "Full Art" in alt and (card_name.lower() in alt.lower()):
|
||||
full_art_url = src
|
||||
break
|
||||
|
||||
# Fallback to the first "Full Art" if no exact match (sometimes names might slightly differ)
|
||||
if not full_art_url:
|
||||
for src, alt in matches:
|
||||
if "Full Art" in alt:
|
||||
full_art_url = src
|
||||
break
|
||||
|
||||
# Absolute fallback to any data-lightbox-src with the pattern if still nothing
|
||||
if not full_art_url:
|
||||
match = re.search(r'data-lightbox-src="(https://cdn\.playchrono\.com/latest/en_us/img/cards/set/1/[^"]+\.png)"', response.text)
|
||||
if match:
|
||||
full_art_url = match.group(1)
|
||||
|
||||
if not full_art_url:
|
||||
print(f" [INFO] No full art found for {card_name}")
|
||||
return
|
||||
|
||||
print(f" [FOUND] {full_art_url} for {card_name}")
|
||||
|
||||
# Download image
|
||||
img_response = requests.get(full_art_url, headers={"User-Agent": USER_AGENT}, timeout=10)
|
||||
if img_response.status_code == 200:
|
||||
filename = f"fa{card_name}.png"
|
||||
|
||||
# Save to Cloud
|
||||
os.makedirs(CLOUD_CARDS_DIR, exist_ok=True)
|
||||
with open(os.path.join(CLOUD_CARDS_DIR, filename), "wb") as f:
|
||||
f.write(img_response.content)
|
||||
|
||||
# Save to Standalone
|
||||
os.makedirs(STANDALONE_CARDS_DIR, exist_ok=True)
|
||||
with open(os.path.join(STANDALONE_CARDS_DIR, filename), "wb") as f:
|
||||
f.write(img_response.content)
|
||||
|
||||
print(f" [SUCCESS] Saved {filename}")
|
||||
else:
|
||||
print(f" [ERROR] Failed to download image for {card_name}: {img_response.status_code}")
|
||||
|
||||
except Exception as e:
|
||||
print(f" [ERROR] Exception for {card_name}: {e}")
|
||||
|
||||
def main():
|
||||
card_names = get_card_names()
|
||||
print(f"Found {len(card_names)} cards to process.")
|
||||
|
||||
# Use ThreadPoolExecutor for faster downloads
|
||||
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||
executor.map(download_full_art, card_names)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user