def view_downloads(self): """ ***************************************** View Log ***************************************** """ prev_combined = "" Stuff_metadata = dict while True: # Load All the Stuff Being download list_of_downloads = Config.LIST_IN_PROGRESS_LIB + Config.LIST_PENDING_LIB # Get Informations about their library if not exist combined = "\nPENDING DOWNLOAD\n--> {}\n\nDOWNLOAD IN PROGRESS\n--> {}\n\nDOWNLOADED\n--> {} \n\n\n\n".format( str(Config.LIST_PENDING_LIB), str(Config.LIST_IN_PROGRESS_LIB), str(Config.LIST_DOWNLOADED_LIB)) if prev_combined != combined: Console.app_title() Console.menu_title("View Downloads") print("{}\n\n Press <Enter> to quit log ...".format(combined)) if Auxiliaries.input_timeout(1) == "": break prev_combined = combined else: if Auxiliaries.input_timeout(2) == "": break
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 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 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 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 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_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 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 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 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 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 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 about(self): """ ***************************************** View Log ***************************************** """ Console.app_title() Console.menu_title("About") message = "EMMA Torrent V1.0 \nUniversity Jean Monnet \nGroup I\n" print("{}\n\n Press <Enter> to quit log ...".format(message)) Auxiliaries.input_timeout(15)
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 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 download_library(self): """ ***************************************** Download Library command ***************************************** """ Console.app_title() Console.menu_title("Download Library") # View All Library dirs = Auxiliaries.scan_dir(Config.LIBS_DIR) options = dict() n = 1 for dir in dirs: options[n] = dir print("{} - {} ".format(str(n), dir)) n += 1 print("\n\n Enter <exit> to quit \n\n") # Choose an option choice = "" while True: choice = input("Enter an option : ") if choice.upper() == "EXIT": return elif Auxiliaries.isInteger(choice) is False: print("Invalid Option Provided. ") elif int(choice) in options.keys(): break else: print("Invalid Option Provided. ") library_id = str(options[int(choice)]).replace(".lib", "") # Push to queue if Config.add_pending_download_lib(library_id) is True: print("Library id {} has been successfully loaded".format( library_id)) time.sleep(2) self.view_downloads() else: print("Sorry, failed to load Library id {}") print(Config.LIST_PENDING_LIB)
def settings(self): """ ***************************************** Setting menu ***************************************** """ Console.app_title() Console.menu_title("Settings") all_config_vars = dict(Config.view_global_var()) for key in all_config_vars: print("[ {} ] = {} ".format(str(key), all_config_vars[str(key)])) print("\n Enter <exit> to quit \n") while True: choice = input("Enter key to modify: ") choice = choice.strip().upper() if choice == "EXIT": return elif choice not in all_config_vars.keys(): print("Unknown key [ {} ] provided.".format(choice)) elif choice == "": print("No option provided") elif choice in all_config_vars.keys(): value = input("Provide new value for [{}]: ".format(choice)) value = value.strip().upper() if value == "EXIT": return self.settings() else: Console.start_loading("Updating Config") status, msg = Config.update_global_var(choice, value) time.sleep(2) Console.stop_loading() if status is True: print("[ SUCCESS ] - Config successfully set ") time.sleep(3) else: print("[ FAILURE ] - {}".format(msg)) Auxiliaries.input_timeout(5) return self.settings() else: print("Unknown key [ {} ] provided.".format(choice))
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 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"
def clear_screen(): """ ***************************************** Clear screen ***************************************** """ if Auxiliaries.get_os_name() == "WINDOWS": os.system("cls") else: os.system("clear")
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 view_log(self): """ ***************************************** View Log ***************************************** """ prev_combined = "" while True: combined = "" for line in Auxiliaries.LOG_BUFFER: combined += "\n" + str(line[0]) if prev_combined != combined: Console.clear_screen() print("{}\n\n Press <Enter> to quit log ...".format(combined)) if Auxiliaries.input_timeout(5) == "": break prev_combined = combined else: if Auxiliaries.input_timeout(5) == "": break
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 view_services(self): """ ***************************************** View Log ***************************************** """ prev_combined = "" while True: maestro_status = "OFF" distributor_status = "OFF" requestor_status = "OFF" if Maestro.get_service_status() is True: maestro_status = "RUNNING" if Distributor.get_service_status() is True: distributor_status = "RUNNING" if Requestor.get_service_status() is True: requestor_status = "RUNNING" maestro_last_message = Maestro.get_last_message() combined = "--> Maestro Service ({}) - {}\n\t|\t\n\t|--> Distributor service ( {} )\n\t|\n\t|--> Requestor Service ( {} ) \n\n\n".format( maestro_status, maestro_last_message, distributor_status, requestor_status) if prev_combined != combined: Console.app_title() Console.menu_title("Services") print("{}\n\n Press <Enter> to quit log ...".format(combined)) if Auxiliaries.input_timeout(5) == "": break prev_combined = combined else: if Auxiliaries.input_timeout(5) == "": break
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 exit_menu(self): """ ***************************************** Exit Menu ***************************************** """ message = " EMMA Torrent V1.0 \nUniversity Jean Monnet \nGroup I " print("\r") answer = True while answer: answer = input("Do you really want to exit EMMA Torrent? : [y|n] ") if answer.upper() == "Y": Console.start_loading("Exiting") Config.persist_setting() Auxiliaries.flush_to_log() time.sleep(2) Console.stop_loading() Console.clear_screen() os._exit(0) elif answer.upper() == "N": return else: print("Invalid input provided.")
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)