Esempio n. 1
0
async def run_command(msg):
    if cc.my_state_event[cc.State.TERMINATING].is_set():
        return False
    cc.change_my_state(state=cc.State.COORDINATING)
    formatted_command = format_command(cmd=msg.data)
    for module_name, command_key, command_dict in get_all_commands():
        if command_key in formatted_command:
            #if intersect_strings(command_key, formatted_command).get("char_count", 0) >= 2:
            # test = command_key.split(" ")
            # try:
            #     answer = set(test).issubset(set(formatted_command))
            # except:
            #     traceback.print_exc()
            # if answer:
            #actually run the command
            dprint(command_key)
            module_function = getattr(sys.modules[module_name],
                                      command_dict[Command.FUNCTION])
            result = await module_function(msg)
            if result != False:
                cc.change_my_state(state=cc.State.LISTENING)
                return result
    aprint("I don't know what you mean by \'", msg.data, "\'.")
    cc.change_my_state(state=cc.State.LISTENING)
    return False
Esempio n. 2
0
async def get_voice_input(loop):
    '''Waits for a line of input from system microphone.
    Throws an EnvironmentError if no microphone could be setup.
    '''
    if not mic:
        if not setup_microphone():
            raise EnvironmentError
    try:
        result_future = asyncio.Future()

        def threaded_listen():
            global mic
            global r
            result = None
            with mic as source:
                try:
                    audio = r.listen(source, phrase_time_limit=10)
                    result = r.recognize_google(audio)
                except Exception as ex:
                    dprint(ex)
            if result:
                loop.call_soon_threadsafe(result_future.set_result, result)
            else:
                loop.call_soon_threadsafe(result_future.set_exception,
                                          ValueError)
            return True

        listener_thread = threading.Thread(target=threaded_listen)
        listener_thread.daemon = True
        listener_thread.start()
        return await result_future
    except Exception as ex:
        dprint(ex)
    return None
Esempio n. 3
0
def load_commands():
    global command_modules
    dprint("Loading commands...")
    command_modules = []
    for module_filename in os.listdir(COMMANDS_DIRECTORY):
        module_name, extension = os.path.splitext(module_filename)
        if "__init__" in module_name or extension != ".py":
            continue
        try:
            #import module
            #module = import_module(os.path.join(COMMANDS_DIRECTORY, module_filename))
            #spec = util.spec_from_file_location(os.path.splitext(module_filename)[0], os.path.join(COMMANDS_DIRECTORY, module_filename))
            #dprint(spec)
            #mod = util.module_from_spec(spec)
            #spec.loader.exec_module(mod)
            #dprint(mod.__name__)
            #mod = sys.modules[mod.__name__]
            #collect module's commands
            mod_path = '.'.join(
                (os.path.basename(COMMANDS_DIRECTORY), module_name))
            mod = sys.modules[mod_path]
            if mod._commands != None:
                dprint(mod_path, " commands: ", mod._commands)
                command_modules.append(mod_path)
        except Exception as _:
            traceback.print_exc()
Esempio n. 4
0
async def update_resources(msg):
    '''Message header must contain str(Resource.SECTION):section.
    Message data must contain a dict of resources.
    Updates the local resources with the given ones.
    '''
    dprint("updating resources from ", msg.sender_mac)
    propagate = (
        cerebratesinfo.get_overmind_mac() == mysysteminfo.get_mac_address())
    section = None
    for header in msg.header:
        if str(Resource.SECTION) in header:
            split_header = header.split(':')
            if len(split_header) <= 1:
                continue
            section = split_header[len(split_header) - 1]
            if section:
                break
    if not section:
        return cc.CLOSE_CONNECTION, "no section supplied in header"
    for resources in msg.data:
        #if Overmind receives new information then propagate it to other cerebrates
        if resource_handler.update_resources(
                section=section, resources=resources) and propagate:
            communication.Secretary.broadcast_message(
                msg=communication.Message("update_resources",
                                          ':'.join((str(Resource.SECTION),
                                                    section)),
                                          data=[resources]))
    return cc.CLOSE_CONNECTION, "resources updated"
