def ListContacts(request): """ Called when "ListContacts" packet is received, it keeps a list of suppliers OR customers and some extra info. I think this is a most important method here, call different code from here. """ global _CentralStatusDict global legal_codes global OnListSuppliersFunc global OnListCustomersFunc data = request.Payload dhnio.Dprint(6, 'central_service.ListContacts\n%s' % data) words = data.split('\n', 1) if len(words) < 2: dhnio.Dprint(1, 'central_service.ListContacts ERROR wrong data packet [%s]' % str(request.Payload)) return code = words[0] if not code in legal_codes: dhnio.Dprint(1, 'central_service.ListContacts ERROR wrong data in the packet [%s] ' % str(request.Payload)) return current_contacts = [] clist, tail = dhnio._unpack_list(words[1]) fire_flag = code.startswith('f') ban_flag = code.startswith('b') contact_type = code.lower()[-1] error_flag = code[-1].islower() spaceDict = None if tail is not None: # extract info about who is alive at the moment onlineArray = '' spaceDict = dhnio._unpack_dict_from_list(tail) if spaceDict.has_key('online'): onlineArray = spaceDict.pop('online') for i in range(len(onlineArray)): if i < len(clist): if clist[i]: _CentralStatusDict[clist[i]] = onlineArray[i] # extract info about contacts local ip # if they are in same LAN we need to connect to local IP, not external local_ips = {} i = 0 while True: idurl_and_local_ip = spaceDict.get('localip%03d' % i, None) if idurl_and_local_ip is None: break try: contact_idurl, contact_local_ip = idurl_and_local_ip.split('|') except: break local_ips[contact_idurl] = contact_local_ip spaceDict.pop('localip%03d' % i) i += 1 dhnio.Dprint(6, 'central_service.ListContacts got local IP for %s: %s' % (nameurl.GetName(contact_idurl), contact_local_ip)) identitycache.SetLocalIPs(local_ips) #---suppliers if contact_type == 's': current_contacts = contacts.getSupplierIDs() contacts.setSupplierIDs(clist) eccmap.init() contacts.saveSupplierIDs() for supid in contacts.getSupplierIDs(): if supid.strip() == '': error_flag = True break dhnio.Dprint(4, "central_service.ListContacts (SUPPLIERS) code:%s error:%s length:%d" % (str(code), str(error_flag), len(clist))) for oldidurl in current_contacts: if oldidurl: if oldidurl not in clist: events.info('central_service', 'supplier %s were disconnected' % nameurl.GetName(oldidurl),) misc.writeSupplierData(oldidurl, 'disconnected', time.strftime('%d%m%y %H:%M:%S')) dhnio.Dprint(6, 'central_service.ListContacts supplier %s were disconnected' % nameurl.GetName(oldidurl)) for newidurl in clist: if newidurl: if newidurl not in current_contacts: transport_control.ClearAliveTime(newidurl) misc.writeSupplierData(newidurl, 'connected', time.strftime('%d%m%y %H:%M:%S')) events.info('central_service', 'new supplier %s connected' % nameurl.GetName(newidurl), '',) dhnio.Dprint(6, 'central_service.ListContacts new supplier %s connected' % nameurl.GetName(newidurl)) backup_control.SetSupplierList(clist) if not fire_flag and current_contacts != clist: dhnio.Dprint(6, 'central_service.ListContacts going to call suppliers') identitypropagate.suppliers(wide=True) if OnListSuppliersFunc is not None: OnListSuppliersFunc() #---customers elif contact_type == 'c': current_contacts = contacts.getCustomerIDs() contacts.setCustomerIDs(clist) contacts.saveCustomerIDs() if spaceDict is not None: dhnio._write_dict(settings.CustomersSpaceFile(), spaceDict) reactor.callLater(3, local_tester.TestUpdateCustomers) # if not fire_flag and current_contacts != clist: identitypropagate.customers(wide=True) dhnio.Dprint(4, "central_service.ListContacts (CUSTOMERS) code:%s error:%s length:%d" % (str(code), str(error_flag), len(clist))) for oldidurl in current_contacts: if oldidurl not in clist: events.info('central_service', 'customer %s were disconnected' % nameurl.GetName(oldidurl),) dhnio.Dprint(6, 'central_service.ListContacts customer %s were disconnected' % nameurl.GetName(oldidurl)) for newidurl in clist: if newidurl not in current_contacts: transport_control.ClearAliveTime(newidurl) events.info('central_service', 'new customer %s connected' % nameurl.GetName(newidurl)) dhnio.Dprint(6, 'central_service.ListContacts new customer %s connected' % nameurl.GetName(newidurl)) if OnListCustomersFunc is not None: OnListCustomersFunc() #---fire_flag if fire_flag: if contact_type == 's': index = -1 for index in range(len(clist)): if clist[index] != current_contacts[index]: break if index >= 0: # we want to send our Identity to new supplier # and than ask a list of files he have # so it should start rebuilding backups immediately # right after we got ListFiles from him identitypropagate.single(clist[index], wide=True) #---ban_flag if ban_flag: events.notify('central_service', 'you have negative balance, all your suppliers was removed', '',) dhnio.Dprint(2, 'central_service.ListContacts !!! you have negative balance, all your suppliers was removed !!!') #---error_flag if error_flag: #reactor.callLater(settings.DefaultNeedSuppliersPacketTimeOut(), SendRequestSuppliers) events.info('central_service', 'could not find available suppliers', 'Central server can not find available suppliers for you.\nCheck your central settings.\n',) dhnio.Dprint(2, 'central_service.ListContacts !!! could not find available suppliers !!!') #---send ack transport_control.SendAck(request) #---automats if contact_type == 's': central_connector.A('list-suppliers', clist) fire_hire.A('list-suppliers', (current_contacts, clist)) data_sender.A('restart') elif contact_type == 'c': central_connector.A('list-customers', clist) #---transport_udp if transport_control._TransportUDPEnable: import lib.transport_udp as transport_udp new_contacts = contacts.getContactsAndCorrespondents() transport_udp.ListContactsCallback(current_contacts, new_contacts)
def doSendMyIdentity(self, arg): identitypropagate.single(arg, wide=True)