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 |
| 35 | self.doc_version = '2.2.1' |
| 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 | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 49 | self.mkpath(self.build_html) |
| 50 | os.chdir(self.build_base) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 51 | self.spawn('curl','-O', 'http://www.python.org/ftp/python/doc/%s/html-%s.tgz' % (self.doc_version,self.doc_version)) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 52 | os.chdir(workdir) |
| 53 | os.chdir(self.build_html) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 54 | self.spawn('tar', '-xzf', '../html-%s.tgz' % self.doc_version) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 55 | os.chdir(workdir) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 56 | |
Jack Jansen | f68043c | 2003-02-14 12:47:14 +0000 | [diff] [blame] | 57 | def buildDocsFromSource(self): |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 58 | srcdir = '../../..' |
| 59 | docdir = os.path.join(srcdir, 'Doc') |
| 60 | htmldir = os.path.join(docdir, 'html') |
| 61 | spawn(('make','--directory', docdir, 'html'), 1, self.verbose, self.dry_run) |
| 62 | self.mkpath(self.build_html) |
| 63 | copy_tree(htmldir, self.build_html) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 64 | |
| 65 | def ensureHtml(self): |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 66 | if not os.path.exists(self.build_html): |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 67 | if self.download: |
| 68 | self.downloadDocs() |
| 69 | else: |
| 70 | self.buildDocsFromSource() |
| 71 | |
| 72 | def hackIndex(self): |
| 73 | ind_html = 'index.html' |
| 74 | #print 'self.build_dest =', self.build_dest |
| 75 | hackedIndex = file(os.path.join(self.build_dest, ind_html),'w') |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 76 | origIndex = file(os.path.join(self.build_html,ind_html)) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 77 | r = re.compile('<style type="text/css">.*</style>', re.DOTALL) |
| 78 | hackedIndex.write(r.sub('<META NAME="AppleTitle" CONTENT="Python Help">',origIndex.read())) |
| 79 | |
| 80 | def hackFile(self,d,f): |
| 81 | origPath = os.path.join(d,f) |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 82 | assert(origPath[:len(self.build_html)] == self.build_html) |
| 83 | 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] | 84 | (name, ext) = os.path.splitext(f) |
| 85 | if os.path.isdir(origPath): |
| 86 | self.mkpath(outPath) |
| 87 | elif ext == '.html': |
| 88 | if self.verbose: print 'hacking %s to %s' % (origPath,outPath) |
| 89 | hackedFile = file(outPath, 'w') |
| 90 | origFile = file(origPath,'r') |
| 91 | hackedFile.write(self.r.sub('<dl><dt><dd>', origFile.read())) |
| 92 | else: |
| 93 | copy_file(origPath, outPath) |
| 94 | |
| 95 | def hackHtml(self): |
| 96 | self.r = re.compile('<dl><dd>') |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 97 | os.path.walk(self.build_html, self.visit, None) |
| 98 | |
| 99 | def visit(self, dummy, dirname, filenames): |
| 100 | for f in filenames: |
| 101 | self.hackFile(dirname, f) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 102 | |
| 103 | def makeHelpIndex(self): |
| 104 | app = '/Developer/Applications/Apple Help Indexing Tool.app' |
| 105 | self.spawn('open', '-a', app , self.build_dest) |
| 106 | print "Please wait until Apple Help Indexing Tool finishes before installing" |
| 107 | |
| 108 | def run(self): |
| 109 | self.ensure_finalized() |
| 110 | self.ensureHtml() |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 111 | if not os.path.isdir(self.build_html): |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 112 | raise RuntimeError, \ |
| 113 | "Can't find source folder for documentation." |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 114 | self.mkpath(self.build_dest) |
| 115 | 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] | 116 | self.mkpath(self.build_dest) |
| 117 | self.hackHtml() |
| 118 | self.hackIndex() |
| 119 | self.makeHelpIndex() |
| 120 | |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 121 | class AHVDocInstall(Command): |
| 122 | description = "install Apple Help Viewer html files" |
| 123 | user_options = [('install-doc=', 'd', |
| 124 | 'directory to install HTML tree'), |
| 125 | ('root=', None, |
| 126 | "install everything relative to this alternate root directory"), |
| 127 | ] |
| 128 | |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 129 | def initialize_options(self): |
| 130 | self.build_dest = None |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 131 | self.install_doc = None |
| 132 | self.prefix = None |
| 133 | self.root = None |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 134 | |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 135 | def finalize_options(self): |
| 136 | self.set_undefined_options('install', |
| 137 | ('prefix', 'prefix'), |
| 138 | ('root', 'root')) |
| 139 | # import pdb ; pdb.set_trace() |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 140 | build_cmd = self.get_finalized_command('build') |
| 141 | if self.build_dest == None: |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 142 | build_cmd = self.get_finalized_command('build') |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 143 | self.build_dest = build_cmd.build_dest |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 144 | if self.install_doc == None: |
| 145 | self.install_doc = os.path.join(self.prefix, 'Resources/English.lproj/Documentation') |
| 146 | print 'INSTALL', self.build_dest, '->', self.install_doc |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 147 | |
| 148 | def run(self): |
| 149 | self.finalize_options() |
| 150 | self.ensure_finalized() |
| 151 | print "Running Installer" |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 152 | instloc = self.install_doc |
| 153 | if self.root: |
| 154 | instloc = change_root(self.root, instloc) |
| 155 | self.mkpath(instloc) |
| 156 | copy_tree(self.build_dest, instloc) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 157 | print "Installation complete" |
| 158 | |
| 159 | def mungeVersion(infile, outfile): |
| 160 | i = file(infile,'r') |
| 161 | o = file(outfile,'w') |
| 162 | o.write(re.sub('\$\(VERSION\)',sysconfig.get_config_var('VERSION'),i.read())) |
| 163 | i.close() |
| 164 | o.close() |
| 165 | |
| 166 | def main(): |
| 167 | # turn off warnings when deprecated modules are imported |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 168 | ## import warnings |
| 169 | ## warnings.filterwarnings("ignore",category=DeprecationWarning) |
| 170 | setup(name = 'Documentation', |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 171 | version = '%d.%d' % sys.version_info[:2], |
Jack Jansen | d2c684f | 2003-02-14 23:46:22 +0000 | [diff] [blame] | 172 | cmdclass = {'install_data':AHVDocInstall, 'build':DocBuild}, |
| 173 | data_files = ['dummy'], |
| 174 | ) |
Jack Jansen | 278a3a2 | 2002-08-28 22:22:10 +0000 | [diff] [blame] | 175 | |
| 176 | if __name__ == '__main__': |
| 177 | main() |