svgui/pyjs/build.py
changeset 1784 64beb9e9c749
parent 1783 3311eea28d56
child 1826 91796f408540
--- a/svgui/pyjs/build.py	Mon Aug 21 20:17:19 2017 +0000
+++ b/svgui/pyjs/build.py	Mon Aug 21 23:22:58 2017 +0300
@@ -7,11 +7,12 @@
 from os.path import join, dirname, basename, abspath, split, isfile, isdir
 from optparse import OptionParser
 import pyjs
+import time
 from cStringIO import StringIO
 try:
     # Python 2.5 and above
     from hashlib import md5
-except:
+except Exception:
     import md5
 import re
 
@@ -45,7 +46,7 @@
 
 
 # .cache.html files produces look like this
-CACHE_HTML_PAT=re.compile('^[a-z]*.[0-9a-f]{32}\.cache\.html$')
+CACHE_HTML_PAT = re.compile('^[a-z]*.[0-9a-f]{32}\.cache\.html$')
 
 # ok these are the three "default" library directories, containing
 # the builtins (str, List, Dict, ord, round, len, range etc.)
@@ -63,6 +64,7 @@
 def read_boilerplate(data_dir, filename):
     return open(join(data_dir, "builder/boilerplate", filename)).read()
 
+
 def copy_boilerplate(data_dir, filename, output_dir):
     filename = join(data_dir, "builder/boilerplate", filename)
     shutil.copy(filename, output_dir)
@@ -76,7 +78,7 @@
     names = os.listdir(src)
     try:
         os.mkdir(dst)
-    except:
+    except Exception:
         pass
 
     errors = []
@@ -103,6 +105,7 @@
     if errors:
         print errors
 
+
 def check_html_file(source_file, dest_path):
     """ Checks if a base HTML-file is available in the PyJamas
         output directory.
@@ -136,19 +139,17 @@
 </html>
 """
 
-    filename = os.path.split    ( source_file )[1]
-    mod_name = os.path.splitext ( filename    )[0]
-    file_name = os.path.join     ( dest_path, mod_name + '.html' )
+    filename = os.path.split(source_file)[1]
+    mod_name = os.path.splitext(filename)[0]
+    file_name = os.path.join(dest_path, mod_name + '.html')
 
     # if html file in output directory exists, leave it alone.
-    if os.path.exists ( file_name ):
+    if os.path.exists(file_name):
         return 0
 
-    if os.path.exists (
-        os.path.join ( dest_path, mod_name + '.css' ) ) :
+    if os.path.exists(os.path.join(dest_path, mod_name + '.css')):
         css = "<link rel='stylesheet' href='" + mod_name + ".css'>"
-    elif os.path.exists (
-        os.path.join ( dest_path, 'pyjamas_default.css' ) ) :
+    elif os.path.exists(os.path.join(dest_path, 'pyjamas_default.css')):
         css = "<link rel='stylesheet' href='pyjamas_default.css'>"
 
     else:
@@ -158,9 +159,9 @@
 
     base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css}
 
-    fh = open (file_name, 'w')
-    fh.write  (base_html)
-    fh.close  ()
+    fh = open(file_name, 'w')
+    fh.write(base_html)
+    fh.close()
 
     return 1
 
@@ -187,14 +188,14 @@
         except StandardError, e:
             print >>sys.stderr, "Exception creating output directory %s: %s" % (output, e)
 
-    ## public dir
+    # public dir
     for p in pyjs.path:
         pub_dir = join(p, 'public')
         if isdir(pub_dir):
             print "Copying: public directory of library %r" % p
             copytree_exists(pub_dir, output)
 
-    ## AppName.html - can be in current or public directory
+    # AppName.html - can be in current or public directory
     html_input_filename = app_name + ".html"
     html_output_filename = join(output, basename(html_input_filename))
     if os.path.isfile(html_input_filename):
@@ -203,7 +204,7 @@
                os.path.getmtime(html_output_filename):
             try:
                 shutil.copy(html_input_filename, html_output_filename)
