Index: /pykota/trunk/setup.py
===================================================================
--- /pykota/trunk/setup.py (revision 997)
+++ /pykota/trunk/setup.py (revision 1018)
@@ -23,4 +23,7 @@
 #
 # $Log$
+# Revision 1.16  2003/06/06 20:49:15  jalet
+# Very latest schema. UNTESTED.
+#
 # Revision 1.15  2003/05/17 16:32:30  jalet
 # Also outputs the original import error message.
@@ -111,5 +114,5 @@
     return result
     
-def checkWithPrompt(prompt, module=None, command=None, help=None) :
+def checkWithPrompt(prompt, module=None, command=None, helper=None) :
     """Tells the user what will be checked, and asks him what to do if something is absent."""
     sys.stdout.write("Checking for %s availability : " % prompt)
@@ -125,6 +128,6 @@
         sys.stdout.write("NO.\n")
         sys.stderr.write("ERROR : %s not available !\n" % prompt)
-        if help is not None :
-            sys.stdout.write("%s\n" % help)
+        if helper is not None :
+            sys.stdout.write("%s\n" % helper)
             sys.stdout.write("You may continue safely if you don't need this functionnality.\n")
         answer = raw_input("%s is missing. Do you want to continue anyway (y/N) ? " % prompt)
@@ -190,8 +193,11 @@
     
     # checks if some needed Python modules are there or not.
-    modulestocheck = [("PygreSQL", "pg"), ("mxDateTime", "mx.DateTime")]
+    modulestocheck = [ ("PygreSQL", "pg", "PygreSQL is mandatory if you want to use PostgreSQL as the quota storage backend."),                                            
+                       ("mxDateTime", "mx.DateTime", "eGenix' mxDateTime is mandatory for PyKota to work."), 
+                       ("Python-LDAP", "ldap", "Python-LDAP is mandatory if you plan to use an LDAP\ndirectory as the quota storage backend.")
+                     ]
     commandstocheck = [("SNMP Tools", "snmpget", "SNMP Tools are needed if you want to use SNMP enabled printers."), ("Netatalk", "pap", "Netatalk is needed if you want to use AppleTalk enabled printers.")]
-    for (name, module) in modulestocheck :
-        action = checkWithPrompt(name, module=module)
+    for (name, module, helper) in modulestocheck :
+        action = checkWithPrompt(name, module=module, helper=helper)
         if action == ACTION_ABORT :
             sys.stderr.write("Aborted !\n")
@@ -199,6 +205,6 @@
             
     # checks if some software are there or not.
-    for (name, command, help) in commandstocheck :
-        action = checkWithPrompt(name, command=command, help=help)
+    for (name, command, helper) in commandstocheck :
+        action = checkWithPrompt(name, command=command, helper=helper)
         if action == ACTION_ABORT :
             sys.stderr.write("Aborted !\n")
Index: /pykota/trunk/CREDITS
===================================================================
--- /pykota/trunk/CREDITS (revision 1017)
+++ /pykota/trunk/CREDITS (revision 1018)
@@ -40,9 +40,9 @@
   The following people contributed code or ideas to PyKota :
   
-    - Jo�Collet : made the PyKota logo
+    - Jo�Collet : PyKota's logo
     - Stefan Wold - Stockholm University : code
     - John Flynn - University of Belize : LDAP support
     - Wayne Godoy - University of Belize : LDAP support
-    - Leif Johansson - LDAP support
+    - Leif Johansson - Stockholm University : LDAP support
 
 ============================================================
Index: /pykota/trunk/pykota/storages/ldapstorage.py
===================================================================
--- /pykota/trunk/pykota/storages/ldapstorage.py (revision 1017)
+++ /pykota/trunk/pykota/storages/ldapstorage.py (revision 1018)
@@ -21,4 +21,7 @@
 #
 # $Log$
+# Revision 1.3  2003/06/06 20:49:15  jalet
+# Very latest schema. UNTESTED.
+#
 # Revision 1.2  2003/06/06 14:21:08  jalet
 # New LDAP schema.
@@ -86,5 +89,5 @@
     def getPrinterId(self, printername) :        
         """Returns a printerid given a printername."""
-        result = self.doSearch("(&(objectClass=pykotaPrinter)(pykotaPrinterName=%s))" % printername, ["pykotaPrinterName"])
+        result = self.doSearch("(&(objectClass=pykotaPrinter)(|(pykotaPrinterName=%s)(cn=%s)))" % (printername, printername), ["pykotaPrinterName"])
         if result :
             return result[0][0]
@@ -92,5 +95,5 @@
     def getPrinterPrices(self, printerid) :        
         """Returns a printer prices per page and per job given a printerid."""
