Skip to content

Commit

Permalink
Merge pull request #6 from pablerass/feature/multiple-backs
Browse files Browse the repository at this point in the history
Allow definition of multiple back images
  • Loading branch information
pablerass authored Nov 19, 2023
2 parents 7273850 + 870a44c commit 382c53b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 37 deletions.
90 changes: 56 additions & 34 deletions cartuli/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from multiprocessing import Pool, cpu_count
from pathlib import Path

from .card import Card, CardImage
from .card import CardImage, Card
from .deck import Deck
from .filters import Filter, NullFilter, from_dict as filter_from_dict
from .measure import Size, from_str
Expand All @@ -21,6 +21,10 @@
CardsFilter = Callable[[Path], bool]


class DefinitionError(Exception):
pass


class Definition:
"""Definition."""

Expand Down Expand Up @@ -67,49 +71,67 @@ def decks(self) -> list[Deck]:
self.__decks = []
for name, deck_definition in self.__values.get('decks', {}).items():
logger.debug(f"Deck '{name}' definition {deck_definition}")
self.__decks.append(self._create_deck(deck_definition, name))
self.__decks.append(self._load_deck(deck_definition, name))
if not self.__decks:
logger.warning('No decks loaded in definition')

return self.__decks

def _create_deck(self, definition: dict, name: str) -> Deck:
def _load_images(self, images_definition: dict, size: Size, deck_name: str, side: str = 'front') -> list[CardImage]:
logger = logging.getLogger('cartuli.definition.Definition.decks')

image_filter = images_definition.get('filter', '')
image_files = sorted(glob(images_definition['images']))
logger.debug(f"Found {len(image_files)} {side} images for '{deck_name}' deck")
with Pool(processes=cpu_count() - 1) as pool:
images = pool.map(
self.filters[image_filter].apply,
(CardImage(
path, size=size,
bleed=from_str(images_definition.get('bleed', str(CardImage.DEFAULT_BLEED))),
name=Path(path).stem
) for path in image_files if self.__cards_filter(path))
)
if len(image_files) != len(images):
logger.debug(f"{side.capitalize()} images filterd from {len(image_files)} to "
f" {len(images)} for '{deck_name}' deck")

return images

def _load_deck(self, definition: dict, name: str) -> Deck:
logger = logging.getLogger('cartuli.definition.Definition.decks')

size = Size.from_str(definition['size'])
front_images = []
cards = []

if 'front' in definition:
front_filter = definition['front'].get('filter', '')
front_image_files = sorted(glob(definition['front']['images']))
logger.debug(f"Found {len(front_image_files)} front images for '{name}' deck")
with Pool(processes=cpu_count() - 1) as pool:
front_images = pool.map(
self.filters[front_filter].apply,
(CardImage(
path, size=size,
bleed=from_str(definition['front'].get('bleed', str(CardImage.DEFAULT_BLEED))),
name=Path(path).stem
) for path in front_image_files if self.__cards_filter(path))
)
if len(front_image_files) != len(front_images):
logger.debug(f"Front images filterd from {len(front_image_files)} to "
f" {len(front_images)} for '{name}' deck")
back_image = None
if 'back' in definition:
back_image_file = definition['back']['image']
if self.__cards_filter(back_image_file):
back_filter = definition['back'].get('filter', '')
back_image = self.filters[back_filter].apply(
CardImage(
definition['back']['image'],
size=size,
bleed=from_str(definition['back'].get('bleed', str(CardImage.DEFAULT_BLEED))),
name=Path(back_image_file).stem
)
)
front_images = self._load_images(definition['front'], size, name, 'front')
if 'back' in definition:
back_images = self._load_images(definition['back'], size, name, 'back')
if len(front_images) != len(back_images):
raise DefinitionError(f"The number of front ({len(front_images)}) and "
f"back ({len(back_images)}) images must be the same")
cards = [Card(front_image, back_image) for front_image, back_image in zip(front_images, back_images)]
else:
logger.debug(f"Back image '{back_image_file}' filtered for '{name}' deck")
return Deck((Card(image) for image in front_images), default_back=back_image, size=size, name=name)
cards = [Card(image) for image in front_images]

if not cards:
logger.warning(f"No cards found for deck {name} with specified fiters")

default_back = None
if 'default_back' in definition:
default_back_file = definition['default_back']['image']
default_back_filter = definition['default_back'].get('filter', '')
default_back = self.filters[default_back_filter].apply(
CardImage(
default_back_file,
size=size,
bleed=from_str(definition['default_back'].get('bleed', str(CardImage.DEFAULT_BLEED))),
name=Path(default_back_file).stem
)
)

return Deck(cards, name=name, default_back=default_back, size=size)

@property
def sheets(self) -> dict[tuple[str], Sheet]:
Expand Down
2 changes: 1 addition & 1 deletion tests/files/simple-cartulifile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ decks:
size: "STANDARD"
front:
images: "cards/*.png"
back:
default_back:
image: "card-back.png"
outputs:
sheet:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test_file(fixture_file):
'front': {
'images': "cards/*.png"
},
'back': {
'default_back': {
'image': "card-back.png"
}
}
Expand Down Expand Up @@ -76,7 +76,7 @@ def test_definition(random_image_file):
'images': str(random_image_dir / "*.png"),
'bleed': '2*mm'
},
'back': {
'default_back': {
'image': str(random_image_file("back"))
}
}
Expand Down

0 comments on commit 382c53b

Please sign in to comment.