Ejemplo n.º 1
0
def update_my_record():
    '''Updates the local cerebrate's record (mostly IP address, but also sets defaults for any attributes without values).
    '''
    my_record = get_cerebrate_record(
        record_attribute=Record.MAC,
        attribute_value=mysysteminfo.get_mac_address()) or default_dictionary(
        )
    my_record[Record.NAME] = my_record.get(Record.NAME, MY_RECORD_DEFAULT_NAME)
    my_record[Record.MAC] = my_record.get(Record.MAC,
                                          mysysteminfo.get_mac_address())
    my_record[Record.IP] = mysysteminfo.get_ip_address()
    my_record[Record.LASTCONTACT] = datetime.datetime.now()
    my_record[Record.STATUS] = Status.AWAKE
    my_record[Record.ROLE] = my_record.get(Record.ROLE, Role.DRONE)
    update_cerebrate_record(cerebrate_record=my_record)
Ejemplo n.º 2
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"
Ejemplo n.º 3
0
async def send_message(msg):
    data = msg.data
    recipients = []
    for cerebrate in cerebratesinfo.get_cerebrate_records():
        name = cerebrate.get(cerebratesinfo.Record.NAME, "")
        if name in data:
            mac = cerebrate.get(cerebratesinfo.Record.MAC, "")
            if not mac in recipients:
                recipients.append(mac)
                communication.distill_msg(msg, name)
    for cerebrate in cerebratesinfo.get_cerebrate_records():
        location = cerebrate.get(cerebratesinfo.Record.LOCATION, "")
        if location in data:
            mac = cerebrate.get(cerebratesinfo.Record.MAC, "")
            if not mac in recipients:
                recipients.append(mac)
                communication.distill_msg(msg, location)
    if recipients.__len__() <= 0:
        recipients = cerebratesinfo.get_cerebrate_macs()
        recipients.remove(mysysteminfo.get_mac_address())
    for recipient in recipients:
        await communication.Secretary.communicate_message(
            cerebrate_mac=recipient,
            msg=communication.Message('display_message', data=msg.data))
    # speak msg
    #aprint("Message communicated")
    return True
Ejemplo n.º 4
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
Ejemplo n.º 5
0
def get_overmind_record():
    with shelve.open(CEREBRATE_RECORDS, flag='r') as db:
        return next((db[key] for key in db
                     if db[key].get(Record.ROLE, Role.DRONE) == Role.OVERMIND),
                    get_cerebrate_record(
                        record_attribute=Record.MAC,
                        attribute_value=mysysteminfo.get_mac_address()))
Ejemplo n.º 6
0
def update_resources(section: str, resources: dict):
    '''Updates resources if the given resources are more recent.
	Returns a dict of the updated resources.
	'''
    # NOT FULLY CORRECT: If local copy of resource has had more recent changes it will not accept the given resource even if given contains changes local has not seen
    updated_resources = {}
    try:
        with shelve.open(filename=_get_file_location(section=section),
                         flag='c',
                         writeback=True) as s:
            for key, value in resources.items():
                if key not in s.keys():
                    s[key] = value
                    updated_resources[key] = value
                elif value.get(MODIFIED_TIME, datetime.datetime(
                        1, 1, 1)) > s[key].get(MODIFIED_TIME,
                                               datetime.datetime(1, 1, 1)):
                    try:
                        #if resource is derived from Resource_BC
                        s[key][RESOURCE_VALUE].update(value[RESOURCE_VALUE])
                        s[key][MODIFIED_TIME] = value[MODIFIED_TIME]
                    except:
                        #resource is not derived from Resource_BC
                        s[key] = value
                    updated_resources[key] = s[key]
    except:
        raise
    if len(updated_resources) > 0 and get_mac_address(
    ) == cerebratesinfo.get_overmind_mac():
        propagate_resources(section=section,
                            timestamped_resources=updated_resources)
    return updated_resources
Ejemplo n.º 7
0
def say_hello():
    #Assume everyone is asleep
    for mac in cerebratesinfo.get_cerebrate_macs():
        cerebratesinfo.update_cerebrate_attribute(
            mac=mac,
            record_attribute=cerebratesinfo.Record.STATUS,
            attribute_value=cerebratesinfo.Status.ASLEEP)
    #Set self status to awake
    cerebratesinfo.update_cerebrate_attribute(
        mac=mysysteminfo.get_mac_address(),
        record_attribute=cerebratesinfo.Record.STATUS,
        attribute_value=cerebratesinfo.Status.AWAKE)
    #Assume we are the only cerebrate up, temporarily designate ourself as Overmind
    cerebratesinfo.designate_overmind(mac=mysysteminfo.get_mac_address())
    #Contact existing Overmind, if there is one
    communication.Secretary.broadcast_message(msg=communication.Message(
        'acknowledge', data={"version": cc.my_version}))
