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

Revision 3367, 6.4 kB (checked in by jerome, 16 years ago)

Moved new method around.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[3260]1# -*- coding: UTF-8 -*-
[695]2#
[3260]3# PyKota : Print Quotas for CUPS
[695]4#
[3275]5# (c) 2003, 2004, 2005, 2006, 2007, 2008 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.
[3260]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.
15#
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()
43    except locale.Error :   
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"
[3298]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"
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", \
62                                        languages=["%s.%s" % (lang, 
63                                                              cset)], 
64                                        codeset=cset)
65        except TypeError : # Python <2.4
66            trans = gettext.translation("pykota", 
67                                        languages=["%s.%s" % (lang, 
68                                                              cset)])
69        trans.install(unicode=True)
70    except :
71        gettext.NullTranslations().install(unicode=True)
[3295]72       
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("-", "_")
78   
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
[3295]85def reinitcgilocale() :       
86    """Reinitializes the locale and gettext translations for CGI scripts, according to browser's preferences."""
87    initgettext(*initlocale(getpreferredlanguage(), getpreferredcharset()))
88   
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.
95   
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")
102        else :   
103            # MySQL already returns unicode objects
104            return text
[3294]105    else : 
106        return None
107   
108def unicodeToDatabase(text) :
109    """Converts from unicode to database format (UTF-8)."""
110    if text is not None : 
[3298]111        return text.encode("UTF-8")
[3294]112    else :   
113        return None
114           
[3354]115def getdefaultcharset() :           
116    """Returns the default charset to use."""
117    return sys.stdout.encoding or locale.getlocale()[1] or "ANSI_X3.4-1968"
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()
[3318]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.
127    """   
[3354]128    message = _("Invalid value '%(value)s' for the %(opt)s command line option") \
[3318]129                                % locals()
[3354]130    if defaultvalue is not None :                           
131        message += ", using default '%(defaultvalue)s' instead" % locals()
[3318]132    if additionalinfo :
133        logerr("%s (%s)\n" % (message, additionalinfo))
134    else :   
135        logerr("%s\n" % message)
[3294]136           
[3295]137def crashed(message="Bug in PyKota") :   
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
[3318]148   
149def run(optparser, workclass, requireargs=False) :
150    """Runs a PyKota command line tool."""
151    appname = os.path.basename(sys.argv[0])
152    retcode = 0
153    (options, arguments) = optparser.parse_args()                   
154    if requireargs and not arguments :
155        logerr("%s\n" % (_("%(appname)s requires arguments, please use --help") \
156                            % locals()))
157        retcode = -1
[3321]158    application = None   
[3318]159    try :
160        try :
[3321]161            application = workclass()
162            application.deferredInit()
163            retcode = application.main(arguments, options)
164        except KeyboardInterrupt :       
165            logerr("\nInterrupted with Ctrl+C !\n")
166            retcode = -3
167        except PyKotaCommandLineError, msg :   
168            logerr("%s : %s\n" % (sys.argv[0], msg))
169            retcode = -2
170        except SystemExit :       
171            pass
172        except :
173            title = _("%(appname)s failed") % locals()
174            try :
175                application.crashed(title)
176            except :   
177                crashed(title)
178            retcode = -1
179    finally :   
180        try :
181            application.storage.close()
[3318]182        except :   
[3321]183            pass
184           
[3318]185    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.