root / pykota / trunk / pykota / utils.py @ 3481

Revision 3481, 6.2 kB (checked in by jerome, 15 years ago)

Changed copyright years.
Copyright years are now dynamic when displayed by a command line tool.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[3411]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#
[3294]21
22"""This module defines some utility functions which make no sense as methods."""
23
24import sys
[3295]25import os
[3366]26import pwd
[3294]27import locale
28import gettext
[3310]29from types import UnicodeType
[3294]30
[3318]31from pykota.errors import PyKotaCommandLineError
32
[3294]33def initlocale(lang="", cset=None) :
34    """Initializes the locale stuff."""
35    try :
36        locale.setlocale(locale.LC_ALL, (lang, cset))
37    except (locale.Error, IOError) :
38        locale.setlocale(locale.LC_ALL, None)
39    (language, charset) = locale.getlocale()
40    language = language or "C"
41    try :
42        charset = charset or locale.getpreferredencoding()
[3413]43    except locale.Error :
[3294]44        charset = sys.stdout.encoding or sys.getfilesystemencoding()
45
[3298]46    if (not charset) or charset in ("ASCII", "ANSI_X3.4-1968") :
[3294]47        charset = "UTF-8"
[3413]48
[3294]49    return (language, charset)
50
[3298]51def setenv(varname, value, charset) :
52    """Sets an environment variable."""
53    if value is None :
54        value = "None"
[3413]55    os.environ[varname] = value.encode(charset, "replace")
56
[3294]57def initgettext(lang, cset) :
58    """Initializes gettext translations for PyKota."""
59    try :
60        try :
61            trans = gettext.translation("pykota", \
[3413]62                                        languages=["%s.%s" % (lang,
63                                                              cset)],
[3294]64                                        codeset=cset)
65        except TypeError : # Python <2.4
[3413]66            trans = gettext.translation("pykota",
67                                        languages=["%s.%s" % (lang,
[3294]68                                                              cset)])
69        trans.install(unicode=True)
70    except :
71        gettext.NullTranslations().install(unicode=True)
[3413]72
[3295]73def getpreferredlanguage() :
74    """Returns the preferred language."""
75    languages = os.environ.get("HTTP_ACCEPT_LANGUAGE", "")
76    langs = [l.strip().split(';')[0] for l in languages.split(",")]
77    return langs[0].replace("-", "_")
[3413]78
[3295]79def getpreferredcharset() :
80    """Returns the preferred charset."""
81    charsets = os.environ.get("HTTP_ACCEPT_CHARSET", "UTF-8")
82    charsets = [l.strip().split(';')[0] for l in charsets.split(",")]
83    return charsets[0]
[3294]84
[3413]85def reinitcgilocale() :
[3295]86    """Reinitializes the locale and gettext translations for CGI scripts, according to browser's preferences."""
87    initgettext(*initlocale(getpreferredlanguage(), getpreferredcharset()))
[3413]88
[3295]89def N_(message) :
90    """Fake translation marker for translatable strings extraction."""
91    return message
92
[3294]93def databaseToUnicode(text) :
[3298]94    """Converts from database format (UTF-8) to unicode.
[3413]95
[3298]96       We use "replace" to accomodate legacy datas which may not
97       have been recorded correctly.
98    """
[3294]99    if text is not None :
[3310]100        if not isinstance(text, UnicodeType) :
101            return text.decode("UTF-8", "replace")
[3413]102        else :
[3310]103            # MySQL already returns unicode objects
104            return text
[3413]105    else :
[3294]106        return None
[3413]107
[3294]108def unicodeToDatabase(text) :
109    """Converts from unicode to database format (UTF-8)."""
[3413]110    if text is not None :
[3298]111        return text.encode("UTF-8")
[3413]112    else :
[3294]113        return None
[3413]114
115def getdefaultcharset() :
[3354]116    """Returns the default charset to use."""
117    return sys.stdout.encoding or locale.getlocale()[1] or "ANSI_X3.4-1968"
[3413]118
[3294]119def logerr(text) :
120    """Logs an unicode text to stderr."""
[3354]121    sys.stderr.write(text.encode(getdefaultcharset(), "replace"))
[3295]122    sys.stderr.flush()
[3413]123
[3354]124def loginvalidparam(opt, value, defaultvalue=None, additionalinfo=None) :
[3318]125    """Logs an error when an invalid parameter to a command line option
126       is encountered.
[3413]127    """
[3354]128    message = _("Invalid value '%(value)s' for the %(opt)s command line option") \
[3318]129                                % locals()
[3413]130    if defaultvalue is not None :
[3354]131        message += ", using default '%(defaultvalue)s' instead" % locals()
[3318]132    if additionalinfo :
133        logerr("%s (%s)\n" % (message, additionalinfo))
[3413]134    else :
[3318]135        logerr("%s\n" % message)
[3413]136
137def crashed(message="Bug in PyKota") :
[3295]138    """Minimal crash method."""
139    import traceback
140    from pykota.version import __version__
141    lines = []
142    for line in traceback.format_exception(*sys.exc_info()) :
[3354]143        line = line.decode(getdefaultcharset(), "replace")
[3295]144        lines.extend([l for l in line.split("\n") if l])
145    msg = "ERROR: ".join(["%s\n" % l for l in (["ERROR: PyKota v%s" % __version__, message] + lines)])
146    logerr(msg)
147    return msg
[3413]148
[3318]149def run(optparser, workclass, requireargs=False) :
150    """Runs a PyKota command line tool."""
151    appname = os.path.basename(sys.argv[0])
152    retcode = 0
[3413]153    (options, arguments) = optparser.parse_args()
[3318]154    if requireargs and not arguments :
155        logerr("%s\n" % (_("%(appname)s requires arguments, please use --help") \
156                            % locals()))
157        retcode = -1
[3413]158    application = None
[3318]159    try :
160        try :
[3321]161            application = workclass()
162            application.deferredInit()
163            retcode = application.main(arguments, options)
[3413]164        except KeyboardInterrupt :
[3321]165            logerr("\nInterrupted with Ctrl+C !\n")
166            retcode = -3
[3413]167        except PyKotaCommandLineError, msg :
[3321]168            logerr("%s : %s\n" % (sys.argv[0], msg))
169            retcode = -2
[3413]170        except SystemExit :
[3321]171            pass
172        except :
173            title = _("%(appname)s failed") % locals()
174            try :
175                application.crashed(title)
[3413]176            except :
[3321]177                crashed(title)
178            retcode = -1
[3413]179    finally :
[3321]180        try :
181            application.storage.close()
[3413]182        except :
[3321]183            pass
[3413]184
185    sys.exit(retcode)
Note: See TracBrowser for help on using the browser.