Index: pykota/branches/1.26_fixes/bin/pkturnkey
===================================================================
--- pykota/branches/1.26_fixes/bin/pkturnkey (revision 3133)
+++ pykota/branches/1.26_fixes/bin/pkturnkey (revision 3416)
@@ -16,5 +16,5 @@
 # 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
@@ -32,4 +32,6 @@
 import signal
 
+from pkipplib import pkipplib
+
 from pykota.tool import Tool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
 
@@ -50,17 +52,17 @@
   -v | --version       Prints pkturnkey version number then exits.
   -h | --help          Prints this message then exits.
-  
+
   -c | --doconf        Give hints about what to put into pykota.conf
-  
+
   -d | --dousers       Manages users accounts as well.
-  
+
   -D | --dogroups      Manages users groups as well.
                        Implies -d | --dousers.
-  
+
   -e | --emptygroups   Includes empty groups.
-  
+
   -f | --force         Modifies the database instead of printing what
                        it would do.
-                       
+
   -u | --uidmin uid    Only adds users whose uid is greater than or equal to
                        uid. You can pass an username there as well, and its
@@ -68,5 +70,5 @@
                        If not set, 0 will be used automatically.
                        Implies -d | --dousers.
-                       
+
   -U | --uidmax uid    Only adds users whose uid is lesser than or equal to
                        uid. You can pass an username there as well, and its
@@ -80,5 +82,5 @@
                        If not set, 0 will be used automatically.
                        Implies -D | --dogroups.
-                       
+
   -G | --gidmax gid    Only adds groups whose gid is lesser than or equal to
                        gid. You can pass a groupname there as well, and its
@@ -87,5 +89,5 @@
                        Implies -D | --dogroups.
 
-examples :                              
+examples :
 
   $ pkturnkey --dousers --uidmin jerome
@@ -94,12 +96,12 @@
   printers and print accounts for all users whose uid is greater than
   or equal to jerome's one. Won't manage any users group.
-  
+
   To REALLY initialize the database instead of simulating it, please
   use the -f | --force command line switch.
-  
+
   You can limit the initialization to only a subset of the existing
   printers, by passing their names at the end of the command line.
 """)
-        
+
 class PKTurnKey(Tool) :
     """A class for an initialization tool."""
@@ -107,23 +109,27 @@
         """Returns a list of tuples (queuename, deviceuri) for all existing print queues."""
         self.printInfo("Extracting all print queues.")
-        result = os.popen("lpstat -v", "r")
-        lines = result.readlines()
-        result.close()
         printers = []
-        for line in lines :
-            (begin, end) = line.split(':', 1)
-            deviceuri = end.strip()
-            queuename = begin.split()[-1]
-            if self.matchString(queuename, namestomatch) :
-                printers.append((queuename, deviceuri))
-            else :    
-                self.printInfo("Print queue %s skipped." % queuename)
-        return printers    
-        
-    def listUsers(self, uidmin, uidmax) :    
+        server = pkipplib.CUPS()
+        for queuename in server.getPrinters() :
+            req = server.newRequest(pkipplib.IPP_GET_PRINTER_ATTRIBUTES)
+            req.operation["printer-uri"] = ("uri", server.identifierToURI("printers", queuename))
+            req.operation["requested-attributes"] = ("keyword", "device-uri")
+            result = server.doRequest(req)
+            try :
+                deviceuri = result.printer["device-uri"][0][1]
+            except (AttributeError, IndexError) :
+                deviceuri = None
+            if deviceuri is not None :
+                if self.matchString(queuename, namestomatch) :
+                    printers.append((queuename, deviceuri))
+                else :
+                    self.printInfo("Print queue %s skipped." % queuename)
+        return printers
+
+    def listUsers(self, uidmin, uidmax) :
         """Returns a list of users whose uids are between uidmin and uidmax."""
         self.printInfo("Extracting all users whose uid is between %s and %s." % (uidmin, uidmax))
         return [(entry[0], entry[3]) for entry in pwd.getpwall() if uidmin <= entry[2] <= uidmax]
-        
+
     def listGroups(self, gidmin, gidmax, users) :
         """Returns a list of groups whose gids are between gidmin and gidmax."""
@@ -134,7 +140,7 @@
         for u in users :
             gidusers.setdefault(u[1], []).append(u[0])
-            usersgid.setdefault(u[0], []).append(u[1]) 
-            
-        membership = {}    
+            usersgid.setdefault(u[0], []).append(u[1])
+
+        membership = {}
         for g in range(len(groups)) :
             (gname, gid, members) = groups[g]
@@ -144,23 +150,23 @@
             try :
                 usernames = gidusers[gid]
-            except KeyError :    
+            except KeyError :
                 pass
-            else :    
+            else :
                 for username in usernames :
                     if not newmembers.has_key(username) :
                         newmembers[username] = username
-            for member in newmembers.keys() :            
+            for member in newmembers.keys() :
                 if not usersgid.has_key(member) :
                     del newmembers[member]
             membership[gname] = newmembers.keys()
         return membership
-        
-    def runCommand(self, command, dryrun) :    
+
+    def runCommand(self, command, dryrun) :
         """Launches an external command."""
         self.printInfo("%s" % command)
-        if not dryrun :    
+        if not dryrun :
             os.system(command)
-            
-    def createPrinters(self, printers, dryrun=0) :    
+
+    def createPrinters(self, printers, dryrun=0) :
         """Creates all printers in PyKota's database."""
         if printers :
@@ -170,5 +176,5 @@
             args.close()
             self.runCommand("pkprinters --arguments /tmp/pkprinters.args", dryrun)
-        
+
     def createUsers(self, users, printers, dryrun=0) :
         """Creates all users in PyKota's database."""
@@ -179,5 +185,5 @@
             args.close()
             self.runCommand("pkusers --arguments /tmp/pkusers.users.args", dryrun)
-            
+
             printersnames = [p[0] for p in printers]
             args = open("/tmp/edpykota.users.args", "w")
@@ -187,5 +193,5 @@
             args.close()
             self.runCommand("edpykota --arguments /tmp/edpykota.users.args", dryrun)
-            
+
     def createGroups(self, groups, printers, dryrun=0) :
         """Creates all groups in PyKota's database."""
@@ -196,5 +202,5 @@
             args.close()
             self.runCommand("pkusers --arguments /tmp/pkusers.groups.args", dryrun)
-            
+
             printersnames = [p[0] for p in printers]
             args = open("/tmp/edpykota.groups.args", "w")
@@ -204,16 +210,16 @@
             args.close()
             self.runCommand("edpykota --arguments /tmp/edpykota.groups.args", dryrun)
-            
+
             revmembership = {}
             for (groupname, usernames) in groups.items() :
                 for username in usernames :
                     revmembership.setdefault(username, []).append(groupname)
-            commands = []        
-            for (username, groupnames) in revmembership.items() :        
+            commands = []
+            for (username, groupnames) in revmembership.items() :
                 commands.append('pkusers --ingroups %s "%s"' \
                     % (",".join(['"%s"' % g for g in groupnames]), username))
             for command in commands :
                 self.runCommand(command, dryrun)
-        
+
     def supportsSNMP(self, hostname, community) :
         """Returns 1 if the printer accepts SNMP queries, else 0."""
@@ -221,5 +227,5 @@
         try :
             from pysnmp.entity.rfc3413.oneliner import cmdgen
-        except ImportError :    
+        except ImportError :
             hasV4 = False
             try :
@@ -227,11 +233,11 @@
                 from pysnmp.mapping.udp.role import Manager
                 from pysnmp.proto.api import alpha
-            except ImportError :    
+            except ImportError :
                 sys.stderr.write("pysnmp doesn't seem to be installed. SNMP checks will be ignored !\n")
                 return 0
-        else :        
+        else :
             hasV4 = True
-            
-        if hasV4 :    
+
+        if hasV4 :
             def retrieveSNMPValues(hostname, community) :
                 """Retrieves a printer's internal page counter and status via SNMP."""
@@ -240,12 +246,12 @@
                                                       cmdgen.UdpTransportTarget((hostname, 161)), \
                                                       tuple([int(i) for i in pageCounterOID.split('.')]))
-                if errorIndication :                                                  
+                if errorIndication :
                     raise "No SNMP !"
-                elif errorStatus :    
+                elif errorStatus :
                     raise "No SNMP !"
-                else :                                 
+                else :
                     self.SNMPOK = True
         else :
-            def retrieveSNMPValues(hostname, community) :    
+            def retrieveSNMPValues(hostname, community) :
                 """Retrieves a printer's internal page counter and status via SNMP."""
                 ver = alpha.protoVersions[alpha.protoVersionId1]
@@ -259,8 +265,8 @@
                                        (hostname, 161), \
                                        (handleAnswer, req))
-                except :    
+                except :
                     raise "No SNMP !"
                 tsp.close()
-            
+
             def handleAnswer(wholemsg, notusedhere, req):
                 """Decodes and handles the SNMP answer."""
@@ -269,5 +275,5 @@
                 try :
                     rsp.berDecode(wholemsg)
-                except TypeMismatchError, msg :    
+                except TypeMismatchError, msg :
                     raise "No SNMP !"
                 else :
@@ -280,24 +286,24 @@
                             for varBind in rsp.apiAlphaGetPdu().apiAlphaGetVarBindList():
                                 self.values.append(varBind.apiAlphaGetOidVal()[1].rawAsn1Value)
-                            try :    
+                            try :
                                 pagecounter = self.values[0]
                             except :
                                 raise "No SNMP !"
-                            else :    
+                            else :
                                 self.SNMPOK = 1
                                 return 1
-            
+
         self.SNMPOK = 0
         try :
             retrieveSNMPValues(hostname, community)
-        except :    
+        except :
             self.SNMPOK = 0
         return self.SNMPOK
-        
+
     def supportsPJL(self, hostname, port) :
         """Returns 1 if the printer accepts PJL queries over TCP, else 0."""
         def alarmHandler(signum, frame) :
             raise "Timeout !"
-        
+
         pjlsupport = 0
         signal.signal(signal.SIGALRM, alarmHandler)
@@ -310,7 +316,7 @@
             if not answer.startswith("@PJL") :
                 raise "No PJL !"
-        except :    
+        except :
             pass
-        else :    
+        else :
             pjlsupport = 1
         s.close()
@@ -318,11 +324,11 @@
         signal.signal(signal.SIGALRM, signal.SIG_IGN)
         return pjlsupport
-            
-    def hintConfig(self, printers) :    
+
+    def hintConfig(self, printers) :
         """Gives some hints about what to put into pykota.conf"""
         if not printers :
             return
-        sys.stderr.flush() # ensure outputs don't mix    
-        print     
+        sys.stderr.flush() # ensure outputs don't mix
+        print
         print "--- CUT ---"
         print "# Here are some lines that we suggest you add at the end"
@@ -337,19 +343,19 @@
             try :
                 uri = uri.split("cupspykota:", 2)[-1]
-            except (ValueError, IndexError) :    
+            except (ValueError, IndexError) :
                 pass
-            else :    
+            else :
                 while uri and uri.startswith("/") :
                     uri = uri[1:]
                 try :
-                    (backend, destination) = uri.split(":", 1) 
+                    (backend, destination) = uri.split(":", 1)
                     if backend not in ("ipp", "http", "https", "lpd", "socket") :
                         raise ValueError
-                except ValueError :    
+                except ValueError :
                     pass
-                else :        
+                else :
                     while destination.startswith("/") :
                         destination = destination[1:]
-                    checkauth = destination.split("@", 1)    
+                    checkauth = destination.split("@", 1)
                     if len(checkauth) == 2 :
                         destination = checkauth[1]
@@ -361,7 +367,7 @@
                         except ValueError :
                             port = 9100
-                    else :    
+                    else :
                         (hostname, port) = parts[0], 9100
-                        
+
                     if self.supportsSNMP(hostname, "public") :
                         accounter = "hardware(snmp)"
@@ -370,12 +376,12 @@
                     elif self.supportsPJL(hostname, 9101) :
                         accounter = "hardware(pjl:9101)"
-                    elif self.supportsPJL(hostname, port) :    
+                    elif self.supportsPJL(hostname, port) :
                         accounter = "hardware(pjl:%s)" % port
-                    
-            print "preaccounter : software()" 
+
+            print "preaccounter : software()"
             print "accounter : %s" % accounter
             print
         print "--- CUT ---"
-        
+
     def main(self, names, options) :
         """Intializes PyKota's database."""
@@ -383,74 +389,74 @@
             raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], \
                                    _("You're not allowed to use this command."))
-            
+
         if not names :
             names = ["*"]
-            
+
         self.printInfo(_("Please be patient..."))
         dryrun = not options["force"]
         if dryrun :
             self.printInfo(_("Don't worry, the database WILL NOT BE MODIFIED."))
-        else :    
+        else :
             self.printInfo(_("Please WORRY NOW, the database WILL BE MODIFIED."))
-            
-        if options["dousers"] :    
-            if not options["uidmin"] :    
+
+        if options["dousers"] :
+            if not options["uidmin"] :
                 self.printInfo(_("System users will have a print account as well !"), "warn")
                 uidmin = 0
-            else :    
+            else :
                 try :
                     uidmin = int(options["uidmin"])
-                except :    
+                except :
                     try :
                         uidmin = pwd.getpwnam(options["uidmin"])[2]
-                    except KeyError, msg :    
+                    except KeyError, msg :
                         raise PyKotaCommandLineError, _("Unknown username %s : %s") \
                                                    % (options["uidmin"], msg)
-                        
-            if not options["uidmax"] :    
+
+            if not options["uidmax"] :
                 uidmax = sys.maxint
-            else :    
+            else :
                 try :
                     uidmax = int(options["uidmax"])
-                except :    
+                except :
                     try :
                         uidmax = pwd.getpwnam(options["uidmax"])[2]
-                    except KeyError, msg :    
+                    except KeyError, msg :
                         raise PyKotaCommandLineError, _("Unknown username %s : %s") \
                                                    % (options["uidmax"], msg)
