def test_different_servers(self): packs_one = XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2) pack_two = XDCCPack(IrcServer("irc.rizon.net"), "xdcc_servbot", 2) results = self.downloader.download([packs_one, pack_two]) self.assertEqual(results[packs_one], "OK") self.assertEqual(results[pack_two], "OTHERSERVER")
def from_xdcc_message(cls, xdcc_message: str, destination_directory: str = os.getcwd(), server: str = "irc.rizon.net") \ -> list: """ Generates XDCC Packs from an xdcc message of the form "/msg <bot> xdcc send #<packnumber>[-<packnumber>]" :param xdcc_message: the XDCC message to parse :param destination_directory: the destination directory of the file :param server: the server to use, defaults to irc.rizon.net for simplicity's sake :return: The generated XDCC Packs in a list """ regex = r"^/msg [^ ]+ xdcc send #" \ r"[0-9]+((,[0-9]+)*|(-[0-9]+(;[0-9]+)?)?)$" if not re.search(regex, xdcc_message): return [] bot = xdcc_message.split("/msg ")[1].split(" ")[0] try: packnumber = xdcc_message.rsplit("#", 1)[1] packnumbers = packnumber.split(",") packs = [] for number in packnumbers: xdcc_pack = XDCCPack(IrcServer(server), bot, int(number)) xdcc_pack.set_directory(destination_directory) packs.append(xdcc_pack) return packs except ValueError: packnumbers = xdcc_message.rsplit("#", 1)[1] start, end = packnumbers.split("-") try: step = int(end.split(";")[1]) end = end.split(";")[0] except (IndexError, ValueError): step = 1 packs = [] for pack in range(int(start), int(end) + 1, step): xdcc_pack = XDCCPack(IrcServer(server), bot, pack) xdcc_pack.set_directory(destination_directory) packs.append(xdcc_pack) return packs
def test_download_multiple_packs(self): progress = Progress(2) packs = [XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 3)] results = self.downloader.download(packs, progress) for pack in results: self.assertTrue(os.path.isfile(pack.get_filepath())) self.assertEqual(results[pack], "OK") self.assertEqual(progress.get_single_progress_percentage(), 100.0) self.assertEqual(progress.get_total_percentage(), 100.0)
def test_move_selection_up_or_down(self): self.form.download_queue = [ XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 1), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 3) ] self.form.refresh_download_queue() self.form.download_queue_list_widget.selectAll() QTest.mouseClick(self.form.up_arrow_button, Qt.LeftButton) self.form.download_queue_list_widget.selectAll() QTest.mouseClick(self.form.down_arrow_button, Qt.LeftButton) self.assertEqual(self.form.download_queue_list_widget.count(), 3)
def find_subsplease_packs(search_phrase: str) -> List[XDCCPack]: """ Method that conducts the xdcc pack search for subsplease.org :return: the search results as a list of XDCCPack objects """ if not search_phrase: return [] search_query = search_phrase.replace(" ", "%20") search_query = search_query.replace("!", "%21") url = "https://subsplease.org/xdcc/search.php?t=" + search_query scraper = cfscrape.create_scraper() results = scraper.get(url).text.split(";") packs = [] for result in results: try: result = parse_result(result) botname = result["b"] filename = result["f"] filesize = int(result["s"]) packnumber = int(result["n"]) pack = XDCCPack(IrcServer("irc.rizon.net"), botname, packnumber) pack.set_filename(filename) pack.set_size(filesize * 1000 * 1000) packs.append(pack) except IndexError: # In case the line is not parseable pass return packs
def test_download_multiple_packs_different_servers(self): progress = Progress(2) downloader = MultipleServerDownloader("random") downloader.download([ XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2), XDCCPack(IrcServer("namibsun.net"), "xdcc_servbot", 3) ], progress) self.assertTrue(os.path.isfile("2_test.txt")) self.assertTrue(os.path.isfile("3_test.txt")) self.assertEqual(progress.get_single_progress_percentage(), 100.0) self.assertEqual(progress.get_total_percentage(), 100.0)
def test_bot_not_found(self): pack = XDCCPack(IrcServer("irc.namibsun.net"), "nosuchbot", 2) results = self.downloader.download([pack]) self.assertFalse(os.path.isfile(pack.get_filepath())) self.assertEqual(results[pack], "BOTNOTFOUND")
def find_horriblesubs_packs(search_phrase: str) -> List[XDCCPack]: """ Method that conducts the xdcc pack search for xdcc.horriblesubs.info :return: the search results as a list of XDCCPack objects """ if not search_phrase: return [] search_query = search_phrase.replace(" ", "%20") search_query = search_query.replace("!", "%21") url = "http://xdcc.horriblesubs.info/search.php?t=" + search_query scraper = cfscrape.create_scraper() results = scraper.get(url).text.split(";") packs = [] for result in results: try: botname = get_attribute(result, "b") filename = get_attribute(result, "f") filesize = get_attribute(result, "s") packnumber = get_attribute(result, "n") pack = XDCCPack(IrcServer("irc.rizon.net"), botname, packnumber) pack.set_filename(filename) pack.set_size(filesize) packs.append(pack) except IndexError: # In case the line is not parseable pass return packs
def find_xdcc_eu_packs(search_phrase: str) -> List[XDCCPack]: """ Method that conducts the xdcc pack search for xdcc.eu :return: the search results as a list of XDCCPack objects """ url = "https://www.xdcc.eu/search.php?searchkey=" + search_phrase response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser") entries = soup.select("tr") entries.pop(0) packs = [] for entry in entries: parts = entry.select("td") info = parts[1].select("a")[1] server = IrcServer(info["data-s"]) pack_message = info["data-p"] bot, pack_number = pack_message.split(" xdcc send #") size = byte_string_to_byte_count(parts[5].text) filename = parts[6].text pack = XDCCPack(server, bot, int(pack_number)) pack.set_size(size) pack.set_filename(filename) packs.append(pack) return packs
def test_incorrect_file_sent(self): pack = XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2) pack.set_original_filename("something_else.txt") results = self.downloader.download([pack]) self.assertFalse(os.path.isfile(pack.get_filepath())) self.assertEqual(results[pack], "INCORRECT")
def test_download_packs(self): self.form.download_queue = [ XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 1), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 3) ] self.form.refresh_download_queue() self.assertEqual(self.form.destination_edit.text(), os.getcwd()) QTest.mouseClick(self.form.download_button, Qt.LeftButton) while self.form.downloading: pass self.assertTrue(os.path.isfile("1_test.txt")) self.assertTrue(os.path.isfile("2_test.txt")) self.assertTrue(os.path.isfile("3_test.txt")) self.form.show_download_complete_message_signal.emit("")
def test_quitting(self): packs = [XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 1)] downloader = MultipleServerDownloader("random") downloader.quit() downloader.download(packs) downloader.quit() self.assertFalse(os.path.isfile("1_test.txt"))
def test_file_existed(self): pack = XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2) self.downloader.download([pack]) self.assertTrue(os.path.isfile(pack.get_filepath())) results = self.downloader.download([pack]) self.assertTrue(os.path.isfile(pack.get_filepath())) self.assertEqual(results[pack], "EXISTED")
def test_removing_queue_items(self): self.form.download_queue = [ XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 1), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 3) ] self.form.refresh_download_queue() self.form.download_queue_list_widget.selectAll() self.assertEqual(self.form.download_queue_list_widget.count(), 3) self.assertEqual(len(self.form.download_queue), 3) self.assertEqual( len(self.form.download_queue_list_widget.selectedIndexes()), 3) QTest.mouseClick(self.form.left_arrow_button, Qt.LeftButton) self.assertEqual(self.form.download_queue_list_widget.count(), 0) self.assertEqual(len(self.form.download_queue), 0) self.assertEqual( len(self.form.download_queue_list_widget.selectedIndexes()), 0)
def test_removing_pack_from_queue(self): self.form.download_queue = [ XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 1) ] self.form.refresh_download_queue() self.assertEqual(1, self.form.download_queue_list_widget.count()) self.form.download_queue_list_widget.selectAll() QTest.mouseClick(self.form.left_arrow_button, Qt.LeftButton) self.assertEqual(0, len(self.form.download_queue)) self.assertEqual(0, self.form.download_queue_list_widget.count())
def find_nibl_packs(search_phrase: str) -> List[XDCCPack]: """ Searches for XDCC Packs matching the specified search string on nibl.co.uk :param search_phrase: The search phrase to search for :return: The list of found XDCC Packs """ # Prepare the search term, nibl.co.uk uses + symbols as spaces. split_search_term = search_phrase.split(" ") prepared_search_term = split_search_term[0] i = 1 while i < len(split_search_term): prepared_search_term += "+" + split_search_term[i] i += 1 # Get the data from the website url = "https://nibl.co.uk/bots.php?search=" + prepared_search_term html = requests.get(url).text print(html) content = BeautifulSoup(html, "html.parser") file_names = content.select(".filename") pack_numbers = content.select(".packnumber") bot_names = content.select(".name") file_sizes = content.select(".filesize") results = [] i = 0 # We need a counter variable since we have four lists of data while i < len(file_names): # The filename has two links after it, which need to be cut out filename = file_names[i].text.rsplit(" \n", 1)[0] # The bot name has a link after it, which needs to be cut out print(bot_names) bot = bot_names[i].text.rsplit(" ", 1)[0] server = "irc.rizon.net" packnumber = int(pack_numbers[i].text) size = file_sizes[i].text result = XDCCPack(IrcServer(server), bot, packnumber) result.set_size(size) result.set_filename(filename) results.append(result) i += 1 return results
def test_download_while_downloading(self): self.form.download_queue = [ XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 1), XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 3) ] self.form.refresh_download_queue() QTest.mouseClick(self.form.download_button, Qt.LeftButton) time.sleep(0.5) self.form.download_queue = [ XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 2) ] self.form.refresh_download_queue() QTest.mouseClick(self.form.download_button, Qt.LeftButton) while self.form.downloading: pass self.assertTrue(os.path.isfile("1_test.txt")) self.assertFalse(os.path.isfile("2_test.txt")) self.assertTrue(os.path.isfile("3_test.txt")) self.form.show_download_complete_message_signal.emit("")
def find_ixirc_packs(search_phrase: str) -> List[XDCCPack]: """ Searches for XDCC Packs matching the specified search string on ixirc.com Implementation courtesy of Jean Wicht <*****@*****.**>. :param search_phrase: The search phrase to search for :return: The list of found XDCC Packs """ if not search_phrase: return [] packs: List[XDCCPack] = [] page_id = 0 # the number of pages of results will be set properly in the request below page_count = 42 while page_id < page_count: request = requests.get( "https://ixirc.com/api/", params={ "q": search_phrase, "pn": str(page_id) }, ) if request.status_code != 200: return packs data = request.json() page_count = int(data["pc"]) if "results" not in data: # no results return [] for result in data["results"]: if "uname" not in result: # bot not online continue server = IrcServer(result["naddr"], result["nport"]) pack = XDCCPack(server, result["uname"], int(result["n"])) pack.set_filename(result["name"]) pack.set_size(result["sz"]) packs.append(pack) page_id += 1 # next page return packs
def find_namibsun_packs(search_phrase: str) -> List[XDCCPack]: """ Searches for XDCC Packs matching the specified search string on irc.namibsun.net:8000 :param search_phrase: The search phrase to search for :return: The list of found XDCC Packs """ soup = BeautifulSoup( requests.get("http://irc.namibsun.net:8000").text, "html.parser") content = soup.select(".content") all_packs = [] for i, item in enumerate(content): if item.text == search_phrase: all_packs.append( XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", i + 1)) all_packs[len(all_packs) - 1].set_filename(item.text) return all_packs
def download(self, packs: List[XDCCPack], progress: Progress = None)\ -> Dict[XDCCPack, str]: """ Downloads all XDCC packs specified. Optionally shares state with other threads using a Progress object :param packs: The packs to download :param progress: Optional Progress object :return: Dictionary of packs mapped to status codes: "OK": Download was successful "BOTNOTFOUND": Bot was not found "NETWORKERROR": Download failed due to network error "INCOMPLETE": Download was incomplete "EXISTED": File already existed and was completely downloaded """ results = {} packservers = {} for pack in packs: try: packservers[pack.get_server().get_address()].append(pack) except KeyError: packservers[pack.get_server().get_address()] = [pack] for server in packservers: if not self.quit_called: self.current_downloader = \ XDCCDownloader(IrcServer(server), self.user, self.logger) server_results = \ self.current_downloader.download( packservers[server], progress ) for result in server_results: results[result] = server_results[result] return results
def test_from_message(self): single = XDCCPack.from_xdcc_message("/msg Bot1 xdcc send #1") _range = XDCCPack.from_xdcc_message("/msg Bot2 xdcc send #2-5") range_step = XDCCPack.from_xdcc_message("/msg Bot3 xdcc send #6-10;2") commas = XDCCPack.from_xdcc_message("/msg Bot4 xdcc send #11,111,1111") rizon = IrcServer("irc.rizon.net") self.assertEqual(single[0], XDCCPack(rizon, "Bot1", 1)) for x in range(2, 6): self.assertEqual(_range[x - 2], XDCCPack(rizon, "Bot2", x)) i = 0 for x in range(6, 11, 2): self.assertEqual(range_step[i], XDCCPack(rizon, "Bot3", x)) i += 1 commas_value = "11" for pack in commas: self.assertEqual(pack, XDCCPack(rizon, "Bot4", int(commas_value))) commas_value += "1"
def __init__(self, server: IrcServer or str, user: User or str, logger: Logger or int = 0): """ Initializes the Client's Server Connection Information and disables Buffer Errors. The parameters can all be initialized with either a string/int representing the object's main value or the classes themselves :param server: The IRC Server to which the client will attempt to connect to. If a string was provided, create IrcServer with default port 6667 :param user: The User to log in to the IRC Server with. If a string was provided, create user object with that username. :param logger: The logger used to print informational messages to the console If an int was provided, creates a standard console logger with the specified verbosity level """ super().__init__() Variables.__init__(self) ConnectionStates.__init__(self) jaraco.logging.log_level("0") irc.client.ServerConnection.buffer_class = IgnoreErrorsBuffer irc.client.SimpleIRCClient.buffer_class = IgnoreErrorsBuffer self.user = user if user.__class__ == User else User(user) self.server = server if server.__class__ == IrcServer else \ IrcServer(server) self.logger = logger if logger.__class__ == Logger else Logger(logger)
def get_page_results(page_content: BeautifulSoup) -> List[XDCCPack]: """ This parses a single ixIRC page to find all search results from that page :param page_content: The Beautifulsoup-parsed content of the page :return: A list of XDCC Packs on that page """ results = [] packs = page_content.select("td") # Initialize the pack variables file_name = "" bot = "" server = "" pack_number = 0 size = "" # Keeps track of which column the parser is currently working on column_count = 0 # Counts how often the word "ago" was used, # which is used to keep track of on which # pack we currently are. Each pack has two instances of 'ago' occurring. ago_count = 0 # The process is aborted whenever an invalid pack is encountered aborted = False # Flag that lets other parts of the loop know that # we are moving on to the next pack next_element = False # line_part is a x,y section of the rows and columns of the website. # We go through it in the order Left->Right, Top->Bottom for line_part in packs: if next_element and line_part.text == "": # Jumps to the next not-empty element # if we are currently jumping to the next pack continue elif next_element and not line_part.text == "": # We reached a new pack, start parsing the new pack next_element = False elif not next_element and line_part.text == "": # Invalid pack element if a string == "" in the middle of the pack, # abort the pack and jump to next element aborted = True elif "ago" in line_part.text and column_count > 6: # Counts the number of times 'ago' is seen by the parser. # The last two elements of a pack both end # with 'ago', which makes it ideal to use as a marker # for when a single pack element ends. # This only starts counting once we got all relevant information # from the pack itself (column_count > 6) # to avoid conflicts when the substring 'ago' # is contained inside the file name ago_count += 1 # This gets the information from the pack and stores # them into variables. # This gets skipped if it has been established that the pack is invalid if not aborted: if column_count == 0: # File Name file_name = line_part.text elif column_count == 1: # Server Address server = "irc." + line_part.text.lower() + ".net" elif column_count == 2: # Channel Information, not needed due to /whois IRC queries pass elif column_count == 3: # Bot Name bot = line_part.text elif column_count == 4: # Pack Number pack_number = int(line_part.text) elif column_count == 5: pass # This is the 'gets' section, we don't need that elif column_count == 6: size = line_part.text.replace("\xa0", " ").replace(" ", "") # Resets state after a pack was successfully parsed, # and adds xdcc pack to results if not aborted and ago_count == 2: ago_count = 0 column_count = 0 next_element = True # Generate XDCCPack and append it to the list result = XDCCPack(IrcServer(server), bot, pack_number) result.set_filename(file_name) result.set_size(byte_string_to_byte_count(size)) results.append(result) # Resets state after invalid pack elif aborted and ago_count == 2: aborted = False ago_count = 0 column_count = 0 next_element = True if not next_element: # Only increment column_count in the middle of a pack, # not when we jump to the next pack element column_count += 1 return results
def setUp(self): self.pack = XDCCPack(IrcServer("irc.namibsun.net"), "xdcc_servbot", 1)
def test_server_entity_constructor_with_port(self): server = IrcServer("irc.namibsun.net", 9000) self.assertEqual(server.get_address(), "irc.namibsun.net") self.assertEqual(server.get_port(), 9000)
def test_network_error(self): pack = XDCCPack(IrcServer("gitlab.namibsun.net"), "xdcc_servbot", 2) results = XDCCDownloader("gitlab.namibsun.net", "random").\ download([pack]) self.assertEqual(results[pack], "NETWORKERROR")
def on_welcome(self, conn, event): self.current_pack = XDCCPack(IrcServer("irc.namibsun.net"), "notexistingbot", 1) self.connection.whois("notexistingbot")