anki-sync-server/src/ankisyncd/full_sync/manager.py
2022-10-14 23:36:13 +01:00

75 lines
2.2 KiB
Python

import shutil
from sqlite3 import dbapi2 as sqlite
from anki.db import DB
from anki.collection import Collection
from ankisyncd.exceptions import BadRequestException
class FullSyncManager:
def test_db(self, db: DB):
"""
:param anki.db.DB db: the database uploaded from the client.
"""
if db.scalar("pragma integrity_check") != "ok":
raise BadRequestException(
"Integrity check failed for uploaded collection database file."
)
def upload(self, col: Collection, data: bytes, session) -> str:
"""
Uploads a sqlite database from the client to the sync server.
:param anki.collection.Collectio col:
:param bytes data: The binary sqlite database from the client.
:param .sync_app.SyncUserSession session: The current session.
"""
# Verify integrity of the received database file before replacing our
# existing db.
temp_db_path = session.get_collection_path() + ".tmp"
with open(temp_db_path, "wb") as f:
f.write(data)
try:
with DB(temp_db_path) as test_db:
self.test_db(test_db)
except sqlite.Error as e:
raise BadRequestException(
"Uploaded collection database file is " "corrupt."
)
# Overwrite existing db.
col.close()
try:
shutil.copyfile(temp_db_path, session.get_collection_path())
finally:
col.reopen()
# Reopen the media database
col.media.connect()
return "OK"
def download(self, col: Collection, session) -> bytes:
"""Download the binary database.
Performs a downgrade to database schema 11 before sending the database
to the client.
:param anki.collection.Collection col:
:param .sync_app.SyncUserSession session:
:return bytes: the binary sqlite3 database
"""
col.close(downgrade=True)
db_path = session.get_collection_path()
try:
with open(db_path, "rb") as tmp:
data = tmp.read()
finally:
col.reopen()
# Reopen the media database
col.media.connect()
return data