changeset 610:efc1dc916e7c

admin: Configuration changes. * Move publish targets to site configuration. * Add direct accessor for the current site.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 28 Jan 2016 22:17:58 -0800
parents 978d8bca9fb3
children 906cc2520773
files foodtruck/configuration.py foodtruck/sites.py foodtruck/views/create.py foodtruck/views/dashboard.py foodtruck/views/edit.py foodtruck/views/menu.py foodtruck/views/publish.py foodtruck/views/sources.py foodtruck/web.py
diffstat 9 files changed, 61 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/foodtruck/configuration.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/configuration.py	Thu Jan 28 22:17:58 2016 -0800
@@ -10,10 +10,10 @@
 logger = logging.getLogger(__name__)
 
 
-def get_foodtruck_config(dirname=None):
+def get_foodtruck_config(dirname=None, fallback_config=None):
     dirname = dirname or os.getcwd()
     cfg_path = os.path.join(dirname, 'foodtruck.yml')
-    return FoodTruckConfiguration(cfg_path)
+    return FoodTruckConfiguration(cfg_path, fallback_config)
 
 
 class FoodTruckConfigNotFoundError(Exception):
@@ -21,9 +21,10 @@
 
 
 class FoodTruckConfiguration(Configuration):
-    def __init__(self, cfg_path):
+    def __init__(self, cfg_path, fallback_config=None):
         super(FoodTruckConfiguration, self).__init__()
         self.cfg_path = cfg_path
+        self.fallback_config = fallback_config
 
     def _load(self):
         try:
@@ -34,7 +35,12 @@
 
             self._values = self._validateAll(values)
         except OSError:
-            raise FoodTruckConfigNotFoundError()
+            if self.fallback_config is None:
+                raise FoodTruckConfigNotFoundError()
+
+            logger.debug("No FoodTruck configuration found, using fallback "
+                         "configuration.")
+            self._values = copy.deepcopy(self.fallback_config)
         except Exception as ex:
             raise ConfigurationError(
                     "Error loading configuration from: %s" %
--- a/foodtruck/sites.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/sites.py	Thu Jan 28 22:17:58 2016 -0800
@@ -6,7 +6,7 @@
 import threading
 import subprocess
 from piecrust.app import PieCrust
-from piecrust.configuration import merge_dicts, Configuration
+from piecrust.configuration import merge_dicts
 
 
 logger = logging.getLogger(__name__)
@@ -24,7 +24,6 @@
     def __init__(self, name, root_dir, config):
         self.name = name
         self.root_dir = root_dir
-        self.config = Configuration(values=config.get('sites/%s' % name, {}))
         self._global_config = config
         self._piecrust_app = None
         self._scm = None
@@ -43,7 +42,7 @@
     def scm(self):
         if self._scm is None:
             cfg = copy.deepcopy(self._global_config.get('scm', {}))
-            merge_dicts(cfg, self.config.get('scm', {}))
+            merge_dicts(cfg, self.piecrust_app.config.get('scm', {}))
 
             if os.path.isdir(os.path.join(self.root_dir, '.hg')):
                 from .scm.mercurial import MercurialSourceControl
@@ -66,7 +65,7 @@
         return self._publish_thread
 
     def publish(self, target):
-        target_cfg = self.config.get('publish/%s' % target)
+        target_cfg = self.piecrust_app.config.get('publish/%s' % target)
         if not target_cfg:
             raise Exception("No such publish target: %s" % target)
 
@@ -126,7 +125,6 @@
 class FoodTruckSites():
     def __init__(self, config, current_site):
         self._sites = {}
-        self._site_dirs = {}
         self.config = config
         self.current_site = current_site
         if current_site is None:
@@ -134,19 +132,11 @@
 
     def get_root_dir(self, name=None):
         name = name or self.current_site
-        s = self._site_dirs.get(name)
-        if s:
-            return s
-
-        scfg = self.config.get('sites/%s' % name)
-        if scfg is None:
+        root_dir = self.config.get('sites/%s' % name)
+        if root_dir is None:
             raise InvalidSiteError("No such site: %s" % name)
-        root_dir = scfg.get('path')
-        if root_dir is None:
-            raise InvalidSiteError("Site '%s' has no path defined." % name)
         if not os.path.isdir(root_dir):
             raise InvalidSiteError("Site '%s' has an invalid path." % name)
-        self._site_dirs[name] = root_dir
         return root_dir
 
     def get(self, name=None):
@@ -160,3 +150,7 @@
         self._sites[name] = s
         return s
 
+    def getall(self):
+        for name in self.config.get('sites'):
+            yield self.get(name)
+
--- a/foodtruck/views/create.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/views/create.py	Thu Jan 28 22:17:58 2016 -0800
@@ -16,7 +16,7 @@
 @app.route('/write/<source_name>', methods=['GET', 'POST'])
 @login_required
 def write_page(source_name):
-    site = g.sites.get().piecrust_app
+    site = g.site.piecrust_app
     source = site.getSource(source_name)
     if source is None:
         abort(400)
@@ -50,7 +50,7 @@
             dummy = _DummyPage(fac)
             route_metadata = create_route_metadata(dummy)
             uri = route.getUri(route_metadata)
-            uri_root = '/site/%s/' % g.sites.get().name
+            uri_root = '/site/%s/' % g.site.name
             uri = uri[len(uri_root):]
             logger.debug("Redirecting to: %s" % uri)
 
--- a/foodtruck/views/dashboard.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/views/dashboard.py	Thu Jan 28 22:17:58 2016 -0800
@@ -20,12 +20,9 @@
 @login_required
 def index():
     data = {}
-    site_name = request.cookies.get('foodtruck_site_name')
-    site = g.sites.get(site_name)
-    assert site is not None
-
+    data['sources'] = []
+    site = g.site
     fs_endpoints = {}
-    data['sources'] = []
     for source in site.piecrust_app.sources:
         if source.is_theme_source:
             continue
@@ -58,11 +55,11 @@
     data['url_preview'] = url_for('preview_site_root', sitename=site.name)
 
     data['sites'] = []
-    for k, v in g.config.get('sites').items():
+    for s in g.sites.getall():
         data['sites'].append({
-            'name': k,
-            'display_name': v.get('name', k),
-            'url': url_for('index', site_name=site_name)
+            'name': s.name,
+            'display_name': s.piecrust_app.config.get('site/title'),
+            'url': url_for('index', site_name=s.name)
             })
     data['needs_switch'] = len(g.config.get('sites')) > 1
     data['url_switch'] = url_for('switch_site')
--- a/foodtruck/views/edit.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/views/edit.py	Thu Jan 28 22:17:58 2016 -0800
@@ -17,7 +17,7 @@
 @app.route('/edit/<path:slug>', methods=['GET', 'POST'])
 @login_required
 def edit_page(slug):
-    site = g.sites.get()
+    site = g.site
     site_app = site.piecrust_app
     rp = get_requested_page(site_app,
                             '/site/%s/%s' % (g.sites.current_site, slug))
--- a/foodtruck/views/menu.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/views/menu.py	Thu Jan 28 22:17:58 2016 -0800
@@ -9,7 +9,7 @@
         'title': "Dashboard",
         'icon': 'speedometer'})
 
