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

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

Added some code to close the database if needed.

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