Index: pykota/trunk/bin/pknotify
===================================================================
--- pykota/trunk/bin/pknotify (revision 3413)
+++ pykota/trunk/bin/pknotify (revision 3441)
@@ -36,125 +36,11 @@
 
 import pykota.appinit
-from pykota.utils import *
-
-from pykota.errors import PyKotaToolError, PyKotaCommandLineError
+from pykota.utils import run
+from pykota.commandline import PyKotaOptionParser, \
+                               checkandset_positiveint
+from pykota.errors import PyKotaToolError, \
+                          PyKotaCommandLineError, \
+                          PyKotaTimeoutError
 from pykota.tool import Tool
-
-__doc__ = N_("""pknotify v%(__version__)s (c) %(__years__)s %(__author__)s
-
-Notifies or ask questions to end users who launched the PyKotIcon application.
-
-command line usage :
-
-  pknotify  [options]  [arguments]
-
-options :
-
-  -v | --version             Prints pknotify's version number then exits.
-  -h | --help                Prints this message then exits.
-
-  -d | --destination h[:p]   Sets the destination hostname and optional
-                             port onto which contact the remote PyKotIcon
-                             application. This option is mandatory.
-                             When not specified, the port defaults to 7654.
-
-  -a | --ask                 Tells pknotify to ask something to the end
-                             user. Then pknotify will output the result.
-
-  -C | --checkauth           When --ask is used and both an 'username' and a
-                             'password' are asked to the end user, then
-                             pknotify will try to authenticate the user
-                             through PAM. If authentified, this program
-                             will print "AUTH=YES", else "AUTH=NO".
-                             If a field is missing, "AUTH=IMPOSSIBLE" will
-                             be printed. If the user is authenticated, then
-                             "USERNAME=xxxx" will be printed as well.
-
-  -c | --confirm             Tells pknotify to ask for either a confirmation
-                             or abortion.
-
-  -D | --denyafter N         With --checkauth above, makes pknotify loop
-                             up to N times if the password is incorrect.
-                             After having reached the limit, "DENY" will
-                             be printed, which effectively rejects the job.
-                             The default value of N is 1, meaning the job
-                             is denied after the first unsuccessful try.
-
-  -N | --noremote action     If it's impossible to connect to the remote
-                             PyKotIcon machine, do this action instead.
-                             Allowed actions are 'CONTINUE' and 'CANCEL',
-                             which will respectively allow the processing
-                             of the print job to continue, or the job to
-                             be cancelled. The default value is CANCEL.
-
-  -n | --notify              Tells pknotify to send an informational message
-                             to the end user.
-
-  -q | --quit                Tells pknotify to send a message asking the
-                             PyKotIcon application to exit. This option can
-                             be combined with the other ones to make PyKotIcon
-                             exit after having sent the answer from the dialog.
-
-  -t | --timeout T           Tells pknotify to ignore the end user's answer if
-                             it comes past T seconds after the dialog box being
-                             opened. The default value is 0 seconds, which
-                             tells pknotify to wait indefinitely.
-                             Use this option to avoid having an user who
-                             leaved his computer stall a whole print queue.
-
-  You MUST specify either --ask, --confirm, --notify or --quit.
-
-  arguments :
-
-    -a | --ask : Several arguments are accepted, of the form
-                 "label:varname:defaultvalue". The result will
-                 be printed to stdout in the following format :
-                 VAR1NAME=VAR1VALUE
-                 VAR2NAME=VAR2VALUE
-                 ...
-                 If the dialog was cancelled, nothing will be
-                 printed. If one of the varname is 'password'
-                 then this field is asked as a password (you won't
-                 see what you type in), and is NOT printed. Although
-                 it is not printed, it will be used to check if
-                 authentication is valid if you specify --checkauth.
-
-    -c | --confirm : A single argument is expected, representing the
-                     message to display. If the dialog is confirmed
-                     then pknotify will print OK, else CANCEL.
-
-    -n | --notify : A single argument is expected, representing the
-                    message to display. In this case pknotify will
-                    always print OK.
-
-examples :
-
-  pknotify -d client:7654 --noremote CONTINUE --confirm "This job costs 10 credits"
-
-  Would display the cost of the print job and asks for confirmation.
-  If the end user doesn't have PyKotIcon running and accepting connections
-  from the print server, PyKota will consider that the end user accepted
-  to print this job.
-
-  pknotify --destination $PYKOTAJOBORIGINATINGHOSTNAME:7654 \\
-           --checkauth --ask "Your name:username:" "Your password:password:"
-
-  Asks an username and password, and checks if they are valid.
-  NB : The PYKOTAJOBORIGINATINGHOSTNAME environment variable is
-  only set if you launch pknotify from cupspykota through a directive
-  in ~pykota/pykota.conf
-
-  The TCP port you'll use must be reachable on the client from the
-  print server.
-""")
-
-class TimeoutError(Exception) :
-    """An exception for timeouts."""
-    def __init__(self, message = ""):
-        self.message = message
-        Exception.__init__(self, message)
-    def __repr__(self):
-        return self.message
-    __str__ = __repr__
 
 class PyKotaNotify(Tool) :
