From 8654021f8719cf9d0f17f9d58e4455074aa43bb9 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Wed, 19 Aug 2015 19:09:59 -0300 Subject: [bug] fixes small issues pointed by drebs * file headers * variable names * missing docstrings * prune_conflicts ** extra: tests failed on a 1-based index bug --- .../leap/soledad/client/http_target/__init__.py | 2 +- client/src/leap/soledad/client/http_target/api.py | 16 +++++++++ .../src/leap/soledad/client/http_target/fetch.py | 6 ++-- client/src/leap/soledad/client/http_target/send.py | 12 +++---- .../src/leap/soledad/client/http_target/support.py | 40 +++++++++++++++++++++- 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 . 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) -- cgit v1.2.3