Compare commits
No commits in common. "6e01ea7ff88249680fdb0cb751fc9c1d62183cea" and "cad067d5cb279cfa3e453b525e76123717fe4539" have entirely different histories.
6e01ea7ff8
...
cad067d5cb
@ -1,81 +0,0 @@
|
|||||||
import requests
|
|
||||||
import pandas as pd
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Function to fetch card details from Scryfall using the set code and collector number
|
|
||||||
def fetch_card_images_by_set_and_number(set_code, collector_number):
|
|
||||||
url = f"https://api.scryfall.com/cards/{set_code}/{collector_number}"
|
|
||||||
response = requests.get(url)
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
|
||||||
card_data = response.json()
|
|
||||||
images = []
|
|
||||||
|
|
||||||
# Handle single-sided or multi-sided cards
|
|
||||||
if 'image_uris' in card_data:
|
|
||||||
images.append((card_data['image_uris']['art_crop'], card_data['name']))
|
|
||||||
if 'card_faces' in card_data:
|
|
||||||
for face in card_data['card_faces']:
|
|
||||||
if 'image_uris' in face:
|
|
||||||
images.append((face['image_uris']['art_crop'], face['name']))
|
|
||||||
return images
|
|
||||||
else:
|
|
||||||
print(f"Error fetching card with set code {set_code} and collector number {collector_number}: {response.status_code}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Function to download and save an image
|
|
||||||
def download_image(image_url, save_path):
|
|
||||||
response = requests.get(image_url)
|
|
||||||
if response.status_code == 200:
|
|
||||||
with open(save_path, 'wb') as file:
|
|
||||||
file.write(response.content)
|
|
||||||
else:
|
|
||||||
print(f"Failed to download image from {image_url}")
|
|
||||||
|
|
||||||
# Function to process the CSV and download images
|
|
||||||
def download_images_from_csv(csv_path, output_folder):
|
|
||||||
# Create output directory if it doesn't exist
|
|
||||||
if not os.path.exists(output_folder):
|
|
||||||
os.makedirs(output_folder)
|
|
||||||
|
|
||||||
# Read the CSV file
|
|
||||||
df = pd.read_csv(csv_path)
|
|
||||||
|
|
||||||
# Assuming the CSV has columns 'Card Name', 'Set Code', and 'Collector Number'
|
|
||||||
for index, row in df.iterrows():
|
|
||||||
card_name = row['Card Name']
|
|
||||||
set_code = row['Set Code']
|
|
||||||
collector_number = row['Collector Number']
|
|
||||||
|
|
||||||
# Naming convention: set_code_card_name_face_name.jpg
|
|
||||||
image_base_name = f"{set_code}_{card_name.replace('/', '-').replace(':', '')}"
|
|
||||||
|
|
||||||
print(f"Processing {card_name} from set {set_code} with collector number {collector_number}...")
|
|
||||||
|
|
||||||
images = fetch_card_images_by_set_and_number(set_code, collector_number)
|
|
||||||
if images:
|
|
||||||
for image_url, face_name in images:
|
|
||||||
# Sanitize file name by removing invalid characters
|
|
||||||
image_file_name = f"{image_base_name}_{face_name.replace('/', '-').replace(':', '')}_art_crop.jpg"
|
|
||||||
save_path = os.path.join(output_folder, image_file_name)
|
|
||||||
|
|
||||||
# Skip downloading if the image already exists
|
|
||||||
if os.path.exists(save_path):
|
|
||||||
print(f"Image already exists for {card_name} ({face_name}), skipping download.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
download_image(image_url, save_path)
|
|
||||||
time.sleep(0.1) # Sleep to avoid hitting API rate limits
|
|
||||||
else:
|
|
||||||
print(f"No images found for {card_name} from set {set_code} with collector number {collector_number}")
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# Define the path to the input CSV and output folder
|
|
||||||
csv_path = 'cards.csv' # Replace with your CSV file path
|
|
||||||
output_folder = 'artcrop_images'
|
|
||||||
|
|
||||||
# Start the download process
|
|
||||||
download_images_from_csv(csv_path, output_folder)
|
|
||||||
print("Download completed.")
|
|
@ -1,102 +0,0 @@
|
|||||||
import os
|
|
||||||
import random
|
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
# Function to load, resize, and crop JPG images from a directory
|
|
||||||
def load_resize_and_crop_images(directory, target_size):
|
|
||||||
images = []
|
|
||||||
for filename in os.listdir(directory):
|
|
||||||
if filename.lower().endswith((".jpg", ".jpeg")):
|
|
||||||
try:
|
|
||||||
img = Image.open(os.path.join(directory, filename))
|
|
||||||
|
|
||||||
# Calculate the aspect ratios for scaling
|
|
||||||
img_aspect = img.width / img.height
|
|
||||||
target_aspect = target_size[0] / target_size[1]
|
|
||||||
|
|
||||||
if img_aspect > target_aspect:
|
|
||||||
# Image is wider than the target: scale height and crop width
|
|
||||||
img = img.resize((int(img_aspect * target_size[1]), target_size[1]), Image.Resampling.LANCZOS)
|
|
||||||
left = (img.width - target_size[0]) / 2
|
|
||||||
img = img.crop((left, 0, left + target_size[0], target_size[1]))
|
|
||||||
else:
|
|
||||||
# Image is taller than the target: scale width and crop height
|
|
||||||
img = img.resize((target_size[0], int(target_size[0] / img_aspect)), Image.Resampling.LANCZOS)
|
|
||||||
top = (img.height - target_size[1]) / 2
|
|
||||||
img = img.crop((0, top, target_size[0], top + target_size[1]))
|
|
||||||
|
|
||||||
images.append(img)
|
|
||||||
except IOError:
|
|
||||||
print(f"Warning: Unable to open image {filename}. It may be corrupted or not a valid image file.")
|
|
||||||
return images
|
|
||||||
|
|
||||||
# Function to create a wallpaper from images
|
|
||||||
def create_wallpaper(images, screen_size, output_file):
|
|
||||||
wallpaper = Image.new('RGB', screen_size)
|
|
||||||
|
|
||||||
random.shuffle(images) # Randomize the order of images
|
|
||||||
|
|
||||||
x_offset = 0
|
|
||||||
y_offset = 0
|
|
||||||
|
|
||||||
for img in images:
|
|
||||||
img_width, img_height = img.size
|
|
||||||
|
|
||||||
if x_offset + img_width > screen_size[0]: # Move to next row if needed
|
|
||||||
x_offset = 0
|
|
||||||
y_offset += img_height
|
|
||||||
|
|
||||||
if y_offset + img_height > screen_size[1]: # Stop if out of vertical space
|
|
||||||
break
|
|
||||||
|
|
||||||
wallpaper.paste(img, (x_offset, y_offset))
|
|
||||||
x_offset += img_width
|
|
||||||
|
|
||||||
wallpaper.save(output_file, format='JPEG')
|
|
||||||
print(f"Wallpaper saved as {output_file}")
|
|
||||||
|
|
||||||
# Function to prompt user for screen size
|
|
||||||
def get_screen_size():
|
|
||||||
sizes = {
|
|
||||||
"1": (1920, 1080),
|
|
||||||
"2": (2560, 1440),
|
|
||||||
"3": (3840, 2160),
|
|
||||||
"4": (1280, 720),
|
|
||||||
"5": (1600, 900)
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Choose a screen size:")
|
|
||||||
print("1: 1920x1080 (Full HD)")
|
|
||||||
print("2: 2560x1440 (2K)")
|
|
||||||
print("3: 3840x2160 (4K)")
|
|
||||||
print("4: 1280x720 (HD)")
|
|
||||||
print("5: 1600x900 (HD+)")
|
|
||||||
|
|
||||||
choice = input("Enter the number corresponding to your choice: ")
|
|
||||||
|
|
||||||
return sizes.get(choice, (1920, 1080)) # Default to 1920x1080 if invalid choice
|
|
||||||
|
|
||||||
def main():
|
|
||||||
directory = input("Enter the directory containing JPG files: ")
|
|
||||||
screen_size = get_screen_size()
|
|
||||||
|
|
||||||
# Determine the target size for each image based on the screen size
|
|
||||||
# Here, we assume a grid of 5 images across and as many rows as needed
|
|
||||||
target_size = (screen_size[0] // 5, screen_size[1] // 5)
|
|
||||||
|
|
||||||
output_file = input("Enter the name of the output wallpaper file (e.g., wallpaper.jpg): ")
|
|
||||||
|
|
||||||
# Ensure the output file has a .jpg extension
|
|
||||||
if not output_file.lower().endswith('.jpg'):
|
|
||||||
output_file += '.jpg'
|
|
||||||
|
|
||||||
images = load_resize_and_crop_images(directory, target_size)
|
|
||||||
|
|
||||||
if not images:
|
|
||||||
print("No JPG files found in the directory.")
|
|
||||||
return
|
|
||||||
|
|
||||||
create_wallpaper(images, screen_size, output_file)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,96 +0,0 @@
|
|||||||
import csv
|
|
||||||
import os
|
|
||||||
import requests
|
|
||||||
|
|
||||||
# Function to append a card entry to the CSV file
|
|
||||||
def add_card_to_csv(csv_path, card_name, set_code, collector_number, quantity, foil):
|
|
||||||
file_exists = os.path.isfile(csv_path)
|
|
||||||
|
|
||||||
with open(csv_path, mode='a', newline='') as file:
|
|
||||||
writer = csv.writer(file)
|
|
||||||
|
|
||||||
# Write header if the file doesn't exist
|
|
||||||
if not file_exists:
|
|
||||||
writer.writerow(['Card Name', 'Set Code', 'Collector Number', 'Quantity', 'Foil'])
|
|
||||||
|
|
||||||
# Append the card data
|
|
||||||
writer.writerow([card_name, set_code, collector_number, quantity, foil])
|
|
||||||
|
|
||||||
print(f"Added {quantity}x {card_name} from set {set_code} with collector number {collector_number} (Foil: {foil}) to {csv_path}.")
|
|
||||||
|
|
||||||
# Function to download the full card image
|
|
||||||
def download_full_card_image(set_code, collector_number, card_name, foil):
|
|
||||||
url = f"https://api.scryfall.com/cards/{set_code}/{collector_number}"
|
|
||||||
response = requests.get(url)
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
|
||||||
card_data = response.json()
|
|
||||||
|
|
||||||
# Determine the image URL (normal)
|
|
||||||
image_url = card_data['image_uris']['normal'] if 'image_uris' in card_data else None
|
|
||||||
if not image_url and 'card_faces' in card_data: # Check for double-sided cards
|
|
||||||
image_url = card_data['card_faces'][0]['image_uris']['normal']
|
|
||||||
|
|
||||||
if image_url:
|
|
||||||
# Create the full_card directory if it doesn't exist
|
|
||||||
directory = 'full_card'
|
|
||||||
if not os.path.exists(directory):
|
|
||||||
os.makedirs(directory)
|
|
||||||
|
|
||||||
# Create a filename for the image
|
|
||||||
foil_text = "_foil" if foil else ""
|
|
||||||
file_name = f"{card_name.replace('/', '-').replace(':', '').replace(' ', '_')}_{set_code}_{collector_number}{foil_text}.jpg"
|
|
||||||
file_path = os.path.join(directory, file_name)
|
|
||||||
|
|
||||||
# Download and save the image
|
|
||||||
image_response = requests.get(image_url)
|
|
||||||
with open(file_path, 'wb') as file:
|
|
||||||
file.write(image_response.content)
|
|
||||||
|
|
||||||
print(f"Downloaded full card image for {card_name} (Set: {set_code}, Collector Number: {collector_number}, Foil: {foil})")
|
|
||||||
else:
|
|
||||||
print(f"No full card image found for {card_name} (Set: {set_code}, Collector Number: {collector_number})")
|
|
||||||
else:
|
|
||||||
print(f"Failed to fetch data for {card_name} (Set: {set_code}, Collector Number: {collector_number}) from Scryfall.")
|
|
||||||
|
|
||||||
# Function to sort the CSV file by Set Code and Collector Number
|
|
||||||
def sort_csv_file(csv_path):
|
|
||||||
with open(csv_path, mode='r') as file:
|
|
||||||
reader = csv.reader(file)
|
|
||||||
header = next(reader) # Read the header
|
|
||||||
sorted_rows = sorted(reader, key=lambda row: (row[1], int(row[2]))) # Sort by Set Code (row[1]) and Collector Number (row[2]))
|
|
||||||
|
|
||||||
# Write the sorted data back to the CSV
|
|
||||||
with open(csv_path, mode='w', newline='') as file:
|
|
||||||
writer = csv.writer(file)
|
|
||||||
writer.writerow(header) # Write the header back
|
|
||||||
writer.writerows(sorted_rows) # Write the sorted rows
|
|
||||||
|
|
||||||
print(f"CSV file sorted by Set Code and Collector Number.")
|
|
||||||
|
|
||||||
# Function to get user input and add multiple cards interactively
|
|
||||||
def interactive_card_entry(csv_path):
|
|
||||||
while True:
|
|
||||||
# Get the card details from the user
|
|
||||||
card_name = input("Enter the card name (or type 'exit' to quit): ").strip()
|
|
||||||
if card_name.lower() == 'exit':
|
|
||||||
print("Exiting the program.")
|
|
||||||
break
|
|
||||||
|
|
||||||
set_code = input("Enter the set code: ").strip()
|
|
||||||
collector_number = input("Enter the collector number: ").strip()
|
|
||||||
quantity = int(input("Enter the quantity: ").strip())
|
|
||||||
foil = input("Is this card a foil? (yes/no): ").strip().lower() == 'yes'
|
|
||||||
|
|
||||||
# Add the card to the CSV file
|
|
||||||
add_card_to_csv(csv_path, card_name, set_code, collector_number, quantity, foil)
|
|
||||||
|
|
||||||
# Download the full card image
|
|
||||||
download_full_card_image(set_code, collector_number, card_name, foil)
|
|
||||||
|
|
||||||
# Sort the CSV file after each entry
|
|
||||||
sort_csv_file(csv_path)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
csv_path = input("Enter the path to the CSV file: ").strip()
|
|
||||||
interactive_card_entry(csv_path)
|
|
Loading…
Reference in New Issue
Block a user