Skip to main content

A Python CLI tool for arithmetic operations on Magic: The Gathering Cockatrice deck files

Project description

🃏 MTG Wants - Cockatrice Deck Operations

Python Version License: MIT Version

A powerful Python CLI tool and library for performing arithmetic operations on Magic: The Gathering deck files in Cockatrice format (.cod). Perfect for deck management, inventory tracking, and wantslist generation for Cardmarket.

✨ Features

  • 🔢 Deck Arithmetic: Add and subtract decks with --add and --sub operations
  • 📦 Sideboard Support: Full support for sideboard management
  • 🎯 Cardmarket Integration: Export formatted wantslists ready to paste into Cardmarket, automatically copied to clipboard
  • 🔄 Sequential Operations: Chain multiple operations in exact order
  • 📁 Cockatrice Compatible: Native support for Cockatrice .cod XML format
  • 🐍 Python Library: Use as a CLI tool or import as a Python library

🎮 Use Cases

  • Build a wantslist: Subtract your collection from a target deck to know what to buy
  • Combine decks: Merge multiple decklists into one
  • Track inventory: Keep your digital collection synchronized with physical cards
  • Deck variations: Create deck variants by adding/removing specific cards
  • Budget planning: Calculate exact cards needed for deck upgrades

📦 Installation

From PyPI (Coming Soon)

pip install mtgwants

From Source

git clone https://github.com/Firi0n/mtgwants.git
cd mtgwants
pip install -e .

📋 Requirements

  • Python 3.10 or higher
  • pyperclip (for clipboard support)

🚀 Quick Start

Basic Usage

# Save a single deck
mtgwants main.cod -o output.cod

# Create a wantslist: deck minus your collection
mtgwants deck.cod --sub collection.cod --print

# Combine multiple decks with sideboard
mtgwants deck1.cod --add deck2.cod --add deck3.cod --sideboard -o combined.cod

📖 Documentation

Command Line Interface

mtgwants MAIN_DECK [OPTIONS]

Required Arguments

  • MAIN_DECK: The primary deck file in Cockatrice .cod format

Deck Operations

Option Short Description
--add DECK.COD -a Add cards from deck file (repeatable)
--sub DECK.COD -b Subtract cards from deck file (repeatable)

Important: Operations are executed in the exact order you specify them on the command line. Order matters because subtraction doesn't produce negative quantities.

Other Options

Option Short Description
--sideboard -s Include sideboard from all decks
--output FILE -o Save result to a .cod file
--print -p Print cardlist to console (Cardmarket format) and copy it to clipboard
--deck-name NAME -n Custom name for output deck (default: "Deck")
--verbose -v Verbose output (use -vv for extra detail)

Note: At least one of --output or --print must be specified.

📚 Examples

Example 1: Generate a Wantslist

You want to build a Commander deck but need to know which cards to buy:

mtgwants commander_deck.cod --sub my_collection.cod --sideboard --print

This outputs a formatted list and copies it directly to your clipboard, ready to paste into Cardmarket's wantslist.

Example 2: Combine Decklists

Merge several decklists into one master list:

mtgwants deck1.cod --add deck2.cod --add deck3.cod -o master_deck.cod

Example 3: Track Inventory

After buying cards, update your collection and recalculate what you still need:

mtgwants target_deck.cod --sub old_collection.cod --add new_cards.cod -o updated_needs.cod --print

Example 4: Short Form Syntax

Use abbreviated flags for quicker commands:

mtgwants main.cod -a extras.cod -b dupes.cod -o final.cod -p

Example 5: Order Matters

Operations are executed left-to-right in exact order:

# Add first, then subtract
mtgwants deck.cod --add new.cod --sub owned.cod -p
# Result: (deck + new) - owned

# Different order, different result
mtgwants deck.cod --sub owned.cod --add new.cod -p
# Result: (deck - owned) + new

Example 6: Debug with Verbose Output

See detailed information about each operation:

mtgwants main.cod -a extras.cod -b dupes.cod -o final.cod -vv

Output:

Loading main deck: main.cod
  Main: 60 cards
Adding: extras.cod
  Result main: 75 cards
Subtracting: dupes.cod
  Result main: 60 cards
Saving to: final.cod
✓ Saved successfully

✓ Operations completed successfully
Final deck: 60 cards in main

🐍 Python Library Usage

Use mtgwants as a library in your Python projects:

from mtgwants import Card, Zone, Deck, CockatriceParser

# Create parser
parser = CockatriceParser(sideboard=True)

# Load decks
deck1 = parser.load("deck1.cod")
deck2 = parser.load("deck2.cod")

# Perform operations
combined = deck1 + deck2
needs = deck1 - deck2

# Access card data
for card, quantity in combined.main.items():
    print(f"{quantity}x {card.name}")

# Save result
parser.save(combined, "output.cod", "My Combined Deck")

Core Classes

Card

Represents a Magic: The Gathering card identified by name.

card = Card("Lightning Bolt")
print(card.name)  # "Lightning Bolt"
print(card.is_basic_land)  # False
Zone

