PageRenderTime 196ms CodeModel.GetById 183ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/builder/build.py

http://pyjamas.googlecode.com/
Python | 216 lines | 211 code | 4 blank | 1 comment | 6 complexity | cc876a7bbc0d661d5390ea4ba949a9bf MD5 | raw file
  1#!/usr/bin/env python
  2
  3import sys
  4import os
  5import shutil
  6from os.path import join, dirname, basename
  7from optparse import OptionParser
  8
  9sys.path.append(join(dirname(__file__), "../pyjs"))
 10import pyjs
 11
 12
 13usage = """
 14  usage: %prog [options] <application name>
 15
 16This is the command line builder for the pyjamas project, which can be used to 
 17build Ajax applications from Python.
 18For more information, see the website at http://pyjamas.pyworks.org/
 19"""
 20
 21# GWT1.2 Impl  | GWT1.2 Output         | Pyjamas 0.2 Platform | Pyjamas 0.2 Output
 22# -------------+-----------------------+----------------------+----------------------
 23# IE6          | ie6                   | IE6                  | ie6
 24# Opera        | opera                 | Opera                | opera
 25# Safari       | safari                | Safari               | safari
 26# --           | gecko1_8              | Mozilla              | mozilla
 27# --           | gecko                 | OldMoz               | oldmoz
 28# Standard     | all                   | (default code)       | all
 29# Mozilla      | gecko1_8, gecko       | --                   | --
 30# Old          | safari, gecko, opera  | --                   | --
 31
 32version = "%prog pyjamas version 2006-08-19"
 33app_platforms = ['IE6', 'Opera', 'OldMoz', 'Safari', 'Mozilla']
 34app_library_dirs = ["../library/builtins", "../library", "../addons"]
 35
 36
 37def read_boilerplate(filename):
 38    return open(join(dirname(__file__), "boilerplate", filename)).read()
 39
 40
 41def copy_boilerplate(filename, output_dir):
 42    filename = join(dirname(__file__), "boilerplate", filename)
 43    shutil.copy(filename, output_dir)
 44
 45
 46# taken and modified from python2.4
 47def copytree_exists(src, dst, symlinks=False):
 48    if not os.path.exists(src):
 49        return
 50    
 51    names = os.listdir(src)
 52    try:
 53        os.mkdir(dst)
 54    except:
 55        pass
 56
 57    errors = []
 58    for name in names:
 59        if name.startswith('.svn'):
 60            continue
 61
 62        srcname = os.path.join(src, name)
 63        dstname = os.path.join(dst, name)
 64        try:
 65            if symlinks and os.path.islink(srcname):
 66                linkto = os.readlink(srcname)
 67                os.symlink(linkto, dstname)
 68            elif os.path.isdir(srcname):
 69                copytree_exists(srcname, dstname, symlinks)
 70            else:
 71                shutil.copy2(srcname, dstname)
 72        except (IOError, os.error), why:
 73            errors.append((srcname, dstname, why))
 74    if errors:
 75        print errors
 76
 77
 78def build(app_name, output="output", js_includes=()):
 79    dir_public = "public"
 80
 81    print "Building '%(app_name)s' to output directory '%(output)s'" % locals()
 82
 83    # check the output directory
 84    if os.path.exists(output) and not os.path.isdir(output):
 85        print >>sys.stderr, "Output destination %s exists and is not a directory" % output
 86        return
 87    if not os.path.isdir(output):
 88        try:
 89            print "Creating output directory"
 90            os.mkdir(output)
 91        except StandardError, e:
 92            print >>sys.stderr, "Exception creating output directory %s: %s" % (output, e)
 93
 94    # Check that the app_name file exists
 95    py_app_name = app_name[:]
 96    if py_app_name[-2:] != "py":
 97        py_app_name = app_name + ".py"
 98    if app_name[-3:] == ".py":
 99        app_name = app_name[:-3]