-            except:
+            except Exception:
                 print >>sys.stderr, "Warning: Missing module HTML file %s" % html_input_filename
 
             print "Copying: %(html_input_filename)s" % locals()
@@ -211,7 +212,7 @@
     if check_html_file(html_input_filename, output):
         print >>sys.stderr, "Warning: Module HTML file %s has been auto-generated" % html_input_filename
 
-    ## pygwt.js
+    # pygwt.js
 
     print "Copying: pygwt.js"
 
@@ -222,7 +223,7 @@
 
     pygwt_js_output.close()
 
-    ## Images
+    # Images
 
     print "Copying: Images and History"
     copy_boilerplate(data_dir, "corner_dialog_topleft_black.png", output)
@@ -240,12 +241,11 @@
     copy_boilerplate(data_dir, "tree_white.gif", output)
     copy_boilerplate(data_dir, "history.html", output)
 
-
-    ## all.cache.html
+    # all.cache.html
     app_files = generateAppFiles(data_dir, js_includes, app_name, debug,
                                  output, dynamic, cache_buster, optimize)
 
-    ## AppName.nocache.html
+    # AppName.nocache.html
 
     print "Creating: %(app_name)s.nocache.html" % locals()
 
@@ -261,8 +261,8 @@
         print >> script_selectors, select_tmpl % (platform, file_prefix)
 
     print >>home_nocache_html_output, home_nocache_html_template % dict(
-        app_name = app_name,
-        script_selectors = script_selectors.getvalue(),
+        app_name=app_name,
+        script_selectors=script_selectors.getvalue(),
     )
 
     home_nocache_html_output.close()
@@ -287,8 +287,8 @@
     tmpl = read_boilerplate(data_dir, "all.cache.html")
     parser = pyjs.PlatformParser("platform")
     app_headers = ''
-    scripts = ['<script type="text/javascript" src="%s"></script>'%script \
-                                                  for script in js_includes]
+    scripts = ['<script type="text/javascript" src="%s"></script>' %
+               script for script in js_includes]
     app_body = '\n'.join(scripts)
 
     mod_code = {}
@@ -306,7 +306,7 @@
     # Second, (dynamic only), post-analyse the places where modules
     # haven't changed
     # Third, write everything out.
-    
+
     for platform in app_platforms:
 
         mod_code[platform] = {}
@@ -324,24 +324,24 @@
         app_translator = pyjs.AppTranslator(
             parser=parser, dynamic=dynamic, optimize=optimize)
         early_app_libs[platform], appcode = \
-                     app_translator.translate(None, is_app=False,
-                                              debug=debug,
-                                      library_modules=['dynamicajax.js',
-                                                    '_pyjs.js', 'sys',
-                                                     'pyjslib'])
+            app_translator.translate(None, is_app=False,
+                                     debug=debug,
+                                     library_modules=['dynamicajax.js',
+                                                      '_pyjs.js', 'sys',
+                                                      'pyjslib'])
         pover[platform].update(app_translator.overrides.items())
         for mname, name in app_translator.overrides.items():
             pd = overrides.setdefault(mname, {})
             pd[platform] = name
 
         print appcode
-        #mod_code[platform][app_name] = appcode
-
-        # platform.Module.cache.js 
+        # mod_code[platform][app_name] = appcode
+
+        # platform.Module.cache.js
 
         modules_done = ['pyjslib', 'sys', '_pyjs.js']
-        #modules_to_do = [app_name] + app_translator.library_modules
-        modules_to_do = [app_name] + app_translator.library_modules 
+        # modules_to_do = [app_name] + app_translator.library_modules
+        modules_to_do = [app_name] + app_translator.library_modules
 
         dependencies = {}
 
@@ -350,13 +350,13 @@
             sublist = add_subdeps(dependencies, d)
             modules_to_do += sublist
         deps = uniquify(deps)
-        #dependencies[app_name] = deps
+        # dependencies[app_name] = deps
 
         modules[platform] = modules_done + modules_to_do
 
         while modules_to_do:
 
-            #print "modules to do", modules_to_do
+            # print "modules to do", modules_to_do
 
             mn = modules_to_do.pop()
             mod_name = pyjs.strip_py(mn)
