implement our own optparse.Option with date/timezone types
authorTero Marttila <terom@fixme.fi>
Wed, 11 Feb 2009 04:41:22 +0200
changeset 105 e24da9a94ffb
parent 104 34c65a8c8b94
child 106 0690d715385d
implement our own optparse.Option with date/timezone types
scripts/search-index
--- a/scripts/search-index	Wed Feb 11 04:19:10 2009 +0200
+++ b/scripts/search-index	Wed Feb 11 04:41:22 2009 +0200
@@ -9,6 +9,7 @@
 
 import os, os.path, fcntl
 import datetime, pytz
+import optparse
 
 # configuration and the LogSearchIndex module
 import config, utils, log_search, channels
@@ -116,7 +117,7 @@
 
     # default tz
     if not tz :
-        tz = options.tz
+        tz = options.timezone
 
     try :
         # parse
@@ -388,7 +389,7 @@
             else :
                 if not options.quiet :
                     print "\t[WARN] Ignoring --after because we found a tempfile"
-        
+            
         # only up to some specific date?
         if options.until :
             until = options.until
@@ -474,42 +475,100 @@
             # display
             print "\t%10s %-30s : %s" % (cmd_name, inspect.formatargspec(cmd_args, cmd_varargs, None, cmd_default), cmd_doc)
 
+class MyOption (optparse.Option) :
+    """
+        Our custom types for optparse
+    """
+
+    def check_date (option, opt, value) :
+        """
+            Parse a date
+        """
+
+        try :
+            # parse
+            return datetime.datetime.strptime(value, '%Y-%m-%d')
+        
+        # trap -> OptionValueError
+        except Exception, e :
+            raise optparse.OptionValueError("option %s: invalid date value: %r" % (opt, value))
+    
+    def check_timezone (option, opt, value) :
+        """
+            Parse a timezone
+        """
+
+        try :
+            # parse
+            return pytz.timezone(value)
+        
+        # trap -> OptionValueError
+        except Exception, e :
+            raise optparse.OptionValueError("option %s: invalid timezone: %r" % (opt, value))
+
+    def take_action (self, action, dest, opt, value, values, parser) :
+        """
+            Override take_action to handle date
+        """
+
+        if action == "parse_date" :
+            # get timezone
+            tz = values.timezone
+
+            # set timezone
+            value = value.replace(tzinfo=tz)
+
+            # store
+            return optparse.Option.take_action(self, 'store', dest, opt, value, values, parser)
+
+        else :
+            # default
+            return optparse.Option.take_action(self, action, dest, opt, value, values, parser)
+
+    TYPES = optparse.Option.TYPES + ('date', 'timezone')
+    TYPE_CHECKER = optparse.Option.TYPE_CHECKER.copy()
+    TYPE_CHECKER['date'] = check_date
+    TYPE_CHECKER['timezone'] = check_timezone
+    ACTIONS = optparse.Option.ACTIONS + ('parse_date', )
+    STORE_ACTIONS = optparse.Option.STORE_ACTIONS + ('parse_date', )
+    TYPED_ACTIONS = optparse.Option.TYPED_ACTIONS + ('parse_date', )
+    ACTIONS = optparse.Option.ACTIONS + ('parse_date', )
+
 def main (argv) :
     """
         Command-line main, with given argv
     """
 
-    from optparse import OptionParser, OptionGroup
-    
     # define parser
