root / pykota / trunk / bin / pykosd @ 3488

Revision 3481, 8.5 kB (checked in by jerome, 16 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:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: utf-8 -*-*-
3#
4# PyKota : Print Quotas for CUPS
5#
6# (c) 2003-2009 Jerome Alet <alet@librelogiciel.com>
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19#
20# $Id$
21#
22#
23
24"""An On Screen Display (OSD) monitor for PyKota's end users."""
25
26import sys
27import os
28import pwd
29import time
30
31try :
32    import pyosd
33except ImportError :
34    sys.stderr.write("Sorry ! You need both xosd and the Python OSD library (pyosd) for this software to work.\n")
35    sys.exit(-1)
36
37import pykota.appinit
38from pykota.utils import run, loginvalidparam
39from pykota.commandline import PyKotaOptionParser
40from pykota.errors import PyKotaToolError, PyKotaCommandLineError
41from pykota.tool import PyKotaTool
42
43class PyKOSD(PyKotaTool) :
44    """A class for an On Screen Display print quota monitor."""
45    def main(self, args, options) :
46        """Main function starts here."""
47        savecolor = options.color
48        loop = options.loop
49        username = pwd.getpwuid(os.getuid())[0]
50        while True :
51            color = savecolor
52            user = self.storage.getUserFromBackend(username) # don't use cache
53            if not user.Exists :
54                raise PyKotaCommandLineError, _("You %(username)s don't have a PyKota printing account. Please contact your administrator.") % locals()
55            if user.LimitBy == "quota" :
56                printers = self.storage.getMatchingPrinters("*")
57                upquotas = [ self.storage.getUserPQuotaFromBackend(user, p) for p in printers ] # don't use cache
58                nblines = len(upquotas)
59                display = pyosd.osd(font=options.font,
60                                    colour=color,
61                                    timeout=options.duration,
62                                    shadow=2,
63                                    lines=nblines)
64                for line in range(nblines) :
65                    upq = upquotas[line]
66                    if upq.HardLimit is None :
67                        if upq.SoftLimit is None :
68                            percent = "%i" % upq.PageCounter
69                        else :
70                            percent = "%i%%" % min((upq.PageCounter * 100) / upq.SoftLimit, 100)
71                    else :
72                        percent = "%i%%" % min((upq.PageCounter * 100) / upq.HardLimit, 100)
73                    printername = upq.Printer.Name
74                    msg = _("Pages used on %(printername)s : %(percent)s") % locals()
75                    display.display(msg.encode(self.charset, "replace"),
76                                    type=pyosd.TYPE_STRING,
77                                    line=line)
78            elif user.LimitBy == "balance" :
79                if user.AccountBalance <= self.config.getBalanceZero() :
80                    color = "#FF0000"
81                display = pyosd.osd(font=options.font,
82                                    colour=color,
83                                    timeout=options.duration,
84                                    shadow=2)
85                balance = user.AccountBalance
86                msg = _("PyKota Units left : %(balance).2f") % locals()
87                display.display(msg.encode(self.charset, "replace"),
88                                type=pyosd.TYPE_STRING)
89            elif user.LimitBy == "noprint" :
90                display = pyosd.osd(font=options.font,
91                                    colour="#FF0000",
92                                    timeout=options.duration,
93                                    shadow=2)
94                msg = _("Printing denied.")
95                display.display(msg.encode(self.charset, "replace"),
96                                type=pyosd.TYPE_STRING)
97            elif user.LimitBy == "noquota" :
98                display = pyosd.osd(font=options.font,
99                                    colour=savecolor,
100                                    timeout=options.duration,
101                                    shadow=2)
102                msg = _("Printing not limited.")
103                display.display(msg.encode(self.charset, "replace"),
104                                type=pyosd.TYPE_STRING)
105            elif user.LimitBy == "nochange" :
106                display = pyosd.osd(font=options.font,
107                                    colour=savecolor,
108                                    timeout=options.duration,
109                                    shadow=2)
110                msg = _("Printing not limited, no accounting.")
111                display.display(msg.encode(self.charset, "replace"),
112                                type=pyosd.TYPE_STRING)
113            else :
114                limitby = repr(user.LimitBy)
115                raise PyKotaToolError, "Incorrect limitation factor %(limitby)s for user %(username)s" % locals()
116
117            time.sleep(options.duration + 1)
118            if loop :
119                loop -= 1
120                if not loop :
121                    break
122            time.sleep(options.sleep)
123
124        return 0
125
126if __name__ == "__main__" :
127    def checkandset_positiveint(option, opt, value, optionparser) :
128        """Checks and sets positive integer values."""
129        if value < 0 :
130            loginvalidparam(opt, value, option.default)
131            setattr(optionparser.values, option.dest, option.default)
132        else :
133            setattr(optionparser.values, option.dest, value)
134
135    def checkandset_color(option, opt, value, optionparser) :
136        """Checks and sets the color value."""
137        if not value.startswith("#") :
138            value = "#%s" % value
139        try :
140            int(value[1:], 16)
141        except (ValueError, TypeError) :
142            error = True
143        else :
144            error = False
145        if (len(value) != 7) or error :
146            loginvalidparam(opt, value, option.default)
147            setattr(optionparser.values, option.dest, option.default)
148        else :
149            setattr(optionparser.values, option.dest, value)
150
151    parser = PyKotaOptionParser(description=_("An On Screen Display (OSD) monitor for PyKota's end users."))
152    parser.add_option("-c", "--color", "--colour",
153                            type="string",
154                            action="callback",
155                            callback=checkandset_color,
156                            dest="color",
157                            default="#00FF00",
158                            help=_("Set the color that will be used for display, as an hexadecimal triplet. For example #FF0000 is 100% red. The default is 100% green (%default)."))
159    parser.add_option("-d", "--duration",
160                            type="int",
161                            action="callback",
162                            callback=checkandset_positiveint,
163                            dest="duration",
164                            default=3,
165                            help=_("Set the time in seconds during which the message will be displayed. Defaults to %default seconds."))
166    parser.add_option("-f", "--font",
167                            dest="font",
168                            default=pyosd.default_font,
169                            help=_("Set the font to use. Defaults to %default."))
170    parser.add_option("-l", "--loop",
171                            type="int",
172                            action="callback",
173                            callback=checkandset_positiveint,
174                            dest="loop",
175                            default=0,
176                            help=_("Set the number of times the info will be displayed. Defaults to %default, which means loop forever."))
177    parser.add_option("-s", "--sleep",
178                            type="int",
179                            action="callback",
180                            callback=checkandset_positiveint,
181                            dest="sleep",
182                            default=180,
183                            help=_("Set the sleeping time in seconds between two refreshes. Defaults to %default seconds."))
184
185    parser.add_example('-s 60 --loop 5',
186                       _("This would tell pykosd to display the current user's status for 3 seconds (the default) every 60 seconds, and exit after 5 iterations."))
187
188    run(parser, PyKOSD)
Note: See TracBrowser for help on using the browser.