@@ -371,9 +371,9 @@
             parser.setPlatform(platform)
             mod_translator = pyjs.AppTranslator(parser=parser, optimize=optimize)
             mod_libs[platform][mod_name], mod_code[platform][mod_name] = \
-                              mod_translator.translate(mod_name,
-                                                  is_app=False,
-                                                  debug=debug)
+                mod_translator.translate(mod_name,
+                                         is_app=False,
+                                         debug=debug)
             pover[platform].update(mod_translator.overrides.items())
             for mname, name in mod_translator.overrides.items():
                 pd = overrides.setdefault(mname, {})
@@ -390,22 +390,22 @@
             while mod_name in deps:
                 deps.remove(mod_name)
 
-            #print
-            #print
-            #print "modname preadd:", mod_name, deps
-            #print
-            #print
+            # print
+            # print
+            # print "modname preadd:", mod_name, deps
+            # print
+            # print
             for d in deps:
                 sublist = add_subdeps(dependencies, d)
                 modules_to_do += sublist
             modules_to_do += add_subdeps(dependencies, mod_name)
-            #print "modname:", mod_name, deps
+            # print "modname:", mod_name, deps
             deps = uniquify(deps)
-            #print "modname:", mod_name, deps
+            # print "modname:", mod_name, deps
             dependencies[mod_name] = deps
-            
+
         # work out the dependency ordering of the modules
-    
+
         mod_levels[platform] = make_deps(None, dependencies, modules_done)
 
     # now write everything out
@@ -415,7 +415,7 @@
         early_app_libs_ = early_app_libs[platform]
         app_libs_ = app_libs[platform]
         app_code_ = app_code[platform]
-        #modules_ = filter_mods(app_name, modules[platform])
+        # modules_ = filter_mods(app_name, modules[platform])
         mods = flattenlist(mod_levels[platform])
         mods.reverse()
         modules_ = filter_mods(None, mods)
@@ -427,7 +427,7 @@
             mod_name = pyjs.strip_py(mod_name)
 
             override_name = "%s.%s" % (platform.lower(), mod_name)
-            if pover[platform].has_key(override_name):
+            if override_name in pover[platform]:
                 mod_cache_name = "%s.cache.js" % (override_name)
             else:
                 mod_cache_name = "%s.cache.js" % (mod_name)
@@ -457,13 +457,13 @@
                 mod_cache_html_output = StringIO()
 
             print >>mod_cache_html_output, mod_cache_html_template % dict(
-                mod_name = mod_name,
-                app_name = app_name,
-                modnames = modnames,
-                overrides = overnames,
-                mod_libs = mod_libs[platform][mod_name],
-                dynamic = dynamic,
-                mod_code = mod_code_,
+                mod_name=mod_name,
+                app_name=app_name,
+                modnames=modnames,
+                overrides=overnames,
+                mod_libs=mod_libs[platform][mod_name],
+                dynamic=dynamic,
+                mod_code=mod_code_,
             )
 
             if dynamic:
@@ -473,7 +473,7 @@
                 app_libs_ += mod_cache_html_output.read()
 
         # write out the dependency ordering of the modules
-    
+
         app_modnames = []
 
         for md in mod_levels[platform]:
@@ -489,30 +489,30 @@
         overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
         overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
 
-        #print "platform names", platform, overnames
-        #print pover
+        # print "platform names", platform, overnames
+        # print pover
 
         # now write app.allcache including dependency-ordered list of
         # library modules
 
         file_contents = all_cache_html_template % dict(
-            app_name = app_name,
-            early_app_libs = early_app_libs_,
-            app_libs = app_libs_,
-            app_code = app_code_,
-            app_body = app_body,
-            overrides = overnames,
-            platform = platform.lower(),
-            dynamic = dynamic,
-            app_modnames = app_modnames,
-            app_headers = app_headers
+            app_name=app_name,
+            early_app_libs=early_app_libs_,
+            app_libs=app_libs_,
+            app_code=app_code_,
+            app_body=app_body,
+            overrides=overnames,
+            platform=platform.lower(),
+            dynamic=dynamic,
+            app_modnames=app_modnames,
+            app_headers=app_headers
         )
         if cache_buster:
             digest = md5.new(file_contents).hexdigest()
             file_name = "%s.%s.%s" % (platform.lower(), app_name, digest)
         else:
             file_name = "%s.%s" % (platform.lower(), app_name)
