[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