-        result = self.doSearch("pykotaPrinterName=*", ["pykotaPricePerPage", "pykotaPricePerJob"], base=printerid)
+        result = self.doSearch("(|(pykotaPrinterName=*)(cn=*))", ["pykotaPricePerPage", "pykotaPricePerJob"], base=printerid, scope=ldap.SCOPE_BASE)
         if result :
             return (float(result[0][1]["pykotaPricePerPage"][0]), float(result[0][1]["pykotaPricePerJob"][0]))
@@ -102,5 +105,5 @@
     def getUserId(self, username) :
         """Returns a userid given a username."""
-        result = self.doSearch("(&(objectClass=pykotaAccount)(pykotaUserName=%s))" % username, ["uid"])
+        result = self.doSearch("(&(objectClass=pykotaAccount)(|(pykotaUserName=%s)(uid=%s)))" % (username, username), ["uid"])
         if result :
             return result[0][0]
@@ -108,5 +111,5 @@
     def getGroupId(self, groupname) :
         """Returns a groupid given a grupname."""
-        result = self.doSearch("(&(objectClass=pykotaGroup)(pykotaGroupName=%s))" % groupname, ["cn"])
+        result = self.doSearch("(&(objectClass=pykotaGroup)(|(pykotaGroupName=%s)(cn=%s)))" % (groupname, groupname), ["cn"])
         if result is not None :
             (groupid, dummy) = result[0]
@@ -120,7 +123,8 @@
         """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"], base=printerid, scope=ldap.SCOPE_BASE)
-        if result :
-            printername = result[0][1]["pykotaPrinterName"][0]
+        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"]) 
             if result :
@@ -130,7 +134,8 @@
         """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"], base=printerid, scope=ldap.SCOPE_BASE)
-        if result :
-            printername = result[0][1]["pykotaPrinterName"][0]
+        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"]) 
             if result :
@@ -139,7 +144,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))" % groupname, ["memberUid"])
-        if result :
-            return result[0][1]["memberUid"]
+        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")
         
     def getUserGroupsNames(self, userid) :        
@@ -177,5 +183,5 @@
         if result :
             username = result[0][1]["pykotaUserName"][0]
-            result = self.doSearch("(&(objectClass=pykotaAccountBalance)(pykotaUserName=%s))" % username, ["pykotaBalance", "pykotaLifeTimePaid"])
+            result = self.doSearch("(&(objectClass=pykotaAccountBalance)(|(pykotaUserName=%s)(uid=%s)))" % (username, username), ["pykotaBalance", "pykotaLifeTimePaid"])
             if result :
                 fields = result[0][1]
@@ -185,8 +191,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"], base=userid, scope=ldap.SCOPE_BASE)
-        if result :
-            username = result[0][1]["pykotaUserName"][0]
-            result = self.doSearch("(&(objectClass=pykotaAccountBalance)(pykotaUserName=%s))" % username, ["pykotaBalance", "pykotaLifeTimePaid"])
+        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"])
             if result :
                 fields = result[0][1]
Index: /pykota/trunk/pykota/version.py
===================================================================
--- /pykota/trunk/pykota/version.py (revision 1017)
+++ /pykota/trunk/pykota/version.py (revision 1018)
@@ -21,5 +21,5 @@
 #
 
-__version__ = "1.08alpha6_unofficial"
+__version__ = "1.08alpha7_unofficial"
 
 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""
Index: /pykota/trunk/initscripts/ldap/pykota-sample.ldif
===================================================================
--- /pykota/trunk/initscripts/ldap/pykota-sample.ldif (revision 1017)
+++ /pykota/trunk/initscripts/ldap/pykota-sample.ldif (revision 1018)
@@ -72,5 +72,5 @@
 
 dn: cn=apple,ou=Printers,ou=PyKota,dc=librelogiciel,dc=com
-objectClass: pykotaNamed
+objectClass: pykotaObject
 objectClass: pykotaPrinter
 cn: apple
@@ -80,5 +80,5 @@
 
 dn: cn=uniqueidentifier01,ou=UQuotas,ou=PyKota,dc=librelogiciel,dc=com
-objectClass: pykotaNamed
+objectClass: pykotaObject
 objectClass: pykotaUserPQuota
 cn: uniqueidentifier01
@@ -92,5 +92,5 @@
 
 dn: cn=uniqueidentifier02,ou=GQuotas,ou=PyKota,dc=librelogiciel,dc=com
-objectClass: pykotaNamed
+objectClass: pykotaObject
 objectClass: pykotaGroupPQuota
 cn: uniqueidentifier02
