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
Metadata
Release files for ankisync2 0.3.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ankisync2-0.3.0.1.tar.gz | 11.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ankisync2-0.3.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.8 kB
Release files / ankisync2-0.3.0.1.tar.gz
| Download URL | ankisync2-0.3.0.1.tar.gz |
|---|---|
| Size | 11.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4bff7f3774418773b865fbbf6edcab708ddb1121c762caacaa955d7e0f07389
|
|
BLAKE2b-256 checksum How to use checksums |
55bb0a9e17c2a45d5fbca08eb172636ebf5918e236bb81a3e35342a571048b38
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.4 CPython/3.8.6 Windows/10
|
Release files / ankisync2-0.3.0.1-py3-none-any.whl
| Download URL | ankisync2-0.3.0.1-py3-none-any.whl |
|---|---|
| Size | 15.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0e6a056f327f3f8b48e97a2f8df885e171032a5e4445ebb1bc8b31a3e6f2a255
|
|
BLAKE2b-256 checksum How to use checksums |
2424404eeed9cf87faa70f5af082185799e8b233406174294eb2a26df7329fb7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.4 CPython/3.8.6 Windows/10
|