degal/command.py
author Tero Marttila <terom@fixme.fi>
Thu, 02 Jul 2009 21:59:01 +0300
changeset 144 97505a789003
parent 120 55cb7fc9c8fb
permissions -rw-r--r--
reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
     2
    Command-line based command implementation, handling option/argument parsing.
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
"""
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
     5
import concurrent
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
     6
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
     7
import inspect, itertools, logging, traceback, optparse
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
     8
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
     9
def optify (symbol) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    10
    """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    11
        Turns the given python symbol into the suitable version for use as a command-line argument.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    12
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    13
        In other words, this replaces '_' with '-'.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    14
    """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    15
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    16
    return symbol.replace('_', '-')
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    17
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    18
# wrapper around optparse.make_option
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    19
Option = optparse.make_option
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    20
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    21
class Command (object) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    22
    """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    23
        A Command is simply a function that can be executed from the command line with some options/arguments
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    24
    """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    25
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    26
    def __init__ (self, name, func, doc=None, options=None) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    27
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    28
            Create a new Command
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    29
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    30
             name       - the name of the command
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    31
             func       - the callable python function
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    32
             doc        - descriptive help text
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    33
             options    - named options as Option objects
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    34
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    35
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    36
        self.name = name
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    37
        self.func = func
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    38
        self.doc = doc
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    39
        self.options = options
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    40
    
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    41
    def parse_args (self, args) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    42
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    43
            Pre-parse the given arguments list.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    44
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    45
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    46
        return args
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    47
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    48
    def apply (self, config, gallery, options, *args, **kwargs) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    49
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    50
            Construct a CommandContext for execution of this command with the given environment.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    51
            the command with the given context.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    52
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    53
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    54
        # apply extra options
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    55
        for k, v in kwargs.iteritems() :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    56
            setattr(options, k, v)
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    57
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    58
        return Environment(self, config, gallery, options, args)
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    59
    
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    60
    def option_group (self, parser) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    61
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    62
            Returns an optparse.OptionGroup for this command's options.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    63
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    64
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    65
        group = optparse.OptionGroup(parser, "Command-specific options")
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    66
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    67
        for opt in self.options :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    68
            group.add_option(opt)
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    69
    
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    70
        return group
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    71
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    72
    def cmdopt_callback (self, option, opt_str, value, parser) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    73
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    74
            Used as a optparse.Option callback-action, adds this command's options to the parser, and stores the
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    75
            selected command.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    76
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    77
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    78
        # check
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    79
        if hasattr(parser.values, option.dest) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    80
            raise ArgumentError("More than one command option given: %s + %s" % (getattr(parser.values, option.dest), self.name))
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    81
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    82
        if self.options :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    83
            # setup command-specific options
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    84
            parser.add_option_group(self.build_options(parser))
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    85
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    86
        # store selected command
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    87
        setattr(parser.values, option.dest, self)
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
class CommandList (object) :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
    """
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    91
        A set of available Commands
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
    """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
    def __init__ (self, commands) :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
            Store with given initial commands
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
        self.list = commands
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
        self.dict = dict((cmd.name, cmd) for cmd in commands)
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    def lookup (self, name) :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
            Lookup a command by name
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
        return self.dict[name]
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   109
    def option_group (self, parser, default) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   110
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   111
            Returns an optparse.OptionGroup for these commands, using the given parser.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   112
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   113
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   114
        group = optparse.OptionGroup(parser, "Command Options", "Select what command to execute, may introduce other options")
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   115
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   116
        for command in self.list :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   117
            group.add_option('--%s' % optify(command.name), action='callback', callback=command.cmdopt_callback, dest='command', help=command.doc)
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   118
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   119
        # store default
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   120
        parser.set_defaults(command=default)
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   121
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   122
        return group
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   123
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   124
class Environment (object) :
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
    """
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   126
        The environment that a Command will execute in.
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   127
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   128
        This is bound to a Configuration, a Gallery, options values, argument values and other miscellaneous things. An
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   129
        environment also provides other services, such as status output, concurrent execution and error handling.
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
    """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   132
    def __init__ (self, command, config, gallery, options, args) :
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
            Create the execution environment
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
        self.command = command
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        self.config = config
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        self.gallery = gallery
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   140
        self.options = options
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   141
        self.args = args
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
117
a2e4562deaab implement concurrency... :)
Tero Marttila <terom@fixme.fi>
parents: 114
diff changeset
   143
        # conccurency
a2e4562deaab implement concurrency... :)
Tero Marttila <terom@fixme.fi>
parents: 114
diff changeset
   144
        self.concurrent = concurrent.Manager(thread_count=config.thread_count)
a2e4562deaab implement concurrency... :)
Tero Marttila <terom@fixme.fi>
parents: 114
diff changeset
   145
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   146
    def execute (self) :
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
            Run the command in this context
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   151
        return self.command.func(self, *self.args)
92
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   152
    
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   153
    def run (self) :
92
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   154
        """
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   155
            Run the command with error handling
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   156
        """
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   157
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   158
        try :
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   159
            # run it
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   160
            return self.execute()
92
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   161
        
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   162
        except KeyboardInterrupt :
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   163
            self.log_error("Interrupted")
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   164
eb50b4f7812d move Command exception handling into command.py, and handle KeyboardInterrupt
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   165
        except :
114
4096f8a7e63c fix use of handle_error in command.py
Tero Marttila <terom@fixme.fi>
parents: 92
diff changeset
   166
            # dump traceback
120
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 117
diff changeset
   167
            # XXX: skip all crap up to the actual function
114
4096f8a7e63c fix use of handle_error in command.py
Tero Marttila <terom@fixme.fi>
parents: 92
diff changeset
   168
            self.handle_error()
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   169
    
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   170
    # XXX: split off to a .log object
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
    def log_msg (self, level, msg, *args, **kwargs) :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
            Output a log message with the given level
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
            XXX: unicode
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
        """
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
        
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
        # control level of output
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        if level < self.config.log_level :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
            return
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
        # format?
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
        if args or kwargs :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
            if args and not kwargs :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
                msg = msg % args
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
            elif kwargs and not args :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
                msg = msg % kwargs
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
            else :
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
                raise Exception("log_msg called with both args and kwargs")
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
        # output
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
        # XXX: stdout/err?
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
        print msg
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
    def log_debug (self, msg, *args, **kwargs) :
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   198
        self.log_msg(logging.DEBUG, msg, *args, **kwargs)
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
    def log_info (self, msg, *args, **kwargs) :
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   201
        self.log_msg(logging.INFO, msg, *args, **kwargs)
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
    
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
    def log_warning (self, msg, *args, **kwargs) :
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   204
        self.log_msg(logging.WARNING, msg, *args, **kwargs)
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
    def log_error (self, msg, *args, **kwargs) :
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   207
        self.log_msg(logging.ERROR, msg, *args, **kwargs)
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   208
    
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   209
    def handle_error (self, exc_info=None) :
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   210
        """
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   211
            Do something to handle an error that occured
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   212
        """
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   213
        
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   214
        if exc_info :
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   215
            traceback.print_execption(*exc_info)
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   216
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   217
        else :
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 65
diff changeset
   218
            traceback.print_exc()
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
144
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   220
def command (options=None) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   221
    def _decorator (func) :
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   222
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   223
            A function decorator used to define Commands automatically
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   224
        """
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   225
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   226
        # find help string
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   227
        doc = inspect.getdoc(func)
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   228
        
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   229
        return Command(func.__name__, func, doc, options)
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   230
    
97505a789003 reorganize/rename the commands and their options stuff, options like --force-html are now split out from main.py into commands/update.py
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
   231
    return _decorator
65
97e1bc208574 initial commands infrastructure
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232