Esempio n. 5
0
async def acknowledge(msg):
    '''Initiates file and record updating between cerebrates.
    When a cerebrate comes online it broadcasts to other cerebrates asking for acknowledgment.
    Only the Overmind responds.
    '''
    #Only respond if local is the Overmind
    if cerebratesinfo.get_overmind_mac() != mysysteminfo.get_mac_address():
        return cc.CLOSE_CONNECTION, cc.FINISHED
    dprint("acknowledging")
    #Send a current list of records
    await communication.Secretary.communicate_message(
        cerebrate_mac=msg.sender_mac,
        msg=communication.Message(
            "update_records",
            cc.RECIPROCATE,
            cc.OVERRULE,
            data=cerebratesinfo.get_cerebrate_records_list()))
    #Send a current list of resources
    await _send_all_resources(cerebrate_mac=msg.sender_mac)
    #Get a current list of their resources
    await communication.Secretary.communicate_message(
        cerebrate_mac=msg.sender_mac,
        msg=communication.Message("send_resources"))
    #Ensure up-to-date files
    if msg.data.get("version", None):
        return await check_version(msg=msg)
    return cc.CLOSE_CONNECTION, cc.SUCCESS
Esempio n. 6
0
def update_cerebrate_record(cerebrate_record):
    '''Overwrites the appropriate cerebrate record with the given record.
    Creates a new one if the given cerebrate does not exist.
    Returns False if no MAC is given in record.
    '''
    mac = cerebrate_record.get(Record.MAC, None)
    if not mac:
        logging.warning('No MAC address provided in record:')
        logging.info(''.join(("record: ", str(cerebrate_record))))
        return False
    with shelve.open(CEREBRATE_RECORDS, writeback=True) as db:
        if not db.get(mac, None):
            db[mac] = default_dictionary()
        cerebrate_time = cerebrate_record.get(Record.LASTCONTACT,
                                              datetime.datetime(1, 1, 1))
        db_time = db[mac].get(Record.LASTCONTACT, datetime.datetime(1, 1, 1))
        #print(cerebrate_time, " vs ", db_time)
        if cerebrate_time >= db_time:
            #print("Updating '", mac, "' record")
            dprint("Updating record:")
            dprint(cerebrate_record)
            db[mac] = cerebrate_record
            return True
        else:
            dprint("Out of date:")
            dprint(cerebrate_record)
            return False
    return True
Esempio n. 7
0
async def _designate_overmind(mac):
    if cerebratesinfo.get_overmind_mac() == mac:
        return
    dprint("designating ", mac)
    cerebratesinfo.designate_overmind(mac=mac)
    if mac != mysysteminfo.get_mac_address():
        '''shouldn't need to ask for acknowledgment, cerebrates are already up to date'''
        #dprint("asking for acknowledgment")
        #await communication.Secretary.communicate_message(cerebrate_mac=mac, msg=communication.Message("acknowledge", data={"version": cc.my_version}))
    else:
        communication.Secretary.broadcast_message(msg=communication.Message(
            "update_records",
            cc.OVERRULE,
            data=[cerebratesinfo.get_overmind_record()]))
Esempio n. 8
0
 def threaded_listen():
     global mic
     global r
     result = None
     with mic as source:
         try:
             audio = r.listen(source, phrase_time_limit=10)
             result = r.recognize_google(audio)
         except Exception as ex:
             dprint(ex)
     if result:
         loop.call_soon_threadsafe(result_future.set_result, result)
     else:
         loop.call_soon_threadsafe(result_future.set_exception,
                                   ValueError)
     return True
Esempio n. 9
0
async def run_command(msg):
    '''Given a Message, runs the contained command if possible 
    Returns an action, data pair.
    '''
    if cc.my_state_event[cc.State.TERMINATING].is_set():
        return cc.CLOSE_CONNECTION, "cerebrate terminating"
    formatted_header = command.format_header(header=msg.header)
    cerebratesinfo.update_cerebrate_contact_time(
        mac=mysysteminfo.get_mac_address())
    for key, _ in commands.items():
        if key in formatted_header:
            dprint("before: ", cerebratesinfo.get_overmind_mac())
            result = await commands[key][command.Command.FUNCTION](msg)
            dprint("after: ", cerebratesinfo.get_overmind_mac())
            return result
    return cc.CLOSE_CONNECTION, "command not recognized"
