[Nym3-commit] r172 - trunk/nym3/Client

laurent at conuropsis.org laurent at conuropsis.org
Mon Apr 4 22:11:41 CEST 2005


Author: laurent
Date: 2005-04-04 22:11:37 +0200 (Mon, 04 Apr 2005)
New Revision: 172

Added:
   trunk/nym3/Client/Account.py
Removed:
   trunk/nym3/Client/User.py
Modified:
   trunk/nym3/Client/Main.py
   trunk/nym3/Client/README.Dev
Log:
Rename User.py to Account.py and work on it.


Copied: trunk/nym3/Client/Account.py (from rev 170, trunk/nym3/Client/User.py)
===================================================================
--- trunk/nym3/Client/User.py	2005-04-02 21:39:38 UTC (rev 170)
+++ trunk/nym3/Client/Account.py	2005-04-04 20:11:37 UTC (rev 172)
@@ -0,0 +1,273 @@
+# $Id$
+# -*- coding: iso-8859-1 -*-
+# Copyright (c) 2004,2005 Jean-René Reinhard <jr at komite.net>
+# and Laurent Fousse <laurent at komite.net>.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to
+# do so, provided that the above copyright notice(s) and this permission
+# notice appear in all copies of the Software and that both the above
+# copyright notice(s) and this permission notice appear in supporting
+# documentation.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
+# LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""Contains user account information on the client side
++ way to create, access and modify them"""
+
+import os
+import nym3.Client.Config as Config
+import nym3.Mail as Mail
+import mixminion.Common
+import nym3.Common as Common
+import mixminion.Crypto as _cr
+import nym3.Message as Message
+import mixminion.ClientAPI as mapi
+import pickle
+
+class NoSuchAccount(Exception): pass
+"""Exception thrown when a user identified by her nym can't be found"""
+
+class AlreadySuchAccount(Exception): pass
+"""Exception thrown when a user identified by her nym already exists"""
+
+class TagMap:
+    """Contains mapping between idTag and nickname"""
+    def __init__(self):
+        self.id2nick = {}
+        self.nick2id = {}
+
+    def _lock(self):
+        """Lock the tagmap file"""
+        self.lock = mixminion.Common.Lockfile(Config.path + os.sep +
+					      'tagmap.lck')
+        self.lock.acquire()
+
+    def _release(self):
+        self.lock.release()
+
+    def _tagfile(self):
+        return Config.path + os.sep + "tagmap" 
+
+    def _load(self):
+	tag = self._tagfile()
+	try:
+	    f = open(tag, 'r')
+	    self.id2nick = pickle.load(f)
+	    f.close()
+	except IOError:
+	    self.id2nick = {}
+	for i in self.id2nick.keys():
+	    self.nick2id[self.id2nick[i]] = i
+    
+    def _loadifneeded(self):
+	if self.id2nick == None:
+	    self._lock()
+	    self._load()
+	    self._release()
+        
+    def _save(self):
+        if self.id2nick == None: return
+	tagmap = self._tagfile()
+	f = open(tagmap, 'w')
+	pickle.dump(self.id2nick, f)
+	f.close()
+
+    def nickFromId(self, idTag):
+        self._loadifneeded()
+        return self.id2nick[idTag]
+
+    def idFromNick(self, nick):
+        self._loadifneeded()
+        return self.nick2id[nick]
+
+    def getnewId(self, nick):
+        self._lock()
+	self._load()
+	if self.nick2id.has_key(nick):
+	    raise AlreadySuchAccount()
+	while True:
+	    tag = Mail.genMid(8)
+	    rtag = Mail.mid2filename(tag)
+	    if not self.id2nick.has_key(rtag): break
+	self.nick2id[nick] = rtag
+	self.id2nick[rtag] = nick
+	self._save()
+	self._release()
+	return rtag
+
+class Account:
+    """Hold account data"""
+
+    def __init__(self, nickname, create = 0):
+	"""Load from an existing account, or create a new, or fail"""
+	# Set data to dummy values
+	self.idTag = None
+        self.datafile = None
+	self.index = None
+	self.mbox = None
+	self.syn = None
+	self.params = None
+	if create == 1:
+	    tagmap = TagMap()
+	    self.idTag = tagmap.getnewId(nickname)
+	    # If the nick already existed, we're out of this because of
+	    # a thrown AlreadySuchAccount.
+	# Everything below this line has not been reread and can be considered
+	# work in progress.
+	    
+            
+    def __del__(self):
+	"""Flushes the user account to the disk"""
+        self._save_index()
+        self._save_synbox()
+        self._save_mbox()
+        self._save_data()
+        self._release()
+    
+    def __getitem__(self, key):
+	"""Gets user account field as in a hashtable"""
+	return self.data[key]
+
+    def __setitem__(self, key, value):
+	"""Gets user account field as in a hashtable"""
+	self.data[key] = value
+
+    def _lock(self):
+	"""Locks the user. For well behaved functions."""
+	self.lock = mixminion.Common.Lockfile(Config.path + os.sep + self.idTag + '.lck')
+	self.lock.acquire()
+
+    def _release(self):
+	"""Releases the lock"""
+	self.lock.release()
+
+    def homeDir(self):
+	"""Gets the home directory of this account"""
+        return  Config.path + os.sep + self.idTag + os.sep
+
+    def load_mbox(self):
+	"""Loads the mailbox from the disk"""
+	if not self.mbox == None: return
+	mbox = self.mboxfile()
+	try:
+	    f = open(mbox, 'r')
+	    self.mbox = pickle.load(f)
+	    f.close()
+	except IOError:
+	    self.mbox = {}
+
+    def mboxfile(self):
+	"""Gets the path of the mailbox"""
+	return self.home + 'mbox'
+
+    def _save_mbox(self):
+	"""Flushes the mailbox to the disk"""
+	if self.mbox == None: return
+	mbox = self.mboxfile()
+	f = open(mbox, 'w')
+	pickle.dump(self.mbox, f)
+	f.close()
+
+    def synboxfile(self):
+	"""Gets the path of the synbox"""
+	return self.home + 'syn'
+
+    def indexfile(self):
+	"""Gets the path of the index"""
+	return self.home + 'idx'
+	
+    def load_synbox(self):
+	"""Loads the synbox from the disk"""
+	if not self.syn == None: return
+	synbox = self.synboxfile()
+	try:
+	    f = open(synbox, 'r')
+	    self.syn = pickle.load(f)
+	    f.close()
+	except IOError:
+	    self.syn = []
+
+    def _save_synbox(self):
+	"""Flushes the synbox to the disk"""
+	if self.syn == None: return
+	synbox = self.synboxfile()
+	f = open(synbox, 'w')
+	pickle.dump(self.syn, f)
+	f.close()
+    
+    def load_index(self):
+	"""Loads the index from the disk"""
+	if not self.index == None: return
+	index = self.indexfile()
+	try:
+	    f = open(index, 'r')
+	    self.index = pickle.load(f)
+	    f.close()
+	except IOError:
+	    self.index = {}
+    
+    def _save_index(self):
+	"""Flushes the index to the disk"""
+	if self.index == None: return
+	index = self.indexfile()
+	f = open(index, 'w')
+	pickle.dump(self.index, f)
+	f.close()
+
+    def _save_data(self):
+	"""Flushes the data to the disk"""
+	pass
+
+    def generateKeys(self):
+	"""Generates keys for this account"""
+        self.data['idKey'] = _cr.pk_generate()
+        self.data['encKey'] = _cr.pk_generate()
+        
+    def getSeqNo(self):
+	"""?"""
+        return chr(0)*Common.seqNoLength
+
+    def addHeader(self, msg):
+	"""Generates a header for a message using the identification key"""
+        h = Message.Header()
+        sig = _cr.pk_sign(_cr.sha1(msg), self.data['idKey'])
+        h.fromData(self.data['username'], self.getSeqNo(), sig)
+        return str(h) + msg
+
+    def setServer(self, serv):
+	"""Sets the name of the nymserver hosting the nym account"""
+        self.data['server'] = serv
+
+    def setAddress(self, add):
+	"""?"""
+        #TODOcheck that add has a good format?
+        self.data['address'] = add
+    
+    def send(self, msg):
+	"""Sends a message from the nymholder to the nymserver"""
+        pass
+
+    def sendControl(self, l):
+	"""Sends a list of command messages to the nymserver"""
+        msg = Message.buildMessage(l)
+        msg = self.addHeader(msg)
+        nymUser.send(msg)
+        
+    def generateSurbs(self, n):
+        """Generate surbs"""
+	capi = mapi.ClientEnv(); # TODO: create it once and share it.
+	return [ "wait for ClientAPI... or write it."] * n
+	return capi.generateSURBs(n, messageDest = self.data['address'],
+				  identity = self.idTag);
+    