100    app_basename = basename(app_name)
101    
102    if not os.path.isfile(py_app_name):
103        print >>sys.stderr, "Could not find %s" % py_app_name
104        return
105
106    ## public dir
107    print "Copying: public directory"
108    copytree_exists(dir_public, output)
109
110    ## AppName.html - can be in current or public directory
111    html_input_filename = app_name + ".html"
112    html_output_filename = join(output, basename(html_input_filename))
113    if os.path.isfile(html_input_filename):
114        if not os.path.isfile(html_output_filename) or os.path.getmtime(html_input_filename) > os.path.getmtime(html_output_filename):
115            try:
116                shutil.copy(html_input_filename, html_output_filename)
117            except:
118                print >>sys.stderr, "Warning: Missing module HTML file %s" % html_input_filename
119    
120            print "Copying: %(html_input_filename)s" % locals()
121
122    ## pygwt.js
123    
124    print "Copying: pygwt.js"
125
126    pygwt_js_template = read_boilerplate("pygwt.js")
127    pygwt_js_output = open(join(output, "pygwt.js"), "w")
128    
129    print >>pygwt_js_output, pygwt_js_template
130    
131    pygwt_js_output.close()
132
133    ## Images
134    
135    print "Copying: Images and History"
136    copy_boilerplate("tree_closed.gif", output)
137    copy_boilerplate("tree_open.gif", output)
138    copy_boilerplate("tree_white.gif", output)
139    copy_boilerplate("history.html", output)
140    
141    ## AppName.nocache.html
142    
143    print "Creating: %(app_basename)s.nocache.html" % locals()
144    
145    home_nocache_html_template = read_boilerplate("home.nocache.html")
146    home_nocache_html_output = open(join(output, app_basename + ".nocache.html"), "w")
147    
148    print >>home_nocache_html_output, home_nocache_html_template % dict(
149        app_name = app_basename,
150        safari_js = "Safari",
151        ie6_js = "IE6",
152        oldmoz_js = "OldMoz",
153        moz_js = "Mozilla",
154        opera_js = "Opera",
155    )
156    
157    home_nocache_html_output.close()
158
159    ## all.cache.html
160
161    all_cache_html_template = read_boilerplate("all.cache.html")
162
163    parser = pyjs.PlatformParser("platform")
164    app_headers = ''
165    app_body = '\n'.join(['<script type="text/javascript" src="%s"></script>'%script for script in js_includes])
166
167    for platform in app_platforms:
168        all_cache_name = platform + ".cache.html"
169        print "Creating: " + all_cache_name
170
171        parser.setPlatform(platform)
172        app_translator = pyjs.AppTranslator(app_library_dirs, parser)
173        app_libs = app_translator.translateLibraries(['pyjslib'])
174        app_code = app_translator.translate(app_name)
175        all_cache_html_output = open(join(output, all_cache_name), "w")
176        
177        print >>all_cache_html_output, all_cache_html_template % dict(
178            app_name = app_basename,
179            app_libs = app_libs,
180            app_code = app_code,
181            app_body = app_body,
182            app_headers = app_headers
183        )
184        
185        all_cache_html_output.close()
186
187    ## Done.
188    
189    print "Done. You can run your app by opening '%(html_output_filename)s' in a browser" % locals()
190
191def main():
192    global app_library_dirs
193    global app_platforms
194    parser = OptionParser(usage = usage, version = version)
195    parser.add_option("-o", "--output", dest="output",
196        help="directory to which the webapp should be written")
197    parser.add_option("-j", "--include-js", dest="js_includes", action="append",
198        help="javascripts to load into the same frame as the rest of the script")
199    parser.add_option("-I", "--library_dir", dest="library_dirs", action="append",
200        help="paths to search for python modules")
201    parser.add_option("-P", "--platforms", dest="platforms",
202        help="platforms to build for, comma-seperated")
203    parser.set_defaults(output = "output", js_includes=[], library_dirs=[], platforms=(','.join(app_platforms)))
204    (options, args) = parser.parse_args()
205    if len(args) != 1:
206        parser.error("incorrect number of arguments")
207    
208    app_library_dirs += options.library_dirs
209    if options.platforms:
210       app_platforms = options.platforms.split(',')
211    build(args[0], options.output, options.js_includes)
212
213
214if __name__ == "__main__":
215    main()
216