moinsetup

Changeset

20:533880275f46
2010-06-10 Paul Boddie raw files shortlog changelog graph Added extension package installation and stylesheet integration, adjusting the stylesheet import regular expression. Added an error reporting function.
moinsetup.py (file)
     1.1 --- a/moinsetup.py	Tue Jun 08 00:59:33 2010 +0200
     1.2 +++ b/moinsetup.py	Thu Jun 10 01:10:25 2010 +0200
     1.3 @@ -19,7 +19,7 @@
     1.4  moin_cgi_fix_script_name = compile_definition("fix_script_name")
     1.5  moin_cgi_force_cgi       = re.compile("^#(os.environ\['FCGI_FORCE_CGI'\].*)$", re.MULTILINE)
     1.6  
     1.7 -css_import_stylesheet    = re.compile("^(\s*@import\s+[\"'])(.*?)([\"'].*)$", re.MULTILINE)
     1.8 +css_import_stylesheet    = re.compile("(\s*@import\s+[\"'])(.*?)([\"']\s*;)")
     1.9  
    1.10  # Templates for Apache site definitions.
    1.11  
    1.12 @@ -66,8 +66,8 @@
    1.13  def status(message):
    1.14      print message
    1.15  
    1.16 -def note(message):
    1.17 -    print message
    1.18 +note = status
    1.19 +error = status
    1.20  
    1.21  class Configuration:
    1.22  
    1.23 @@ -304,6 +304,26 @@
    1.24              if not exists(d):
    1.25                  os.makedirs(d)
    1.26  
    1.27 +    def get_theme_directories(self, theme_name=None):
    1.28 +
    1.29 +        """
    1.30 +        Return tuples of the form (theme name, theme directory) for all themes,
    1.31 +        or for a single theme if the optional 'theme_name' is specified.
    1.32 +        """
    1.33 +
    1.34 +        filenames = theme_name and [theme_name] or os.listdir(self.htdocs_dir)
    1.35 +        directories = []
    1.36 +
    1.37 +        for filename in filenames:
    1.38 +            theme_dir = join(self.htdocs_dir, filename)
    1.39 +
    1.40 +            if not exists(theme_dir) or not isdir(theme_dir):
    1.41 +                continue
    1.42 +
    1.43 +            directories.append((filename, theme_dir))
    1.44 +
    1.45 +        return directories
    1.46 +
    1.47      # Main methods.
    1.48  
    1.49      def setup(self):
    1.50 @@ -643,6 +663,15 @@
    1.51              if exists(css_file_path):
    1.52                  shutil.copy(css_file_path, target_dir)
    1.53  
    1.54 +    def install_extension_package(self, extension_dir):
    1.55 +
    1.56 +        "Install any libraries from 'extension_dir' using a setup script."
    1.57 +
    1.58 +        this_dir = os.getcwd()
    1.59 +        os.chdir(extension_dir)
    1.60 +        os.system("python setup.py install --prefix=%s" % self.prefix)
    1.61 +        os.chdir(this_dir)
    1.62 +
    1.63      def install_plugins(self, plugins_dir, plugin_type):
    1.64  
    1.65          """
    1.66 @@ -679,15 +708,9 @@
    1.67          specified resources.
    1.68          """
    1.69  
    1.70 -        # Copy the resources.
    1.71 -
    1.72 -        filenames = theme_name and [theme_name] or os.listdir(self.htdocs_dir)
    1.73 +        for theme_name, theme_dir in self.get_theme_directories(theme_name):
    1.74  
    1.75 -        for filename in filenames:
    1.76 -            theme_dir = join(self.htdocs_dir, filename)
    1.77 -
    1.78 -            if not exists(theme_dir) or not isdir(theme_dir):
    1.79 -                continue
    1.80 +            # Copy the resources.
    1.81  
    1.82              copied = 0
    1.83  
    1.84 @@ -705,6 +728,82 @@
    1.85              if copied:
    1.86                  status("Copied theme resources into %s..." % theme_dir)
    1.87  
    1.88 +    def edit_theme_stylesheet(self, theme_stylesheet, imported_stylesheet, action="ensure", theme_name=None):
    1.89 +
    1.90 +        """
    1.91 +        Edit the given 'theme_stylesheet', ensuring (or removing) a reference to
    1.92 +        the 'imported_stylesheet' according to the given 'action' (optional,
    1.93 +        defaulting to "ensure"). If a specific 'theme_name' is given, only that
    1.94 +        theme will be affected.
    1.95 +        """
    1.96 +
    1.97 +        if action == "ensure":
    1.98 +            ensure = 1
    1.99 +        elif action == "remove":
   1.100 +            ensure = 0
   1.101 +        else:
   1.102 +            error("Action %s not valid: it must be given as either 'ensure' or 'remove'." % action)
   1.103 +            return
   1.104 +
   1.105 +        for theme_name, theme_dir in self.get_theme_directories(theme_name):
   1.106 +
   1.107 +            # Locate the resources.
   1.108 +
   1.109 +            css_dir = join(theme_dir, "css")
   1.110 +
   1.111 +            if not exists(css_dir):
   1.112 +                continue
   1.113 +
   1.114 +            theme_stylesheet_filename = join(css_dir, theme_stylesheet)
   1.115 +            imported_stylesheet_filename = join(css_dir, imported_stylesheet)
   1.116 +
   1.117 +            if not exists(theme_stylesheet_filename):
   1.118 +                error("Stylesheet %s not defined in theme %s." % (theme_stylesheet, theme_name))
   1.119 +                continue
   1.120 +
   1.121 +            if not exists(imported_stylesheet_filename):
   1.122 +                error("Stylesheet %s not defined in theme %s." % (imported_stylesheet, theme_name))
   1.123 +                continue
   1.124 +
   1.125 +            # Edit the resources.
   1.126 +
   1.127 +            s = readfile(theme_stylesheet_filename)
   1.128 +            after_point = 0
   1.129 +
   1.130 +            for stylesheet_import in css_import_stylesheet.finditer(s):
   1.131 +                before, filename, after = stylesheet_import.groups()
   1.132 +                before_point, after_point = stylesheet_import.span()
   1.133 +
   1.134 +                # Test the import for a reference to the requested imported
   1.135 +                # stylesheet.
   1.136 +
   1.137 +                if filename == imported_stylesheet:
   1.138 +                    if ensure:
   1.139 +                        break
   1.140 +                    else:
   1.141 +                        if s[after_point:after_point+1] == "\n":
   1.142 +                            after_point += 1
   1.143 +                        s = "%s%s" % (s[:before_point], s[after_point:])
   1.144 +
   1.145 +                        status("Removing %s from %s in theme %s..." % (imported_stylesheet, theme_stylesheet, theme_name))
   1.146 +                        writefile(theme_stylesheet_filename, s)
   1.147 +                        break
   1.148 +
   1.149 +            # Where no import references the imported stylesheet, insert a
   1.150 +            # reference into the theme stylesheet.
   1.151 +
   1.152 +            else:
   1.153 +                if ensure:
   1.154 +
   1.155 +                    # Assume that the stylesheet can follow other imports.
   1.156 +
   1.157 +                    if s[after_point:after_point+1] == "\n":
   1.158 +                        after_point += 1
   1.159 +                    s = "%s%s\n%s" % (s[:after_point], '@import "%s";' % imported_stylesheet, s[after_point:])
   1.160 +
   1.161 +                    status("Adding %s to %s in theme %s..." % (imported_stylesheet, theme_stylesheet, theme_name))
   1.162 +                    writefile(theme_stylesheet_filename, s)
   1.163 +
   1.164  # Command line option syntax.
   1.165  
   1.166  syntax_description = "<argument> ... --method=METHOD [ <method-argument> ... ]"