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

# PyKota Print Quota Quote sender
#
# 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: pykotme,v 1.11 2004/06/07 18:43:40 jalet Exp $
#
# $Log: pykotme,v $
# Revision 1.11  2004/06/07 18:43:40  jalet
# Fixed over-verbose exits when displaying help or version number
#
# Revision 1.10  2004/06/03 21:50:34  jalet
# Improved error logging.
# crashrecipient directive added.
# Now exports the job's size in bytes too.
#
# Revision 1.9  2004/05/21 20:53:34  jalet
# Now pykotme doesn't spawn a new process anymore to compute job's size, but
# use the PDLAnalyzer class directly
#
# Revision 1.8  2004/05/10 07:23:21  jalet
# pykotme now uses pkpgcounter to compute the job's size.
#
# Revision 1.7  2004/01/12 22:43:40  jalet
# New formula to compute a job's price
#
# Revision 1.6  2004/01/08 14:10:32  jalet
# Copyright year changed.
#
# Revision 1.5  2003/10/09 21:25:25  jalet
# Multiple printer names or wildcards can be passed on the command line
# separated with commas.
# Beta phase.
#
# Revision 1.4  2003/10/07 09:07:27  jalet
# Character encoding added to please latest version of Python
#
# Revision 1.3  2003/07/29 20:55:17  jalet
# 1.14 is out !
#
# Revision 1.2  2003/07/25 10:41:29  jalet
# Better documentation.
# pykotme now displays the current user's account balance.
# Some test changed in ldap module.
#
# Revision 1.1  2003/07/03 09:44:01  jalet
# Now includes the pykotme utility
#
#
#

import sys
import os
import pwd

from pykota import version
from pykota.tool import PyKotaTool, PyKotaToolError
from pykota.config import PyKotaConfigError
from pykota.storage import PyKotaStorageError
from pykota.pdlanalyzer import PDLAnalyzer, PDLAnalyzerError

__doc__ = """pykotme v%s (c) 2003-2004 C@LL - Conseil Internet & Logiciels Libres

Gives print quotes to users.

command line usage :

  pykotme  [options]  [files]

options :

  -v | --version       Prints pykotme's version number then exits.
  -h | --help          Prints this message then exits.
  
  -P | --printer p     Gives a quote for this printer only. Actually p can
                       use wildcards characters to select only
                       some printers. The default value is *, meaning
                       all printers.
                       You can specify several names or wildcards, 
                       by separating them with commas.
  
examples :                              

  $ pykotme --printer apple file1.ps file2.ps
  
  This will give a print quote to the current user. The quote will show
  the price and size of a job consisting in file1.ps and file2.ps 
  which would be sent to the apple printer.
  
  $ pykotme --printer apple,hplaser <file1.ps
  
  This will give a print quote to the current user. The quote will show
  the price and size of a job consisting in file1.ps as read from
  standard input, which would be sent to the apple or hplaser
  printer.

  $ pykotme 
  
  This will give a quote for a job consisting of what is on standard 
  input. The quote will list the job size, and the price the job
  would cost on each printer.


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""" % (version.__version__, version.__author__)
        
        
class PyKotMe(PyKotaTool) :        
    """A class for pykotme."""
    def main(self, files, options) :
        """Gives print quotes."""
        if (not sys.stdin.isatty()) and ("-" not in files) :
            files.append("-")
        totalsize = 0    
        for filename in files :    
            try :
                parser = PDLAnalyzer(filename)
                totalsize += parser.getJobSize()
            except PDLAnalyzerError, msg :    
                sys.stderr.write("%s\n" % msg)
                sys.stderr.flush()
            
        # get current user
        uid = os.geteuid()
        username = pwd.getpwuid(uid)[0]
        user = self.storage.getUser(username)
        if user.Exists and user.LimitBy and (user.LimitBy.lower() == "balance"):
            print _("Your account balance : %.2f") % (user.AccountBalance or 0.0)
            
        printers = self.storage.getMatchingPrinters(options["printer"])
        if not printers :
            raise PyKotaToolError, _("There's no printer matching %s") % options["printer"]
            
        print _("Job size : %i pages") % totalsize    
        for printer in printers :
            userpquota = self.storage.getUserPQuota(user, printer)
            cost = userpquota.computeJobPrice(totalsize)
            print _("Cost on printer %s : %.2f") % (printer.Name, cost)
            
if __name__ == "__main__" : 
    retcode = 0
    try :
        defaults = { \
                     "printer" : "*", \
                   }
        short_options = "vhP:"
        long_options = ["help", "version", "printer="]
        
        # Initializes the command line tool
        sender = PyKotMe(doc=__doc__)
        
        # parse and checks the command line
        (options, args) = sender.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["printer"] = options["P"] or options["printer"] or defaults["printer"]
        
        if options["help"] :
            sender.display_usage_and_quit()
        elif options["version"] :
            sender.display_version_and_quit()
        else :
            retcode = sender.main(args, options)
    except SystemExit :        
        pass
    except :
        try :
            sender.crashed("pykotme failed")
        except :    
            pass
        retcode = -1

    try :
        sender.storage.close()
    except (TypeError, NameError, AttributeError) :    
        pass
        
    sys.exit(retcode)    
