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

Revision 3489, 10.2 kB (checked in by jerome, 15 years ago)

Removed bad copy and paste artifact.

  • 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-2009 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, getdefaultcharset
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 float 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
68def checkandset_percent(option, opt, value, optionparser) :
69    """Checks if an option argument is comprised between 0.0 included and 100.0 not included, and validates the option if it is the case."""
70    if not (0.0 <= value < 100.0) :
71        loginvalidparam(opt, value, option.default, \
72                        _("Value must be comprised between 0.0 included and 100.0 not included"))
73        setattr(optionparser.values, option.dest, option.default)
74    else :
75        setattr(optionparser.values, option.dest, value)
76
77def load_arguments_file(option, opt, value, optionparser) :
78    """Loads arguments from a file, one per line."""
79    setattr(optionparser.values, option.dest, value)
80    try :
81        argsfile = open(value.encode(getdefaultcharset(), "replace"), "r")
82    except IOError :
83        loginvalidparam(opt, value, additionalinfo=_("this option will be ignored"))
84    else :
85        arguments = [ l.strip().decode(getdefaultcharset(), "replace") for l in argsfile.readlines() ]
86        argsfile.close()
87        for i in range(len(arguments)) :
88            argi = arguments[i]
89            if argi.startswith('"') and argi.endswith('"') :
90                arguments[i] = argi[1:-1]
91        arguments.reverse()
92        for arg in arguments :
93            optionparser.rargs.insert(0, arg)
94
95class PyKotaOptionParser(optparse.OptionParser) :
96    """
97    This class to define additional methods, and different help
98    formatting, from the traditional OptionParser.
99    """
100    def __init__(self, *args, **kwargs) :
101        """
102        Initializes our option parser with additional attributes.
103        """
104        self.filterexpressions = []
105        self.examples = []
106        kwargs["version"] = "%s (PyKota) %s" % (os.path.basename(sys.argv[0]),
107                                                version.__version__)
108        optparse.OptionParser.__init__(self, *args, **kwargs)
109        self.disable_interspersed_args()
110        self.remove_version_and_help()
111        self.add_generic_options()
112
113    def format_help(self, formatter=None) :
114        """
115        Reformats help our way : adding examples and copyright
116        message at the end.
117        """
118        if formatter is None :
119            formatter = self.formatter
120        result = []
121        result.append(optparse.OptionParser.format_help(self, formatter) + "\n")
122        result.append(self.format_filterexpressions())
123        result.append(self.format_examples())
124        result.append(self.format_copyright())
125        return "".join(result)
126
127    #
128    # Below are PyKota specific additions
129    #
130    def format_filterexpressions(self, formatter=None) :
131        """Formats filter expressions our way."""
132        if formatter is None :
133            formatter = self.formatter
134        result = []
135        if self.filterexpressions :
136            result.append(formatter.format_heading(_("filtering expressions")))
137            formatter.indent()
138            result.append(formatter.format_description(_("Use the filtering expressions to extract only parts of the datas. Allowed filters are of the form 'key=value'. Wildcards are not expanded as part of these filtering expressions, so you can't use them here.")))
139            result.append("\n")
140            result.append(formatter.format_heading(_("allowed keys for now")))
141            formatter.indent()
142            for (expression, explanation) in self.filterexpressions :
143                result.append(formatter.format_description("%s : %s" % (expression, explanation)))
144            formatter.dedent()
145            result.append("\n")
146            result.append(formatter.format_heading(_("formatting of dates with the 'start' and 'end' filtering keys")))
147            formatter.indent()
148            result.append(formatter.format_description(_("YYYY : year boundaries")))
149            result.append(formatter.format_description(_("YYYYMM : month boundaries")))
150            result.append(formatter.format_description(_("YYYYMMDD : day boundaries")))
151            result.append(formatter.format_description(_("YYYYMMDDhh : hour boundaries")))
152            result.append(formatter.format_description(_("YYYYMMDDhhmm : minute boundaries")))
153            result.append(formatter.format_description(_("YYYYMMDDhhmmss : second boundaries")))
154            result.append(formatter.format_description(_("yesterday[+-N] : yesterday more or less N days (e.g. : yesterday-15)")))
155            result.append(formatter.format_description(_("today[+-N] : today more or less N days (e.g. : today-15)")))
156            result.append(formatter.format_description(_("tomorrow[+-N] : tomorrow more or less N days (e.g. : tomorrow-15)")))
157            result.append(formatter.format_description(_("now[+-N] : now more or less N days (e.g. now-15)")))
158            formatter.dedent()
159            result.append("\n")
160            result.append(formatter.format_description(_("'now' and 'today' are not exactly the same since 'today' represents the first or last second of the day depending on if it's used in a 'start=' or 'end=' date expression.")))
161            result.append("\n")
162        return "".join(result)
163
164    def format_examples(self, formatter=None) :
165        """Formats examples our way."""
166        if formatter is None :
167            formatter = self.formatter
168        result = []
169        if self.examples :
170            result.append(formatter.format_heading(_("examples")))
171            formatter.indent()
172            for (cmd, explanation) in self.examples :
173                result.append(formatter.format_description(self.expand_prog_name(cmd)))
174                result.append(formatter.format_description(self.expand_prog_name(explanation)) + "\n")
175            formatter.dedent()
176        return "".join(result)
177
178    def format_copyright(self, formatter=None) :
179        """Formats copyright message our way."""
180        if formatter is None :
181            formatter = self.formatter
182        result = []
183        result.append(formatter.format_heading(_("licensing terms")))
184        formatter.indent()
185        result.append(formatter.format_description("(c) %s %s\n" \
186                                                      % (version.__years__, \
187                                                         version.__author__)))
188        for part in version.__gplblurb__.split("\n\n") :
189            result.append(formatter.format_description(part) + "\n")
190        formatter.dedent()
191        return "".join(result)
192
193    def add_filterexpression(self, expression, doc) :
194        """Adds a filtering expression."""
195        self.filterexpressions.append((expression, doc))
196
197    def add_example(self, command, doc) :
198        """Adds an usage example."""
199        self.examples.append(("%prog " + command, doc))
200
201    def remove_version_and_help(self) :
202        """Removes the default definitions for options version and help."""
203        for o in ("-h", "-help", "--help", "-v", "-version", "--version") :
204            try :
205                self.remove_option(o)
206            except ValueError :
207                pass
208
209    def add_generic_options(self) :
210        """Adds options which are common to all PyKota command line tools."""
211        self.add_option("-h", "--help",
212                              action="help",
213                              help=_("show this help message and exit."))
214        self.add_option("-v", "--version",
215                              action="version",
216                              help=_("show the version number and exit."))
217        self.add_option("-A", "--arguments",
218                              action="callback",
219                              type="string",
220                              dest="argumentsfile",
221                              callback=load_arguments_file,
222                              help=_("loads additional options and arguments from a file, one per line."))
Note: See TracBrowser for help on using the browser.