Fresh Cards: under the hood
This page is all about how Fresh Cards works behind the scenes.
- Card and lesson storage
- Freshpack file format
- Text file format
- Open Flashcard format
- Journal sync format
Card and lesson storage
Card and lesson info are stored in the app’s Documents folder. (On iOS, it’s stored in the data folder, which is the parent folder of the Documents folder.) The info about all decks is stored in one SQLite database and each deck gets a separate folder, with its own SQLite database and folders for storing resources and sync data.
More details coming soon. Let me know if you are interested.
Freshpack file format
When you export a deck to Freshpack, a .freshpack file is created. This file is actually just a zip archive. You can use the built-in macOS Archive Utility to unarchive the file. Simply control-click on the .freshpack file and select Open With/Archive Utility. This will unarchive it to a new folder.
Within the folder is a cards.sqlite file and a resources folder. The cards.sqlite file is simply a SQLite database. I recommend using DB Browser for SQLite to view it. There are two tables in the database, a cards table, which is all the cards that were exported. The identifier field is a unique identifier used to look up the card. The resources table contains an entry for each resource that is referenced by a card. Resources are images and audio files.
The resources folder contains all of the image and audio resources. The filename corresponds to the resource entry in the database.
More notes on the DB schema coming soon.
Text file format
Another great option for import is to use a simple text file. If you create a file with the file extension .txt and enter your front and back contents in an alternating format, Fresh Cards will be able to import it just as it does with freshpacks, i.e. you’ll be able to import to a new deck or to an existing deck.
Here’s an example of a short german deck in the front/back alternating format. Note that this format means that each front and back text must not have any newlines. Be sure to leave a space between each front/back combo.
the fall (season) der Herbst the season die Jahreszeit September der September the camp das Zeltlager the daughter die Tochter to wake aufwachen
Keep in mind the file you save to must end in .txt for this to work. The back text is actually optional, so feel free to create front content only if you are okay with a blank back card or you are using cloze deletions.
This is front text and no back text. Apollo 11 landed on the moon in .
You can mix and match cards.
This one has back text as well as front text.
To actually import this file, just drag and drop as you see in the diagram here.
Open Flashcard Format
Fresh Cards also supports a more complex text file format, called Open Flashcard. This file format allows you to specify all the details of a flashcard, including references to image and audio files. The contents can also be zipped up in an archive for easy sharing with others.
As before, to actually import the contents of the text (or zip) file, just drag and drop as you see in the diagram here.
Like the simple text file format, create a file with the file extension .txt. This format is backwards compatible with simple text format but you may optionally use the following attributes on each card:
- id - to specify the unique identifier for the card, in UUID format (ex: A8635303-026F-4F50-9509-393DFE37661C)
- front-text - to specify the front card text
- back-text - to specify the back card text
- level - to specify the level of the card (cards with lower levels are pulled into lessons first)
- tags - to specify a space-separated list of tags
- front-resources - to specify one or more image or audio files for the front card
- back-resources - to specify one or more image or audio files for the back card
To use an attribute, simply start a line in the text file with the attribute name followed by a colon.
front-text: Auf wiedersehen front-resources: auf-wiedersehen.wav back-text: Goodbye front-resources: saturn.jpg Saturn tags: space planets
All of the attributes above are optional. However, it’s recommended that if you plan to share this content with others that you assign an id to all your cards. This will make it easier for Fresh Cards to detect duplicates. (If possible, also name your resource files with a UUID naming scheme. More below.)
Okay, so let’s see more examples:
id: 44723FA2-F278-4190-ABFD-99090849DC50 Apollo 11 landed on the moon on this date July 20, 1969 Who is this man? front-resources: neil-armstrong.jpeg Neil Armstrong # You can even comment out lines using the # character # This is another comment # This example has an image in front and text on the back. If you only have resources on # the front card, you must use back-text otherwise Fresh Cards will think the text # is for the front card. front-resources: gene-kranz.jpeg back-text: Gene Kranz # You can specify multiple tags. You do not need to use hashtags here. This is the fourth planet from the sun. Mars tags: astronomy planets space # Cloze deletions work as they did before. ich habe [Hunger] # It is highly recommended that if you are creating many cards and are planning on # sharing and updating this deck, that you use an id for each card and each resource. id: 3B074CF6-5A45-4B0C-9164-E0ED8422F324 This card has text and resources with uuid filenames front-resources: 033ACA23-E7BA-423E-A2D5-03FEF3BD4643.jpeg 246E0785-A246-450E-8169-F99E160E8C5F.wav back-text: Note that this card has both an image and an audio file # Here's a common example you might use. It specifies an audio file for the front # card and a translation on the back front-resources: auf-wiedersehen.wav back-text: Goodbye! # You can specify a level, this can start at 0 (the default). Cards with lower # get pulled into lessons before cards with higher levels. This is great if you # have hundreds of cards that you wish to learn and want to make sure you focus # on the easier ones first. This is an easy card. level: 0 This is a harder card. level: 10
Resources referenced by the text must be put in a folder called resources. For instance, in the following example, a file called image.jpeg must be in a resources folder that is a sibling to the text file you are dragging in.
This is some front text. front-resources: image.jpeg
If you drag a .txt file for import and it references any resources, the app will launch a File Open dialog on the resources folder. Click ‘Open’ to allow it access to the resources folder. If any resources are not found, Fresh Cards will pop up a friendly error dialog to let you know which ones were not found.
You may use “\n” in the text to indicate a new line should be started.
This is a front card\nwith multiple\n\nlines\nof\ntext And a back card with text is just very long and will end up wrapping This space mission failed to land on the moon but was safely returned to earth. Apollo 13\nLaunched April 11, 1970
Why use identifiers?
If you are planning on sharing your deck with others, adding the id attribute to each card will help make it easier for others to import your deck again and again should you decide to make udpates to it. At the moment, Fresh Cards does a best guess attempt at finding duplicates of cards if you don’t specify an id attribute, but for perfomrnace reasons, it’s not able to do card comparisons when there are images or audio in the cards, unless the cards themselves have an id and the image and audio files have them as well.
To assign ids to resources, simply name them using a UUID, but maintain the file extension. For instance, you might rename a file named sayonara.wav to 457325D0-CBF4-4808-80FC-8943F48275BC.wav. Don’t worry about the file name, users of the card won’t see it anyway.
Fresh Cards will validate the import file as soon as you drag it into the app and will let you know which lines have errors. It won’t let you import until all errors are fixed.
Zipping up the contents
To make it easier to share a deck with others, you can archive the the text file and the resources folder into a .zip file. If you drag and drop the .zip file into the app, it will automatically extract the contents and do a validation. The nice thing about this is it won’t need to ask you for permission to open the resources folder.
If you plan to share your text file and resources in a .zip file, you must name the text file flashcards.txt. If the flashcards.txt file is not found in the .zip file you drag into the app, it won’t know it’s an Open Flashcard archive.
Journal sync format
Fresh Cards uses a journal system for syncing data across devices. What this means is that whenever you do anything to cards or lessons in the app, it gets recorded as an action in a journal for that specific device. For instance, when you finish a lesson, each card’s lesson score is stored as a journal entry. This entry is used to make changes to the data storage for the deck. What future features are you planning?