paulb@659 | 1 | #!/usr/bin/env jython |
paulb@573 | 2 | |
paulb@573 | 3 | "A simple Jython-based installer for the Web applications." |
paulb@573 | 4 | |
paulb@573 | 5 | import os |
paulb@573 | 6 | |
paulb@573 | 7 | def copy_file(source, destination): |
paulb@573 | 8 | |
paulb@573 | 9 | """ |
paulb@573 | 10 | Copy a file from 'source' to 'destination'. Note that 'destination' must |
paulb@573 | 11 | include the name of the file - it cannot be a directory name. |
paulb@573 | 12 | """ |
paulb@573 | 13 | |
paulb@573 | 14 | print "Copying", source, "to", destination |
paulb@573 | 15 | |
paulb@573 | 16 | # Do things by the book, since Jython/Java won't copy the file contents in |
paulb@573 | 17 | # all cases presumably due to finalisation issues. |
paulb@573 | 18 | |
paulb@573 | 19 | f = open(source, "rb") |
paulb@573 | 20 | s = f.read() |
paulb@573 | 21 | f.close() |
paulb@573 | 22 | |
paulb@573 | 23 | f = open(destination, "wb") |
paulb@573 | 24 | f.write(s) |
paulb@573 | 25 | f.close() |
paulb@573 | 26 | |
paulb@573 | 27 | def recurse(dirs_and_files, dirname, names): |
paulb@573 | 28 | |
paulb@573 | 29 | """ |
paulb@573 | 30 | A recursive directory and file collector for os.path.walk. The provided |
paulb@573 | 31 | 'dirs_and_files' list must contain two lists (one for directory names, one |
paulb@573 | 32 | for filenames). The 'dirname' and 'names' parameters are supplied by the |
paulb@573 | 33 | os.path.walk mechanism. |
paulb@573 | 34 | """ |
paulb@573 | 35 | |
paulb@573 | 36 | if dirname.endswith("/CVS"): |
paulb@573 | 37 | return |
paulb@573 | 38 | dirs_and_files[0].append(dirname) |
paulb@573 | 39 | for name in names: |
paulb@573 | 40 | if os.path.isfile(os.path.join(dirname, name)): |
paulb@573 | 41 | dirs_and_files[1].append(os.path.join(dirname, name)) |
paulb@573 | 42 | |
paulb@573 | 43 | def copy_directory(source, destination): |
paulb@573 | 44 | |
paulb@573 | 45 | """ |
paulb@573 | 46 | Copy a directory found at 'source' in the filesystem to the 'destination'. |
paulb@573 | 47 | Note that 'destination' is the parent directory of the newly created |
paulb@573 | 48 | directory. |
paulb@573 | 49 | """ |
paulb@573 | 50 | |
paulb@573 | 51 | # Remove trailing directory separators. |
paulb@573 | 52 | |
paulb@573 | 53 | source = os.path.normpath(source) |
paulb@573 | 54 | prefix = os.path.split(source)[0] |
paulb@573 | 55 | dirs_and_files = [[], []] |
paulb@573 | 56 | os.path.walk(source, recurse, dirs_and_files) |
paulb@573 | 57 | |
paulb@573 | 58 | for dirname in dirs_and_files[0]: |
paulb@573 | 59 | |
paulb@573 | 60 | # Remove the prefix from the name and create the object under the destination. |
paulb@573 | 61 | # NOTE: Joining "" to the path in Jython doesn't add the path separator. |
paulb@573 | 62 | |
paulb@573 | 63 | new_dirname = dirname[len(os.path.join(prefix, "x")) - 1:] |
paulb@573 | 64 | print "Making", new_dirname, "under", destination |
paulb@573 | 65 | os.mkdir(os.path.join(destination, new_dirname)) |
paulb@573 | 66 | |
paulb@573 | 67 | for filename in dirs_and_files[1]: |
paulb@573 | 68 | |
paulb@573 | 69 | # Remove the prefix from the name and create the object under the destination. |
paulb@573 | 70 | # NOTE: Joining "" to the path in Jython doesn't add the path separator. |
paulb@573 | 71 | |
paulb@573 | 72 | new_filename = filename[len(os.path.join(prefix, "x")) - 1:] |
paulb@573 | 73 | copy_file(filename, os.path.join(destination, new_filename)) |
paulb@573 | 74 | |
paulb@573 | 75 | def get_appname(handler): |
paulb@573 | 76 | return os.path.split(os.path.splitext(handler)[0])[1] |
paulb@573 | 77 | |
paulb@659 | 78 | def make_app(handler, appdir, webstack_home, jython_cachedir, web_xml_template_name): |
paulb@573 | 79 | |
paulb@573 | 80 | """ |
paulb@573 | 81 | Make the application directory from the given 'handler', application |
paulb@573 | 82 | directory 'appdir', the 'webstack_home' where the WebStack package can be |
paulb@659 | 83 | found, the 'jython_cachedir' where Jython classes are cached, and the |
paulb@659 | 84 | deployment descriptor with the given 'web_xml_template_name'. |
paulb@573 | 85 | """ |
paulb@573 | 86 | |
paulb@573 | 87 | appname = get_appname(handler) |
paulb@573 | 88 | print "Making", appname |
paulb@573 | 89 | |
paulb@573 | 90 | os.mkdir(appname) |
paulb@573 | 91 | os.mkdir(os.path.join(appname, "WEB-INF")) |
paulb@573 | 92 | os.mkdir(os.path.join(appname, "WEB-INF", "jython")) |
paulb@573 | 93 | os.mkdir(os.path.join(appname, "WEB-INF", "lib")) |
paulb@573 | 94 | |
paulb@573 | 95 | # Copy the Jython runtime. |
paulb@573 | 96 | |
paulb@573 | 97 | jython_home = sys.exec_prefix |
paulb@573 | 98 | copy_file(os.path.join(jython_home, "jython.jar"), |
paulb@573 | 99 | os.path.join(appname, "WEB-INF", "lib", "jython.jar")) |
paulb@573 | 100 | |
paulb@573 | 101 | # Copy the special PyServlet classes. |
paulb@573 | 102 | |
paulb@573 | 103 | copy_directory(os.path.join(webstack_home, "tools", "JavaServlet", "classes"), |
paulb@573 | 104 | os.path.join(appname, "WEB-INF")) |
paulb@573 | 105 | |
paulb@573 | 106 | # Copy the WebStack package. |
paulb@573 | 107 | |
paulb@573 | 108 | copy_directory(os.path.join(webstack_home, "WebStack"), |
paulb@573 | 109 | os.path.join(appname, "WEB-INF", "jython")) |
paulb@573 | 110 | |
paulb@573 | 111 | # Copy the application itself. |
paulb@573 | 112 | |
paulb@573 | 113 | copy_directory(appdir, os.path.join(appname, "WEB-INF", "jython")) |
paulb@573 | 114 | |
paulb@573 | 115 | # Copy the handler. |
paulb@573 | 116 | |
paulb@573 | 117 | handler_filename = os.path.split(handler)[1] |
paulb@573 | 118 | copy_file(handler, os.path.join(appname, handler_filename)) |
paulb@573 | 119 | |
paulb@659 | 120 | # Find additional Jython paths. |
paulb@659 | 121 | |
paulb@659 | 122 | jython_paths = [] |
paulb@659 | 123 | for path in sys.path: |
paulb@659 | 124 | if path.startswith(jython_home) and path != os.path.join(jython_home, "Lib"): |
paulb@659 | 125 | jython_paths.append(path) |
paulb@659 | 126 | |
paulb@659 | 127 | jython_path = ":".join(jython_paths) |
paulb@659 | 128 | |
paulb@659 | 129 | # Create the cache directory if necessary. |
paulb@659 | 130 | |
paulb@659 | 131 | if not os.path.exists(jython_cachedir): |
paulb@659 | 132 | os.mkdir(jython_cachedir) |
paulb@659 | 133 | |
paulb@573 | 134 | # Configure the deployment descriptor. |
paulb@573 | 135 | |
paulb@573 | 136 | f = open(os.path.join(webstack_home, "tools", "JavaServlet", web_xml_template_name)) |
paulb@573 | 137 | web_xml = f.read() |
paulb@573 | 138 | f.close() |
paulb@659 | 139 | web_xml = web_xml % (jython_home, jython_path, jython_cachedir, handler_filename) |
paulb@573 | 140 | |
paulb@573 | 141 | # Write the deployment descriptor. |
paulb@573 | 142 | |
paulb@573 | 143 | f = open(os.path.join(appname, "WEB-INF", "web.xml"), "w") |
paulb@573 | 144 | f.write(web_xml) |
paulb@573 | 145 | f.close() |
paulb@573 | 146 | |
paulb@573 | 147 | if __name__ == "__main__": |
paulb@573 | 148 | import sys |
paulb@573 | 149 | if len(sys.argv) < 5: |
paulb@573 | 150 | print "Please specify..." |
paulb@573 | 151 | print " * The location of the application handler." |
paulb@573 | 152 | print " eg. .../WebStack-x.y/examples/JavaServlet/SimpleApp.py" |
paulb@573 | 153 | print " * The location of the application." |
paulb@573 | 154 | print " eg. .../WebStack-x.y/examples/Common/Simple" |
paulb@573 | 155 | print " * The location of the WebStack package distribution or where" |
paulb@573 | 156 | print " WebStack documentation and extras have been installed." |
paulb@573 | 157 | print " eg. .../WebStack-x.y" |
paulb@573 | 158 | print " eg. /usr/share/doc/python2.4-webstack" |
paulb@659 | 159 | print " * The location of the Jython cache directory." |
paulb@659 | 160 | print " eg. /home/paulb/.jython-cache" |
paulb@573 | 161 | print " * The name of the deployment descriptor template." |
paulb@573 | 162 | print " eg. web.xml" |
paulb@573 | 163 | print "You can also specify some additional libraries for the application..." |
paulb@573 | 164 | print " eg. $CATALINA_HOME/common/lib/activation.jar" |
paulb@573 | 165 | print " $CATALINA_HOME/common/lib/mail.jar" |
paulb@573 | 166 | sys.exit(1) |
paulb@573 | 167 | |
paulb@573 | 168 | print "Making application directory..." |
paulb@659 | 169 | make_app(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]) |
paulb@573 | 170 | |
paulb@659 | 171 | if len(sys.argv) > 6: |
paulb@573 | 172 | print "Copying additional libraries..." |
paulb@573 | 173 | appname = get_appname(sys.argv[1]) |
paulb@659 | 174 | for library in sys.argv[6:]: |
paulb@573 | 175 | library_dir, library_name = os.path.split(library) |
paulb@573 | 176 | library_dest = os.path.join(appname, "WEB-INF", "lib", library_name) |
paulb@573 | 177 | copy_file(library, library_dest) |
paulb@573 | 178 | |
paulb@573 | 179 | print "Now copy or move the application directory to your servlet container." |
paulb@573 | 180 | |
paulb@573 | 181 | # vim: tabstop=4 expandtab shiftwidth=4 |