root / pykota / trunk / setup.py @ 1279

Revision 1279, 17.7 kB (checked in by jalet, 20 years ago)

Now installs documentation in /usr/share/doc/pykota too.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3#
4# PyKota
5#
6# PyKota : Print Quotas for CUPS and LPRng
7#
8# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22#
23# $Id$
24#
25# $Log$
26# Revision 1.30  2004/01/12 15:45:03  jalet
27# Now installs documentation in /usr/share/doc/pykota too.
28#
29# Revision 1.29  2004/01/08 14:10:32  jalet
30# Copyright year changed.
31#
32# Revision 1.28  2003/12/27 16:49:25  uid67467
33# Should be ok now.
34#
35# Revision 1.28  2003/12/06 09:03:43  jalet
36# Added Perl script to retrieve printer's internal page counter via PJL,
37# contributed by Ren�und Jensen.
38#
39# Revision 1.27  2003/11/28 08:31:28  jalet
40# Shell script to wait for AppleTalk enabled printers being idle was added.
41#
42# Revision 1.26  2003/11/08 16:05:31  jalet
43# CUPS backend added for people to experiment.
44#
45# Revision 1.25  2003/10/08 07:01:19  jalet
46# Job history can be disabled.
47# Some typos in README.
48# More messages in setup script.
49#
50# Revision 1.24  2003/10/07 09:07:27  jalet
51# Character encoding added to please latest version of Python
52#
53# Revision 1.23  2003/07/29 20:55:17  jalet
54# 1.14 is out !
55#
56# Revision 1.22  2003/07/29 09:54:03  jalet
57# Added configurable LDAP mail attribute support
58#
59# Revision 1.21  2003/07/28 09:11:12  jalet
60# PyKota now tries to add its attributes intelligently in existing LDAP
61# directories.
62#
63# Revision 1.20  2003/07/23 16:51:32  jalet
64# waitprinter.sh is now included to prevent PyKota from asking the
65# printer's internal page counter while a job is still being printer.
66#
67# Revision 1.19  2003/07/16 21:53:07  jalet
68# Really big modifications wrt new configuration file's location and content.
69#
70# Revision 1.18  2003/07/03 09:44:00  jalet
71# Now includes the pykotme utility
72#
73# Revision 1.17  2003/06/30 12:46:15  jalet
74# Extracted reporting code.
75#
76# Revision 1.16  2003/06/06 20:49:15  jalet
77# Very latest schema. UNTESTED.
78#
79# Revision 1.15  2003/05/17 16:32:30  jalet
80# Also outputs the original import error message.
81#
82# Revision 1.14  2003/05/17 16:31:38  jalet
83# Dies gracefully if DistUtils is not present.
84#
85# Revision 1.13  2003/04/29 18:37:54  jalet
86# Pluggable accounting methods (actually doesn't support external scripts)
87#
88# Revision 1.12  2003/04/23 22:13:56  jalet
89# Preliminary support for LPRng added BUT STILL UNTESTED.
90#
91# Revision 1.11  2003/04/17 13:49:29  jalet
92# Typo
93#
94# Revision 1.10  2003/04/17 13:48:39  jalet
95# Better help
96#
97# Revision 1.9  2003/04/17 13:47:28  jalet
98# Help added during installation.
99#
100# Revision 1.8  2003/04/15 17:49:29  jalet
101# Installation script now checks the presence of Netatalk
102#
103# Revision 1.7  2003/04/03 20:03:37  jalet
104# Installation script now allows to install the sample configuration file.
105#
106# Revision 1.6  2003/03/29 13:45:26  jalet
107# GPL paragraphs were incorrectly (from memory) copied into the sources.
108# Two README files were added.
109# Upgrade script for PostgreSQL pre 1.01 schema was added.
110#
111# Revision 1.5  2003/03/29 13:08:28  jalet
112# Configuration is now expected to be found in /etc/pykota.conf instead of
113# in /etc/cups/pykota.conf
114# Installation script can move old config files to the new location if needed.
115# Better error handling if configuration file is absent.
116#
117# Revision 1.4  2003/03/29 09:47:00  jalet
118# More powerful installation script.
119#
120# Revision 1.3  2003/03/26 17:48:36  jalet
121# First shot at trying to detect the availability of the needed software
122# during the installation.
123#
124# Revision 1.2  2003/03/09 16:49:04  jalet
125# The installation script installs the man pages too now.
126#
127# Revision 1.1  2003/02/05 21:28:17  jalet
128# Initial import into CVS
129#
130#
131#
132
133import sys
134import glob
135import os
136import shutil
137try :
138    from distutils.core import setup
139except ImportError, msg :   
140    sys.stderr.write("%s\n" % msg)
141    sys.stderr.write("You need the DistUtils Python module.\nunder Debian, you may have to install the python-dev package.\nOf course, YMMV.\n")
142    sys.exit(-1)
143
144sys.path.insert(0, "pykota")
145from pykota.version import __version__, __doc__
146
147ACTION_CONTINUE = 0
148ACTION_ABORT = 1
149
150def checkModule(module) :
151    """Checks if a Python module is available or not."""
152    try :
153        exec "import %s" % module
154    except ImportError :   
155        return 0
156    else :   
157        return 1
158       
159def checkCommand(command) :
160    """Checks if a command is available or not."""
161    input = os.popen("type %s 2>/dev/null" % command)
162    result = input.read().strip()
163    input.close()
164    return result
165   
166def checkWithPrompt(prompt, module=None, command=None, helper=None) :
167    """Tells the user what will be checked, and asks him what to do if something is absent."""
168    sys.stdout.write("Checking for %s availability : " % prompt)
169    sys.stdout.flush()
170    if command is not None :
171        result = checkCommand(command)
172    elif module is not None :   
173        result = checkModule(module)
174    if result :   
175        sys.stdout.write("OK\n")
176        return ACTION_CONTINUE
177    else :   
178        sys.stdout.write("NO.\n")
179        sys.stderr.write("ERROR : %s not available !\n" % prompt)
180        if helper is not None :
181            sys.stdout.write("%s\n" % helper)
182            sys.stdout.write("You may continue safely if you don't need this functionnality.\n")
183        answer = raw_input("%s is missing. Do you want to continue anyway (y/N) ? " % prompt)
184        if answer[0:1].upper() == 'Y' :
185            return ACTION_CONTINUE
186        else :
187            return ACTION_ABORT
188   
189if ("install" in sys.argv) and not ("help" in sys.argv) :
190    # checks if Python version is correct, we need >= 2.1
191    if not (sys.version > "2.1") :
192        sys.stderr.write("PyKota needs at least Python v2.1 !\nYour version seems to be older than that, please update.\nAborted !\n")
193        sys.exit(-1)
194       
195    # checks if a configuration file is present in the new location
196    if not os.path.isfile("/etc/pykota/pykota.conf") :
197        if not os.path.isdir("/etc/pykota") :
198            try :
199                os.mkdir("/etc/pykota")
200            except OSError, msg :   
201                sys.stderr.write("An error occured while creating the /etc/pykota directory.\n%s\n" % msg)
202                sys.exit(-1)
203               
204        if os.path.isfile("/etc/pykota.conf") :
205            # upgrade from pre-1.14 to 1.14 and above
206            sys.stdout.write("From version 1.14 on, PyKota expects to find its configuration\nfile in /etc/pykota/ instead of /etc/\n")
207            sys.stdout.write("It seems that you've got a configuration file in the old location,\nso it will not be used anymore,\nand there's no configuration file in the new location.\n")
208            answer = raw_input("Do you want to move /etc/pykota.conf to /etc/pykota/pykota.conf (y/N) ? ")
209            if answer[0:1].upper() == 'Y' :
210                try :
211                    os.rename("/etc/pykota.conf", "/etc/pykota/pykota.conf")
212                except OSError :   
213                    sys.stderr.write("ERROR : An error occured while moving /etc/pykota.conf to /etc/pykota/pykota.conf\nAborted !\n")
214                    sys.exit(-1)
215                else :   
216                    sys.stdout.write("Configuration file /etc/pykota.conf moved to /etc/pykota/pykota.conf.\n")
217            else :
218                sys.stderr.write("WARNING : Configuration file /etc/pykota.conf won't be used ! Move it to /etc/pykota/ instead.\n")
219                sys.stderr.write("PyKota installation will continue anyway,\nbut the software won't run until you put a proper configuration file in /etc/pykota/\n")
220            dummy = raw_input("Please press ENTER when you have read the message above. ")
221        else :
222            # first installation
223            if os.path.isfile("conf/pykota.conf.sample") :
224                answer = raw_input("Do you want to install\n\tconf/pykota.conf.sample as /etc/pykota/pykota.conf (y/N) ? ")
225                if answer[0:1].upper() == 'Y' :
226                    try :
227                        shutil.copy("conf/pykota.conf.sample", "/etc/pykota/pykota.conf")       
228                        shutil.copy("conf/pykotadmin.conf.sample", "/etc/pykota/pykotadmin.conf")       
229                    except IOError, msg :   
230                        sys.stderr.write("WARNING : Problem while installing sample configuration files in /etc/pykota/, please do it manually.\n%s\n" % msg)
231                    else :   
232                        sys.stdout.write("Configuration file /etc/pykota/pykota.conf and /etc/pykota/pykotadmin.conf installed.\nDon't forget to adapt these files to your needs.\n")
233                else :       
234                    sys.stderr.write("WARNING : PyKota won't run without a configuration file !\n")
235            else :       
236                # Problem ?
237                sys.stderr.write("WARNING : PyKota's sample configuration file cannot be found.\nWhat you have downloaded seems to be incomplete,\nor you are not in the pykota directory.\nPlease double check, and restart the installation procedure.\n")
238            dummy = raw_input("Please press ENTER when you have read the message above. ")
239    else :   
240        # already at 1.14 or above, nothing to be done.
241        pass
242       
243    # Second stage, we will fail if onfiguration is incorrect for security reasons
244    from pykota.config import PyKotaConfig,PyKotaConfigError
245    try :
246        conf = PyKotaConfig("/etc/pykota/")
247    except PyKotaConfigError, msg :   
248        sys.stedrr.write("%s\nINSTALLATION ABORTED !\nPlease restart installation.\n" % msg)
249        sys.exit(-1)
250    else :
251        hasadmin = conf.getGlobalOption("storageadmin", ignore=1)
252        hasadminpw = conf.getGlobalOption("storageadminpw", ignore=1)
253        hasuser = conf.getGlobalOption("storageuser", ignore=1)
254        if hasadmin or hasadminpw : 
255            sys.stderr.write("From version 1.14 on, PyKota expects that /etc/pykota/pykota.conf doesn't contain the Quota Storage Administrator's name and optional password.\n")
256            sys.stderr.write("Please put these in a [global] section in /etc/pykota/pykotadmin.conf\n")
257            sys.stderr.write("Then replace these values with 'storageuser' and 'storageuserpw' in /etc/pykota/pykota.conf\n")
258            sys.stderr.write("These two fields were re-introduced to allow any user to read to his own quota, without allowing them to modify it.\n")
259            sys.stderr.write("You can look at the conf/pykota.conf.sample and conf/pykotadmin.conf.sample files for examples.\n")
260            sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n")
261            sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n")
262            sys.exit(-1)
263        if not hasuser :
264            sys.stderr.write("From version 1.14 on, PyKota expects that /etc/pykota/pykota.conf contains the Quota Storage Normal User's name and optional password.\n")
265            sys.stderr.write("Please put these in a [global] section in /etc/pykota/pykota.conf\n")
266            sys.stderr.write("These fields are respectively named 'storageuser' and 'storageuserpw'.\n")
267            sys.stderr.write("These two fields were re-introduced to allow any user to read to his own quota, without allowing them to modify it.\n")
268            sys.stderr.write("You can look at the conf/pykota.conf.sample and conf/pykotadmin.conf.sample files for examples.\n")
269            sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n")
270            sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n")
271            sys.exit(-1)
272           
273        sb = conf.getStorageBackend()
274        if (sb.get("storageadmin") is None) or (sb.get("storageuser") is None) :
275            sys.stderr.write("From version 1.14 on, PyKota expects that /etc/pykota/pykota.conf contains the Quota Storage Normal User's name and optional password which gives READONLY access to the Print Quota DataBase,")
276            sys.stderr.write("and that /etc/pykota/pykotadmin.conf contains the Quota Storage Administrator's name and optional password which gives READ/WRITE access to the Print Quota DataBase.\n")
277            sys.stderr.write("Your configuration doesn't seem to be OK, please modify your configuration files in /etc/pykota/\n")
278            sys.stderr.write("AND RESTART THE INSTALLATION.\n")
279            sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n")
280            sys.exit(-1)
281           
282        # warns for new LDAP fields   
283        if sb.get("storagebackend") == "ldapstorage" :   
284            usermail = conf.getGlobalOption("usermail", ignore=1)
285            newuser = conf.getGlobalOption("newuser", ignore=1)
286            newgroup = conf.getGlobalOption("newgroup", ignore=1)
287            if not (usermail and newuser and newgroup) :
288                sys.stderr.write("From version 1.14 on, PyKota LDAP Support needs three additional configuration fields.\n")
289                sys.stderr.write("Please put the 'usermail', 'newuser' and 'newgroup' configuration fields in a\n[global] section in /etc/pykota/pykota.conf\n")
290                sys.stderr.write("You can look at the conf/pykota.conf.sample file for examples.\n")
291                sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n")
292                sys.stderr.write("INSTALLATION ABORTED BECAUSE CONFIGURATION INCOMPLETE.\n")
293                sys.exit(-1)
294               
295        # Say something about caching mechanism and disabling job history
296        sys.stdout.write("You can now activate the database caching mechanism\nwhich is disabled by default.\nIt is especially recommanded with the LDAP backend.\n")
297        sys.stdout.write("You can now disable the preservation of the complete\njob history which is enabled by default.\nIt is probably more useful with the LDAP backend.\n")
298        sys.stdout.write("PLEASE LOOK AT THE SAMPLE CONFIGURATION FILE conf/pykota.conf.sample\n")
299        sys.stdout.write("TO LEARN HOW TO DO\n")
300        dummy = raw_input("Please press ENTER when you have read the message above. ")
301        sys.stdout.write("\n")
302           
303    # change files permissions   
304    os.chmod("/etc/pykota/pykota.conf", 0644)
305    os.chmod("/etc/pykota/pykotadmin.conf", 0640)
306   
307    # WARNING MESSAGE   
308    sys.stdout.write("WARNING : IF YOU ARE UPGRADING FROM A PRE-1.14 TO 1.14 OR ABOVE\n")
309    sys.stdout.write("AND USE THE POSTGRESQL BACKEND, THEN YOU HAVE TO MODIFY YOUR\n")
310    sys.stdout.write("DATABASE SCHEMA USING initscripts/postgresql/upgrade-to-1.14.sql\n")
311    sys.stdout.write("PLEASE READ DOCUMENTATION IN initscripts/postgresql/ TO LEARN HOW TO DO.\n")
312    sys.stdout.write("YOU CAN DO THAT AFTER THE INSTALLATION IS FINISHED, OR PRESS CTRL+C NOW.\n")
313    sys.stdout.write("\n\nYOU DON'T HAVE ANYTHING SPECIAL TO DO IF THIS IS YOUR FIRST INSTALLATION\nOR IF YOU ARE ALREADY RUNNING VERSION 1.14 OR ABOVE.\n\n")
314    dummy = raw_input("Please press ENTER when you have read the message above. ")
315   
316    # checks if some needed Python modules are there or not.
317    modulestocheck = [ ("PygreSQL", "pg", "PygreSQL is mandatory if you want to use PostgreSQL as the quota storage backend."),                                           
318                       ("mxDateTime", "mx.DateTime", "eGenix' mxDateTime is mandatory for PyKota to work."), 
319                       ("Python-LDAP", "ldap", "Python-LDAP is mandatory if you plan to use an LDAP\ndirectory as the quota storage backend.")
320                     ]
321    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.")]
322    for (name, module, helper) in modulestocheck :
323        action = checkWithPrompt(name, module=module, helper=helper)
324        if action == ACTION_ABORT :
325            sys.stderr.write("Aborted !\n")
326            sys.exit(-1)
327           
328    # checks if some software are there or not.
329    for (name, command, helper) in commandstocheck :
330        action = checkWithPrompt(name, command=command, helper=helper)
331        if action == ACTION_ABORT :
332            sys.stderr.write("Aborted !\n")
333            sys.exit(-1)
334           
335data_files = []
336mofiles = glob.glob(os.sep.join(["po", "*", "*.mo"]))
337for mofile in mofiles :
338    lang = mofile.split(os.sep)[1]
339    directory = os.sep.join(["share", "locale", lang, "LC_MESSAGES"])
340    data_files.append((directory, [ mofile ]))
341   
342docfiles = ["README", "FAQ", "SECURITY", "COPYING", "LICENSE", "CREDITS", "TODO", "NEWS"] + glob.glob(os.sep.join(["docs", "*.pdf"])) + glob.glob(os.sep.join(["docs", "pykota", "*.html"]))
343data_files.append(("/usr/share/doc/pykota", docfiles))
344
345directory = os.sep.join(["share", "man", "man1"])
346manpages = glob.glob(os.sep.join(["man", "*.1"]))   
347data_files.append((directory, manpages))
348
349setup(name = "pykota", version = __version__,
350      license = "GNU GPL",
351      description = __doc__,
352      author = "Jerome Alet",
353      author_email = "alet@librelogiciel.com",
354      url = "http://www.librelogiciel.com/software/",
355      packages = [ "pykota", "pykota.storages", "pykota.requesters", "pykota.loggers", "pykota.accounters", "pykota.reporters" ],
356      scripts = [ "bin/cupspykota", "bin/pykota", "bin/edpykota", "bin/repykota", "bin/warnpykota", "bin/pykotme", "bin/waitprinter.sh", "bin/papwaitprinter.sh", "bin/mailandpopup.sh", "contributed/pagecount.pl" ],
357      data_files = data_files)
Note: See TracBrowser for help on using the browser.