Commits

Joshua Bonsink committed 0524725

Extended the framework to make it possible for more bot-server-botmaster communication.

Comments (0)

Files changed (8)

         """Initialize the logger."""
         logging.basicConfig()
         logger = logging.getLogger(self.name)
-        # self.logger.setLevel(logging.DEBUG)
+        logger.setLevel(logging.DEBUG)
         logger.setLevel(logging.WARNING)
         return logger
     
             print 'Pickle error'  
             return
                 
-        self.logger.debug('event_name will be triggered: ' + unpickled.event)
+        self.logger.debug('event_name will be triggered: ' + unpickled.event)        
         self.trigger(unpickled.event, sock, unpickled)
 
     def install(self, node):

core/cmd/command.py

     def __init__(self):
         """"""
         self.event = 'echo'
-        self.msg = 'verified, hi master, what you want to do'
+        self.msg = 'verified, hi master, what you want to do'
+        
+class NewAddressCmd(object):
+    
+    """"""
+    
+    def __init__(self):
+        """"""
+        self.event = 'add_address'
+        self.addresses = ''

core/cmd/description.py

         Description.__init__(self)
         self.initial = 'waiting'
         self.start_action = 'initialize'
-
+        self.master_password = '1234'
+         
 class BotmasterDescription(Description):
     
     """
         Description.__init__(self)    
         self.inital = 'waiting'
         self.start_action = 'request_connect'
+        self.master_password = '1234'
+        self.interval = 2 
+        self.num_commands = 1
+        self.command = None   
 
 class ClientDescription(Description):
     

core/nodes/base_node.py

     def set_master_sock(self, sock):
         """Set a socket as the master socket."""
         self.sockets[sock]['type'] = 'master'
-
+    
+    @property
+    def master_sock(self):
+        """Return the master socket."""               
+        for sock, val in self.sockets.iteritems():
+            if val['type'] == 'master': return sock
+        
+        return None
+    
     @property
     def client_socks(self):
         """Return an array containing the client sockets."""

core/nodes/botmaster.py

 """This file defines the bot master Command Meta Description"""
 
 import sys
+import argparse
 import doctest
 import jsonpickle
 
         """ 
         abstract_method()
 
-    def echo(self, data):
-        """Print received data to the console."""
-        print 'recv from server: ', data
-
 class BotMasterManInput(BotMaster):
     
     """
     
     """
     
-    @staticmethod
-    def print_help():
-        """Print help"""
-        docs = """
-        A typical command consists of a series of equality sentences
-        for example:
-            event=forward_to_bots;bot_event=send_ping;hostname=127.0.0.1;
-        which means:
-            event is the command that will run on server, "forward_to_bots" will
-            be executed this time.
-            bot_event is the command that will executed on bots
-            hostname is the parameter for the send_ping command
-        """
-        print docs
-
-    def recv_ack(self):
-        """Send and receive data to the server."""
-        print 'connection constructed'
-        while True:
-            cmd = raw_input('hi master, please input your command\
-                (h for help): ')
-            if cmd == 'h':
-                self.print_help()
-                continue
-            print 'the following command will to send to execute: ', cmd
-            if cmd == 'q':
-                self.node.send(self.sock, 'master exit')
-                self.node.close_sock(self.sock)
-                break
-
-            self.node.send(self.sock, jsonpickle.encode(cmd))
-            self.node.recv(self.sock, 512, self.echo, threaded=True)
-        print 'finish recv_ack'
-
-class BotMasterOneCMD(BotMaster):
-    """
-   
-    This class is a subclass of BotMaster. It extends the superclass with 
-    methods to periodically send out commands. This bot master will not take
-    responsibility to check whether the commands have been executed or not.
-
-    """
-    def __init__(self, desc, master_password, interval, num_commands, command):
+    def __init__(self, desc):
         """
         
         Bot master that verifies itself with the server and sends commands.
         """
         BotMaster.__init__(self, desc)
                 
