def setUpClass(cls): cls.o = Opt() globals.set_options(cls.o)
def test_double_init(self): with self.assertRaises(ValueError): globals.set_options(True)
def __parse_cmd_options(self): parser = OptionParser( version=offlineimap.__version__, description="%s.\n\n%s" % (offlineimap.__copyright__, offlineimap.__license__)) parser.add_option("-V", action="store_true", dest="version", default=False, help="show full version infos") parser.add_option("--dry-run", action="store_true", dest="dryrun", default=False, help="dry run mode") parser.add_option( "--info", action="store_true", dest="diagnostics", default=False, help="output information on the configured email repositories") parser.add_option( "-1", action="store_true", dest="singlethreading", default=False, help="(the number one) disable all multithreading operations") parser.add_option("-P", dest="profiledir", metavar="DIR", help="sets OfflineIMAP into profile mode.") parser.add_option("-a", dest="accounts", metavar="account1[,account2[,...]]", help="list of accounts to sync") parser.add_option("-c", dest="configfile", metavar="FILE", default=None, help="specifies a configuration file to use") parser.add_option("-d", dest="debugtype", metavar="type1[,type2[,...]]", help="enables debugging for OfflineIMAP " " (types: imap, maildir, thread)") parser.add_option("-l", dest="logfile", metavar="FILE", help="log to FILE") parser.add_option("-s", action="store_true", dest="syslog", default=False, help="log to syslog") parser.add_option("-f", dest="folders", metavar="folder1[,folder2[,...]]", help="only sync the specified folders") parser.add_option("-k", dest="configoverride", action="append", metavar="[section:]option=value", help="override configuration file option") parser.add_option("-o", action="store_true", dest="runonce", default=False, help="run only once (ignore autorefresh)") parser.add_option( "-q", action="store_true", dest="quick", default=False, help="run only quick synchronizations (don't update flags)") parser.add_option( "-u", dest="interface", help="specifies an alternative user interface" " (quiet, basic, syslog, ttyui, blinkenlights, machineui)") parser.add_option("--delete-folder", dest="deletefolder", default=None, metavar="FOLDERNAME", help="Delete a folder (on the remote repository)") parser.add_option( "--migrate-fmd5-using-nametrans", action="store_true", dest="migrate_fmd5", default=False, help="migrate FMD5 hashes from versions prior to 6.3.5") parser.add_option( "--mbnames-prune", action="store_true", dest="mbnames_prune", default=False, help="remove mbnames entries for accounts not in accounts") (options, args) = parser.parse_args() globals.set_options(options) if options.version: print("offlineimap v%s, imaplib2 v%s (%s), Python v%s" % (offlineimap.__version__, imaplib.__version__, imaplib.DESC, PYTHON_VERSION)) sys.exit(0) # Read in configuration file. if not options.configfile: # Try XDG location, then fall back to ~/.offlineimaprc xdg_var = 'XDG_CONFIG_HOME' if not xdg_var in os.environ or not os.environ[xdg_var]: xdg_home = os.path.expanduser('~/.config') else: xdg_home = os.environ[xdg_var] options.configfile = os.path.join(xdg_home, "offlineimap", "config") if not os.path.exists(options.configfile): options.configfile = os.path.expanduser('~/.offlineimaprc') configfilename = options.configfile else: configfilename = os.path.expanduser(options.configfile) config = CustomConfigParser() if not os.path.exists(configfilename): # TODO, initialize and make use of chosen ui for logging logging.error(" *** Config file '%s' does not exist; aborting!" % configfilename) sys.exit(1) config.read(configfilename) # Profile mode chosen? if options.profiledir: if not options.singlethreading: # TODO, make use of chosen ui for logging logging.warn("Profile mode: Forcing to singlethreaded.") options.singlethreading = True if os.path.exists(options.profiledir): # TODO, make use of chosen ui for logging logging.warn("Profile mode: Directory '%s' already exists!" % options.profiledir) else: os.mkdir(options.profiledir) threadutil.ExitNotifyThread.set_profiledir(options.profiledir) # TODO, make use of chosen ui for logging logging.warn("Profile mode: Potentially large data will be " "created in '%s'" % options.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) # Which ui to use? CLI option overrides config file. ui_type = config.getdefault('general', 'ui', 'ttyui') if options.interface != None: ui_type = options.interface if '.' in ui_type: # Transform Curses.Blinkenlights -> Blinkenlights. ui_type = ui_type.split('.')[-1] # TODO, make use of chosen ui for logging logging.warning('Using old interface name, consider using one ' 'of %s' % ', '.join(UI_LIST.keys())) if options.diagnostics: ui_type = 'ttyui' # Enforce this UI for --info. # dry-run? Set [general]dry-run=True. if options.dryrun: dryrun = config.set('general', 'dry-run', 'True') config.set_if_not_exists('general', 'dry-run', 'False') try: # Create the ui class. self.ui = UI_LIST[ui_type.lower()](config) except KeyError: logging.error("UI '%s' does not exist, choose one of: %s" % (ui_type, ', '.join(UI_LIST.keys()))) sys.exit(1) setglobalui(self.ui) # Set up additional log files. if options.logfile: self.ui.setlogfile(options.logfile) # Set up syslog. if options.syslog: self.ui.setup_sysloghandler() # Welcome blurb. self.ui.init_banner() if options.debugtype: self.ui.logger.setLevel(logging.DEBUG) if options.debugtype.lower() == 'all': options.debugtype = 'imap,maildir,thread' # Force single threading? if not ('thread' in options.debugtype.split(',') \ and not options.singlethreading): self.ui._msg("Debug mode: Forcing to singlethreaded.") options.singlethreading = True debugtypes = options.debugtype.split(',') + [''] for dtype in debugtypes: dtype = dtype.strip() self.ui.add_debug(dtype) if dtype.lower() == u'imap': imaplib.Debug = 5 if options.runonce: # Must kill the possible default option. if config.has_option('DEFAULT', 'autorefresh'): config.remove_option('DEFAULT', 'autorefresh') # FIXME: spaghetti code alert! for section in accounts.getaccountlist(config): config.remove_option('Account ' + section, "autorefresh") if options.quick: for section in accounts.getaccountlist(config): config.set('Account ' + section, "quick", '-1') # Custom folder list specified? if options.folders: foldernames = options.folders.split(",") folderfilter = "lambda f: f in %s" % foldernames folderincludes = "[]" for accountname in accounts.getaccountlist(config): account_section = 'Account ' + accountname remote_repo_section = 'Repository ' + \ config.get(account_section, 'remoterepository') config.set(remote_repo_section, "folderfilter", folderfilter) config.set(remote_repo_section, "folderincludes", folderincludes) if options.logfile: sys.stderr = self.ui.logfile socktimeout = config.getdefaultint("general", "socktimeout", 0) if socktimeout > 0: socket.setdefaulttimeout(socktimeout) threadutil.initInstanceLimit( ACCOUNT_LIMITED_THREAD_NAME, config.getdefaultint('general', 'maxsyncaccounts', 1)) for reposname in config.getsectionlist('Repository'): # Limit the number of threads. Limitation on usage is handled at the # imapserver level. for namespace in [ accounts.FOLDER_NAMESPACE + reposname, MSGCOPY_NAMESPACE + reposname ]: if options.singlethreading: threadutil.initInstanceLimit(namespace, 1) else: threadutil.initInstanceLimit( namespace, config.getdefaultint('Repository ' + reposname, 'maxconnections', 2)) self.config = config return (options, args)
def __parse_cmd_options(self): parser = OptionParser( version=offlineimap.__version__, description="%s.\n\n%s"% (offlineimap.__copyright__, offlineimap.__license__) ) parser.add_option("-V", action="store_true", dest="version", default=False, help="show full version infos") parser.add_option("--dry-run", action="store_true", dest="dryrun", default=False, help="dry run mode") parser.add_option("--info", action="store_true", dest="diagnostics", default=False, help="output information on the configured email repositories") parser.add_option("-1", action="store_true", dest="singlethreading", default=False, help="(the number one) disable all multithreading operations") parser.add_option("-P", dest="profiledir", metavar="DIR", help="sets OfflineIMAP into profile mode.") parser.add_option("-a", dest="accounts", metavar="account1[,account2[,...]]", help="list of accounts to sync") parser.add_option("-c", dest="configfile", metavar="FILE", default=None, help="specifies a configuration file to use") parser.add_option("-d", dest="debugtype", metavar="type1[,type2[,...]]", help="enables debugging for OfflineIMAP " " (types: imap, maildir, thread)") parser.add_option("-l", dest="logfile", metavar="FILE", help="log to FILE") parser.add_option("-s", action="store_true", dest="syslog", default=False, help="log to syslog") parser.add_option("-f", dest="folders", metavar="folder1[,folder2[,...]]", help="only sync the specified folders") parser.add_option("-k", dest="configoverride", action="append", metavar="[section:]option=value", help="override configuration file option") parser.add_option("-o", action="store_true", dest="runonce", default=False, help="run only once (ignore autorefresh)") parser.add_option("-q", action="store_true", dest="quick", default=False, help="run only quick synchronizations (don't update flags)") parser.add_option("-u", dest="interface", help="specifies an alternative user interface" " (quiet, basic, syslog, ttyui, blinkenlights, machineui)") parser.add_option("--delete-folder", dest="deletefolder", default=None, metavar="FOLDERNAME", help="Delete a folder (on the remote repository)") parser.add_option("--migrate-fmd5-using-nametrans", action="store_true", dest="migrate_fmd5", default=False, help="migrate FMD5 hashes from versions prior to 6.3.5") parser.add_option("--mbnames-prune", action="store_true", dest="mbnames_prune", default=False, help="remove mbnames entries for accounts not in accounts") (options, args) = parser.parse_args() globals.set_options (options) if options.version: print("offlineimap v%s, imaplib2 v%s (%s)"% ( offlineimap.__version__, imaplib.__version__, imaplib.DESC)) sys.exit(0) # Read in configuration file. if not options.configfile: # Try XDG location, then fall back to ~/.offlineimaprc xdg_var = 'XDG_CONFIG_HOME' if not xdg_var in os.environ or not os.environ[xdg_var]: xdg_home = os.path.expanduser('~/.config') else: xdg_home = os.environ[xdg_var] options.configfile = os.path.join(xdg_home, "offlineimap", "config") if not os.path.exists(options.configfile): options.configfile = os.path.expanduser('~/.offlineimaprc') configfilename = options.configfile else: configfilename = os.path.expanduser(options.configfile) config = CustomConfigParser() if not os.path.exists(configfilename): # TODO, initialize and make use of chosen ui for logging logging.error(" *** Config file '%s' does not exist; aborting!"% configfilename) sys.exit(1) config.read(configfilename) # Profile mode chosen? if options.profiledir: if not options.singlethreading: # TODO, make use of chosen ui for logging logging.warn("Profile mode: Forcing to singlethreaded.") options.singlethreading = True if os.path.exists(options.profiledir): # TODO, make use of chosen ui for logging logging.warn("Profile mode: Directory '%s' already exists!"% options.profiledir) else: os.mkdir(options.profiledir) threadutil.ExitNotifyThread.set_profiledir(options.profiledir) # TODO, make use of chosen ui for logging logging.warn("Profile mode: Potentially large data will be " "created in '%s'"% options.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) # Which ui to use? CLI option overrides config file. ui_type = config.getdefault('general', 'ui', 'ttyui') if options.interface != None: ui_type = options.interface if '.' in ui_type: # Transform Curses.Blinkenlights -> Blinkenlights. ui_type = ui_type.split('.')[-1] # TODO, make use of chosen ui for logging logging.warning('Using old interface name, consider using one ' 'of %s'% ', '.join(UI_LIST.keys())) if options.diagnostics: ui_type = 'ttyui' # Enforce this UI for --info. # dry-run? Set [general]dry-run=True. if options.dryrun: dryrun = config.set('general', 'dry-run', 'True') config.set_if_not_exists('general', 'dry-run', 'False') try: # Create the ui class. self.ui = UI_LIST[ui_type.lower()](config) except KeyError: logging.error("UI '%s' does not exist, choose one of: %s"% (ui_type, ', '.join(UI_LIST.keys()))) sys.exit(1) setglobalui(self.ui) # Set up additional log files. if options.logfile: self.ui.setlogfile(options.logfile) # Set up syslog. if options.syslog: self.ui.setup_sysloghandler() # Welcome blurb. self.ui.init_banner() if options.debugtype: self.ui.logger.setLevel(logging.DEBUG) if options.debugtype.lower() == 'all': options.debugtype = 'imap,maildir,thread' # Force single threading? if not ('thread' in options.debugtype.split(',') \ and not options.singlethreading): self.ui._msg("Debug mode: Forcing to singlethreaded.") options.singlethreading = True debugtypes = options.debugtype.split(',') + [''] for dtype in debugtypes: dtype = dtype.strip() self.ui.add_debug(dtype) if dtype.lower() == u'imap': imaplib.Debug = 5 if options.runonce: # Must kill the possible default option. if config.has_option('DEFAULT', 'autorefresh'): config.remove_option('DEFAULT', 'autorefresh') # FIXME: spaghetti code alert! for section in accounts.getaccountlist(config): config.remove_option('Account ' + section, "autorefresh") if options.quick: for section in accounts.getaccountlist(config): config.set('Account ' + section, "quick", '-1') # Custom folder list specified? if options.folders: foldernames = options.folders.split(",") folderfilter = "lambda f: f in %s"% foldernames folderincludes = "[]" for accountname in accounts.getaccountlist(config): account_section = 'Account ' + accountname remote_repo_section = 'Repository ' + \ config.get(account_section, 'remoterepository') config.set(remote_repo_section, "folderfilter", folderfilter) config.set(remote_repo_section, "folderincludes", folderincludes) if options.logfile: sys.stderr = self.ui.logfile socktimeout = config.getdefaultint("general", "socktimeout", 0) if socktimeout > 0: socket.setdefaulttimeout(socktimeout) threadutil.initInstanceLimit( ACCOUNT_LIMITED_THREAD_NAME, config.getdefaultint('general', 'maxsyncaccounts', 1) ) for reposname in config.getsectionlist('Repository'): # Limit the number of threads. Limitation on usage is handled at the # imapserver level. for namespace in [accounts.FOLDER_NAMESPACE + reposname, MSGCOPY_NAMESPACE + reposname]: if options.singlethreading: threadutil.initInstanceLimit(namespace, 1) else: threadutil.initInstanceLimit( namespace, config.getdefaultint( 'Repository ' + reposname, 'maxconnections', 2) ) self.config = config return (options, args)
def parse_cmd_options(self): parser = OptionParser( version=offlineimap.__version__, description="%s.\n\n%s" % (offlineimap.__copyright__, offlineimap.__license__)) parser.add_option( "--dry-run", action="store_true", dest="dryrun", default=False, help="Do not actually modify any store but check and print " "what synchronization actions would be taken if a sync would be" " performed. It will not precisely give the exact information w" "hat will happen. If e.g. we need to create a folder, it merely" " outputs 'Would create folder X', but not how many and which m" "ails it would transfer.") parser.add_option( "--info", action="store_true", dest="diagnostics", default=False, help="Output information on the configured email repositories" ". Useful for debugging and bug reporting. Use in conjunction wit" "h the -a option to limit the output to a single account. This mo" "de will prevent any actual sync to occur and exits after it outp" "ut the debug information.") 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 " "decrease 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 " "%default.") parser.add_option( "-d", dest="debugtype", metavar="type1,[type2...]", help="Enables debugging for OfflineIMAP. This is useful " "if you are to track down a malfunction or figure out what is " "going on under the hood. This option requires one or more " "debugtypes, separated by commas. These define what exactly " "will be debugged, and so far include two options: imap, thread, " "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. " "The use of any debug option (unless 'thread' is included), " "implies the single-thread option -1.") 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 folder names " "are the *untranslated* foldernames of the remote repository. " "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 (if a flag on the remote IMAP " "changes, and we have the message locally, it will be left " "untouched in a quick run.") 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(UI_LIST.keys())) (options, args) = parser.parse_args() globals.set_options(options) #read in configuration file configfilename = os.path.expanduser(options.configfile) config = CustomConfigParser() if not os.path.exists(configfilename): # TODO, initialize and make use of chosen ui for logging logging.error(" *** Config file '%s' does not exist; aborting!" % configfilename) sys.exit(1) config.read(configfilename) #profile mode chosen? if options.profiledir: if not options.singlethreading: # TODO, make use of chosen ui for logging logging.warn("Profile mode: Forcing to singlethreaded.") options.singlethreading = True if os.path.exists(options.profiledir): # TODO, make use of chosen ui for logging logging.warn("Profile mode: Directory '%s' already exists!" % options.profiledir) else: os.mkdir(options.profiledir) threadutil.ExitNotifyThread.set_profiledir(options.profiledir) # TODO, make use of chosen ui for logging logging.warn("Profile mode: Potentially large data will be " "created in '%s'" % options.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) #which ui to use? cmd line option overrides config file ui_type = config.getdefault('general', 'ui', 'ttyui') if options.interface != None: ui_type = options.interface if '.' in ui_type: #transform Curses.Blinkenlights -> Blinkenlights ui_type = ui_type.split('.')[-1] # TODO, make use of chosen ui for logging logging.warning('Using old interface name, consider using one ' 'of %s' % ', '.join(UI_LIST.keys())) if options.diagnostics: ui_type = 'basic' # enforce basic UI for --info #dry-run? Set [general]dry-run=True if options.dryrun: dryrun = config.set('general', 'dry-run', "True") config.set_if_not_exists('general', 'dry-run', 'False') try: # create the ui class self.ui = UI_LIST[ui_type.lower()](config) except KeyError: logging.error("UI '%s' does not exist, choose one of: %s" % \ (ui_type,', '.join(UI_LIST.keys()))) sys.exit(1) setglobalui(self.ui) #set up additional log files if options.logfile: self.ui.setlogfile(options.logfile) #welcome blurb self.ui.init_banner() if options.debugtype: self.ui.logger.setLevel(logging.DEBUG) if options.debugtype.lower() == 'all': options.debugtype = 'imap,maildir,thread' #force single threading? if not ('thread' in options.debugtype.split(',') \ and not options.singlethreading): self.ui._msg("Debug mode: Forcing to singlethreaded.") options.singlethreading = True debugtypes = options.debugtype.split(',') + [''] for type in debugtypes: type = type.strip() self.ui.add_debug(type) if type.lower() == 'imap': imaplib.Debug = 5 if options.runonce: # FIXME: maybe need a better for section in accounts.getaccountlist(config): config.remove_option('Account ' + section, "autorefresh") if options.quick: for section in accounts.getaccountlist(config): config.set('Account ' + section, "quick", '-1') #custom folder list specified? if options.folders: foldernames = options.folders.split(",") folderfilter = "lambda f: f in %s" % foldernames folderincludes = "[]" for accountname in accounts.getaccountlist(config): account_section = 'Account ' + accountname remote_repo_section = 'Repository ' + \ config.get(account_section, 'remoterepository') config.set(remote_repo_section, "folderfilter", folderfilter) config.set(remote_repo_section, "folderincludes", folderincludes) if options.logfile: sys.stderr = self.ui.logfile socktimeout = config.getdefaultint("general", "socktimeout", 0) if socktimeout > 0: socket.setdefaulttimeout(socktimeout) threadutil.initInstanceLimit( 'ACCOUNTLIMIT', config.getdefaultint('general', 'maxsyncaccounts', 1)) for reposname in config.getsectionlist('Repository'): for instancename in [ "FOLDER_" + reposname, "MSGCOPY_" + reposname ]: if options.singlethreading: threadutil.initInstanceLimit(instancename, 1) else: threadutil.initInstanceLimit( instancename, config.getdefaultint('Repository ' + reposname, 'maxconnections', 2)) self.config = config return (options, args)
def __parse_cmd_options(self): parser = OptionParser(version=offlineimap.__bigversion__, description="%s.\n\n%s" % (offlineimap.__copyright__, offlineimap.__license__)) parser.add_option("--dry-run", action="store_true", dest="dryrun", default=False, help="Do not actually modify any store but check and print " "what synchronization actions would be taken if a sync would be" " performed. It will not precisely give the exact information w" "hat will happen. If e.g. we need to create a folder, it merely" " outputs 'Would create folder X', but not how many and which m" "ails it would transfer.") parser.add_option("--info", action="store_true", dest="diagnostics", default=False, help="Output information on the configured email repositories" ". Useful for debugging and bug reporting. Use in conjunction wit" "h the -a option to limit the output to a single account. This mo" "de will prevent any actual sync to occur and exits after it outp" "ut the debug information.") 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 " "decrease 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=None, help="Specifies a configuration file to use") parser.add_option("-d", dest="debugtype", metavar="type1,[type2...]", help="Enables debugging for OfflineIMAP. This is useful " "if you are to track down a malfunction or figure out what is " "going on under the hood. This option requires one or more " "debugtypes, separated by commas. These define what exactly " "will be debugged, and so far include two options: imap, thread, " "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. " "The use of any debug option (unless 'thread' is included), " "implies the single-thread option -1.") 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 folder names " "are the *untranslated* foldernames of the remote repository. " "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 (if a flag on the remote IMAP " "changes, and we have the message locally, it will be left " "untouched in a quick run.") 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(UI_LIST.keys())) (options, args) = parser.parse_args() globals.set_options (options) #read in configuration file if not options.configfile: # Try XDG location, then fall back to ~/.offlineimaprc xdg_var = 'XDG_CONFIG_HOME' if not xdg_var in os.environ or not os.environ[xdg_var]: xdg_home = os.path.expanduser('~/.config') else: xdg_home = os.environ[xdg_var] options.configfile = os.path.join(xdg_home, "offlineimap", "config") if not os.path.exists(options.configfile): options.configfile = os.path.expanduser('~/.offlineimaprc') configfilename = options.configfile else: configfilename = os.path.expanduser(options.configfile) config = CustomConfigParser() if not os.path.exists(configfilename): # TODO, initialize and make use of chosen ui for logging logging.error(" *** Config file '%s' does not exist; aborting!" % configfilename) sys.exit(1) config.read(configfilename) #profile mode chosen? if options.profiledir: if not options.singlethreading: # TODO, make use of chosen ui for logging logging.warn("Profile mode: Forcing to singlethreaded.") options.singlethreading = True if os.path.exists(options.profiledir): # TODO, make use of chosen ui for logging logging.warn("Profile mode: Directory '%s' already exists!" % options.profiledir) else: os.mkdir(options.profiledir) threadutil.ExitNotifyThread.set_profiledir(options.profiledir) # TODO, make use of chosen ui for logging logging.warn("Profile mode: Potentially large data will be " "created in '%s'" % options.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) #which ui to use? cmd line option overrides config file ui_type = config.getdefault('general','ui', 'ttyui') if options.interface != None: ui_type = options.interface if '.' in ui_type: #transform Curses.Blinkenlights -> Blinkenlights ui_type = ui_type.split('.')[-1] # TODO, make use of chosen ui for logging logging.warning('Using old interface name, consider using one ' 'of %s' % ', '.join(UI_LIST.keys())) if options.diagnostics: ui_type = 'basic' # enforce basic UI for --info #dry-run? Set [general]dry-run=True if options.dryrun: dryrun = config.set('general','dry-run', "True") config.set_if_not_exists('general','dry-run','False') try: # create the ui class self.ui = UI_LIST[ui_type.lower()](config) except KeyError: logging.error("UI '%s' does not exist, choose one of: %s" % \ (ui_type,', '.join(UI_LIST.keys()))) sys.exit(1) setglobalui(self.ui) #set up additional log files if options.logfile: self.ui.setlogfile(options.logfile) #welcome blurb self.ui.init_banner() if options.debugtype: self.ui.logger.setLevel(logging.DEBUG) if options.debugtype.lower() == 'all': options.debugtype = 'imap,maildir,thread' #force single threading? if not ('thread' in options.debugtype.split(',') \ and not options.singlethreading): self.ui._msg("Debug mode: Forcing to singlethreaded.") options.singlethreading = True debugtypes = options.debugtype.split(',') + [''] for type in debugtypes: type = type.strip() self.ui.add_debug(type) if type.lower() == 'imap': imaplib.Debug = 5 # XXX: can we avoid introducing fake configuration item? config.set_if_not_exists('general', 'single-thread', 'True' if options.singlethreading else 'False') if options.runonce: # FIXME: maybe need a better for section in accounts.getaccountlist(config): config.remove_option('Account ' + section, "autorefresh") if options.quick: for section in accounts.getaccountlist(config): config.set('Account ' + section, "quick", '-1') #custom folder list specified? if options.folders: foldernames = options.folders.split(",") folderfilter = "lambda f: f in %s" % foldernames folderincludes = "[]" for accountname in accounts.getaccountlist(config): account_section = 'Account ' + accountname remote_repo_section = 'Repository ' + \ config.get(account_section, 'remoterepository') config.set(remote_repo_section, "folderfilter", folderfilter) config.set(remote_repo_section, "folderincludes", folderincludes) if options.logfile: sys.stderr = self.ui.logfile socktimeout = config.getdefaultint("general", "socktimeout", 0) if socktimeout > 0: socket.setdefaulttimeout(socktimeout) threadutil.initInstanceLimit('ACCOUNTLIMIT', config.getdefaultint('general', 'maxsyncaccounts', 1)) for reposname in config.getsectionlist('Repository'): for instancename in ["FOLDER_" + reposname, "MSGCOPY_" + reposname]: if options.singlethreading: threadutil.initInstanceLimit(instancename, 1) else: threadutil.initInstanceLimit(instancename, config.getdefaultint('Repository ' + reposname, 'maxconnections', 2)) self.config = config return (options, args)
def test_double_init(self): with self.assertRaises(ValueError): globals.set_options (True)
def setUpClass(klass): klass.o = Opt() globals.set_options (klass.o)
def __parse_cmd_options(self): parser = OptionParser( version=offlineimap.__bigversion__, description="%s.\n\n%s" % (offlineimap.__copyright__, offlineimap.__license__), ) parser.add_option("--dry-run", action="store_true", dest="dryrun", default=False, help="dry run mode") parser.add_option( "--info", action="store_true", dest="diagnostics", default=False, help="output information on the configured email repositories", ) parser.add_option( "-1", action="store_true", dest="singlethreading", default=False, help="(the number one) disable all multithreading operations", ) parser.add_option("-P", dest="profiledir", metavar="DIR", help="sets OfflineIMAP into profile mode.") parser.add_option("-a", dest="accounts", metavar="account1[,account2[,...]]", help="list of accounts to sync") parser.add_option( "-c", dest="configfile", metavar="FILE", default=None, help="specifies a configuration file to use" ) parser.add_option( "-d", dest="debugtype", metavar="type1[,type2[,...]]", help="enables debugging for OfflineIMAP " " (types: imap, maildir, thread)", ) 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" ) parser.add_option( "-k", dest="configoverride", action="append", metavar="[section:]option=value", help="override configuration file option", ) parser.add_option( "-o", action="store_true", dest="runonce", default=False, help="run only once (ignore autorefresh)" ) parser.add_option( "-q", action="store_true", dest="quick", default=False, help="run only quick synchronizations (don't update flags)", ) parser.add_option( "-u", dest="interface", help="specifies an alternative user interface" " (quiet, basic, ttyui, blinkenlights, machineui)", ) (options, args) = parser.parse_args() globals.set_options(options) # read in configuration file if not options.configfile: # Try XDG location, then fall back to ~/.offlineimaprc xdg_var = "XDG_CONFIG_HOME" if not xdg_var in os.environ or not os.environ[xdg_var]: xdg_home = os.path.expanduser("~/.config") else: xdg_home = os.environ[xdg_var] options.configfile = os.path.join(xdg_home, "offlineimap", "config") if not os.path.exists(options.configfile): options.configfile = os.path.expanduser("~/.offlineimaprc") configfilename = options.configfile else: configfilename = os.path.expanduser(options.configfile) config = CustomConfigParser() if not os.path.exists(configfilename): # TODO, initialize and make use of chosen ui for logging logging.error(" *** Config file '%s' does not exist; aborting!" % configfilename) sys.exit(1) config.read(configfilename) # profile mode chosen? if options.profiledir: if not options.singlethreading: # TODO, make use of chosen ui for logging logging.warn("Profile mode: Forcing to singlethreaded.") options.singlethreading = True if os.path.exists(options.profiledir): # TODO, make use of chosen ui for logging logging.warn("Profile mode: Directory '%s' already exists!" % options.profiledir) else: os.mkdir(options.profiledir) threadutil.ExitNotifyThread.set_profiledir(options.profiledir) # TODO, make use of chosen ui for logging logging.warn("Profile mode: Potentially large data will be " "created in '%s'" % options.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) # which ui to use? cmd line option overrides config file ui_type = config.getdefault("general", "ui", "ttyui") if options.interface != None: ui_type = options.interface if "." in ui_type: # transform Curses.Blinkenlights -> Blinkenlights ui_type = ui_type.split(".")[-1] # TODO, make use of chosen ui for logging logging.warning("Using old interface name, consider using one " "of %s" % ", ".join(UI_LIST.keys())) if options.diagnostics: ui_type = "basic" # enforce basic UI for --info # dry-run? Set [general]dry-run=True if options.dryrun: dryrun = config.set("general", "dry-run", "True") config.set_if_not_exists("general", "dry-run", "False") try: # create the ui class self.ui = UI_LIST[ui_type.lower()](config) except KeyError: logging.error("UI '%s' does not exist, choose one of: %s" % (ui_type, ", ".join(UI_LIST.keys()))) sys.exit(1) setglobalui(self.ui) # set up additional log files if options.logfile: self.ui.setlogfile(options.logfile) # welcome blurb self.ui.init_banner() if options.debugtype: self.ui.logger.setLevel(logging.DEBUG) if options.debugtype.lower() == "all": options.debugtype = "imap,maildir,thread" # force single threading? if not ("thread" in options.debugtype.split(",") and not options.singlethreading): self.ui._msg("Debug mode: Forcing to singlethreaded.") options.singlethreading = True debugtypes = options.debugtype.split(",") + [""] for dtype in debugtypes: dtype = dtype.strip() self.ui.add_debug(dtype) if dtype.lower() == u"imap": imaplib.Debug = 5 if options.runonce: # FIXME: spaghetti code alert! for section in accounts.getaccountlist(config): config.remove_option("Account " + section, "autorefresh") if options.quick: for section in accounts.getaccountlist(config): config.set("Account " + section, "quick", "-1") # custom folder list specified? if options.folders: foldernames = options.folders.split(",") folderfilter = "lambda f: f in %s" % foldernames folderincludes = "[]" for accountname in accounts.getaccountlist(config): account_section = "Account " + accountname remote_repo_section = "Repository " + config.get(account_section, "remoterepository") config.set(remote_repo_section, "folderfilter", folderfilter) config.set(remote_repo_section, "folderincludes", folderincludes) if options.logfile: sys.stderr = self.ui.logfile socktimeout = config.getdefaultint("general", "socktimeout", 0) if socktimeout > 0: socket.setdefaulttimeout(socktimeout) threadutil.initInstanceLimit("ACCOUNTLIMIT", config.getdefaultint("general", "maxsyncaccounts", 1)) for reposname in config.getsectionlist("Repository"): for instancename in ["FOLDER_" + reposname, "MSGCOPY_" + reposname]: if options.singlethreading: threadutil.initInstanceLimit(instancename, 1) else: threadutil.initInstanceLimit( instancename, config.getdefaultint("Repository " + reposname, "maxconnections", 2) ) self.config = config return (options, args)