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

Revision 3366, 6.7 kB (checked in by jerome, 16 years ago)

Added a method to check if user is admin and fail if needed.

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