def load_config(self, configfile):
        # get full path of config file
        configfile = self.tmp_file_path(configfile)

        # check that it exists because CustomConfigParser will
        # ignore absent files
        if not os.path.isfile(configfile):
            raise Exception("Config file %s doesn't exist" % configfile)

        config = CustomConfigParser()
        config.read(configfile)
        config.set_if_not_exists('general','dry-run','False')

        #config.write(sys.stdout)

        return config
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)