From anadelonbrin at users.sourceforge.net Fri Apr 7 04:23:09 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:23:09 -0700 Subject: [Spambayes-checkins] spambayes/spambayes dbmstorage.py,1.14,1.15 Message-ID: <20060407022312.2C9991E400A@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19059/spambayes Modified Files: dbmstorage.py Log Message: Fix #1387709: if dbm_type is non default, then use it, not whichdb, to determine database type. Index: dbmstorage.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/dbmstorage.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** dbmstorage.py 24 Jan 2005 05:56:37 -0000 1.14 --- dbmstorage.py 7 Apr 2006 02:23:05 -0000 1.15 *************** *** 59,63 **** def open(db_name, mode): ! if os.path.exists(db_name): # let the file tell us what db to use dbm_type = whichdb.whichdb(db_name) --- 59,65 ---- def open(db_name, mode): ! if os.path.exists(db_name) and \ ! options.default("globals", "dbm_type") != \ ! options["globals", "dbm_type"]: # let the file tell us what db to use dbm_type = whichdb.whichdb(db_name) *************** *** 68,72 **** dbm_type = "db3hash" else: ! # fresh file - open with what the user specified dbm_type = options["globals", "dbm_type"].lower() f = open_funcs.get(dbm_type) --- 70,74 ---- dbm_type = "db3hash" else: ! # fresh file or overridden - open with what the user specified dbm_type = options["globals", "dbm_type"].lower() f = open_funcs.get(dbm_type) From anadelonbrin at users.sourceforge.net Fri Apr 7 04:25:30 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:25:30 -0700 Subject: [Spambayes-checkins] spambayes/scripts sb_filter.py,1.18,1.19 Message-ID: <20060407022532.633D71E4023@bag.python.org> Update of /cvsroot/spambayes/spambayes/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20716/scripts Modified Files: sb_filter.py Log Message: Add [ 1081787 ] Adding the version only to sb_filter.py Fix [ 1387699 ] train_on_filter=True needs the db to be opened read/write Index: sb_filter.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/scripts/sb_filter.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** sb_filter.py 3 Jun 2005 01:13:17 -0000 1.18 --- sb_filter.py 7 Apr 2006 02:25:25 -0000 1.19 *************** *** 20,23 **** --- 20,25 ---- -h show usage and exit + -v + show version and exit -x show some usage examples and exit *************** *** 136,139 **** --- 138,146 ---- sys.exit(code) + def version(): + v = get_current_version() + print >> sys.stderr, v.get_long_version("SpamBayes Command Line Filter") + sys.exit(0) + class HammieFilter(object): def __init__(self): *************** *** 174,178 **** def filter(self, msg): ! self.open('r') return self.h.filter(msg) --- 181,188 ---- def filter(self, msg): ! if Options.options["Hammie", "train_on_filter"]: ! self.open('c') ! else: ! self.open('r') return self.h.filter(msg) *************** *** 204,213 **** h = HammieFilter() actions = [] ! opts, args = getopt.getopt(sys.argv[1:], 'hxd:p:nfgstGSo:', ! ['help', 'examples', 'option=']) create_newdb = False for opt, arg in opts: if opt in ('-h', '--help'): usage(0) elif opt in ('-x', '--examples'): examples() --- 214,225 ---- h = HammieFilter() actions = [] ! opts, args = getopt.getopt(sys.argv[1:], 'hvxd:p:nfgstGSo:', ! ['help', 'version', 'examples', 'option=']) create_newdb = False for opt, arg in opts: if opt in ('-h', '--help'): usage(0) + elif opt in ('-v', '--version'): + version() elif opt in ('-x', '--examples'): examples() From anadelonbrin at users.sourceforge.net Fri Apr 7 04:30:00 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:30:00 -0700 Subject: [Spambayes-checkins] spambayes/spambayes storage.py,1.58,1.59 Message-ID: <20060407023003.A1DAF1E400C@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23599/spambayes Modified Files: storage.py Log Message: Don't store on close when read-only. Index: storage.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/storage.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** storage.py 21 Feb 2006 02:52:02 -0000 1.58 --- storage.py 7 Apr 2006 02:29:57 -0000 1.59 *************** *** 788,792 **** # closed and cause problems. For now, saving seems to make sense # (and we can always add abort methods if they are ever needed). ! self.store() # Do the closing. --- 788,793 ---- # closed and cause problems. For now, saving seems to make sense # (and we can always add abort methods if they are ever needed). ! if self.mode != 'r': ! self.store() # Do the closing. From anadelonbrin at users.sourceforge.net Fri Apr 7 04:31:16 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:31:16 -0700 Subject: [Spambayes-checkins] spambayes/spambayes FileCorpus.py,1.21,1.22 Message-ID: <20060407023117.914DE1E4019@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24535/spambayes Modified Files: FileCorpus.py Log Message: Non-gzipped files might look like gzipped ones. Index: FileCorpus.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/FileCorpus.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** FileCorpus.py 15 Nov 2005 00:42:39 -0000 1.21 --- FileCorpus.py 7 Apr 2006 02:31:09 -0000 1.22 *************** *** 213,217 **** fp.read(), _class = self.message_class) except IOError, e: ! if str(e) == 'Not a gzipped file': # We've probably got both gzipped messages and # non-gzipped messages, and need to work with both. --- 213,218 ---- fp.read(), _class = self.message_class) except IOError, e: ! if str(e) == 'Not a gzipped file' or \ ! str(e) == 'Unknown compression method': # We've probably got both gzipped messages and # non-gzipped messages, and need to work with both. From anadelonbrin at users.sourceforge.net Fri Apr 7 04:33:18 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:33:18 -0700 Subject: [Spambayes-checkins] spambayes/spambayes message.py,1.74,1.75 Message-ID: <20060407023320.1FC661E400A@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26007/spambayes Modified Files: message.py Log Message: Add mode parameter to MessageInfo ZODB. Index: message.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/message.py,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** message.py 28 Nov 2005 10:52:29 -0000 1.74 --- message.py 7 Apr 2006 02:33:15 -0000 1.75 *************** *** 279,285 **** class MessageInfoZODB(storage.ZODBClassifier): ClassifierClass = _PersistentMessageInfo ! def __init__(self, db_name): self.nham = self.nspam = 0 # Only used for debugging prints ! storage.ZODBClassifier.__init__(self, db_name) self.classifier.store = self.store self.db = self.classifier --- 279,285 ---- class MessageInfoZODB(storage.ZODBClassifier): ClassifierClass = _PersistentMessageInfo ! def __init__(self, db_name, mode='c'): self.nham = self.nspam = 0 # Only used for debugging prints ! storage.ZODBClassifier.__init__(self, db_name, mode) self.classifier.store = self.store self.db = self.classifier *************** *** 296,300 **** ## "mysql" : (MessageInfoMySQL, False, False), ## "cdb" : (MessageInfoCDB, False, True), ! "zodb" : (MessageInfoZODB, False, True), ## "zeo" : (MessageInfoZEO, False, False), } --- 296,300 ---- ## "mysql" : (MessageInfoMySQL, False, False), ## "cdb" : (MessageInfoCDB, False, True), ! "zodb" : (MessageInfoZODB, True, True), ## "zeo" : (MessageInfoZEO, False, False), } From anadelonbrin at users.sourceforge.net Fri Apr 7 04:35:37 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:35:37 -0700 Subject: [Spambayes-checkins] spambayes/scripts sb_server.py,1.50,1.51 Message-ID: <20060407023539.3BBC51E4027@bag.python.org> Update of /cvsroot/spambayes/spambayes/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28728/scripts Modified Files: sb_server.py Log Message: Fix [ 1383801 ] trustedIPs wildcard to regex broken Don't unnecessarily reopen messageinfo db. Index: sb_server.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/scripts/sb_server.py,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** sb_server.py 14 Dec 2005 08:18:00 -0000 1.50 --- sb_server.py 7 Apr 2006 02:35:34 -0000 1.51 *************** *** 290,294 **** return True ! trustedIPs = trustedIPs.replace('.', '\.').replace('*', '([01]?\d\d?|2[04]\d|25[0-5])') for trusted in trustedIPs.split(','): if re.search("^" + trusted + "$", remoteIP): --- 290,294 ---- return True ! trustedIPs = trustedIPs.replace('.', '\.').replace('*', '([01]?\d\d?|2[0-4]\d|25[0-5])') for trusted in trustedIPs.split(','): if re.search("^" + trusted + "$", remoteIP): *************** *** 884,891 **** self.DBName, self.useDB = storage.database_type([]) self.bayes = storage.open_storage(self.DBName, self.useDB) ! if not hasattr(self, "MBDName"): ! self.MDBName, self.useMDB = spambayes.message.database_type() ! self.mdb = spambayes.message.open_storage(self.MDBName, self.useMDB) ! spambayes.message.Message.message_info_db = self.mdb # Load stats manager. --- 884,888 ---- self.DBName, self.useDB = storage.database_type([]) self.bayes = storage.open_storage(self.DBName, self.useDB) ! self.mdb = spambayes.message.Message().message_info_db # Load stats manager. From anadelonbrin at users.sourceforge.net Fri Apr 7 04:36:43 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:36:43 -0700 Subject: [Spambayes-checkins] spambayes/scripts sb_imapfilter.py,1.65,1.66 Message-ID: <20060407023644.979051E402B@bag.python.org> Update of /cvsroot/spambayes/spambayes/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30163/scripts Modified Files: sb_imapfilter.py Log Message: Don't unnecessarily reopen messageinfo db. Index: sb_imapfilter.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/scripts/sb_imapfilter.py,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** sb_imapfilter.py 28 Nov 2005 10:57:07 -0000 1.65 --- sb_imapfilter.py 7 Apr 2006 02:36:40 -0000 1.66 *************** *** 149,152 **** --- 149,153 ---- from spambayes.UserInterface import UserInterfaceServer from spambayes.ImapUI import IMAPUserInterface, LoginFailure + from spambayes.Version import get_current_version *************** *** 1127,1131 **** classifier = storage.open_storage(bdbname, useDBM) ! message_db = message.open_storage(*message.database_type()) if options["globals", "verbose"]: --- 1128,1132 ---- classifier = storage.open_storage(bdbname, useDBM) ! message_db = message.Message().message_info_db if options["globals", "verbose"]: *************** *** 1196,1200 **** def change_db(): classifier = storage.open_storage(*storage.database_type(opts)) ! message_db = message.open_storage(*message.database_type()) imap_filter = IMAPFilter(classifier, message_db) --- 1197,1201 ---- def change_db(): classifier = storage.open_storage(*storage.database_type(opts)) ! message.Message.message_info_db = message_db imap_filter = IMAPFilter(classifier, message_db) From anadelonbrin at users.sourceforge.net Fri Apr 7 04:37:33 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu, 06 Apr 2006 19:37:33 -0700 Subject: [Spambayes-checkins] spambayes CHANGELOG.txt,1.53,1.54 Message-ID: <20060407023734.70C5B1E400B@bag.python.org> Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30924 Modified Files: CHANGELOG.txt Log Message: Bring up-to-date. Index: CHANGELOG.txt =================================================================== RCS file: /cvsroot/spambayes/spambayes/CHANGELOG.txt,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** CHANGELOG.txt 27 Nov 2005 01:09:54 -0000 1.53 --- CHANGELOG.txt 7 Apr 2006 02:37:28 -0000 1.54 *************** *** 3,6 **** --- 3,10 ---- Release 1.1a2 ============= + Tony Meyer 03/04/2006 Add [ 1081787 ] Adding the version only to sb_filter.py + Tony Meyer 03/04/2006 Fix [ 1383801 ] trustedIPs wildcard to regex broken + Tony Meyer 02/04/2006 Fix [ 1387699 ] train_on_filter=True needs the db to be opened read/write + Tony Meyer 02/04/2006 Fix [ 1387709 ] If globals:dbm_type is non-default, then don't use whichdb. Tony Meyer 27/11/2005 Install the conversion utility and offer to run it on Windows install. Tony Meyer 26/11/2005 Add conversion utility to easily convert dbm to ZODB. From anadelonbrin at users.sourceforge.net Thu Apr 20 05:12:20 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Wed, 19 Apr 2006 20:12:20 -0700 Subject: [Spambayes-checkins] spambayes README-DEVEL.txt,1.22,1.23 Message-ID: <20060420031224.236A01E4004@bag.python.org> Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29914 Modified Files: README-DEVEL.txt Log Message: Update some release creation notes. Index: README-DEVEL.txt =================================================================== RCS file: /cvsroot/spambayes/spambayes/README-DEVEL.txt,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** README-DEVEL.txt 7 Apr 2005 04:15:10 -0000 1.22 --- README-DEVEL.txt 20 Apr 2006 03:12:17 -0000 1.23 *************** *** 467,470 **** --- 467,474 ---- o Change spambayes/__init__.py to contain the new version number but don't commit it yet, just in case something goes wrong. + o Note that if you cheated above, and used an existing checkout, you need + to ensure that you don't have extra files in there. For example, if you + have a few thousand email messages in testtools/Data, setup.py will take + a *very* long time. o In the Windows checkout, run "python setup.py sdist --formats zip" o In the Unix checkout, run "python setup.py sdist --formats gztar" *************** *** 486,495 **** o In either checkout, run "python setup.py register" to register the new version with PyPI. ! o Create MD5 checksums for the files, and update download.ht with these. ! Tony uses wxChecksums (http://wxchecksums.sourceforge.net) for this, ! but you could just do ! >>> import md5 ! >>> print md5.md5(file("spambayes-1.0.1.exe", "rb").read()).hexdigest() ! o Calculate the sizes of the files, and update download.ht with these. From release 1.1 doing a "setup.py sdist" will generate checksums and sizes for you, and print out the results to stdout. --- 490,494 ---- o In either checkout, run "python setup.py register" to register the new version with PyPI. ! o Update download.ht with checksums, links, and sizes for the files. From release 1.1 doing a "setup.py sdist" will generate checksums and sizes for you, and print out the results to stdout. From anadelonbrin at users.sourceforge.net Thu Apr 20 05:13:28 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Wed, 19 Apr 2006 20:13:28 -0700 Subject: [Spambayes-checkins] spambayes/spambayes __init__.py,1.17,1.18 Message-ID: <20060420031330.19E981E4004@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30762/spambayes Modified Files: __init__.py Log Message: Bump version number (gasp!). Index: __init__.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/__init__.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** __init__.py 7 Apr 2005 06:20:06 -0000 1.17 --- __init__.py 20 Apr 2006 03:13:26 -0000 1.18 *************** *** 6,9 **** _ = lambda arg: arg ! __version__ = "1.1a1+" __date__ = _("April 2005") --- 6,9 ---- _ = lambda arg: arg ! __version__ = "1.1a2" __date__ = _("April 2005") From anadelonbrin at users.sourceforge.net Sat Apr 22 06:41:56 2006 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Fri, 21 Apr 2006 21:41:56 -0700 Subject: [Spambayes-checkins] spambayes/spambayes storage.py,1.59,1.60 Message-ID: <20060422044158.E84511E4006@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29434/spambayes Modified Files: storage.py Log Message: Tim says that a cache size of 10,000 is appropriate, and he probably knows a thing or two about ZODB :) Index: storage.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/storage.py,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** storage.py 7 Apr 2006 02:29:57 -0000 1.59 --- storage.py 22 Apr 2006 04:41:54 -0000 1.60 *************** *** 729,733 **** self.create_storage() ! self.DB = ZODB.DB(self.storage) self.conn = self.DB.open() root = self.conn.root() --- 729,733 ---- self.create_storage() ! self.DB = ZODB.DB(self.storage, cache_size=10000) self.conn = self.DB.open() root = self.conn.root() From montanaro at users.sourceforge.net Sun Apr 23 05:52:27 2006 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Sat, 22 Apr 2006 20:52:27 -0700 Subject: [Spambayes-checkins] website/scripts/ht2html SpamBayesGenerator.py, 1.8, 1.9 Message-ID: <20060423035230.114B51E4007@bag.python.org> Update of /cvsroot/spambayes/website/scripts/ht2html In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15511 Modified Files: SpamBayesGenerator.py Log Message: unused import Index: SpamBayesGenerator.py =================================================================== RCS file: /cvsroot/spambayes/website/scripts/ht2html/SpamBayesGenerator.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** SpamBayesGenerator.py 16 Dec 2003 05:06:34 -0000 1.8 --- SpamBayesGenerator.py 23 Apr 2006 03:52:25 -0000 1.9 *************** *** 5,9 **** import os import posixpath - import whrandom from Skeleton import Skeleton --- 5,8 ---- From montanaro at users.sourceforge.net Mon Apr 24 00:30:48 2006 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Sun, 23 Apr 2006 15:30:48 -0700 Subject: [Spambayes-checkins] spambayes/contrib spamcounts.py,1.6,1.7 Message-ID: <20060423223050.BD85C1E400B@bag.python.org> Update of /cvsroot/spambayes/spambayes/contrib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4248 Modified Files: spamcounts.py Log Message: I think this reduces the sensitivity of this code to classifier changes. It could still be better. Awaiting someone's verdict on storage.database_type(). Index: spamcounts.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/contrib/spamcounts.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** spamcounts.py 12 Jan 2004 08:36:15 -0000 1.6 --- spamcounts.py 23 Apr 2006 22:30:46 -0000 1.7 *************** *** 27,31 **** from spambayes.Options import options, get_pathname_option from spambayes.tokenizer import tokenize ! from spambayes.storage import STATE_KEY prog = sys.argv[0] --- 27,31 ---- from spambayes.Options import options, get_pathname_option from spambayes.tokenizer import tokenize ! from spambayes.storage import STATE_KEY, database_type, open_storage prog = sys.argv[0] *************** *** 36,57 **** print >> sys.stderr, __doc__.strip() % globals() - # From msgs on spambayes mailing list, spam prob is calculated thusly: - ## hc = ham token count - ## nh = total number of ham messages - ## sc = spam token count - ## ns = total number of spam messages - ## hr = ham ratio = hc / nh - ## sr = spam ratio = sc / ns - ## p = base spam probability = sr / (sr + hr) - ## S = unknown word strength (static factor = 0.45 by default) - ## x = unknown word probability (static factor = 0.5 by default) - ## n = total number of messages the token appeared in = hc + sc - ## sp = final spam probability = ((S * x) + (n * p)) / (S + n) - - def print_spamcounts(tokens, db, use_re): if use_re: s = sets.Set() ! keys = db.keys() for pat in tokens: for k in keys: --- 36,43 ---- print >> sys.stderr, __doc__.strip() % globals() def print_spamcounts(tokens, db, use_re): if use_re: s = sets.Set() ! keys = db._wordinfokeys() for pat in tokens: for k in keys: *************** *** 60,67 **** tokens = list(s) - S = options["Classifier", "unknown_word_strength"] - x = options["Classifier", "unknown_word_prob"] - _, ns, nh = db[STATE_KEY] - writer = csv.writer(sys.stdout) writer.writerow(("token", "nspam", "nham", "spam prob")) --- 46,49 ---- *************** *** 72,87 **** seen.add(t) ! try: ! sc, hc = db.get(t, (0, 0)) ! except ValueError: ! _, sc, hc = db.get(t, (0, 0, 0)) if sc == hc == 0: continue ! hr = hc / nh ! sr = sc / ns ! p = sr / (sr + hr) ! n = hc + sc ! sp = ((S * x) + (n * p)) / (S + n) writer.writerow((t, sc, hc, sp)) --- 54,62 ---- seen.add(t) ! sc, hc = db._wordinfoget(t).__getstate__() if sc == hc == 0: continue ! sp = db.spamprob([t]) writer.writerow((t, sc, hc, sp)) *************** *** 117,126 **** return 1 ! dbname = os.path.expanduser(dbname) ! print >> sys.stderr, "db:", dbname ! if ispickle: ! db = pickle.load(file(dbname)) ! else: ! db = shelve.open(dbname, flag='r') if tokenizestdin: --- 92,97 ---- return 1 ! dbname, usedb = database_type(opts) ! db = open_storage(dbname, usedb) if tokenizestdin: