Index: pykota/trunk/conf/pykota.conf.sample
===================================================================
--- pykota/trunk/conf/pykota.conf.sample (revision 1027)
+++ pykota/trunk/conf/pykota.conf.sample (revision 1029)
@@ -55,14 +55,18 @@
 # Here we define some helpers to know where 
 # to plug into an existing LDAP directory
-#usersou: ou=People,dc=librelogiciel,dc=com
+#userbase: ou=People,dc=librelogiciel,dc=com
 #userrdn: uid
-#groupsou: ou=Groups,dc=librelogiciel,dc=com
+#groupbase: ou=Groups,dc=librelogiciel,dc=com
 #grouprdn: cn
-#printersou: ou=Printers,dc=librelogiciel,dc=com
+#printerbase: ou=Printers,ou=PyKota,dc=librelogiciel,dc=com
 #printerrdn: cn
-#jobsou: ou=Jobs,ou=PyKota,dc=librelogiciel,dc=com
-#userquotasou: ou=UQuotas,ou=PyKota,dc=librelogiciel,dc=com
-#groupquotasou: ou=GQuotas,ou=PyKota,dc=librelogiciel,dc=com
-#lastjobsou: ou=LastJobs,ou=PyKota,dc=librelogiciel,dc=com
+#jobbase: ou=Jobs,ou=PyKota,dc=librelogiciel,dc=com
+#userquotabase: ou=UQuotas,ou=PyKota,dc=librelogiciel,dc=com
+#groupquotabase: ou=GQuotas,ou=PyKota,dc=librelogiciel,dc=com
+#lastjobbase: ou=LastJobs,ou=PyKota,dc=librelogiciel,dc=com
+# 
+# Choose what attribute contains the list of group members
+# common values are : memberUid, uniqueMember, member
+#groupmembers: memberUid
 
 # Where to log ?
Index: pykota/trunk/pykota/storages/ldapstorage.py
===================================================================
--- pykota/trunk/pykota/storages/ldapstorage.py (revision 1027)
+++ pykota/trunk/pykota/storages/ldapstorage.py (revision 1029)
@@ -21,4 +21,7 @@
 #
 # $Log$
+# Revision 1.7  2003/06/14 22:44:21  jalet
+# More work on LDAP storage backend.
+#
 # Revision 1.6  2003/06/13 19:07:57  jalet
 # Two big bugs fixed, time to release something ;-)
@@ -67,7 +70,8 @@
         """Opens the LDAP connection."""
         # raise PyKotaStorageError, "Sorry, the LDAP backend for PyKota is not yet implemented !"
+        self.closed = 1
         self.tool = pykotatool
         self.debug = pykotatool.config.getDebug()
-        self.closed = 1
+        self.info = pykotatool.config.getLDAPInfo()
         try :
             self.database = ldap.initialize(host) 
@@ -103,5 +107,5 @@
     def getMatchingPrinters(self, printerpattern) :
         """Returns the list of all printers as tuples (id, name) for printer names which match a certain pattern."""
-        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName"])
+        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName"], base=self.info["printerbase"])
         if result :
             return [(printerid, printer["pykotaPrinterName"][0]) for (printerid, printer) in result if fnmatch.fnmatchcase(printer["pykotaPrinterName"][0], printerpattern)]
@@ -109,5 +113,5 @@
     def getPrinterId(self, printername) :        
         """Returns a printerid given a printername."""
-        result = self.doSearch("(&(objectClass=pykotaPrinter)(|(pykotaPrinterName=%s)(cn=%s)))" % (printername, printername), ["pykotaPrinterName"])
+        result = self.doSearch("(&(objectClass=pykotaPrinter)(|(pykotaPrinterName=%s)(%s=%s)))" % (printername, self.info["printerrdn"], printername), ["pykotaPrinterName"], base=self.info["printerbase"])
         if result :
             return result[0][0]
@@ -115,5 +119,5 @@
     def getPrinterPrices(self, printerid) :        
         """Returns a printer prices per page and per job given a printerid."""
-        result = self.doSearch("(|(pykotaPrinterName=*)(cn=*))", ["pykotaPricePerPage", "pykotaPricePerJob"], base=printerid, scope=ldap.SCOPE_BASE)
+        result = self.doSearch("(|(pykotaPrinterName=*)(%s=*))" % self.info["printerrdn"], ["pykotaPricePerPage", "pykotaPricePerJob"], base=printerid, scope=ldap.SCOPE_BASE)
         if result :
             return (float(result[0][1]["pykotaPricePerPage"][0]), float(result[0][1]["pykotaPricePerJob"][0]))
@@ -125,5 +129,5 @@
     def getUserId(self, username) :
         """Returns a userid given a username."""
-        result = self.doSearch("(&(objectClass=pykotaAccount)(|(pykotaUserName=%s)(uid=%s)))" % (username, username), ["uid"])
+        result = self.doSearch("(&(objectClass=pykotaAccount)(|(pykotaUserName=%s)(%s=%s)))" % (username, self.info["userrdn"], username), [self.info["userrdn"]], base=self.info["userbase"])
         if result :
             return result[0][0]
@@ -131,5 +135,5 @@
     def getGroupId(self, groupname) :
         """Returns a groupid given a grupname."""
-        result = self.doSearch("(&(objectClass=pykotaGroup)(|(pykotaGroupName=%s)(cn=%s)))" % (groupname, groupname), ["cn"])
+        result = self.doSearch("(&(objectClass=pykotaGroup)(|(pykotaGroupName=%s)(%s=%s)))" % (groupname, self.info["grouprdn"], groupname), [self.info["grouprdn"]], base=self.info["groupbase"])
         if result is not None :
             (groupid, dummy) = result[0]
@@ -146,9 +150,9 @@
         """Returns the list of userids and usernames which uses a given printer."""
         # first get the printer's name from the id
-        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName", "cn"], base=printerid, scope=ldap.SCOPE_BASE)
-        if result :
-            fields = result[0][1]
-            printername = (fields.get("pykotaPrinterName") or fields.get("cn"))[0]
-            result = self.doSearch("(&(objectClass=pykotaUserPQuota)(pykotaPrinterName=%s))" % printername, ["pykotaUserName"]) 
+        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName", self.info["printerrdn"]], base=printerid, scope=ldap.SCOPE_BASE)
+        if result :
+            fields = result[0][1]
+            printername = (fields.get("pykotaPrinterName") or fields.get(self.info["printerrdn"]))[0]
+            result = self.doSearch("(&(objectClass=pykotaUserPQuota)(pykotaPrinterName=%s))" % printername, ["pykotaUserName"], base=self.info["userquotabase"]) 
             if result :
                 return [(pquotauserid, fields["pykotaUserName"][0]) for (pquotauserid, fields) in result]
@@ -157,9 +161,9 @@
         """Returns the list of groups which uses a given printer."""
         # first get the printer's name from the id
-        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName", "cn"], base=printerid, scope=ldap.SCOPE_BASE)
-        if result :
-            fields = result[0][1]
-            printername = (fields.get("pykotaPrinterName") or fields.get("cn"))[0]
-            result = self.doSearch("(&(objectClass=pykotaGroupPQuota)(pykotaPrinterName=%s))" % printername, ["pykotaGroupName"]) 
+        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName", self.info["printerrdn"]], base=printerid, scope=ldap.SCOPE_BASE)
+        if result :
+            fields = result[0][1]
+            printername = (fields.get("pykotaPrinterName") or fields.get(self.info["printerrdn"]))[0]
+            result = self.doSearch("(&(objectClass=pykotaGroupPQuota)(pykotaPrinterName=%s))" % printername, ["pykotaGroupName"], base=self.info["groupquotabase"]) 
             if result :
                 return [(pquotagroupid, fields["pykotaGroupName"][0]) for (pquotagroupid, fields) in result]
@@ -167,8 +171,8 @@
     def getGroupMembersNames(self, groupname) :        
         """Returns the list of user's names which are member of this group."""
-        result = self.doSearch("(&(objectClass=pykotaGroup)(|(pykotaGroupName=%s)(cn=%s)))" % (groupname, groupname), ["memberUid", "uniqueMember", "member"])
-        if result :
-            fields = result[0][1]
-            return fields.get("memberUid") or fields.get("uniqueMember") or fields.get("member")
+        result = self.doSearch("(&(objectClass=pykotaGroup)(|(pykotaGroupName=%s)(%s=%s)))" % (groupname, self.info["grouprdn"], groupname), [self.info["groupmembers"]])
+        if result :
+            fields = result[0][1]
+            return fields.get(self.info["groupmembers"])
         
     def getUserGroupsNames(self, userid) :        
@@ -206,5 +210,5 @@
         if result :
             username = result[0][1]["pykotaUserName"][0]
-            result = self.doSearch("(&(objectClass=pykotaAccountBalance)(|(pykotaUserName=%s)(uid=%s)))" % (username, username), ["pykotaBalance", "pykotaLifeTimePaid"])
+            result = self.doSearch("(&(objectClass=pykotaAccountBalance)(|(pykotaUserName=%s)(%s=%s)))" % (username, self.info["userrdn"], username), ["pykotaBalance", "pykotaLifeTimePaid"])
             if result :
                 fields = result[0][1]
@@ -214,9 +218,9 @@
         """Returns the current account balance for a given user id."""
         # first get the user's name from the user id
-        result = self.doSearch("objectClass=pykotaAccount", ["pykotaUserName", "uid"], base=userid, scope=ldap.SCOPE_BASE)
-        if result :
-            fields = result[0][1]
-            username = (fields.get("pykotaUserName") or fields.get("uid"))[0]
-            result = self.doSearch("(&(objectClass=pykotaAccountBalance)(|(pykotaUserName=%s)(uid=%s)))" % (username, username), ["pykotaBalance", "pykotaLifeTimePaid"])
+        result = self.doSearch("objectClass=pykotaAccount", ["pykotaUserName", self.info["userrdn"]], base=userid, scope=ldap.SCOPE_BASE)
+        if result :
+            fields = result[0][1]
+            username = (fields.get("pykotaUserName") or fields.get(self.info["userrdn"]))[0]
+            result = self.doSearch("(&(objectClass=pykotaAccountBalance)(|(pykotaUserName=%s)(%s=%s)))" % (username, self.info["userrdn"], username), ["pykotaBalance", "pykotaLifeTimePaid"])
             if result :
                 fields = result[0][1]
@@ -241,9 +245,12 @@
             return (balance, lifetimepaid)            
         
-    def getUserLimitBy(self, userid) :    
+    def getUserLimitBy(self, userquotaid) :    
         """Returns the way in which user printing is limited."""
-        result = self.doSearch("objectClass=pykotaAccount", ["pykotaLimitBy"], base=userid, scope=ldap.SCOPE_BASE)
-        if result :
-            return result[0][1]["pykotaLimitBy"][0]
+        result = self.doSearch("objectClass=pykotaUserPQuota", ["pykotaUserName"], base=userquotaid, scope=ldap.SCOPE_BASE)
+        if result :
+            username = result[0][1]["pykotaUserName"][0]
+            result = self.doSearch("(&(objectClass=pykotaAccount)(|(pykotaUserName=%s)(%s=%s)))" % (username, self.info["userrdn"], username), ["pykotaLimitBy"])
+            if result :
+                return result[0][1]["pykotaLimitBy"][0]
         
     def getGroupLimitBy(self, groupquotaid) :    
@@ -253,5 +260,5 @@
         if result :
             groupname = result[0][1]["pykotaGroupName"][0]
-            result = self.doSearch("(&(objectClass=pykotaGroup)(pykotaGroupName=%s))" % groupname, ["pykotaLimitBy"])
+            result = self.doSearch("(&(objectClass=pykotaGroup)(|(pykotaGroupName=%s)(%s=%s)))" % (groupname, self.info["grouprdn"], groupname), ["pykotaLimitBy"])
             if result :
                 return result[0][1]["pykotaLimitBy"][0]
@@ -350,14 +357,20 @@
     def getPrinterPageCounter(self, printerid) :
         """Returns the last page counter value for a printer given its id, also returns last username, last jobid and history line id."""
-        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName", "cn"], base=printerid, scope=ldap.SCOPE_BASE)
-        if result :
-            fields = result[0][1]
-            printername = (fields.get("pykotaPrinterName") or fields.get("cn"))[0]
-            result = self.doSearch("(&(objectClass=pykotaLastjob)(|(pykotaPrinterName=%s)(cn=%s)))" % (printername, printername), ["pykotaLastJobIdent"])
+        result = self.doSearch("objectClass=pykotaPrinter", ["pykotaPrinterName", self.info["printerrdn"]], base=printerid, scope=ldap.SCOPE_BASE)
+        if result :
+            fields = result[0][1]
+            printername = (fields.get("pykotaPrinterName") or fields.get(self.info["printerrdn"]))[0]
+            result = self.doSearch("(&(objectClass=pykotaLastjob)(|(pykotaPrinterName=%s)(%s=%s)))" % (printername, self.info["printerrdn"], printername), ["pykotaLastJobIdent"], base=self.info["lastjobbase"])
             if result :
                 lastjobident = result[0][1]["pykotaLastJobIdent"][0]
-                result = self.doSearch("(&(objectClass=pykotaJob)(cn=%s))" % lastjobident, ["pykotaUserName", "pykotaPrinterName", "pykotaJobId", "pykotaPrinterPageCounter", "pykotaJobSize", "pykotaAction", "createTimestamp"])
+                result = self.doSearch("(&(objectClass=pykotaJob)(cn=%s))" % lastjobident, ["pykotaUserName", "pykotaPrinterName", "pykotaJobId", "pykotaPrinterPageCounter", "pykotaJobSize", "pykotaAction", "createTimestamp"], base=self.info["jobbase"])
                 if result :
-                    pass # TODO
+                    fields = result[0][1]
+                    return { "id": lastjobident, 
+                             "jobid" : fields.get("pykotaJobId")[0],
+                             "userid" : self.getUserId(fields.get("pykotaUserName")[0]),
+                             "username" : fields.get("pykotaUserName")[0], 
+                             "pagecounter" : int(fields.get("pykotaPrinterPageCounter")[0]),
+                           }
         
     def addUserToGroup(self, userid, groupid) :    
Index: pykota/trunk/pykota/config.py
===================================================================
--- pykota/trunk/pykota/config.py (revision 1021)
+++ pykota/trunk/pykota/config.py (revision 1029)
@@ -21,4 +21,7 @@
 #
 # $Log$
+# Revision 1.29  2003/06/14 22:44:21  jalet
+# More work on LDAP storage backend.
+#
 # Revision 1.28  2003/06/10 16:37:54  jalet
 # Deletion of the second user which is not needed anymore.
@@ -194,4 +197,16 @@
         return backendinfo
         
+    def getLDAPInfo(self) :    
+        """Returns some hints for the LDAP backend."""        
+        ldapinfo = {}
+        for option in [ "userbase", "userrdn", \
+                        "groupbase", "grouprdn", "groupmembers", \
+                        "printerbase", "printerrdn", \
+                        "userquotabase", "groupquotabase", \
+                        "jobbase", "lastjobbase", \
+                      ] :
+            ldapinfo[option] = self.getGlobalOption(option)
+        return ldapinfo
+        
     def getLoggingBackend(self) :    
         """Returns the logging backend information."""
Index: pykota/trunk/pykota/version.py
===================================================================
--- pykota/trunk/pykota/version.py (revision 1027)
+++ pykota/trunk/pykota/version.py (revision 1029)
@@ -21,5 +21,5 @@
 #
 
-__version__ = "1.08_unofficial"
+__version__ = "1.09alpha1_unofficial"
 
 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""
Index: pykota/trunk/NEWS
===================================================================
--- pykota/trunk/NEWS (revision 1028)
+++ pykota/trunk/NEWS (revision 1029)
@@ -22,7 +22,14 @@
 PyKota NEWS :
 
+    - 1.09alpha1 :
+    
+        - More work on LDAP storage backend. Many options
+          were added to /etc/pykota.conf to give some
+          hints to the LDAP storage backend.
+      
     - 1.08 :
     
         - Major bug fix wrt LPRng support for remote jobs.
+        
         - Major bug fix wrt increase/decrease account balances.
         
@@ -30,8 +37,10 @@
     
         - Code refactoring.
+        
         - A single user/password pair is used to connect
           to the database backend. The storageuser configuration
           field, and its associated passwords storageuserpw, are 
           not used anymore.
+          
         - You can now set PyKota in debug mode, see sample configuration  
           file for details. 
@@ -42,4 +51,5 @@
     
         - Very latest LDAP schema.
+        
         - Code enhancement wrt easy pluggability of PyKota attributes
           and object classes into an existing LDAP directory.
@@ -48,4 +58,5 @@
     
         - Minor bug corrections
+        
         - More work on LDAP : new schema
         
