def getSphinxDocumentationApi(packages, cloneDirectory, outputDirectory, apiFile): """ This definition gets Sphinx documentation API. :param packages: Packages. ( String ) :param cloneDirectory: Source clone directory. ( String ) :param outputDirectory: Content directory. ( String ) :param apiFile: API file. ( String ) """ LOGGER.info("{0} | Building Sphinx documentation API!".format(getSphinxDocumentationApi.__name__)) if os.path.exists(cloneDirectory): shutil.rmtree(cloneDirectory) os.makedirs(cloneDirectory) packagesModules = {"apiModules" : [], "testsModules" : []} for package in packages.split(","): package = __import__(package) path = foundations.common.getFirstItem(package.__path__) sourceDirectory = os.path.dirname(path) for file in sorted(list(foundations.walkers.filesWalker(sourceDirectory, filtersIn=("{0}.*\.ui$".format(path),)))): LOGGER.info("{0} | Ui file: '{1}'".format(getSphinxDocumentationApi.__name__, file)) targetDirectory = os.path.dirname(file).replace(sourceDirectory, "") directory = "{0}{1}".format(cloneDirectory, targetDirectory) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) modules = [] for file in sorted(list(foundations.walkers.filesWalker(sourceDirectory, filtersIn=("{0}.*\.py$".format(path),), filtersOut=EXCLUDED_PYTHON_MODULES))): LOGGER.info("{0} | Python file: '{1}'".format(getSphinxDocumentationApi.__name__, file)) module = "{0}.{1}" .format((".".join(os.path.dirname(file).replace(sourceDirectory, "").split("/"))), foundations.strings.getSplitextBasename(file)).strip(".") LOGGER.info("{0} | Module name: '{1}'".format(getSphinxDocumentationApi.__name__, module)) directory = os.path.dirname(os.path.join(cloneDirectory, module.replace(".", "/"))) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) sourceFile = File(source) sourceFile.cache() trimFromIndex = trimEndIndex = None inMultilineString = inDecorator = False for i, line in enumerate(sourceFile.content): if re.search(r"__name__ +\=\= +\"__main__\"", line): trimFromIndex = i for pattern, value in CONTENT_SUBSTITUTIONS.iteritems(): if re.search(pattern, line): sourceFile.content[i] = re.sub(pattern, value, line) strippedLine = line.strip() if re.search(r"^\"\"\"", strippedLine): inMultilineString = not inMultilineString if inMultilineString: continue if re.search(r"^@\w+", strippedLine) and \ not re.search(r"@property", strippedLine) and \ not re.search(r"^@\w+\.setter", strippedLine) and \ not re.search(r"^@\w+\.deleter", strippedLine): inDecorator = True indent = re.search(r"^([ \t]*)", line) if re.search(r"^[ \t]*def \w+", sourceFile.content[i]) or \ re.search(r"^[ \t]*class \w+", sourceFile.content[i]): inDecorator = False if not inDecorator: continue sourceFile.content[i] = "{0}{1} {2}".format(indent.groups()[0], DECORATORS_COMMENT_MESSAGE, line) if trimFromIndex: LOGGER.info("{0} | Trimming '__main__' statements!".format(getSphinxDocumentationApi.__name__)) content = [sourceFile.content[i] for i in range(trimFromIndex)] content.append("{0}\n".format(STATEMENTS_UPDATE_MESSAGGE)) sourceFile.content = content sourceFile.write() if "__init__.py" in file: continue rstFilePath = "{0}{1}".format(module, FILES_EXTENSION) LOGGER.info("{0} | Building API file: '{1}'".format(getSphinxDocumentationApi.__name__, rstFilePath)) rstFile = File(os.path.join(outputDirectory, rstFilePath)) header = ["_`{0}`\n".format(module), "==={0}\n".format("="*len(module)), "\n", ".. automodule:: {0}\n".format(module), "\n"] rstFile.content.extend(header) functions = OrderedDict() classes = OrderedDict() moduleAttributes = OrderedDict() for member, object in moduleBrowser._readmodule(module, [source, ]).iteritems(): if object.__class__ == moduleBrowser.Function: if not member.startswith("_"): functions[member] = [".. autofunction:: {0}\n".format(member)] elif object.__class__ == moduleBrowser.Class: classes[member] = [".. autoclass:: {0}\n".format(member), " :show-inheritance:\n", " :members:\n"] elif object.__class__ == moduleBrowser.Global: if not member.startswith("_"): moduleAttributes[member] = [".. attribute:: {0}.{1}\n".format(module, member)] moduleAttributes and rstFile.content.append("Module Attributes\n-----------------\n\n") for moduleAttribute in moduleAttributes.itervalues(): rstFile.content.extend(moduleAttribute) rstFile.content.append("\n") functions and rstFile.content.append("Functions\n---------\n\n") for function in functions.itervalues(): rstFile.content.extend(function) rstFile.content.append("\n") classes and rstFile.content.append("Classes\n-------\n\n") for class_ in classes.itervalues(): rstFile.content.extend(class_) rstFile.content.append("\n") rstFile.write() modules.append(module) packagesModules["apiModules"].extend([module for module in modules if not "tests" in module]) packagesModules["testsModules"].extend([module for module in modules if "tests" in module]) apiFile = File(apiFile) apiFile.content.extend(TOCTREE_TEMPLATE_BEGIN) for module in packagesModules["apiModules"]: apiFile.content.append(" {0} <{1}>\n".format(module, "api/{0}".format(module))) for module in packagesModules["testsModules"]: apiFile.content.append(" {0} <{1}>\n".format(module, "api/{0}".format(module))) apiFile.content.extend(TOCTREE_TEMPLATE_END) apiFile.write()
def buildApi(packages, input, output, sanitizer, excludedModules=None): """ Builds the Sphinx documentation API. :param packages: Packages to include in the API. :type packages: list :param input: Input modules directory. :type input: unicode :param output: Output reStructuredText files directory. :type output: unicode :param sanitizer: Sanitizer python module. :type sanitizer: unicode :param excludedModules: Excluded modules. :type excludedModules: list :return: Definition success. :rtype: bool """ LOGGER.info("{0} | Building Sphinx documentation API!".format(buildApi.__name__)) sanitizer = importSanitizer(sanitizer) if os.path.exists(input): shutil.rmtree(input) os.makedirs(input) excludedModules = [] if excludedModules is None else excludedModules packagesModules = {"apiModules": [], "testsModules": []} for package in packages: package = __import__(package) path = foundations.common.getFirstItem(package.__path__) packageDirectory = os.path.dirname(path) for file in sorted( list(foundations.walkers.filesWalker(packageDirectory, filtersIn=("{0}.*\.ui$".format(path),)))): LOGGER.info("{0} | Ui file: '{1}'".format(buildApi.__name__, file)) targetDirectory = os.path.dirname(file).replace(packageDirectory, "") directory = "{0}{1}".format(input, targetDirectory) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) modules = [] for file in sorted( list(foundations.walkers.filesWalker(packageDirectory, filtersIn=("{0}.*\.py$".format(path),), filtersOut=excludedModules))): LOGGER.info("{0} | Python file: '{1}'".format(buildApi.__name__, file)) module = "{0}.{1}".format((".".join(os.path.dirname(file).replace(packageDirectory, "").split("/"))), foundations.strings.getSplitextBasename(file)).strip(".") LOGGER.info("{0} | Module name: '{1}'".format(buildApi.__name__, module)) directory = os.path.dirname(os.path.join(input, module.replace(".", "/"))) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) sanitizer.bleach(source) if "__init__.py" in file: continue rstFilePath = "{0}{1}".format(module, FILES_EXTENSION) LOGGER.info("{0} | Building API file: '{1}'".format(buildApi.__name__, rstFilePath)) rstFile = File(os.path.join(output, rstFilePath)) header = ["_`{0}`\n".format(module), "==={0}\n".format("=" * len(module)), "\n", ".. automodule:: {0}\n".format(module), "\n"] rstFile.content.extend(header) functions = OrderedDict() classes = OrderedDict() moduleAttributes = OrderedDict() for member, object in moduleBrowser._readmodule(module, [source, ]).iteritems(): if object.__class__ == moduleBrowser.Function: if not member.startswith("_"): functions[member] = [".. autofunction:: {0}\n".format(member)] elif object.__class__ == moduleBrowser.Class: classes[member] = [".. autoclass:: {0}\n".format(member), " :show-inheritance:\n", " :members:\n"] elif object.__class__ == moduleBrowser.Global: if not member.startswith("_"): moduleAttributes[member] = [".. attribute:: {0}.{1}\n".format(module, member)] moduleAttributes and rstFile.content.append("Module Attributes\n-----------------\n\n") for moduleAttribute in moduleAttributes.itervalues(): rstFile.content.extend(moduleAttribute) rstFile.content.append("\n") functions and rstFile.content.append("Functions\n---------\n\n") for function in functions.itervalues(): rstFile.content.extend(function) rstFile.content.append("\n") classes and rstFile.content.append("Classes\n-------\n\n") for class_ in classes.itervalues(): rstFile.content.extend(class_) rstFile.content.append("\n") rstFile.write() modules.append(module) packagesModules["apiModules"].extend([module for module in modules if not "tests" in module]) packagesModules["testsModules"].extend([module for module in modules if "tests" in module]) apiFile = File("{0}{1}".format(output, FILES_EXTENSION)) apiFile.content.extend(TOCTREE_TEMPLATE_BEGIN) for module in packagesModules["apiModules"]: apiFile.content.append(" {0} <{1}>\n".format(module, "api/{0}".format(module))) for module in packagesModules["testsModules"]: apiFile.content.append(" {0} <{1}>\n".format(module, "api/{0}".format(module))) apiFile.content.extend(TOCTREE_TEMPLATE_END) apiFile.write() return True
def getSphinxDocumentationApi(packages, cloneDirectory, outputDirectory, apiFile): """ This definition gets Sphinx documentation API. :param packages: Packages. ( String ) :param cloneDirectory: Source clone directory. ( String ) :param outputDirectory: Content directory. ( String ) :param apiFile: API file. ( String ) """ LOGGER.info("{0} | Building Sphinx documentation API!".format( getSphinxDocumentationApi.__name__)) if os.path.exists(cloneDirectory): shutil.rmtree(cloneDirectory) os.makedirs(cloneDirectory) packagesModules = {"apiModules": [], "testsModules": []} for package in packages.split(","): package = __import__(package) path = foundations.common.getFirstItem(package.__path__) sourceDirectory = os.path.dirname(path) for file in sorted( list( foundations.walkers.filesWalker( sourceDirectory, filtersIn=("{0}.*\.ui$".format(path), )))): LOGGER.info("{0} | Ui file: '{1}'".format( getSphinxDocumentationApi.__name__, file)) targetDirectory = os.path.dirname(file).replace( sourceDirectory, "") directory = "{0}{1}".format(cloneDirectory, targetDirectory) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) modules = [] for file in sorted( list( foundations.walkers.filesWalker( sourceDirectory, filtersIn=("{0}.*\.py$".format(path), ), filtersOut=EXCLUDED_PYTHON_MODULES))): LOGGER.info("{0} | Python file: '{1}'".format( getSphinxDocumentationApi.__name__, file)) module = "{0}.{1}".format( (".".join( os.path.dirname(file).replace(sourceDirectory, "").split("/"))), foundations.strings.getSplitextBasename(file)).strip(".") LOGGER.info("{0} | Module name: '{1}'".format( getSphinxDocumentationApi.__name__, module)) directory = os.path.dirname( os.path.join(cloneDirectory, module.replace(".", "/"))) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) sourceFile = File(source) sourceFile.cache() trimFromIndex = trimEndIndex = None inMultilineString = inDecorator = False for i, line in enumerate(sourceFile.content): if re.search(r"__name__ +\=\= +\"__main__\"", line): trimFromIndex = i for pattern, value in CONTENT_SUBSTITUTIONS.iteritems(): if re.search(pattern, line): sourceFile.content[i] = re.sub(pattern, value, line) strippedLine = line.strip() if re.search(r"^\"\"\"", strippedLine): inMultilineString = not inMultilineString if inMultilineString: continue if re.search(r"^@\w+", strippedLine) and \ not re.search(r"@property", strippedLine) and \ not re.search(r"^@\w+\.setter", strippedLine) and \ not re.search(r"^@\w+\.deleter", strippedLine): inDecorator = True indent = re.search(r"^([ \t]*)", line) if re.search(r"^[ \t]*def \w+", sourceFile.content[i]) or \ re.search(r"^[ \t]*class \w+", sourceFile.content[i]): inDecorator = False if not inDecorator: continue sourceFile.content[i] = "{0}{1} {2}".format( indent.groups()[0], DECORATORS_COMMENT_MESSAGE, line) if trimFromIndex: LOGGER.info("{0} | Trimming '__main__' statements!".format( getSphinxDocumentationApi.__name__)) content = [sourceFile.content[i] for i in range(trimFromIndex)] content.append("{0}\n".format(STATEMENTS_UPDATE_MESSAGGE)) sourceFile.content = content sourceFile.write() if "__init__.py" in file: continue rstFilePath = "{0}{1}".format(module, FILES_EXTENSION) LOGGER.info("{0} | Building API file: '{1}'".format( getSphinxDocumentationApi.__name__, rstFilePath)) rstFile = File(os.path.join(outputDirectory, rstFilePath)) header = [ "_`{0}`\n".format(module), "==={0}\n".format("=" * len(module)), "\n", ".. automodule:: {0}\n".format(module), "\n" ] rstFile.content.extend(header) functions = OrderedDict() classes = OrderedDict() moduleAttributes = OrderedDict() for member, object in moduleBrowser._readmodule( module, [ source, ]).iteritems(): if object.__class__ == moduleBrowser.Function: if not member.startswith("_"): functions[member] = [ ".. autofunction:: {0}\n".format(member) ] elif object.__class__ == moduleBrowser.Class: classes[member] = [ ".. autoclass:: {0}\n".format(member), " :show-inheritance:\n", " :members:\n" ] elif object.__class__ == moduleBrowser.Global: if not member.startswith("_"): moduleAttributes[member] = [ ".. attribute:: {0}.{1}\n".format(module, member) ] moduleAttributes and rstFile.content.append( "Module Attributes\n-----------------\n\n") for moduleAttribute in moduleAttributes.itervalues(): rstFile.content.extend(moduleAttribute) rstFile.content.append("\n") functions and rstFile.content.append("Functions\n---------\n\n") for function in functions.itervalues(): rstFile.content.extend(function) rstFile.content.append("\n") classes and rstFile.content.append("Classes\n-------\n\n") for class_ in classes.itervalues(): rstFile.content.extend(class_) rstFile.content.append("\n") rstFile.write() modules.append(module) packagesModules["apiModules"].extend( [module for module in modules if not "tests" in module]) packagesModules["testsModules"].extend( [module for module in modules if "tests" in module]) apiFile = File(apiFile) apiFile.content.extend(TOCTREE_TEMPLATE_BEGIN) for module in packagesModules["apiModules"]: apiFile.content.append(" {0} <{1}>\n".format( module, "api/{0}".format(module))) for module in packagesModules["testsModules"]: apiFile.content.append(" {0} <{1}>\n".format( module, "api/{0}".format(module))) apiFile.content.extend(TOCTREE_TEMPLATE_END) apiFile.write()
def buildApi(packages, input, output, sanitizer, excludedModules=None): """ Builds the Sphinx documentation API. :param packages: Packages to include in the API. :type packages: list :param input: Input modules directory. :type input: unicode :param output: Output reStructuredText files directory. :type output: unicode :param sanitizer: Sanitizer python module. :type sanitizer: unicode :param excludedModules: Excluded modules. :type excludedModules: list :return: Definition success. :rtype: bool """ LOGGER.info("{0} | Building Sphinx documentation API!".format( buildApi.__name__)) sanitizer = importSanitizer(sanitizer) if os.path.exists(input): shutil.rmtree(input) os.makedirs(input) excludedModules = [] if excludedModules is None else excludedModules packagesModules = {"apiModules": [], "testsModules": []} for package in packages: package = __import__(package) path = foundations.common.getFirstItem(package.__path__) packageDirectory = os.path.dirname(path) for file in sorted( list( foundations.walkers.filesWalker( packageDirectory, filtersIn=("{0}.*\.ui$".format(path), )))): LOGGER.info("{0} | Ui file: '{1}'".format(buildApi.__name__, file)) targetDirectory = os.path.dirname(file).replace( packageDirectory, "") directory = "{0}{1}".format(input, targetDirectory) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) modules = [] for file in sorted( list( foundations.walkers.filesWalker( packageDirectory, filtersIn=("{0}.*\.py$".format(path), ), filtersOut=excludedModules))): LOGGER.info("{0} | Python file: '{1}'".format( buildApi.__name__, file)) module = "{0}.{1}".format( (".".join( os.path.dirname(file).replace(packageDirectory, "").split("/"))), foundations.strings.getSplitextBasename(file)).strip(".") LOGGER.info("{0} | Module name: '{1}'".format( buildApi.__name__, module)) directory = os.path.dirname( os.path.join(input, module.replace(".", "/"))) if not foundations.common.pathExists(directory): os.makedirs(directory) source = os.path.join(directory, os.path.basename(file)) shutil.copyfile(file, source) sanitizer.bleach(source) if "__init__.py" in file: continue rstFilePath = "{0}{1}".format(module, FILES_EXTENSION) LOGGER.info("{0} | Building API file: '{1}'".format( buildApi.__name__, rstFilePath)) rstFile = File(os.path.join(output, rstFilePath)) header = [ "_`{0}`\n".format(module), "==={0}\n".format("=" * len(module)), "\n", ".. automodule:: {0}\n".format(module), "\n" ] rstFile.content.extend(header) functions = OrderedDict() classes = OrderedDict() moduleAttributes = OrderedDict() for member, object in moduleBrowser._readmodule( module, [ source, ]).iteritems(): if object.__class__ == moduleBrowser.Function: if not member.startswith("_"): functions[member] = [ ".. autofunction:: {0}\n".format(member) ] elif object.__class__ == moduleBrowser.Class: classes[member] = [ ".. autoclass:: {0}\n".format(member), " :show-inheritance:\n", " :members:\n" ] elif object.__class__ == moduleBrowser.Global: if not member.startswith("_"): moduleAttributes[member] = [ ".. attribute:: {0}.{1}\n".format(module, member) ] moduleAttributes and rstFile.content.append( "Module Attributes\n-----------------\n\n") for moduleAttribute in moduleAttributes.itervalues(): rstFile.content.extend(moduleAttribute) rstFile.content.append("\n") functions and rstFile.content.append("Functions\n---------\n\n") for function in functions.itervalues(): rstFile.content.extend(function) rstFile.content.append("\n") classes and rstFile.content.append("Classes\n-------\n\n") for class_ in classes.itervalues(): rstFile.content.extend(class_) rstFile.content.append("\n") rstFile.write() modules.append(module) packagesModules["apiModules"].extend( [module for module in modules if not "tests" in module]) packagesModules["testsModules"].extend( [module for module in modules if "tests" in module]) apiFile = File("{0}{1}".format(output, FILES_EXTENSION)) apiFile.content.extend(TOCTREE_TEMPLATE_BEGIN) for module in packagesModules["apiModules"]: apiFile.content.append(" {0} <{1}>\n".format( module, "api/{0}".format(module))) for module in packagesModules["testsModules"]: apiFile.content.append(" {0} <{1}>\n".format( module, "api/{0}".format(module))) apiFile.content.extend(TOCTREE_TEMPLATE_END) apiFile.write() return True