-        file_name += ".cache.html" 
+        file_name += ".cache.html"
         out_path = join(output, file_name)
         out_file = open(out_path, 'w')
         out_file.write(file_contents)
@@ -523,49 +523,56 @@
 
     return app_files
 
+
 def flattenlist(ll):
     res = []
     for l in ll:
         res += l
     return res
 
-# creates sub-dependencies e.g. pyjamas.ui.Widget
-# creates pyjamas.ui.Widget, pyjamas.ui and pyjamas.
+
 def subdeps(m):
+    """
+    creates sub-dependencies e.g. pyjamas.ui.Widget
+    creates pyjamas.ui.Widget, pyjamas.ui and pyjamas.
+    """
     d = []
     m = m.split(".")
     for i in range(0, len(m)):
         d.append('.'.join(m[:i+1]))
     return d
 
-import time
 
 def add_subdeps(deps, mod_name):
     sd = subdeps(mod_name)
     if len(sd) == 1:
         return []
-    #print "subdeps", mod_name, sd
-    #print "deps", deps
+    # print "subdeps", mod_name, sd
+    # print "deps", deps
     res = []
     for i in range(0, len(sd)-1):
         parent = sd[i]
         child = sd[i+1]
-        l = deps.get(child, [])
-        l.append(parent)
-        deps[child] = l
+        k = deps.get(child, [])
+        k.append(parent)
+        deps[child] = k
         if parent not in res:
             res.append(parent)
-    #print deps
+    # print deps
     return res
 
-# makes unique and preserves list order
+
 def uniquify(md):
+    """
+    makes unique and preserves list order
+    """
     res = []
     for m in md:
         if m not in res:
             res.append(m)
     return res
 
+
 def filter_mods(app_name, md):
     while 'sys' in md:
         md.remove('sys')
@@ -578,6 +585,7 @@
 
     return uniquify(md)
 
+
 def filter_deps(app_name, deps):
 
     res = {}
@@ -588,18 +596,20 @@
         res[k] = mods
     return res
 
+
 def has_nodeps(mod, deps):
-    if not deps.has_key(mod) or not deps[mod]:
+    if mod not in deps or not deps[mod]:
         return True
     return False
 
+
 def nodeps_list(mod_list, deps):
     res = []
     for mod in mod_list:
         if has_nodeps(mod, deps):
             res.append(mod)
     return res
-        
+
 # this function takes a dictionary of dependent modules and
 # creates a list of lists.  the first list will be modules
 # that have no dependencies; the second list will be those
@@ -616,26 +626,26 @@
     if not mod_list:
         return []
 
-    #print mod_list
-    #print deps
+    # print mod_list
+    # print deps
 
     ordered_deps = []
     last_len = -1
     while deps:
         l_deps = len(deps)
-        #print l_deps
-        if l_deps==last_len:
+        # print l_deps
+        if l_deps == last_len:
             for m, dl in deps.items():
                 for d in dl:
                     if m in deps.get(d, []):
                         raise Exception('Circular Imports found: \n%s %s -> %s %s'
                                         % (m, dl, d, deps[d]))
-            #raise Exception('Could not calculate dependencies: \n%s' % deps)
+            # raise Exception('Could not calculate dependencies: \n%s' % deps)
             break
         last_len = l_deps
-        #print "modlist", mod_list
+        # print "modlist", mod_list
         nodeps = nodeps_list(mod_list, deps)
-        #print "nodeps", nodeps
+        # print "nodeps", nodeps
         mod_list = filter(lambda x: x not in nodeps, mod_list)
         newdeps = {}
         for k in deps.keys():
@@ -643,45 +653,86 @@
             depslist = filter(lambda x: x not in nodeps, depslist)
             if depslist:
                 newdeps[k] = depslist
