# HG changeset patch # User Paul Boddie # Date 1274832368 -7200 # Node ID 81cf24ef084c1179ea69d808f07315df56d344f9 # Parent 4cca4300a8eb6fc3f171cca98a41a78526f119ce Added support for installation in a published Web directory controlled by a .htaccess file, permitting script name overriding and copied htdocs content. Changed the static URL used for 1.8 (and earlier) installations, adopting the moin_static187 convention. Removed references to the old "private" site definition, no longer used. diff -r 4cca4300a8eb -r 81cf24ef084c moinsetup.py --- a/moinsetup.py Tue May 25 00:40:48 2010 +0200 +++ b/moinsetup.py Wed May 26 02:06:08 2010 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python -from os.path import abspath, exists, extsep, join, normpath, split +from os.path import abspath, exists, extsep, isdir, join, normpath, split from getpass import getpass import os import sys @@ -10,10 +10,13 @@ # Regular expressions for editing MoinMoin scripts and configuration files. def compile_definition(name): - return re.compile(r"^(\s*)#?(%s =).*$" % name, re.MULTILINE) + return re.compile(r"^(\s*)#*(%s =).*$" % name, re.MULTILINE) -moin_cgi_prefix = re.compile("^#sys.path.insert\(0, 'PREFIX.*$", re.MULTILINE) -moin_cgi_wikiconfig = re.compile("^#sys.path.insert\(0, '/path/to/wikiconfigdir.*$", re.MULTILINE) +moin_cgi_prefix = re.compile("^#sys\.path\.insert\(0, 'PREFIX.*$", re.MULTILINE) +moin_cgi_wikiconfig = re.compile("^#sys\.path\.insert\(0, '/path/to/wikiconfigdir.*$", re.MULTILINE) +moin_cgi_properties = compile_definition("properties") +moin_cgi_fix_script_name = compile_definition("fix_script_name") +moin_cgi_force_cgi = re.compile("^#(os.environ\['FCGI_FORCE_CGI'\].*)$", re.MULTILINE) # Templates for Apache site definitions. @@ -25,6 +28,22 @@ Alias %(static_url_path)s "%(htdocs_dir)s/" """ +# Limited hosting .htaccess definitions require the following settings to be +# configured in the main Apache configuration files: +# +# Options ExecCGI FollowSymLinks Indexes SymLinksIfOwnerMatch +# AllowOverride FileInfo Limit +# AddHandler cgi-script .cgi + +apache_htaccess_combined_mod_rewrite = """ +DirectoryIndex moin.cgi +RewriteEngine On +RewriteBase %(url_path)s +RewriteCond %%{REQUEST_FILENAME} !-f +RewriteCond %%{REQUEST_FILENAME} !-d +RewriteRule ^(.*) moin.cgi/$1 [PT,L,QSA] +""" + # Utility functions. def readfile(filename): @@ -204,13 +223,26 @@ self.moin_version = self.get_moin_version() - # 1.8: moin/share/moin/htdocs + # The static resources reside in different locations depending on the + # version of MoinMoin. Moreover, these resources may end up in a + # published directory for 1.8 installations where the Web server cannot + # be instructed to fetch the content from outside certain designated + # locations. + # 1.9: moin/lib/python2.x/site-packages/MoinMoin/web/static/htdocs if self.moin_version.startswith("1.9"): - self.htdocs_dir = join(self.prefix_site_packages, "MoinMoin", "web", "static", "htdocs") + self.htdocs_dir = self.htdocs_dir_source = join(self.prefix_site_packages, "MoinMoin", "web", "static", "htdocs") + + # 1.8: moin/share/moin/htdocs (optionally copied to a Web directory) + else: - self.htdocs_dir = join(self.instance_dir, "share", "moin", "htdocs") + self.htdocs_dir_source = join(self.instance_dir, "share", "moin", "htdocs") + + if self.limited_hosting(): + self.htdocs_dir = join(self.web_app_dir, self.get_static_identifier()) + else: + self.htdocs_dir = self.htdocs_dir_source def get_moin_version(self): @@ -242,6 +274,18 @@ finally: os.chdir(this_dir) + def get_static_identifier(self): + + "Return the static URL/directory identifier for the Wiki." + + return "moin_static%s" % self.moin_version.replace(".", "") + + def limited_hosting(self): + + "Return whether limited Web hosting is being used." + + return self.web_site_dir == self.web_app_dir + def ensure_directories(self): "Make sure that all the directories are available." @@ -326,6 +370,20 @@ else: status("Could not copy %s into installed Wiki." % d) + # Copy static Web data if appropriate. + + if not self.moin_version.startswith("1.9") and self.limited_hosting(): + + if not exists(self.htdocs_dir): + os.mkdir(self.htdocs_dir) + + for item in os.listdir(self.htdocs_dir_source): + path = join(self.htdocs_dir_source, item) + if isdir(path): + shutil.copytree(path, join(self.htdocs_dir, item)) + else: + shutil.copy(path, join(self.htdocs_dir, item)) + def configure_moin(self): "Edit the Wiki configuration file." @@ -342,7 +400,11 @@ self.static_url_path = self.url_path url_prefix_static = "%r + url_prefix_static" % self.static_url_path else: - self.static_url_path = self.url_path + "-static" + # Add the static identifier to the URL path. For example: + # / -> /moin_static187 + # /hgwiki -> /hgwiki/moin_static187 + + self.static_url_path = self.url_path + "/" + self.get_static_identifier() url_prefix_static = "%r" % self.static_url_path # Copy the Wiki configuration file from the distribution. @@ -405,7 +467,11 @@ # NOTE: CGI only so far. # NOTE: Permissions should be checked. - moin_cgi = join(self.instance_dir, "share", "moin", "server", "moin.cgi") + if self.moin_version.startswith("1.9"): + moin_cgi = join(self.instance_dir, "share", "moin", "server", "moin.fcgi") + else: + moin_cgi = join(self.instance_dir, "share", "moin", "server", "moin.cgi") + moin_cgi_installed = join(self.web_app_dir, "moin.cgi") status("Editing moin.cgi script from %s..." % moin_cgi) @@ -414,6 +480,16 @@ s = moin_cgi_prefix.sub("sys.path.insert(0, %r)" % self.prefix_site_packages, s) s = moin_cgi_wikiconfig.sub("sys.path.insert(0, %r)" % self.conf_dir, s) + # Handle differences in script names when using limited hosting with + # URL rewriting. + + if self.limited_hosting(): + if self.moin_version.startswith("1.9"): + s = moin_cgi_fix_script_name.sub(r"\1\2 %r" % self.url_path, s) + s = moin_cgi_force_cgi.sub(r"\1", s) + else: + s = moin_cgi_properties.sub(r"\1\2 %r" % {"script_name" : self.url_path}, s) + writefile(moin_cgi_installed, s) os.system("chmod a+rx '%s'" % moin_cgi_installed) @@ -447,15 +523,26 @@ # NOTE: Using local namespace for substitution. - site_def = join(self.web_site_dir, self.site_name) - site_def_private = join(self.web_site_dir, "%s-private" % self.site_name) + # Where the site definitions and applications directories are different, + # use a normal site definition. - status("Writing Apache site definitions to %s and %s..." % (site_def, site_def_private)) + if not self.limited_hosting(): + + site_def = join(self.web_site_dir, self.site_name) + + s = apache_site % self.__dict__ - s = apache_site % self.__dict__ + if not self.moin_version.startswith("1.9"): + s += apache_site_extra_moin18 % self.__dict__ + + # Otherwise, use an .htaccess file. - if not self.moin_version.startswith("1.9"): - s += apache_site_extra_moin18 % self.__dict__ + else: + site_def = join(self.web_site_dir, ".htaccess") + + s = apache_htaccess_combined_mod_rewrite % self.__dict__ + + status("Writing Apache site definitions to %s..." % site_def) writefile(site_def, s)