Project

General

Profile

Download (3.57 KB) Statistics
| Branch: | Tag: | Revision:
#--
# CyborgHood, a distributed system management software.
# Copyright (c) 2009-2010 Marc Dequènes (Duck) <Duck@DuckCorp.org>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#++

require 'singleton'


module CyborgHood
module CyborgServerInterface
def self.included(base)
base.class_eval("include Singleton")
base.extend(ClassMethods)
end

def find_node_action(node_name)
next_node_name, other_nodes_names = node_name.split('.', 2)

next_node_klass = api_klasses[next_node_name]
if next_node_klass.nil?
if api_methods.include? next_node_name
next_node_method = self.method(next_node_name)
return next_node_method if other_nodes_names.nil?
next_node = next_node_method.call
else
return
end
else
next_node = next_node_klass.instance
return next_node.method('api_nodes') if other_nodes_names.nil?
end

next_node.find_node_action(other_nodes_names)
end

module ClassMethods
attr_accessor :exported_methods
attr_accessor :auto_export_public_instance_methods

def export_method(syms)
syms = [syms] unless syms.is_a? Array
self.exported_methods ||= []
self.exported_methods += syms.collect{|m| m.to_s }
end
end

def initialize
@config = Config.instance

self.class.exported_methods ||= []
self.class.auto_export_public_instance_methods = true
end

def api_klasses
list = self.class.constants.collect do |c|
cc = self.class.const_get(c)
(cc.class == Class and cc.ancestors.include? CyborgServerInterface) ? [c, cc] : nil
end.compact
Hash[list]
end

def api_methods
methods = self.class.exported_methods
methods += self.class.public_instance_methods(false) if self.class.auto_export_public_instance_methods
methods & self.methods
end

def api_nodes
(api_klasses.keys + api_methods).sort
end

# preliminary incoming message handling
def call(cmd, data)
action = find_node_action(cmd)
return "551 unknown node" if action.nil?

if data.nil?
formated_data = []
else
begin
formated_data = YAML.load(data) unless data.nil?
rescue
return "552 unreadable YAML data for arguments"
end

return "552 wrong format for arguments" unless formated_data.is_a? Array
end

begin
# preliminary outgoing message handling
action.call(*formated_data).to_yaml
rescue
return "550 method call failed: " + $!
end
end
end

module CyborgServerDefaultInterface
PROTOCOL_VERSION = "0.1~"

def self.included(base)
list = self.public_instance_methods(false)
base.class_eval do
export_method list
end
end

def product_name
PRODUCT
end

def product_version
VERSION
end

def protocol_version
PROTOCOL_VERSION
end

def bot_name
@config.bot_name
end
end
end
(1-1/2)