From ad065fc8c9204e6d63b7fb69b1d9cf469812237f Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 4 May 2017 15:59:47 +0200 Subject: [doc] add attachments documentation --- client/src/leap/soledad/client/_document.py | 5 +- docs/sphinx/.gitignore | 1 + docs/sphinx/Makefile | 20 ++++++++ docs/sphinx/attachments.rst | 77 +++++++++++++++++++++++++++++ docs/sphinx/conf.py | 1 + docs/sphinx/index.rst | 1 + docs/sphinx/requirements.pip | 2 + 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 docs/sphinx/.gitignore create mode 100644 docs/sphinx/Makefile create mode 100644 docs/sphinx/attachments.rst create mode 100644 docs/sphinx/requirements.pip diff --git a/client/src/leap/soledad/client/_document.py b/client/src/leap/soledad/client/_document.py index 89e75fa2..38026f20 100644 --- a/client/src/leap/soledad/client/_document.py +++ b/client/src/leap/soledad/client/_document.py @@ -107,8 +107,9 @@ class IDocumentWithAttachment(Interface): Return whether this document's content differs from the contents stored in local database. - :return: Whether this document is dirty or not. - :rtype: bool + :return: A deferred which fires with True or False, depending on + whether this document is dirty or not. + :rtype: Deferred """ def upload_attachment(self): diff --git a/docs/sphinx/.gitignore b/docs/sphinx/.gitignore new file mode 100644 index 00000000..e35d8850 --- /dev/null +++ b/docs/sphinx/.gitignore @@ -0,0 +1 @@ +_build diff --git a/docs/sphinx/Makefile b/docs/sphinx/Makefile new file mode 100644 index 00000000..dcc387ce --- /dev/null +++ b/docs/sphinx/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = Soledad +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/sphinx/attachments.rst b/docs/sphinx/attachments.rst new file mode 100644 index 00000000..098f634f --- /dev/null +++ b/docs/sphinx/attachments.rst @@ -0,0 +1,77 @@ +Document Attachments +==================== + +.. contents:: Contents: + :local: + +The content of a Soledad document is assumed to be JSON. This is particularly +bad for storing larger amounts of binary data, because: + +* the only way to store data in JSON is as unicode string, and this uses more + space than needed for binary data storage. + +* the process of synchronization of Soledad documents depends on completing the + transfer and decryption of the content of all new/updated documents before + synchronized documents are available for use. + +Document attachments were introduced as a means to store large payloads of +binary data and have them be synchronized separate from the usual Soledad +document synchronization process. + +Example +------- + +The attachments API is currently available in the `Document` class, and the +document needs to know about the store to be able to manage attachments. When +you create a new document with soledad, that document will already know about +the store that created it, and can put/get/delete an attachment: + +.. code-block:: python + + from twisted.internet.defer import inlineCallbacks + + @inlineCallbacks + def attachment_example(soledad): + doc = yield soledad.create_doc({}) + + state = yield doc.get_attachment_state() + dirty = yield doc.is_dirty() + assert state == AttachmentStates.NONE + assert dirty == False + + yield doc.put_attachment(open('hackers.txt')) + state = yield doc.get_attachment_state() + dirty = yield doc.is_dirty() + assert state | AttachmentState.LOCAL + assert dirty == True + + yield soledad.put_doc(doc) + dirty = yield doc.is_dirty() + assert dirty == False + + yield doc.upload_attachment() + state = yield doc.get_attachment_state() + assert state | AttachmentState.REMOTE + assert state == AttachmentState.SYNCED + + fd = yield doc.get_attachment() + assert fd.read() == open('hackers.txt').read() + +Implementation +-------------- + +The current implementation of document attachments store data in a separate +SQLCipher database in the client (using SQLite's BLOB type) and in the +filesystem in the server. Encryption of data before it's sent to the server is +the same used by normal Soledad synchronization process (AES-256 GCM mode). + +Document attachment API +----------------------- + +.. autoclass:: leap.soledad.client._document.AttachmentStates + :members: + :undoc-members: + +.. autointerface:: leap.soledad.client._document.IDocumentWithAttachment + :members: + :undoc-members: diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index bad9da6e..38ff330f 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -36,6 +36,7 @@ extensions = [ 'sphinx.ext.coverage', 'sphinx.ext.imgmath', 'sphinx.ext.viewcode', + 'sphinxcontrib.zopeext.autointerface', ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/sphinx/index.rst b/docs/sphinx/index.rst index c4ccffc9..6800ee42 100644 --- a/docs/sphinx/index.rst +++ b/docs/sphinx/index.rst @@ -14,6 +14,7 @@ all user's devices that access a LEAP provider. :maxdepth: 2 client + attachments server Indices and tables diff --git a/docs/sphinx/requirements.pip b/docs/sphinx/requirements.pip new file mode 100644 index 00000000..39055139 --- /dev/null +++ b/docs/sphinx/requirements.pip @@ -0,0 +1,2 @@ +sphinx +sphinxcontrib-zopeext -- cgit v1.2.3