├── src ├── djankiserv │ ├── __init__.py │ └── assets │ │ ├── jsonfiles │ │ ├── __init__.py │ │ ├── default_deck.json │ │ ├── default_collection_conf.json │ │ ├── default_deck_conf.json │ │ └── default_model.json │ │ └── sql │ │ └── sqlite3 │ │ ├── __init__.py │ │ ├── init_col_table.sql │ │ └── add_indices.sql ├── djankiserv_api │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── views │ │ ├── health.py │ │ ├── __init__.py │ │ ├── models.py │ │ ├── tags.py │ │ ├── decks.py │ │ └── notes.py │ ├── wsgi.py │ ├── apps.py │ ├── signals.py │ └── urls.py ├── djankiserv_cli │ ├── __init__.py │ ├── __main__.py │ └── manage.py ├── djankiserv_utils │ ├── logger.py │ └── __init__.py ├── requirements.mariadb.txt ├── requirements.postgres.txt ├── requirements.txt └── djankiserv_sync │ ├── views │ └── __init__.py │ ├── dependencies.py │ └── urls.py ├── tests └── assets │ ├── __init__.py │ ├── api │ ├── __init__.py │ ├── tags.json │ ├── new_notes.json │ ├── two_notes.json │ ├── decks.json │ └── decks_conf.json │ ├── up │ ├── __init__.py │ ├── modify_deck_conf │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── pre_applyChunk.json │ │ ├── post_start.json │ │ ├── pre_start.json │ │ ├── post_applyChanges.txt │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ ├── post_applyChanges.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_sanityCheck2.json │ │ └── pre_applyChanges.txt │ ├── one_note_w_media │ │ ├── pre_begin.json │ │ ├── post_upload.txt │ │ ├── pre_mediaChanges.json │ │ ├── pre_mediaSanity.json │ │ ├── post_mediaChanges.json │ │ ├── post_mediaChanges.txt │ │ ├── post_mediaSanity.json │ │ ├── post_mediaSanity.txt │ │ ├── post_uploadChanges.txt │ │ ├── post_begin.txt │ │ ├── post_uploadChanges.json │ │ ├── pre_mediaChanges.txt │ │ ├── pre_mediaSanity.txt │ │ ├── post_begin.json │ │ ├── pre_upload.bin │ │ ├── post_upload.bin │ │ ├── pre_uploadChanges.bin │ │ ├── pre_begin.txt │ │ └── pre_upload.sql │ ├── two_notes_one_added │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── pre_mediaSanity.json │ │ ├── post_sanityCheck2.json │ │ ├── pre_mediaChanges.json │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.txt │ │ ├── post_mediaChanges.json │ │ ├── post_mediaChanges.txt │ │ ├── post_mediaSanity.json │ │ ├── post_mediaSanity.txt │ │ ├── post_uploadChanges.txt │ │ ├── post_start.txt │ │ ├── post_start.json │ │ ├── post_applyChanges.txt │ │ ├── post_begin.txt │ │ ├── pre_start.json │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ ├── post_uploadChanges.json │ │ ├── pre_mediaSanity.txt │ │ ├── pre_mediaChanges.txt │ │ ├── post_begin.json │ │ ├── post_applyChanges.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_uploadChanges.bin │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.json │ │ ├── pre_applyGraves.txt │ │ ├── pre_sanityCheck2.json │ │ ├── pre_applyChunk.txt │ │ ├── pre_applyChunk.json │ │ └── pre_applyChanges.txt │ ├── new_deck_one_new_card │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── post_start.json │ │ ├── pre_start.json │ │ ├── post_applyChanges.txt │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ ├── post_begin.txt │ │ ├── post_applyChanges.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── post_begin.json │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_applyGraves.json │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_sanityCheck2.json │ │ ├── pre_applyChunk.txt │ │ ├── pre_applyChunk.json │ │ └── pre_applyChanges.txt │ ├── rem_new_deck_one_new_card │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── post_start.json │ │ ├── post_applyChanges.txt │ │ ├── pre_start.json │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ ├── post_begin.txt │ │ ├── post_applyChanges.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── post_begin.json │ │ ├── pre_begin.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_sanityCheck2.json │ │ ├── pre_applyGraves.json │ │ ├── pre_applyChanges.txt │ │ └── pre_applyChanges.json │ ├── two_notes_two_studied │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── post_start.json │ │ ├── post_begin.txt │ │ ├── pre_start.json │ │ ├── post_applyChanges.txt │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ ├── post_begin.json │ │ ├── pre_applyGraves.json │ │ ├── post_applyChanges.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_sanityCheck2.json │ │ ├── pre_applyChunk.txt │ │ └── pre_applyChanges.txt │ ├── one_note_delete_unused_media │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── pre_mediaSanity.json │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── pre_mediaChanges.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_mediaChanges.json │ │ ├── post_mediaSanity.json │ │ ├── post_mediaChanges.txt │ │ ├── post_mediaSanity.txt │ │ ├── post_start.txt │ │ ├── post_uploadChanges.txt │ │ ├── post_begin.txt │ │ ├── post_start.json │ │ ├── post_chunk.txt │ │ ├── pre_start.json │ │ ├── post_chunk.json │ │ ├── post_uploadChanges.json │ │ ├── pre_mediaSanity.txt │ │ ├── pre_mediaChanges.txt │ │ ├── post_begin.json │ │ ├── pre_applyGraves.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_uploadChanges.bin │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyChanges.json │ │ ├── pre_applyChanges.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_sanityCheck2.json │ │ ├── post_applyChanges.txt │ │ ├── pre_uploadChanges.txt │ │ └── post_applyChanges.json │ └── start_two_notes_delete_one │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── post_start.json │ │ ├── post_begin.txt │ │ ├── pre_start.json │ │ ├── post_applyChanges.txt │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ ├── post_begin.json │ │ ├── post_applyChanges.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyGraves.json │ │ ├── pre_sanityCheck2.json │ │ ├── pre_applyChanges.txt │ │ └── pre_applyChanges.json │ ├── down │ ├── __init__.py │ ├── modify_deck_conf │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── pre_applyChunk.json │ │ ├── post_start.json │ │ ├── post_chunk.txt │ │ ├── pre_start.json │ │ ├── post_chunk.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_sanityCheck2.json │ │ ├── pre_applyChanges.txt │ │ ├── post_applyChanges.txt │ │ └── pre_applyChanges.json │ ├── one_note_w_media │ │ ├── pre_begin.json │ │ ├── pre_download.json │ │ ├── pre_mediaSanity.json │ │ ├── pre_mediaChanges.1.json │ │ ├── pre_mediaChanges.json │ │ ├── post_mediaSanity.json │ │ ├── post_mediaChanges.1.json │ │ ├── post_mediaChanges.1.txt │ │ ├── post_mediaSanity.txt │ │ ├── pre_downloadFiles.json │ │ ├── post_begin.txt │ │ ├── pre_mediaSanity.txt │ │ ├── pre_mediaChanges.1.txt │ │ ├── pre_mediaChanges.txt │ │ ├── pre_downloadFiles.txt │ │ ├── post_begin.json │ │ ├── post_mediaChanges.txt │ │ ├── post_download.bin │ │ ├── post_downloadFiles.bin │ │ ├── pre_begin.txt │ │ ├── pre_download.txt │ │ └── post_mediaChanges.json │ ├── new_deck_one_new_card │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── pre_start.json │ │ ├── post_begin.txt │ │ ├── post_start.json │ │ ├── pre_applyGraves.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── post_begin.json │ │ ├── pre_begin.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyChanges.json │ │ ├── pre_applyChanges.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_sanityCheck2.json │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ └── post_applyChanges.txt │ ├── two_notes_one_added │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── pre_mediaChanges.json │ │ ├── pre_mediaSanity.json │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── pre_mediaChanges.1.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_mediaChanges.1.json │ │ ├── post_mediaSanity.json │ │ ├── post_mediaSanity.txt │ │ ├── post_mediaChanges.1.txt │ │ ├── pre_downloadFiles.json │ │ ├── post_begin.txt │ │ ├── pre_start.json │ │ ├── post_start.txt │ │ ├── pre_mediaChanges.txt │ │ ├── pre_mediaSanity.txt │ │ ├── pre_mediaChanges.1.txt │ │ ├── post_begin.json │ │ ├── post_start.json │ │ ├── pre_downloadFiles.txt │ │ ├── post_mediaChanges.txt │ │ ├── pre_applyGraves.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── post_downloadFiles.bin │ │ ├── pre_applyChunk.json │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyChanges.txt │ │ ├── pre_applyChanges.json │ │ ├── pre_applyChunk.txt │ │ ├── post_mediaChanges.json │ │ ├── pre_sanityCheck2.json │ │ ├── post_chunk.txt │ │ ├── post_chunk.json │ │ └── post_applyChanges.txt │ ├── two_notes_two_studied │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_start.txt │ │ ├── post_begin.txt │ │ ├── post_start.json │ │ ├── pre_start.json │ │ ├── post_begin.json │ │ ├── pre_applyGraves.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyChanges.json │ │ ├── pre_applyChanges.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_sanityCheck2.json │ │ ├── post_chunk.txt │ │ ├── post_applyChanges.txt │ │ └── post_applyChanges.json │ ├── one_note_delete_unused_media │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── pre_mediaSanity.json │ │ ├── post_applyGraves.txt │ │ ├── pre_mediaChanges.1.json │ │ ├── pre_mediaChanges.json │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_mediaChanges.1.json │ │ ├── post_mediaChanges.1.txt │ │ ├── post_mediaSanity.json │ │ ├── post_mediaSanity.txt │ │ ├── post_start.txt │ │ ├── post_start.json │ │ ├── post_begin.txt │ │ ├── post_mediaChanges.txt │ │ ├── pre_start.json │ │ ├── post_chunk.txt │ │ ├── pre_mediaSanity.txt │ │ ├── post_chunk.json │ │ ├── pre_mediaChanges.1.txt │ │ ├── pre_mediaChanges.txt │ │ ├── post_begin.json │ │ ├── pre_applyGraves.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_begin.txt │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── post_mediaChanges.json │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyChanges.json │ │ ├── pre_applyChanges.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_sanityCheck2.json │ │ ├── post_applyChanges.txt │ │ └── post_applyChanges.json │ ├── rem_new_deck_one_new_card │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_chunk.txt │ │ ├── pre_start.json │ │ ├── post_chunk.json │ │ ├── post_begin.txt │ │ ├── post_start.txt │ │ ├── pre_applyGraves.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── post_begin.json │ │ ├── pre_begin.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyChanges.json │ │ ├── pre_applyChanges.txt │ │ ├── post_start.json │ │ ├── pre_applyChunk.txt │ │ ├── pre_sanityCheck2.json │ │ ├── post_applyChanges.txt │ │ └── post_applyChanges.json │ ├── start_two_notes_delete_one │ │ ├── pre_begin.json │ │ ├── pre_chunk.json │ │ ├── pre_finish.json │ │ ├── post_applyChunk.json │ │ ├── post_applyGraves.json │ │ ├── post_finish.json │ │ ├── post_applyChunk.txt │ │ ├── post_applyGraves.txt │ │ ├── post_finish.txt │ │ ├── post_sanityCheck2.json │ │ ├── post_sanityCheck2.txt │ │ ├── post_begin.txt │ │ ├── post_chunk.txt │ │ ├── pre_start.json │ │ ├── post_chunk.json │ │ ├── post_start.txt │ │ ├── post_begin.json │ │ ├── pre_applyGraves.json │ │ ├── pre_chunk.txt │ │ ├── pre_finish.txt │ │ ├── pre_applyChunk.json │ │ ├── pre_begin.txt │ │ ├── post_start.json │ │ ├── pre_start.txt │ │ ├── pre_sanityCheck2.txt │ │ ├── pre_applyGraves.txt │ │ ├── pre_applyChanges.json │ │ ├── pre_applyChanges.txt │ │ ├── pre_applyChunk.txt │ │ ├── pre_sanityCheck2.json │ │ ├── post_applyChanges.txt │ │ └── post_applyChanges.json │ ├── wo1.png │ └── wo2.png │ └── one_note_reviewed_one_deleted_sql.anki2 ├── scripts ├── poetry-lock.sh ├── helm │ ├── charts │ │ ├── postgresql-10.3.4.tgz │ │ └── ingress-nginx-3.23.0.tgz │ ├── linter_values.yaml │ ├── Chart.lock │ ├── templates │ │ ├── serviceaccount.yaml │ │ ├── djankiserv-service.yaml │ │ ├── static-service.yaml │ │ ├── tests │ │ │ └── test-connection.yaml │ │ ├── djankiserv-pvc.yaml │ │ ├── clusterissuer.prod.yaml │ │ ├── clusterissuer.staging.yaml │ │ ├── ingress.yaml │ │ ├── static-deployment.yaml │ │ └── NOTES.txt │ ├── .helmignore │ └── Chart.yaml ├── images │ ├── static │ │ ├── nginx.conf │ │ └── Dockerfile │ └── main │ │ └── Dockerfile ├── postgres.sh ├── postgres-clean.sh ├── postgres-init.sh ├── precommit-install.sh ├── precommit-uninstall.sh ├── runtests.sh ├── runcoverage.sh ├── rundevserver.sh ├── poetry-update.sh ├── runlinting.sh ├── runmanage.sh ├── runsetup.sh ├── runserver.sh ├── buildimages.sh └── poetry-export.sh ├── .editorconfig ├── docker-compose.example.yml ├── .pre-commit-config.yaml └── .gitignore /src/djankiserv/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/assets/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/assets/api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/assets/up/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/djankiserv_api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/djankiserv_cli/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/assets/down/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/djankiserv/assets/jsonfiles/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/djankiserv_api/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/djankiserv/assets/sql/sqlite3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_download.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_finish.json: -------------------------------------------------------------------------------- 1 | 1599273693138 2 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_begin.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_chunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_finish.json: -------------------------------------------------------------------------------- 1 | 1599274043513 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_finish.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886052235 2 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_finish.json: -------------------------------------------------------------------------------- 1 | 1598367192254 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886018778 2 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886100128 2 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_finish.json: -------------------------------------------------------------------------------- 1 | 1598367352369 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_applyChunk.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_applyGraves.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_finish.json: -------------------------------------------------------------------------------- 1 | 1598367437541 2 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886130368 2 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_finish.json: -------------------------------------------------------------------------------- 1 | 1598367401962 2 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886173729 2 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886268613 2 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886198998 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_finish.json: -------------------------------------------------------------------------------- 1 | 1597886228758 2 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_upload.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'OK' 3 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": 1 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 0 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": 1 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": 2 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1599274043513' 3 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_mediaChanges.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 1 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 0 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 1 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": 2 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1599273693138' 3 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 1 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1598367352369' 3 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": 1 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886052235' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_mediaChanges.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 2 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886130368' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1598367192254' 3 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": 1 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_applyChunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886018778' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886100128' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_applyGraves.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_mediaChanges.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 3 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 2 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1598367437541' 3 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886198998' 3 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886228758' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastUsn": 2 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1598367401962' 3 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886173729' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_finish.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'1597886268613' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ok" 3 | } 4 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "OK", 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [], 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "OK", 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": "OK", "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [], 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/api/tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "a_tag", 4 | "another_tag" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_mediaChanges.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [], 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_mediaChanges.1.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": "OK", "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_mediaChanges.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [], 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "OK", 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": "OK", "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_uploadChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [1, 1], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "OK", 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": "OK", "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"status": "ok"}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_mediaChanges.1.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "done": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [], 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "OK", 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_uploadChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [1, 2], "err": ""}' 3 | -------------------------------------------------------------------------------- /src/djankiserv_utils/logger.py: -------------------------------------------------------------------------------- 1 | 2 | import logging 3 | 4 | def get_logger(name): 5 | return logging.getLogger(name) -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "done": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_mediaChanges.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [], 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_mediaChanges.1.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_mediaSanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "OK", 3 | "err": "" 4 | } 5 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": "OK", "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_downloadFiles.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "wo1.png" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_downloadFiles.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "wo2.png" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": "OK", "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /src/djankiserv_cli/__main__.py: -------------------------------------------------------------------------------- 1 | from djankiserv_cli.manage import main 2 | 3 | if __name__ == "__main__": 4 | main() 5 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "96c7786c", "usn": 1}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/wo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/down/wo1.png -------------------------------------------------------------------------------- /tests/assets/down/wo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/down/wo2.png -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": true, 3 | "minUsn": 1, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_uploadChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [1, 3], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "e87cecbd", "usn": 0}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": true, 3 | "minUsn": 1, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "96c7786c", "usn": 2}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": false, 3 | "minUsn": 1, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "96c7786c", "usn": 2}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": true, 3 | "minUsn": 1, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "e87cecbd", "usn": 1}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": true, 3 | "minUsn": 1, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "e87cecbd", "usn": 2}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": true, 3 | "minUsn": 2, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /scripts/poetry-lock.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: poetry-lock.sh 3 | # description: Update poetry.lock file. 4 | 5 | poetry lock 6 | -------------------------------------------------------------------------------- /src/djankiserv/assets/sql/sqlite3/init_col_table.sql: -------------------------------------------------------------------------------- 1 | insert or ignore into col 2 | values(1,0,0,%(s)s,%(v)s,0,0,0,'','{}','','','{}'); 3 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [1598367068684], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": false, 3 | "minUsn": 1, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "96c7786c", "usn": 2}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [], "notes": [1597886003751], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": false, 3 | "minUsn": 3, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "e87cecbd", "usn": 2}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [] 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": true, 3 | "minUsn": 2, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "e87cecbd", "usn": 2}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": true, 3 | "minUsn": 4, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "96c7786c", "usn": 3}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [["wo2.png", 3, null]], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": false, 3 | "minUsn": 7, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": false, 3 | "minUsn": 3, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": false, 3 | "minUsn": 5, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "lnewer": false, 3 | "minUsn": 6, 4 | "offset": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [], "notes": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'local': 1} 6 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_uploadChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | 1, 4 | 1 5 | ], 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 0} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'local': 1} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_uploadChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | 1, 4 | 2 5 | ], 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'local': 2} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_mediaChanges.1.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 1} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 0} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 1} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'local': 2} 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 1} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /scripts/helm/charts/postgresql-10.3.4.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/scripts/helm/charts/postgresql-10.3.4.tgz -------------------------------------------------------------------------------- /scripts/helm/linter_values.yaml: -------------------------------------------------------------------------------- 1 | djankiserv: 2 | host: a.fqdn.org 3 | clusterissuer: 4 | staging: 5 | enabled: true 6 | email: an@email.com 7 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "9ocu274z31wmfi63pe32m6m588xjwlnz", "usn": 0}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'local': 1} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_downloadFiles.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'files': ['wo1.png']} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [1597886003748], "notes": [1597885981983], "decks": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_mediaChanges.1.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 2} 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "to0929gkkinyuk5916y8as2d4egnp33p", "usn": 0}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_uploadChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | 1, 4 | 3 5 | ], 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_mediaSanity.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'local': 1} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "e87cecbd", 4 | "usn": 0 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /scripts/helm/charts/ingress-nginx-3.23.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/scripts/helm/charts/ingress-nginx-3.23.0.tgz -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "done": true, 4 | "notes": [], 5 | "revlog": [] 6 | } 7 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_mediaChanges.1.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 3} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 2} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "96c7786c", 4 | "usn": 1 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "9ocu274z31wmfi63pe32m6m588xjwlnz", "usn": 0}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "96c7786c", 4 | "usn": 2 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [ 5 | 1597886003751 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_downloadFiles.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'files': ['wo2.png']} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'lastUsn': 2} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_begin.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": {"sk": "to0929gkkinyuk5916y8as2d4egnp33p", "usn": 0}, "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "e87cecbd", 4 | "usn": 1 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "e87cecbd", 4 | "usn": 2 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /scripts/images/static/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name _; 4 | 5 | root /var/www; 6 | 7 | location / { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [], 3 | "decks": [], 4 | "notes": [ 5 | 1598367068684 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [["wo1.png", 1, "f18e0dc430b26c75e16315bd6367bdcc744ea2c8"]], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_start.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"cards": [1598367068673], "notes": [1598367055800], "decks": [1598367050979]}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "96c7786c", 4 | "usn": 2 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_upload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/up/one_note_w_media/pre_upload.bin -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "e87cecbd", 4 | "usn": 2 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "96c7786c", 4 | "usn": 3 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "96c7786c", 4 | "usn": 2 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_mediaChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"data": [["wo2.png", 2, "f18e0dc430b26c75e16315bd6367bdcc744ea2c8"]], "err": ""}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks": [ 3 | [], 4 | [] 5 | ], 6 | "models": [], 7 | "tags": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "e87cecbd", 4 | "usn": 2 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/post_upload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/up/one_note_w_media/post_upload.bin -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks": [ 3 | [], 4 | [] 5 | ], 6 | "models": [], 7 | "tags": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | *']}> 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | *']}> 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_download.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/down/one_note_w_media/post_download.bin -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/one_note_reviewed_one_deleted_sql.anki2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/one_note_reviewed_one_deleted_sql.anki2 -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks": [ 3 | [], 4 | [] 5 | ], 6 | "models": [], 7 | "tags": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks": [ 3 | [], 4 | [] 5 | ], 6 | "models": [], 7 | "tags": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks": [ 3 | [], 4 | [] 5 | ], 6 | "models": [], 7 | "tags": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_uploadChanges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/up/one_note_w_media/pre_uploadChanges.bin -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks": [ 3 | [], 4 | [] 5 | ], 6 | "models": [], 7 | "tags": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_chunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_finish.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_downloadFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/down/one_note_w_media/post_downloadFiles.bin -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "to0929gkkinyuk5916y8as2d4egnp33p", 4 | "usn": 0 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_uploadChanges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/up/two_notes_one_added/pre_uploadChanges.bin -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "9ocu274z31wmfi63pe32m6m588xjwlnz", 4 | "usn": 0 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "9ocu274z31wmfi63pe32m6m588xjwlnz", 4 | "usn": 0 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/post_begin.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "sk": "to0929gkkinyuk5916y8as2d4egnp33p", 4 | "usn": 0 5 | }, 6 | "err": "" 7 | } 8 | -------------------------------------------------------------------------------- /scripts/images/static/Dockerfile: -------------------------------------------------------------------------------- 1 | # vim:set ft=dockerfile 2 | FROM nginx:stable 3 | 4 | COPY ./build/static/ /var/www/static 5 | COPY ./images/static/nginx.conf /etc/nginx/conf.d/default.conf 6 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_downloadFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/down/two_notes_one_added/post_downloadFiles.bin -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | *']}> 3 | 4 | DATA: 5 | {'chunk': {'done': True}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/pre_download.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_uploadChanges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankicommunity/ankicommunity-api-server/HEAD/tests/assets/up/one_note_delete_unused_media/pre_uploadChanges.bin -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "done": true, 5 | "notes": [], 6 | "revlog": [] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /scripts/postgres.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: postgres.sh 3 | # description: 4 | 5 | [[ -f docker-compose.yml ]] || cp docker-compose.example.yml docker-compose.yml 6 | 7 | docker-compose up -d postgres -------------------------------------------------------------------------------- /src/djankiserv_api/views/health.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.http import JsonResponse 4 | 5 | 6 | def health(request): 7 | return JsonResponse({"status": "ok"}) 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_begin.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {} 6 | -------------------------------------------------------------------------------- /scripts/postgres-clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: postgres-clean.sh 3 | # description: Stop and remove local postgres database files. 4 | 5 | docker-compose rm --stop postgres 6 | trash instances/postgres_5432 -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | *']}> 3 | 4 | DATA: 5 | {'minUsn': 1, 'offset': None, 'lnewer': True} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [ 3 | 1597886003748 4 | ], 5 | "decks": [], 6 | "notes": [ 7 | 1597885981983 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 1, 'offset': None, 'lnewer': True} 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 1, 'lnewer': True, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 1, 'lnewer': True, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 2, 'lnewer': True, 'offset': None} 6 | -------------------------------------------------------------------------------- /scripts/postgres-init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: postgres-init.sh 3 | # description: Initalise postgres database. 4 | 5 | ${BASH} ./scripts/runmanage.sh migrate 6 | ${BASH} ./scripts/runmanage.sh createsuperuser -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 1, 'lnewer': False, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 1, 'lnewer': False, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 3, 'lnewer': False, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 2, 'lnewer': True, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 4, 'lnewer': True, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[2, 0, 0], 2, 2, 0, 1, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /scripts/precommit-install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: precommit-install.sh 3 | # description: Install pre-commit Git hook. 4 | 5 | [[ ! -z "${PRECOMMIT}" ]] || PRECOMMIT="poetry run pre-commit" 6 | ${PRECOMMIT} install -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[1, 0, 0], 2, 2, 0, 1, 5, 2, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 7, 'lnewer': False, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 3, 'lnewer': False, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 5, 'lnewer': False, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[2, 0, 0], 2, 2, 0, 1, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[0, 0, 0], 2, 2, 4, 1, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [ 6 | 1598367068684 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[1, 0, 0], 2, 2, 0, 1, 5, 2, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_start.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'minUsn': 6, 'lnewer': False, 'offset': None} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[1, 0, 0], 1, 1, 0, 4, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [], 4 | "decks": [], 5 | "notes": [ 6 | 1597886003751 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[0, 0, 0], 2, 2, 4, 1, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /scripts/precommit-uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: precommit-install.sh 3 | # description: Install pre-commit Git hook. 4 | 5 | [[ ! -z "${PRECOMMIT}" ]] || PRECOMMIT="poetry run pre-commit" 6 | ${PRECOMMIT} uninstall -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[0, 0, 0], 1, 1, 4, 3, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[1, 0, 0], 1, 1, 0, 4, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[0, 0, 0], 1, 1, 4, 3, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[0, 0, 0], 1, 1, 4, 3, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[0, 0, 0], 1, 1, 4, 3, 5, 1, 1]} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | *']}> 3 | 4 | DATA: 5 | {'client': [[1, 0, 0], 1, 1, 0, 0, 5, 1, 1], 'full': True} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | [ 4 | "wo2.png", 5 | 3, 6 | null 7 | ] 8 | ], 9 | "err": "" 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_sanityCheck2.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'client': [[1, 0, 0], 1, 1, 0, 0, 5, 1, 1], 'full': True} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "decks": [ 4 | [], 5 | [] 6 | ], 7 | "models": [], 8 | "tags": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "decks": [ 4 | [], 5 | [] 6 | ], 7 | "models": [], 8 | "tags": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "decks": [ 4 | [], 5 | [] 6 | ], 7 | "models": [], 8 | "tags": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [1598367068684], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [1597886003751], 'cards': [], 'decks': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "decks": [ 4 | [], 5 | [] 6 | ], 7 | "models": [], 8 | "tags": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "decks": [ 4 | [], 5 | [] 6 | ], 7 | "models": [], 8 | "tags": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "decks": [ 4 | [], 5 | [] 6 | ], 7 | "models": [], 8 | "tags": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "decks": [ 4 | [], 5 | [] 6 | ], 7 | "models": [], 8 | "tags": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_start.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [ 3 | 1598367068673 4 | ], 5 | "decks": [ 6 | 1598367050979 7 | ], 8 | "notes": [ 9 | 1598367055800 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_w_media/post_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | [ 4 | "wo1.png", 5 | 1, 6 | "f18e0dc430b26c75e16315bd6367bdcc744ea2c8" 7 | ] 8 | ], 9 | "err": "" 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_mediaChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | [ 4 | "wo2.png", 5 | 2, 6 | "f18e0dc430b26c75e16315bd6367bdcc744ea2c8" 7 | ] 8 | ], 9 | "err": "" 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [1597885981983], 'cards': [1597886003748], 'decks': []}} 6 | -------------------------------------------------------------------------------- /scripts/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source scripts/runsetup.sh 5 | export PYTHONPATH=$PYTHONPATH:tests 6 | export DJANKISERV_DATA_ROOT=./instances/djankiserv_tests 7 | 8 | coverage run --source='src' src/djankiserv_cli/manage.py test --verbosity=1 tests/ -------------------------------------------------------------------------------- /src/djankiserv_api/wsgi.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | 5 | from django.core.wsgi import get_wsgi_application 6 | 7 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djankiserv_api.settings") 8 | 9 | application = get_wsgi_application() 10 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_applyGraves.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'notes': [1598367055800], 'cards': [1598367068673], 'decks': [1598367050979]}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [ 4 | 1597886003748 5 | ], 6 | "decks": [], 7 | "notes": [ 8 | 1597885981983 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /scripts/runcoverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/runsetup.sh 4 | export PYTHONPATH=$PYTHONPATH:tests 5 | 6 | [[ ! -z "${COVERAGE_FAIL_UNDER}" ]] || COVERAGE_FAIL_UNDER=80 7 | 8 | coverage report -m --skip-covered --skip-empty --fail-under ${COVERAGE_FAIL_UNDER} 9 | 10 | -------------------------------------------------------------------------------- /scripts/rundevserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/runsetup.sh 4 | 5 | export DJANKISERV_DEBUG=true 6 | export DJANKISERV_ALLOWED_HOSTS='*' 7 | [[ ! -z "${DJANKISERV_PORT}" ]] || DJANKISERV_PORT=5000 8 | 9 | python3 -m djankiserv_cli runserver 0.0.0.0:${DJANKISERV_PORT} 10 | -------------------------------------------------------------------------------- /src/djankiserv_api/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class DjankiservConfig(AppConfig): 7 | name = "djankiserv" 8 | 9 | def ready(self): 10 | import djankiserv_api.signals # noqa # pylint: disable=C0415,W0611 11 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 2, 5 | 0, 6 | 0 7 | ], 8 | 2, 9 | 2, 10 | 0, 11 | 1, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 1, 5 | 0, 6 | 0 7 | ], 8 | 2, 9 | 2, 10 | 0, 11 | 1, 12 | 5, 13 | 2, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 2, 5 | 0, 6 | 0 7 | ], 8 | 2, 9 | 2, 10 | 0, 11 | 1, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 0, 5 | 0, 6 | 0 7 | ], 8 | 2, 9 | 2, 10 | 4, 11 | 1, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 1, 5 | 0, 6 | 0 7 | ], 8 | 2, 9 | 2, 10 | 0, 11 | 1, 12 | 5, 13 | 2, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 1, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 0, 11 | 4, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 0, 5 | 0, 6 | 0 7 | ], 8 | 2, 9 | 2, 10 | 4, 11 | 1, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 1, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 0, 11 | 4, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 0, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 4, 11 | 3, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 0, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 4, 11 | 3, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 0, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 4, 11 | 3, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 0, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 4, 11 | 3, 12 | 5, 13 | 1, 14 | 1 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_applyGraves.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [ 4 | 1598367068673 5 | ], 6 | "decks": [ 7 | 1598367050979 8 | ], 9 | "notes": [ 10 | 1598367055800 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 1, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 0, 11 | 0, 12 | 5, 13 | 1, 14 | 1 15 | ], 16 | "full": true 17 | } 18 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_sanityCheck2.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | [ 4 | 1, 5 | 0, 6 | 0 7 | ], 8 | 1, 9 | 1, 10 | 0, 11 | 0, 12 | 5, 13 | 1, 14 | 1 15 | ], 16 | "full": true 17 | } 18 | -------------------------------------------------------------------------------- /scripts/poetry-update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: poetry-update.sh 3 | # description: Update Python dependencies to latest. 4 | 5 | POETRY_UPDATE_ARGS=$1 6 | POETRY_UPDATE_OPTS=--dry-run 7 | 8 | poetry update "${POETRY_UPDATE_OPTS}" "${POETRY_UPDATE_ARGS}" 9 | 10 | # TODO: Run poetry export 11 | # TODO: Create git branch and commit 12 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [[1598367068673, 1598367055800, 1598367050979, 0, 1598367068, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, ""]], "notes": [[1598367055800, "O5$t1BD18N", 1598366965257, 1598367068, 2, " second_tag ", "second front\\u001fsecond back", "", "", 0, ""]]}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [], "cards": [[1597886003748, 1597885981983, 1, 0, 1597886003, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, ""]], "notes": [[1597885981983, "z)[>@3N3g3", 1597885581299, 1597886003, 2, " second_tag ", "second front\\u001fsecond back\\u001f", "", "", 0, ""]]}' 3 | -------------------------------------------------------------------------------- /src/djankiserv/assets/jsonfiles/default_deck.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Default", 4 | "newToday": [0, 0], 5 | "revToday": [0, 0], 6 | "lrnToday": [0, 0], 7 | "timeToday": [0, 0], 8 | "conf": 1, 9 | "usn": 0, 10 | "desc": "", 11 | "dyn": 0, 12 | "collapsed": false, 13 | "extendNew": 10, 14 | "extendRev": 50 15 | } 16 | -------------------------------------------------------------------------------- /scripts/helm/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://charts.bitnami.com/bitnami 4 | version: 10.3.4 5 | - name: ingress-nginx 6 | repository: https://kubernetes.github.io/ingress-nginx 7 | version: 3.23.0 8 | digest: sha256:b29cda6f6de01577a5a2b139f780db5ce3a7be4007166af124ce954c16c2a36b 9 | generated: "2021-02-21T13:44:49.7200784+08:00" 10 | -------------------------------------------------------------------------------- /scripts/runlinting.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source scripts/runsetup.sh 5 | export PYTHONPATH=$PYTHONPATH:tests 6 | export DJANKISERV_DATA_ROOT=./instances/djankiserv_tests 7 | 8 | pylint --ignore requirements.txt,requirements.ci.txt,requirements.postgres.txt,requirements.mariadb.txt,djankiserv.egg-info src/* 9 | pylint tests/* 10 | 11 | pre-commit run --all-files --verbose -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | indent_style = space 9 | indent_size = 4 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [*.{rb,yml}] 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /scripts/runmanage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/runsetup.sh 4 | 5 | 6 | [[ ! -z "${DJANGO_MANAGE}" ]] || DJANGO_MANAGE="python3 -m djankiserv_cli" 7 | # [[ ! -z "${DJANGO_MANAGE_OPTS}" ]] || DJANGO_MANAGE_OPTS= 8 | [[ ! -z "${DJANGO_MANAGE_CMD}" ]] || DJANGO_MANAGE_CMD=$@ 9 | # [[ ! -z "${DJANGO_MANAGE_ARGS}" ]] || DJANGO_MANAGE_CMD=$@ 10 | 11 | ${DJANGO_MANAGE} ${DJANGO_MANAGE_CMD} 12 | -------------------------------------------------------------------------------- /scripts/helm/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "djankiserv.serviceAccountName" . }} 6 | labels: 7 | {{- include "djankiserv.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /scripts/runsetup.sh: -------------------------------------------------------------------------------- 1 | export PYTHONBREAKPOINT=ipdb.set_trace 2 | export PYTHONPATH=$PYTHONPATH:src 3 | 4 | # execute dev workstation-specific init (like making sure the db is running, etc.) 5 | # FIXME: find out how this is supposed to work but doesn't 6 | # cd "${BASH_SOURCE%/*}" 7 | 8 | FILE=.local_setup.sh 9 | if [ -f "$FILE" ]; then 10 | echo "Found .local_setup.sh file, sourcing" 11 | source $FILE 12 | fi 13 | -------------------------------------------------------------------------------- /src/djankiserv/assets/jsonfiles/default_collection_conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "activeDecks": [1], 3 | "curDeck": 1, 4 | "newSpread": 0, 5 | "collapseTime": 1200, 6 | "timeLim": 0, 7 | "estTimes": true, 8 | "dueCounts": true, 9 | "curModel": null, 10 | "nextPos": 1, 11 | "sortType": "noteFld", 12 | "sortBackwards": false, 13 | "addToCur": true, 14 | "dayLearnFirst": false 15 | } 16 | -------------------------------------------------------------------------------- /src/djankiserv_api/views/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from djankiserv_api.views.health import health 3 | from djankiserv_api.views.notes import add_notes 4 | from djankiserv_api.views.notes import get_notes 5 | from djankiserv_api.views.notes import delete_notes 6 | from djankiserv_api.views.decks import get_decks 7 | from djankiserv_api.views.decks import get_deck_confs 8 | from djankiserv_api.views.tags import tags 9 | from djankiserv_api.views.models import models -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": [], "conf": {"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": "1598366965257", "nextPos": 3, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "schedVer": 1, "newBury": true}, "crt": 1598299200}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [[1598367068673, 1598367055800, 1598367050979, 0, 1598367068, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, '']], 'notes': [[1598367055800, 'O5$t1BD18N', 1598366965257, 1598367068, 1, ' second_tag ', 'second front\x1fsecond back', '', '', 0, '']]}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [], 'cards': [[1597886003748, 1597885981983, 1, 0, 1597886003, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, '']], 'notes': [[1597885981983, 'z)[>@3N3g3', 1597885581299, 1597886003, 1, ' second_tag ', 'second front\x1fsecond back\x1f', '', '', 0, '']]}} 6 | -------------------------------------------------------------------------------- /scripts/helm/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /src/requirements.mariadb.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.3.1; python_version >= "3.6" 2 | django-k8s==0.2.9 3 | django==3.1.7; python_version >= "3.6" 4 | djangorestframework-simplejwt==4.6.0; python_version >= "3.7" 5 | djangorestframework==3.12.2; python_version >= "3.5" 6 | gunicorn==20.0.4; python_version >= "3.4" 7 | mysqlclient==2.0.3; python_version >= "3.5" 8 | pyjwt==2.0.1; python_version >= "3.7" 9 | pytz==2021.1; python_version >= "3.6" 10 | sqlparse==0.4.1; python_version >= "3.6" 11 | -------------------------------------------------------------------------------- /scripts/images/main/Dockerfile: -------------------------------------------------------------------------------- 1 | # vim:set ft=dockerfile 2 | FROM python:3.9-slim 3 | 4 | RUN apt update && apt install -y gcc git && apt -y autoremove && apt -y clean && rm -rf /var/lib/apt/lists/* 5 | 6 | # Set environment varibles 7 | ENV PYTHONDONTWRITEBYTECODE 1 8 | ENV PYTHONUNBUFFERED 1 9 | 10 | WORKDIR /app 11 | 12 | COPY ./src /app 13 | COPY ./scripts /app/scripts 14 | 15 | RUN pip install -r requirements.postgres.txt 16 | 17 | CMD ["/bin/bash", "/app/scripts/runserver.sh"] 18 | -------------------------------------------------------------------------------- /scripts/helm/templates/djankiserv-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "djankiserv.fullname" . }} 5 | labels: 6 | {{- include "djankiserv.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.djankiserv.service.type }} 9 | ports: 10 | - port: {{ .Values.djankiserv.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "djankiserv.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": [], "conf": {"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": "1597885581299", "nextPos": 3, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "schedVer": 1, "newBury": true, "activeCols": ["noteFld", "template", "cardDue", "deck"]}, "crt": 1597867200}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": [], "conf": {"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": "1597885581299", "nextPos": 3, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "schedVer": 1, "newBury": true, "activeCols": ["noteFld", "template", "cardDue", "deck"]}, "crt": 1597867200}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[], []], "tags": [], "conf": {"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": "1597885581299", "nextPos": 3, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "schedVer": 1, "newBury": true, "activeCols": ["noteFld", "template", "cardDue", "deck"]}, "crt": 1597867200}' 3 | -------------------------------------------------------------------------------- /scripts/helm/templates/static-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "djankiserv.fullname" . }}-static 5 | labels: 6 | {{- include "djankiserv.static.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.static.service.type }} 9 | ports: 10 | - port: {{ .Values.static.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "djankiserv.static.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /src/djankiserv_api/views/models.py: -------------------------------------------------------------------------------- 1 | 2 | from django.conf import settings 3 | from django.http import JsonResponse 4 | from django.views.decorators.csrf import csrf_exempt 5 | from rest_framework.decorators import api_view 6 | 7 | from djankiserv_unki.collection import Collection 8 | 9 | @csrf_exempt 10 | @api_view(["POST", "GET"]) 11 | def models(request): 12 | with Collection(request.user.username, settings.DJANKISERV_DATA_ROOT) as col: 13 | return JsonResponse({"models": col.models.models}) 14 | -------------------------------------------------------------------------------- /scripts/helm/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "djankiserv.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "djankiserv.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test-success 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "djankiserv.fullname" . }}:{{ .Values.djankiserv.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /scripts/runserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/runsetup.sh 4 | 5 | DJANKISERV_GUNICORN_TIMEOUT="${DJANKISERV_GUNICORN_TIMEOUT:-30}" 6 | DJANKISERV_GUNICORN_WORKERS="${DJANKISERV_GUNICORN_WORKERS:-1}" 7 | DJANKISERV_LISTEN_ADDRESS="${DJANKISERV_LISTEN_ADDRESS:-127.0.0.1}" 8 | DJANKISERV_LISTEN_PORT="${DJANKISERV_LISTEN_PORT:-27701}" 9 | 10 | gunicorn --timeout $DJANKISERV_GUNICORN_TIMEOUT --workers=$DJANKISERV_GUNICORN_WORKERS -b $DJANKISERV_LISTEN_ADDRESS:$DJANKISERV_LISTEN_PORT djankiserv_api.wsgi 11 | -------------------------------------------------------------------------------- /src/djankiserv_api/views/tags.py: -------------------------------------------------------------------------------- 1 | 2 | from django.conf import settings 3 | from django.http import JsonResponse 4 | from django.views.decorators.csrf import csrf_exempt 5 | from rest_framework.decorators import api_view 6 | 7 | from djankiserv_unki.collection import Collection 8 | 9 | @csrf_exempt 10 | @api_view(["POST", "GET"]) 11 | def tags(request): 12 | with Collection(request.user.username, settings.DJANKISERV_DATA_ROOT) as col: 13 | return JsonResponse({"tags": list(col.tags.keys())}) 14 | 15 | -------------------------------------------------------------------------------- /scripts/helm/templates/djankiserv-pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.djankiserv.enabled .Values.djankiserv.persistence.enabled -}} 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: {{ include "djankiserv.fullname" . }} 6 | labels: 7 | {{- include "djankiserv.labels" . | nindent 4 }} 8 | spec: 9 | accessModes: 10 | - {{ .Values.djankiserv.persistence.accessMode }} 11 | resources: 12 | requests: 13 | storage: {{ .Values.djankiserv.persistence.size }} 14 | status: {} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /scripts/buildimages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source scripts/runsetup.sh 5 | 6 | TAG=${DJANKISERV_BUILD_TAG:-$(git describe --tags)} 7 | 8 | MAIN_IMAGE=${DJANKISERV_DOCKER_REPO}/djankiserv:$TAG 9 | buildah bud -t ${MAIN_IMAGE} -f images/main/Dockerfile . 10 | buildah push -D ${MAIN_IMAGE} 11 | 12 | STATIC_IMAGE=${DJANKISERV_DOCKER_REPO}/djankiserv-static:$TAG 13 | python3 -m djankiserv_cli collectstatic --noinput 14 | buildah bud -t ${STATIC_IMAGE} -f images/static/Dockerfile . 15 | buildah push -D ${STATIC_IMAGE} 16 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | *']}> 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': [], 'conf': {'schedVer': 1, 'addToCur': True, 'estTimes': True, 'curDeck': 1, 'newBury': True, 'timeLim': 0, 'dueCounts': True, 'sortBackwards': False, 'sortType': 'noteFld', 'curModel': 1599273529538, 'nextPos': 2, 'newSpread': 0, 'dayLearnFirst': False, 'activeDecks': [1], 'collapseTime': 1200}, 'crt': 1599249600}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/pre_uploadChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'data': b'PK\x03\x04\x14\x00\x00\x00\x08\x00$J\x14Q\xc7 \x1ct\x13\x00\x00\x00\x11\x00\x00\x00\x05\x00\x00\x00_meta\x8b\x8eV*\xcf7\xd2+\xc8KW\xd2QPR\x8a\x8d\x05\x00PK\x01\x02\x14\x03\x14\x00\x00\x00\x08\x00$J\x14Q\xc7 \x1ct\x13\x00\x00\x00\x11\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00_metaPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x003\x00\x00\x006\x00\x00\x00\x00\x00'} 6 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': [], 'conf': {'activeDecks': [1], 'curDeck': 1, 'newSpread': 0, 'collapseTime': 1200, 'timeLim': 0, 'estTimes': True, 'dueCounts': True, 'curModel': '1598366965257', 'nextPos': 3, 'sortType': 'noteFld', 'sortBackwards': False, 'addToCur': True, 'dayLearnFirst': False, 'schedVer': 1, 'newBury': True}, 'crt': 1598299200}} 6 | -------------------------------------------------------------------------------- /docker-compose.example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # file: docker-compose.yml 3 | version: '3.7' 4 | services: 5 | 6 | postgres: 7 | image: postgres:latest 8 | container_name: djankiserv_postgres_${POSTGRES_PORT-5432} 9 | ports: 10 | - ${POSTGRES_PORT-5432}:5432 11 | environment: 12 | - POSTGRES_DB=${POSTGRES_DB} 13 | - POSTGRES_USER=${POSTGRES_USER} 14 | - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} 15 | volumes: 16 | - ./instances/postgres_${POSTGRES_PORT-5432}:/var/lib/postgresql 17 | restart: unless-stopped -------------------------------------------------------------------------------- /src/requirements.postgres.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.3.1; python_version >= "3.6" 2 | django-k8s==0.2.9 3 | django==3.1.7; python_version >= "3.6" 4 | djangorestframework-simplejwt==4.6.0; python_version >= "3.7" 5 | djangorestframework==3.12.2; python_version >= "3.5" 6 | gunicorn==20.0.4; python_version >= "3.4" 7 | psycopg2-binary==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") 8 | pyjwt==2.0.1; python_version >= "3.7" 9 | pytz==2021.1; python_version >= "3.6" 10 | sqlparse==0.4.1; python_version >= "3.6" 11 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_chunk.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"done": true, "revlog": [[1597886088348, 1597885646044, 4, 2, -600, -60, 0, 2454, 0], [1597886089720, 1597886003748, 4, 2, -600, -60, 0, 1371, 0], [1597886091395, 1597885646044, 4, 2, 1, -600, 2500, 1674, 0], [1597886093662, 1597886003748, 4, 2, 1, -600, 2500, 2266, 0]], "cards": [[1597885646044, 1597885612479, 1, 0, 1597886091, 4, 2, 2, 1, 1, 2500, 2, 0, 1001, 0, 0, 0, ""], [1597886003748, 1597885981983, 1, 0, 1597886093, 4, 2, 2, 1, 1, 2500, 2, 0, 1001, 0, 0, 0, ""]], "notes": []}' 3 | -------------------------------------------------------------------------------- /src/requirements.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.3.1; python_version >= "3.6" 2 | django-k8s==0.2.9 3 | django==3.1.7; python_version >= "3.6" 4 | djangorestframework-simplejwt==4.6.0; python_version >= "3.7" 5 | djangorestframework==3.12.2; python_version >= "3.5" 6 | gunicorn==20.0.4; python_version >= "3.4" 7 | mysqlclient==2.0.3; python_version >= "3.5" 8 | psycopg2-binary==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") 9 | pyjwt==2.0.1; python_version >= "3.7" 10 | pytz==2021.1; python_version >= "3.6" 11 | sqlparse==0.4.1; python_version >= "3.6" 12 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[], []], 'tags': [], 'conf': {'activeDecks': [1], 'curDeck': 1, 'newSpread': 0, 'collapseTime': 1200, 'timeLim': 0, 'estTimes': True, 'dueCounts': True, 'curModel': '1597885581299', 'nextPos': 3, 'sortType': 'noteFld', 'sortBackwards': False, 'addToCur': True, 'dayLearnFirst': False, 'schedVer': 1, 'newBury': True, 'activeCols': ['noteFld', 'template', 'cardDue', 'deck']}, 'crt': 1597867200}} 6 | -------------------------------------------------------------------------------- /src/djankiserv/assets/sql/sqlite3/add_indices.sql: -------------------------------------------------------------------------------- 1 | 2 | -- syncing 3 | create index if not exists ix_notes_usn on notes (usn); 4 | create index if not exists ix_cards_usn on cards (usn); 5 | create index if not exists ix_revlog_usn on revlog (usn); 6 | -- card spacing, etc 7 | create index if not exists ix_cards_nid on cards (nid); 8 | -- scheduling and deck limiting 9 | create index if not exists ix_cards_sched on cards (did, queue, due); 10 | -- revlog by card 11 | create index if not exists ix_revlog_cid on revlog (cid); 12 | -- field uniqueness 13 | create index if not exists ix_notes_csum on notes (csum); 14 | -------------------------------------------------------------------------------- /tests/assets/api/new_notes.json: -------------------------------------------------------------------------------- 1 | { 2 | "deck": "Default", 3 | "notes": [ 4 | { 5 | "fields": [ 6 | "front value", 7 | "back value" 8 | ], 9 | "model": "Basic", 10 | "tags": [ 11 | "a_tag" 12 | ] 13 | }, 14 | { 15 | "fields": [ 16 | "a deleted front", 17 | "a deleted back" 18 | ], 19 | "model": "Basic", 20 | "tags": [ 21 | "another_tag" 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_applyChunk.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'chunk': {'done': True, 'revlog': [[1597886088348, 1597885646044, 3, 2, -600, -60, 0, 2454, 0], [1597886089720, 1597886003748, 3, 2, -600, -60, 0, 1371, 0], [1597886091395, 1597885646044, 3, 2, 1, -600, 2500, 1674, 0], [1597886093662, 1597886003748, 3, 2, 1, -600, 2500, 2266, 0]], 'cards': [[1597885646044, 1597885612479, 1, 0, 1597886091, 3, 2, 2, 1, 1, 2500, 2, 0, 1001, 0, 0, 0, ''], [1597886003748, 1597885981983, 1, 0, 1597886093, 3, 2, 2, 1, 1, 2500, 2, 0, 1001, 0, 0, 0, '']], 'notes': []}} 6 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[{"newToday": [0, 2], "revToday": [0, 0], "lrnToday": [0, 2], "timeToday": [0, 7765], "conf": 1, "usn": 3, "desc": "", "dyn": 0, "collapsed": false, "extendNew": 10, "extendRev": 50, "id": 1, "name": "Default", "mod": 1597886093}], []], "tags": [], "conf": {"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": "1597885581299", "nextPos": 3, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "schedVer": 1, "newBury": true}, "crt": 1597867200}' 3 | -------------------------------------------------------------------------------- /tests/assets/api/two_notes.json: -------------------------------------------------------------------------------- 1 | { 2 | "notes": [ 3 | { 4 | "fields": [ 5 | "front value", 6 | "back value" 7 | ], 8 | "id": 1597199240668, 9 | "model": "Basic", 10 | "tags": [ 11 | "a_tag" 12 | ] 13 | }, 14 | { 15 | "fields": [ 16 | "a deleted front", 17 | "a deleted back" 18 | ], 19 | "id": 1597199560880, 20 | "model": "Basic", 21 | "tags": [ 22 | "another_tag" 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /src/djankiserv_cli/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks. 3 | 4 | This should typically always be used via the djankiserv cli. However, 5 | a manage.py is maintained to follow django convension and for legacy reasons. 6 | 7 | This may be removed in the future if not needed. 8 | """ 9 | 10 | import os 11 | import sys 12 | 13 | from django.core.management import execute_from_command_line 14 | 15 | 16 | def main(): 17 | """Run administrative tasks.""" 18 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djankiserv_api.settings") 19 | execute_from_command_line(sys.argv) 20 | 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /tests/assets/down/rem_new_deck_one_new_card/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "conf": { 3 | "activeDecks": [ 4 | 1 5 | ], 6 | "addToCur": true, 7 | "collapseTime": 1200, 8 | "curDeck": 1, 9 | "curModel": "1598366965257", 10 | "dayLearnFirst": false, 11 | "dueCounts": true, 12 | "estTimes": true, 13 | "newBury": true, 14 | "newSpread": 0, 15 | "nextPos": 3, 16 | "schedVer": 1, 17 | "sortBackwards": false, 18 | "sortType": "noteFld", 19 | "timeLim": 0 20 | }, 21 | "crt": 1598299200, 22 | "decks": [ 23 | [], 24 | [] 25 | ], 26 | "models": [], 27 | "tags": [] 28 | } 29 | -------------------------------------------------------------------------------- /scripts/helm/templates/clusterissuer.prod.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.clusterissuer.prod.enabled -}} 2 | apiVersion: cert-manager.io/v1 3 | kind: ClusterIssuer 4 | metadata: 5 | name: {{ .Values.clusterissuer.prod.name }} 6 | spec: 7 | acme: 8 | email: {{ required "A valid .Values.clusterissuer.prod.email entry required!" .Values.clusterissuer.prod.email }} 9 | server: https://acme-v02.api.letsencrypt.org/directory 10 | privateKeySecretRef: 11 | # Secret resource that will be used to store the account's private key. 12 | name: {{ .Values.clusterissuer.prod.privateKeySecretRef }} 13 | # Add a single challenge solver, HTTP01 using nginx 14 | solvers: 15 | - http01: 16 | ingress: 17 | class: nginx 18 | {{- end }} 19 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_two_studied/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[{'newToday': [0, 2], 'revToday': [0, 0], 'lrnToday': [0, 2], 'timeToday': [0, 7765], 'conf': 1, 'usn': 3, 'desc': '', 'dyn': 0, 'collapsed': False, 'extendNew': 10, 'extendRev': 50, 'id': 1, 'name': 'Default', 'mod': 1597886093}], []], 'tags': [], 'conf': {'activeDecks': [1], 'curDeck': 1, 'newSpread': 0, 'collapseTime': 1200, 'timeLim': 0, 'estTimes': True, 'dueCounts': True, 'curModel': '1597885581299', 'nextPos': 3, 'sortType': 'noteFld', 'sortBackwards': False, 'addToCur': True, 'dayLearnFirst': False, 'schedVer': 1, 'newBury': True}, 'crt': 1597867200}} 6 | -------------------------------------------------------------------------------- /scripts/helm/templates/clusterissuer.staging.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.clusterissuer.staging.enabled -}} 2 | apiVersion: cert-manager.io/v1 3 | kind: ClusterIssuer 4 | metadata: 5 | name: {{ .Values.clusterissuer.staging.name }} 6 | spec: 7 | acme: 8 | email: {{ required "A valid .Values.clusterissuer.staging.email entry required!" .Values.clusterissuer.staging.email }} 9 | server: https://acme-staging-v02.api.letsencrypt.org/directory 10 | privateKeySecretRef: 11 | # Secret resource that will be used to store the account's private key. 12 | name: {{ .Values.clusterissuer.staging.privateKeySecretRef }} 13 | # Add a single challenge solver, HTTP01 using nginx 14 | solvers: 15 | - http01: 16 | ingress: 17 | class: nginx 18 | {{- end }} 19 | -------------------------------------------------------------------------------- /tests/assets/api/decks.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks": { 3 | "1": { 4 | "collapsed": false, 5 | "conf": 1, 6 | "desc": "", 7 | "dyn": 0, 8 | "extendNew": 10, 9 | "extendRev": 50, 10 | "id": 1, 11 | "lrnToday": [ 12 | 26, 13 | 0 14 | ], 15 | "mod": 1597199283, 16 | "name": "Default", 17 | "newToday": [ 18 | 26, 19 | 0 20 | ], 21 | "revToday": [ 22 | 26, 23 | 0 24 | ], 25 | "timeToday": [ 26 | 26, 27 | 0 28 | ], 29 | "usn": 0 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [], "decks": [[{"id": 1, "mod": 1599273687, "name": "Default", "usn": 1, "lrnToday": [0, 0], "revToday": [0, 0], "newToday": [0, 0], "timeToday": [0, 0], "collapsed": false, "browserCollapsed": false, "desc": "An options group description", "dyn": 0, "conf": 1, "extendNew": 0, "extendRev": 0}], [{"id": 1, "mod": 1599273687, "name": "renamed_options_group", "usn": 1, "maxTaken": 61, "autoplay": true, "timer": 0, "replayq": true, "new": {"bury": false, "delays": [1.0, 11.0], "initialFactor": 1300, "ints": [1, 4, 0], "order": 1, "perDay": 20}, "rev": {"bury": false, "ease4": 1.3, "ivlFct": 1.0, "maxIvl": 36500, "perDay": 201, "hardFactor": 1.2}, "lapse": {"delays": [11.0], "leechAction": 1, "leechFails": 8, "minInt": 1, "mult": 0.0}, "dyn": false}]], "tags": []}' 3 | -------------------------------------------------------------------------------- /tests/assets/down/modify_deck_conf/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "conf": { 4 | "activeDecks": [ 5 | 1 6 | ], 7 | "addToCur": true, 8 | "collapseTime": 1200, 9 | "curDeck": 1, 10 | "curModel": 1599273529538, 11 | "dayLearnFirst": false, 12 | "dueCounts": true, 13 | "estTimes": true, 14 | "newBury": true, 15 | "newSpread": 0, 16 | "nextPos": 2, 17 | "schedVer": 1, 18 | "sortBackwards": false, 19 | "sortType": "noteFld", 20 | "timeLim": 0 21 | }, 22 | "crt": 1599249600, 23 | "decks": [ 24 | [], 25 | [] 26 | ], 27 | "models": [], 28 | "tags": [] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/assets/up/rem_new_deck_one_new_card/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "conf": { 4 | "activeDecks": [ 5 | 1 6 | ], 7 | "addToCur": true, 8 | "collapseTime": 1200, 9 | "curDeck": 1, 10 | "curModel": "1598366965257", 11 | "dayLearnFirst": false, 12 | "dueCounts": true, 13 | "estTimes": true, 14 | "newBury": true, 15 | "newSpread": 0, 16 | "nextPos": 3, 17 | "schedVer": 1, 18 | "sortBackwards": false, 19 | "sortType": "noteFld", 20 | "timeLim": 0 21 | }, 22 | "crt": 1598299200, 23 | "decks": [ 24 | [], 25 | [] 26 | ], 27 | "models": [], 28 | "tags": [] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/djankiserv/assets/jsonfiles/default_deck_conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Default", 4 | "new": { 5 | "delays": [1, 10], 6 | "ints": [1, 4, 7], 7 | "initialFactor": 2500, 8 | "separate": true, 9 | "order": 1, 10 | "perDay": 20, 11 | "bury": false 12 | }, 13 | "lapse": { 14 | "delays": [10], 15 | "mult": 0, 16 | "minInt": 1, 17 | "leechFails": 8, 18 | "leechAction": 0 19 | }, 20 | "rev": { 21 | "perDay": 200, 22 | "ease4": 1.3, 23 | "fuzz": 0.05, 24 | "minSpace": 1, 25 | "ivlFct": 1, 26 | "maxIvl": 36500, 27 | "bury": false, 28 | "hardFactor": 1.2 29 | }, 30 | "maxTaken": 60, 31 | "timer": 0, 32 | "autoplay": true, 33 | "replayq": true, 34 | "mod": 0, 35 | "usn": 0 36 | } 37 | -------------------------------------------------------------------------------- /tests/assets/down/one_note_delete_unused_media/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "conf": { 3 | "activeCols": [ 4 | "noteFld", 5 | "template", 6 | "cardDue", 7 | "deck" 8 | ], 9 | "activeDecks": [ 10 | 1 11 | ], 12 | "addToCur": true, 13 | "collapseTime": 1200, 14 | "curDeck": 1, 15 | "curModel": "1597885581299", 16 | "dayLearnFirst": false, 17 | "dueCounts": true, 18 | "estTimes": true, 19 | "newBury": true, 20 | "newSpread": 0, 21 | "nextPos": 3, 22 | "schedVer": 1, 23 | "sortBackwards": false, 24 | "sortType": "noteFld", 25 | "timeLim": 0 26 | }, 27 | "crt": 1597867200, 28 | "decks": [ 29 | [], 30 | [] 31 | ], 32 | "models": [], 33 | "tags": [] 34 | } 35 | -------------------------------------------------------------------------------- /tests/assets/down/start_two_notes_delete_one/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "conf": { 3 | "activeCols": [ 4 | "noteFld", 5 | "template", 6 | "cardDue", 7 | "deck" 8 | ], 9 | "activeDecks": [ 10 | 1 11 | ], 12 | "addToCur": true, 13 | "collapseTime": 1200, 14 | "curDeck": 1, 15 | "curModel": "1597885581299", 16 | "dayLearnFirst": false, 17 | "dueCounts": true, 18 | "estTimes": true, 19 | "newBury": true, 20 | "newSpread": 0, 21 | "nextPos": 3, 22 | "schedVer": 1, 23 | "sortBackwards": false, 24 | "sortType": "noteFld", 25 | "timeLim": 0 26 | }, 27 | "crt": 1597867200, 28 | "decks": [ 29 | [], 30 | [] 31 | ], 32 | "models": [], 33 | "tags": [] 34 | } 35 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_delete_unused_media/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "conf": { 3 | "activeCols": [ 4 | "noteFld", 5 | "template", 6 | "cardDue", 7 | "deck" 8 | ], 9 | "activeDecks": [ 10 | 1 11 | ], 12 | "addToCur": true, 13 | "collapseTime": 1200, 14 | "curDeck": 1, 15 | "curModel": "1597885581299", 16 | "dayLearnFirst": false, 17 | "dueCounts": true, 18 | "estTimes": true, 19 | "newBury": true, 20 | "newSpread": 0, 21 | "nextPos": 3, 22 | "schedVer": 1, 23 | "sortBackwards": false, 24 | "sortType": "noteFld", 25 | "timeLim": 0 26 | }, 27 | "crt": 1597867200, 28 | "decks": [ 29 | [], 30 | [] 31 | ], 32 | "models": [], 33 | "tags": [] 34 | } 35 | -------------------------------------------------------------------------------- /scripts/helm/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: djankiserv 3 | description: A Helm chart for installing Djankiserv 4 | 5 | type: application 6 | version: 0.0.9 7 | appVersion: 0.0.9 8 | 9 | keywords: 10 | - Django 11 | - Anki 12 | - sync 13 | sources: 14 | - https://github.com/ankicommunity/djankiserv 15 | home: https://github.com/ankicommunity/djankiserv 16 | dependencies: 17 | - name: postgresql 18 | version: 10.x.x 19 | repository: https://charts.bitnami.com/bitnami 20 | condition: postgresql.enabled 21 | tags: 22 | - djankiserv-database 23 | 24 | - name: ingress-nginx 25 | version: 3.x.x 26 | alias: ingress # because https://github.com/helm/helm/issues/2192 27 | repository: https://kubernetes.github.io/ingress-nginx 28 | condition: ingress-nginx.enabled # FIXME: this doesn't appear to work 29 | tags: 30 | - djankiserv-nginx 31 | -------------------------------------------------------------------------------- /src/djankiserv_api/signals.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf import settings 4 | from django.contrib.auth.models import User 5 | from django.db.models.signals import post_delete, post_save 6 | from django.dispatch import receiver 7 | 8 | from djankiserv_unki.collection import Collection 9 | 10 | 11 | @receiver(post_save, sender=User) # pylint: disable=W0613 12 | def update_profile_signal(sender, instance, created, **kwargs): # pylint: disable=W0613 13 | if created: 14 | # Creates on first loading if it doesn't exist 15 | # FIXME: so do I still need to do this here? 16 | Collection(instance.username, settings.DJANKISERV_DATA_ROOT) 17 | 18 | 19 | @receiver(post_delete, sender=User) 20 | def delete_user_signal(sender, instance, **kwargs): # pylint: disable=W0613 21 | Collection.delete(instance.username, settings.DJANKISERV_DATA_ROOT) # pylint: disable=W0613 22 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [ 3 | [ 4 | 1598367068673, 5 | 1598367055800, 6 | 1598367050979, 7 | 0, 8 | 1598367068, 9 | 2, 10 | 0, 11 | 0, 12 | 2, 13 | 0, 14 | 0, 15 | 0, 16 | 0, 17 | 0, 18 | 0, 19 | 0, 20 | 0, 21 | "" 22 | ] 23 | ], 24 | "done": true, 25 | "notes": [ 26 | [ 27 | 1598367055800, 28 | "O5$t1BD18N", 29 | 1598366965257, 30 | 1598367068, 31 | 2, 32 | " second_tag ", 33 | "second front\u001fsecond back", 34 | "", 35 | "", 36 | 0, 37 | "" 38 | ] 39 | ], 40 | "revlog": [] 41 | } 42 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "cards": [ 3 | [ 4 | 1597886003748, 5 | 1597885981983, 6 | 1, 7 | 0, 8 | 1597886003, 9 | 2, 10 | 0, 11 | 0, 12 | 2, 13 | 0, 14 | 0, 15 | 0, 16 | 0, 17 | 0, 18 | 0, 19 | 0, 20 | 0, 21 | "" 22 | ] 23 | ], 24 | "done": true, 25 | "notes": [ 26 | [ 27 | 1597885981983, 28 | "z)[>@3N3g3", 29 | 1597885581299, 30 | 1597886003, 31 | 2, 32 | " second_tag ", 33 | "second front\u001fsecond back\u001f", 34 | "", 35 | "", 36 | 0, 37 | "" 38 | ] 39 | ], 40 | "revlog": [] 41 | } 42 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/ambv/black 3 | rev: stable 4 | hooks: 5 | - id: black 6 | args: [--line-length, "120"] 7 | language_version: python3.8 8 | 9 | - repo: https://github.com/pre-commit/pre-commit-hooks 10 | rev: v3.2.0 11 | hooks: 12 | - id: trailing-whitespace 13 | - id: end-of-file-fixer 14 | - id: check-json 15 | - id: check-merge-conflict 16 | - id: check-xml 17 | - id: check-yaml 18 | exclude: ^charts/djankiserv/templates 19 | - id: end-of-file-fixer 20 | - id: mixed-line-ending 21 | - id: debug-statements 22 | 23 | - repo: https://github.com/gruntwork-io/pre-commit 24 | rev: v0.0.9 25 | hooks: 26 | - id: helmlint 27 | 28 | - repo: https://gitlab.com/retnikt/flake9 29 | rev: 3.8.3.post1 30 | hooks: 31 | - id: flake8 32 | additional_dependencies: ['toml'] 33 | 34 | - repo: https://github.com/timothycrosley/isort 35 | rev: 5.4.2 36 | hooks: 37 | - id: isort 38 | -------------------------------------------------------------------------------- /src/djankiserv_sync/views/__init__.py: -------------------------------------------------------------------------------- 1 | # /sync 2 | from djankiserv_sync.views.sync import base_meta 3 | from djankiserv_sync.views.sync import base_start 4 | from djankiserv_sync.views.sync import base_applyGraves 5 | from djankiserv_sync.views.sync import base_applyChanges 6 | from djankiserv_sync.views.sync import base_chunk 7 | from djankiserv_sync.views.sync import base_applyChunk 8 | from djankiserv_sync.views.sync import base_sanityCheck2 9 | from djankiserv_sync.views.sync import base_finish 10 | from djankiserv_sync.views.sync import base_hostKey 11 | from djankiserv_sync.views.sync import base_upload 12 | from djankiserv_sync.views.sync import base_download 13 | 14 | # /msync 15 | from djankiserv_sync.views.msync import media_begin 16 | from djankiserv_sync.views.msync import media_mediaChanges 17 | from djankiserv_sync.views.msync import media_mediaSanity 18 | from djankiserv_sync.views.msync import media_uploadChanges 19 | from djankiserv_sync.views.msync import media_downloadFiles 20 | -------------------------------------------------------------------------------- /tests/assets/up/start_two_notes_delete_one/pre_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": { 3 | "conf": { 4 | "activeCols": [ 5 | "noteFld", 6 | "template", 7 | "cardDue", 8 | "deck" 9 | ], 10 | "activeDecks": [ 11 | 1 12 | ], 13 | "addToCur": true, 14 | "collapseTime": 1200, 15 | "curDeck": 1, 16 | "curModel": "1597885581299", 17 | "dayLearnFirst": false, 18 | "dueCounts": true, 19 | "estTimes": true, 20 | "newBury": true, 21 | "newSpread": 0, 22 | "nextPos": 3, 23 | "schedVer": 1, 24 | "sortBackwards": false, 25 | "sortType": "noteFld", 26 | "timeLim": 0 27 | }, 28 | "crt": 1597867200, 29 | "decks": [ 30 | [], 31 | [] 32 | ], 33 | "models": [], 34 | "tags": [] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [ 4 | [ 5 | 1598367068673, 6 | 1598367055800, 7 | 1598367050979, 8 | 0, 9 | 1598367068, 10 | 1, 11 | 0, 12 | 0, 13 | 2, 14 | 0, 15 | 0, 16 | 0, 17 | 0, 18 | 0, 19 | 0, 20 | 0, 21 | 0, 22 | "" 23 | ] 24 | ], 25 | "done": true, 26 | "notes": [ 27 | [ 28 | 1598367055800, 29 | "O5$t1BD18N", 30 | 1598366965257, 31 | 1598367068, 32 | 1, 33 | " second_tag ", 34 | "second front\u001fsecond back", 35 | "", 36 | "", 37 | 0, 38 | "" 39 | ] 40 | ], 41 | "revlog": [] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_applyChunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "chunk": { 3 | "cards": [ 4 | [ 5 | 1597886003748, 6 | 1597885981983, 7 | 1, 8 | 0, 9 | 1597886003, 10 | 1, 11 | 0, 12 | 0, 13 | 2, 14 | 0, 15 | 0, 16 | 0, 17 | 0, 18 | 0, 19 | 0, 20 | 0, 21 | 0, 22 | "" 23 | ] 24 | ], 25 | "done": true, 26 | "notes": [ 27 | [ 28 | 1597885981983, 29 | "z)[>@3N3g3", 30 | 1597885581299, 31 | 1597886003, 32 | 1, 33 | " second_tag ", 34 | "second front\u001fsecond back\u001f", 35 | "", 36 | "", 37 | 0, 38 | "" 39 | ] 40 | ], 41 | "revlog": [] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/djankiserv_sync/dependencies.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import logging 4 | 5 | from django.conf import settings 6 | from django.contrib.sessions.backends.db import SessionStore 7 | from django.core.exceptions import PermissionDenied 8 | 9 | from djankiserv_unki.collection import Collection 10 | from djankiserv_utils import print_request 11 | 12 | 13 | logger = logging.getLogger("djankiserv.views") 14 | 15 | ## In order to be compatible with the clients and use the bespoke auth, we need to tell DRF not to manage 16 | ## auth for the xSYNC methods 17 | 18 | 19 | def get_session(request): 20 | return SessionStore(session_key=(request.POST.get("k") or request.GET.get("k") or request.POST.get("sk"))) 21 | 22 | 23 | def safe_get_session(request): 24 | # Get and verify the session 25 | print_request(request) 26 | 27 | session = get_session(request) 28 | 29 | if not session.get("skey"): # FIXME: there is probably a better way than this 30 | raise PermissionDenied 31 | 32 | return session 33 | 34 | 35 | def get_collection(session): 36 | return Collection(session["name"], settings.DJANKISERV_DATA_ROOT) 37 | -------------------------------------------------------------------------------- /scripts/poetry-export.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # file: poetry-export.sh 3 | # description: Lock dependencies and export them as backward-compatible requirements.txt files. 4 | 5 | echo '[INFO] Updating poetry.lock file.' 6 | poetry lock 7 | 8 | echo '[INFO] Generating requirements.txt.' 9 | echo "# file: requirements.txt" > src/requirements.txt 10 | echo "# description: Dependencies. THE FILE WAS GENERATED BY POETRY, DO NOT EDIT!" >> src/requirements.txt 11 | printf "# date: $(date '+%Y-%m-%d')\n\n" >> src/requirements.txt 12 | 13 | echo '[INFO] Generating requirements-dev.txt.' 14 | echo "# file: requirements-dev.txt " > src/requirements-dev.txt 15 | echo "# description: Dev dependencies. THE FILE WAS GENERATED BY POETRY, DO NOT EDIT!" >> src/requirements-dev.txt 16 | printf "# date: $(date '+%Y-%m-%d')\n\n" >> src/requirements-dev.txt 17 | 18 | echo '[INFO] Generate requirement files for backward compatibility.' 19 | poetry export --without-hashes -f requirements.txt >> src/requirements.txt 20 | poetry export --dev --without-hashes -f requirements.txt >> src/requirements-dev.txt 21 | 22 | # Include editable install for src 23 | echo "-e src/." >> src/requirements-dev.txt 24 | -------------------------------------------------------------------------------- /src/djankiserv_utils/__init__.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | 4 | def print_request(request): 5 | try: 6 | if settings.DEBUG: 7 | print(pretty_request(request)) 8 | except NameError: 9 | pass # we haven't defined it, so can't be interested 10 | 11 | 12 | def pretty_request(request): 13 | headers = "" 14 | for header, value in request.META.items(): 15 | if not header.startswith("HTTP"): 16 | continue 17 | # header = "-".join([h.capitalize() for h in header[5:].lower().split("_")]) 18 | header = "-".join([h.capitalize() for h in header.lower().split("_")]) 19 | headers += "{}: {}\n".format(header, value) 20 | 21 | return ( 22 | "{path}\n" 23 | "{method} HTTP/1.1\n" 24 | "Content-Length: {content_length}\n" 25 | "Content-Type: {content_type}\n" 26 | "{headers}\n\n" 27 | "{body}\n\n" 28 | ).format( 29 | path=request.path, 30 | method=request.method, 31 | content_length=request.META.get("CONTENT_LENGTH"), 32 | content_type=request.META.get("CONTENT_TYPE"), 33 | headers=headers, 34 | body=request.data, 35 | ) 36 | -------------------------------------------------------------------------------- /src/djankiserv_api/views/decks.py: -------------------------------------------------------------------------------- 1 | 2 | from urllib import response 3 | from django.conf import settings 4 | from django.http import JsonResponse 5 | from django.views.decorators.csrf import csrf_exempt 6 | from rest_framework.decorators import api_view 7 | 8 | from djankiserv_unki.collection import Collection 9 | 10 | @csrf_exempt 11 | @api_view(["GET"]) 12 | def get_decks(request): 13 | decks = None 14 | with Collection(request.user.username, settings.DJANKISERV_DATA_ROOT) as col: 15 | decks = [value for key, value in dict(col.decks.decks).items()] 16 | 17 | response = {} 18 | response['pagination'] = {} 19 | response["pagination"]['count'] = len(decks) 20 | response['decks'] = decks 21 | return JsonResponse(response) 22 | 23 | 24 | @csrf_exempt 25 | @api_view(["GET"]) 26 | def get_deck_confs(request): 27 | conf = None 28 | with Collection(request.user.username, settings.DJANKISERV_DATA_ROOT) as col: 29 | conf = [value for key, value in dict(col.decks.dconf).items()] 30 | 31 | response = {} 32 | response['pagination'] = {} 33 | response['pagination']['count'] = len(conf) 34 | response['decksConf'] = conf 35 | return JsonResponse(response) 36 | 37 | 38 | -------------------------------------------------------------------------------- /tests/assets/up/modify_deck_conf/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [], 'decks': [[{'id': 1, 'mod': 1599273687, 'name': 'Default', 'usn': 1, 'lrnToday': [0, 0], 'revToday': [0, 0], 'newToday': [0, 0], 'timeToday': [0, 0], 'collapsed': False, 'browserCollapsed': False, 'desc': 'An options group description', 'dyn': 0, 'conf': 1, 'extendNew': 0, 'extendRev': 0}], [{'id': 1, 'mod': 1599273687, 'name': 'renamed_options_group', 'usn': 1, 'maxTaken': 61, 'autoplay': True, 'timer': 0, 'replayq': True, 'new': {'bury': False, 'delays': [1.0, 11.0], 'initialFactor': 1300, 'ints': [1, 4, 0], 'order': 1, 'perDay': 20}, 'rev': {'bury': False, 'ease4': 1.3, 'ivlFct': 1.0, 'maxIvl': 36500, 'perDay': 201, 'hardFactor': 1.2}, 'lapse': {'delays': [11.0], 'leechAction': 1, 'leechFails': 8, 'minInt': 1, 'mult': 0.0}, 'dyn': False}]], 'tags': [], 'conf': {'schedVer': 1, 'estTimes': True, 'curModel': 1599273529538, 'dayLearnFirst': False, 'curDeck': 1, 'dueCounts': True, 'nextPos': 2, 'sortType': 'noteFld', 'collapseTime': 1200, 'activeDecks': [1], 'addToCur': True, 'sortBackwards': False, 'timeLim': 0, 'newSpread': 0}, 'crt': 1599249600}} 6 | -------------------------------------------------------------------------------- /tests/assets/up/one_note_w_media/pre_upload.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO {schema_name}.col (id, crt, modified, scm, ver, dty, usn, ls, conf, models, decks, dconf, tags) VALUES (1, 1597809600, 1597885562514, 1597885562509, 11, 0, 0, 0, '{"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": null, "nextPos": 1, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "newBury": true}', '{}', '{"1": {"newToday": [0, 0], "revToday": [0, 0], "lrnToday": [0, 0], "timeToday": [0, 0], "conf": 1, "usn": 0, "desc": "", "dyn": 0, "collapsed": false, "extendNew": 10, "extendRev": 50, "id": 1, "name": "Default", "mod": 1597885562}}', '{"1": {"name": "Default", "new": {"delays": [1, 10], "ints": [1, 4, 7], "initialFactor": 2500, "separate": true, "order": 1, "perDay": 20, "bury": false}, "lapse": {"delays": [10], "mult": 0, "minInt": 1, "leechFails": 8, "leechAction": 0}, "rev": {"perDay": 200, "ease4": 1.3, "fuzz": 0.05, "minSpace": 1, "ivlFct": 1, "maxIvl": 36500, "bury": false, "hardFactor": 1.2}, "maxTaken": 60, "timer": 0, "autoplay": true, "replayq": true, "mod": 0, "usn": 0, "id": 1}}', '{}'); 2 | INSERT INTO {schema_name}.meta (dirmod, lastusn) VALUES (0, 0); 3 | -------------------------------------------------------------------------------- /src/djankiserv_sync/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.urls import path 4 | 5 | from djankiserv_sync import views 6 | 7 | urlpatterns = [ 8 | # /sync 9 | path("sync/start", views.base_start, name="sync_start"), 10 | path("sync/applyChanges", views.base_applyChanges, name="sync_applyChanges"), 11 | path("sync/applyGraves", views.base_applyGraves, name="sync_applyGraves"), 12 | path("sync/chunk", views.base_chunk, name="sync_chunk"), 13 | path("sync/applyChunk", views.base_applyChunk, name="sync_applyChunk"), 14 | path("sync/sanityCheck2", views.base_sanityCheck2, name="sync_sanityCheck2"), 15 | path("sync/finish", views.base_finish, name="sync_finish"), 16 | path("sync/meta", views.base_meta, name="meta"), 17 | path("sync/hostKey", views.base_hostKey, name="hostKey"), 18 | path("sync/upload", views.base_upload, name="upload"), 19 | path("sync/download", views.base_download, name="download"), 20 | # /msync 21 | path("msync/begin", views.media_begin, name="media_begin"), 22 | path("msync/mediaChanges", views.media_mediaChanges, name="media_mediaChanges"), 23 | path("msync/mediaSanity", views.media_mediaSanity, name="media_mediaSanity"), 24 | path("msync/uploadChanges", views.media_uploadChanges, name="media_uploadChanges"), 25 | path("msync/downloadFiles", views.media_downloadFiles, name="media_downloadFiles"), 26 | ] 27 | -------------------------------------------------------------------------------- /tests/assets/api/decks_conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "decks_conf": { 3 | "1": { 4 | "autoplay": true, 5 | "dyn": false, 6 | "id": 1, 7 | "lapse": { 8 | "delays": [ 9 | 10 10 | ], 11 | "leechAction": 0, 12 | "leechFails": 8, 13 | "minInt": 1, 14 | "mult": 0 15 | }, 16 | "maxTaken": 60, 17 | "mod": 0, 18 | "name": "Default", 19 | "new": { 20 | "bury": false, 21 | "delays": [ 22 | 1, 23 | 10 24 | ], 25 | "initialFactor": 2500, 26 | "ints": [ 27 | 1, 28 | 4, 29 | 7 30 | ], 31 | "order": 1, 32 | "perDay": 20, 33 | "separate": true 34 | }, 35 | "replayq": true, 36 | "rev": { 37 | "bury": false, 38 | "ease4": 1.3, 39 | "fuzz": 0.05, 40 | "hardFactor": 1.2, 41 | "ivlFct": 1, 42 | "maxIvl": 36500, 43 | "minSpace": 1, 44 | "perDay": 200 45 | }, 46 | "timer": 0, 47 | "usn": 0 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /scripts/helm/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "djankiserv.fullname" . -}} 3 | {{- $staticSvcPort := .Values.static.service.port -}} 4 | {{- $djankiservSvcPort := .Values.djankiserv.service.port -}} 5 | 6 | apiVersion: networking.k8s.io/v1 7 | kind: Ingress 8 | metadata: 9 | name: {{ $fullName }} 10 | labels: 11 | {{- include "djankiserv.labels" . | nindent 4 }} 12 | {{- with .Values.ingress.annotations }} 13 | annotations: 14 | {{- toYaml . | nindent 4 }} 15 | {{- end }} 16 | spec: 17 | {{- if .Values.ingress.tls }} 18 | tls: 19 | - hosts: 20 | - {{ required "A valid .Values.djankiserv.host entry required!" .Values.djankiserv.host | quote }} 21 | secretName: {{ .Values.ingress.tls.secretName }} 22 | {{- end }} 23 | rules: 24 | - host: {{ required "A valid .Values.djankiserv.host entry required!" .Values.djankiserv.host | quote }} 25 | http: 26 | paths: 27 | - path: /static/ 28 | pathType: Prefix 29 | backend: 30 | service: 31 | name: {{ $fullName }}-static 32 | port: 33 | number: {{ $staticSvcPort }} 34 | - path: / 35 | pathType: Prefix 36 | backend: 37 | service: 38 | name: {{ $fullName }} 39 | port: 40 | number: {{ $djankiservSvcPort }} 41 | {{- end }} 42 | -------------------------------------------------------------------------------- /scripts/helm/templates/static-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "djankiserv.fullname" . }}-static 5 | labels: 6 | {{- include "djankiserv.static.labels" . | nindent 4 }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | {{- include "djankiserv.static.selectorLabels" . | nindent 6 }} 11 | template: 12 | metadata: 13 | {{- with .Values.podAnnotations }} 14 | annotations: 15 | {{- toYaml . | nindent 8 }} 16 | {{- end }} 17 | labels: 18 | {{- include "djankiserv.static.selectorLabels" . | nindent 8 }} 19 | spec: 20 | containers: 21 | - name: {{ .Chart.Name }}-static 22 | securityContext: 23 | {{- toYaml .Values.securityContext | nindent 12 }} 24 | image: "{{ .Values.static.image.repository }}:{{ .Values.static.image.tag | default .Chart.AppVersion }}" 25 | imagePullPolicy: {{ .Values.static.image.pullPolicy }} 26 | # livenessProbe: 27 | # httpGet: 28 | # path: /health 29 | # port: http 30 | # readinessProbe: 31 | # httpGet: 32 | # path: /health 33 | # port: http 34 | resources: 35 | {{- toYaml .Values.resources | nindent 12 }} 36 | ports: 37 | - name: http 38 | containerPort: {{ .Values.static.listenPort }} 39 | protocol: TCP 40 | -------------------------------------------------------------------------------- /src/djankiserv_api/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.contrib import admin 4 | from django.urls import path 5 | from django.views.generic.base import RedirectView 6 | from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView 7 | 8 | from djankiserv_api import views 9 | 10 | from djankiserv_sync.urls import urlpatterns as sync_routes 11 | 12 | def routes(): 13 | routes = sync_routes 14 | routes.append(path("", RedirectView.as_view(url="/admin/"))) 15 | routes.append(path("admin/", admin.site.urls)) 16 | routes.append(path("health", views.health)) 17 | routes.append(path("api/v1/auth/token", TokenObtainPairView.as_view(), name="token_obtain_pair")) 18 | routes.append(path("api/v1/auth/refresh", TokenRefreshView.as_view(), name="token_refresh")) 19 | # TODO: api/v1/auth/revoke 20 | routes.append(path("api/v1/notes/add", views.add_notes, name="add_notes")) 21 | routes.append(path("api/v1/notes", views.get_notes, name="notes")) 22 | routes.append(path("api/v1/notes/delete", views.delete_notes, name="delete_notes")) 23 | routes.append(path("api/v1/decks", views.get_decks, name="decks")) 24 | routes.append(path("api/v1/decks/conf", views.get_deck_confs, name="decks_conf")) 25 | routes.append(path("api/v1/tags", views.tags, name="tags")) 26 | routes.append(path("api/v1/models", views.models, name="models")) 27 | return routes 28 | 29 | 30 | urlpatterns = routes() 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_one_added/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [{"sortf": 0, "did": 1, "latexPre": "\\\\documentclass[12pt]{article}\\n\\\\special{papersize=3in,5in}\\n\\\\usepackage[utf8]{inputenc}\\n\\\\usepackage{amssymb,amsmath}\\n\\\\pagestyle{empty}\\n\\\\setlength{\\\\parindent}{0in}\\n\\\\begin{document}\\n", "latexPost": "\\\\end{document}", "mod": 1597886003, "usn": 1, "vers": [], "type": 0, "css": ".card {\\n font-family: arial;\\n font-size: 20px;\\n text-align: center;\\n color: black;\\n background-color: white;\\n}\\n", "name": "Basic", "flds": [{"name": "Front", "ord": 0, "sticky": false, "rtl": false, "font": "Liberation Sans", "size": 20, "media": []}, {"name": "Back", "ord": 1, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "media": []}, {"name": "myimg", "ord": 2, "sticky": false, "rtl": false, "font": "Liberation Sans", "size": 20, "media": []}], "tmpls": [{"name": "Card 1", "ord": 0, "qfmt": "{{Front}}", "afmt": "{{FrontSide}}\\n\\n
\\n\\n{{Back}}", "did": null, "bqfmt": "", "bafmt": ""}], "tags": ["second_tag"], "id": "1597885581299", "req": [[0, "any", [0]]]}], "decks": [[], []], "tags": ["second_tag"], "conf": {"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": "1597885581299", "nextPos": 3, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "schedVer": 1, "newBury": true}, "crt": 1597867200}' 3 | -------------------------------------------------------------------------------- /tests/assets/up/two_notes_one_added/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [{'sortf': 0, 'did': 1, 'latexPre': '\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n', 'latexPost': '\\end{document}', 'mod': 1597886003, 'usn': 1, 'vers': [], 'type': 0, 'css': '.card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n', 'name': 'Basic', 'flds': [{'name': 'Front', 'ord': 0, 'sticky': False, 'rtl': False, 'font': 'Liberation Sans', 'size': 20, 'media': []}, {'name': 'Back', 'ord': 1, 'sticky': False, 'rtl': False, 'font': 'Arial', 'size': 20, 'media': []}, {'name': 'myimg', 'ord': 2, 'sticky': False, 'rtl': False, 'font': 'Liberation Sans', 'size': 20, 'media': []}], 'tmpls': [{'name': 'Card 1', 'ord': 0, 'qfmt': '{{Front}}', 'afmt': '{{FrontSide}}\n\n
\n\n{{Back}}', 'did': None, 'bqfmt': '', 'bafmt': ''}], 'tags': ['second_tag'], 'id': '1597885581299', 'req': [[0, 'any', [0]]]}], 'decks': [[], []], 'tags': ['second_tag'], 'conf': {'activeDecks': [1], 'curDeck': 1, 'newSpread': 0, 'collapseTime': 1200, 'timeLim': 0, 'estTimes': True, 'dueCounts': True, 'curModel': '1597885581299', 'nextPos': 3, 'sortType': 'noteFld', 'sortBackwards': False, 'addToCur': True, 'dayLearnFirst': False, 'schedVer': 1, 'newBury': True}, 'crt': 1597867200}} 6 | -------------------------------------------------------------------------------- /src/djankiserv/assets/jsonfiles/default_model.json: -------------------------------------------------------------------------------- 1 | { 2 | "1599180874580": { 3 | "sortf": 0, 4 | "did": 1, 5 | "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", 6 | "latexPost": "\\end{document}", 7 | "mod": 1599180906, 8 | "usn": -1, 9 | "vers": [], 10 | "type": 0, 11 | "css": ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", 12 | "name": "Basic", 13 | "flds": [ 14 | { 15 | "name": "Front", 16 | "ord": 0, 17 | "sticky": false, 18 | "rtl": false, 19 | "font": "Arial", 20 | "size": 20, 21 | "media": [] 22 | }, 23 | { 24 | "name": "Back", 25 | "ord": 1, 26 | "sticky": false, 27 | "rtl": false, 28 | "font": "Arial", 29 | "size": 20, 30 | "media": [] 31 | } 32 | ], 33 | "tmpls": [ 34 | { 35 | "name": "Card 1", 36 | "ord": 0, 37 | "qfmt": "{{Front}}", 38 | "afmt": "{{FrontSide}}\n\n
\n\n{{Back}}", 39 | "did": null, 40 | "bqfmt": "", 41 | "bafmt": "" 42 | } 43 | ], 44 | "tags": [], 45 | "id": "1599180874580", 46 | "req": [ 47 | [ 48 | 0, 49 | "all", 50 | [ 51 | 0 52 | ] 53 | ] 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/djankiserv_api/views/notes.py: -------------------------------------------------------------------------------- 1 | 2 | from django.conf import settings 3 | from django.http import JsonResponse 4 | from django.views.decorators.csrf import csrf_exempt 5 | from rest_framework.decorators import api_view, parser_classes 6 | from rest_framework.parsers import JSONParser 7 | 8 | from djankiserv_unki.collection import Collection 9 | 10 | @csrf_exempt 11 | @api_view(["POST"]) 12 | @parser_classes([JSONParser]) 13 | def add_notes(request): 14 | with Collection(request.user.username, settings.DJANKISERV_DATA_ROOT) as col: 15 | note_ids = [] 16 | for note in request.data["notes"]: 17 | note_ids.append(col.create_note(note, deck_name=request.data["deck"])) 18 | 19 | return JsonResponse({"note_ids": note_ids}) 20 | 21 | 22 | @csrf_exempt 23 | @api_view(["POST", "GET"]) 24 | @parser_classes([JSONParser]) 25 | def get_notes(request): 26 | with Collection(request.user.username, settings.DJANKISERV_DATA_ROOT) as col: 27 | notes = col.get_notes(request.data.get("ids")) 28 | 29 | return JsonResponse({"notes": [n.as_dict() for n in notes]}) 30 | 31 | 32 | @csrf_exempt 33 | @api_view(["POST"]) 34 | @parser_classes([JSONParser]) 35 | def delete_notes(request): 36 | with Collection(request.user.username, settings.DJANKISERV_DATA_ROOT) as col: 37 | note_ids = request.data.get("ids") 38 | if not note_ids: # is this a little dangerous maybe? 39 | note_ids = col.all_note_ids() 40 | col.rem_notes(note_ids) 41 | 42 | return JsonResponse({"status": "ok"}) 43 | 44 | -------------------------------------------------------------------------------- /tests/assets/down/two_notes_two_studied/post_applyChanges.json: -------------------------------------------------------------------------------- 1 | { 2 | "conf": { 3 | "activeDecks": [ 4 | 1 5 | ], 6 | "addToCur": true, 7 | "collapseTime": 1200, 8 | "curDeck": 1, 9 | "curModel": "1597885581299", 10 | "dayLearnFirst": false, 11 | "dueCounts": true, 12 | "estTimes": true, 13 | "newBury": true, 14 | "newSpread": 0, 15 | "nextPos": 3, 16 | "schedVer": 1, 17 | "sortBackwards": false, 18 | "sortType": "noteFld", 19 | "timeLim": 0 20 | }, 21 | "crt": 1597867200, 22 | "decks": [ 23 | [ 24 | { 25 | "collapsed": false, 26 | "conf": 1, 27 | "desc": "", 28 | "dyn": 0, 29 | "extendNew": 10, 30 | "extendRev": 50, 31 | "id": 1, 32 | "lrnToday": [ 33 | 0, 34 | 2 35 | ], 36 | "mod": 1597886093, 37 | "name": "Default", 38 | "newToday": [ 39 | 0, 40 | 2 41 | ], 42 | "revToday": [ 43 | 0, 44 | 0 45 | ], 46 | "timeToday": [ 47 | 0, 48 | 7765 49 | ], 50 | "usn": 3 51 | } 52 | ], 53 | [] 54 | ], 55 | "models": [], 56 | "tags": [] 57 | } 58 | -------------------------------------------------------------------------------- /scripts/helm/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .Values.djankiserv.host }} 4 | {{- else if contains "NodePort" .Values.service.type }} 5 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "djankiserv.fullname" . }}) 6 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 7 | echo http://$NODE_IP:$NODE_PORT 8 | {{- else if contains "LoadBalancer" .Values.service.type }} 9 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 10 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "djankiserv.fullname" . }}' 11 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "djankiserv.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 12 | echo http://$SERVICE_IP:{{ .Values.service.port }} 13 | {{- else if contains "ClusterIP" .Values.service.type }} 14 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "djankiserv.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 15 | echo "Visit http://127.0.0.1:8080 to use your application" 16 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /tests/assets/down/new_deck_one_new_card/post_applyChanges.txt: -------------------------------------------------------------------------------- 1 | Response Content: 2 | b'{"models": [{"sortf": 0, "did": 1598367050979, "latexPre": "\\\\documentclass[12pt]{article}\\n\\\\special{papersize=3in,5in}\\n\\\\usepackage[utf8]{inputenc}\\n\\\\usepackage{amssymb,amsmath}\\n\\\\pagestyle{empty}\\n\\\\setlength{\\\\parindent}{0in}\\n\\\\begin{document}\\n", "latexPost": "\\\\end{document}", "mod": 1598367068, "usn": 1, "vers": [], "type": 0, "css": ".card {\\n font-family: arial;\\n font-size: 20px;\\n text-align: center;\\n color: black;\\n background-color: white;\\n}\\n", "name": "Basic", "flds": [{"name": "Front", "ord": 0, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "media": []}, {"name": "Back", "ord": 1, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "media": []}], "tmpls": [{"name": "Card 1", "ord": 0, "qfmt": "{{Front}}", "afmt": "{{FrontSide}}\\n\\n
\\n\\n{{Back}}", "did": null, "bqfmt": "", "bafmt": ""}], "tags": ["second_tag"], "id": "1598366965257", "req": [[0, "any", [0]]]}], "decks": [[{"newToday": [0, 0], "revToday": [0, 0], "lrnToday": [0, 0], "timeToday": [0, 0], "conf": 1, "usn": 1, "desc": "", "dyn": 0, "collapsed": false, "extendNew": 10, "extendRev": 50, "name": "new_deck", "id": 1598367050979, "mod": 1598367050}], []], "tags": ["second_tag"], "conf": {"activeDecks": [1], "curDeck": 1, "newSpread": 0, "collapseTime": 1200, "timeLim": 0, "estTimes": true, "dueCounts": true, "curModel": "1598366965257", "nextPos": 3, "sortType": "noteFld", "sortBackwards": false, "addToCur": true, "dayLearnFirst": false, "schedVer": 1, "newBury": true}, "crt": 1598299200}' 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### OSX ### 4 | .DS_Store 5 | .AppleDouble 6 | .LSOverride 7 | 8 | # Icon must end with two \r 9 | Icon 10 | 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear on external disk 16 | .Spotlight-V100 17 | .Trashes 18 | 19 | # Directories potentially created on remote AFP share 20 | .AppleDB 21 | .AppleDesktop 22 | Network Trash Folder 23 | Temporary Items 24 | .apdisk 25 | 26 | 27 | ### Python ### 28 | # Byte-compiled / optimized / DLL files 29 | __pycache__/ 30 | *.py[cod] 31 | 32 | # C extensions 33 | *.so 34 | 35 | # Distribution / packaging 36 | .Python 37 | env/ 38 | build/ 39 | develop-eggs/ 40 | dist/ 41 | downloads/ 42 | eggs/ 43 | lib/ 44 | lib64/ 45 | parts/ 46 | sdist/ 47 | var/ 48 | *.egg-info/ 49 | .installed.cfg 50 | *.egg 51 | 52 | # PyInstaller 53 | # Usually these files are written by a python script from a template 54 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 55 | *.manifest 56 | *.spec 57 | 58 | # Installer logs 59 | pip-log.txt 60 | pip-delete-this-directory.txt 61 | 62 | # Unit test / coverage reports 63 | htmlcov/ 64 | .tox/ 65 | .coverage 66 | .cache 67 | nosetests.xml 68 | coverage.xml 69 | 70 | # Translations 71 | *.mo 72 | *.pot 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | target/ 79 | 80 | ### Django ### 81 | *.log 82 | *.pot 83 | *.pyc 84 | __pycache__/ 85 | local_settings.py 86 | 87 | # Added 88 | .env 89 | db.sqlite3 90 | /static/ 91 | /instances/ 92 | docker-compose.yml 93 | .local_setup.sh 94 | # should these be in git? 95 | chart/djankiserv/charts/*.tgz 96 | build/* 97 | -------------------------------------------------------------------------------- /tests/assets/up/new_deck_one_new_card/pre_applyChanges.txt: -------------------------------------------------------------------------------- 1 | POST: 2 | 3 | 4 | DATA: 5 | {'changes': {'models': [{'sortf': 0, 'did': 1598367050979, 'latexPre': '\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n', 'latexPost': '\\end{document}', 'mod': 1598367068, 'usn': 1, 'vers': [], 'type': 0, 'css': '.card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n', 'name': 'Basic', 'flds': [{'name': 'Front', 'ord': 0, 'sticky': False, 'rtl': False, 'font': 'Arial', 'size': 20, 'media': []}, {'name': 'Back', 'ord': 1, 'sticky': False, 'rtl': False, 'font': 'Arial', 'size': 20, 'media': []}], 'tmpls': [{'name': 'Card 1', 'ord': 0, 'qfmt': '{{Front}}', 'afmt': '{{FrontSide}}\n\n
\n\n{{Back}}', 'did': None, 'bqfmt': '', 'bafmt': ''}], 'tags': ['second_tag'], 'id': '1598366965257', 'req': [[0, 'any', [0]]]}], 'decks': [[{'newToday': [0, 0], 'revToday': [0, 0], 'lrnToday': [0, 0], 'timeToday': [0, 0], 'conf': 1, 'usn': 1, 'desc': '', 'dyn': 0, 'collapsed': False, 'extendNew': 10, 'extendRev': 50, 'name': 'new_deck', 'id': 1598367050979, 'mod': 1598367050}], []], 'tags': ['second_tag'], 'conf': {'activeDecks': [1], 'curDeck': 1, 'newSpread': 0, 'collapseTime': 1200, 'timeLim': 0, 'estTimes': True, 'dueCounts': True, 'curModel': '1598366965257', 'nextPos': 3, 'sortType': 'noteFld', 'sortBackwards': False, 'addToCur': True, 'dayLearnFirst': False, 'schedVer': 1, 'newBury': True}, 'crt': 1598299200}} 6 | --------------------------------------------------------------------------------