root / pykota / trunk / setup.py @ 1475

Revision 1475, 21.6 kB (checked in by jalet, 20 years ago)

Code simplifications

  • 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.40  2004/05/13 13:59:27  jalet
27# Code simplifications
28#
29# Revision 1.39  2004/04/08 17:07:41  jalet
30# pkpgcounter added
31#
32# Revision 1.38  2004/03/18 09:18:09  jalet
33# Installation now checks for old scripts
34#
35# Revision 1.37  2004/03/03 19:35:36  jalet
36# Spelling problem. Thanks to Jurandy Martins
37#
38# Revision 1.36  2004/02/25 15:10:38  jalet
39# Preliminary snmpprinterstatus command added.
40#
41# Revision 1.35  2004/02/12 22:43:58  jalet
42# Better integration in Debian and more LSB compliance, thanks to
43# Peter Hawkins.
44#
45# Revision 1.34  2004/02/07 13:45:51  jalet
46# Preliminary work on the pkhint command
47#
48# Revision 1.33  2004/02/04 11:16:59  jalet
49# pkprinters command line tool added.
50#
51# Revision 1.32  2004/01/18 20:52:50  jalet
52# Portuguese portuguese translation replaces brasilian portuguese one, which
53# moves in its own directory.
54# Installation script modified to reorganise installed documentation and include
55# the documentation on OpenOffice.org + ODBC
56#
57# Revision 1.31  2004/01/15 12:50:41  jalet
58# Installation scripts now tells where the documentation was installed.
59#
60# Revision 1.30  2004/01/12 15:45:03  jalet
61# Now installs documentation in /usr/share/doc/pykota too.
62#
63# Revision 1.29  2004/01/08 14:10:32  jalet
64# Copyright year changed.
65#
66# Revision 1.28  2003/12/27 16:49:25  uid67467
67# Should be ok now.
68#
69# Revision 1.28  2003/12/06 09:03:43  jalet
70# Added Perl script to retrieve printer's internal page counter via PJL,
71# contributed by Ren�und Jensen.
72#
73# Revision 1.27  2003/11/28 08:31:28  jalet
74# Shell script to wait for AppleTalk enabled printers being idle was added.
75#
76# Revision 1.26  2003/11/08 16:05:31  jalet
77# CUPS backend added for people to experiment.
78#
79# Revision 1.25  2003/10/08 07:01:19  jalet
80# Job history can be disabled.
81# Some typos in README.
82# More messages in setup script.
83#
84# Revision 1.24  2003/10/07 09:07:27  jalet
85# Character encoding added to please latest version of Python
86#
87# Revision 1.23  2003/07/29 20:55:17  jalet
88# 1.14 is out !
89#
90# Revision 1.22  2003/07/29 09:54:03  jalet
91# Added configurable LDAP mail attribute support
92#
93# Revision 1.21  2003/07/28 09:11:12  jalet
94# PyKota now tries to add its attributes intelligently in existing LDAP
95# directories.
96#
97# Revision 1.20  2003/07/23 16:51:32  jalet
98# waitprinter.sh is now included to prevent PyKota from asking the
99# printer's internal page counter while a job is still being printer.
100#
101# Revision 1.19  2003/07/16 21:53:07  jalet
102# Really big modifications wrt new configuration file's location and content.
103#
104# Revision 1.18  2003/07/03 09:44:00  jalet
105# Now includes the pykotme utility
106#
107# Revision 1.17  2003/06/30 12:46:15  jalet
108# Extracted reporting code.
109#
110# Revision 1.16  2003/06/06 20:49:15  jalet
111# Very latest schema. UNTESTED.
112#
113# Revision 1.15  2003/05/17 16:32:30  jalet
114# Also outputs the original import error message.
115#
116# Revision 1.14  2003/05/17 16:31:38  jalet
117# Dies gracefully if DistUtils is not present.
118#
119# Revision 1.13  2003/04/29 18:37:54  jalet
120# Pluggable accounting methods (actually doesn't support external scripts)
121#
122# Revision 1.12  2003/04/23 22:13:56  jalet
123# Preliminary support for LPRng added BUT STILL UNTESTED.
124#
125# Revision 1.11  2003/04/17 13:49:29  jalet
126# Typo
127#
128# Revision 1.10  2003/04/17 13:48:39  jalet
129# Better help
130#
131# Revision 1.9  2003/04/17 13:47:28  jalet
132# Help added during installation.
133#
134# Revision 1.8  2003/04/15 17:49:29  jalet
135# Installation script now checks the presence of Netatalk
136#
137# Revision 1.7  2003/04/03 20:03:37  jalet
138# Installation script now allows to install the sample configuration file.
139#
140# Revision 1.6  2003/03/29 13:45:26  jalet
141# GPL paragraphs were incorrectly (from memory) copied into the sources.
142# Two README files were added.
143# Upgrade script for PostgreSQL pre 1.01 schema was added.
144#
145# Revision 1.5  2003/03/29 13:08:28  jalet
146# Configuration is now expected to be found in /etc/pykota.conf instead of
147# in /etc/cups/pykota.conf
148# Installation script can move old config files to the new location if needed.
149# Better error handling if configuration file is absent.
150#
151# Revision 1.4  2003/03/29 09:47:00  jalet
152# More powerful installation script.
153#
154# Revision 1.3  2003/03/26 17:48:36  jalet
155# First shot at trying to detect the availability of the needed software
156# during the installation.
157#
158# Revision 1.2  2003/03/09 16:49:04  jalet
159# The installation script installs the man pages too now.
160#
161# Revision 1.1  2003/02/05 21:28:17  jalet
162# Initial import into CVS
163#
164#
165#
166
167import sys
168import glob
169import os
170import shutil
171try :
172    from distutils.core import setup
173except ImportError, msg :   
174    sys.stderr.write("%s\n" % msg)
175    sys.stderr.write("You need the DistUtils Python module.\nunder Debian, you may have to install the python-dev package.\nOf course, YMMV.\n")
176    sys.exit(-1)
177
178from distutils import sysconfig
179sys.path.insert(0, "pykota")
180from pykota.version import __version__, __doc__
181
182ACTION_CONTINUE = 0
183ACTION_ABORT = 1
184
185def checkOldModule(path) :
186    """Checks if an old PyKota module is still in the destination (in case of upgrade)."""
187    fname = os.path.join(sysconfig.get_python_lib(), "pykota", path)
188    for ext in ["py", "pyc", "pyo"] :
189        fullname = "%s.%s" % (fname, ext)
190        if os.path.isfile(fullname) :
191            sys.stderr.write("ERROR : old module %s still exists. Remove it and restart installation.\n" % fullname)
192            sys.stderr.write("INSTALLATION ABORTED !\n")
193            sys.exit(-1)
194   
195def checkOldScript(cmd) :
196    """Checks if an old shell script is still around in /usr/bin."""
197    return os.path.isfile(os.path.join("/usr/bin", cmd))
198
199def checkModule(module) :
200    """Checks if a Python module is available or not."""
201    try :
202        exec "import %s" % module
203    except ImportError :   
204        return 0
205    else :   
206        return 1
207       
208def checkCommand(command) :
209    """Checks if a command is available or not."""
210    input = os.popen("type %s 2>/dev/null" % command)
211    result = input.read().strip()
212    input.close()
213    return result
214   
215def checkWithPrompt(prompt, module=None, command=None, helper=None) :
216    """Tells the user what will be checked, and asks him what to do if something is absent."""
217    sys.stdout.write("Checking for %s availability : " % prompt)
218    sys.stdout.flush()
219    if command is not None :
220        result = checkCommand(command)
221    elif module is not None :   
222        result = checkModule(module)
223    if result :   
224        sys.stdout.write("OK\n")
225        return ACTION_CONTINUE
226    else :   
227        sys.stdout.write("NO.\n")
228        sys.stderr.write("ERROR : %s not available !\n" % prompt)
229        if helper is not None :
230            sys.stdout.write("%s\n" % helper)
231            sys.stdout.write("You may continue safely if you don't need this functionnality.\n")
232        answer = raw_input("%s is missing. Do you want to continue anyway (y/N) ? " % prompt)
233        if answer[0:1].upper() == 'Y' :
234            return ACTION_CONTINUE
235        else :
236            return ACTION_ABORT
237   
238if ("install" in sys.argv) and not ("help" in sys.argv) :
239    # checks if Python version is correct, we need >= 2.1
240    if not (sys.version > "2.1") :
241        sys.stderr.write("PyKota needs at least Python v2.1 !\nYour version seems to be older than that, please update.\nAborted !\n")
242        sys.exit(-1)
243       
244    # checks if a configuration file is present in the new location
245    if not os.path.isfile("/etc/pykota/pykota.conf") :
246        if not os.path.isdir("/etc/pykota") :
247            try :
248                os.mkdir("/etc/pykota")
249            except OSError, msg :   
250                sys.stderr.write("An error occured while creating the /etc/pykota directory.\n%s\n" % msg)
251                sys.exit(-1)
252               
253        if os.path.isfile("/etc/pykota.conf") :
254            # upgrade from pre-1.14 to 1.14 and above
255            sys.stdout.write("From version 1.14 on, PyKota expects to find its configuration\nfile in /etc/pykota/ instead of /etc/\n")
256            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")
257            answer = raw_input("Do you want to move /etc/pykota.conf to /etc/pykota/pykota.conf (y/N) ? ")
258            if answer[0:1].upper() == 'Y' :
259                try :
260                    os.rename("/etc/pykota.conf", "/etc/pykota/pykota.conf")
261                except OSError :   
262                    sys.stderr.write("ERROR : An error occured while moving /etc/pykota.conf to /etc/pykota/pykota.conf\nAborted !\n")
263                    sys.exit(-1)
264                else :   
265                    sys.stdout.write("Configuration file /etc/pykota.conf moved to /etc/pykota/pykota.conf.\n")
266            else :
267                sys.stderr.write("WARNING : Configuration file /etc/pykota.conf won't be used ! Move it to /etc/pykota/ instead.\n")
268                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")
269            dummy = raw_input("Please press ENTER when you have read the message above. ")
270        else :
271            # first installation
272            if os.path.isfile("conf/pykota.conf.sample") :
273                answer = raw_input("Do you want to install\n\tconf/pykota.conf.sample as /etc/pykota/pykota.conf (y/N) ? ")
274                if answer[0:1].upper() == 'Y' :
275                    try :
276                        shutil.copy("conf/pykota.conf.sample", "/etc/pykota/pykota.conf")       
277                        shutil.copy("conf/pykotadmin.conf.sample", "/etc/pykota/pykotadmin.conf")       
278                    except IOError, msg :   
279                        sys.stderr.write("WARNING : Problem while installing sample configuration files in /etc/pykota/, please do it manually.\n%s\n" % msg)
280                    else :   
281                        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")
282                else :       
283                    sys.stderr.write("WARNING : PyKota won't run without a configuration file !\n")
284            else :       
285                # Problem ?
286                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")
287            dummy = raw_input("Please press ENTER when you have read the message above. ")
288    else :   
289        # already at 1.14 or above.
290        # Now check if old scripts are still in /usr/bin
291        for script in ["cupspykota", "pykota", "waitprinter.sh", "papwaitprinter.sh", "mailandpopup.sh", "pagecount.pl"] :
292            if checkOldScript(script) :
293                sys.stderr.write("WARNING : the %s script is still present in /usr/bin, but the new version will be installed in /usr/share/pykota, please remove the %s script from /usr/bin and double check that your configuration is correct.\n" % (script, script))
294                if script == "cupspykota" :
295                    sys.stderr.write("\nBe sure to also remove the old symbolic link from /usr/lib/cups/backend/cupspykota to /usr/bin/cupspykota. You'll have to recreate it once the installation has finished successfully.\n")
296                sys.stderr.write("\nINSTALLATION ABORTED !\nPlease correct the problem and restart installation.\n")
297                sys.exit(-1)
298               
299        # now checks if pre-1.19alpha8 code is still there       
300        for module in ["accounters/querying", "accounters/external", "requesters/snmp"] :
301            checkOldModule(module)
302       
303    # Second stage, we will fail if onfiguration is incorrect for security reasons
304    from pykota.config import PyKotaConfig,PyKotaConfigError
305    try :
306        conf = PyKotaConfig("/etc/pykota/")
307    except PyKotaConfigError, msg :   
308        sys.stedrr.write("%s\nINSTALLATION ABORTED !\nPlease restart installation.\n" % msg)
309        sys.exit(-1)
310    else :
311        hasadmin = conf.getGlobalOption("storageadmin", ignore=1)
312        hasadminpw = conf.getGlobalOption("storageadminpw", ignore=1)
313        hasuser = conf.getGlobalOption("storageuser", ignore=1)
314        if hasadmin or hasadminpw : 
315            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")
316            sys.stderr.write("Please put these in a [global] section in /etc/pykota/pykotadmin.conf\n")
317            sys.stderr.write("Then replace these values with 'storageuser' and 'storageuserpw' in /etc/pykota/pykota.conf\n")
318            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")
319            sys.stderr.write("You can look at the conf/pykota.conf.sample and conf/pykotadmin.conf.sample files for examples.\n")
320            sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n")
321            sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n")
322            sys.exit(-1)
323        if not hasuser :
324            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")
325            sys.stderr.write("Please put these in a [global] section in /etc/pykota/pykota.conf\n")
326            sys.stderr.write("These fields are respectively named 'storageuser' and 'storageuserpw'.\n")
327            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")
328            sys.stderr.write("You can look at the conf/pykota.conf.sample and conf/pykotadmin.conf.sample files for examples.\n")
329            sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n")
330            sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n")
331            sys.exit(-1)
332           
333        sb = conf.getStorageBackend()
334        if (sb.get("storageadmin") is None) or (sb.get("storageuser") is None) :
335            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,")
336            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")
337            sys.stderr.write("Your configuration doesn't seem to be OK, please modify your configuration files in /etc/pykota/\n")
338            sys.stderr.write("AND RESTART THE INSTALLATION.\n")
339            sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n")
340            sys.exit(-1)
341           
342        # warns for new LDAP fields   
343        if sb.get("storagebackend") == "ldapstorage" :   
344            usermail = conf.getGlobalOption("usermail", ignore=1)
345            newuser = conf.getGlobalOption("newuser", ignore=1)
346            newgroup = conf.getGlobalOption("newgroup", ignore=1)
347            if not (usermail and newuser and newgroup) :
348                sys.stderr.write("From version 1.14 on, PyKota LDAP Support needs three additional configuration fields.\n")
349                sys.stderr.write("Please put the 'usermail', 'newuser' and 'newgroup' configuration fields in a\n[global] section in /etc/pykota/pykota.conf\n")
350                sys.stderr.write("You can look at the conf/pykota.conf.sample file for examples.\n")
351                sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n")
352                sys.stderr.write("INSTALLATION ABORTED BECAUSE CONFIGURATION INCOMPLETE.\n")
353                sys.exit(-1)
354               
355        # Say something about caching mechanism and disabling job history
356        sys.stdout.write("You can now activate the database caching mechanism\nwhich is disabled by default.\nIt is especially recommended with the LDAP backend.\n")
357        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")
358        sys.stdout.write("PLEASE LOOK AT THE SAMPLE CONFIGURATION FILE conf/pykota.conf.sample\n")
359        sys.stdout.write("TO LEARN HOW TO DO\n")
360        dummy = raw_input("Please press ENTER when you have read the message above. ")
361        sys.stdout.write("\n")
362           
363    # change files permissions   
364    os.chmod("/etc/pykota/pykota.conf", 0644)
365    os.chmod("/etc/pykota/pykotadmin.conf", 0640)
366   
367    # WARNING MESSAGE   
368    sys.stdout.write("WARNING : IF YOU ARE UPGRADING FROM A PRE-1.19alpha7 TO 1.19alpha7 OR ABOVE\n")
369    sys.stdout.write("AND USE THE POSTGRESQL BACKEND, THEN YOU HAVE TO MODIFY YOUR\n")
370    sys.stdout.write("DATABASE SCHEMA USING initscripts/postgresql/upgrade-to-1.19.sql\n")
371    sys.stdout.write("PLEASE READ DOCUMENTATION IN initscripts/postgresql/ TO LEARN HOW TO DO.\n")
372    sys.stdout.write("YOU CAN DO THAT AFTER THE INSTALLATION IS FINISHED, OR PRESS CTRL+C NOW.\n")
373    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.19alpha7 OR ABOVE.\n\n")
374    dummy = raw_input("Please press ENTER when you have read the message above. ")
375   
376    # checks if some needed Python modules are there or not.
377    modulestocheck = [ ("PygreSQL", "pg", "PygreSQL is mandatory if you want to use PostgreSQL as the quota storage backend."),                                           
378                       ("mxDateTime", "mx.DateTime", "eGenix' mxDateTime is mandatory for PyKota to work."), 
379                       ("Python-LDAP", "ldap", "Python-LDAP is mandatory if you plan to use an LDAP\ndirectory as the quota storage backend.")
380                     ]
381    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.")]
382    for (name, module, helper) in modulestocheck :
383        action = checkWithPrompt(name, module=module, helper=helper)
384        if action == ACTION_ABORT :
385            sys.stderr.write("Aborted !\n")
386            sys.exit(-1)
387           
388    # checks if some software are there or not.
389    for (name, command, helper) in commandstocheck :
390        action = checkWithPrompt(name, command=command, helper=helper)
391        if action == ACTION_ABORT :
392            sys.stderr.write("Aborted !\n")
393            sys.exit(-1)
394           
395data_files = []
396mofiles = glob.glob(os.sep.join(["po", "*", "*.mo"]))
397for mofile in mofiles :
398    lang = mofile.split(os.sep)[1]
399    directory = os.sep.join(["share", "locale", lang, "LC_MESSAGES"])
400    data_files.append((directory, [ mofile ]))
401   
402docdir = "/usr/share/doc/pykota"   
403docfiles = ["README", "FAQ", "SECURITY", "COPYING", "LICENSE", "CREDITS", "TODO", "NEWS"]
404data_files.append((docdir, docfiles))
405
406docfiles = glob.glob(os.sep.join(["docs", "*.pdf"]))
407data_files.append((docdir, docfiles))
408
409docfiles = glob.glob(os.sep.join(["docs", "spanish", "*.pdf"]))
410docfiles += glob.glob(os.sep.join(["docs", "spanish", "*.sxw"]))
411data_files.append((os.path.join(docdir, "spanish"), docfiles))
412
413docfiles = glob.glob(os.sep.join(["docs", "pykota", "*.html"]))
414data_files.append((os.path.join(docdir, "html"), docfiles))
415
416docfiles = glob.glob(os.sep.join(["openoffice", "*.sxw"]))
417docfiles += glob.glob(os.sep.join(["openoffice", "*.png"]))
418docfiles += glob.glob(os.sep.join(["openoffice", "README"]))
419data_files.append((os.path.join(docdir, "openoffice"), docfiles))
420
421directory = os.sep.join(["share", "man", "man1"])
422manpages = glob.glob(os.sep.join(["man", "*.1"]))   
423data_files.append((directory, manpages))
424
425directory = os.sep.join(["share", "pykota"])
426data_files.append((directory, ["bin/cupspykota", "bin/pykota", "bin/waitprinter.sh", "bin/papwaitprinter.sh", "bin/mailandpopup.sh", "contributed/pagecount.pl", "untested/pjl/pagecount.pjl", "untested/pjl/status.pjl", "untested/netatalk/netatalk.sh", "untested/netatalk/pagecount.ps"]))
427
428setup(name = "pykota", version = __version__,
429      license = "GNU GPL",
430      description = __doc__,
431      author = "Jerome Alet",
432      author_email = "alet@librelogiciel.com",
433      url = "http://www.librelogiciel.com/software/",
434      packages = [ "pykota", "pykota.storages", "pykota.requesters", "pykota.loggers", "pykota.accounters", "pykota.reporters" ],
435      scripts = [ "bin/pkpgcounter", "bin/snmpprinterstatus", "bin/edpykota", "bin/repykota", "bin/warnpykota", "bin/pykotme", "bin/pkprinters", "bin/pkhint" ],
436      data_files = data_files)
437
438if ("install" in sys.argv) and not ("help" in sys.argv) :
439    sys.stdout.write("\n\nYou can give a look at PyKota's documentation in:\n%s\n\n" % docdir)
Note: See TracBrowser for help on using the browser.