-    parser = OptionParser(
+    parser = optparse.OptionParser(
         usage           = "%prog [options] <command> [ ... ]",
         add_help_option = False,
+        option_class    = MyOption,
     )
 
     # define command-line arguments
-    general = OptionGroup(parser, "General Options")
-    general.add_option('-h', "--help",           dest="help",            help="Show this help message and exit",     action="store_true" )
+    general = optparse.OptionGroup(parser, "General Options")
+    general.add_option('-h', "--help",           dest="help",            help="Show this help message and exit",     action="store_true"    )
     general.add_option(      "--formatter",      dest="formatter_name",  help="LogFormatter to use",                 metavar="FMT",  type="choice", default="irssi",
         choices=[fmt_name for fmt_name in config.LOG_FORMATTERS.iterkeys()])
 
-    general.add_option(      "--index",          dest="index_path",      help="Index database path",                 metavar="PATH", default="logs/index"            )
-    general.add_option(      "--timezone",       dest="tz_name",         help="Timezone for output",                 metavar="TZ",   default="UTC"                   )
-    general.add_option(      "--force",          dest="force",           help="Force dangerous operation",           action="store_true" )
-    general.add_option(      "--quiet",          dest="quiet",           help="Supress status messages",             action="store_true" )
+    general.add_option(      "--index",          dest="index_path",      help="Index database path",                 metavar="PATH", default="logs/index"               )
+    general.add_option(      "--timezone",       dest="timezone",        help="Timezone for output",                 metavar="TZ",   type="timezone", default=pytz.utc  )
+    general.add_option(      "--force",          dest="force",           help="Force dangerous operation",           action="store_true"    )
+    general.add_option(      "--quiet",          dest="quiet",           help="Supress status messages",             action="store_true"    )
     parser.add_option_group(general)
     
-    load = OptionGroup(parser, "Load Options")
-    load.add_option(      "--skip-missing",   dest="skip_missing",    help="Skip missing logfiles",               action="store_true" )
-    load.add_option(      "--create",         dest="create",          help="Create index database",               action="store_true" )
+    load = optparse.OptionGroup(parser, "Load Options")
+    load.add_option(      "--skip-missing",   dest="skip_missing",    help="Skip missing logfiles",               action="store_true"       )
+    load.add_option(      "--create",         dest="create",          help="Create index database",               action="store_true"       )
     parser.add_option_group(load)
     
-    autoload = OptionGroup(parser, "Autoload Options")
+    autoload = optparse.OptionGroup(parser, "Autoload Options")
     autoload.add_option(      "--autoload-state", dest="autoload_state_path", help="Path to autoload state dir",      metavar="PATH", default="logs/autoload-state"   )
-    autoload.add_option(      "--after",          dest="after",           help="Only autoload logfiles after the given date", metavar="DATE", default=None            )
-    autoload.add_option(      "--until",          dest="until",           help="Only autoload logfiles up to the given date", metavar="DATE", default=None            )
-    autoload.add_option(      "--reload",         dest="reload",          help="Force reload lines",                  action="store_true" )
-    autoload.add_option(      "--reset",          dest="reset",           help="Reset old autload state",             action="store_true" )
+    autoload.add_option(      "--after",          dest="after",           help="Only autoload logfiles after the given date", metavar="DATE", type="date", action="parse_date", default=None )
+    autoload.add_option(      "--until",          dest="until",           help="Only autoload logfiles up to the given date", metavar="DATE", type="date", action="parse_date", default=None )
+    autoload.add_option(      "--reload",         dest="reload",          help="Force reload lines",                  action="store_true"   )
+    autoload.add_option(      "--reset",          dest="reset",           help="Reset old autload state",             action="store_true"   )
     autoload.add_option(      "--ignore-resume",  dest="ignore_resume",   help="Do not try and resume interrupted autoload",  action="store_true" )
     parser.add_option_group(autoload)
 
@@ -518,15 +577,7 @@
 
     # postprocess stuff
     options._parser = parser
-    options.tz = pytz.timezone(options.tz_name)
-    options.formatter = config.LOG_FORMATTERS[options.formatter_name](options.tz, "%H:%M:%S", None, None)
-
-    # XXX: convert to custom types
-    if options.after :
-        options.after = _parse_date(options, options.after)
-
-    if options.until :
-        options.until = _parse_date(options, options.until)
+    options.formatter = config.LOG_FORMATTERS[options.formatter_name](options.timezone, "%H:%M:%S", None, None)
 
     # special-case --help
     if options.help :