diff --git a/src/core/data/scrapers/monkrus.py b/src/core/data/scrapers/monkrus.py index 67e64f3..c7af80f 100644 --- a/src/core/data/scrapers/monkrus.py +++ b/src/core/data/scrapers/monkrus.py @@ -2,6 +2,14 @@ from bs4 import BeautifulSoup import requests import time +Metadata = { + "headers" : ["Post Title", "Author"], + "name" : "m0nkrus", +} + +def get_Metadata(): + return Metadata + cache = { "data": [], "last_fetched": 0 @@ -67,4 +75,7 @@ def scrape_m0nkrus(query): filtered_post["id"] = len(filtered_posts) + 1 filtered_posts.append(filtered_post) - return filtered_posts \ No newline at end of file + return filtered_posts + +if __name__ == "__main__": + print(scrape_m0nkrus("adobe")) diff --git a/src/core/data/scrapers/rutracker.py b/src/core/data/scrapers/rutracker.py index bf67bb5..2266ead 100644 --- a/src/core/data/scrapers/rutracker.py +++ b/src/core/data/scrapers/rutracker.py @@ -2,6 +2,14 @@ import requests from core.utils.data.state import state from core.utils.logging.logs import consoleLog +Metadata = { + "headers" : ["Post Title", "Author", "Seeders", "Leechers"], + "name" : "rutracker", +} + +def get_Metadata(): + return Metadata + def scrape_rutracker(query): search = requests.get(f"{state.api_url}/search?q={query}") consoleLog("Sent request to server") @@ -9,7 +17,7 @@ def scrape_rutracker(query): try: return search.text except Exception: - consoleLog("No results found / No response from server") + consoleLog(f"No results found / No response from server, exception: {Exception}") return None else: return None diff --git a/src/core/data/scrapers/steamrip.py b/src/core/data/scrapers/steamrip.py index 0fa667d..8d0076e 100644 --- a/src/core/data/scrapers/steamrip.py +++ b/src/core/data/scrapers/steamrip.py @@ -2,7 +2,14 @@ from bs4 import BeautifulSoup import requests import re -#from core.utils.general.logs import consoleLog + +Metadata = { + "headers" : ["Game", "Availible Downloads"], + "name" : "steamrip", +} + +def get_Metadata(): + return Metadata def scrape_steamrip_links(text = None): if text is None: diff --git a/src/core/data/scrapers/uztracker.py b/src/core/data/scrapers/uztracker.py index 956629f..a110e00 100644 --- a/src/core/data/scrapers/uztracker.py +++ b/src/core/data/scrapers/uztracker.py @@ -3,6 +3,14 @@ from bs4 import BeautifulSoup from urllib.parse import urljoin from core.utils.logging.logs import consoleLog +Metadata = { + "headers" : ["Post Title", "Author"], + "name" : "uztracker", +} + +def get_Metadata(): + return Metadata + def scrape_uztracker(query): base_url="https://uztracker.net/" search_url = f"{base_url.rstrip('/')}/tracker.php?nm={query}" @@ -32,4 +40,4 @@ def scrape_uztracker(query): except requests.RequestException as e: consoleLog(f"Failed to fetch {search_url}: {e}") - return None \ No newline at end of file + return None diff --git a/src/core/interface/gui.py b/src/core/interface/gui.py index 7639c6d..c75f6aa 100644 --- a/src/core/interface/gui.py +++ b/src/core/interface/gui.py @@ -147,30 +147,25 @@ class MainWindow(QtWidgets.QMainWindow, QWidget): flush_log_buffer() - def create_tracker_table(headers, key): - table = QTableWidget() - table.setColumnCount(len(headers)) - table.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) - table.verticalHeader().setVisible(False) - table.setHorizontalHeaderLabels(headers) + # create tracker tables + state.trackertable + table = QTableWidget() + table.setColumnCount(len(headers)) + table.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + table.verticalHeader().setVisible(False) + table.setHorizontalHeaderLabels(headers) - header = table.horizontalHeader() - header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch) - header.setSectionResizeMode(1, QHeaderView.ResizeMode.Fixed) - header.resizeSection(1, 500) - header.setStretchLastSection(False) - - table.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) - table.viewport().setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) + header = table.horizontalHeader() + header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch) + header.setSectionResizeMode(1, QHeaderView.ResizeMode.Fixed) + header.resizeSection(1, 500) + header.setStretchLastSection(False) + + table.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) + table.viewport().setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) - state.tracker_list.update({key: table}) + state.tracker_list.update({key: table}) - - create_tracker_table(["Post Title", "Author", "Seeders", "Leechers"], "rutracker") - create_tracker_table(["Post Title", "Author"], "uztracker") - create_tracker_table(["Post Title", "Author"], "m0nkrus") - create_tracker_table(["Game", "Availible Downloads"], "steamrip") - container = QWidget() containerLayout = QVBoxLayout() containerLayout.addWidget(self.searchbar) diff --git a/src/core/interface/utils/fzhelper.py b/src/core/interface/utils/fzhelper.py index 5c4e261..9aba5d8 100644 --- a/src/core/interface/utils/fzhelper.py +++ b/src/core/interface/utils/fzhelper.py @@ -7,7 +7,7 @@ from copy import deepcopy class FuzzySearchWindow(QtWidgets.QWidget): # should work everywhere """ The dict should contain a: - name : str + $(keytosortby) : str THIS IS REQUIRED all other things will be displayed alphabetically after it. @@ -20,13 +20,14 @@ class FuzzySearchWindow(QtWidgets.QWidget): # should work everywhere keys in ignorekeys will be ignored and not displayed, e.g. if oyu have links in the database which arent relevant """ - def __init__(self, options: list[dict[str, str]], ignorekeys: list[str] = [], columnClicklShouldReturn = 1): + def __init__(self, options: list[dict[str, str]], ignorekeys: list[str] = [], columnClicklShouldReturn = 1, keytosortby = "name"): super().__init__() self.opts: list[dict[str, str]] = options self.filtered_opts = deepcopy(self.opts) self.ignorekeys = ignorekeys self.returncolumn = columnClicklShouldReturn + self.sortkey = keytosortby self.searchbox = QtWidgets.QLineEdit() self.searchbox.setPlaceholderText("Search for a game on Steamrip") @@ -74,7 +75,7 @@ class FuzzySearchWindow(QtWidgets.QWidget): # should work everywhere searchquery = self.searchbox.text() - options: Generator = fuzzyfinder.main.fuzzyfinder(searchquery, self.opts, accessor=lambda x: x["name"]) + options: Generator = fuzzyfinder.main.fuzzyfinder(searchquery, self.opts, accessor=lambda x: x[self.sortkey]) self.filtered_opts = [] @@ -90,7 +91,7 @@ class FuzzySearchWindow(QtWidgets.QWidget): # should work everywhere QtWidgets.QTableWidgetItem(value) ) - def cellClick(self, row: int, column: int): + def cellClick(self, row: int, _: int): item = self.table.item(row, self.returncolumn) if item is not None: diff --git a/src/core/interface/utils/searchhelper.py b/src/core/interface/utils/searchhelper.py index d3e4f14..9787c12 100644 --- a/src/core/interface/utils/searchhelper.py +++ b/src/core/interface/utils/searchhelper.py @@ -19,7 +19,7 @@ def return_pressed(self): return consoleLog(f"User searched for: {search_text}") - if state.tracker == "rutracker": + if state.currenttracker == "rutracker": response = scrape_rutracker(search_text) if response: _, state.posts, _, _, cached = split_data(response) diff --git a/src/core/utils/data/state.py b/src/core/utils/data/state.py index 1e33a70..6077010 100644 --- a/src/core/utils/data/state.py +++ b/src/core/utils/data/state.py @@ -1,6 +1,6 @@ from PySide6.QtCore import QObject, Signal from PySide6.QtWidgets import QTableWidget -from typing import Optional, Any, List, Dict +from typing import Any, List, Dict from pathlib import Path class AppState(QObject): @@ -8,20 +8,27 @@ class AppState(QObject): def __init__(self): super().__init__() - self.posts: list[Any] | None = None - self.post_titles: Optional[List] = None - self.post_urls: Optional[List] = None - self.post_author: List[str] = [] - self.post_seeders: List[str] = [] - self.post_leechers: List[str] = [] + self.posts: list[Dict[str,str]] | None = None # titles, urls, author, seederm leecher self.version: str = "dev" self._image_path: str = "" self.ignore_updates: bool = False self.debug: bool = False self.autoresume: bool = True - self.tracker: str = "rutracker" - self.tracker_list: dict[str, QTableWidget] = {} + + self.currenttracker: str = "rutracker" + self.trackertable: QTableWidget + self.trackers: Dict[str,Dict[str,Any]] # each tracker should add itself here, will be listed in order of module initialisation + ''' + an example: + "rutracker" : { + "name" : "rutracker", # name of the tracker + "posts" : [post1, post2, ...], # all the posts, will be in self.posts, + "headers" : ["author", "title"], # keys shown in the table + "sortkey" : "name" # the key to sort posts by # currently only usefull to steamrip + } + ''' self.api_url: str = "https://api.michijackson.xyz" + self.seeded_magnets: set = set() self.download_path: str = str(Path.home() / "Downloads") self.up_speed_limit: int = 0 self.down_speed_limit: int = 0 @@ -30,12 +37,30 @@ class AppState(QObject): self.settings_path: str = "" self.dl_session: Any = None self.active_downloads: Dict = {} - self.seeded_magnets: set = set() self.window_transparency: bool = False self.interfaces: List = [] self.active_interfaces: List = [] self.bound_interface: Any = None + def update_tracker_table(self, newtracker: str): + + if newtracker not in self.trackers.keys(): + raise ValueError("the selected tracker is not initialised.") + + self.trackertable.setColumnCount(self.trackers[self.currenttracker][]) + + for row_index, row_data in enumerate(self.trackers[self.currenttracker].values()): + for col_index, key in enumerate(row_data.keys()): + if key in self.trackers[self.currenttracker]["ignorekeys"]: + continue + value = row_data.get(key, "") + self.trackertable.setItem( + row_index, + col_index, + QtWidgets.QTableWidgetItem(value) + ) + + @property def image_path(self) -> str: return self._image_path