diff --git a/art_image_dl.py b/art_image_dl.py new file mode 100644 index 0000000..c7098e7 --- /dev/null +++ b/art_image_dl.py @@ -0,0 +1,81 @@ +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.") diff --git a/create_wallpaper.py b/create_wallpaper.py new file mode 100644 index 0000000..351d93c --- /dev/null +++ b/create_wallpaper.py @@ -0,0 +1,102 @@ +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() diff --git a/interactive_cards_with_dl.py b/interactive_cards_with_dl.py new file mode 100644 index 0000000..9c3febf --- /dev/null +++ b/interactive_cards_with_dl.py @@ -0,0 +1,96 @@ +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 art crop image +def download_art_crop_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 (art_crop) + image_url = card_data['image_uris']['art_crop'] 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']['art_crop'] + + if image_url: + # Create the art_crop directory if it doesn't exist + directory = 'art_crop' + 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 art crop image for {card_name} (Set: {set_code}, Collector Number: {collector_number}, Foil: {foil})") + else: + print(f"No art crop 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 art crop image + download_art_crop_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)