A multiset of cards with arithmetic operations (main deck, sideboard, etc.).

zone = Zone({Card("Lightning Bolt"): 4, Card("Counterspell"): 2})
print(len(zone))  # 6 (total cards)
print(zone.unique_cards)  # 2 (different cards)
Deck

Complete deck with main zone and optional sideboard.

main = Zone({Card("Lightning Bolt"): 4})
side = Zone({Card("Counterspell"): 2})
deck = Deck(main, side)

print(deck.has_sideboard)  # True
print(len(deck))  # 6 (main + sideboard)

# Get deck without basic lands
result = deck.nonland_deck
print(result.main_lands)   # number of basic lands removed from main
print(result.side_lands)   # number of basic lands removed from sideboard
print(result.deck)         # filtered Deck
ZoneType

Enum for specifying which zone to operate on.

from mtgwants import ZoneType

deck.get_count(Card("Lightning Bolt"), zone=ZoneType.MAIN)
deck.items(zone=ZoneType.SIDEBOARD)
CockatriceParser

Parser for reading and writing .cod files.

parser = CockatriceParser(sideboard=True)
deck = parser.load("deck.cod")
parser.save(deck, "output.cod", "Deck Name")

🛠️ Technical Details

File Format

Cockatrice .cod files are XML files with the following structure:

<?xml version="1.0"?>
<cockatrice_deck version="1">
    <deckname>My Deck</deckname>
    <comments></comments>
    <zone name="main">
        <card number="4" name="Lightning Bolt"/>
        <card number="2" name="Counterspell"/>
    </zone>
    <zone name="side">
        <card number="3" name="Negate"/>
    </zone>
</cockatrice_deck>

Cardmarket Export Format

The --print option generates output ready for Cardmarket's "Add a Deck List" feature, and automatically copies it to your clipboard:

4 Lightning Bolt
2 Counterspell

// Sideboard
3 Negate

Basic lands (Plains, Island, Swamp, Mountain, Forest, Wastes) are automatically excluded from the output.

After pasting into Cardmarket:

  1. Select all cards → Edit
  2. Set language, condition, and foil preferences
  3. Save your wantslist

Arithmetic Operations

Operations follow mathematical rules:

  • Addition: Combines card quantities

    deck1 = Zone({Card("Bolt"): 2})
    deck2 = Zone({Card("Bolt"): 2})
    result = deck1 + deck2  # {Card("Bolt"): 4}
    
  • Subtraction: Removes cards (negatives become zero)

    deck = Zone({Card("Bolt"): 4})
    owned = Zone({Card("Bolt"): 2})
    needs = deck - owned  # {Card("Bolt"): 2}
    
  • Sequential Operations: Processed in exact command-line order (left to right)

    mtgwants A.cod --add B.cod --sub C.cod --add D.cod
    # Equivalent to: (((A + B) - C) + D)
    

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

🎯 Roadmap

  • Cardmarket API integration (when/if they finally release it to private users)

💡 FAQ

Q: Why "mtgwants"?
A: The tool was originally designed to generate wantslists for Cardmarket by subtracting your collection from target decks.

Q: Does this work with other MTG software?
A: Currently only Cockatrice .cod format is supported. Other formats are planned.

Q: What about the Cardmarket API?
A: Cardmarket's API v3.0 for private users has been "coming soon" since 2021. Until then, use the --print option for manual import.

Q: Can I use this in my own Python project?
A: Absolutely! Import the library and use the Card, Zone, ZoneType, Deck, and CockatriceParser classes.

Q: The clipboard copy didn't work.
A: On some Linux systems you may need to install a clipboard backend: sudo apt install xclip or sudo apt install xsel.

🙏 Acknowledgments

  • Cockatrice - Open source MTG client
  • Cardmarket - European MTG marketplace
  • The Magic: The Gathering community

📞 Contact


⭐ If you find this tool useful, please consider giving it a star on GitHub!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mtgwants-0.1.1.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mtgwants-0.1.1-py3-none-any.whl (14.8 kB view details)

Uploaded Python 3

File details

Details for the file mtgwants-0.1.1.tar.gz.

File metadata

  • Download URL: mtgwants-0.1.1.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for mtgwants-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c396b5807f5fc69196dd2dfd29b3acf06bdc48c81ffdbfc151ed6a9551d0ffbf
MD5 c414499e97ae5deea9776f19733e1fca
BLAKE2b-256 316bb6e4e87b545a722e6f4b793fc81f95a2589ca85948c82caa4159926f8ea4

See more details on using hashes here.

File details

Details for the file mtgwants-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: mtgwants-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 14.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for mtgwants-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 67181ec02a4414962ab4a7f36dc7c72ced4e3f12b9861ec80f917f54805296d6
MD5 a9ad12a0ba3afd991157b7baaaeefd0a
BLAKE2b-256 f99f4cb4515c040a79a54bff916bc675187cf78478a6b6c50496c10f92aa02e1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page