Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 1 | # Build and install an Apple Help Viewer compatible version of the Python |
| 2 | # documentation into the framework. |
| 3 | # Code by Bill Fancher, with some modifications by Jack Jansen. |
| 4 | # |
| 5 | # You must run this as a two-step process |
| 6 | # 1. python setupDocs.py build |
| 7 | # 2. Wait for Apple Help Indexing Tool to finish |
| 8 | # 3. python setupDocs.py install |
| 9 | # |
| 10 | # To do: |
| 11 | # - test whether the docs are available locally before downloading |
| 12 | # - fix buildDocsFromSource |
| 13 | # - Get documentation version from sys.version, fallback to 2.2.1 |
| 14 | # - See if we can somehow detect that Apple Help Indexing Tool is finished |
| 15 | # - data_files to setup() doesn't seem the right way to pass the arguments |
| 16 | # |
| 17 | import sys, os, re |
| 18 | from distutils.cmd import Command |
| 19 | from distutils.command.build import build |
| 20 | from distutils.core import setup |
| 21 | from distutils.file_util import copy_file |
| 22 | from distutils.dir_util import copy_tree |
| 23 | from distutils.log import log |
| 24 | from distutils.spawn import spawn |
| 25 | from distutils import sysconfig, dep_util |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 26 | from distutils.util import change_root |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 27 | |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 28 | |
| 29 | class DocBuild(build): |
| 30 | def initialize_options(self): |
| 31 | build.initialize_options(self) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 32 | self.build_html = None |
| 33 | self.build_dest = None |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 34 | self.download = 1 |
Jack Jansen | 08801db | 2003-03-16 22:09:22 +0000 | [diff] [blame] | 35 | self.doc_version = '2.2.2' |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 36 | |
| 37 | def finalize_options(self): |
| 38 | build.finalize_options(self) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 39 | if self.build_html is None: |
| 40 | self.build_html = os.path.join(self.build_base, 'html') |
| 41 | if self.build_dest is None: |
| 42 | self.build_dest = os.path.join(self.build_base, 'processed-html') |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 43 | |
| 44 | def spawn(self, *args): |
| 45 | spawn(args, 1, self.verbose, self.dry_run) |
| 46 | |
| 47 | def downloadDocs(self): |
| 48 | workdir = os.getcwd() |
Jack Jansen | 08801db | 2003-03-16 22:09:22 +0000 | [diff] [blame] | 49 | url = 'http://www.python.org/ftp/python/doc/%s/html-%s.tgz' % \ |
| 50 | (self.doc_version,self.doc_version) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 51 | os.chdir(self.build_base) |
Jack Jansen | 08801db | 2003-03-16 22:09:22 +0000 | [diff] [blame] | 52 | self.spawn('curl','-O', url) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 53 | os.chdir(workdir) |
Jack Jansen | 08801db | 2003-03-16 22:09:22 +0000 | [diff] [blame] | 54 | tarfile = 'html-%s.tgz' % self.doc_version |
| 55 | ## This no longer works due to name changes |
| 56 | ## self.mkpath(self.build_html) |
| 57 | ## os.chdir(self.build_html) |
| 58 | ## self.spawn('tar', '-xzf', '../' + tarfile) |
| 59 | ## os.chdir(workdir) |
| 60 | print "** Please unpack %s" % os.path.join(self.build_base, tarfile) |
| 61 | print "** Unpack the files into %s" % self.build_html |
| 62 | raise RuntimeError, "You need to unpack the docs manually" |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 63 | |
Jack Jansen | f68043c | 2003-02-14 12:47:14 +0000 | [diff] [blame] | 64 | def buildDocsFromSource(self): |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 65 | srcdir = '../../..' |
| 66 | docdir = os.path.join(srcdir, 'Doc') |
| 67 | htmldir = os.path.join(docdir, 'html') |
| 68 | spawn(('make','--directory', docdir, 'html'), 1, self.verbose, self.dry_run) |
| 69 | self.mkpath(self.build_html) |
| 70 | copy_tree(htmldir, self.build_html) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 71 | |
| 72 | def ensureHtml(self): |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 73 | if not os.path.exists(self.build_html): |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 74 | if self.download: |
| 75 | self.downloadDocs() |
| 76 | else: |
| 77 | self.buildDocsFromSource() |
| 78 | |
| 79 | def hackIndex(self): |
| 80 | ind_html = 'index.html' |
| 81 | #print 'self.build_dest =', self.build_dest |
| 82 | hackedIndex = file(os.path.join(self.build_dest, ind_html),'w') |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 83 | origIndex = file(os.path.join(self.build_html,ind_html)) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 84 | r = re.compile('<style type="text/css">.*</style>', re.DOTALL) |
Jack Jansen | 08801db | 2003-03-16 22:09:22 +0000 | [diff] [blame] | 85 | hackedIndex.write(r.sub('<META NAME="AppleTitle" CONTENT="Python Documentation">',origIndex.read())) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 86 | |
| 87 | def hackFile(self,d,f): |
| 88 | origPath = os.path.join(d,f) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 89 | assert(origPath[:len(self.build_html)] == self.build_html) |
| 90 | outPath = os.path.join(self.build_dest, d[len(self.build_html)+1:], f) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 91 | (name, ext) = os.path.splitext(f) |
| 92 | if os.path.isdir(origPath): |
| 93 | self.mkpath(outPath) |
| 94 | elif ext == '.html': |
| 95 | if self.verbose: print 'hacking %s to %s' % (origPath,outPath) |
| 96 | hackedFile = file(outPath, 'w') |
| 97 | origFile = file(origPath,'r') |
| 98 | hackedFile.write(self.r.sub('<dl><dt><dd>', origFile.read())) |
| 99 | else: |
| 100 | copy_file(origPath, outPath) |
| 101 | |
| 102 | def hackHtml(self): |
| 103 | self.r = re.compile('<dl><dd>') |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 104 | os.path.walk(self.build_html, self.visit, None) |
| 105 | |
| 106 | def visit(self, dummy, dirname, filenames): |
| 107 | for f in filenames: |
| 108 | self.hackFile(dirname, f) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 109 | |
| 110 | def makeHelpIndex(self): |
| 111 | app = '/Developer/Applications/Apple Help Indexing Tool.app' |
| 112 | self.spawn('open', '-a', app , self.build_dest) |
| 113 | print "Please wait until Apple Help Indexing Tool finishes before installing" |
| 114 | |
| 115 | def run(self): |
| 116 | self.ensure_finalized() |
Jack Jansen | 08801db | 2003-03-16 22:09:22 +0000 | [diff] [blame] | 117 | self.mkpath(self.build_base) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 118 | self.ensureHtml() |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 119 | if not os.path.isdir(self.build_html): |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 120 | raise RuntimeError, \ |
| 121 | "Can't find source folder for documentation." |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 122 | self.mkpath(self.build_dest) |
| 123 | if dep_util.newer(os.path.join(self.build_html,'index.html'), os.path.join(self.build_dest,'index.html')): |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 124 | self.mkpath(self.build_dest) |
| 125 | self.hackHtml() |
| 126 | self.hackIndex() |
| 127 | self.makeHelpIndex() |
| 128 | |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 129 | class AHVDocInstall(Command): |
| 130 | description = "install Apple Help Viewer html files" |
| 131 | user_options = [('install-doc=', 'd', |
| 132 | 'directory to install HTML tree'), |
| 133 | ('root=', None, |
| 134 | "install everything relative to this alternate root directory"), |
| 135 | ] |
| 136 | |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 137 | def initialize_options(self): |
| 138 | self.build_dest = None |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 139 | self.install_doc = None |
| 140 | self.prefix = None |
| 141 | self.root = None |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 142 | |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 143 | def finalize_options(self): |
| 144 | self.set_undefined_options('install', |
| 145 | ('prefix', 'prefix'), |
| 146 | ('root', 'root')) |
| 147 | # import pdb ; pdb.set_trace() |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 148 | build_cmd = self.get_finalized_command('build') |
| 149 | if self.build_dest == None: |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 150 | build_cmd = self.get_finalized_command('build') |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 151 | self.build_dest = build_cmd.build_dest |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 152 | if self.install_doc == None: |
Jack Jansen | 08801db | 2003-03-16 22:09:22 +0000 | [diff] [blame] | 153 | self.install_doc = os.path.join(self.prefix, 'Resources/Python.app/Contents/Resources/English.lproj/PythonDocumentation') |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 154 | print 'INSTALL', self.build_dest, '->', self.install_doc |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 155 | |
| 156 | def run(self): |
| 157 | self.finalize_options() |
| 158 | self.ensure_finalized() |
| 159 | print "Running Installer" |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 160 | instloc = self.install_doc |
| 161 | if self.root: |
| 162 | instloc = change_root(self.root, instloc) |
| 163 | self.mkpath(instloc) |
| 164 | copy_tree(self.build_dest, instloc) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 165 | print "Installation complete" |
| 166 | |
| 167 | def mungeVersion(infile, outfile): |
| 168 | i = file(infile,'r') |
| 169 | o = file(outfile,'w') |
| 170 | o.write(re.sub('\$\(VERSION\)',sysconfig.get_config_var('VERSION'),i.read())) |
| 171 | i.close() |
| 172 | o.close() |
| 173 | |
| 174 | def main(): |
| 175 | # turn off warnings when deprecated modules are imported |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 176 | ## import warnings |
| 177 | ## warnings.filterwarnings("ignore",category=DeprecationWarning) |
| 178 | setup(name = 'Documentation', |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 179 | version = '%d.%d' % sys.version_info[:2], |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 180 | cmdclass = {'install_data':AHVDocInstall, 'build':DocBuild}, |
| 181 | data_files = ['dummy'], |
| 182 | ) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 183 | |
| 184 | if __name__ == '__main__': |
| 185 | main() |