Ejemplo n.º 8
0
 def datagram_received(self, data, addr):
     msg = pickle.loads(data)
     if Secretary.terminating:
         return
     if msg.sender_mac == mysysteminfo.get_mac_address():
         return
     try:
         asyncio.ensure_future(handle_message(msg=msg))
     except Exception as _:
         traceback.print_exc()
Ejemplo n.º 9
0
def propagate_resources(section: str, timestamped_resources: dict):
    overmind_mac = cerebratesinfo.get_overmind_mac()
    msg = communication.Message("update_resources",
                                ':'.join((str(Resource.SECTION), section)),
                                data=[timestamped_resources])
    if get_mac_address() == overmind_mac:
        run_coroutine(communication.Secretary.broadcast_message(msg=msg))
    else:
        run_coroutine(
            communication.Secretary.communicate_message(
                cerebrate_mac=overmind_mac, msg=msg))
Ejemplo n.º 10
0
async def say_goodbye():
    #Set someone else as Overmind
    successor_mac = await designate_successor()
    #Tell Overmind that we are going to sleep
    # If no other cerebrate is online we end up sending this to ourselves, which is ignored
    cerebratesinfo.update_cerebrate_attribute(
        mac=mysysteminfo.get_mac_address(),
        record_attribute=cerebratesinfo.Record.STATUS,
        attribute_value=cerebratesinfo.Status.ASLEEP)
    cerebratesinfo.update_cerebrate_contact_time(
        mac=mysysteminfo.get_mac_address())
    await communication.Secretary.communicate_message(
        cerebrate_mac=successor_mac,
        msg=communication.Message(
            "update_records",
            data=[
                cerebratesinfo.get_cerebrate_record(
                    record_attribute=cerebratesinfo.Record.MAC,
                    attribute_value=mysysteminfo.get_mac_address())
            ]))
Ejemplo n.º 11
0
async def designate_successor():
    '''Establishes a new Overmind among the remaining (awake) cerebrates.
    Returns the new Overmind's mac address.
    '''
    successor_mac = cerebratesinfo.get_overmind_mac()
    if mysysteminfo.get_mac_address() == successor_mac:
        for record in cerebratesinfo.get_cerebrate_records():
            if record.get(cerebratesinfo.Record.MAC
                          ) == mysysteminfo.get_mac_address():
                continue
            if record.get(cerebratesinfo.Record.STATUS, cerebratesinfo.Status.
                          UNKNOWN) == cerebratesinfo.Status.AWAKE:
                if cerebratesinfo.designate_overmind(
                        mac=record.get(cerebratesinfo.Record.MAC, None)):
                    received = await communication.Secretary.communicate_message(
                        cerebrate_mac=record.get(cerebratesinfo.Record.MAC,
                                                 None),
                        msg=communication.Message("assume_overmind",
                                                  data=None))
                    if received == cc.SUCCESS:
                        successor_mac = record.get(cerebratesinfo.Record.MAC)
                        break
    return successor_mac
Ejemplo n.º 12
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()]))
Ejemplo n.º 13
0
def store_resources(section: str, resources: dict):
    '''Saves  resources for later reference, overwriting existing records with the same keys.
	Returns False if unsuccessful.
	'''
    try:
        if len(resources) <= 0:
            return True
        timestamped_resources = _update_resources_modified_time(resources)
        update_resources(section=section, resources=resources)
        if get_mac_address() != cerebratesinfo.get_overmind_mac():
            propagate_resources(section=section,
                                timestamped_resources=timestamped_resources)
    except Exception:
        traceback.print_exc()
        return False
    return True
Ejemplo n.º 14
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"
Ejemplo n.º 15
0
 async def __communicate(reader, writer):
     ''' Communicates with the cerebrate on the other end of reader, writer pair.
     Returns the reason (as string) for the end of communication.
     '''
     while not Secretary.terminating:
         msg = await Secretary._read_message(reader=reader)
         #print("Received: ", msg.header)
         if msg.sender_mac == mysysteminfo.get_mac_address():
             return "schizophrenia"
         action, message = await handle_message(msg=msg)
         if action == cc.CLOSE_CONNECTION:
             return message
         elif action == cc.FILE_TRANSFER:
             return await Secretary.__receive_files(reader=reader, writer=writer)
         else:
             await Secretary._write_message(writer=writer, msg=message)
     return "secretary terminating"
