moinsetup

Changeset

14:81cf24ef084c
2010-05-26 Paul Boddie raw files shortlog changelog graph 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.
moinsetup.py (file)
     1.1 --- a/moinsetup.py	Tue May 25 00:40:48 2010 +0200
     1.2 +++ b/moinsetup.py	Wed May 26 02:06:08 2010 +0200
     1.3 @@ -1,6 +1,6 @@
     1.4  #!/usr/bin/env python
     1.5  
     1.6 -from os.path import abspath, exists, extsep, join, normpath, split
     1.7 +from os.path import abspath, exists, extsep, isdir, join, normpath, split
     1.8  from getpass import getpass
     1.9  import os
    1.10  import sys
    1.11 @@ -10,10 +10,13 @@
    1.12  # Regular expressions for editing MoinMoin scripts and configuration files.
    1.13  
    1.14  def compile_definition(name):
    1.15 -    return re.compile(r"^(\s*)#?(%s =).*$" % name, re.MULTILINE)
    1.16 +    return re.compile(r"^(\s*)#*(%s =).*$" % name, re.MULTILINE)
    1.17  
    1.18 -moin_cgi_prefix                 = re.compile("^#sys.path.insert\(0, 'PREFIX.*$", re.MULTILINE)
    1.19 -moin_cgi_wikiconfig             = re.compile("^#sys.path.insert\(0, '/path/to/wikiconfigdir.*$", re.MULTILINE)
    1.20 +moin_cgi_prefix          = re.compile("^#sys\.path\.insert\(0, 'PREFIX.*$", re.MULTILINE)
    1.21 +moin_cgi_wikiconfig      = re.compile("^#sys\.path\.insert\(0, '/path/to/wikiconfigdir.*$", re.MULTILINE)
    1.22 +moin_cgi_properties      = compile_definition("properties")
    1.23 +moin_cgi_fix_script_name = compile_definition("fix_script_name")
    1.24 +moin_cgi_force_cgi       = re.compile("^#(os.environ\['FCGI_FORCE_CGI'\].*)$", re.MULTILINE)
    1.25  
    1.26  # Templates for Apache site definitions.
    1.27  
    1.28 @@ -25,6 +28,22 @@
    1.29  Alias %(static_url_path)s "%(htdocs_dir)s/"
    1.30  """
    1.31  
    1.32 +# Limited hosting .htaccess definitions require the following settings to be
    1.33 +# configured in the main Apache configuration files:
    1.34 +#
    1.35 +# Options ExecCGI FollowSymLinks Indexes SymLinksIfOwnerMatch
    1.36 +# AllowOverride FileInfo Limit
    1.37 +# AddHandler cgi-script .cgi
    1.38 +
    1.39 +apache_htaccess_combined_mod_rewrite = """
    1.40 +DirectoryIndex moin.cgi
    1.41 +RewriteEngine On
    1.42 +RewriteBase %(url_path)s
    1.43 +RewriteCond %%{REQUEST_FILENAME} !-f
    1.44 +RewriteCond %%{REQUEST_FILENAME} !-d
    1.45 +RewriteRule ^(.*) moin.cgi/$1 [PT,L,QSA]
    1.46 +"""
    1.47 +
    1.48  # Utility functions.
    1.49  
    1.50  def readfile(filename):
    1.51 @@ -204,13 +223,26 @@
    1.52  
    1.53          self.moin_version = self.get_moin_version()
    1.54  
    1.55 -        # 1.8: moin/share/moin/htdocs
    1.56 +        # The static resources reside in different locations depending on the
    1.57 +        # version of MoinMoin. Moreover, these resources may end up in a
    1.58 +        # published directory for 1.8 installations where the Web server cannot
    1.59 +        # be instructed to fetch the content from outside certain designated
    1.60 +        # locations.
    1.61 +
    1.62          # 1.9: moin/lib/python2.x/site-packages/MoinMoin/web/static/htdocs
    1.63  
    1.64          if self.moin_version.startswith("1.9"):
    1.65 -            self.htdocs_dir = join(self.prefix_site_packages, "MoinMoin", "web", "static", "htdocs")
    1.66 +            self.htdocs_dir = self.htdocs_dir_source = join(self.prefix_site_packages, "MoinMoin", "web", "static", "htdocs")
    1.67 +
    1.68 +        # 1.8: moin/share/moin/htdocs (optionally copied to a Web directory)
    1.69 +
    1.70          else:
    1.71 -            self.htdocs_dir = join(self.instance_dir, "share", "moin", "htdocs")
    1.72 +            self.htdocs_dir_source = join(self.instance_dir, "share", "moin", "htdocs")
    1.73 +
    1.74 +            if self.limited_hosting():
    1.75 +                self.htdocs_dir = join(self.web_app_dir, self.get_static_identifier())
    1.76 +            else:
    1.77 +                self.htdocs_dir = self.htdocs_dir_source
    1.78  
    1.79      def get_moin_version(self):
    1.80  
    1.81 @@ -242,6 +274,18 @@
    1.82          finally:
    1.83              os.chdir(this_dir)
    1.84  
    1.85 +    def get_static_identifier(self):
    1.86 +
    1.87 +        "Return the static URL/directory identifier for the Wiki."
    1.88 +
    1.89 +        return "moin_static%s" % self.moin_version.replace(".", "")
    1.90 +
    1.91 +    def limited_hosting(self):
    1.92 +
    1.93 +        "Return whether limited Web hosting is being used."
    1.94 +
    1.95 +        return self.web_site_dir == self.web_app_dir
    1.96 +
    1.97      def ensure_directories(self):
    1.98  
    1.99          "Make sure that all the directories are available."
   1.100 @@ -326,6 +370,20 @@
   1.101              else:
   1.102                  status("Could not copy %s into installed Wiki." % d)
   1.103  
   1.104 +        # Copy static Web data if appropriate.
   1.105 +
   1.106 +        if not self.moin_version.startswith("1.9") and self.limited_hosting():
   1.107 +
   1.108 +            if not exists(self.htdocs_dir):
   1.109 +                os.mkdir(self.htdocs_dir)
   1.110 +
   1.111 +            for item in os.listdir(self.htdocs_dir_source):
   1.112 +                path = join(self.htdocs_dir_source, item)
   1.113 +                if isdir(path):
   1.114 +                    shutil.copytree(path, join(self.htdocs_dir, item))
   1.115 +                else:
   1.116 +                    shutil.copy(path, join(self.htdocs_dir, item))
   1.117 +
   1.118      def configure_moin(self):
   1.119  
   1.120          "Edit the Wiki configuration file."
   1.121 @@ -342,7 +400,11 @@
   1.122              self.static_url_path = self.url_path
   1.123              url_prefix_static = "%r + url_prefix_static" % self.static_url_path
   1.124          else:
   1.125 -            self.static_url_path = self.url_path + "-static"
   1.126 +            # Add the static identifier to the URL path. For example:
   1.127 +            # /         -> /moin_static187
   1.128 +            # /hgwiki   -> /hgwiki/moin_static187
   1.129 +
   1.130 +            self.static_url_path = self.url_path + "/" + self.get_static_identifier()
   1.131              url_prefix_static = "%r" % self.static_url_path
   1.132  
   1.133          # Copy the Wiki configuration file from the distribution.
   1.134 @@ -405,7 +467,11 @@
   1.135          # NOTE: CGI only so far.
   1.136          # NOTE: Permissions should be checked.
   1.137  
   1.138 -        moin_cgi = join(self.instance_dir, "share", "moin", "server", "moin.cgi")
   1.139 +        if self.moin_version.startswith("1.9"):
   1.140 +            moin_cgi = join(self.instance_dir, "share", "moin", "server", "moin.fcgi")
   1.141 +        else:
   1.142 +            moin_cgi = join(self.instance_dir, "share", "moin", "server", "moin.cgi")
   1.143 +
   1.144          moin_cgi_installed = join(self.web_app_dir, "moin.cgi")
   1.145  
   1.146          status("Editing moin.cgi script from %s..." % moin_cgi)
   1.147 @@ -414,6 +480,16 @@
   1.148          s = moin_cgi_prefix.sub("sys.path.insert(0, %r)" % self.prefix_site_packages, s)
   1.149          s = moin_cgi_wikiconfig.sub("sys.path.insert(0, %r)" % self.conf_dir, s)
   1.150  
   1.151 +        # Handle differences in script names when using limited hosting with
   1.152 +        # URL rewriting.
   1.153 +
   1.154 +        if self.limited_hosting():
   1.155 +            if self.moin_version.startswith("1.9"):
   1.156 +                s = moin_cgi_fix_script_name.sub(r"\1\2 %r" % self.url_path, s)
   1.157 +                s = moin_cgi_force_cgi.sub(r"\1", s)
   1.158 +            else:
   1.159 +                s = moin_cgi_properties.sub(r"\1\2 %r" % {"script_name" : self.url_path}, s)
   1.160 +
   1.161          writefile(moin_cgi_installed, s)
   1.162          os.system("chmod a+rx '%s'" % moin_cgi_installed)
   1.163  
   1.164 @@ -447,15 +523,26 @@
   1.165  
   1.166          # NOTE: Using local namespace for substitution.
   1.167  
   1.168 -        site_def = join(self.web_site_dir, self.site_name)
   1.169 -        site_def_private = join(self.web_site_dir, "%s-private" % self.site_name)
   1.170 +        # Where the site definitions and applications directories are different,
   1.171 +        # use a normal site definition.
   1.172  
   1.173 -        status("Writing Apache site definitions to %s and %s..." % (site_def, site_def_private))
   1.174 +        if not self.limited_hosting():
   1.175 +
   1.176 +            site_def = join(self.web_site_dir, self.site_name)
   1.177 +
   1.178 +            s = apache_site % self.__dict__
   1.179  
   1.180 -        s = apache_site % self.__dict__
   1.181 +            if not self.moin_version.startswith("1.9"):
   1.182 +                s += apache_site_extra_moin18 % self.__dict__
   1.183 +
   1.184 +        # Otherwise, use an .htaccess file.
   1.185  
   1.186 -        if not self.moin_version.startswith("1.9"):
   1.187 -            s += apache_site_extra_moin18 % self.__dict__
   1.188 +        else:
   1.189 +            site_def = join(self.web_site_dir, ".htaccess")
   1.190 +
   1.191 +            s = apache_htaccess_combined_mod_rewrite % self.__dict__
   1.192 +
   1.193 +        status("Writing Apache site definitions to %s..." % site_def)
   1.194  
   1.195          writefile(site_def, s)
   1.196