Modified: trunk/nym3/Client/Main.py
===================================================================
--- trunk/nym3/Client/Main.py	2005-04-04 16:18:54 UTC (rev 171)
+++ trunk/nym3/Client/Main.py	2005-04-04 20:11:37 UTC (rev 172)
@@ -29,13 +29,24 @@
 import os
 import string
 from optparse import OptionParser, make_option
-import nym3.Client.User as User
+import nym3.Client.Account as Account
 import nym3.Client.Config as Config
 import nym3.Message as Message
 import nym3.Common as Common
 import nym3.Mail as Mail
 import mixminion.Crypto as _cr
 
+class CLI:
+    def __init__(self): pass
+
+    def prompt(self, s):
+	sys.stdout.write(s + ": ")
+	sys.stdout.flush()
+	return sys.stdin.readline()
+
+    def display(self, s):
+	print s
+
 def processMessage(msg):
     """process incoming control message"""
       
@@ -63,8 +74,8 @@
     while True: # chose a suitable account name
 	account = None
 	try:
-	    account = User.Account(nickname)
-	except User.AlreadySuchAccount:
+	    account = Account.Account(nickname, create = 1)
+	except Account.AlreadySuchAccount:
 	    ui.display("This account name is already in use")
 	    nickname = ui.prompt("New account name")
 	if account: break
