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
│ ├── collection.anki2
│ ├── collection.anki21 # newer Anki Desktop creates and uses this file instead, while retaining the old one as stub.
│ ├── media # JSON of dict[int, str]
│ ├── 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.
However, internal *.anki2 has recently changed. If you need to edit internally, if maybe safer to do in Anki<=2.1.26. If you have trouble running two Anki versions (latest and 2.1.26), see /__utils__/anki2.1.26.
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 import Apkg
with Apkg("example.apkg") as apkg:
# Or Apkg("example/") also works - the folder named 'example' will be created.
apkg.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.
for card in apkg:
print(card)
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.
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
with Apkg("example.apkg") as apkg:
m = apkg.db.Models.create(name="foo", flds=["field1", "field2"])
d = apkg.db.Decks.create(name="bar::baz")
t = [
apkg.db.Templates.create(name="fwd", mid=m.id, qfmt="{{field1}}", afmt="{{field2}}"),
apkg.db.Templates.create(name="bwd", mid=m.id, qfmt="{{field2}}", afmt="{{field1}}")
]
n = apkg.db.Notes.create(mid=m.id, flds=["data1", "<img src='media.jpg'>"], tags=["tag1", "tag2"])
c = [
apkg.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.export("example1.apkg")
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,
with Apkg("example1.apkg") as apkg:
for n in apkg.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 import DataclassJSONEncoder
import json
json.dumps(dataclassObject, cls=DataclassJSONEncoder)
Editing user's collection.anki2
This can be found at ${ankiPath}/${user}/collection.anki2. Of course, do this at your own risk. Always backup first.
from ankisync2 import AnkiDesktop
AnkiDesktop.backup("/path/to/anki-desktop.db")
anki = AnkiDesktop(filename="/path/to/anki-desktop.db")
... # Edit as you please
AnkiDesktop.restore("/path/to/anki-desktop.db")
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__, and /tests.
Installation
pip install ankisync2
Related projects
Metadata
Release files for ankisync2 0.3.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ankisync2-0.3.4.tar.gz | 16.6 kB | Without provenance | Details for ankisync2-0.3.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ankisync2-0.3.4-py3-none-any.whl | Python 3 | none | any | Details for ankisync2-0.3.4-py3-none-any.whl |
Total release size: 36.0 kB
Release files / ankisync2-0.3.4.tar.gz
| Download URL | ankisync2-0.3.4.tar.gz |
|---|---|
| Size | 16.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d339c70b95ba39d2746c0f9825835354bc9adcde517b10a05380abc7031282d
|
|
BLAKE2b-256 checksum How to use checksums |
556cadcce683ec92c2fee19fa0fc8f3ab9522cd816b3b491db07fdb7774dc26e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.12 CPython/3.10.2 Linux/5.16.5-arch1-1
|
Release files / ankisync2-0.3.4-py3-none-any.whl
| Download URL | ankisync2-0.3.4-py3-none-any.whl |
|---|---|
| Size | 19.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
57343fa0ce2c57166184440c5bf07b16114a5f4f69069eb5c40dd5b2cc84863c
|
|
BLAKE2b-256 checksum How to use checksums |
34c40a4e7b3878a5b5f1ebeec6e0395ad552131c96f1b9f7af066c74666ddc82
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.12 CPython/3.10.2 Linux/5.16.5-arch1-1
|
Security for ankisync2 0.3.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.