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
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 module defines some utility functions which make no sense as methods."""
23
24import sys
25import os
26import pwd
27import locale
28import gettext
29from types import UnicodeType
30
31from pykota.errors import PyKotaCommandLineError
32
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
46    if (not charset) or charset in ("ASCII", "ANSI_X3.4-1968") :
47        charset = "UTF-8"
48
49    return (language, charset)
50
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
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)
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]
84
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
93def databaseToUnicode(text) :
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    """
99    if text is not None :
100        if not isinstance(text, UnicodeType) :
101            return text.decode("UTF-8", "replace")
102        else :
103            # MySQL already returns unicode objects
104            return text
105    else :
106        return None
107
108def unicodeToDatabase(text) :
109    """Converts from unicode to database format (UTF-8)."""
110    if text is not None :
111        return text.encode("UTF-8")
112    else :
113        return None
114
115def getdefaultcharset() :
116    """Returns the default charset to use."""
117    return sys.stdout.encoding or locale.getlocale()[1] or "ANSI_X3.4-1968"
118
119def logerr(text) :
120    """Logs an unicode text to stderr."""
121    sys.stderr.write(text.encode(getdefaultcharset(), "replace"))
122    sys.stderr.flush()
123
124def loginvalidparam(opt, value, defaultvalue=None, additionalinfo=None) :
125    """Logs an error when an invalid parameter to a command line option
126       is encountered.
127    """
128    message = _("Invalid value '%(value)s' for the %(opt)s command line option") \
129                                % locals()
130    if defaultvalue is not None :
131        message += ", using default '%(defaultvalue)s' instead" % locals()
132    if additionalinfo :
133        logerr("%s (%s)\n" % (message, additionalinfo))
134    else :
135        logerr("%s\n" % message)
136
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()) :
143        line = line.decode(getdefaultcharset(), "replace")
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
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
158    application = None
159    try :
160        try :
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()
182        except :
183            pass
184
185    sys.exit(retcode)
Note: See TracBrowser for help on using the browser.