def start(): """ ***************************************** Method used to start the application Ui and services of EMMA Torrents :return: Void ***************************************** """ try: # Loading console app in case setup is to be done ... cli = Console() cli.setup() # Loading System Settings ... Config.load_setting() # Starting Master Service (Maestro) ... Maestro.start_service() # Launching Console Application to monitor and manage activities ... cli.launch() # Handling all exceptions here ... except Exception as e: from app.utilites.auxiliaries import Auxiliaries Auxiliaries.console_log("Exception raised in Main: {} ".format(e)) traceback.print_exc()
def start_service(): # Enforcing single Process for Requestor service ... Auxiliaries.console_log("Starting Requestor service ...") if Requestor.service_status is True: return True Requestor.handle_request_all().start()
def getProgress(self): Auxiliaries.console_log("received so far: ", len(self.list_book_received), " / ", self.total_no_books) # print ("received so far: ", len(self.list_book_received), " / ", self.total_no_books) return len(self.list_book_received) / self.total_no_books
def remove_downloaded_lib(library_id): try: Config.LIST_DOWNLOADED_LIB.remove(library_id) Config.persist_setting() return True except Exception as e: Auxiliaries.console_log(e) return False
def remove_in_progress_download_lib(library_id): try: Config.LIST_IN_PROGRESS_LIB.remove(library_id) Config.persist_setting() return True except Exception as e: Auxiliaries.console_log(e) return False
def remove_pending_download_lib(library_id): try: Config.LIST_PENDING_LIB.remove(library_id) Config.persist_setting() return True except Exception as e: Auxiliaries.console_log(e) return False
def constructBook(self, b_bytes, book_id): try: # print("type: ", type(book)) book = Book() book.book_bytes = bytearray(b_bytes) self.storeBook(book, book_id) except Exception as e: Auxiliaries.console_log("Exception", e) traceback.printnt_exc()
def add_downloaded_lib(library_id): try: if library_id not in Config.LIST_DOWNLOADED_LIB: Config.LIST_DOWNLOADED_LIB.append(library_id) Config.persist_setting() return True except Exception as e: Auxiliaries.console_log(e) return False
def add_in_progress_download_lib(library_id): try: if library_id not in Config.LIST_IN_PROGRESS_LIB: Config.LIST_IN_PROGRESS_LIB.append(library_id) Config.persist_setting() return True except Exception as e: Auxiliaries.console_log(e) return False
def storeAvailableBooks(self, peerId, availableBooks): # self.lock.acquire() try: # print("storeBook: ", peerId , " - ", availableBooks ) self.availableBooks[peerId] = availableBooks except Exception as e: Auxiliaries.console_log( "Exception in storeAvailableBooks: {} ".format(e))
def flushToFile(self, filePath): data = bytearray() # print(type(self.books)) index = 0 for bookIndex in self.books: book = self.books[index] index = index + 1 # print(bookIndex) # print(type(book)) data = data + book.book_bytes Auxiliaries.console_log("final: ", len(data)) self.create_file(filePath, data)
def data_repo_inspection(): try: # Check if all the dir exist and create them if not Config.create_dir(Config.DATA_DIR) Config.create_dir(Config.LIBS_DIR) Config.create_dir(Config.STUFFS_DIR) Config.create_dir(Config.MYDB_DIR) Config.create_dir(Config.DOWNLOAD_DIR) Config.create_dir(Config.LOG_DIR) return True except Exception as e: Auxiliaries.console_log(e) return False
def register_peer(self, library_id, ip, port): """ ***************************************** Method used to register a peer to the tracker :param library_id: :param ip: :param port: :return: ***************************************** """ command = "REGISTER_PEER {} {} {}".format(library_id, ip, port) Auxiliaries.console_log("writing to socket ...", command) # Sending <Register peer> Request to Candidate Peer ... self.connect() self.sock_write(command) Auxiliaries.console_log("waiting for socket response ...") # Reading Response from Candidate Peer ... response = self.sock_read() self.disconnect() Auxiliaries.console_log("reading response from socket ...", response) Auxiliaries.console_log(response) # Decoding response from Candidate Peer ... if response == "200": return True else: return False
def master_job(): Auxiliaries.console_log("Starting Distributor Server ...") def handle(): try: Auxiliaries.console_log("Maestro Server Started") Maestro.status = True while True: default_sleeping_duration = 14 up_flag = True try: for service in Maestro.get_sub_services_pool(): service_class = eval(service) # In case service is OFF Try to restart service if service_class.get_service_status() is False: up_flag = False Maestro.last_message = "Maestro is attempting to restart service ... [{}] ".format( service) Auxiliaries.console_log(Maestro.last_message) service_class.start_service() time.sleep(1) # Set an shorter sleeping duration default_sleeping_duration = 3 if up_flag is True: Maestro.last_message = " All sub-services are Running ... ".format( service) Auxiliaries.console_log(Maestro.last_message) except Exception as e: Auxiliaries.console_log( "Exception in Maestro :{}".format(e)) # Waiting before running another cycle ... time.sleep(default_sleeping_duration) except Exception as e: Auxiliaries.console_log("Exception in Maestro :{}".format(e)) finally: Maestro.status = False t = Thread(target=handle, args=[]) return t
def request_book(self, library_id, book_id): """ ***************************************** Method used to request a book from a candidate peer :param library_id: :param book_id: :return: ***************************************** """ command = "REQUEST_BOOK {} {}".format(library_id, book_id) # Sending <RequestBook> to Candidate Peer ... self.sock_write(command) # Reading Response from Candidate Peer ... response = self.sock_read() # Decoding response from Candidate Peer ... # response = bytes(response, encoding="utf-8") response_parts = response.split() Auxiliaries.console_log("response as received ") # Auxiliaries.console_log(response_parts) Auxiliaries.console_log("book_id [{}] received ".format(str(book_id))) res_code = response_parts[0] Auxiliaries.console_log("response code: {} ".format(res_code)) res_data = None res_data_length = 0 if res_code == "200": Auxiliaries.console_log("in 200 detected") res_data_length = int(response_parts[1]) Auxiliaries.console_log( "in 200 detected: length: {} ".format(res_data_length)) res_data = str.join("", response_parts[2:]) res_data = eval(res_data) #Auxiliaries.console_log("Before eval: {}".format(res_data)) res_data = bytearray(res_data) return res_code, res_data_length, res_data
def get_book_response(self, args=None): """ ***************************************** Method used to handle get books response :return: String Encoded ***************************************** """ try: # get args if len(args) != 2: response_to_send = "401" return self.reply(response_to_send) library_id = args[0] stuff = self.load_stuff(library_id) # In case library_id does not exist if stuff is None: response_to_send = "402" return self.reply(response_to_send) # in case book_id is not integer try: book_id = int(args[1]) except Exception as ex: Auxiliaries.console_log("Exception Occurred", ex) response_to_send = "402" return self.reply(response_to_send) # Auxiliaries.console_log("total_number_of_books: {} ".format( str(stuff.total_no_books) )) if book_id >= stuff.total_no_books: Auxiliaries.console_log("Out of list index", book_id) response_to_send = "402" return self.reply(response_to_send) # Auxiliaries.console_log("before encoding: {} ".format(stuff.fetchBook(book_id).book_bytes)) # --- res_data = list(stuff.fetchBook(book_id).book_bytes) # --- res_data_length = len(res_data) response_to_send = "200 {} {}".format(res_data_length, res_data) Auxiliaries.console_log("Replying with book id {} ".format( str(book_id))) return response_to_send except Exception as e: Auxiliaries.console_log("Exception Occurred: {} ".format(e)) response_to_send = "500" return self.reply(response_to_send)
def list_peers(self, library_id): """ ***************************************** Method used to list peers given a library id :return: ***************************************** """ command = "LIST_PEERS {}".format(library_id) Auxiliaries.console_log("writing to socket ...", command) # Sending <Ping> Request to Candidate Peer ... self.connect() self.sock_write(command) Auxiliaries.console_log("waiting for socket response ...") # Reading Response from Candidate Peer ... response_str = self.sock_read() #print(response_str) self.disconnect() Auxiliaries.console_log("reading response from socket ...", response_str) try: # Response format : 200 {length_resp} {resp} # Decoding response res_code = "500" res_data = None res_data_length = 0 response_parts = response_str.split(" ") res_code = response_parts[0] if res_code == "200": res_data_length = int(response_parts[1]) # Adapting to new protocol res_data = str.join("", response_parts[2:]) res_data = json.loads(str(res_data)) #print("json_load", res_data) ip_port_lists = list() for objs in res_data: ip_port_lists.append( str(objs['peer_ip']) + ":" + str(objs['peer_port'])) res_data = json.dumps(ip_port_lists) except Exception as e: Auxiliaries.console_log( "Error occurred while decoding response. Details: " + str(e)) res_code = 500 return res_code, res_data_length, res_data
def update_global_var(key, value): # Checking existence and mutability of key IMMUTABLE_GLOBAL_VARS = [ "LIST_PENDING_LIB", "LIST_IN_PROGRESS_LIB", "LIST_DOWNLOADED_LIB" ] if key not in Config.get_all_config_static_vars(): return False, "GlobalVars [{}] in not found".format(key) if key in IMMUTABLE_GLOBAL_VARS: return False, "GlobalVars [{}] is not mutable ".format(key) # Casting new Value to the type of old value old_value = Config.get_one_config_static_var(key) old_value_type = type(old_value) try: value = old_value_type(value) except Exception as e: Auxiliaries.console_log(e) return False, "GlobalVars [{}] can not be casted to Type: {} ".format( key, str(old_value_type)) # Execute Special parser when applicable status, msg = Config.special_parsor(key, value) if status is False: return status, msg # Update Value try: Config.set_one_config_static_var(key, value) except Exception as e: Auxiliaries.console_log(e) return False, "Error occurred while updating GlobalVars [{}]".format( key) return True, "GlobalVars [{}] has been successfully updated.".format( key)
def getNextBook(self, peerId, collected_books): # self.lock.acquire() try: # print("started") collected = [x[0] for x in collected_books] allBooksList = [] for key, value in self.availableBooks.items(): allBooksList.append(value) # print("all Books: ", allBooksList) pq = self.getPriorityBooks(allBooksList) # print('queue: ', pq.queue) # while not pq.empty(): # next_item = pq.get() # freq = next_item [0] # element = next_item[1] # element = element.split(":") [1] # print(freq, element) # return while not pq.empty(): next_item = pq.get()[1] next_item = next_item.split(":")[1] next_item = int(next_item) # print('next_item: ', next_item) if next_item in self.availableBooks[peerId]: # print("in", self.get_list_book_received()) if next_item not in self.get_list_book_received( ) and next_item not in collected: # print("returning: ", next_item) return next_item # print("end") return None except Exception as e: Auxiliaries.console_log("Exception in getNextBook: {} ".format(e))
def ping(self): """ ***************************************** Method used to ping candidate Peer :return: ***************************************** """ command = "PING" Auxiliaries.console_log("writing to socket ...") # Sending <Ping> Request to Candidate Peer ... self.sock_write(command) Auxiliaries.console_log("waiting for socket response ...") # Reading Response from Candidate Peer ... response = self.sock_read() Auxiliaries.console_log(response) # Decoding response from Candidate Peer ... if response == "200": return True else: return False
def get_available_books_response(self, args): """ ***************************************** Method used to handle get available books response :return: String Encoded ***************************************** """ try: # get args if len(args) != 1: response_to_send = "401" return self.reply(response_to_send) library_id = args[0] stuff = self.load_stuff(library_id) # In case library_id does not exist if stuff is None: response_to_send = "402" return self.reply(response_to_send) availableBooks = list(stuff.get_list_book_received()) shuffle(availableBooks) res_data = json.dumps(availableBooks) Auxiliaries.console_log(res_data) res_data_length = len(res_data) response_to_send = "200 {} {}".format(res_data_length, res_data) Auxiliaries.console_log(response_to_send) return self.reply(response_to_send) except Exception as e: Auxiliaries.console_log("Exception Occurred {}".format(e)) response_to_send = "500" return self.reply(response_to_send)
def handle(_self, library_id, collected_books, stuff_obj, library_obj): Auxiliaries.console_log("starting srcpeer download_job ... ") try: # Connect to peer ... if _self.connect() is False: _self.set_activity_status(False) else: # Ping/handshake ... if _self.ping() is False: _self.set_activity_status(False) while _self.get_activity_status(): # Requesting available books ... res_code, res_data_length, res_data = _self.get_available_books( _library_id) available_books = list() if res_code == "200": available_books = json.loads(res_data) # Auxiliaries.console_log("available_books", available_books) else: _self.set_activity_status(False) break peerId = self.peer_ip + ":" + str(self.peer_port) # start = time.time() stuff_obj.storeAvailableBooks(peerId, available_books) # end = time.time() # elapsed = end - start # print("elapse time for store Book: ", elapsed) interrested_flag = False while True: # start = time.time() book_id = stuff_obj.getNextBook( peerId, collected_books) end = time.time() # elapsed = end - start # print("elapse time for get Nex Book: ", elapsed) if book_id is None: if interrested_flag is False: _self.set_activity_status(False) break else: interrested_flag = True if not book_id is None: Auxiliaries.console_log("requesting book id ...", book_id) res_code, res_data_length, res_data = _self.request_book( library_id, book_id) if res_code == "200": book = res_data Auxiliaries.console_log( "received book :", book_id) collected_books.append([book_id, book]) # # Checking missing books per what is already available in stuff ... # missing_book = Auxiliaries.diff_list( stuff_obj.get_list_book_received(), available_books) # Auxiliaries.console_log("list book already received", stuff_obj.get_list_book_received()) # Auxiliaries.console_log("missing book", missing_book) # if len(missing_book) == 0: # Auxiliaries.console_log("No interresting available book(s) from you, I am not interested. bye") # _self.set_activity_status(False) # break # # Requesting for all the missing books till none are left ... # for book_id in missing_book: # Auxiliaries.console_log("requesting book id ...", book_id) # res_code, res_data_length, res_data = _self.request_book(library_id, book_id) # if res_code == "200": # book = res_data # Auxiliaries.console_log("received book :", book) # collected_books.append([book_id,book]) # Requesting books from peers time.sleep(14) _self.set_activity_status(False) Auxiliaries.console_log("exiting srcpeer download_job... ", _self.get_peer_id()) except Exception as e: Auxiliaries.console_log("Exception: {} ".format(e)) traceback.print_exc() _self.set_activity_status(False) pass
def handle(): try: Auxiliaries.console_log("Requestor service started") limit_no_concurrent_lib_jobs = 10 start_flag = False while True: Requestor.service_status = True # Fetching list of all pending libraries to download ( and push in Library Queue ) ... # Is there any new libraries ? if start_flag is False: Requestor.library_queue = Config.LIST_IN_PROGRESS_LIB + Config.LIST_PENDING_LIB start_flag = True else: Requestor.library_queue = Config.LIST_PENDING_LIB if len(Requestor.library_queue) > 0: Auxiliaries.console_log("pending downloads detected.", Requestor.library_queue) else: Auxiliaries.console_log( "no pending download detected.") # For each library fetching the list of available candidates on their respective tracker for library_id in list(set(Requestor.library_queue)): if Requestor.no_library_jobs >= limit_no_concurrent_lib_jobs: Auxiliaries.console_log( "max number of concurrent lib jobs reached ...", limit_no_concurrent_lib_jobs) break # Creating a Job for every library ... Requestor.library_job(library_id).start() Requestor.library_queue.remove(library_id) if library_id in Config.LIST_PENDING_LIB: Config.remove_pending_download_lib(library_id) if library_id not in Config.LIST_IN_PROGRESS_LIB: Config.add_in_progress_download_lib(library_id) # Sleeping for a while before checking if there is any other pending books that can be processed ... Auxiliaries.console_log("Requestor Service Sleeping ...") time.sleep(20) Auxiliaries.console_log( "\nRequestor Service awaking... active Library {} ". format(Requestor.no_library_jobs)) except Exception as e: Auxiliaries.console_log("Exception {} ".format(e)) finally: Requestor.service_status = False Auxiliaries.console_log("Requestor service off")
def handle(peer_socket): while True: try: line = Netutils.read_line(self.peer_socket) Auxiliaries.console_log("\nCommand IN: {} ".format(line)) if line is None: Auxiliaries.console_log("Client disconnecting ...") InPeer.incoming_peer_length = InPeer.incoming_peer_length - 1 break # Handling command line_parts = line.split() command = line_parts[0] req_args = [] if len(line_parts) > 1: req_args = line_parts[1:] # PING if command == "PING": response_to_send = self.ping_response(req_args) peer_socket.sendall(response_to_send) Auxiliaries.console_log( "\nCommand OUT: {} ".format(response_to_send)) # GET AVAILABLE BOOK elif command == "GET_AVAILABLE_BOOKS": response_to_send = self.get_available_books_response( req_args) peer_socket.sendall(response_to_send) Auxiliaries.console_log( "\nCommand OUT: {} ".format(response_to_send)) # REQUEST BOOK elif command == "REQUEST_BOOK": response_to_send = self.get_book_response(req_args) peer_socket.sendall( str.encode("{}\r\n".format(response_to_send))) # Auxiliaries.console_log("\nCommand OUT: {} ".format(response_to_send)) else: response_to_send = "400" peer_socket.sendall( str.encode("{}\r\n".format(response_to_send))) Auxiliaries.console_log( "\nCommand OUT: {} ".format(response_to_send)) except Exception as e: response_to_send = "500" peer_socket.sendall( str.encode("{}\r\n".format(response_to_send))) Auxiliaries.console_log( "\nCommand OUT: {} ".format(response_to_send)) Auxiliaries.console_log( "Exception occurred. disconnecting ...") break
def handle(library_id): Auxiliaries.console_log("starting new library job ....", library_id) Requestor.no_library_jobs += 1 # Shared vars for library Job # --------- preprocess_flag = True library_job_status = True player_pool = dict() collected_books = [] stuff_object = None library_object = None library_checksums = list() library_path = Config.LIBS_DIR + os.sep + library_id + ".lib" stuff_file_path = Config.STUFFS_DIR + os.sep + library_id + ".pkl" self_hub_registration_flag = False collecting_cycle_limit = 3 collecting_cycle_counter = 0 # --------- # Loading details about pending library ( Tracker IP and Port, missing books )... Auxiliaries.console_log("libpath".format(library_path)) library_file = Path(library_path) if library_file.exists(): with open(library_path, 'r') as library_file: document = "" for line in library_file: document = document + str(line) Auxiliaries.console_log("loading library ...", library_id) library_object = json.loads(document) library_checksums = library_object['hashes'] # Loading / Creating stuff ... Auxiliaries.console_log("loading/Creating Stuff ...", library_id) sfuff_file = Path(stuff_file_path) if sfuff_file.exists(): stuff_object = Stuff.load(stuff_file_path) else: no_books = len(library_object['hashes']) stuff_object = Stuff(total_no_books=no_books) stuff_object.persist(stuff_file_path) if library_object is None: Auxiliaries.console_log( "Library file could not be decoded", library_id) preprocess_flag = False else: Auxiliaries.console_log("Library file not Found", library_id) preprocess_flag = False library_job_status = preprocess_flag # Creating a library Job ... while library_job_status: try: # Connecting to the Tracker and sending request Auxiliaries.console_log("Connecting to hub", library_id) hub_address = str(library_object["hub_address"]).split(":") tracker = Tracker(Config.HUB_IP, Config.HUB_PORT) res_code, res_data_length, res_data = tracker.list_peers( library_id) # In case < list player > was successful .... if res_code == "200": Auxiliaries.console_log(res_data) list_of_peers = json.loads(res_data) # Register self Distributor on Hub if self_hub_registration_flag is False: Auxiliaries.console_log( "Registering current player on hub", library_id) Auxiliaries.console_log("Distributor port", Distributor.get_port()) # Use the real port instead of the hardcoded one if tracker.register_peer( library_id, Distributor.get_ip(), Distributor.get_port()) is True: Auxiliaries.console_log( "successfully registered on hub") self_hub_registration_flag = True my_player_id = Distributor.get_ip() + ":" + str( Distributor.get_port()) # Building pool of candidate players ( <str,srcPeers> ) ... for player in list_of_peers: player_parts = str(player).split(":") player_id = player_parts[0] + ":" + player_parts[1] if player_id not in player_pool: if player_id != my_player_id: player_pool[player_id] = SrcPeer( player_parts[0], player_parts[1]) player_pool[player_id].download_job( library_id, collected_books, stuff_object, library_object).start() else: Auxiliaries.console_log( "same player_id", player_id) Auxiliaries.console_log("player_pool", player_pool) # Monitoring the peers activity until no more books in available from SrcPeer ... while len(player_pool) > 0: try: collecting_cycle_counter += 1 # Monitoring all players Activities ... Auxiliaries.console_log( "monitoring players activity ...") player_blacklist = [] for player_id in player_pool: Auxiliaries.console_log( "monitoring activity of player_id ", player_id) if player_pool[ player_id].get_activity_status( ) is False: player_blacklist.append(player_id) # Collecting all buffered books, check their validity against signature .. . Auxiliaries.console_log( "collected_books_to_flush", collected_books) if len( collected_books ) > 0 and collecting_cycle_counter > collecting_cycle_limit: collecting_cycle_counter = 0 len_collected_books = len(collected_books) for i in range(len_collected_books): cur_book = collected_books[0] Auxiliaries.console_log( "cur_book", cur_book) collected_books.remove(cur_book) # Checking the current book against the checksum before adding book(s) to stuff if Security.sha1( cur_book[1] ) == library_checksums[cur_book[0]]: stuff_object.constructBook( cur_book[1], int(cur_book[0])) else: Auxiliaries.console_log( "book discarded", Security.sha1(cur_book[1]), library_checksums[cur_book[0]]) # Persisting collected books to disk ... Auxiliaries.console_log("flushing ...") stuff_object.persist(stuff_file_path) # Removing Blacklisted Candidate Players from current Pool ... for player_id in player_blacklist: Auxiliaries.console_log( "removing blacklisted player_id from Pool ", player_id) del (player_pool[player_id]) Auxiliaries.console_log( "is_complete", stuff_object.list_book_received) # Checking whether stuff has been fully downloaded ... if stuff_object.is_download_complete(): Auxiliaries.console_log( "File completely downloaded ") # Building file to download Repository download_path = Config.DOWNLOAD_DIR + os.sep + library_object[ 'file_name'] stuff_object.flushToFile(download_path) library_job_status = False # Remove library_id among pending library ... Config.remove_in_progress_download_lib( library_id) Config.add_downloaded_lib(library_id) break except Exception as e: Auxiliaries.console_log( "Exception: {} ".format(e)) time.sleep(7) # ------ End of Monitoring ------ # In case < list player > failed .... else: Auxiliaries.console_log("error while listing peers.") break # In Library is to be stopped, suspend activities on player pool if any ... if library_job_status is False: # Suspend all current candidates peer for player_id in player_pool: # player_pool[player_id] player_pool[player_id].set_activity_status(False) time.sleep(20) # Seconds # --------- End Library job cycle ---------- except Exception as e: Auxiliaries.console_log("Exception {}".format(e)) # traceback.print_exc() finally: Requestor.no_library_jobs -= 1 Auxiliaries.console_log("exiting library job ....", library_id)
def create_file(self, filePath, data): Auxiliaries.console_log("Writing to file") with open(filePath, 'wb') as file: file.write(data) return True
def get_one_config_static_var(static_var_key): return getattr(Config, static_var_key) @staticmethod def set_one_config_static_var(static_var_key, static_var_value): return setattr(Config, static_var_key, static_var_value) @staticmethod def special_parsor(key, value): if key == "HUB_PORT" or key == "DISTRIBUTOR_PORT": if Auxiliaries.parse_port(value) is False: return False, "Invalid Port number provided range [0,65535]" if key == "HUB_IP": if Netutils.parse_ip_address(value) is False: return False, "'{}' does not appear to be an IPv4 or IPv6 address".format( value) return True, "Special parsor successfully completed" #################################################################################################################### # END CONFIG MODULE #################################################################################################################### if __name__ == "__main__": Auxiliaries.console_log(Config.update_global_var("DISTRIBUTOR_PORT", 5003)) Auxiliaries.console_log(Config.get_all_config_static_vars()) #Auxiliaries.console_log(Config.view_global_var()) pass
def handle(port): try: Distributor.port = port server_socket = socket.socket() Auxiliaries.console_log(port) server_socket.bind(("0.0.0.0", port)) Auxiliaries.console_log("Starting Distributor Server ...") server_socket.listen() Auxiliaries.console_log("Distributor Server Started") Distributor.status = True while True: client_con, client_address = server_socket.accept() Auxiliaries.console_log("Client connected ...") Auxiliaries.console_log("Current peer connected count ", InPeer.incoming_peer_length) incoming_peer = InPeer(client_con, client_address) incoming_peer.handle_request().start() except Exception as e: Auxiliaries.console_log("Exception", e) finally: Distributor.status = False