diff options
| -rw-r--r-- | client/src/leap/soledad/client/http_target/__init__.py | 2 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/http_target/api.py | 16 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/http_target/fetch.py | 6 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/http_target/send.py | 12 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/http_target/support.py | 40 | ||||
| -rw-r--r-- | common/src/leap/soledad/common/couch.py | 16 | 
6 files changed, 77 insertions, 15 deletions
| diff --git a/client/src/leap/soledad/client/http_target/__init__.py b/client/src/leap/soledad/client/http_target/__init__.py index e77d20f5..7fa33153 100644 --- a/client/src/leap/soledad/client/http_target/__init__.py +++ b/client/src/leap/soledad/client/http_target/__init__.py @@ -1,5 +1,5 @@  # -*- coding: utf-8 -*- -# http_target.py +# __init__.py  # Copyright (C) 2015 LEAP  #  # This program is free software: you can redistribute it and/or modify diff --git a/client/src/leap/soledad/client/http_target/api.py b/client/src/leap/soledad/client/http_target/api.py index 9e677304..344d999c 100644 --- a/client/src/leap/soledad/client/http_target/api.py +++ b/client/src/leap/soledad/client/http_target/api.py @@ -1,3 +1,19 @@ +# -*- coding: utf-8 -*- +# api.py +# Copyright (C) 2015 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>.  import json  import base64 diff --git a/client/src/leap/soledad/client/http_target/fetch.py b/client/src/leap/soledad/client/http_target/fetch.py index c4bb79a0..aa02063a 100644 --- a/client/src/leap/soledad/client/http_target/fetch.py +++ b/client/src/leap/soledad/client/http_target/fetch.py @@ -1,5 +1,5 @@  # -*- coding: utf-8 -*- -# http_target.py +# fetch.py  # Copyright (C) 2015 LEAP  #  # This program is free software: you can redistribute it and/or modify @@ -164,7 +164,7 @@ class HTTPDocFetcher(object):              # end of symmetric decryption              # -------------------------------------------------------------          self._received_docs += 1 -        _emit_received(self._received_docs, total) +        _emit_receive_status(self._received_docs, total)          return number_of_changes, new_generation, new_transaction_id      def _parse_received_doc_response(self, response): @@ -231,7 +231,7 @@ class HTTPDocFetcher(object):                  source_replica_uid=self.source_replica_uid) -def _emit_received(received_docs, total): +def _emit_receive_status(received_docs, total):      msg = "%d/%d" % (received_docs, total)      emit(SOLEDAD_SYNC_RECEIVE_STATUS, msg)      logger.debug("Sync receive status: %s" % msg) diff --git a/client/src/leap/soledad/client/http_target/send.py b/client/src/leap/soledad/client/http_target/send.py index de18df8b..a6e64908 100644 --- a/client/src/leap/soledad/client/http_target/send.py +++ b/client/src/leap/soledad/client/http_target/send.py @@ -1,5 +1,5 @@  # -*- coding: utf-8 -*- -# http_target.py +# send.py  # Copyright (C) 2015 LEAP  #  # This program is free software: you can redistribute it and/or modify @@ -33,13 +33,13 @@ class HTTPDocSender(object):              defer.returnValue([None, None])          # add remote replica metadata to the request -        initial_body = RequestBody( +        metadata = RequestBody(              last_known_generation=last_known_generation,              last_known_trans_id=last_known_trans_id,              sync_id=sync_id,              ensure=self._ensure_callback is not None)          total = len(docs_by_generation) -        entries = yield self._entries_from_docs(initial_body, docs_by_generation) +        entries = yield self._entries_from_docs(metadata, docs_by_generation)          while len(entries):              result = yield self._http_request(                  self._url, @@ -49,14 +49,14 @@ class HTTPDocSender(object):              idx = total - len(entries)              if self._defer_encryption:                  self._delete_sent(idx, docs_by_generation) -            _emit_send(idx, total) +            _emit_send_status(idx, total)          response_dict = json.loads(result)[0]          gen_after_send = response_dict['new_generation']          trans_id_after_send = response_dict['new_transaction_id']          defer.returnValue([gen_after_send, trans_id_after_send])      def _delete_sent(self, idx, docs_by_generation): -        doc = docs_by_generation[idx][0] +        doc = docs_by_generation[idx - 1][0]          self._sync_enc_pool.delete_encrypted_doc(              doc.doc_id, doc.rev) @@ -93,7 +93,7 @@ class HTTPDocSender(object):          return d -def _emit_send(idx, total): +def _emit_send_status(idx, total):      msg = "%d/%d" % (idx, total)      emit(          SOLEDAD_SYNC_SEND_STATUS, diff --git a/client/src/leap/soledad/client/http_target/support.py b/client/src/leap/soledad/client/http_target/support.py index 88934636..363a4f7d 100644 --- a/client/src/leap/soledad/client/http_target/support.py +++ b/client/src/leap/soledad/client/http_target/support.py @@ -1,5 +1,5 @@  # -*- coding: utf-8 -*- -# http_target.py +# support.py  # Copyright (C) 2015 LEAP  #  # This program is free software: you can redistribute it and/or modify @@ -128,17 +128,47 @@ def readBody(response):  class RequestBody(object): +    """ +    This class is a helper to generate send and fetch requests. +    The expected format is something like: +    [ +    {headers}, +    {entry1}, +    {...}, +    {entryN}, +    ] +    """      def __init__(self, **header_dict): +        """ +        Creates a new RequestBody holding header information. + +        @param header_dict: A dictionary with the headers. +        """          self.headers = header_dict          self.entries = []      def insert_info(self, **entry_dict): +        """ +        Dumps an entry into JSON format and add it to entries list. + +        @param entry_dicts: Entry as a dictionary + +        @return: length of the entry after JSON dumps +        """          entry = json.dumps(entry_dict)          self.entries.append(entry)          return len(entry)      def remove(self, number=1): +        """ +        Removes an amount of entries and returns it formatted and ready +        to be sent. + +        @param number: number of entries to remove and format + +        @return: formatted body ready to be sent +        """          entries = [self.entries.pop(0) for i in xrange(number)]          return self.entries_to_str(entries) @@ -149,6 +179,14 @@ class RequestBody(object):          return len(self.entries)      def entries_to_str(self, entries=None): +        """ +        Format a list of entries into the body format expected +        by the server. + +        @param entries: entries to format + +        @return: formatted body ready to be sent +        """          data = '[\r\n' + json.dumps(self.headers)          data += ''.join(',\r\n' + entry for entry in entries)          return data + '\r\n]' diff --git a/common/src/leap/soledad/common/couch.py b/common/src/leap/soledad/common/couch.py index 3ae79382..90f1a36f 100644 --- a/common/src/leap/soledad/common/couch.py +++ b/common/src/leap/soledad/common/couch.py @@ -158,10 +158,11 @@ class CouchDocument(SoledadDocument):              self.content = new_doc.content          self.has_conflicts = new_doc.has_conflicts -    def _prune_conflicts(self, doc_vcr, autoresolved_increment): +    def prune_conflicts(self, doc_vcr, autoresolved_increment):          """          Prune conflicts that are older then the current document's revision, or          whose content match to the current document's content. +        Originally in u1db.CommonBackend          :param doc: The document to have conflicts pruned.          :type doc: CouchDocument @@ -1206,7 +1207,7 @@ class CouchDatabase(CommonBackend):          :type doc: CouchDocument          """          my_doc = self._get_doc(doc.doc_id, check_for_conflicts=True) -        doc._prune_conflicts(vectorclock.VectorClockRev(doc.rev), self._replica_uid) +        doc.prune_conflicts(vectorclock.VectorClockRev(doc.rev), self._replica_uid)          doc.add_conflict(my_doc)          self._put_doc(my_doc, doc) @@ -1388,6 +1389,13 @@ class CouchDatabase(CommonBackend):                  continue              yield t._doc +    def _prune_conflicts(self, doc, doc_vcr): +        """ +        Overrides original method, but it is implemented elsewhere for +        simplicity. +        """ +        doc.prune_conflicts(doc_vcr, self._replica_uid) +      def _new_resource(self, *path):          """          Return a new resource for accessing a couch database. @@ -1506,7 +1514,7 @@ def _process_incoming_doc(my_doc, other_doc, save_conflict, replica_uid):      cur_vcr = vectorclock.VectorClockRev(my_doc.rev)      if doc_vcr.is_newer(cur_vcr):          rev = new_doc.rev -        new_doc._prune_conflicts(doc_vcr, replica_uid) +        new_doc.prune_conflicts(doc_vcr, replica_uid)          if new_doc.rev != rev:              # conflicts have been autoresolved              return 'superseded', new_doc @@ -1529,7 +1537,7 @@ def _process_incoming_doc(my_doc, other_doc, save_conflict, replica_uid):          return 'superseded', new_doc      else:          if save_conflict: -            new_doc._prune_conflicts(vectorclock.VectorClockRev(new_doc.rev), replica_uid) +            new_doc.prune_conflicts(vectorclock.VectorClockRev(new_doc.rev), replica_uid)              new_doc.add_conflict(my_doc)              return 'conflicted', new_doc          other_doc.update(new_doc) | 
