[Bf-extensions-cvs] [727127a4] master: development_api_navigator: moved to contrib: T63750
meta-androcto
noreply at git.blender.org
Fri May 24 02:42:25 CEST 2019
Commit: 727127a47911640d6e8bc432a75596c95ff0218c
Author: meta-androcto
Date: Fri May 24 10:42:00 2019 +1000
Branches: master
https://developer.blender.org/rBAC727127a47911640d6e8bc432a75596c95ff0218c
development_api_navigator: moved to contrib: T63750
===================================================================
A development_api_navigator.py
===================================================================
diff --git a/development_api_navigator.py b/development_api_navigator.py
new file mode 100644
index 00000000..11193984
--- /dev/null
+++ b/development_api_navigator.py
@@ -0,0 +1,723 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENCE BLOCK #####
+
+bl_info = {
+ "name": "API Navigator",
+ "author": "Dany Lebel (Axon_D)",
+ "version": (1, 0, 4),
+ "blender": (2, 57, 0),
+ "location": "Text Editor > Properties > API Navigator Panel",
+ "description": "Allows exploration of the python api via the user interface",
+ "warning": "",
+ "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Text_Editor/API_Navigator",
+ "category": "Development",
+}
+
+"""
+ You can browse through the tree structure of the api. Each child object appears in a list
+that tries to be representative of its type. These lists are :
+
+ * Items (for an iterable object)
+ * Item Values (for an iterable object which only supports index)
+ * Modules
+ * Types
+ * Properties
+ * Structs and Functions
+ * Methods and Functions
+ * Attributes
+ * Inaccessible (some objects may be listed but inaccessible)
+
+ The lists can be filtered to help searching in the tree. Just enter the text in the
+filter section. It is also possible to explore other modules. Go the the root and select
+it in the list of available modules. It will be imported dynamically.
+
+ In the text section, some information are displayed. The type of the object,
+what it returns, and its docstring. We could hope that these docstrings will be as
+descriptive as possible. This text data block named api_doc_ can be toggled on and off
+with the Escape key. (but a bug prevent the keymap to register correctly at start)
+
+"""
+
+import bpy
+from bpy.types import (
+ Operator,
+ Panel,
+ PropertyGroup,
+ )
+from bpy.props import (
+ BoolVectorProperty,
+ StringProperty,
+ IntProperty,
+ PointerProperty,
+ )
+from console.complete_import import get_root_modules
+
+
+# ########## Global Variables ##########
+
+last_text = None # last text data block
+root_module = None # root module of the tree
+root_m_path = '' # root_module + path as a string
+current_module = None # the object itself in the tree structure
+tree_level = None # the list of objects from the current_module
+
+
+def init_tree_level():
+ global tree_level
+ tree_level = [[], [], [], [], [], [], [], [], []]
+
+
+init_tree_level()
+
+api_doc_ = '' # the documentation formatted for the API Navigator
+module_type = None # the type of current_module
+return_report = '' # what current_module returns
+filter_mem = {} # remember last filters entered for each path
+too_long = False # is tree_level list too long to display in a panel?
+
+
+# ########## Functions ############
+def get_root_module(path):
+ global root_module
+ if '.' in path:
+ root = path[:path.find('.')]
+ else:
+ root = path
+ try:
+ root_module = __import__(root)
+ except:
+ root_module = None
+
+
+def evaluate(module):
+ global root_module, tree_level, root_m_path
+
+ try:
+ len_name = root_module.__name__.__len__()
+ root_m_path = 'root_module' + module[len_name:]
+ current_module = eval(root_m_path)
+ return current_module
+ except:
+ init_tree_level
+ return None
+
+
+def get_tree_level():
+
+ path = bpy.context.window_manager.api_nav_props.path
+
+ def object_list():
+ global current_module, root_m_path
+
+ itm, val, mod, typ, props, struct, met, att, bug = [], [], [], [], [], [], [], [], []
+ iterable = isiterable(current_module)
+ if iterable:
+ iter(current_module)
+ current_type = str(module_type)
+ if current_type != "<class 'str'>":
+ if iterable == 'a':
+ itm = list(current_module.keys())
+ if not itm:
+ val = list(current_module)
+ else:
+ val = list(current_module)
+
+ for i in dir(current_module):
+ try:
+ t = str(type(eval(root_m_path + '.' + i)))
+ except (AttributeError, SyntaxError):
+ bug += [i]
+ continue
+
+ if t == "<class 'module'>":
+ mod += [i]
+ elif t[0:16] == "<class 'bpy_prop":
+ props += [i]
+ elif t[8:11] == 'bpy':
+ struct += [i]
+ elif t == "<class 'builtin_function_or_method'>":
+ met += [i]
+ elif t == "<class 'type'>":
+ typ += [i]
+ else:
+ att += [i]
+
+ return [itm, val, mod, typ, props, struct, met, att, bug]
+
+ if not path:
+ return [[], [], [i for i in get_root_modules()], [], [], [], [], [], []]
+ return object_list()
+
+
+def parent(path):
+ """Returns the parent path"""
+ parent = path
+ if parent[-1] == ']' and '[' in parent:
+ while parent[-1] != '[':
+ parent = parent[:-1]
+ elif '.' in parent:
+ while parent[-1] != '.':
+ parent = parent[:-1]
+ else:
+ return ''
+ parent = parent[:-1]
+ return parent
+
+
+def update_filter():
+ """Update the filter according to the current path"""
+ global filter_mem
+
+ try:
+ bpy.context.window_manager.api_nav_props.filters = filter_mem[
+ bpy.context.window_manager.api_nav_props.path
+ ]
+ except:
+ bpy.context.window_manager.api_nav_props.filters = ''
+
+
+def isiterable(mod):
+ try:
+ iter(mod)
+ except:
+ return False
+ try:
+ mod['']
+ return 'a'
+ except KeyError:
+ return 'a'
+ except (AttributeError, TypeError):
+ return 'b'
+
+
+def fill_filter_mem():
+ global filter_mem
+
+ filters = bpy.context.window_manager.api_nav_props.filters
+ if filters:
+ filter_mem[bpy.context.window_manager.api_nav_props.old_path] = \
+ bpy.context.window_manager.api_nav_props.filters
+ else:
+ filter_mem.pop(bpy.context.window_manager.api_nav_props.old_path, None)
+
+
+# #### API Navigator parent class ######
+class ApiNavigator():
+ """Parent class for API Navigator"""
+
+ @staticmethod
+ def generate_global_values():
+ """Populate the level attributes to display the panel buttons and the documentation"""
+ global tree_level, current_module, module_type, return_report, last_text
+
+ text = bpy.context.space_data.text
+ if text:
+ if text.name != 'api_doc_':
+ last_text = bpy.context.space_data.text.name
+ elif bpy.data.texts.__len__() < 2:
+ last_text = None
+ else:
+ last_text = None
+ bpy.context.window_manager.api_nav_props.pages = 0
+ get_root_module(bpy.context.window_manager.api_nav_props.path)
+ current_module = evaluate(bpy.context.window_manager.api_nav_props.path)
+ module_type = str(type(current_module))
+ return_report = str(current_module)
+ tree_level = get_tree_level()
+
+ if tree_level.__len__() > 30:
+ global too_long
+ too_long = True
+ else:
+ too_long = False
+
+ ApiNavigator.generate_api_doc()
+ return {'FINISHED'}
+
+ @staticmethod
+ def generate_api_doc():
+ """Format the doc string for API Navigator"""
+ global current_module, api_doc_, return_report, module_type
+
+ path = bpy.context.window_manager.api_nav_props.path
+ line = "-" * (path.__len__() + 2)
+ header = """\n\n\n\t\t%s\n\t %s\n\
+_____________________________________________\n\
+\n\
+Type : %s\n\
+\n\
+\n\
+Return : %s\n\
+_____________________________________________\n\
+\n\
+Doc:
+\n\
+""" % (path, line, module_type, return_report)
+ footer = "\n\
+_____________________________________________\n\
+\n\
+\n\
+\n\
+#############################################\n\
+# api_doc_ #\n\
+# Escape to toggle text #\n\
+# (F8 to reload modules if doesn't work) #\n\
+#############################################"
+ doc = current_module.__doc__
+ api_doc_ = header + str(doc) + footer
+ return {'FINISHED'}
+
+ @staticmethod
+ def doc_text_datablock():
+ """Create the text databloc or overwrite it if it already exist"""
+ global api_doc_
+
+ space_data = bpy.context.space_data
+
+ try:
+ doc_text = bpy.data.texts['api_doc_']
+ space_data.text = doc_text
+ doc_text.clear()
+ except:
+ bpy.data.texts.new(name='api_doc_')
+ doc_text = bpy.data.texts['api_doc_']
+ space_data.text = doc_text
+
+ doc_text.write(text=api_doc_)
+ return {'FINISHED'}
+
+
+# ######### Operators ###########
+def api_update(context):
+ if bpy.context.window_manager.api_nav_props.path != bpy.context.window_manager.api_nav_props.old_path:
+ fill_filter_mem()
+ bpy.context.window_manager.api_nav_props.old_path = bpy.context.window_manager.api_nav_props.path
+ update_filter
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list