root / pykota / trunk / pykota / commandline.py @ 3339

Revision 3339, 8.8 kB (checked in by jerome, 16 years ago)

Can now add filtering expressions as part of the generated help.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# -*- coding: UTF-8 -*-
2#
3# PyKota : Print Quotas for CUPS
4#
5# (c) 2003, 2004, 2005, 2006, 2007, 2008 Jerome Alet <alet@librelogiciel.com>
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19# $Id$
20#
21
22"""This modules defines a command line options parser for PyKota's command line tools."""
23
24import sys
25import os
26import optparse
27from gettext import gettext as _
28
29from pykota import version
30from pykota.utils import loginvalidparam
31
32def checkandset_pagesize(option, opt, value, optionparser) :
33    """Checks and sets the page size."""
34    from pykota.pdfutils import getPageSize
35    if getPageSize(value) is None :
36        loginvalidparam(opt, value, option.default)
37        setattr(optionparser.values, option.dest, option.default)
38    else :   
39        setattr(optionparser.values, option.dest, value)
40   
41def checkandset_savetoner(option, opt, value, optionparser) :   
42    """Checks and sets the save toner value."""
43    if (value < 0.0) or (value > 99.0) :
44        loginvalidparam(opt, value, option.default, \
45                        _("Allowed range is (0..99)"))
46        setattr(optionparser.values, option.dest, option.default)
47    else :   
48        setattr(optionparser.values, option.dest, value)
49       
50def checkandset_positiveint(option, opt, value, optionparser) :   
51    """Checks if an option argument is a positive integer and validates the option if it is the case."""
52    if not (value >= 0) :
53        loginvalidparam(opt, value, option.default, \
54                        _("Value must be positive"))
55        setattr(optionparser.values, option.dest, option.default)
56    else :   
57        setattr(optionparser.values, option.dest, value)
58       
59def checkandset_positivefloat(option, opt, value, optionparser) :   
60    """Checks if an option argument is a positive integer and validates the option if it is the case."""
61    if not (value >= 0.0) :
62        loginvalidparam(opt, value, option.default, \
63                        _("Value must be positive"))
64        setattr(optionparser.values, option.dest, option.default)
65    else :   
66        setattr(optionparser.values, option.dest, value)
67
68class PyKotaOptionParser(optparse.OptionParser) :
69    """
70    This class to define additional methods, and different help
71    formatting, from the traditional OptionParser.
72    """   
73    def __init__(self, *args, **kwargs) :
74        """
75        Initializes our option parser with additional attributes.
76        """
77        self.filterexpressions = []
78        self.examples = []
79        kwargs["version"] = "%s (PyKota) %s" % (os.path.basename(sys.argv[0]),
80                                                version.__version__)
81        optparse.OptionParser.__init__(self, *args, **kwargs)
82        self.disable_interspersed_args()
83        self.remove_version_and_help()
84        self.add_generic_options()
85       
86    def format_help(self, formatter=None) :
87        """
88        Reformats help our way : adding examples and copyright
89        message at the end.
90        """
91        if formatter is None :
92            formatter = self.formatter
93        result = []
94        result.append(optparse.OptionParser.format_help(self, formatter) + "\n")
95        result.append(self.format_filterexpressions())
96        result.append(self.format_examples())
97        result.append(self.format_copyright())
98        return "".join(result)
99           
100    #   
101    # Below are PyKota specific additions   
102    #
103    def format_filterexpressions(self, formatter=None) :
104        """Formats filter expressions our way."""
105        if formatter is None :
106            formatter = self.formatter
107        result = []   
108        if self.filterexpressions :
109            result.append(formatter.format_heading(_("filtering expressions")))
110            formatter.indent()
111            result.append(formatter.format_description(_("Use the filtering expressions to extract only parts of the datas. Allowed filters are of the form 'key=value'.")))
112            result.append("\n")
113            result.append(formatter.format_heading(_("allowed keys for now")))
114            formatter.indent() 
115            for (expression, explanation) in self.filterexpressions :
116                result.append(formatter.format_description("%s : %s" % (expression, explanation)))
117            formatter.dedent()   
118            result.append("\n")
119            result.append(formatter.format_heading(_("formatting of dates with the 'start' and 'end' filtering keys")))
120            formatter.indent()
121            result.append(formatter.format_description(_("YYYY : year boundaries")))
122            result.append(formatter.format_description(_("YYYYMM : month boundaries")))
123            result.append(formatter.format_description(_("YYYYMMDD : day boundaries")))
124            result.append(formatter.format_description(_("YYYYMMDDhh : hour boundaries")))
125            result.append(formatter.format_description(_("YYYYMMDDhhmm : minute boundaries")))
126            result.append(formatter.format_description(_("YYYYMMDDhhmmss : second boundaries")))
127            result.append(formatter.format_description(_("yesterday[+-N] : yesterday more or less N days (e.g. : yesterday-15)")))
128            result.append(formatter.format_description(_("today[+-N] : today more or less N days (e.g. : today-15)")))
129            result.append(formatter.format_description(_("tomorrow[+-N] : tomorrow more or less N days (e.g. : tomorrow-15)")))
130            result.append(formatter.format_description(_("now[+-N] : now more or less N days (e.g. now-15)")))
131            formatter.dedent()   
132            result.append("\n")
133        return "".join(result)
134       
135
136  #'now' and 'today' are not exactly the same since today represents the first
137  #or last second of the day depending on if it's used in a start= or end=
138  #date expression. The utility to be able to specify dates in the future is
139  #a question which remains to be answered :-)
140  #
141  #Contrary to other PyKota management tools, wildcard characters are not
142  #expanded, so you can't use them.
143       
144    def format_examples(self, formatter=None) :
145        """Formats examples our way."""
146        if formatter is None :
147            formatter = self.formatter
148        result = []
149        if self.examples :
150            result.append(formatter.format_heading(_("examples")))
151            formatter.indent()
152            for (cmd, explanation) in self.examples :
153                result.append(formatter.format_description(self.expand_prog_name(cmd)))
154                result.append(formatter.format_description(self.expand_prog_name(explanation)) + "\n")
155            formatter.dedent()
156        return "".join(result)   
157       
158    def format_copyright(self, formatter=None) :
159        """Formats copyright message our way."""
160        if formatter is None :
161            formatter = self.formatter
162        result = []   
163        result.append(formatter.format_heading(_("licensing terms")))
164        formatter.indent()
165        result.append(formatter.format_description("(c) %s %s\n" \
166                                                      % (version.__years__, \
167                                                         version.__author__)))
168        for part in version.__gplblurb__.split("\n\n") :
169            result.append(formatter.format_description(part) + "\n")
170        formatter.dedent()   
171        return "".join(result)
172       
173    def add_filterexpression(self, expression, doc) :   
174        """Adds a filtering expression."""
175        self.filterexpressions.append((expression, doc))
176       
177    def add_example(self, command, doc) :   
178        """Adds an usage example."""
179        self.examples.append(("%prog " + command, doc))
180       
181    def remove_version_and_help(self) :   
182        """Removes the default definitions for options version and help."""
183        for o in ("-h", "-help", "--help", "-v", "-version", "--version") :
184            try :
185                self.remove_option(o)
186            except ValueError :     
187                pass
188               
189    def add_generic_options(self) :   
190        """Adds options which are common to all PyKota command line tools."""
191        self.add_option("-h", "--help",
192                              action="help",
193                              help=_("show this help message and exit"))
194        self.add_option("-v", "--version",
195                              action="version",
196                              help=_("show the version number and exit"))
Note: See TracBrowser for help on using the browser.