Creating and editing *.apkg and *.anki2 safely
Project description
AnkiSync 2
*.apkg and *.anki2 file structure is very simple, but with some quirks of incompleteness.
*.apkg file structure is a zip of at least two files.
.
├── example
│ ├── example.anki2
│ ├── media
│ ├── 1 # Media files with the names masked as integers
│ ├── 2
│ ├── 3
| └── ...
└── example.apkg
*.anki2 is a SQLite file with foreign key disabled, and the usage of some JSON schemas instead of some tables
Also, *.anki2 is used internally at os.path.join(appdirs.user_data_dir('Anki2'), 'User 1', 'collection.anki2'), so editing the SQLite there will also edit the database.
The media file is a text file of at least a string of {}, which is actually a dictionary of keys -- stringified int; and values -- filenames.
Usage
Some extra tables are created if not exists.
from ankisync2.apkg import Apkg, db
apkg = Apkg("example.apkg") # Or Apkg("example/") also works, otherwise the folder named 'example' will be created.
db.database.execute_sql(SQL, PARAMS)
apkg.zip(output="example1.apkg")
I also support adding media.
apkg.add_media("path/to/media.jpg")
To find the wanted cards and media, iterate though the Apkg and Apkg.iter_media object.
iter_apkg = iter(apkg)
for i in range(5):
print(next(iter_apkg))
Creating a new *.apkg
You can create a new *.apkg via Apkg with any custom filename (and *.anki2 via Anki2()). A folder required to create *.apkg needs to be created first.
from ankisync2.apkg import Apkg
apkg = Apkg("example") # Create example folder
After that, the Apkg will require at least 1 card, which is connected to at least 1 note, 1 model, 1 template, and 1 deck; which should be created in this order.
- Model, Deck
- Template, Note
- Card
from ankisync2.apkg import db
m = db.Models.create(name="foo", flds=["field1", "field2"])
d = db.Decks.create(name="bar::baz")
t = [
db.Templates.create(name="fwd", mid=m.id, qfmt="{{field1}}", afmt="{{field2}}"),
db.Templates.create(name="bwd", mid=m.id, qfmt="{{field2}}", afmt="{{field1}}")
]
n = db.Notes.create(mid=m.id, flds=["data1", "<img src='media.jpg'>"], tags=["tag1", "tag2"])
c = [
db.Cards.create(nid=n.id, did=d.id, ord=i)
for i, _ in enumerate(t)
]
You can also add media, which is not related to the SQLite database.
apkg.add_media("path/to/media.jpg")
Finally, finalize with
apkg.zip(output="example1.apkg")
apkg.close()
Updating an *.apkg
This is also possible, by modifying db.Notes.data as sqlite_ext.JSONField, with peewee.signals.
It is now as simple as,
from ankisync2.apkg import Apkg, db
apkg = Apkg("example1.apkg")
for n in db.Notes.filter(db.Notes.data["field1"] == "data1"):
n.data["field3"] = "data2"
n.save()
apkg.close()
JSON schema of Col.models, Col.decks, Col.conf and Col.dconf
I have created dataclasses for this at /ankisync2/builder.py. To serialize it, use dataclasses.asdict or
from ankisync2.util import DataclassJSONEncoder
import json
json.dumps(dataclassObject, cls=DataclassJSONEncoder)
Editing user's collection.anki2
This can be found at ${ankiPath}/${user}/collection.anki2, but you might need ankisync2.anki21 package, depending on your Anki version. Of course, do this at your own risk. Always backup first.
from ankisync2.anki21 import db
from ankisync2.dir import get_anki_collection
db.database.init(get_anki_collection("User 1"))
Using peewee framework
This is based on peewee ORM framework. You can use Dataclasses and Lists directly, without converting them to string first.
Examples
Please see /examples, /scripts and /tests.
Installation
pip install ankisync2
Related projects
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ankisync2-0.3.0.1.tar.gz.
File metadata
- Download URL: ankisync2-0.3.0.1.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.4 CPython/3.8.6 Windows/10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4bff7f3774418773b865fbbf6edcab708ddb1121c762caacaa955d7e0f07389
|
|
| MD5 |
0b88261c5a8e9ef16a4f403b3d89af5c
|
|
| BLAKE2b-256 |
55bb0a9e17c2a45d5fbca08eb172636ebf5918e236bb81a3e35342a571048b38
|
File details
Details for the file ankisync2-0.3.0.1-py3-none-any.whl.
File metadata
- Download URL: ankisync2-0.3.0.1-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.4 CPython/3.8.6 Windows/10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e6a056f327f3f8b48e97a2f8df885e171032a5e4445ebb1bc8b31a3e6f2a255
|
|
| MD5 |
d0ae62060bdec790d68bf96040887b88
|
|
| BLAKE2b-256 |
2424404eeed9cf87faa70f5af082185799e8b233406174294eb2a26df7329fb7
|