-            
-            if uidmin > uidmax :            
+
+            if uidmin > uidmax :
                 (uidmin, uidmax) = (uidmax, uidmin)
             users = self.listUsers(uidmin, uidmax)
-        else :    
+        else :
             users = []
-            
-        if options["dogroups"] :    
-            if not options["gidmin"] :    
+
+        if options["dogroups"] :
+            if not options["gidmin"] :
                 self.printInfo(_("System groups will have a print account as well !"), "warn")
                 gidmin = 0
-            else :    
+            else :
                 try :
                     gidmin = int(options["gidmin"])
-                except :    
+                except :
                     try :
                         gidmin = grp.getgrnam(options["gidmin"])[2]
-                    except KeyError, msg :    
+                    except KeyError, msg :
                         raise PyKotaCommandLineError, _("Unknown groupname %s : %s") \
                                                    % (options["gidmin"], msg)
-                        
-            if not options["gidmax"] :    
+
+            if not options["gidmax"] :
                 gidmax = sys.maxint
-            else :    
+            else :
                 try :
                     gidmax = int(options["gidmax"])
-                except :    
+                except :
                     try :
                         gidmax = grp.getgrnam(options["gidmax"])[2]
-                    except KeyError, msg :    
+                    except KeyError, msg :
                         raise PyKotaCommandLineError, _("Unknown groupname %s : %s") \
                                                    % (options["gidmax"], msg)
-            
-            if gidmin > gidmax :            
+
+            if gidmin > gidmax :
                 (gidmin, gidmax) = (gidmax, gidmin)
             groups = self.listGroups(gidmin, gidmax, users)
@@ -459,7 +465,7 @@
                     if not members :
                         del groups[groupname]
-        else :    
+        else :
             groups = []
-            
+
         printers = self.listPrinters(names)
         if printers :
@@ -467,15 +473,15 @@
             self.createUsers([entry[0] for entry in users], printers, dryrun)
             self.createGroups(groups, printers, dryrun)
-        
+
         if dryrun :
             self.printInfo(_("Simulation terminated."))
-        else :    
+        else :
             self.printInfo(_("Database initialized !"))
-       
-        if options["doconf"] :    
+
+        if options["doconf"] :
             self.hintConfig(printers)
-                    
-                     
-if __name__ == "__main__" : 
+
+
+if __name__ == "__main__" :
     retcode = 0
     try :
@@ -484,9 +490,9 @@
                         "emptygroups", "force", "uidmin=", "uidmax=", \
                         "gidmin=", "gidmax=", "doconf"]
-        
+
         # Initializes the command line tool
         manager = PKTurnKey(doc=__doc__)
         manager.deferredInit()
-        
+
         # parse and checks the command line
         (options, args) = manager.parseCommandline(sys.argv[1:], \
@@ -494,5 +500,5 @@
                                                    long_options, \
                                                    allownothing=1)
-        
+
         # sets long options
         options["help"] = options["h"] or options["help"]
@@ -507,20 +513,20 @@
         options["gidmax"] = options["G"] or options["gidmax"]
         options["doconf"] = options["c"] or options["doconf"]
-        
+
         if options["uidmin"] or options["uidmax"] :
             if not options["dousers"] :
                 manager.printInfo(_("The --uidmin or --uidmax command line option implies --dousers as well."), "warn")
-            options["dousers"] = 1    
-            
+            options["dousers"] = 1
+
         if options["gidmin"] or options["gidmax"] :
             if not options["dogroups"] :
                 manager.printInfo(_("The --gidmin or --gidmax command line option implies --dogroups as well."), "warn")
             options["dogroups"] = 1
-        
+
         if options["dogroups"] :
             if not options["dousers"] :
                 manager.printInfo(_("The --dogroups command line option implies --dousers as well."), "warn")
-            options["dousers"] = 1    
-            
+            options["dousers"] = 1
+
         if options["help"] :
             manager.display_usage_and_quit()
@@ -529,16 +535,16 @@
         else :
             retcode = manager.main(args, options)
-    except KeyboardInterrupt :        
+    except KeyboardInterrupt :
         sys.stderr.write("\nInterrupted with Ctrl+C !\n")
         retcode = -3
-    except PyKotaCommandLineError, msg :    
+    except PyKotaCommandLineError, msg :
         sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
         retcode = -2
-    except SystemExit :        
+    except SystemExit :
         pass
     except :
         try :
             manager.crashed("pkturnkey failed")
-        except :    
+        except :
             crashed("pkturnkey failed")
         retcode = -1
@@ -546,6 +552,6 @@
     try :
         manager.storage.close()
-    except (TypeError, NameError, AttributeError) :    
+    except (TypeError, NameError, AttributeError) :
         pass
-        
-    sys.exit(retcode)    
+
+    sys.exit(retcode)
