Add only-type-any and only-type-all options (#241)
* Added only-type options * added ci test for only-type options
This commit is contained in:
parent
a796dc59bd
commit
088c3b633d
134
domdiv/main.py
134
domdiv/main.py
@ -27,12 +27,6 @@ LINE_CHOICES = ["line", "dot", "cropmarks", "dot-cropmarks"]
|
||||
|
||||
EDITION_CHOICES = ["1", "2", "latest", "all"]
|
||||
|
||||
EXPANSION_CHOICES = ["adventures", "alchemy", "base", "cornucopia", "dark ages",
|
||||
"dominion1stEdition", "dominion2ndEdition", "dominion2ndEditionUpgrade",
|
||||
"empires", "guilds", "hinterlands",
|
||||
"intrigue1stEdition", "intrigue2ndEdition", "intrigue2ndEditionUpgrade",
|
||||
"promo", "prosperity", "renaissance", "seaside", "nocturne"]
|
||||
FAN_CHOICES = ["animals"]
|
||||
ORDER_CHOICES = ["expansion", "global", "colour", "cost"]
|
||||
|
||||
LANGUAGE_DEFAULT = 'en_us' # the primary language used if a language's parts are missing
|
||||
@ -63,6 +57,46 @@ def get_resource_stream(path):
|
||||
return codecs.EncodedFile(pkg_resources.resource_stream('domdiv', path), "utf-8")
|
||||
|
||||
|
||||
def get_expansions():
|
||||
set_db_filepath = os.path.join("card_db", "sets_db.json")
|
||||
with get_resource_stream(set_db_filepath) as setfile:
|
||||
set_file = json.loads(setfile.read().decode('utf-8'))
|
||||
assert set_file, "Could not load any sets from database"
|
||||
|
||||
fan = []
|
||||
official = []
|
||||
for s in set_file:
|
||||
if 'extras' not in s:
|
||||
# Make sure this are set either True or False
|
||||
set_file[s]['fan'] = set_file[s].get('fan', False)
|
||||
if set_file[s]['fan']:
|
||||
fan.append(s)
|
||||
else:
|
||||
official.append(s)
|
||||
fan.sort()
|
||||
official.sort()
|
||||
return official, fan
|
||||
|
||||
|
||||
EXPANSION_CHOICES, FAN_CHOICES = get_expansions()
|
||||
|
||||
|
||||
def get_types(language='en_us'):
|
||||
# get a list of valid types
|
||||
language = language.lower()
|
||||
type_text_filepath = os.path.join("card_db", language, "types_{}.json".format(language))
|
||||
with get_resource_stream(type_text_filepath) as type_text_file:
|
||||
type_text = json.loads(type_text_file.read().decode('utf-8'))
|
||||
assert type_text, "Could not load type file for %r" % language
|
||||
|
||||
types = [x.lower() for x in type_text]
|
||||
types.sort()
|
||||
return types
|
||||
|
||||
|
||||
TYPE_CHOICES = get_types(LANGUAGE_DEFAULT)
|
||||
|
||||
|
||||
# Load Label information
|
||||
LABEL_INFO = None
|
||||
LABEL_CHOICES = []
|
||||
@ -301,8 +335,7 @@ def parse_opts(cmdline_args=None):
|
||||
"'*' any number of characters, '?' matches any single character, "
|
||||
"'[seq]' matches any character in seq, and '[!seq]' matches any character not in seq. "
|
||||
"For example, 'dominion*' will match all expansions that start with 'dominion'. "
|
||||
"Choices available in all languages include: %s" %
|
||||
", ".join("%s" % x for x in EXPANSION_CHOICES))
|
||||
"Choices available in all languages include: {}".format(", ".join("%s" % x for x in EXPANSION_CHOICES)))
|
||||
group_select.add_argument(
|
||||
"--fan",
|
||||
nargs="*",
|
||||
@ -316,8 +349,7 @@ def parse_opts(cmdline_args=None):
|
||||
"Values are not case sensitive. Wildcards may be used: "
|
||||
"'*' any number of characters, '?' matches any single character, "
|
||||
"'[seq]' matches any character in seq, and '[!seq]' matches any character not in seq. "
|
||||
"Choices available in all languages include: %s" %
|
||||
", ".join("%s" % x for x in FAN_CHOICES))
|
||||
"Choices available in all languages include: {}".format(", ".join("%s" % x for x in FAN_CHOICES)))
|
||||
group_select.add_argument(
|
||||
"--edition",
|
||||
choices=EDITION_CHOICES,
|
||||
@ -373,6 +405,27 @@ def parse_opts(cmdline_args=None):
|
||||
"--exclude-landmarks",
|
||||
action="store_true",
|
||||
help="Group all 'Landmark' cards across all expansions into one divider.")
|
||||
group_select.add_argument(
|
||||
"--only-type-any", "--only-type", "--type-any",
|
||||
nargs="*",
|
||||
action="append",
|
||||
dest="only_type_any",
|
||||
help="Limit dividers to only those with the specified types. "
|
||||
"A divider is kept if ANY of the provided types are associated with the divider. "
|
||||
"Default is all types are included. "
|
||||
"Any type with a space in the name must be enclosed in double quotes. "
|
||||
"Values are not case sensitive. "
|
||||
"Choices available in all languages include: {}".format(", ".join("%s" % x for x in TYPE_CHOICES)))
|
||||
group_select.add_argument(
|
||||
"--only-type-all", "--type-all",
|
||||
nargs="*",
|
||||
action="append",
|
||||
dest="only_type_all",
|
||||
help="Limit dividers to only those with the specified types. "
|
||||
"A divider is kept if ALL of the provided types are associated with the divider. "
|
||||
"Any type with a space in the name must be enclosed in double quotes. "
|
||||
"Values are not case sensitive. "
|
||||
"Choices available in all languages include: {}".format(", ".join("%s" % x for x in TYPE_CHOICES)))
|
||||
|
||||
# Divider Sleeves/Wrappers
|
||||
group_wrapper = parser.add_argument_group(
|
||||
@ -633,6 +686,20 @@ def clean_opts(options):
|
||||
# keyword to indicate no options. Same as --fan without any expansions given
|
||||
options.fan = []
|
||||
|
||||
if options.only_type_any is None:
|
||||
# No instance given, so default to empty list
|
||||
options.only_type_any = []
|
||||
else:
|
||||
# options.only_type_any is a list of lists. Reduce to single lowercase list
|
||||
options.only_type_any = list(set([item.lower() for sublist in options.only_type_any for item in sublist]))
|
||||
|
||||
if options.only_type_all is None:
|
||||
# No instance given, so default to empty list
|
||||
options.only_type_all = []
|
||||
else:
|
||||
# options.only_type_any is a list of lists. Reduce to single lowercase list
|
||||
options.only_type_all = list(set([item.lower() for sublist in options.only_type_all for item in sublist]))
|
||||
|
||||
if options.tabs_only and options.label_name is None:
|
||||
# default is Avery 8867
|
||||
options.label_name = "8867"
|
||||
@ -1359,6 +1426,53 @@ def filter_sort_cards(cards, options):
|
||||
card_tag=set_tag)
|
||||
cards.append(c)
|
||||
|
||||
# Take care of any --only-type-xxx requirements
|
||||
if options.only_type_any or options.only_type_all:
|
||||
# First make a dictionary for easier lookup of Type name used by the program
|
||||
# The index in each case is lower case for easier matching
|
||||
# The value in each case is the type index as used in types_en_us.json
|
||||
types_lookup = defaultdict(dict)
|
||||
for x in Card.type_names:
|
||||
types_lookup[x.lower()] = x
|
||||
types_lookup[Card.type_names[x].lower()] = x
|
||||
|
||||
# Start the valid lists
|
||||
type_unknown = []
|
||||
type_known_any = []
|
||||
type_known_all = []
|
||||
|
||||
# Assemble a list of valid "any" types. Options are already lowercase.
|
||||
for x in options.only_type_any:
|
||||
if x in types_lookup:
|
||||
type_known_any.append(types_lookup[x])
|
||||
else:
|
||||
type_unknown.append(x)
|
||||
|
||||
# Assemble a list of valid "all" types. Options are already lowercase.
|
||||
for x in options.only_type_all:
|
||||
if x in types_lookup:
|
||||
type_known_all.append(types_lookup[x])
|
||||
else:
|
||||
type_unknown.append(x)
|
||||
|
||||
# Indicate if unknown types are given
|
||||
assert not type_unknown, "Error - unknown type(s): {}".format(", ".join(type_unknown))
|
||||
|
||||
# If there are any valid Types left, go through the cards and keep cards that match
|
||||
if type_known_any or type_known_all:
|
||||
keep_cards = []
|
||||
for c in cards:
|
||||
if type_known_any and any(x in c.types for x in type_known_any):
|
||||
keep_it = True
|
||||
elif type_known_all and all(x in c.types for x in type_known_all):
|
||||
keep_it = True
|
||||
else:
|
||||
keep_it = False
|
||||
|
||||
if keep_it:
|
||||
keep_cards.append(c)
|
||||
cards = keep_cards
|
||||
|
||||
# Now sort what is left
|
||||
cards.sort(key=cardSorter)
|
||||
|
||||
|
||||
@ -111,3 +111,19 @@ def test_languagetool_run(pytestconfig):
|
||||
except subprocess.CalledProcessError as e:
|
||||
assert e.output == ''
|
||||
assert out.decode('utf-8') == ''
|
||||
|
||||
|
||||
def test_only_type():
|
||||
options = main.parse_opts(['--expansions', 'base', 'alchemy',
|
||||
'--include-blanks', '5',
|
||||
'--only-type-any', 'blank', 'curse',
|
||||
'--only-type-all', 'attack', 'action'])
|
||||
options = main.clean_opts(options)
|
||||
options.data_path = '.'
|
||||
cards = main.read_card_data(options)
|
||||
cards = main.filter_sort_cards(cards, options)
|
||||
# Total 8 from
|
||||
# Blank: +5 added in options
|
||||
# Curse: +1 from base
|
||||
# Action Attack: +2 from Alchemy
|
||||
assert len(cards) == 8
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user