Skip to content

RobertSchueler/tc_tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tc_tools

Support for automatic generation of trading cards

This repository will be filled slowly with python code aiming to provide easy generation of trading cards using the commonly known tools Inkscape and Excel. I aim to work 1 to 2 hours each monday in my free time on this project, but some mondays have to be skipped when I want to do other stuff. If you are interested in this project growing faster, consider to create a PR by yourself ;). I already had a repository tc_tools, but deleted that since it was more of a collection of prototypes and I want to do it more "properly" this time. If you have ideas or you see bugs/problems with the project, feel free to create an issue on Github.

The Vision

The big idea is, that the generation of custom cardgames will be made easier.

  • If you are not affine to IT you should be able to describe your custom card game using an svg template (generated by hand with Inkscape) an Excel sheet and maybe a configuration textfile and then just run tc_tools from command line or using a leightweight GUI to generate your custom cardgame (or customizable example cardgames if necessary).
  • If you want to add some logic which is not supported by the command line/GUI you should be able to import tc_tools into your own Python project and use some dedicated objects in order to implement your custom logic fast and easy

How to use

The only way to already use the project is to clone or download it on a computer with a local python instalation (I use Python 3.10.7) and run gui/window.py using your local python for the GUI.

When you open the GUI you should see something like this:

guiv0 1 0snippet

Then just pick your Excel file, your template SVG and your configuration file and press "Render deck" and it will run :).

The Excel file should contain rowwise information about all your cards.

The SVG file should contain a template of how your cards should look like.

The processor then does roughly the following to your template svg for each row of the excel file:

  • replaces the path to an image labeled "image_label" by the respective content of the column named "image_label" or "image_label.href" (since 0.2.0)
  • replaces the text content of a text element labeled "text_label" by the respective content of the column named "text_label" or "text_label.text" (since 0.3.0)

Be careful with your labels, don't let two columns refer to the same object and don't label two objects the same.

The configuration file contains information about your system and your preferences by lines of the form <parameter>:<value>. The only supported parameter is currently inkscape_path which is mandatory to set to the absolute path of your local inkscape installation.

Currently it is only possible to replace images as you like. More possibilities will come in the future.

How to customize