Ejemplo n.º 16
0
 async def __initiate_connection(cerebrate_mac):
     '''Tries to open a connection with given cerebrate.
     Throws an asyncio.TimeoutError if no connection is made.
     Returns a reader, writer pair. Both will be None if no connection is made.
     '''
     if cerebrate_mac == mysysteminfo.get_mac_address():
         return None, None
     global event_loop
     cerebrate_ip = cerebratesinfo.get_cerebrate_attribute(cerebrate_mac=cerebrate_mac, record_attribute=cerebratesinfo.Record.IP)
     reader, writer = None, None
     try:
         fut = asyncio.open_connection(host=cerebrate_ip, port=TCP_PORT, loop=event_loop)
         reader, writer = await asyncio.wait_for(fut, timeout=3)
         #Secretary._made_contact(mac=cerebrate_mac, ip=cerebrate_ip)
     except asyncio.TimeoutError:
         print("Failed to connect to ", cerebrate_ip)
         raise asyncio.TimeoutError()
     return reader, writer
Ejemplo n.º 17
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"
Ejemplo n.º 18
0
Archivo: info.py Proyecto: Hynchus/Hive
async def change(msg):
    attribute_recognized = False
    while True:
        cmd = command.format_command(msg.data)
        if "_mic" in cmd:
            attribute_recognized = True
            audio.list_microphones()
            input = prompt(prompt_string="\nMicrophone index: ")
            index = int(re.search(r'\d+', input).group())
            if index:
                if audio.setup_microphone(mic_index=index):
                    print("Microphone ", index, " is active")
                else:
                    print("Could not set microphone ", index)
            else:
                print("index not recognized")
        record = cerebratesinfo.get_cerebrate_record(
            record_attribute=cerebratesinfo.Record.MAC,
            attribute_value=mysysteminfo.get_mac_address())
        if record is None:
            aprint("My record has been misplaced")
            return False
        if "_name_" in cmd:
            attribute_recognized = True
            current_name = record.get(cerebratesinfo.Record.NAME, "unknown")
            aprint("Current name: ", current_name)
            record[cerebratesinfo.Record.NAME] = await prompt(
                prompt_string="New name")
            cerebratesinfo.update_cerebrate_record(cerebrate_record=record)
            aprint(current_name, " => ",
                   record.get(cerebratesinfo.Record.NAME, "unknown"))
        if "_location_" in cmd:
            attribute_recognized = True
            current_location = record.get(cerebratesinfo.Record.LOCATION,
                                          "unknown")
            aprint("Current location: ", current_location)
            record[cerebratesinfo.Record.LOCATION] = await prompt(
                prompt_string="New location")
            cerebratesinfo.update_cerebrate_record(cerebrate_record=record)
            aprint(current_location, " => ",
                   record.get(cerebratesinfo.Record.LOCATION, "unknown"))
        '''
        if "_role_" in cmd:
            attribute_recognized = True
            current_role = record.get(cerebratesinfo.Record.ROLE, "unknown")
            aprint("Current Role: ", current_role)
            for role in cerebratesinfo.Role:
                aprint(role.value, ") ", role.name)
            number = int(await prompt("New role (number)"))
            for role in cerebratesinfo.Role:
                if role.value == number:
                    cerebratesinfo.update_cerebrate_attribute(mysysteminfo.get_mac_address(), cerebratesinfo.Record.ROLE, role)
                    aprint(current_role.name, " => ", role.name)
                    break
        '''
        response = None
        if not attribute_recognized:
            return False
            #response = ''.join(("_", await prompt(prompt_string="What do you want changed? "), "_"))
        else:
            response = ''.join(
                ("_", await prompt(prompt_string="Any other changes? "), "_"))
        if "_nothing_" in response or "_no_" in response:
            break
        msg.data = response
        aprint("")
    #broadcast the changes we made to other cerebrates
    cerebratesinfo.update_cerebrate_contact_time(
        mac=mysysteminfo.get_mac_address())
    msg = communication.Message(
        "update_records",
        data=[
            cerebratesinfo.get_cerebrate_record(
                record_attribute=cerebratesinfo.Record.MAC,
                attribute_value=mysysteminfo.get_mac_address())
        ])
    if cerebratesinfo.get_overmind_mac() == mysysteminfo.get_mac_address():
        communication.Secretary.broadcast_message(msg=msg)
    else:
        await communication.Secretary.communicate_message(
            cerebrate_mac=cerebratesinfo.get_overmind_mac(), msg=msg)
    return True
Ejemplo n.º 19
0
 def __init__(self, *headers, data:list=None):
     self.sender_mac = mysysteminfo.get_mac_address()
     self.sender_ip = mysysteminfo.get_ip_address()
     self.header = [header for header in headers if header]
     self.data = data
Ejemplo n.º 20
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