Esempio n. 10
0
async def audio_listener(loop):
    await cc.my_state_event[cc.State.LISTENING].wait()
    while not cc.my_state_event[cc.State.TERMINATING].is_set():
        try:
            voice_input = await audio.get_voice_input(loop)
            if not voice_input:
                continue
            if not cc.accept_audio_control.is_set():
                if not "eddie" in voice_input.lower():
                    dprint("ignore input")
                    continue
            voice_input = voice_input.replace('Eddie', '', 1).strip()
            await command.run_command(
                msg=communication.Message("cmd", "voice", data=voice_input))
        except EnvironmentError:
            cc.accept_audio_control.clear()
        except Exception:
            traceback.print_exc()
Esempio n. 11
0
 async def communicate_message(cerebrate_mac, msg:Message):
     """Opens a TCP connection with the given cerebrate, provided they are running a Secretary.
     Returns a cc.SUCCESS if connection and initial write are successful.
     No guarantee after that.
     """
     #print("Communicating: ", msg.header)
     dprint(msg.data)
     result_string = "Fail"
     try:
         reader, writer = await Secretary.__initiate_connection(cerebrate_mac=cerebrate_mac)
         if not reader or not writer:
             return result_string
         await Secretary._write_message(writer=writer, msg=msg)
         asyncio.ensure_future(Secretary.__connection_made(reader=reader, writer=writer))
         result_string = cc.SUCCESS
     except asyncio.TimeoutError:
         print(cerebrate_mac, " timed out")
         Secretary._timed_out(mac=cerebrate_mac)
     return result_string
Esempio n. 12
0
async def send_update(msg):
    version = msg.data.get("version", None)
    if not version:
        return cc.CLOSE_CONNECTION, "requester's version number not included"
    if version >= cc.my_version:
        return cc.CLOSE_CONNECTION, "requester not out of date"
    requirements.update_requirements()
    dprint("Sending updates to ", msg.sender_mac)
    files = await get_cerebrate_file_names()
    success = await communication.Secretary.transfer_files(
        cerebrate_mac=msg.sender_mac, file_names=files)
    if success:
        await communication.Secretary.communicate_message(
            cerebrate_mac=msg.sender_mac,
            msg=communication.Message("restart", data="cerebrate updated"))
    else:
        dprint("FAILED TO UPDATE ", msg.sender_mac)
        return cc.CLOSE_CONNECTION, "failed"
    return cc.CLOSE_CONNECTION, cc.SUCCESS
Esempio n. 13
0
async def update_records(msg):
    '''Message data must contain a list of cerebrate records.
    Updates the local cerebrate records with the given ones, if the given ones contain more recent information.
    If CC.RECIPROCATE is in the header a Message containing the local copy of updated cerebrate records will be returned.
    '''
    if cc.OVERRULE in msg.header:
        dprint("Being overruled")
        await _designate_overmind(mac=msg.sender_mac)
    dprint("updating records from ", msg.sender_mac)
    propagate = (
        cerebratesinfo.get_overmind_mac() == mysysteminfo.get_mac_address())
    for record in msg.data:
        #if Overmind receives new information then propagate it to other cerebrates
        if cerebratesinfo.update_cerebrate_record(
                cerebrate_record=record) and propagate:
            communication.Secretary.broadcast_message(
                msg=communication.Message("update_records", data=[record]))
    if cc.RECIPROCATE in msg.header:
        return cc.REMOTE_COMMAND, communication.Message(
            "update_records", data=cerebratesinfo.get_cerebrate_records_list())
    return cc.CLOSE_CONNECTION, "records updated"
Esempio n. 14
0
 def __exit__(self, type, value, traceback):
     dprint("Finished bypassing lock")
Esempio n. 15
0
 def __enter__(self):
     dprint("Bypassing lock")
     return True
Esempio n. 16
0
async def assume_overmind(msg):
    '''Sets self as Overmind, broadcasts the change to others.
    '''
    dprint("Assuming Overmind")
    await _designate_overmind(mac=mysysteminfo.get_mac_address())
    return cc.CLOSE_CONNECTION, cc.SUCCESS