@@ -216,5 +102,5 @@
     def alarmHandler(self, signum, frame) :
         """Alarm handler."""
-        raise TimeoutError, _("The end user at %s:%i didn't answer within %i seconds. The print job will be cancelled.") % (self.destination, self.port, self.timeout)
+        raise PyKotaTimeoutError, _("The end user at %s:%i didn't answer within %i seconds. The print job will be cancelled.") % (self.destination, self.port, self.timeout)
 
     def main(self, arguments, options) :
@@ -313,5 +199,5 @@
                 #        raise PyKotaToolError, "%s : %s" % (str(msg), (_("Are you sure that PyKotIcon is running and accepting incoming connections on %s:%s ?") % (self.destination, self.port)))
                 self.printInfo("%s : %s" % (_("Connection error"), str(msg)), "warn")
-            except TimeoutError, msg :
+            except PyKotaTimeoutError, msg :
                 self.printInfo(msg, "warn")
                 print "CANCEL"      # Timeout occured : job is cancelled.
@@ -321,6 +207,98 @@
 
 if __name__ == "__main__" :
-    retcode = 0
-    try :
+    sys.stderr.write("The pknotify command line tool is currently broken in this development tree. Please use a stable release instead.\n")
+    sys.exit(-1)
+    parser = PyKotaOptionParser(description=_("Notifies end users who have launched the PyKotIcon client side graphical desktop helper."),
+                                usage="pknotify [options] [arguments]")
+    parser.add_option("-a", "--ask",
+                            action="store_const",
+                            const="ask",
+                            dest="action",
+                            help=_("Ask something to the remote user, then print the result."))
+    parser.add_option("-c", "--confirm",
+                            action="store_const",
+                            const="confirm",
+                            dest="action",
+                            help=_("Ask the remote user to confirm or abort, then print the result."))
+    parser.add_option("-C", "--checkauth",
+                            dest="checkauth",
+                            help=_("When --ask is used, if both an username and password are asked to the end user, pknotify tries to authenticate these username and password through PAM. If this is successful, both 'AUTH=YES' and 'USERNAME=theusername' are printed. If unsuccessful, 'AUTH=NO' is printed. Finally, if one field is missing, 'AUTH=IMPOSSIBLE' is printed."))
+    parser.add_option("-D", "--denyafter",
+                            type="int",
+                            action="callback",
+                            callback=checkandset_positiveint,
+                            default=1,
+                            dest="denyafter",
+                            help=_("When --checkauth is used, this option tell pknotify to loop up to this value times or until the password is correct for the returned username. If authentication was impossible with the username and password received from the remote user, 'DENY' is printed, rejecting the print job. The default value is %default, meaning pknotify asks a single time."))
+    parser.add_option("-d", "--destination",
+                            dest="destination",
+                            help=_("Indicate the mandatory remote hostname or IP address and optional TCP port where PyKotIcon is listening for incoming connections from pknotify. If not specified, the port defaults to 7654."))
+    parser.add_option("-n", "--notify",
+                            action="store_const",
+                            const="notify",
+                            dest="action",
+                            help=_("Send an informational message to the remote user."))
+    parser.add_option("-N", "--noremote",
+                            dest="noremote",
+                            default="CANCEL",
+                            help=_("Tell pknotify what to print if it can't connect to a remote PyKotIcon application. The default value is 'CANCEL', which tells PyKota to cancel the print job. The only other supported value is 'CONTINUE', which tells PyKota to continue the processing of the current job."))
+    parser.add_option("-q", "--quit",
+                            dest="quit",
+                            help=_("Ask the remote PyKotIcon application to quit. When combined with other command line options, any other action is performed first."))
+    parser.add_option("-t", "--timeout",
+                            type="int",
+                            action="callback",
+                            callback=checkandset_positiveint,
+                            default=0,
+                            dest="timeout",
+                            help=_("Ensure that pknotify won't wait more than timeout seconds for an answer from the remote user. This avoids end users stalling a print queue because they don't answer in time. The default value is %default, making pknotify wait indefinitely."))
+    run(parser, PyKotaNotify)
+
+"""
+  arguments :
+
+    -a | --ask : Several arguments are accepted, of the form
+                 "label:varname:defaultvalue". The result will
+                 be printed to stdout in the following format :
+                 VAR1NAME=VAR1VALUE
+                 VAR2NAME=VAR2VALUE
+                 ...
+                 If the dialog was cancelled, nothing will be
+                 printed. If one of the varname is 'password'
+                 then this field is asked as a password (you won't
+                 see what you type in), and is NOT printed. Although
+                 it is not printed, it will be used to check if
+                 authentication is valid if you specify --checkauth.
+
+    -c | --confirm : A single argument is expected, representing the
+                     message to display. If the dialog is confirmed
+                     then pknotify will print OK, else CANCEL.
+
+    -n | --notify : A single argument is expected, representing the
+                    message to display. In this case pknotify will
+                    always print OK.
+
+examples :
+
+  pknotify -d client:7654 --noremote CONTINUE --confirm "This job costs 10 credits"
+
+  Would display the cost of the print job and asks for confirmation.
+  If the end user doesn't have PyKotIcon running and accepting connections
+  from the print server, PyKota will consider that the end user accepted
+  to print this job.
+
+  pknotify --destination $PYKOTAJOBORIGINATINGHOSTNAME:7654 \\
+           --checkauth --ask "Your name:username:" "Your password:password:"
+
+  Asks an username and password, and checks if they are valid.
+  NB : The PYKOTAJOBORIGINATINGHOSTNAME environment variable is
+  only set if you launch pknotify from cupspykota through a directive
+  in ~pykota/pykota.conf
+
+  The TCP port you'll use must be reachable on the client from the
+  print server.
+"""
+
+"""
         defaults = { \
                      "timeout" : 0,
@@ -332,28 +310,4 @@
                         "quit", "noremote=" ]
 
-        # Initializes the command line tool
-        notifier = PyKotaNotify(doc=__doc__)
-        notifier.deferredInit()
-
-        # parse and checks the command line
-        (options, args) = notifier.parseCommandline(sys.argv[1:], short_options, long_options)
-
-        # sets long options
-        options["help"] = options["h"] or options["help"]
-        options["version"] = options["v"] or options["version"]
-        options["destination"] = options["d"] or options["destination"]
-        options["ask"] = options["a"] or options["ask"]
-        options["confirm"] = options["c"] or options["confirm"]
-        options["notify"] = options["n"] or options["notify"]
-        options["quit"] = options["q"] or options["quit"]
-        options["checkauth"] = options["C"] or options["checkauth"]
-        options["denyafter"] = options["D"] or options["denyafter"]
-        options["timeout"] = options["t"] or options["timeout"] or defaults["timeout"]
-        options["noremote"] = (options["N"] or options["noremote"] or defaults["noremote"]).upper()
-
-        if options["help"] :
-            notifier.display_usage_and_quit()
-        elif options["version"] :
-            notifier.display_version_and_quit()
         elif (options["ask"] and (options["confirm"] or options["notify"])) \
              or (options["confirm"] and (options["ask"] or options["notify"])) \
@@ -368,21 +322,3 @@
         elif (not args) and (not options["quit"]) :
             raise PyKotaCommandLineError, _("some options require arguments, see help.")
-        else :
-            retcode = notifier.main(args, options)
-    except KeyboardInterrupt :
-        logerr("\nInterrupted with Ctrl+C !\n")
-        retcode = -3
-    except PyKotaCommandLineError, msg :
-        logerr("%s : %s\n" % (sys.argv[0], msg))
-        print "CANCEL"  # Forces the cancellation of the print job if a command line switch is incorrect
-        retcode = -2
-    except SystemExit :
-        pass
-    except :
-        try :
-            notifier.crashed("%s failed" % sys.argv[0])
-        except :
-            crashed("%s failed" % sys.argv[0])
-        retcode = -1
-
-    sys.exit(retcode)
+"""