You can run processor.base_process(options_path, excel_path, svg_path, single_item_process) with a custom method single_item_process(svg_root: SVGRoot, data: dict) -> None which should manipulate the svg_root object based on the data in data representing a row of the Excel file. The following functions are supported by `tc_tools``:

  • Use svg_element = svg_root.get_by_label(label) -> SVGElement to get an SVGElement object corresponding to an inkscape object labeled with label (since 0.2.0)
  • Use svg_element.get_label and svg_element.set_label refering to the inkscape labels (since 0.2.0)
  • If svg_element is an SVGImage, use svg_element.get_href and svg_element.set_href (since 0.2.0)
  • If svg_element is an SVGText, use svg_element.get_text_content and svg_element.set_text_content (since 0.3.0)

Technical Details

The project has the following dependencies (with the version used in development, others probably also work)

  • pandas 2.0.3 (for excel reading)
  • PySimpleGUI 4.60.5 (for GUI)
  • matplotlib 3.8.0 (for image comparison when testing)

For different components of an SVG, there should be different custom SVG objects yielding the same structure.

I plan to structure the process in a kind-of layered fashion involving the following layers (moduls):

  • persistence: read data from disk and save data to disk
    • create ElementTree from svg
    • create svg from ElementTree
    • render svg to png or pdf (using Inkscape as "man in the middle")
    • read an excel file and create a respective data source object
  • mapper: extract and transform data types into others
    • extract custom SVG object structure from ElementTree
    • copy custom SVG object structure
    • merge custom SVG object and ElementTree to ElementTree
  • manipulator: change custom SVG objects
    • move, rotate, align elements etc.

In a later stage of the project, I possibly will add another layer between mapper and manipulator for png manipulation.

Another module, the processor module should then control the data flow between the layers and itself be called by the gui (later maybe also by the command_line). Here is a diagram, because diagrams are cool:

module_diagram

Git/Merging strategie

  • the main branch is a version branch and therefore only updated when a new version is released
  • hot fixes will be commited to the main branch directly
  • the future branch contains the current WIP state of the next bigger version
  • If you want to contribute you can create a PR to the future branch that realizes one of the points of the next section
  • I want a linear git history, so everything should be rebased before a fast forward merge is performed
  • The versioning will be according to standard practices
    • changes to README.md and other supplementary files do not result in a version change
    • hot fixes lead to a increase of the last version number, e.g. 0.0.0 -> 0.0.1
    • the merge of the future branch into main will result in an increase of the second version number, e.g. 0.0.99 -> 0.1.0
    • If all milestones are reached, the first version number is increased, e.g. 0.99.99 -> 1.0.0. Note that all deprecated features are removed in such a major change, so versions with a different first version number might not be compatible
  • I want to refine the application feature by feature in a kind-of agile process (every in-between version should be running)

Other design decision

  • tests of behaviour for all methods (created while implementing)
  • no tests of implementation
  • no useless documentation in code
  • make it typesafe
  • in the directory manual_tests there are additional non-automatic tests. These require a suitable local setup with inkscape up and running. You can check this out for more information.
  • the GUI is not automatically tested but just checked manually

Milestones for version 1.0.0

  • Support for Text, Image, Rectangle, Groups
  • Text content can be changed
  • Image can be switched
  • SVG root can be searched for elements by label, text content
  • Elements can be repositioned, resized, rotated and reflected
  • Font-family, font-size and font-weight can be changed
  • Example Projects: Domino and Skat

Plan going forward (to version 0.4.0)

Next I will work on a whole bunch of geometric operations

  • Create and map position attributes
  • Create and map scaling attributes
  • Create and map rotation attributes
  • Create and map reflection attributes
  • Add manual test for geometric operations

Progress resulting in version 0.3.0

  • Create SVGText representing Texts on SVGElement level
  • Map inkscape text objects to SVGText
  • Map SVGText back
  • Let processor map columns linked to text objects replace the text content
  • Create manual tests for that

In version 0.3.0 you are able to replace the text of your cards

Progress resulting in version 0.2.0

  • save inkscape labels when mapping to SVGRoot
  • make SVGRoot searchable by inkscape labels
  • create an SVGElement representing an image with property href
  • map images of the ElementTree to SVGElement images
  • support the mapping of changed href properties
  • make controller to identify excel columns of form <label>.href and change the href property of element with respective inkscape label if it is an image (otherwise throw exception).
  • create SVGCollection for SVG Elements with children
  • map Elements with children to SVGCollection and its children recursively
  • recursively map Elements back
  • add support for recursively found label
  • make manual tests for new behaviour
  • make a domino example project of domino, where the background the separating image and the images used for the dots can be customized (will do example projects later)

In version 0.2.0 you are able to exchange pictures in your card making.

Progress resulting in version 0.1.0

  • create the base module structure
  • implement a method that reads an svg and creates an ElementTree object
  • implement a method that writes an svg from an ElementTree object
  • implement a method that calls Inkscape to create a png from ElementTree
  • implement a basic data source object
  • implement a method that creates data source object from excel sheet
  • implement root SVG object (allowing children to be mapped)
  • implement placeholder SVG object (for unknown svg elements)
  • implement a mapper from ElementTree to root SVG
  • implement a simple mapper mapping Element and placeholder SVG object to Element
  • implement a simple mapper mapping ElementTree object and root SVG object to ElementTree object
  • implement base processor method combining all the previous steps
  • create GUI window
  • add three file picker to GUI named
  • add labels for the three file picker (excel sheet, template, options)
  • add button labeled "render deck"
  • add processor call to button
  • implement command line integration (scraped since it was not as easy and fun to get a first running solution and does not seem to be necessary, maybe will do later)

The resulting version is relatively useless since it only produces copies of the same png. But everything is in place, so it will hopefully be a good starting point for future features.

Feature Wishlist

  • command line interface

Technical Wishlist

  • pipeline
  • PiPy publishing
  • add a single executable to published versions
  • overhaul package structure to be more pythonic