Index: pykota/trunk/initscripts/ldap/pykota-sample.ldif
===================================================================
--- pykota/trunk/initscripts/ldap/pykota-sample.ldif (revision 1015)
+++ pykota/trunk/initscripts/ldap/pykota-sample.ldif (revision 1015)
@@ -0,0 +1,92 @@
+#
+# PyKota sample LDAP directory tree
+# 
+# $Id$
+#
+# 
+dn: ou=People,dc=librelogiciel,dc=com
+ou: People
+objectClass: organizationalUnit
+
+dn: ou=Groups,dc=librelogiciel,dc=com
+ou: Groups
+objectClass: organizationalUnit
+
+dn: ou=Printers,dc=librelogiciel,dc=com
+ou: Printers
+objectClass: organizationalUnit
+
+dn: uid=jerome,ou=People,dc=librelogiciel,dc=com
+uid: jerome
+cn:: SmVyb21lIEFsZXQ=
+objectClass: account
+objectClass: posixAccount
+objectClass: top
+objectClass: shadowAccount
+objectClass: pykotaUser
+userPassword: {crypt}PvuIT4Mz8.lCM
+shadowLastChange: 12093
+shadowMax: 99999
+shadowWarning: 7
+loginShell: /bin/bash
+uidNumber: 500
+gidNumber: 500
+homeDirectory: /home/jerome
+gecos: Jerome Alet,,,
+pykotaLimitBy: quota
+pykotaBalance: 0
+pykotaLifeTimePaid: 0
+
+dn: cn=devel,ou=Groups,dc=librelogiciel,dc=com
+objectClass: posixGroup
+objectClass: top
+objectClass: pykotaGroup
+cn: devel
+userPassword: {crypt}x
+gidNumber: 500
+memberUid: jerome
+pykotaLimitBy: quota
+
+dn: pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
+objectClass: pykotaPrinter
+pykotaPrinterName: apple
+pykotaPricePerPage: 0.1
+pykotaPricePerJob: 0.25
+
+dn: ou=userPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
+ou: userPQuotas
+objectClass: organizationalUnit
+
+dn: ou=groupPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
+ou: groupPQuotas
+objectClass: organizationalUnit
+
+dn: ou=Jobs,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
+ou: Jobs
+objectClass: organizationalUnit
+
+dn: uid=jerome,ou=userPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
+objectClass: pykotaUserPQuota
+uid: jerome
+pykotaPageCounter: 0
+pykotaLifePageCounter: 0
+pykotaSoftLimit: 100
+pykotaHardLimit: 110
+pykotaDateLimit: None
+
+dn: cn=devel,ou=groupPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
+objectClass: pykotaGroupPQuota
+cn: devel
+pykotaSoftLimit: 400
+pykotaHardLimit: 450
+pykotaDateLimit: None
+
+dn: pykotaJobHistoryId=1,ou=Jobs,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
+objectClass: pykotaPrinterJob
+pykotaJobHistoryId: 1
+pykotaJobId: 15
+uid: jerome
+pykotaPrinterPageCounter: 1533
+pykotaJobSize: 5
+pykotaAction: ALLOW
+pykotaJobDate: 2003-06-04 16:12
Index: pykota/trunk/initscripts/ldap/pykota.schema
===================================================================
--- pykota/trunk/initscripts/ldap/pykota.schema (revision 1015)
+++ pykota/trunk/initscripts/ldap/pykota.schema (revision 1015)
@@ -0,0 +1,149 @@
+# $Id$
+#
+# pykota.schema
+#
+# LDAP Schema for Pykota Quota System
+# Version 0.2
+#
+# Written 2003-05-28 by Wayne Godoy and John Flynn <wgodoy =AT= ub -DOT- edu -DOT- bz>
+#
+# Modified by Jerome Alet 2003-06-01
+#
+# 16868.x       => Conseil Internet & Logiciels Libres
+# 16868.1.x     => Pykota
+# 16868.1.1.x   => attributes
+# 16868.1.2.x   => classes
+#
+#
+# THIS IS WORK UNDER HEAVY DEVELOPPMENT !
+#
+# USE AT YOUR OWN RISK, AND ONLY IF YOU PERFECTLY KNOW
+# WHAT YOU ARE DOING.
+#
+# WHEN LDAP SUPPORT WILL BE FINALIZED, YOU'LL KNOW IT !
+#
+
+## Pykota related LDAP attributes
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.1 NAME 'pykotaLimitBy'
+        DESC 'How to limit the user/group : quota or balance'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.2 NAME 'pykotaBalance'
+        DESC 'Current account balance for the user, float'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.3 NAME 'pykotaLifeTimePaid'
+        DESC 'Total money paid by the user to fill his account balance, float'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.4 NAME 'pykotaPricePerPage'
+        DESC 'Price per page for a printer, float'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.5 NAME 'pykotaPricePerJob'
+        DESC 'Price per job for a printer, float'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.6 NAME 'pykotaPrinterName'
+        DESC 'Printer name as defined in the printing environment, e.g. lp'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.7 NAME 'pykotaSoftLimit'
+        DESC 'Soft limit in maximal number of pages'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+        
+attributetype ( 1.3.6.1.4.1.16868.1.1.8 NAME 'pykotaHardLimit'
+        DESC 'Hard limit in maximal number of pages'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.9 NAME 'pykotaDateLimit'
+        DESC 'Date at which the soft limit becomes a hard one'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.10 NAME 'pykotaPageCounter'
+        DESC 'Current page counter for the user on a particular printer'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.11 NAME 'pykotaLifePageCounter'
+        DESC 'Total page counter for the user on a particular printer'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.12 NAME 'pykotaJobHistoryId'
+        DESC 'Id of an entry in a printer history of jobs'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.13 NAME 'pykotaJobId'
+        DESC 'Id of a job in a printer history of jobs'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.14 NAME 'pykotaPrinterPageCounter'
+        DESC 'Life time page counter of a printer when the job began'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.15 NAME 'pykotaJobSize'
+        DESC 'Current job size in number of pages in the history'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.16868.1.1.16 NAME 'pykotaAction'
+        DESC 'Was the job allowed, or denied'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+        
+attributetype ( 1.3.6.1.4.1.16868.1.1.17 NAME 'pykotaJobDate'
+        DESC 'Date of when the job began'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+
+## New Pykota User object type
+objectclass ( 1.3.6.1.4.1.16868.1.2.1 NAME 'pykotaUser' SUP top AUXILIARY
+        DESC 'PyKota Auxiliary User Account'
+        MUST ( uid )
+        MAY  ( pykotaLimitBy $ pykotaBalance $ pykotaLifeTimePaid ) )
+        
+## New Pykota Group object type
+objectclass ( 1.3.6.1.4.1.16868.1.2.2 NAME 'pykotaGroup' SUP top AUXILIARY
+        DESC 'PyKota Auxiliary Group'
+        MUST ( cn )
+        MAY  ( pykotaLimitBy ) )
+        
+## New Pykota Printer object type
+objectclass ( 1.3.6.1.4.1.16868.1.2.3 NAME 'pykotaPrinter' SUP top STRUCTURAL
+        DESC 'PyKota Printer'
+        MUST ( pykotaPrinterName )
+        MAY  ( pykotaPricePerPage $ pykotaPricePerJob ) )
+        
+## New PyKota User Print Quota on a Printer        
+objectclass ( 1.3.6.1.4.1.16868.1.2.4 NAME 'pykotaUserPQuota' SUP top STRUCTURAL
+        DESC 'PyKota User Quota on a Printer'
+        MUST ( uid )
+        MAY  ( pykotaPageCounter $ pykotaLifePageCounter $ pykotaSoftLimit $ pykotaHardLimit $ pykotaDateLimit ) )
+        
+## New PyKota Group Print Quota on a Printer        
+objectclass ( 1.3.6.1.4.1.16868.1.2.5 NAME 'pykotaGroupPQuota' SUP top STRUCTURAL
+        DESC 'PyKota Group Quota on a Printer'
+        MUST ( cn )
+        MAY  ( pykotaSoftLimit $ pykotaHardLimit $ pykotaDateLimit ) )
+        
+## New PyKota Job entry in a Printer's history        
+objectclass ( 1.3.6.1.4.1.16868.1.2.6 NAME 'pykotaPrinterJob' SUP top STRUCTURAL
+        DESC 'An entry in the job history for a printer'
+        MUST ( pykotaJobHistoryId $ uid $ pykotaJobId )
+        MAY  ( pykotaPrinterPageCounter $ pykotaJobSize $ pykotaAction $ pykotaJobDate ) )
+        
Index: pykota/trunk/initscripts/ldap/README.ldap
===================================================================
--- pykota/trunk/initscripts/ldap/README.ldap (revision 1015)
+++ pykota/trunk/initscripts/ldap/README.ldap (revision 1015)
@@ -0,0 +1,38 @@
+# $Id$
+
+PyKota - Print Quota for CUPS and LPRng
+
+(c) 2003 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.
+
+============================================================
+
+Documentation :
+---------------
+
+pykota.schema :
+
+    This file can be used to modify an existing LDAP directory
+    to add the necessary attributes for use with PyKota.
+
+pykota.ldif :
+
+    This file represents a sample LDAP directory tree with
+    PyKota functionnalities.
+    
+More help will be available in the future, when this schema        
+will be completed and LDAP support will be finalized.
+
+============================================================
Index: pykota/trunk/initscripts/postgresql/README.postgresql
===================================================================
--- pykota/trunk/initscripts/postgresql/README.postgresql (revision 1015)
+++ pykota/trunk/initscripts/postgresql/README.postgresql (revision 1015)
@@ -0,0 +1,65 @@
+# $Id$
+
+PyKota - Print Quota for CUPS and LPRng
+
+(c) 2003 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.
+
+============================================================
+
+Documentation for the pykota-postgresql.sql script :
+----------------------------------------------------
+
+This script is to be used to create an empty Quota Storage
+DataBase using PostgreSQL as a backend.
+
+If you have already installed PyKota, and have datas in your
+Quota Storage DataBase, you may prefer to skip this section
+and read the next one.
+
+        - Launch the psql frontend and connect to the
+          database template1 as a PostgreSQL administrator
+          (i.e. the postgres user) :
+          
+            $ psql -h localhost -U postgres template1
+          
+        - Executes the pykota-postgresql.sql script :  
+        
+            template1=# \i pykota-postgresql.sql
+            
+        - Quit the psql frontend :    
+        
+            template1=# \q
+            
+        - Your PostgreSQL PyKota storage is now ready
+          for use.
+        
+============================================================
+
+Upgrade scripts :
+
+  Some scripts to upgrade old PyKota databases to the new
+  database schema are included. You may have to run all
+  of them or only some of them, depending on your 
+  version of PyKota.
+  
+* An sql script to upgrade a pre-1.01 PyKota Quota Storage DataBase to 
+  1.01 is still included for historical reasons. PLEASE DON'T USE IT ! 
+  
+* If you are already running an old version of PyKota (<1.03) and 
+  want to upgrade to 1.03, YOU HAVE TO RUN the 
+  upgrade-from-before-1.03.py shell script. NOT LAUNCHING THIS SCRIPT 
+  WILL CAUSE PYKOTA TO STOP WORKING ! PLEASE NEVER RUN THIS SCRIPT IF 
+  YOUR EXISTING VERSION OF PYKOTA IS ALREADY 1.03 OD HIGHER. 
Index: pykota/trunk/initscripts/postgresql/VERYOLDpykota-upgrade-postgresql.sql
===================================================================
--- pykota/trunk/initscripts/postgresql/VERYOLDpykota-upgrade-postgresql.sql (revision 1015)
+++ pykota/trunk/initscripts/postgresql/VERYOLDpykota-upgrade-postgresql.sql (revision 1015)
@@ -0,0 +1,56 @@
+--
+-- PyKota - Print Quotas for CUPS and LPRng
+--
+-- (c) 2003 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$
+--
+-- $Log$
+-- Revision 1.1  2003/06/05 07:12:31  jalet
+-- Reorganization of directories
+--
+--
+--
+--
+-- This script has to be used if you already
+-- have a pre-1.01 version of PyKota to upgrade
+-- your database schema. Don't use it if
+-- you've just installed PyKota, just use
+-- the normal script instead.
+--
+                        
+--                         
+-- WARNING : YOU NEED A RECENT VERSION OF POSTGRESQL FOR THE DROP COLUMN STATEMENT TO WORK !
+--
+
+--                         
+-- Modify the old database schema
+--
+ALTER TABLE grouppquota DROP COLUMN lifepagecounter;
+ALTER TABLE grouppquota DROP COLUMN pagecounter;
+
+--                         
+-- Create the groups/members relationship
+--
+CREATE TABLE groupsmembers(groupid INT4 REFERENCES groups(id),
+                           userid INT4 REFERENCES users(id),
+                           PRIMARY KEY (groupid, userid));
+                           
+--                        
+-- Set some ACLs                        
+--
+REVOKE ALL ON groupsmembers FROM public;                        
+GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON groupsmembers TO pykotaadmin;
Index: pykota/trunk/initscripts/postgresql/pykota-postgresql.sql
===================================================================
--- pykota/trunk/initscripts/postgresql/pykota-postgresql.sql (revision 1015)
+++ pykota/trunk/initscripts/postgresql/pykota-postgresql.sql (revision 1015)
@@ -0,0 +1,126 @@
+--
+-- PyKota - Print Quotas for CUPS and LPRng
+--
+-- (c) 2003 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$
+--
+-- $Log$
+-- Revision 1.1  2003/06/05 07:12:31  jalet
+-- Reorganization of directories
+--
+--
+--
+
+--
+-- PyKota Database creation script for PostgreSQL
+--
+-- Launch this as PostgreSQL administrator with \i
+--
+
+
+--
+-- Create the print quota database
+--
+CREATE DATABASE pykota;
+
+--
+-- Create the print quota database users
+-- 
+CREATE USER pykotauser;
+CREATE USER pykotaadmin;
+
+-- 
+-- Now connect to the new database
+-- 
+\connect pykota
+
+--
+-- Create the users table
+--
+CREATE TABLE users(id SERIAL PRIMARY KEY NOT NULL,
+                   username TEXT UNIQUE NOT NULL,
+                   balance FLOAT DEFAULT 0.0,
+                   lifetimepaid FLOAT DEFAULT 0.0,
+                   limitby TEXT DEFAULT 'quota');
+                   
+--
+-- Create the groups table
+--
+CREATE TABLE groups(id SERIAL PRIMARY KEY NOT NULL,
+                    groupname TEXT UNIQUE NOT NULL,
+                    limitby TEXT DEFAULT 'quota');
+                    
+--
+-- Create the printers table
+--
+CREATE TABLE printers(id SERIAL PRIMARY KEY NOT NULL,
+                      printername TEXT UNIQUE NOT NULL,
+                      priceperpage FLOAT DEFAULT 0.0,
+                      priceperjob FLOAT DEFAULT 0.0);
+                    
+--
+-- Create the print quota table for users
+--
+CREATE TABLE userpquota(id SERIAL PRIMARY KEY NOT NULL,
+                        userid INT4 REFERENCES users(id),
+                        printerid INT4 REFERENCES printers(id),
+                        lifepagecounter INT4 DEFAULT 0,
+                        pagecounter INT4 DEFAULT 0,
+                        softlimit INT4,
+                        hardlimit INT4,
+                        datelimit TIMESTAMP);
+                        
+--
+-- Create the job history table
+--
+CREATE TABLE jobhistory(id SERIAL PRIMARY KEY NOT NULL,
+                        jobid TEXT,
+                        userid INT4 REFERENCES users(id),
+                        printerid INT4 REFERENCES printers(id),
+                        pagecounter INT4 DEFAULT 0,
+                        jobsize INT4,
+                        action TEXT,
+                        jobdate TIMESTAMP DEFAULT now());
+                        
+--
+-- Create the print quota table for groups
+--
+CREATE TABLE grouppquota(id SERIAL PRIMARY KEY NOT NULL,
+                         groupid INT4 REFERENCES groups(id),
+                         printerid INT4 REFERENCES printers(id),
+                         softlimit INT4,
+                         hardlimit INT4,
+                         datelimit TIMESTAMP);
+                        
+--                         
+-- Create the groups/members relationship
+--
+CREATE TABLE groupsmembers(groupid INT4 REFERENCES groups(id),
+                           userid INT4 REFERENCES users(id),
+                           PRIMARY KEY (groupid, userid));
+
+--                        
+-- Set some ACLs                        
+--
+REVOKE ALL ON users, groups, printers, userpquota, grouppquota, groupsmembers, jobhistory FROM public;                        
+GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON users, groups, printers, userpquota, grouppquota, groupsmembers, jobhistory TO pykotaadmin;
+GRANT SELECT, UPDATE ON users_id_seq, groups_id_seq, printers_id_seq, userpquota_id_seq, grouppquota_id_seq, jobhistory_id_seq TO pykotaadmin;
+GRANT SELECT, UPDATE ON printers, userpquota, grouppquota TO pykotauser;
+GRANT SELECT ON users, groups, groupsmembers TO pykotauser;
+GRANT SELECT, INSERT, UPDATE ON jobhistory TO pykotauser;
+GRANT SELECT, UPDATE ON jobhistory_id_seq TO pykotauser;
+
Index: pykota/trunk/initscripts/postgresql/upgrade-from-before-1.03.py
===================================================================
--- pykota/trunk/initscripts/postgresql/upgrade-from-before-1.03.py (revision 1015)
+++ pykota/trunk/initscripts/postgresql/upgrade-from-before-1.03.py (revision 1015)
@@ -0,0 +1,172 @@
+#! /usr/bin/env python
+
+# PyKota Print Quota Warning sender
+#
+# PyKota - Print Quotas for CUPS and LPRng
+#
+# (c) 2003 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$
+#
+# THIS IS AN UPGRADE SCRIPT FOR OLD PYKOTA DATABASES TO THE 1.03 VERSION
+#
+
+import sys
+import os
+try :
+    import pg
+except ImportError :    
+    sys.stderr.write("The PyGreSQL Python module doesn't seem to be available. ABORTED.\n")
+    sys.exit(-1)
+
+def dump_old_database() :
+    """Dumps the existing PyKota database to a file, to avoir loosing data.
+    
+       Returns 1 if dump is successfull, 0 if it isn't.
+    """   
+    pipeinput = os.popen("pg_dump -C -D -N -U postgres -f pykota-dump.sql pykota")
+    dummy = pipeinput.read()
+    return (pipeinput.close() is None) or 0
+
+def create_new_database() :
+    """Creates the empty database."""
+    pipeinput = os.popen("psql -U postgres template1 <pykota-postgresql.sql")
+    dummy = pipeinput.read()
+    return (pipeinput.close() is None) or 0
+    
+def restore_original_database() :
+    """Creates the empty database."""
+    pipeinput = os.popen("psql -U postgres template1 <pykota-dump.sql")
+    dummy = pipeinput.read()
+    return (pipeinput.close() is None) or 0
+    
+def open_database(dbname="pykota") :
+    """Returns the database object or None if we can't connect to it."""
+    try :
+        pykotadb = pg.connect(host="localhost", port=5432, dbname=dbname, user="postgres")
+    except pg.error, msg :     
+        sys.stderr.write("%s\n" % msg)
+        sys.stderr.write("Unable to connect to the local PostgreSQL server.\nPlease modify the open_database() method in %s\nto connect to the correct PostgreSQL server\nand relaunch the script.\n" % sys.argv[0])
+        return 
+    else :    
+        return pykotadb
+        
+        
+def doQuote(field) :
+    """Quotes a field for use as a string in SQL queries."""
+    if type(field) == type(0) : # TODO : do something safer
+        typ = "decimal"
+    else :    
+        typ = "text"
+    return pg._quote(field, typ)
+        
+def main() :
+    """Does the work."""
+    
+    # First we make a dump of the old database
+    print "Dumping old database for safety...",
+    if not dump_old_database() :
+        sys.stderr.write("Error while dumping old database. ABORTED.\n")
+        return -1
+    print "Done."
+        
+    # Second we try to connect to it    
+    print "Extracting datas from old database...", 
+    db = open_database()
+    if db is None :
+        sys.stderr.write("Impossible to connect to old PyKota database. ABORTED.\nAre you sure you are upgrading an existing installation ?\n")
+        return -1
+    
+    # Third we extract datas
+    oldprinters = db.query("SELECT * FROM printers ORDER BY id;")
+    oldusers = db.query("SELECT * FROM users ORDER BY id;")
+    oldquotas = db.query("SELECT * FROM userpquota ORDER BY printerid, userid;")
+    
+    # Fourth close the database
+    db.close()
+    print "Done."
+    
+    # Fifth we delete the old database !
+    answer = raw_input("The old database will be deleted for the upgrade to take place.\nAre you sure you want to continue (y/N) ? ")
+    if answer[0:1].upper() != 'Y' :
+        sys.stderr.write("User wants to stop now ! ABORTED.\n")
+        return -1
+    db = open_database("template1")
+    if db is None :
+        sys.stderr.write("Impossible to connect to database template1. ABORTED.\nPlease report to your Database administrator.\n")
+        return -1
+    try :
+        db.query("DROP DATABASE pykota;")
+    except pg.error, msg :
+        sys.stderr.write("Impossible to delete old database. ABORTED.\n%s\n" % msg)
+        db.close()
+        return -1
+    else :    
+        db.close()
+        
+    # Sixth we create the new database
+    print "Creating the new database...",
+    if not create_new_database() :
+        sys.stderr.write("impossible to create new database ! ABORTED.\n")
+        return -1
+    print "Done."
+    
+    # Seventh we restore old data
+    print "Restoring old datas..."
+    db = open_database()
+    if db is None :
+        sys.stderr.write("Impossible to connect to new PyKota database. ABORTED.\nOld database will be restored if possible.")
+        print "An error occured, I'll try to restore the original database..."
+        if not restore_original_database() :
+            sys.stderr.write("Shit ! A double-error occured !!!\nPlease report problem to your database administrator.\n")
+            sys.stderr.write("And file a bug report to alet@librelogiciel.com\n")
+        else :    
+            print "Done."
+        return -1
+    db.query("BEGIN;")    
+    try :
+        newprinters = {}
+        for oldprinter in oldprinters.dictresult() :
+            db.query("INSERT INTO printers (printername) VALUES (%s);" % doQuote(oldprinter["printername"]))
+            newid = db.query("SELECT id FROM printers WHERE printername='%s';" % oldprinter["printername"]).dictresult()[0]["id"]
+            newprinters[oldprinter["id"]] = newid
+        newusers = {}    
+        for olduser in oldusers.dictresult() :    
+            db.query("INSERT INTO users (username) VALUES (%s);" % doQuote(olduser["username"]))
+            newid = db.query("SELECT id FROM users WHERE username='%s';" % olduser["username"]).dictresult()[0]["id"]
+            newusers[olduser["id"]] = newid
+        for oldquota in oldquotas.dictresult() :   
+            db.query("INSERT INTO userpquota (userid, printerid, pagecounter, lifepagecounter, softlimit, hardlimit, datelimit) VALUES (%s, %s, %s, %s, %s, %s, %s);" % 
+                                              (doQuote(newusers[oldquota["userid"]]) , doQuote(newprinters[oldquota["printerid"]]), doQuote(oldquota["pagecounter"]), doQuote(oldquota["lifepagecounter"]), doQuote(oldquota["softlimit"]), doQuote(oldquota["hardlimit"]), doQuote(oldquota["datelimit"])))
+    except pg.error, msg :    
+        sys.stderr.write("ERROR : %s\nABORTED.\n" % msg)
+        db.query("ROLLBACK;")
+        db.close()    
+        return -1
+    except :    
+        sys.stderr.write("Unknown error ! ABORTED.\n")
+        db.query("ROLLBACK;")
+        db.close()    
+        return -1
+    else :    
+        db.query("COMMIT;")
+        db.close()
+    print "Done."
+    print "NB : Last job on each printer was lost. This is normal !"
+    return 0
+    
+if __name__ == "__main__" :
+    sys.exit(main())
Index: pykota/trunk/initscripts/README
===================================================================
--- pykota/trunk/initscripts/README (revision 1007)
+++ pykota/trunk/initscripts/README (revision 1015)
@@ -24,9 +24,10 @@
 depending on the storage backend you want to use.
 
+There's one subdirectory per backend type supported.
 
 Files :
 =======
 
-  * pykota-postgresql.sql :
+  * postgresql/pykota-postgresql.sql :
   
     This file creates an empty Quota Storage Database, using PostgreSQL
@@ -34,8 +35,12 @@
     if you want to use PostgreSQL as the Quota Storage Backend.
     
-  * pykota.schema :  
+  * ldap/pykota.schema :  
   
     This file adds the necessary classes and attributes to an existing
     LDAP directory for use with PyKota. Read this file for details.
+    
+    
+Old files, kept to allow people to upgrade from very old versions of PyKota :   
+=============================================================================
     
   * VERYOLDpykota-upgrade-postgresql.sql :
Index: pykota/trunk/initscripts/README.postgresql
===================================================================
--- pykota/trunk/initscripts/README.postgresql (revision 952)
+++  (revision )
@@ -1,65 +1,0 @@
-# $Id$
-
-PyKota - Print Quota for CUPS and LPRng
-
-(c) 2003 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.
-
-============================================================
-
-Documentation for the pykota-postgresql.sql script :
-----------------------------------------------------
-
-This script is to be used to create an empty Quota Storage
-DataBase using PostgreSQL as a backend.
-
-If you have already installed PyKota, and have datas in your
-Quota Storage DataBase, you may prefer to skip this section
-and read the next one.
-
-        - Launch the psql frontend and connect to the
-          database template1 as a PostgreSQL administrator
-          (i.e. the postgres user) :
-          
-            $ psql -h localhost -U postgres template1
-          
-        - Executes the pykota-postgresql.sql script :  
-        
-            template1=# \i pykota-postgresql.sql
-            
-        - Quit the psql frontend :    
-        
-            template1=# \q
-            
-        - Your PostgreSQL PyKota storage is now ready
-          for use.
-        
-============================================================
-
-Upgrade scripts :
-
-  Some scripts to upgrade old PyKota databases to the new
-  database schema are included. You may have to run all
-  of them or only some of them, depending on your 
-  version of PyKota.
-  
-* An sql script to upgrade a pre-1.01 PyKota Quota Storage DataBase to 
-  1.01 is still included for historical reasons. PLEASE DON'T USE IT ! 
-  
-* If you are already running an old version of PyKota (<1.03) and 
-  want to upgrade to 1.03, YOU HAVE TO RUN the 
-  upgrade-from-before-1.03.py shell script. NOT LAUNCHING THIS SCRIPT 
-  WILL CAUSE PYKOTA TO STOP WORKING ! PLEASE NEVER RUN THIS SCRIPT IF 
-  YOUR EXISTING VERSION OF PYKOTA IS ALREADY 1.03 OD HIGHER. 
Index: pykota/trunk/initscripts/VERYOLDpykota-upgrade-postgresql.sql
===================================================================
--- pykota/trunk/initscripts/VERYOLDpykota-upgrade-postgresql.sql (revision 952)
+++  (revision )
@@ -1,59 +1,0 @@
---
--- PyKota - Print Quotas for CUPS and LPRng
---
--- (c) 2003 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$
---
--- $Log$
--- Revision 1.2  2003/04/23 22:13:56  jalet
--- Preliminary support for LPRng added BUT STILL UNTESTED.
---
--- Revision 1.1  2003/04/17 21:33:16  jalet
--- Version 1.03 is out.
---
---
---
---
--- This script has to be used if you already
--- have a pre-1.01 version of PyKota to upgrade
--- your database schema. Don't use it if
--- you've just installed PyKota, just use
--- the normal script instead.
---
-                        
---                         
--- WARNING : YOU NEED A RECENT VERSION OF POSTGRESQL FOR THE DROP COLUMN STATEMENT TO WORK !
---
-
---                         
--- Modify the old database schema
---
-ALTER TABLE grouppquota DROP COLUMN lifepagecounter;
-ALTER TABLE grouppquota DROP COLUMN pagecounter;
-
---                         
--- Create the groups/members relationship
---
-CREATE TABLE groupsmembers(groupid INT4 REFERENCES groups(id),
-                           userid INT4 REFERENCES users(id),
-                           PRIMARY KEY (groupid, userid));
-                           
---                        
--- Set some ACLs                        
---
-REVOKE ALL ON groupsmembers FROM public;                        
-GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON groupsmembers TO pykotaadmin;
Index: pykota/trunk/initscripts/pykota-sample.ldif
===================================================================
--- pykota/trunk/initscripts/pykota-sample.ldif (revision 1013)
+++  (revision )
@@ -1,86 +1,0 @@
-dn: ou=People,dc=librelogiciel,dc=com
-ou: People
-objectClass: organizationalUnit
-
-dn: ou=Groups,dc=librelogiciel,dc=com
-ou: Groups
-objectClass: organizationalUnit
-
-dn: ou=Printers,dc=librelogiciel,dc=com
-ou: Printers
-objectClass: organizationalUnit
-
-dn: uid=jerome,ou=People,dc=librelogiciel,dc=com
-uid: jerome
-cn:: SmVyb21lIEFsZXQ=
-objectClass: account
-objectClass: posixAccount
-objectClass: top
-objectClass: shadowAccount
-objectClass: pykotaUser
-userPassword: {crypt}PvuIT4Mz8.lCM
-shadowLastChange: 12093
-shadowMax: 99999
-shadowWarning: 7
-loginShell: /bin/bash
-uidNumber: 500
-gidNumber: 500
-homeDirectory: /home/jerome
-gecos: Jerome Alet,,,
-pykotaLimitBy: quota
-pykotaBalance: 0
-pykotaLifeTimePaid: 0
-
-dn: cn=devel,ou=Groups,dc=librelogiciel,dc=com
-objectClass: posixGroup
-objectClass: top
-objectClass: pykotaGroup
-cn: devel
-userPassword: {crypt}x
-gidNumber: 500
-memberUid: jerome
-pykotaLimitBy: quota
-
-dn: pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
-objectClass: pykotaPrinter
-pykotaPrinterName: apple
-pykotaPricePerPage: 0.1
-pykotaPricePerJob: 0.25
-
-dn: ou=userPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
-ou: userPQuotas
-objectClass: organizationalUnit
-
-dn: ou=groupPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
-ou: groupPQuotas
-objectClass: organizationalUnit
-
-dn: ou=Jobs,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
-ou: Jobs
-objectClass: organizationalUnit
-
-dn: uid=jerome,ou=userPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
-objectClass: pykotaUserPQuota
-uid: jerome
-pykotaPageCounter: 0
-pykotaLifePageCounter: 0
-pykotaSoftLimit: 100
-pykotaHardLimit: 110
-pykotaDateLimit: None
-
-dn: cn=devel,ou=groupPQuotas,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
-objectClass: pykotaGroupPQuota
-cn: devel
-pykotaSoftLimit: 400
-pykotaHardLimit: 450
-pykotaDateLimit: None
-
-dn: pykotaJobHistoryId=1,ou=Jobs,pykotaPrinterName=apple,ou=Printers,dc=librelogiciel,dc=com
-objectClass: pykotaPrinterJob
-pykotaJobHistoryId: 1
-pykotaJobId: 15
-uid: jerome
-pykotaPrinterPageCounter: 1533
-pykotaJobSize: 5
-pykotaAction: ALLOW
-pykotaJobDate: 2003-06-04 16:12
Index: pykota/trunk/initscripts/pykota-postgresql.sql
===================================================================
--- pykota/trunk/initscripts/pykota-postgresql.sql (revision 952)
+++  (revision )
@@ -1,171 +1,0 @@
---
--- PyKota - Print Quotas for CUPS and LPRng
---
--- (c) 2003 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$
---
--- $Log$
--- Revision 1.14  2003/04/23 22:13:56  jalet
--- Preliminary support for LPRng added BUT STILL UNTESTED.
---
--- Revision 1.13  2003/04/15 11:30:57  jalet
--- More work done on money print charging.
--- Minor bugs corrected.
--- All tools now access to the storage as priviledged users, repykota excepted.
---
--- Revision 1.12  2003/04/14 20:01:02  jalet
--- Typo
---
--- Revision 1.11  2003/04/14 19:58:59  jalet
--- New database schema for users' account balance
---
--- Revision 1.10  2003/04/10 21:47:20  jalet
--- Job history added. Upgrade script neutralized for now !
---
--- Revision 1.9  2003/04/09 20:11:29  jalet
--- Added a field to save the action taken for this job (Allow, Deny)
---
--- Revision 1.8  2003/04/09 20:09:34  jalet
--- New table to keep job history
---
--- Revision 1.7  2003/04/08 20:38:08  jalet
--- The last job Id is saved now for each printer, this will probably
--- allow other accounting methods in the future.
---
--- Revision 1.6  2003/03/29 13:45:27  jalet
--- GPL paragraphs were incorrectly (from memory) copied into the sources.
--- Two README files were added.
--- Upgrade script for PostgreSQL pre 1.01 schema was added.
---
--- Revision 1.5  2003/03/12 19:06:08  jalet
--- Initial support for groups added.
---
--- Revision 1.4  2003/02/27 08:40:14  jalet
--- DATETIME is not supported anymore in PostgreSQL 7.3 it seems, but
--- TIMESTAMP is.
---
--- Revision 1.3  2003/02/26 20:34:22  jalet
--- Default value for printer page counter set to 0
---
--- Revision 1.2  2003/02/08 22:12:09  jalet
--- Life time counter for users and groups added.
---
--- Revision 1.1  2003/02/05 21:28:17  jalet
--- Initial import into CVS
---
---
---
-
---
--- PyKota Database creation script for PostgreSQL
---
--- Launch this as PostgreSQL administrator with \i
---
-
-
---
--- Create the print quota database
---
-CREATE DATABASE pykota;
-
---
--- Create the print quota database users
--- 
-CREATE USER pykotauser;
-CREATE USER pykotaadmin;
-
--- 
--- Now connect to the new database
--- 
-\connect pykota
-
---
--- Create the users table
---
-CREATE TABLE users(id SERIAL PRIMARY KEY NOT NULL,
-                   username TEXT UNIQUE NOT NULL,
-                   balance FLOAT DEFAULT 0.0,
-                   lifetimepaid FLOAT DEFAULT 0.0,
-                   limitby TEXT DEFAULT 'quota');
-                   
---
--- Create the groups table
---
-CREATE TABLE groups(id SERIAL PRIMARY KEY NOT NULL,
-                    groupname TEXT UNIQUE NOT NULL,
-                    limitby TEXT DEFAULT 'quota');
-                    
---
--- Create the printers table
---
-CREATE TABLE printers(id SERIAL PRIMARY KEY NOT NULL,
-                      printername TEXT UNIQUE NOT NULL,
-                      priceperpage FLOAT DEFAULT 0.0,
-                      priceperjob FLOAT DEFAULT 0.0);
-                    
---
--- Create the print quota table for users
---
-CREATE TABLE userpquota(id SERIAL PRIMARY KEY NOT NULL,
-                        userid INT4 REFERENCES users(id),
-                        printerid INT4 REFERENCES printers(id),
-                        lifepagecounter INT4 DEFAULT 0,
-                        pagecounter INT4 DEFAULT 0,
-                        softlimit INT4,
-                        hardlimit INT4,
-                        datelimit TIMESTAMP);
-                        
---
--- Create the job history table
---
-CREATE TABLE jobhistory(id SERIAL PRIMARY KEY NOT NULL,
-                        jobid TEXT,
-                        userid INT4 REFERENCES users(id),
-                        printerid INT4 REFERENCES printers(id),
-                        pagecounter INT4 DEFAULT 0,
-                        jobsize INT4,
-                        action TEXT,
-                        jobdate TIMESTAMP DEFAULT now());
-                        
---
--- Create the print quota table for groups
---
-CREATE TABLE grouppquota(id SERIAL PRIMARY KEY NOT NULL,
-                         groupid INT4 REFERENCES groups(id),
-                         printerid INT4 REFERENCES printers(id),
-                         softlimit INT4,
-                         hardlimit INT4,
-                         datelimit TIMESTAMP);
-                        
---                         
--- Create the groups/members relationship
---
-CREATE TABLE groupsmembers(groupid INT4 REFERENCES groups(id),
-                           userid INT4 REFERENCES users(id),
-                           PRIMARY KEY (groupid, userid));
-
---                        
--- Set some ACLs                        
---
-REVOKE ALL ON users, groups, printers, userpquota, grouppquota, groupsmembers, jobhistory FROM public;                        
-GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON users, groups, printers, userpquota, grouppquota, groupsmembers, jobhistory TO pykotaadmin;
-GRANT SELECT, UPDATE ON users_id_seq, groups_id_seq, printers_id_seq, userpquota_id_seq, grouppquota_id_seq, jobhistory_id_seq TO pykotaadmin;
-GRANT SELECT, UPDATE ON printers, userpquota, grouppquota TO pykotauser;
-GRANT SELECT ON users, groups, groupsmembers TO pykotauser;
-GRANT SELECT, INSERT, UPDATE ON jobhistory TO pykotauser;
-GRANT SELECT, UPDATE ON jobhistory_id_seq TO pykotauser;
-
Index: pykota/trunk/initscripts/pykota.schema
===================================================================
--- pykota/trunk/initscripts/pykota.schema (revision 1013)
+++  (revision )
@@ -1,149 +1,0 @@
-# $Id$
-#
-# pykota.schema
-#
-# LDAP Schema for Pykota Quota System
-# Version 0.2
-#
-# Written 2003-05-28 by Wayne Godoy and John Flynn <wgodoy =AT= ub -DOT- edu -DOT- bz>
-#
-# Modified by Jerome Alet 2003-06-01
-#
-# 16868.x       => Conseil Internet & Logiciels Libres
-# 16868.1.x     => Pykota
-# 16868.1.1.x   => attributes
-# 16868.1.2.x   => classes
-#
-#
-# THIS IS WORK UNDER HEAVY DEVELOPPMENT !
-#
-# USE AT YOUR OWN RISK, AND ONLY IF YOU PERFECTLY KNOW
-# WHAT YOU ARE DOING.
-#
-# WHEN LDAP SUPPORT WILL BE FINALIZED, YOU'LL KNOW IT !
-#
-
-## Pykota related LDAP attributes
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.1 NAME 'pykotaLimitBy'
-        DESC 'How to limit the user/group : quota or balance'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.2 NAME 'pykotaBalance'
-        DESC 'Current account balance for the user, float'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.3 NAME 'pykotaLifeTimePaid'
-        DESC 'Total money paid by the user to fill his account balance, float'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.4 NAME 'pykotaPricePerPage'
-        DESC 'Price per page for a printer, float'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.5 NAME 'pykotaPricePerJob'
-        DESC 'Price per job for a printer, float'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.6 NAME 'pykotaPrinterName'
-        DESC 'Printer name as defined in the printing environment, e.g. lp'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.7 NAME 'pykotaSoftLimit'
-        DESC 'Soft limit in maximal number of pages'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-        
-attributetype ( 1.3.6.1.4.1.16868.1.1.8 NAME 'pykotaHardLimit'
-        DESC 'Hard limit in maximal number of pages'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.9 NAME 'pykotaDateLimit'
-        DESC 'Date at which the soft limit becomes a hard one'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.10 NAME 'pykotaPageCounter'
-        DESC 'Current page counter for the user on a particular printer'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.11 NAME 'pykotaLifePageCounter'
-        DESC 'Total page counter for the user on a particular printer'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.12 NAME 'pykotaJobHistoryId'
-        DESC 'Id of an entry in a printer history of jobs'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.13 NAME 'pykotaJobId'
-        DESC 'Id of a job in a printer history of jobs'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.14 NAME 'pykotaPrinterPageCounter'
-        DESC 'Life time page counter of a printer when the job began'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.15 NAME 'pykotaJobSize'
-        DESC 'Current job size in number of pages in the history'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.16868.1.1.16 NAME 'pykotaAction'
-        DESC 'Was the job allowed, or denied'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-        
-attributetype ( 1.3.6.1.4.1.16868.1.1.17 NAME 'pykotaJobDate'
-        DESC 'Date of when the job began'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-
-## New Pykota User object type
-objectclass ( 1.3.6.1.4.1.16868.1.2.1 NAME 'pykotaUser' SUP top AUXILIARY
-        DESC 'PyKota Auxiliary User Account'
-        MUST ( uid )
-        MAY  ( pykotaLimitBy $ pykotaBalance $ pykotaLifeTimePaid ) )
-        
-## New Pykota Group object type
-objectclass ( 1.3.6.1.4.1.16868.1.2.2 NAME 'pykotaGroup' SUP top AUXILIARY
-        DESC 'PyKota Auxiliary Group'
-        MUST ( cn )
-        MAY  ( pykotaLimitBy ) )
-        
-## New Pykota Printer object type
-objectclass ( 1.3.6.1.4.1.16868.1.2.3 NAME 'pykotaPrinter' SUP top STRUCTURAL
-        DESC 'PyKota Printer'
-        MUST ( pykotaPrinterName )
-        MAY  ( pykotaPricePerPage $ pykotaPricePerJob ) )
-        
-## New PyKota User Print Quota on a Printer        
-objectclass ( 1.3.6.1.4.1.16868.1.2.4 NAME 'pykotaUserPQuota' SUP top STRUCTURAL
-        DESC 'PyKota User Quota on a Printer'
-        MUST ( uid )
-        MAY  ( pykotaPageCounter $ pykotaLifePageCounter $ pykotaSoftLimit $ pykotaHardLimit $ pykotaDateLimit ) )
-        
-## New PyKota Group Print Quota on a Printer        
-objectclass ( 1.3.6.1.4.1.16868.1.2.5 NAME 'pykotaGroupPQuota' SUP top STRUCTURAL
-        DESC 'PyKota Group Quota on a Printer'
-        MUST ( cn )
-        MAY  ( pykotaSoftLimit $ pykotaHardLimit $ pykotaDateLimit ) )
-        
-## New PyKota Job entry in a Printer's history        
-objectclass ( 1.3.6.1.4.1.16868.1.2.6 NAME 'pykotaPrinterJob' SUP top STRUCTURAL
-        DESC 'An entry in the job history for a printer'
-        MUST ( pykotaJobHistoryId $ uid $ pykotaJobId )
-        MAY  ( pykotaPrinterPageCounter $ pykotaJobSize $ pykotaAction $ pykotaJobDate ) )
-        
Index: pykota/trunk/initscripts/README.ldap
===================================================================
--- pykota/trunk/initscripts/README.ldap (revision 1007)
+++  (revision )
@@ -1,31 +1,0 @@
-# $Id$
-
-PyKota - Print Quota for CUPS and LPRng
-
-(c) 2003 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.
-
-============================================================
-
-Documentation for the pykota.schema file :
-------------------------------------------
-
-This file can be used to modify an existing LDAP directory
-to add the necessary attributes for use with PyKota.
-
-More help will be available in the future, when this schema        
-will be completed and LDAP support will be finalized.
-
-============================================================
Index: pykota/trunk/initscripts/upgrade-from-before-1.03.py
===================================================================
--- pykota/trunk/initscripts/upgrade-from-before-1.03.py (revision 952)
+++  (revision )
@@ -1,172 +1,0 @@
-#! /usr/bin/env python
-
-# PyKota Print Quota Warning sender
-#
-# PyKota - Print Quotas for CUPS and LPRng
-#
-# (c) 2003 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$
-#
-# THIS IS AN UPGRADE SCRIPT FOR OLD PYKOTA DATABASES TO THE 1.03 VERSION
-#
-
-import sys
-import os
-try :
-    import pg
-except ImportError :    
-    sys.stderr.write("The PyGreSQL Python module doesn't seem to be available. ABORTED.\n")
-    sys.exit(-1)
-
-def dump_old_database() :
-    """Dumps the existing PyKota database to a file, to avoir loosing data.
-    
-       Returns 1 if dump is successfull, 0 if it isn't.
-    """   
-    pipeinput = os.popen("pg_dump -C -D -N -U postgres -f pykota-dump.sql pykota")
-    dummy = pipeinput.read()
-    return (pipeinput.close() is None) or 0
-
-def create_new_database() :
-    """Creates the empty database."""
-    pipeinput = os.popen("psql -U postgres template1 <pykota-postgresql.sql")
-    dummy = pipeinput.read()
-    return (pipeinput.close() is None) or 0
-    
-def restore_original_database() :
-    """Creates the empty database."""
-    pipeinput = os.popen("psql -U postgres template1 <pykota-dump.sql")
-    dummy = pipeinput.read()
-    return (pipeinput.close() is None) or 0
-    
-def open_database(dbname="pykota") :
-    """Returns the database object or None if we can't connect to it."""
-    try :
-        pykotadb = pg.connect(host="localhost", port=5432, dbname=dbname, user="postgres")
-    except pg.error, msg :     
-        sys.stderr.write("%s\n" % msg)
-        sys.stderr.write("Unable to connect to the local PostgreSQL server.\nPlease modify the open_database() method in %s\nto connect to the correct PostgreSQL server\nand relaunch the script.\n" % sys.argv[0])
-        return 
-    else :    
-        return pykotadb
-        
-        
-def doQuote(field) :
-    """Quotes a field for use as a string in SQL queries."""
-    if type(field) == type(0) : # TODO : do something safer
-        typ = "decimal"
-    else :    
-        typ = "text"
-    return pg._quote(field, typ)
-        
-def main() :
-    """Does the work."""
-    
-    # First we make a dump of the old database
-    print "Dumping old database for safety...",
-    if not dump_old_database() :
-        sys.stderr.write("Error while dumping old database. ABORTED.\n")
-        return -1
-    print "Done."
-        
-    # Second we try to connect to it    
-    print "Extracting datas from old database...", 
-    db = open_database()
-    if db is None :
-        sys.stderr.write("Impossible to connect to old PyKota database. ABORTED.\nAre you sure you are upgrading an existing installation ?\n")
-        return -1
-    
-    # Third we extract datas
-    oldprinters = db.query("SELECT * FROM printers ORDER BY id;")
-    oldusers = db.query("SELECT * FROM users ORDER BY id;")
-    oldquotas = db.query("SELECT * FROM userpquota ORDER BY printerid, userid;")
-    
-    # Fourth close the database
-    db.close()
-    print "Done."
-    
-    # Fifth we delete the old database !
-    answer = raw_input("The old database will be deleted for the upgrade to take place.\nAre you sure you want to continue (y/N) ? ")
-    if answer[0:1].upper() != 'Y' :
-        sys.stderr.write("User wants to stop now ! ABORTED.\n")
-        return -1
-    db = open_database("template1")
-    if db is None :
-        sys.stderr.write("Impossible to connect to database template1. ABORTED.\nPlease report to your Database administrator.\n")
-        return -1
-    try :
-        db.query("DROP DATABASE pykota;")
-    except pg.error, msg :
-        sys.stderr.write("Impossible to delete old database. ABORTED.\n%s\n" % msg)
-        db.close()
-        return -1
-    else :    
-        db.close()
-        
-    # Sixth we create the new database
-    print "Creating the new database...",
-    if not create_new_database() :
-        sys.stderr.write("impossible to create new database ! ABORTED.\n")
-        return -1
-    print "Done."
-    
-    # Seventh we restore old data
-    print "Restoring old datas..."
-    db = open_database()
-    if db is None :
-        sys.stderr.write("Impossible to connect to new PyKota database. ABORTED.\nOld database will be restored if possible.")
-        print "An error occured, I'll try to restore the original database..."
-        if not restore_original_database() :
-            sys.stderr.write("Shit ! A double-error occured !!!\nPlease report problem to your database administrator.\n")
-            sys.stderr.write("And file a bug report to alet@librelogiciel.com\n")
-        else :    
-            print "Done."
-        return -1
-    db.query("BEGIN;")    
-    try :
-        newprinters = {}
-        for oldprinter in oldprinters.dictresult() :
-            db.query("INSERT INTO printers (printername) VALUES (%s);" % doQuote(oldprinter["printername"]))
-            newid = db.query("SELECT id FROM printers WHERE printername='%s';" % oldprinter["printername"]).dictresult()[0]["id"]
-            newprinters[oldprinter["id"]] = newid
-        newusers = {}    
-        for olduser in oldusers.dictresult() :    
-            db.query("INSERT INTO users (username) VALUES (%s);" % doQuote(olduser["username"]))
-            newid = db.query("SELECT id FROM users WHERE username='%s';" % olduser["username"]).dictresult()[0]["id"]
-            newusers[olduser["id"]] = newid
-        for oldquota in oldquotas.dictresult() :   
-            db.query("INSERT INTO userpquota (userid, printerid, pagecounter, lifepagecounter, softlimit, hardlimit, datelimit) VALUES (%s, %s, %s, %s, %s, %s, %s);" % 
-                                              (doQuote(newusers[oldquota["userid"]]) , doQuote(newprinters[oldquota["printerid"]]), doQuote(oldquota["pagecounter"]), doQuote(oldquota["lifepagecounter"]), doQuote(oldquota["softlimit"]), doQuote(oldquota["hardlimit"]), doQuote(oldquota["datelimit"])))
-    except pg.error, msg :    
-        sys.stderr.write("ERROR : %s\nABORTED.\n" % msg)
-        db.query("ROLLBACK;")
-        db.close()    
-        return -1
-    except :    
-        sys.stderr.write("Unknown error ! ABORTED.\n")
-        db.query("ROLLBACK;")
-        db.close()    
-        return -1
-    else :    
-        db.query("COMMIT;")
-        db.close()
-    print "Done."
-    print "NB : Last job on each printer was lost. This is normal !"
-    return 0
-    
-if __name__ == "__main__" :
-    sys.exit(main())
