403b09
From 5386802ebc96ef0c2bc4a3bfa260ee83a6d7fe5f Mon Sep 17 00:00:00 2001
403b09
From: David Kupka <dkupka@redhat.com>
403b09
Date: Tue, 2 Aug 2016 08:16:30 +0200
403b09
Subject: [PATCH] schema: Generate bits for help load them on request
403b09
403b09
Store name, summary, topic_topic and exclude in single entry in cache
403b09
for all commands. These data are needed for help and storing and
403b09
loading them together allows fast help response.
403b09
403b09
https://fedorahosted.org/freeipa/ticket/6048
403b09
403b09
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
403b09
---
403b09
 ipaclient/remote_plugins/schema.py | 54 +++++++++++++++++++++++++++++---------
403b09
 1 file changed, 42 insertions(+), 12 deletions(-)
403b09
403b09
diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
403b09
index d7c018e3de1cc79ffc086e3576542ce993ebc87a..5264d4cc177ba457c517f93f203e0baca7b0ac01 100644
403b09
--- a/ipaclient/remote_plugins/schema.py
403b09
+++ b/ipaclient/remote_plugins/schema.py
403b09
@@ -23,7 +23,7 @@ from ipapython.dn import DN
403b09
 from ipapython.dnsutil import DNSName
403b09
 from ipapython.ipa_log_manager import log_mgr
403b09
 
403b09
-FORMAT = '0'
403b09
+FORMAT = '1'
403b09
 
403b09
 if six.PY3:
403b09
     unicode = str
403b09
@@ -113,9 +113,11 @@ class _SchemaPlugin(object):
403b09
         if self._class is not None:
403b09
             return self._class.summary
403b09
         else:
403b09
-            if self.doc is not None:
403b09
-                return self.doc.split('\n\n', 1)[0].strip()
403b09
-            else:
403b09
+            self._schema.load_help()
403b09
+            schema = self._schema[self.schema_key][self.full_name]
403b09
+            try:
403b09
+                return schema['summary']
403b09
+            except KeyError:
403b09
                 return u'<%s>' % self.full_name
403b09
 
403b09
     def _create_default_from(self, api, name, keys):
403b09
@@ -241,6 +243,7 @@ class _SchemaCommandPlugin(_SchemaPlugin):
403b09
         if self._class is not None:
403b09
             return self._class.topic
403b09
         else:
403b09
+            self._schema.load_help()
403b09
             schema = self._schema[self.schema_key][self.full_name]
403b09
             try:
403b09
                 return str(schema['topic_topic']).partition('/')[0]
403b09
@@ -252,6 +255,7 @@ class _SchemaCommandPlugin(_SchemaPlugin):
403b09
         if self._class is not None:
403b09
             return self._class.NO_CLI
403b09
         else:
403b09
+            self._schema.load_help()
403b09
             schema = self._schema[self.schema_key][self.full_name]
403b09
             return 'cli' in schema.get('exclude', [])
403b09
 
403b09
@@ -432,7 +436,6 @@ class Schema(object):
403b09
 
403b09
     """
403b09
     namespaces = {'classes', 'commands', 'topics'}
403b09
-    schema_info_path = 'schema'
403b09
     _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema')
403b09
 
403b09
     def __init__(self, api, server_info, client):
403b09
@@ -488,8 +491,7 @@ class Schema(object):
403b09
         if fmt != FORMAT:
403b09
             raise RuntimeError('invalid format')
403b09
 
403b09
-        schema_info = json.loads(schema.read(self.schema_info_path))
403b09
-        return schema_info['fingerprint']
403b09
+        return json.loads(schema.read('fingerprint'))
403b09
 
403b09
     def _fetch(self, client):
403b09
         if not client.isconnected():
403b09
@@ -522,6 +524,7 @@ class Schema(object):
403b09
         else:
403b09
             fp = schema['fingerprint']
403b09
             ttl = schema.pop('ttl', 0)
403b09
+            schema.pop('version', None)
403b09
 
403b09
             for key, value in schema.items():
403b09
                 if key in self.namespaces:
403b09
@@ -534,8 +537,6 @@ class Schema(object):
403b09
     def _read_schema(self):
403b09
         with self._open_schema(self._fingerprint, 'r') as schema:
403b09
             self._dict['fingerprint'] = self._get_schema_fingerprint(schema)
403b09
-            schema_info = json.loads(schema.read(self.schema_info_path))
403b09
-            self._dict['version'] = schema_info['version']
403b09
 
403b09
             for name in schema.namelist():
403b09
                 ns, _slash, key = name.partition('/')
403b09
@@ -548,6 +549,27 @@ class Schema(object):
403b09
         except KeyError:
403b09
             return self._dict[key]
403b09
 
403b09
+    def _generate_help(self, schema):
403b09
+        halp = {}
403b09
+
403b09
+        for namespace in ('commands', 'topics'):
403b09
+            halp[namespace] = {}
403b09
+
403b09
+            for member_schema in schema[namespace].values():
403b09
+                member_full_name = member_schema['full_name']
403b09
+
403b09
+                topic = halp[namespace].setdefault(member_full_name, {})
403b09
+                topic['name'] = member_schema['name']
403b09
+                if 'doc' in member_schema:
403b09
+                    topic['summary'] = (
403b09
+                        member_schema['doc'].split('\n\n', 1)[0].strip())
403b09
+                if 'topic_topic' in member_schema:
403b09
+                    topic['topic_topic'] = member_schema['topic_topic']
403b09
+                if 'exclude' in member_schema:
403b09
+                    topic['exclude'] = member_schema['exclude']
403b09
+
403b09
+        return halp
403b09
+
403b09
     def _write_schema(self):
403b09
         try:
403b09
             os.makedirs(self._DIR)
403b09
@@ -557,7 +579,6 @@ class Schema(object):
403b09
                 return
403b09
 
403b09
         with self._open_schema(self._fingerprint, 'w') as schema:
403b09
-            schema_info = {}
403b09
             for key, value in self._dict.items():
403b09
                 if key in self.namespaces:
403b09
                     ns = value
403b09
@@ -565,9 +586,10 @@ class Schema(object):
403b09
                         path = '{}/{}'.format(key, member)
403b09
                         schema.writestr(path, json.dumps(ns[member]))
403b09
                 else:
403b09
-                    schema_info[key] = value
403b09
+                    schema.writestr(key, json.dumps(value))
403b09
 
403b09
-            schema.writestr(self.schema_info_path, json.dumps(schema_info))
403b09
+            schema.writestr('_help',
403b09
+                            json.dumps(self._generate_help(self._dict)))
403b09
 
403b09
     def _read(self, path):
403b09
         with self._open_schema(self._fingerprint, 'r') as zf:
403b09
@@ -587,6 +609,14 @@ class Schema(object):
403b09
     def iter_namespace(self, namespace):
403b09
         return iter(self._dict[namespace])
403b09
 
403b09
+    def load_help(self):
403b09
+        if not self._help:
403b09
+            self._help = self._read('_help')
403b09
+
403b09
+            for ns in self._help:
403b09
+                for member in self._help[ns]:
403b09
+                    self._dict[ns][member].update(self._help[ns][member])
403b09
+
403b09
 
403b09
 def get_package(api, client):
403b09
     try:
403b09
-- 
403b09
2.7.4
403b09