udated naming and added interactive

This commit is contained in:
Caleb Fultz 2024-08-13 16:05:37 -04:00
parent 1a45c349f4
commit 528c8e3dd2
35 changed files with 214 additions and 0 deletions

View File

@ -2,3 +2,37 @@ Card Name,Set Code,Collector Number,Quantity,Foil
"Linda, Kandarian Queen",sld,1355,1,True "Linda, Kandarian Queen",sld,1355,1,True
"Vraska, Golgari Queen",sld,1702,1,False "Vraska, Golgari Queen",sld,1702,1,False
"Vraska, Golgari Queen",sld,1702,1,True "Vraska, Golgari Queen",sld,1702,1,True
"Huatli, Radiant Champion",sld,1699,1,False
"Huatli, Radiant Champion",sld,1699,1,True
"Kiora, Behemoth Beckoner",sld,1700,1,False
"Kiora, Behemoth Beckoner",sld,1700,1,True
"Tezzeret, Master of the Bridge",sld,1701,1,False
"Tezzeret, Master of the Bridge",sld,1701,1,True
Sorin Markov,sld,1698,1,False
Sorin Markov,sld,1698,1,True
"Flubs, The Fool",blc,356,1,True
"Flubs, The Fool",blc,356,1,False
Pollenbright Druid,sld,776,1,True
Frilled Mystic,sld,786,1,True
"Obeka, Brute Chronolgoist",sld,1579,1,False
Dire Undercurrents,sld,1578,1,False
Black Market,sld,1577,1,False
"Jace, Wielder of Mysteries",sld,1576,1,False
Reconnasissance,sld,1575,1,False
"Yargle, Glutton of Urborg",sld,1542,1,False
"Adrix and Nev, Twincasters",sld,1544,1,False
Coveted Jewel,sld,799,1,False
Sakashima of a Thousand Faces,sld,1541,1,False
"Krark, The Thumbless",sld,1543,1,False
Arcance Denial,sld,1545,1,False
Nightscape Familiar,sld,1546,1,False
Rain of Filth,sld,1547,1,False
Simian Spirit Guide,sld,1548,1,False
Prince of Thralls,sld,1549,1,False
Felidar Guardian,sld,1487,1,False
Peregrine Drake,sld,1488,1,False
Serpent of Yawning Depths,sld,1489,1,False
Scourage of Valkas,sld,1490,1,False
Voracious Hydra,sld,1491,1,False
The Scorpion God,sld,904,1,True
"Vilis, Broker of Blood",sld,1567,1,False

1 Card Name Set Code Collector Number Quantity Foil
2 Linda, Kandarian Queen sld 1355 1 True
3 Vraska, Golgari Queen sld 1702 1 False
4 Vraska, Golgari Queen sld 1702 1 True
5 Huatli, Radiant Champion sld 1699 1 False
6 Huatli, Radiant Champion sld 1699 1 True
7 Kiora, Behemoth Beckoner sld 1700 1 False
8 Kiora, Behemoth Beckoner sld 1700 1 True
9 Tezzeret, Master of the Bridge sld 1701 1 False
10 Tezzeret, Master of the Bridge sld 1701 1 True
11 Sorin Markov sld 1698 1 False
12 Sorin Markov sld 1698 1 True
13 Flubs, The Fool blc 356 1 True
14 Flubs, The Fool blc 356 1 False
15 Pollenbright Druid sld 776 1 True
16 Frilled Mystic sld 786 1 True
17 Obeka, Brute Chronolgoist sld 1579 1 False
18 Dire Undercurrents sld 1578 1 False
19 Black Market sld 1577 1 False
20 Jace, Wielder of Mysteries sld 1576 1 False
21 Reconnasissance sld 1575 1 False
22 Yargle, Glutton of Urborg sld 1542 1 False
23 Adrix and Nev, Twincasters sld 1544 1 False
24 Coveted Jewel sld 799 1 False
25 Sakashima of a Thousand Faces sld 1541 1 False
26 Krark, The Thumbless sld 1543 1 False
27 Arcance Denial sld 1545 1 False
28 Nightscape Familiar sld 1546 1 False
29 Rain of Filth sld 1547 1 False
30 Simian Spirit Guide sld 1548 1 False
31 Prince of Thralls sld 1549 1 False
32 Felidar Guardian sld 1487 1 False
33 Peregrine Drake sld 1488 1 False
34 Serpent of Yawning Depths sld 1489 1 False
35 Scourage of Valkas sld 1490 1 False
36 Voracious Hydra sld 1491 1 False
37 The Scorpion God sld 904 1 True
38 Vilis, Broker of Blood sld 1567 1 False

60
cli_cards.py Normal file
View File

@ -0,0 +1,60 @@
import csv
import os
import argparse
# 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 parse and add multiple cards
def add_multiple_cards(csv_path, card_entries):
for entry in card_entries:
card_name, set_code, collector_number, quantity, foil = entry
add_card_to_csv(csv_path, card_name, set_code, collector_number, quantity, foil)
# Main function to handle command-line arguments
def main():
parser = argparse.ArgumentParser(description="Add one or more Magic: The Gathering cards to a CSV file.")
parser.add_argument('csv_path',
help="The path to the CSV file where the card data will be stored. If the file does not exist, it will be created.")
# Allow multiple --card entries
parser.add_argument('--card',
action='append',
nargs=5,
metavar=('Card_Name', 'Set_Code', 'Collector_Number', 'Quantity', 'Foil'),
help=("Add a card to the CSV file. "
"Each card entry should be specified in the following format: "
"Card_Name Set_Code Collector_Number Quantity Foil. "
"Foil should be 'True' or 'False' indicating if the card is foil or not. "
"This option can be used multiple times to add multiple cards in one command."))
args = parser.parse_args()
if args.card:
card_entries = []
for card in args.card:
card_name, set_code, collector_number, quantity, foil = card
quantity = int(quantity)
foil = foil.lower() == 'true' # Convert the foil input to a boolean
card_entries.append((card_name, set_code, collector_number, quantity, foil))
add_multiple_cards(args.csv_path, card_entries)
else:
print("No cards provided. Use the --card option to add cards.")
if __name__ == "__main__":
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

81
image_dl.py Normal file
View File

@ -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']['normal'], 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']['normal'], 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(':', '')}.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.2) # 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 = 'downloaded_images'
# Start the download process
download_images_from_csv(csv_path, output_folder)
print("Download completed.")

39
interactive_cards.py Normal file
View File

@ -0,0 +1,39 @@
import csv
import os
# 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 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)
if __name__ == "__main__":
csv_path = input("Enter the path to the CSV file: ").strip()
interactive_card_entry(csv_path)