@@ -81,9 +92,31 @@
     
 	
 def main(args):
+    if len(args) < 2:
+	print "Usage: WRITEME"
+	sys.exit(1)
     if args[1] == "create":
 	parser = OptionParser()
-	parser.add_option("-s", "--server", action = "store", dest = "server")
+	parser.add_option("-s", "--server", action = "store", dest = "server",
+			  help = "Specify the server")
+	parser.add_option("-u", "--username", action = "store",
+			  dest = "username", 
+			  help = "Specify usernameis to attempt to register in"
+			  " the form user1:user2:user3")
+	parser.add_option("-n", "--nickname", action = "store",
+			  dest = "nickname", help = "How to refer to this "
+			  "account locally")
+	parser.add_option("-e", "--email", help = "Specify the destination "
+			  "email address for returning surbs", action = "store",
+			  dest = "email")
+	(options, args) = parser.parse_args(args[2:])
+	ui = CLI()
+	myusernamelist = []
+	if options.username:
+	    myusernamelist = string.split(options.username, ":")
+	setupAccount(ui, serverName = options.server, 
+		     usernamelist = myusernamelist,
+		     emailAddress = options.email, nickname = options.nickname)
     
 
 if __name__ == '__main__':

Modified: trunk/nym3/Client/README.Dev
===================================================================
--- trunk/nym3/Client/README.Dev	2005-04-04 16:18:54 UTC (rev 171)
+++ trunk/nym3/Client/README.Dev	2005-04-04 20:11:37 UTC (rev 172)
@@ -10,7 +10,7 @@
     o an `synbox' or mailbox of received synopsis
     o a mailbox of received complete emails
     o a server name where this account is registered
-    o the nymname (name of the account registered at the nymserver)
+    o the username (name of the account registered at the nymserver)
     o an idTag used to tag SURBs generated for this account. It should
       be reasonably random, and above all unique to this account. When
       message come back to the server this is the sole information we

Deleted: trunk/nym3/Client/User.py
===================================================================
--- trunk/nym3/Client/User.py	2005-04-04 16:18:54 UTC (rev 171)
+++ trunk/nym3/Client/User.py	2005-04-04 20:11:37 UTC (rev 172)
@@ -1,292 +0,0 @@
-# $Id$
-# -*- coding: iso-8859-1 -*-
-# Copyright (c) 2004,2005 Jean-René Reinhard <jr at komite.net>
-# and Laurent Fousse <laurent at komite.net>.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, and/or sell copies
-# of the Software, and to permit persons to whom the Software is furnished to
-# do so, provided that the above copyright notice(s) and this permission
-# notice appear in all copies of the Software and that both the above
-# copyright notice(s) and this permission notice appear in supporting
-# documentation.
-# 
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
-# LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR
-# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Contains user account information on the client side
-+ way to create, access and modify them"""
-
-import os
-import nym3.Client.Config as Config
-import nym3.Mail as Mail
-import mixminion.Common
-import nym3.Common as Common
-import mixminion.Crypto as _cr
-import nym3.Message as Message
-import mixminion.ClientAPI as mapi
-
-class NoSuchAccount(Exception): pass
-"""Exception thrown when a user identified by her nym can't be found"""
-
-class AlreadySuchAccount(Exception): pass
-"""Exception thrown when a user identified by her nym already exists"""
-
-class TagMap:
-    """Contains mapping between idTag and nickname"""
-    def __init__(self):
-        self.id2nick = None
-        self.nick2id = None
-
-    def _lock(self):
-        """Lock the tagmap file"""
-        self.lock = mixminion.Common.Lockfile(Config.path + os.sep +
-					      'tagmap.lck')
-        self.lock.acquire()
-
-    def _release(self):
-        self.lock.release()
-
-    def _tagfile(self):
-        return Config.path + os.sep + "tagmap" 
-
-    def _load(self):
-	tag = self._tagfile()
-	try:
-	    f = open(tag, 'r')
-	    self.id2nick = pickle.load(f)
-	    f.close()
-	except IOError:
-	    self.id2nick = {}
-	for i in self.id2nick.keys():
-	    self.nick2id[self.id2nick[i]] = i
-    
-    def _loadifneeded(self):
-	if self.id2nick == None:
-	    self._lock()
-	    self._load()
-	    self._release()
-        
-    def _save(self):
-        if self.id2nick == None: return
-	tagmap = self._tagfile()
-	f = open(tagmap, 'w')
-	pickle.dump(self.id2nick, f)
-	f.close()
-
-    def nickFromId(self, idTag):
-        self._loadifneeded()
-        return self.id2nick[idTag]
-
-    def idFromNick(self, nick):
-        self._loadifneeded()
-        return self.nick2id[nick]
-
-    def getnewId(self, nick):
-        self._lock()
-	self._load()
-	if self.nick2id.has_key(nick):
-	    raise AlreadySuchAccount()
-	while True:
-	    tag = Mail.genMid(8)
-	    rtag = Mail.mid2filename(tag)
-	    if not self.id2nick.has_key(rtag): break
-	self.nick2id[nick] = rtag
-	self.id2nick[rtag] = nick
-	self._save()
-	self._release()
-	return rtag
-
-class Account:
-    """Hold account data"""
-
-    def __init__(self, idTag="", tag="", create = 0, username="bazounga"):
-        #TODO what is the criteria determining which account we must load? For the time being we only have a user account
-        """0 : load user data correspondig to idTag, throw an error if the account doesn't exist
-        1 : create a new account (do not take into account idTag)
-        _ : load user data corresponding to idTag, create an account if the account doesn't exist, and in that case discard idTag
-        tag is an optionnal string. if used when the account is created the association tag -> idTag is kept in the home.tag
-        """
-	self.idTag = idTag
-        self.datafile = None
-	self.index = None
-	self.mbox = None
-	self.syn = None
-	self.data = None
-        self._lock()
-	try:
-            self.home = self.homeDir()
-            if create == 1 or idTag == "" or not os.access(self.home, os.F_OK):
-                raise NoSuchUser
-	    f = open(self.datafile, 'r')
-            self.data = pickle.load(f)
-            f.close()
-        except NoSuchUser:
-            if create == 0:
-                raise
-            else:
-                self.idTag = generateIdTag()
-                self.home = self.homeDir()
-                self.datafile = self.home + 'data'
-                self.data = Config.default_settings
-		self.data['username'] = username
-                if tag != "":
-                    T = Tag()
-                    T.store(tag, self.idTag)
-                    del T
-        except IOError:
-            print "the user account of idTag %s contains some error : impossible to open %s" % idTag, self.datafile
-            sys.exit(2)
-            
-    def __del__(self):
-	"""Flushes the user account to the disk"""
-        self._save_index()
-        self._save_synbox()
-        self._save_mbox()
-        self._save_data()
-        self._release()
-    
-    def __getitem__(self, key):
-	"""Gets user account field as in a hashtable"""
-	return self.data[key]
-
-    def __setitem__(self, key, value):
-	"""Gets user account field as in a hashtable"""
-	self.data[key] = value
-
-    def _lock(self):
-	"""Locks the user. For well behaved functions."""
-	self.lock = mixminion.Common.Lockfile(Config.path + os.sep + self.idTag + '.lck')
-	self.lock.acquire()
-
-    def _release(self):
-	"""Releases the lock"""
-	self.lock.release()
-
-    def homeDir(self):
-	"""Gets the home directory of this account"""
-        return  Config.path + os.sep + self.idTag + os.sep
-
-    def load_mbox(self):
-	"""Loads the mailbox from the disk"""
-	if not self.mbox == None: return
-	mbox = self.mboxfile()
-	try:
-	    f = open(mbox, 'r')
-	    self.mbox = pickle.load(f)
-	    f.close()
-	except IOError:
-	    self.mbox = {}
-
-    def mboxfile(self):
-	"""Gets the path of the mailbox"""
-	return self.home + 'mbox'
-
-    def _save_mbox(self):
-	"""Flushes the mailbox to the disk"""
-	if self.mbox == None: return
-	mbox = self.mboxfile()
-	f = open(mbox, 'w')
-	pickle.dump(self.mbox, f)
-	f.close()
-
-    def synboxfile(self):
-	"""Gets the path of the synbox"""
-	return self.home + 'syn'
-
-    def indexfile(self):
-	"""Gets the path of the index"""
-	return self.home + 'idx'
-	
-    def load_synbox(self):
-	"""Loads the synbox from the disk"""
-	if not self.syn == None: return
-	synbox = self.synboxfile()
-	try:
-	    f = open(synbox, 'r')
-	    self.syn = pickle.load(f)
-	    f.close()
-	except IOError:
-	    self.syn = []
-
-    def _save_synbox(self):
-	"""Flushes the synbox to the disk"""
-	if self.syn == None: return
-	synbox = self.synboxfile()
-	f = open(synbox, 'w')
-	pickle.dump(self.syn, f)
-	f.close()
-    
-    def load_index(self):
-	"""Loads the index from the disk"""
-	if not self.index == None: return
-	index = self.indexfile()
-	try:
-	    f = open(index, 'r')
-	    self.index = pickle.load(f)
-	    f.close()
-	except IOError:
-	    self.index = {}
-    
-    def _save_index(self):
-	"""Flushes the index to the disk"""
-	if self.index == None: return
-	index = self.indexfile()
-	f = open(index, 'w')
-	pickle.dump(self.index, f)
-	f.close()
-
-    def _save_data(self):
-	"""Flushes the data to the disk"""
-	pass
-
-    def generateKeys(self):
-	"""Generates keys for this account"""
-        self.data['idKey'] = _cr.pk_generate()
-        self.data['encKey'] = _cr.pk_generate()
-        
-    def getSeqNo(self):
-	"""?"""
-        return chr(0)*Common.seqNoLength
-
-    def addHeader(self, msg):
-	"""Generates a header for a message using the identification key"""
-        h = Message.Header()
-        sig = _cr.pk_sign(_cr.sha1(msg), self.data['idKey'])
-        h.fromData(self.data['username'], self.getSeqNo(), sig)
-        return str(h) + msg
-
-    def setServer(self, serv):
-	"""Sets the name of the nymserver hosting the nym account"""
-        self.data['server'] = serv
-
-    def setAddress(self, add):
-	"""?"""
-        #TODOcheck that add has a good format?
-        self.data['address'] = add
-    
-    def send(self, msg):
-	"""Sends a message from the nymholder to the nymserver"""
-        pass
-
-    def sendControl(self, l):
-	"""Sends a list of command messages to the nymserver"""
-        msg = Message.buildMessage(l)
-        msg = self.addHeader(msg)
-        nymUser.send(msg)
-        
-    def generateSurbs(self, n):
-        """Generate surbs"""
-	capi = mapi.ClientEnv(); # TODO: create it once and share it.
-	return [ "wait for ClientAPI... or write it."] * n
-	return capi.generateSURBs(n, messageDest = self.data['address'],
-				  identity = self.idTag);
-    



More information about the Nym3-commit mailing list