diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index d46eab07b..ffc8b406f 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -123,6 +123,8 @@ namespace graphene { namespace app { if( _app.get_plugin( "affiliate_stats" ) ) _affiliate_stats_api = std::make_shared(std::ref(_app)); } + #include + return; } @@ -349,6 +351,7 @@ namespace graphene { namespace app { FC_ASSERT(_affiliate_stats_api); return *_affiliate_stats_api; } + #include #if 0 vector get_relevant_accounts( const object* obj ) diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 5e4f9c7e4..16be4c5ac 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -464,6 +464,8 @@ namespace detail { wild_access.allowed_apis.push_back( "crypto_api" ); wild_access.allowed_apis.push_back( "bookie_api" ); wild_access.allowed_apis.push_back( "affiliate_stats_api" ); + #include + _apiaccess.permission_map["*"] = wild_access; } diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index 44ce7b68b..7acea84ff 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -385,6 +386,7 @@ namespace graphene { namespace app { fc::api bookie()const; /// @brief Retrieve the affiliate_stats API (if available) fc::api affiliate_stats()const; + #include /// @brief Called to enable an API, not reflected. void enable_api( const string& api_name ); @@ -401,6 +403,7 @@ namespace graphene { namespace app { optional< fc::api > _debug_api; optional< fc::api > _bookie_api; optional< fc::api > _affiliate_stats_api; + #include }; }} // graphene::app diff --git a/libraries/plugins/CMakeLists.txt b/libraries/plugins/CMakeLists.txt index 01079fe29..ba2602fc7 100644 --- a/libraries/plugins/CMakeLists.txt +++ b/libraries/plugins/CMakeLists.txt @@ -1,11 +1,9 @@ -add_subdirectory( witness ) -add_subdirectory( account_history ) -add_subdirectory( accounts_list ) -add_subdirectory( affiliate_stats ) -add_subdirectory( market_history ) -add_subdirectory( delayed_node ) -add_subdirectory( bookie ) -add_subdirectory( generate_genesis ) -add_subdirectory( generate_uia_sharedrop_genesis ) -add_subdirectory( debug_witness ) -add_subdirectory( snapshot ) +# for each subdirectory containing a CMakeLists.txt, add that subdirectory +file( GLOB children RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} * ) +foreach( child ${children} ) + if( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${child}" ) + if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${child}/CMakeLists.txt" ) + add_subdirectory( "${child}" ) + endif() + endif() +endforeach() diff --git a/libraries/plugins/TestPlugin1/plugin.json b/libraries/plugins/TestPlugin1/plugin.json new file mode 100644 index 000000000..782fa63be --- /dev/null +++ b/libraries/plugins/TestPlugin1/plugin.json @@ -0,0 +1,6 @@ +{ + "plugin_name": "TestPlugin1", + "plugin_namespace": "TestPlugin1", + "plugin_project": "TestPlugin1_plugin" +} + \ No newline at end of file diff --git a/libraries/plugins/TestPlugin2/plugin.json b/libraries/plugins/TestPlugin2/plugin.json new file mode 100644 index 000000000..fc1dc0f5e --- /dev/null +++ b/libraries/plugins/TestPlugin2/plugin.json @@ -0,0 +1,6 @@ +{ + "plugin_name": "TestPlugin2", + "plugin_namespace": "TestPlugin2", + "plugin_project": "TestPlugin2_plugin" +} + \ No newline at end of file diff --git a/libraries/utilities/CMakeLists.txt b/libraries/utilities/CMakeLists.txt index f2d646d56..61ccd2a8b 100644 --- a/libraries/utilities/CMakeLists.txt +++ b/libraries/utilities/CMakeLists.txt @@ -1,3 +1,11 @@ +# Executes Python script to generate various files related to plugins +include(FindPythonInterp) +set (plugin_code_generator "libraries/utilities/plugin_code_generator.py") +execute_process( + COMMAND ${PYTHON_EXECUTABLE} ${plugin_code_generator} + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + ) + list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/libraries/fc/GitVersionGen" ) include( GetGitRevisionDescription ) get_git_head_revision(GIT_REFSPEC GRAPHENE_GIT_REVISION_SHA) diff --git a/libraries/utilities/plugin_code_generator.py b/libraries/utilities/plugin_code_generator.py new file mode 100644 index 000000000..367623994 --- /dev/null +++ b/libraries/utilities/plugin_code_generator.py @@ -0,0 +1,138 @@ +#!/usr/bin/python + +# Copyright (c) 2018 Blockchain B.V. +# +# The MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +################################################################################# +# This script is called everytime cmake is called. It generates code to certain # +# files which are related to the creation of plugins. # +# The working directory of the script is the project root directory. # +# Script is called from libraries/utilities/CMakeLists.txt # +################################################################################# + + +import json +import os + + +# list of files where generated code is used (relative to project root) +# libraries/app/include/graphene/api.hpp +# libraries/app/api.cpp +# libraries/app/application.cpp + +generated_files_root_dir = "libraries/utilities/include/graphene/utilities/" + +plugin_root_dir = "libraries/plugins/" + +generated_code_warning = "\ +/*****************************************/\n\ +/* This code is generated automatically. */\n\ +/* To generate new plugin code create a */\n\ +/* plugin.json file in a subdirectory */\n\ +/* of the plugin root directory. */\n\ +/*****************************************/\n\ +\n\ +\n" + +# this is a dictionary of the generated filename and the generated code +# variables in the code are replaced by the variables from the plugin.json file +templates = { +"generated_api_cpp_case_code.hpp": +"else if( api_name == \"{plugin_name}_api\" ) {{ \n\ + _{plugin_name}_api = std::make_shared< {plugin_name}_api >( std::ref(_app) );\n\ +}} \n", + +"generated_api_cpp_login_api_code.hpp": +"fc::api login_api::{plugin_name}() const \n\ +{{ \n\ + FC_ASSERT(_{plugin_name}_api); \n\ + return *_{plugin_name}_api; \n\ +}}\n\n", + +"generated_api_hpp_include_code.hpp": +"#include \n", + +"generated_api_hpp_login_api_method_def_code.hpp": +"/// @brief Retrieve the {plugin_name} API \n\ +fc::api {plugin_name}()const;\n", + +"generated_api_hpp_login_api_apiobj_code.hpp": +"optional< fc::api > _{plugin_name}_api;\n", + +"generated_api_hpp_reflect_code.hpp": +"({plugin_name})\n", + +"generated_application_cpp_allowed_apis_code.hpp": +"wild_access.allowed_apis.push_back( \"{plugin_name}_api\" );\n", + +} + + +# searches for all plugin.json files in the plugin directory +# parses them and returns a list of dictionarys with the parsed data +def get_all_plugin_data(): + + # holds content of all plugin.json files as dictionary + plugin_data_list = [] + # traverse plugin root dir search for plugin.json files + for root, dirs, files in os.walk( "./" + plugin_root_dir ): + for file in files: + if file == "plugin.json": + with open( os.path.join( root, file ) ) as f: + parsed_data = json.load( f ) + data_dic = dict() + data_dic['plugin_name'] = parsed_data['plugin_name'] + data_dic['plugin_namespace'] = parsed_data['plugin_namespace'] + data_dic['plugin_project'] = parsed_data['plugin_project'] + plugin_data_list.append( data_dic ) + + return plugin_data_list + + +def generate_all_files( plugin_data_list ): + print "--" + # t_fn = template_filename, t_con = template_content + for t_fn, t_con in templates.items(): + f_dir = os.path.join( generated_files_root_dir, t_fn ) + with open( f_dir, 'w') as f: + f.write( generated_code_warning ) + # p_data = plugin_data + for p_data in plugin_data_list: + # **p_data = values of the dic + content = t_con.format( **p_data ) + f.write( content ) + print( "-- plugin_code_generator: " + t_fn + " successfully generated" ) + + +def main(): + + plugin_data_list = get_all_plugin_data() + + generate_all_files( plugin_data_list ) + + print "-- plugin_code_generator: plugin code generation complete\n--" + + +if __name__ == "__main__": + main() + +