-        self.verification_command = VerificationCmd(master_password)
-        self.command = command
-        self.interval = interval
-        self.num_commands = num_commands
+        self.verification_command = VerificationCmd(desc.master_password)
+    
+    def parse_arguments(self):    
+        abstract_method()
+            
+    def recv_ack(self):
+        abstract_method()
+    
+class BotMasterOneCMD(BotMaster):
+    """
+   
+    This class is a subclass of BotMaster. It extends the superclass with 
+    methods to periodically send out commands. This bot master will not take
+    responsibility to check whether the commands have been executed or not.
+
+    """
+    def __init__(self, desc):
+        """
+        
+        Bot master that verifies itself with the server and sends commands.
+        One command will be sent automatically.
+
+        Keyword arguments:
+        desc -- specify the server information .
+        master_password -- the password used for verification with the server.
+        interval -- the interval between two consecutive command.
+        num_commands -- the total number of commands that will be sent.
+        command -- the command specification (object)
+        
+        """
+        BotMaster.__init__(self, desc)
+                
+        self.verification_command = VerificationCmd(desc.master_password)
 
     def recv_ack(self):
         """
         self.node.send(self.sock, jsonpickle.encode(self.verification_command))
 
         # Sleep for a while to make sure it has been verified
-        self.node.sleep(self.interval)
-
-        idx = self.num_commands
+        self.node.sleep(self.desc.interval)
+        
+        idx = self.desc.num_commands
         while True:
             if idx == 0: 
                 break
             idx -= 1
-            # print 'send command out', self.cmd_str
-            self.node.send(self.sock, jsonpickle.encode(self.command) )
-            self.node.sleep(self.interval)
+            
+            self.node.send(self.sock, jsonpickle.encode(self.desc.command) )
+            self.node.sleep(self.desc.interval)
 
 class BotMasterTest(BotMasterOneCMD):
     

core/nodes/client.py

         print 'connection constructed'
         self.node.recv(self.sock, 512, self.dispatcher)
 
-    def echo(self, data):
+    def echo(self, sock, data):
         """Echo a message."""
-        self.logger.info("receive echo message, [%s]"%(data['msg'][0]))
-        print '-->', data['msg'][0]
+        self.logger.info("receive echo message, [%s]" % (data.msg))
+        print '-->', data.msg
 
     def start(self):
         """

core/nodes/server.py

 from core.cmd.description import ServerDescription
 from core.cmd.command import EchoCmd
 
-BOT_MASTER_PASSWORD = '1234'
-
 class ServerCMD(CMD):
     
     """
 
     def verify_master(self, sock, data):
         """Verify the identity of the bot master."""
-        if data.password == BOT_MASTER_PASSWORD:
+        if data.password == self.desc.master_password:
             self.logger.info( 'bot master password verified' )
             self.node.set_master_sock(sock)
             self.node.send(sock, jsonpickle.encode(EchoCmd()))
         for client_sock in self.node.client_socks:            
             self.node.send(client_sock, jsonpickle.encode(new_data))
             
+    def send_to_bot(self, sock, data):
+        """Forward data to all the bots"""
+        self.logger.info('send cmd to bot' )
+        new_data = copy.deepcopy(data)
+        new_data.event = data.bot_event
+        
+        del new_data.bot_event
+        del new_data.addr
+        
+        for sock in self.node.sockets:
+            if self.node.sockets[sock]['type'] == 'client':
+                if self.node.sockets[sock]['addr'] == data.addr: 
+                    self.node.send(sock, jsonpickle.encode(new_data))
+            
     def disconnect(self):
         """Log a disconnect request."""
         self.logger.info('receive disconnect request')

core/real/node.py

     def set_master_sock(self, sock):
         """Set a socket as the master socket."""
         self.sockets[sock]['type'] = 'master'
-
+    
+    @property
+    def master_sock(self):
+        """Return the master socket."""               
+        for sock, val in self.sockets.iteritems():
+            if val['type'] == 'master': return sock
+        
+        return None
+    
     @property
     def client_socks(self):
         """Return an array containing the client sockets."""