-        #print "newdeps", newdeps
+        # print "newdeps", newdeps
         deps = newdeps
         ordered_deps.append(nodeps)
-        #time.sleep(0)
+        # time.sleep(0)
 
     if mod_list:
-        ordered_deps.append(mod_list) # last dependencies - usually the app(s)
+        ordered_deps.append(mod_list)  # last dependencies - usually the app(s)
 
     ordered_deps.reverse()
 
     return ordered_deps
 
+
 def main():
     global app_platforms
 
-    parser = OptionParser(usage = usage, version = version)
-    parser.add_option("-o", "--output", dest="output",
-        help="directory to which the webapp should be written")
-    parser.add_option("-j", "--include-js", dest="js_includes", action="append",
-        help="javascripts to load into the same frame as the rest of the script")
-    parser.add_option("-I", "--library_dir", dest="library_dirs",
-        action="append", help="additional paths appended to PYJSPATH")
-    parser.add_option("-D", "--data_dir", dest="data_dir",
-        help="path for data directory")
-    parser.add_option("-m", "--dynamic-modules", action="store_true",
-        dest="dynamic", default=False,
-        help="Split output into separate dynamically-loaded modules (experimental)")
-    parser.add_option("-P", "--platforms", dest="platforms",
-        help="platforms to build for, comma-separated")
-    parser.add_option("-d", "--debug", action="store_true", dest="debug")
-    parser.add_option("-O", "--optimize", action="store_true",
-                      dest="optimize", default=False,
-                      help="Optimize generated code (removes all print statements)",
-                      )
-    parser.add_option("-c", "--cache_buster", action="store_true",
-                  dest="cache_buster",
-        help="Enable browser cache-busting (MD5 hash added to output filenames)")
-
-    parser.set_defaults(output = "output", js_includes=[], library_dirs=[],
+    parser = OptionParser(usage=usage, version=version)
+    parser.add_option(
+        "-o",
+        "--output",
+        dest="output",
+        help="directory to which the webapp should be written"
+    )
+    parser.add_option(
+        "-j",
+        "--include-js",
+        dest="js_includes",
+        action="append",
+        help="javascripts to load into the same frame as the rest of the script"
+    )
+    parser.add_option(
+        "-I",
+        "--library_dir",
+        dest="library_dirs",
+        action="append",
+        help="additional paths appended to PYJSPATH"
+    )
+    parser.add_option(
+        "-D",
+        "--data_dir",
+        dest="data_dir",
+        help="path for data directory"
+    )
+    parser.add_option(
+        "-m",
+        "--dynamic-modules",
+        action="store_true",
+        dest="dynamic",
+        default=False,
+        help="Split output into separate dynamically-loaded modules (experimental)"
+    )
+    parser.add_option(
+        "-P",
+        "--platforms",
+        dest="platforms",
+        help="platforms to build for, comma-separated"
+    )
+    parser.add_option(
+        "-d",
+        "--debug",
+        action="store_true",
+        dest="debug"
+    )
+    parser.add_option(
+        "-O",
+        "--optimize",
+        action="store_true",
+        dest="optimize",
+        default=False,
+        help="Optimize generated code (removes all print statements)",
+    )
+    parser.add_option(
+        "-c",
+        "--cache_buster",
+        action="store_true",
+        dest="cache_buster",
+        help="Enable browser cache-busting (MD5 hash added to output filenames)"
+    )
+
+    parser.set_defaults(output="output", js_includes=[], library_dirs=[],
                         platforms=(','.join(app_platforms)),
                         data_dir=os.path.join(sys.prefix, "share/pyjamas"),
                         dynamic=False,
@@ -710,7 +761,7 @@
         pyjs.path.append(abspath(d))
 
     if options.platforms:
-       app_platforms = options.platforms.split(',')
+        app_platforms = options.platforms.split(',')
 
     # this is mostly for getting boilerplate stuff
     data_dir = os.path.abspath(options.data_dir)
@@ -719,6 +770,6 @@
           options.debug, options.dynamic and 1 or 0, data_dir,
           options.cache_buster, options.optimize)
 
+
 if __name__ == "__main__":
     main()
-