Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(690)

Unified Diff: chrome/common/extensions/docs/server2/availability_graph.py

Issue 23503039: Adding APISchemaGraph class to Extensions Docserver. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/server2/availability_graph.py
diff --git a/chrome/common/extensions/docs/server2/availability_graph.py b/chrome/common/extensions/docs/server2/availability_graph.py
new file mode 100644
index 0000000000000000000000000000000000000000..3d3133deb8aa1caefe986f12a31e76652f87d6ee
--- /dev/null
+++ b/chrome/common/extensions/docs/server2/availability_graph.py
@@ -0,0 +1,102 @@
+# Copyright 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+_ATTRIBUTES = ('events', 'functions', 'parameters', 'properties', 'types')
not at google - send to devlin 2013/09/06 23:29:38 I'm thinking this shouldn't care about what the co
epeterson 2013/09/12 00:32:01 Done.
+
+
+def _NameForNode(node, node_type):
+ '''Creates a unique id for an object in an API schema, depending on
+ what type of attribute the object is a member of.
+ '''
+ if node_type == 'properties': return node
+ if node_type == 'types': return node['id']
+ if node_type is None: return node['namespace']
+ if 'name' in node:
+ return node['name']
+ # The API Schema probably had an error here. Fall back to the 'type' field to
+ # avoid raising an error.
+ return node['type']
+
+
+def _CreateGraph(api_schema, node_type=None):
+ '''Recursively move through an API schema, replacing lists of objects
+ for each attribute listed in |attributes| with a dict containing a
+ key for each object in the list.
+ '''
+ availability_graph = {}
+ for node in api_schema:
not at google - send to devlin 2013/09/06 23:29:38 confusing dicts and lists here is.. odd. And I can
epeterson 2013/09/12 00:32:01 Done.
+ name = _NameForNode(node, node_type)
not at google - send to devlin 2013/09/06 23:29:38 how about asserting "name not in graph" here.
epeterson 2013/09/12 00:32:01 Done.
+ availability_graph[name] = { 'availability': None }
+ if node_type == 'properties':
+ # The 'properties' attribute is a key -> value mapping. Grab the value.
+ node = api_schema[node]
+ for attribute in _ATTRIBUTES:
+ if attribute in node:
+ availability_graph[name][attribute] = _CreateGraph(node[attribute],
+ node_type=attribute)
+ return availability_graph
+
+
+class AvailabilityGraph(object):
+ '''Represents an API schema as a nested dict structure, where lists of
+ schema nodes (falling under one of |_ATTRIBUTES|) are converted to
+ dicts with a key representing each node. Availability information for
+ schema nodes is tracked as the graph is created and processed.
+ '''
+
+ def __init__(self, api_schema, channel_info):
+ self.graph = _CreateGraph(api_schema)
+ self.channel_info = channel_info
not at google - send to devlin 2013/09/06 23:29:38 these need to be private.
epeterson 2013/09/12 00:32:01 Done.
+ self._paths = []
+
+ def SetPaths(self, other):
+ '''Sets a list of '/'-delimited dictionary-keys, or 'paths', that
+ exist in this object's |graph| but not in |other|'s graph. Update
+ 'availability' for keys based on which graphs they are initially
+ found in.
+ '''
+ def get_missing_paths(this_graph, other_graph, path=''):
+ paths = []
+ for key in this_graph:
+ if key == 'availability':
+ continue
+ current_path = '%s/%s' % (path, key) if path else key
+ paths.extend(get_missing_paths(this_graph[key],
+ other_graph.get(key, {}),
+ current_path))
+ if key not in _ATTRIBUTES:
+ # Add the path if the value was not available upon the API's release.
+ if key not in other_graph:
+ this_graph[key]['availability'] = self.channel_info
+ paths.append(current_path)
+ else:
+ this_graph[key]['availability'] = other.channel_info
+ return paths
+
+ self._paths = get_missing_paths(self.graph, other.graph)
+
+ def UpdatePaths(self, other):
+ '''Check each path in |_paths|, removing a path if it has become
+ available and updating that path's availability in the |graph|.
+ '''
+ for path in self._paths[:]:
+ path_pieces = path.split('/')
+ if other.Lookup(*path_pieces) is not None:
+ node = self.graph
+ for path_piece in path_pieces:
+ node = node[path_piece]
+ node['availability'] = other.channel_info
+ self._paths.remove(path)
+ return bool(self._paths)
not at google - send to devlin 2013/09/06 23:29:38 Would a better set of methods on this class be som
epeterson 2013/09/12 00:32:01 Done.
+
+ def Lookup(self, *path):
+ '''Given a list of path components, |path|, checks if |graph|
+ contains |path| and returns its availability if found.
+ '''
+ node = self.graph
+ for path_piece in path:
+ node = node.get(path_piece)
+ if node is None:
+ return None
+ return node.get('availability')

Powered by Google App Engine
This is Rietveld 408576698