cubescripts/cubedeck.py
2023-04-25 00:49:01 -04:00

163 lines
4.1 KiB
Python

# Setup:
# 1. Download cube list .txt from CubeCobra's export to .txt function
# 2. (Windows, non-WSL only) Install pyreadline3
#
# Usage:
# $ python3 cubedeck.py MyCubeList.txt
#
# Enter card: Mo [tab]
# Mogg War Marshal Moment's Peace Monastery Swiftspear Mortarpod Mountain
# Moldervine Cloak Momentary Blink Monoskelion Mortify
#
# Enter card: Moldervine Cloak
#
# Enter card: Moment's Peace
#
# Enter card: Momentary Blink
#
# Enter card: :u # Undo last card added (Momentary Blink)
#
# Enter card: :nl # Add empty line to separate sideboard
#
# Enter card: Monoskelion
#
# Enter card: 10 Forest # autocomplete doesn't work with number
#
# Enter card: :ls # List deck input so far
# ['Moldervine Cloak', 'Moment's Peace', '', 'Monoskelion', '10 Forest']
#
# Enter card: :wq # Save to file and open in default application
# Saved deck to 20230425-001458.txt
#
# Enter card: :q # Exit without saving
from datetime import datetime
import os
import platform
import readline
import sys
import subprocess
def load_cube(cube_file):
cube = []
with open(cube_file) as f:
for line in f:
card = line.strip()
if card:
cube.append(card)
return cube
BASIC_LANDS = ['Plains', 'Island', 'Swamp', 'Mountain', 'Forest']
CUBE_CARDS = load_cube(sys.argv[1])
CARDS = BASIC_LANDS + CUBE_CARDS
CARDS_LOWER = {card.lower(): card for card in CARDS}
def open_file_with_default(file):
if platform.system() == 'Darwin': # macOS
subprocess.call(('open', file))
elif platform.system() == 'Windows': # Windows
os.startfile(file)
else: # linux variants
if 'microsoft' in platform.uname().release.lower():
subprocess.call(('wslview', file)) # WSL
else:
subprocess.call(('xdg-open', file)) # Actual linux
def enable_autocomplete():
if readline.__doc__ is not None and 'libedit' in readline.__doc__:
readline.parse_and_bind("bind ^I rl_complete") # macOS
else:
readline.parse_and_bind("tab: complete")
def card_completer(text, state):
text_to_complete = readline.get_line_buffer().lower()
options = [CARDS_LOWER[i] for i in CARDS_LOWER if i.startswith(text_to_complete)]
if state < len(options):
return options[state][readline.get_begidx():]
else:
return None
def add_card(deck, card):
count_str = None
card_to_check = card
if card[0].isdigit():
parts = card.split(' ', 1)
if len(parts) > 1 and parts[0].isdigit():
count_str = parts[0]
card_to_check = parts[1]
card_canon = card_to_check.lower()
if card_canon not in CARDS_LOWER:
yn = input('"%s" not in cardlist. Are you sure you want to add it to the deck? ' % card_to_check)
if not yn.strip().startswith('y'):
print('Not added.')
return
add_card_with_count(deck, card_canon, count_str)
def add_card_with_count(deck, card_canon, count_str):
card = CARDS_LOWER.get(card_canon, card_canon)
if count_str is None:
deck.append(card)
else:
deck.append('%s %s' % (count_str, card))
def add_delimiter(deck):
deck.append('')
def remove_last_card(deck):
if len(deck) == 0:
print('Empty deck, cannot delete.')
return
deck.pop()
def save_deck(deck):
file_name = datetime.today().strftime('%Y%m%d-%H%M%S') + '.txt'
with open(file_name, 'w') as f:
for card in deck:
f.write(card)
f.write('\n')
print('Saved deck to %s' % file_name)
open_file_with_default(file_name)
if __name__ == '__main__':
deck = []
enable_autocomplete()
readline.set_completer(card_completer)
readline.set_completer_delims('')
while True:
command = input('Enter card: ').strip()
if command == '':
continue
if command == ':q':
print('Exiting without saving.')
exit(0)
elif command == ':wq':
save_deck(deck)
exit(0)
elif command == ':l':
print(deck)
elif command == ':nl':
add_delimiter(deck)
elif command == ':u':
remove_last_card(deck)
elif command.startswith(':'):
print('Unrecognized command "%s"' % command)
else:
add_card(deck, command)