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

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
RevLine 
[3489]1# -*- coding: utf-8 -*-
[695]2#
[3260]3# PyKota : Print Quotas for CUPS
[695]4#
[3481]5# (c) 2003-2009 Jerome Alet <alet@librelogiciel.com>
[3260]6# This program is free software: you can redistribute it and/or modify
[873]7# it under the terms of the GNU General Public License as published by
[3260]8# the Free Software Foundation, either version 3 of the License, or
[873]9# (at your option) any later version.
[3413]10#
[873]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.
[3413]15#
[873]16# You should have received a copy of the GNU General Public License
[3260]17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
[695]18#
19# $Id$
20#
[3304]21
22"""This modules defines a command line options parser for PyKota's command line tools."""
23
[3312]24import sys
25import os
[3304]26import optparse
27from gettext import gettext as _
28
29from pykota import version
[3355]30from pykota.utils import loginvalidparam, getdefaultcharset
[3304]31
[3335]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)
[3413]38    else :
[3335]39        setattr(optionparser.values, option.dest, value)
[3413]40
41def checkandset_savetoner(option, opt, value, optionparser) :
[3335]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)
[3413]47    else :
[3335]48        setattr(optionparser.values, option.dest, value)
[3413]49
50def checkandset_positiveint(option, opt, value, optionparser) :
[3337]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)
[3413]56    else :
[3337]57        setattr(optionparser.values, option.dest, value)
[3413]58
59def checkandset_positivefloat(option, opt, value, optionparser) :
[3387]60    """Checks if an option argument is a positive float and validates the option if it is the case."""
[3337]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)
[3413]65    else :
[3337]66        setattr(optionparser.values, option.dest, value)
[3335]67
[3413]68def checkandset_percent(option, opt, value, optionparser) :
[3341]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)
[3413]74    else :
[3341]75        setattr(optionparser.values, option.dest, value)
76
[3413]77def load_arguments_file(option, opt, value, optionparser) :
[3387]78    """Loads arguments from a file, one per line."""
[3355]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]
[3413]91        arguments.reverse()
[3355]92        for arg in arguments :
[3413]93            optionparser.rargs.insert(0, arg)
[3355]94
[3304]95class PyKotaOptionParser(optparse.OptionParser) :
96    """
97    This class to define additional methods, and different help
98    formatting, from the traditional OptionParser.
[3413]99    """
[3304]100    def __init__(self, *args, **kwargs) :
101        """
102        Initializes our option parser with additional attributes.
103        """
[3339]104        self.filterexpressions = []
[3304]105        self.examples = []
[3316]106        kwargs["version"] = "%s (PyKota) %s" % (os.path.basename(sys.argv[0]),
107                                                version.__version__)
[3304]108        optparse.OptionParser.__init__(self, *args, **kwargs)
109        self.disable_interspersed_args()
[3316]110        self.remove_version_and_help()
[3315]111        self.add_generic_options()
[3413]112
[3304]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")
[3339]122        result.append(self.format_filterexpressions())
[3314]123        result.append(self.format_examples())
124        result.append(self.format_copyright())
[3304]125        return "".join(result)
[3413]126
[3314]127    #
[3413]128    # Below are PyKota specific additions
129    #
[3339]130    def format_filterexpressions(self, formatter=None) :
131        """Formats filter expressions our way."""
132        if formatter is None :
133            formatter = self.formatter
[3413]134        result = []
[3339]135        if self.filterexpressions :
136            result.append(formatter.format_heading(_("filtering expressions")))
137            formatter.indent()
[3340]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.")))
[3339]139            result.append("\n")
140            result.append(formatter.format_heading(_("allowed keys for now")))
[3413]141            formatter.indent()
[3339]142            for (expression, explanation) in self.filterexpressions :
143                result.append(formatter.format_description("%s : %s" % (expression, explanation)))
[3413]144            formatter.dedent()
[3339]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)")))
[3413]158            formatter.dedent()
[3339]159            result.append("\n")
[3340]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")
[3339]162        return "".join(result)
[3413]163
[3304]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()
[3413]176        return "".join(result)
177
[3304]178    def format_copyright(self, formatter=None) :
179        """Formats copyright message our way."""
180        if formatter is None :
181            formatter = self.formatter
[3413]182        result = []
[3304]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")
[3413]190        formatter.dedent()
[3304]191        return "".join(result)
[3413]192
193    def add_filterexpression(self, expression, doc) :
[3339]194        """Adds a filtering expression."""
195        self.filterexpressions.append((expression, doc))
[3413]196
197    def add_example(self, command, doc) :
[3304]198        """Adds an usage example."""
199        self.examples.append(("%prog " + command, doc))
[3413]200
201    def remove_version_and_help(self) :
[3316]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)
[3413]206            except ValueError :
[3316]207                pass
[3413]208
209    def add_generic_options(self) :
[3315]210        """Adds options which are common to all PyKota command line tools."""
[3316]211        self.add_option("-h", "--help",
212                              action="help",
[3369]213                              help=_("show this help message and exit."))
[3315]214        self.add_option("-v", "--version",
[3316]215                              action="version",
[3369]216                              help=_("show the version number and exit."))
[3355]217        self.add_option("-A", "--arguments",
218                              action="callback",
219                              type="string",
220                              dest="argumentsfile",
221                              callback=load_arguments_file,
[3359]222                              help=_("loads additional options and arguments from a file, one per line."))
Note: See TracBrowser for help on using the browser.