#!/usr/bin/python
# -*- coding: ISO-8859-15 -*-

# PyKota Print Quota Editor 
#
# PyKota - Print Quotas for CUPS and LPRng
#
# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
# $Id: pykosd,v 1.10 2004/10/11 22:53:05 jalet Exp $
#
# $Log: pykosd,v $
# Revision 1.10  2004/10/11 22:53:05  jalet
# Postponed string interpolation to help message's output method
#
# Revision 1.9  2004/10/11 12:49:06  jalet
# Renders help translatable
#
# Revision 1.8  2004/10/06 10:05:47  jalet
# Minor changes to allow any PyKota administrator to launch enhanced versions
# of the commands, and not only the root user.
#
# Revision 1.7  2004/07/20 22:42:26  jalet
# pykosd now supports setting color
#
# Revision 1.6  2004/07/20 22:29:49  jalet
# pykosd now supports setting the font
#
# Revision 1.5  2004/07/20 22:19:45  jalet
# Sanitized a bit + use of gettext
#
# Revision 1.4  2004/07/19 22:37:13  jalet
# pykosd is now a very good tool
#
# Revision 1.3  2004/07/07 21:44:15  jalet
# Formatting improvements
#
# Revision 1.2  2004/07/07 14:14:31  jalet
# Now handles limits by quota in addition to limits by balance
#
# Revision 1.1  2004/07/07 13:21:27  jalet
# Introduction of the pykosd command
#
#
#

import sys
import os
import pwd
import time

try :
    import pyosd
except ImportError :    
    sys.stderr.write("Sorry ! You need both xosd and the Python OSD library (pyosd) for this software to work.\n")
    sys.exit(-1)

from pykota.tool import PyKotaTool, PyKotaToolError, crashed, N_

__doc__ = N_("""pykosd v%s (c) 2003-2004 C@LL - Conseil Internet & Logiciels Libres
An OSD quota monitor for PyKota.

command line usage :

  pykosd [options]

options :

  -v | --version       Prints pkprinters's version number then exits.
  -h | --help          Prints this message then exits.
  
  -c | --color #rrggbb Sets the color to use for display as an hexadecimal
                       triplet, for example #FF0000 is 100%% red.
                       Defaults to 100%% green (#00FF00).
                       
  -d | --duration d    Sets the duration of the display in seconds. 
                       Defaults to 3 seconds.
                       
  -f | --font f        Sets the font to use for display.                      
                       Defaults to the Python OSD library's default.
  
  -l | --loop n        Sets the number of times the info will be displayed.
                       Defaults to 0, which means loop forever.
                       
  -s | --sleep s       Sets the sleeping duration between two displays 
                       in seconds. Defaults to 180 seconds (3 minutes).
                       
  
examples :                              

  $ pykosd -s 60 --loop 5
  
  Will launch pykosd. Display will be refreshed every 60 seconds,
  and will last for 3 seconds (the default) each time. After five
  iterations, the program will exit.
  
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

Please e-mail bugs to: %s""")


class PyKOSD(PyKotaTool) :
    def main(self, args, options) :
        """Main function starts here."""
        try :    
            duration = int(options["duration"])
        except :    
            raise PyKotaToolError, _("Invalid duration option %s") % str(options["duration"])
            
        try :    
            loop = int(options["loop"])
        except :    
            raise PyKotaToolError, _("Invalid loop option %s") % str(options["loop"])
            
        try :    
            sleep = float(options["sleep"])
        except :    
            raise PyKotaToolError, _("Invalid sleep option %s") % str(options["sleep"])
            
        color = options["color"]    
        if not color.startswith("#") :
            color = "#%s" % color
        if len(color) != 7 :    
            raise PyKotaToolError, _("Invalid color option %s") % str(color)
        savecolor = color
        
        uname = pwd.getpwuid(os.geteuid())[0]
        while 1 :
            color = savecolor
            user = cmd.storage.getUserFromBackend(uname)        # don't use cache
            if not user.Exists :
                raise PyKotaToolError, _("User %s doesn't exist in PyKota's database") % uname
            if user.LimitBy == "quota" :    
                printers = cmd.storage.getMatchingPrinters("*")
                upquotas = [ cmd.storage.getUserPQuotaFromBackend(user, p) for p in printers ] # don't use cache
                nblines = len(upquotas)
                display = pyosd.osd(font=options["font"], colour=color, timeout=duration, shadow=2, lines=nblines)
                for line in range(nblines) :
                    upq = upquotas[line]
                    if upq.HardLimit is None :
                        if upq.SoftLimit is None :
                            percent = "%s" % upq.PageCounter
                        else :        
                            percent = "%s%%" % min((upq.PageCounter * 100) / upq.SoftLimit, 100)
                    else :        
                        percent = "%s%%" % min((upq.PageCounter * 100) / upq.HardLimit, 100)
                    display.display(_("Pages used on %s : %s") % (upq.Printer.Name, percent), type=pyosd.TYPE_STRING, line=line)
            else :
                if user.AccountBalance <= 0 :
                    color = "#FF0000"
                display = pyosd.osd(font=options["font"], colour=color, timeout=duration, shadow=2)
                display.display(_("PyKota Units left : %.2f") % user.AccountBalance, type=pyosd.TYPE_STRING)
                
            time.sleep(duration + 1)
            if loop :
                loop -= 1
                if not loop :
                    break
            time.sleep(sleep)        
            
        return 0    
        
if __name__ == "__main__" :
    retcode = -1
    try :
        defaults = { \
                     "color" : "#00FF00", \
                     "duration" : "3", \
                     "font" : pyosd.default_font, \
                     "loop" : "0", \
                     "sleep" : "180", \
                   }
        short_options = "hvc:d:f:l:s:"
        long_options = ["help", "version", "color=", "colour=", "duration=", "font=", "loop=", "sleep="]
        
        cmd = PyKOSD(doc=__doc__)
        
        # parse and checks the command line
        (options, args) = cmd.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
        
        # sets long options
        options["help"] = options["h"] or options["help"]
        options["version"] = options["v"] or options["version"]
        options["color"] = options["c"] or options["color"] or options["colour"] or defaults["color"]
        options["duration"] = options["d"] or options["duration"] or defaults["duration"]
        options["font"] = options["f"] or options["font"] or defaults["font"]
        options["loop"] = options["l"] or options["loop"] or defaults["loop"]
        options["sleep"] = options["s"] or options["sleep"] or defaults["sleep"]
        
        if options["help"] :
            cmd.display_usage_and_quit()
        elif options["version"] :
            cmd.display_version_and_quit()
        else :    
            retcode = cmd.main(args, options)
    except KeyboardInterrupt :
        retcode = 0
    except SystemExit :        
        pass
    except :    
        try :
            cmd.crashed("pykosd failed")
        except :    
            crashed("pykosd failed")
        
    try :
        cmd.storage.close()
    except :    
        pass
        
    sys.exit(retcode)
