[Nym3-commit] r469 - in trunk/nymbaron: . Client Server
jr at conuropsis.org
jr at conuropsis.org
Sun Mar 12 16:08:27 CET 2006
Author: jr
Date: 2006-03-12 16:08:26 +0100 (Sun, 12 Mar 2006)
New Revision: 469
Modified:
trunk/nymbaron/Client/Account.py
trunk/nymbaron/Client/Main.py
trunk/nymbaron/Common.py
trunk/nymbaron/Server/Main.py
trunk/nymbaron/Server/User.py
Log:
- make binsearch throw an exception if nothing is found instead of returning it
- change the meaning of the server-side synbox format
- midAfter and prepareSummary processing this new format
-> the behaviour of prepareSummary maybe detailed or changed later
- add TODO comments at points where a choice open to discussion has been made
Modified: trunk/nymbaron/Client/Account.py
===================================================================
--- trunk/nymbaron/Client/Account.py 2006-03-09 00:41:32 UTC (rev 468)
+++ trunk/nymbaron/Client/Account.py 2006-03-12 15:08:26 UTC (rev 469)
@@ -57,9 +57,13 @@
(ie a tuple (dict, seq)."""
#Add to the hash
if h.has_key(mid):
- #TODO what should be done here?
- raise Exception("Bug mid not unique")
+ #We assume the syn has already been added to the synbox.
+ #therefore, we do nothing
+ #we should warn the user here
+ return
h[mid] = (xnymseq, flag, syn)
+ #TODO check the xnymseq is older than the last present in the synbox
+
#Add to the list
#if sorted it is quick to insert from the end
if sorted:
@@ -73,8 +77,11 @@
#else we use a binary search
else:
#look for the first mid whose seq number is greater than xnymseq
- i = binsearch(l, lambda x: (h[x][0] > xnymseq))
- l[i:i] = [mid]
+ try:
+ i = binsearch(l, lambda x: (h[x][0] > xnymseq))
+ l[i:i] = [mid]
+ except IndexError:
+ l.append(mid)
class NoSuchAccount(Exception): pass
"""Exception thrown when a user identified by her nym can't be found"""
Modified: trunk/nymbaron/Client/Main.py
===================================================================
--- trunk/nymbaron/Client/Main.py 2006-03-09 00:41:32 UTC (rev 468)
+++ trunk/nymbaron/Client/Main.py 2006-03-12 15:08:26 UTC (rev 469)
@@ -303,7 +303,10 @@
elif (com.ct() == SToCCODE['Summary']):
# Check the Summary for emptiness
if not com.synSet:
- ui.display("No new synopsis available")
+ #TODO ref to a documentation
+ #TODO check compliance with specifications
+ ui.display("No new synopsis available or maximal number of " + \
+ "synopses asked too low")
return
# We need to decrypt the set of synopsis to retrieve the MIDs
secring = decode_secring(config, ui)
Modified: trunk/nymbaron/Common.py
===================================================================
--- trunk/nymbaron/Common.py 2006-03-09 00:41:32 UTC (rev 468)
+++ trunk/nymbaron/Common.py 2006-03-12 15:08:26 UTC (rev 469)
@@ -47,11 +47,12 @@
def binsearch(slist, prop):
"""Returns the first index i of slist for which slist[i] is true,
- assuming prop is increasing over slist"""
+ assuming prop is increasing over slist. If there is no such element raise
+ IndexError."""
minindex = 0
maxindex = len(slist) - 1
if not prop(slist[maxindex]):
- return IndexError
+ raise IndexError
if prop(slist[minindex]):
return minindex
Modified: trunk/nymbaron/Server/Main.py
===================================================================
--- trunk/nymbaron/Server/Main.py 2006-03-09 00:41:32 UTC (rev 468)
+++ trunk/nymbaron/Server/Main.py 2006-03-12 15:08:26 UTC (rev 469)
@@ -372,6 +372,7 @@
msg = readMessage(options.file)
processMessage(msg)
except Exception: #TODO catch a more detailed exception
+ #since it is currently masking exceptions due to bugs
# see if we got a base64 encoded message.
m = re.search("binary\\n\\n(.*)\\n---", msg, re.S)
if m:
Modified: trunk/nymbaron/Server/User.py
===================================================================
--- trunk/nymbaron/Server/User.py 2006-03-09 00:41:32 UTC (rev 468)
+++ trunk/nymbaron/Server/User.py 2006-03-12 15:08:26 UTC (rev 469)
@@ -140,15 +140,23 @@
messages)
- usage is the volume of data in the account on the server
- quota is the maximum volume of data in the account on the server
- - index is a dictionary mid -> (time, status) where time is the time at
- which the message was received, and status describes the status of the
- message (whereas synopsis was sent, wheres message has been
+ - index is a dictionary mid -> {time:, status:} where time is the time
+ at which the message was received, and status describes the status of
+ the message (whereas synopsis was sent, wheres message has been
deleted...)
- mbox is a dictionary mid -> encrypted message
- syn is a list of (l, status, content) where l is the list of mids
whose synopsis is in the content, status tells whether the content is
encrypted or not and content contains the synopsis or encrypted
- synopses"""
+ synopses.
+ Before r470, there was no other constraints on this list. To simplify
+ the functions processing the synbox, we now suppose that elements of
+ the list are sorted by ascending nymseq :
+ - for i < j all mids in syn[i][0] are older than mids in syn[j][0],
+ - if syn[k] is encrypted, for i < j syn[k][0][i] is older than
+ syn[k][0][j].
+ Furthermore the list can be decomposed in syn = syn1 + syn2 where the
+ status of elements in syn1 is encrypted and in syn2 is clear"""
def __init__(self, username, config, create = 0):
"""0 : load user data throw an error if the user doesn't exist
1 : create user data throw an error if the user exists
@@ -295,22 +303,63 @@
except:
raise ValueError()
- def midAfter(self, mid):
+ def midAfter(self, mid, num = -1):
"""Retrieve mids of messages that came strictly after message `mid'
the elements of the output are ordered by ascending
- order of arrival time"""
+ order of arrival time. A list of num mids is returned unless num = -1,
+ in which case all possible mids are returned"""
self.load_index()
ret = []
+ #i: the first index so that all mids in syn[i][0] are older than "mid"
+ if mid == Mail.oldestMid:
+ i = 0;
#TODO if the mid can't be found in the index tab, what do we do?
- if mid == Mail.oldestMid:
- ret = self.index.keys()
+ #for the time being act as if there are no mid after an bad mid
+ #maybe we should sendan error message
+ elif not self.index.has_key(mid):
+ return []
else:
- midtime = self.index[mid]['time']
- for msg in self.index.keys():
- if self.index[msg]['time'] > midtime:
- ret.append(msg)
- ret.sort(self.timecmp)
+ after = self.index[mid]['time']
+ propoldblob = lambda x: self.index[x[0][0]]['time'] > after
+ propoldmid = lambda x: self.index[x]['time'] > after
+ try:
+ i = binsearch(self.syn, propoldblob)
+ except IndexError:
+ #There may be mids at the end of the last blob
+ nmids = self.syn[-1][0]
+ try:
+ j = binsearch(nmids, propoldmid)
+ if num < 0:
+ return nmids[j:]
+ else:
+ return nmids[j:j+num]
+ except IndexError:
+ #mid is the last syn of the synbox
+ return []
+
+ #There may be mids in the previous blob older than "mid"
+ if i > 0:
+ pmids = self.syn[i-1][0]
+ try:
+ j = binsearch(pmids, propoldmid)
+ if num < 0:
+ ret = pmids[j:]
+ else:
+ ret = pmids[j:j+num]
+ except IndexError:
+ #There are no relevant mids in pmids
+ pass
+
+ #Add mids to ret while we can
+ for t in self.syn[i:]:
+ if num < 0:
+ ret = ret + t[0]
+ else:
+ ret = ret + t[0]
+ if len(ret) >= num:
+ return ret[:num]
+
return ret
def _save_data(self):
@@ -617,7 +666,8 @@
"""Encrypt synopsis we had in clear for too long"""
try:
firstclear = binsearch(self.syn, lambda x: (x[1] == 'clear'))
- except: return
+ except IndexError:
+ return
offset = firstclear
last = len(self.syn)
@@ -637,7 +687,9 @@
propyoung = lambda x: self.index[x[0][0]]['time'] +\
self['EncryptSummaryAfter'] * 30 * 60 > now
fyoung = binsearch(self.syn[offset:], propyoung)
- except:
+ except IndexError:
+ #TODO this is not right, since it will not encrypt the last
+ #element of the synbox as it should
fyoung = last
self.encryptSyn(offset, fyoung)
@@ -672,44 +724,57 @@
self.load_synbox()
self.load_mbox()
# Prepare the midList.
- midList = self.midAfter(after)[:num]
+ midList = self.midAfter(after,num)
if len(midList) == 0:
return []
ret = []
# Hold the clear syn
- clearlist = []
nsyn = 0
- while midList and (len(clearlist) + nsyn < num):
+ firstclear = None
+ nclear = 0
+ while midList and (nclear + nsyn < num):
# look for the synblob containing midList[0]
try:
i, u = self.getSyn(midList[0])
+ del midList[0]
except:
- self.syn = self.syn + clearlist
- print str(midList)
- print str(self.syn)
- print "Doh. Exception."
- return ret
+ #This should not happen, it would mean a broken synbox
+ #TODO log something
+ #code commented before being erased
+ #self.syn = self.syn + clearlist
+ #print str(midList)
+ #print str(self.syn)
+ #print "Doh. Exception."
+ #return ret
+ sys.exit(2)
if u[1] == 'clear':
- clearlist.append(u)
- del self.syn[i]
- del midList[0]
- if len(clearlist) == 8:
- foo = self.blobify(clearlist)
- self.syn.append(foo)
- ret.append(bfprepare(foo))
+ #the following mids will also be held in clear.
+ #if nclear = 0, this is the firstclear
+ if nclear == 0:
+ firstclear = i
+ nclear += 1
+ #we have enough clear syn to form a block
+ #TODO evil numeric constant?
+ if nclear == 8:
+ self.encryptSyn(firstclear, firstclear+nclear)
+ nclear = 0
+ ret.append(bfprepare(self.syn[firstclear]))
nsyn += 8
- clearlist = []
continue
elif u[1] == 'encrypted':
for i in u[0]:
if i in midList:
midList.remove(i)
# Can we afford to add this blob?
- if len(u[0]) + nsyn + len(clearlist) > num:
- continue
+ if len(u[0]) + nsyn > num:
+ #before we had here a continue. That's not the right play,
+ #since we need to guarantee the order of summaries sent
+ #If we cannot add an encrypted blob, we stop here.
+ break
ret.append(bfprepare(u))
- if clearlist:
- foo = self.blobify(clearlist)
- self.syn.append(foo)
- ret.append(bfprepare(foo))
+ #If there are still clear mids to add we need to create a blob with less
+ #than the max number of syns, in order to send them
+ if nclear:
+ self.encryptSyn(firstclear, firstclear+nclear)
+ ret.append(bfprepare(self.syn[firstclear]))
return ret
More information about the Nym3-commit
mailing list