[PATCH 03/17] Convert to use OptionParser for command line handling.
Sebastian Spaeth
Sebastian at SSpaeth.de
Mon Nov 29 16:02:11 GMT 2010
This version is feature-identical to before. With this change, we
should have feature and behavior parity with jgoerzen's original
offlineimap again.
Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
bin/offlineimap | 4 +-
offlineimap.py | 4 +-
offlineimap/init.py | 222 ++++++++++++++++++++++++++++++++++--------------
offlineimap/version.py | 94 --------------------
4 files changed, 161 insertions(+), 163 deletions(-)
diff --git a/bin/offlineimap b/bin/offlineimap
index 420ddb0..e78e6e0 100755
--- a/bin/offlineimap
+++ b/bin/offlineimap
@@ -19,5 +19,5 @@
from offlineimap import OfflineImap
-offlineimap = OfflineImap()
-offlineimap.startup('6.2.0')
+OfflineImap()
+
diff --git a/offlineimap.py b/offlineimap.py
index 566bd36..24255d3 100755
--- a/offlineimap.py
+++ b/offlineimap.py
@@ -19,5 +19,5 @@
from offlineimap import OfflineImap
-offlineimap = OfflineImap()
-offlineimap.startup('6.2.0')
+OfflineImap()
+
diff --git a/offlineimap/init.py b/offlineimap/init.py
index 5f7f007..05bcec9 100644
--- a/offlineimap/init.py
+++ b/offlineimap/init.py
@@ -21,11 +21,13 @@ from offlineimap import imapserver, threadutil, version, syncmaster, accounts
from offlineimap.localeval import LocalEval
from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
import offlineimap.ui
+from offlineimap.ui.detector import DEFAULT_UI_LIST
import os, sys
from offlineimap.CustomConfig import CustomConfigParser as ConfigParser
import threading, socket
-from getopt import getopt
+from optparse import OptionParser
import signal
+import logging
try:
import fcntl
@@ -37,6 +39,9 @@ lockfd = None
class OfflineImap:
+ def __init__(self):
+ self.parse_commandline()
+
def lock(self, config, ui):
global lockfd, hasfcntl
if not hasfcntl:
@@ -48,80 +53,167 @@ class OfflineImap:
ui.locked()
ui.terminate(1)
- def startup(self, versionno):
- assert versionno == version.versionstr, "Revision of main program (%s) does not match that of library (%s). Please double-check your PYTHONPATH and installation locations." % (versionno, version.versionstr)
- options = {}
- options['-k'] = []
- if '--help' in sys.argv[1:]:
- sys.stdout.write(version.getcmdhelp() + "\n")
- sys.exit(0)
-
- for optlist in getopt(sys.argv[1:], 'P:1oqa:c:d:l:u:hk:f:')[0]:
- if optlist[0] == '-k':
- options[optlist[0]].append(optlist[1])
- else:
- options[optlist[0]] = optlist[1]
-
- if options.has_key('-h'):
- sys.stdout.write(version.getcmdhelp())
- sys.stdout.write("\n")
- sys.exit(0)
- configfilename = os.path.expanduser("~/.offlineimaprc")
- if options.has_key('-c'):
- configfilename = options['-c']
- if options.has_key('-P'):
- if not options.has_key('-1'):
- sys.stderr.write("FATAL: profile mode REQUIRES -1\n")
- sys.exit(100)
- profiledir = options['-P']
- os.mkdir(profiledir)
- threadutil.setprofiledir(profiledir)
- sys.stderr.write("WARNING: profile mode engaged;\nPotentially large data will be created in " + profiledir + "\n")
+ def parse_commandline(self):
+ """Parse the commandline and invoke everything"""
+
+ parser = OptionParser()
+ parser.add_option("-1",
+ action="store_true", dest="singlethreading",
+ default=False,
+ help="Disable all multithreading operations and use "
+ "solely a single-thread sync. This effectively sets the "
+ "maxsyncaccounts and all maxconnections configuration file "
+ "variables to 1.")
+
+ parser.add_option("-P", dest="profiledir", metavar="DIR",
+ help="Sets OfflineIMAP into profile mode. The program "
+ "will create DIR (it must not already exist). "
+ "As it runs, Python profiling information about each "
+ "thread is logged into profiledir. Please note: "
+ "This option is present for debugging and optimization "
+ "only, and should NOT be used unless you have a "
+ "specific reason to do so. It will significantly "
+ "slow program performance, may reduce reliability, "
+ "and can generate huge amounts of data. This option "
+ "implies the -1 option.")
+
+ parser.add_option("-a", dest="accounts", metavar="ACCOUNTS",
+ help="""Overrides the accounts section in the config file.
+ Lets you specify a particular account or set of
+ accounts to sync without having to edit the config
+ file. You might use this to exclude certain accounts,
+ or to sync some accounts that you normally prefer not to.""")
+
+ parser.add_option("-c", dest="configfile", metavar="FILE",
+ default="~/.offlineimaprc",
+ help="Specifies a configuration file to use in lieu of "
+ "the default, ~/.offlineimaprc.")
+
+ parser.add_option("-d", dest="debugtype", metavar="type1,[type2...]",
+ help=
+ "Enables debugging for OfflineIMAP. This is useful "
+ "if you are trying to track down a malfunction or "
+ "figure out what is going on under the hood. I suggest "
+ "that you use this with -1 in order to make the "
+ "results more sensible. This option requires one or more "
+ "debugtypes, separated by commas. "
+ "These define what exactly will be debugged, "
+ "and so far include two options: imap, "
+ "maildir or ALL. The imap option will enable IMAP protocol "
+ "stream and parsing debugging. Note that the output "
+ "may contain passwords, so take care to remove that "
+ "from the debugging output before sending it to anyone else. "
+ "The maildir option will enable debugging "
+ "for certain Maildir operations.")
+
+ parser.add_option("-l", dest="logfile", metavar="FILE",
+ help="Log to FILE")
+
+ parser.add_option("-f", dest="folders", metavar="folder1,[folder2...]",
+ help=
+ """Only sync the specified folders. The "foldername"s
+ are the *untranslated* foldernames. This
+ command-line option overrides any "folderfilter"
+ and "folderincludes" options in the configuration
+ file.""")
+
+ parser.add_option("-k", dest="configoverride",
+ action="append",
+ metavar="[section:]option=value",
+ help=
+ """Override configuration file option. If"section" is
+ omitted, it defaults to "general". Any underscores
+ "_" in the section name are replaced with spaces:
+ for instance, to override option "autorefresh" in
+ the "[Account Personal]" section in the config file
+ one would use "-k Account_Personal:autorefresh=30".""")
+
+ parser.add_option("-o",
+ action="store_true", dest="runonce",
+ default=False,
+ help="Run only once, ignoring any autorefresh setting "
+ "in the configuration file.")
+
+ parser.add_option("-q",
+ action="store_true", dest="quick",
+ default=False,
+ help="Run only quick synchronizations. Ignore any "
+ "flag updates on IMAP servers.")
+
+ parser.add_option("-u", dest="interface",
+ help="Specifies an alternative user interface to "
+ "use. This overrides the default specified in the "
+ "configuration file. The UI specified with -u will "
+ "be forced to be used, even if checks determine that it is "
+ "not usable. Possible interface choices are: %s " %
+ ", ".join(DEFAULT_UI_LIST))
+
+ (options, args) = parser.parse_args()
+
+ #read in configuration file
+ configfilename = os.path.expanduser(options.configfile)
config = ConfigParser()
if not os.path.exists(configfilename):
- sys.stderr.write(" *** Config file %s does not exist; aborting!\n" % configfilename)
+ logging.error(" *** Config file '%s' does not exist; aborting!" %
+ configfilename)
sys.exit(1)
-
config.read(configfilename)
-
- # override config values with option '-k'
- for option in options['-k']:
- (key, value) = option.split('=', 1)
- if ':' in key:
- (secname, key) = key.split(':', 1)
- section = secname.replace("_", " ")
- else:
- section = "general"
- config.set(section, key, value)
-
- ui = offlineimap.ui.detector.findUI(config, options.get('-u'))
+
+ #profile mode chosen?
+ if options.profiledir:
+ if not options.singlethreading:
+ logging.warn("Profile mode: Forcing to singlethreaded.")
+ options.singlethreaded = True
+ profiledir = options.profiledir
+ os.mkdir(profiledir)
+ threadutil.setprofiledir(profiledir)
+ logging.warn("Profile mode: Potentially large data will be "
+ "created in '%s'" % profiledir)
+
+ #override a config value
+ if options.configoverride:
+ for option in options.configoverride:
+ (key, value) = option.split('=', 1)
+ if ':' in key:
+ (secname, key) = key.split(':', 1)
+ section = secname.replace("_", " ")
+ else:
+ section = "general"
+ config.set(section, key, value)
+
+ #init the ui, and set up additional log files
+ ui = offlineimap.ui.detector.findUI(config, options.interface)
offlineimap.ui.UIBase.setglobalui(ui)
- if options.has_key('-l'):
- ui.setlogfd(open(options['-l'], 'wt'))
+ if options.logfile:
+ ui.setlogfd(open(options.logfile, 'wt'))
+ #welcome blurb
ui.init_banner()
-
- if options.has_key('-d'):
- for debugtype in options['-d'].split(','):
- ui.add_debug(debugtype.strip())
- if debugtype == 'imap':
+
+ if options.debugtype:
+ if options.debugtype.lower() == 'all':
+ options.debugtype = 'imap,maildir,thread'
+ for type in options.debugtype.split(','):
+ type = type.strip()
+ ui.add_debug(type)
+ if type.lower() == 'imap':
imaplib.Debug = 5
- if debugtype == 'thread':
+ if type.lower() == 'thread':
threading._VERBOSE = 1
-
- if options.has_key('-o'):
+
+ if options.runonce:
# FIXME: maybe need a better
for section in accounts.getaccountlist(config):
config.remove_option('Account ' + section, "autorefresh")
-
- if options.has_key('-q'):
+
+ if options.quick:
for section in accounts.getaccountlist(config):
config.set('Account ' + section, "quick", '-1')
-
- if options.has_key('-f'):
- foldernames = options['-f'].replace(" ", "").split(",")
+
+ if options.folders:
+ foldernames = options.folders.replace(" ", "").split(",")
folderfilter = "lambda f: f in %s" % foldernames
folderincludes = "[]"
for accountname in accounts.getaccountlist(config):
@@ -133,7 +225,7 @@ class OfflineImap:
for section in [remote_repo_section, local_repo_section]:
config.set(section, "folderfilter", folderfilter)
config.set(section, "folderincludes", folderincludes)
-
+
self.lock(config, ui)
@@ -152,7 +244,7 @@ class OfflineImap:
pass
try:
- if options.has_key('-l'):
+ if options.logfile:
sys.stderr = ui.logfile
socktimeout = config.getdefaultint("general", "socktimeout", 0)
@@ -160,8 +252,8 @@ class OfflineImap:
socket.setdefaulttimeout(socktimeout)
activeaccounts = config.get("general", "accounts")
- if options.has_key('-a'):
- activeaccounts = options['-a']
+ if options.accounts:
+ activeaccounts = options.accounts
activeaccounts = activeaccounts.replace(" ", "")
activeaccounts = activeaccounts.split(",")
allaccounts = accounts.AccountHashGenerator(config)
@@ -183,7 +275,7 @@ class OfflineImap:
remoterepos = None
localrepos = None
- if options.has_key('-1'):
+ if options.singlethreading:
threadutil.initInstanceLimit("ACCOUNTLIMIT", 1)
else:
threadutil.initInstanceLimit("ACCOUNTLIMIT",
@@ -192,7 +284,7 @@ class OfflineImap:
for reposname in config.getsectionlist('Repository'):
for instancename in ["FOLDER_" + reposname,
"MSGCOPY_" + reposname]:
- if options.has_key('-1'):
+ if options.singlethreading:
threadutil.initInstanceLimit(instancename, 1)
else:
threadutil.initInstanceLimit(instancename,
diff --git a/offlineimap/version.py b/offlineimap/version.py
index 6ae95fc..aca9310 100644
--- a/offlineimap/version.py
+++ b/offlineimap/version.py
@@ -33,97 +33,3 @@ 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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"""
-
-def getcmdhelp():
- from offlineimap.ui import detector
- import os
- uilist = ""
- for ui in detector.DEFAULT_UI_LIST:
- uilist += " " + ui + os.linesep
- return """
- offlineimap [ -1 ] [ -P profiledir ] [ -a accountlist ] [
- -c configfile ] [ -d debugtype[,debugtype...] ] [ -o ] [
- -u interface ] [ -q ]
-
- offlineimap -h | --help
-
- -1 Disable all multithreading operations and use
- solely a single-thread sync. This effectively sets
- the maxsyncaccounts and all maxconnections configu-
- ration file variables to 1.
-
- -P profiledir
- Sets OfflineIMAP into profile mode. The program
- will create profiledir (it must not already exist).
- As it runs, Python profiling information about each
- thread is logged into profiledir. Please note:
- This option is present for debugging and optimiza-
- tion only, and should NOT be used unless you have a
- specific reason to do so. It will significantly
- slow program performance, may reduce reliability,
- and can generate huge amounts of data. You must
- use the -1 option when you use -P.
-
-
- -a accountlist
- Overrides the accounts section in the config file.
- Lets you specify a particular account or set of
- accounts to sync without having to edit the config
- file. You might use this to exclude certain
- accounts, or to sync some accounts that you nor-
- mally prefer not to.
-
- -c configfile
- Specifies a configuration file to use in lieu of
- the default, ~/.offlineimaprc.
-
- -d debugtype[,debugtype...]
- Enables debugging for OfflineIMAP. This is useful
- if you are trying to track down a malfunction or
- figure out what is going on under the hood. I sug-
- gest that you use this with -1 in order to make the
- results more sensible.
-
- -d now requires one or more debugtypes, separated
- by commas. These define what exactly will be
- debugged, and so far include two options: imap and
- maildir. The imap option will enable IMAP protocol
- stream and parsing debugging. Note that the output
- may contain passwords, so take care to remove that
- from the debugging output before sending it to any-
- one else. The maildir option will enable debugging
- for certain Maildir operations.
-
- -f foldername[,foldername...]
- Only sync the specified folders. The "foldername"s
- are the *untranslated* foldernames. This
- command-line option overrides any "folderfilter"
- and "folderincludes" options in the configuration
- file.
-
- -k [section:]option=value
- Override configuration file option. If"section" is
- omitted, it defaults to "general". Any underscores
- "_" in the section name are replaced with spaces:
- for instance, to override option "autorefresh" in
- the "[Account Personal]" section in the config file
- one would use "-k Account_Personal:autorefresh=30".
-
- -o Run only once, ignoring any autorefresh setting in
- the config file.
-
- -q Run only quick synchronizations. Ignore any flag
- updates on IMAP servers.
-
- -h, --help
- Show summary of options.
-
- -u interface
- Specifies an alternative user interface module to
- use. This overrides the default specified in the
- configuration file. The UI specified with -u will
- be forced to be used, even if its isuable() method
- states that it cannot be. Use this option with
- care. The pre-defined options, described in the
- USER INTERFACES section of the man page, are:
-""" + uilist
--
1.7.1
More information about the OfflineIMAP-project
mailing list