-    site = g.sites.get().piecrust_app
+    site = g.site.piecrust_app
     for s in site.sources:
         if s.is_theme_source:
             continue
--- a/foodtruck/views/publish.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/views/publish.py	Thu Jan 28 22:17:58 2016 -0800
@@ -4,7 +4,6 @@
 import logging
 from flask import request, g, url_for, render_template, Response
 from flask.ext.login import login_required
-from piecrust.configuration import merge_dicts
 from ..pubutil import PublishLogReader
 from ..views import with_menu_context
 from ..web import app
@@ -21,12 +20,10 @@
         if not target:
             raise Exception("No target specified.")
 
-        site = g.sites.get()
-        site.publish(target)
+        g.site.publish(target)
 
-    site = g.sites.get()
-    pub_cfg = copy.deepcopy(g.config.get('publish', {}))
-    merge_dicts(pub_cfg, site.config.get('publish', {}))
+    site = g.site
+    pub_cfg = copy.deepcopy(site.piecrust_app.config.get('publish', {}))
     if not pub_cfg:
         data = {'error': "There are not publish targets defined in your "
                          "configuration file."}
@@ -52,7 +49,7 @@
 @app.route('/publish-log')
 @login_required
 def stream_publish_log():
-    site = g.sites.get()
+    site = g.site
     pid_path = os.path.join(site.root_dir, '.ft_pub.pid')
     log_path = os.path.join(site.root_dir, '.ft_pub.log')
     rdr = PublishLogReader(pid_path, log_path)
--- a/foodtruck/views/sources.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/views/sources.py	Thu Jan 28 22:17:58 2016 -0800
@@ -10,7 +10,7 @@
 @app.route('/list/<source_name>/<int:page_num>')
 @login_required
 def list_source(source_name, page_num):
-    site = g.sites.get().piecrust_app
+    site = g.site.piecrust_app
     source = site.getSource(source_name)
     if source is None:
         abort(400)
--- a/foodtruck/web.py	Thu Jan 28 22:16:47 2016 -0800
+++ b/foodtruck/web.py	Thu Jan 28 22:17:58 2016 -0800
@@ -15,6 +15,21 @@
 
 admin_root = app.config['FOODTRUCK_ROOT'] or os.getcwd()
 config_path = os.path.join(admin_root, 'app.cfg')
+
+# If we're being run as the `chef admin run` command, from inside a PieCrust
+# website, do a few things differently.
+_procedural_config = None
+
+if (app.config['FOODTRUCK_CMDLINE_MODE'] and
+        os.path.isfile(os.path.join(admin_root, 'config.yml'))):
+    app.secret_key = os.urandom(22)
+    app.config['LOGIN_DISABLED'] = True
+    _procedural_config = {
+            'sites': {
+                'local': admin_root}
+            }
+
+
 if os.path.isfile(config_path):
     app.config.from_pyfile(config_path)
 
@@ -48,21 +63,28 @@
 @app.before_request
 def _setup_foodtruck_globals():
     def _get_config():
-        return get_foodtruck_config(admin_root)
+        return get_foodtruck_config(admin_root, _procedural_config)
 
     def _get_sites():
+        names = g.config.get('sites')
+        if not names or not isinstance(names, dict):
+            raise InvalidSiteError(
+                    "No sites are defined in the configuration file.")
+
         current = request.cookies.get('foodtruck_site_name')
+        if current is not None and current not in names:
+            current = None
         if current is None:
-            names = g.config.get('sites')
-            if not names or not isinstance(names, dict):
-                raise InvalidSiteError(
-                        "No sites are defined in the configuration file.")
             current = next(iter(names.keys()))
         s = FoodTruckSites(g.config, current)
         return s
 
+    def _get_current_site():
+        return g.sites.get()
+
     g.config = LazySomething(_get_config)
     g.sites = LazySomething(_get_sites)
+    g.site = LazySomething(_get_current_site)
 
 
 @app.after_request