@@ -102,5 +102,5 @@
 
 dn: cn=uniqueidentifier03,ou=Jobs,ou=PyKota,dc=librelogiciel,dc=com
-objectClass: pykotaNamed
+objectClass: pykotaObject
 objectClass: pykotaJob
 cn: uniqueidentifier03
@@ -113,7 +113,7 @@
 
 dn: cn=uniqueidentifier04,ou=LastJobs,ou=PyKota,dc=librelogiciel,dc=com
-objectClass: pykotaNamed
+objectClass: pykotaObject
 objectClass: pykotaLastJob
 cn: uniqueidentifier04
 pykotaPrinterName: apple
-pykotaLastJobUUID: uniqueidentifier03
+pykotaLastJobIdent: uniqueidentifier03
Index: /pykota/trunk/initscripts/ldap/pykota.schema
===================================================================
--- /pykota/trunk/initscripts/ldap/pykota.schema (revision 1017)
+++ /pykota/trunk/initscripts/ldap/pykota.schema (revision 1018)
@@ -110,6 +110,6 @@
 # pykotaAction
 attributetype ( 1.3.6.1.4.1.16868.1.1.14 NAME 'pykotaAction'
-        DESC 'Was the job allowed, or denied'
-        EQUALITY caseIgnoreIA5Match
+        DESC 'Was the job allowed, or denied : ( "ALLOW" |  "DENY" )'
+        EQUALITY caseExactIA5Match
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
         
@@ -132,7 +132,7 @@
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
         
-# pykotaLastJobUUID        
-attributetype ( 1.3.6.1.4.1.16868.1.1.18 NAME 'pykotaLastJobUUID'
-        DESC 'Last job uuid in the history'
+# pykotaLastJobIdent        
+attributetype ( 1.3.6.1.4.1.16868.1.1.18 NAME 'pykotaLastJobIdent'
+        DESC 'Identifies the last job in the history'
         EQUALITY caseExactIA5Match
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
@@ -145,18 +145,18 @@
 objectclass ( 1.3.6.1.4.1.16868.1.2.1 NAME 'pykotaAccount' SUP top AUXILIARY
         DESC 'PyKota Auxiliary User Account'
-        MUST ( uid $ pykotaUserName )
-        MAY  ( pykotaLimitBy ) )
+        MUST ( uid )
+        MAY  ( pykotaUserName $ pykotaLimitBy ) )
         
 # pykotaGroup        
 objectclass ( 1.3.6.1.4.1.16868.1.2.2 NAME 'pykotaGroup' SUP top AUXILIARY
         DESC 'PyKota Auxiliary Group'
-        MUST ( cn $ pykotaGroupName )
-        MAY  ( pykotaLimitBy $ memberUid ) )
+        MUST ( cn )
+        MAY  ( pykotaGroupName $ pykotaLimitBy $ memberUid $ uniqueMember $ member ) )
         
 # pykotaPrinter        
 objectclass ( 1.3.6.1.4.1.16868.1.2.3 NAME 'pykotaPrinter' SUP top AUXILIARY
         DESC 'PyKota Printer'
-        MUST ( cn $ pykotaPrinterName )
-        MAY  ( pykotaPricePerPage $ pykotaPricePerJob ) )
+        MUST ( cn )
+        MAY  ( pykotaPrinterName $ pykotaPricePerPage $ pykotaPricePerJob ) )
         
 # pykotaUserPQuota        
@@ -181,15 +181,15 @@
 objectclass ( 1.3.6.1.4.1.16868.1.2.7 NAME 'pykotaAccountBalance' SUP top AUXILIARY
         DESC 'PyKota User account balance'
-        MUST ( pykotaUserName )
-        MAY  ( pykotaBalance $ pykotaLifeTimePaid ) )
+        MAY  ( pykotaUserName $ pykotaBalance $ pykotaLifeTimePaid ) )
         
 # pykotaLastJob        
 objectclass ( 1.3.6.1.4.1.16868.1.2.8 NAME 'pykotaLastJob' SUP top AUXILIARY
         DESC 'Last job information for a printer'
-        MUST ( pykotaPrinterName $ pykotaLastJobUUID ) )
+        MUST ( pykotaLastJobIdent )
+        MAY ( pykotaPrinterName ) ) 
         
-# pykotaNamed - Use it if you have to 
-objectclass ( 1.3.6.1.4.1.16868.1.2.9 NAME 'pykotaNamed' SUP top STRUCTURAL
-        DESC 'PyKota Named Object'
+# pykotaObject - Use it if you have to 
+objectclass ( 1.3.6.1.4.1.16868.1.2.9 NAME 'pykotaObject' SUP top STRUCTURAL
+        DESC 'PyKota Object'
         MUST ( cn ) )
         
