cubicweb/web/webctl.py
changeset 11057 0b59724cb3f2
parent 10589 7c23b7de2b8d
child 11461 f5a4e14d1dd2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cubicweb/web/webctl.py	Sat Jan 16 13:48:51 2016 +0100
@@ -0,0 +1,136 @@
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+"""cubicweb-ctl commands and command handlers common to twisted/modpython
+web configuration
+"""
+from __future__ import print_function
+
+__docformat__ = "restructuredtext en"
+
+import os, os.path as osp
+from shutil import copy, rmtree
+
+from logilab.common.shellutils import ASK
+
+from cubicweb import ExecutionError
+from cubicweb.cwctl import CWCTL
+from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
+from cubicweb.toolsutils import Command, CommandHandler, underline_title
+
+
+try:
+    from os import symlink as linkdir
+except ImportError:
+    from shutil import copytree as linkdir
+
+
+class WebCreateHandler(CommandHandler):
+    cmdname = 'create'
+
+    def bootstrap(self, cubes, automatic=False, inputlevel=0):
+        """bootstrap this configuration"""
+        if not automatic:
+            print('\n' + underline_title('Generic web configuration'))
+            config = self.config
+            config.input_config('web', inputlevel)
+            if ASK.confirm('Allow anonymous access ?', False):
+                config.global_set_option('anonymous-user', 'anon')
+                config.global_set_option('anonymous-password', 'anon')
+
+    def postcreate(self, *args, **kwargs):
+        """hooks called once instance's initialization has been completed"""
+
+
+class GenStaticDataDirMixIn(object):
+    """Create a directory merging all data directory content from cubes and CW.
+    """
+    def generate_static_dir(self, config, dest=None, ask_clean=False, repo=None):
+        if not dest:
+            dest = config['staticdir-path']
+        if not dest:
+            dest = osp.join(config.appdatahome, 'data')
+        if osp.exists(dest):
+            if (not ask_clean or
+                not (config.verbosity and
+                     ASK.confirm('Remove existing data directory %s?' % dest))):
+                raise ExecutionError('Directory %s already exists. '
+                                     'Remove it first.' % dest)
+            rmtree(dest)
+        config.quick_start = True # notify this is not a regular start
+        # list all resources (no matter their order)
+        resources = set()
+        for datadir in self._datadirs(config, repo=repo):
+            for dirpath, dirnames, filenames in os.walk(datadir):
+                rel_dirpath = dirpath[len(datadir)+1:]
+                resources.update(osp.join(rel_dirpath, f) for f in filenames)
+        # locate resources and copy them to destination
+        for resource in resources:
+            dest_resource = osp.join(dest, resource)
+            dirname = osp.dirname(dest_resource)
+            if not osp.isdir(dirname):
+                os.makedirs(dirname)
+            resource_dir, resource_path = config.locate_resource(resource)
+            copy(osp.join(resource_dir, resource_path), dest_resource)
+        # handle md5 version subdirectory
+        linkdir(dest, osp.join(dest, config.instance_md5_version()))
+        print('You can use apache rewrite rule below :\n'
+              'RewriteRule ^/data/(.*) %s/$1 [L]' % dest)
+
+    def _datadirs(self, config, repo=None):
+        if repo is None:
+            repo = config.repository()
+        if config._cubes is None:
+            # web only config
+            config.init_cubes(repo.get_cubes())
+        for cube in repo.get_cubes():
+            cube_datadir = osp.join(cwcfg.cube_dir(cube), 'data')
+            if osp.isdir(cube_datadir):
+                yield cube_datadir
+        yield osp.join(config.shared_dir(), 'data')
+
+
+class WebUpgradeHandler(CommandHandler, GenStaticDataDirMixIn):
+    cmdname = 'upgrade'
+
+    def postupgrade(self, repo):
+        config = self.config
+        if not config['generate-staticdir']:
+            return
+        self.generate_static_dir(config, ask_clean=True, repo=repo)
+
+
+class GenStaticDataDir(Command, GenStaticDataDirMixIn):
+    """Create a directory merging all data directory content from cubes and CW.
+    """
+    name = 'gen-static-datadir'
+    arguments = '<instance> [dirpath]'
+    min_args = 1
+    max_args = 2
+
+    options = ()
+
+    def run(self, args):
+        appid = args.pop(0)
+        config = cwcfg.config_for(appid)
+        dest = None
+        if args:
+            dest = args[0]
+        self.generate_static_dir(config, dest)
+
+
+CWCTL.register(GenStaticDataDir)