Compare commits

...

7 Commits

8 changed files with 55 additions and 119 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ def _get_telegram_posts():
return(posts)
def scrape_monkrus_telegram(query):
def scrape_m0nkrus(query):
posts = _get_telegram_posts()
filtered_posts = []
+2 -2
View File
@@ -3,8 +3,8 @@ from core.utils.data.state import state
from core.utils.logging.logs import consoleLog
def scrape_rutracker(search_text):
search = requests.get(f"{state.api_url}/search?q={search_text}")
def scrape_rutracker(query):
search = requests.get(f"{state.api_url}/search?q={query}")
consoleLog("Sent request to server")
if search:
try:
+28 -73
View File
@@ -1,83 +1,38 @@
import requests
import threading
from bs4 import BeautifulSoup
from core.utils.data.state import state
from urllib.parse import urljoin
from core.utils.logging.logs import consoleLog
from core.utils.general.wrappers import run_thread
def scrape_uztracker(query):
base_url="https://uztracker.net/"
search_url = f"{base_url.rstrip('/')}/tracker.php?nm={query}"
consoleLog(search_url)
posts = []
global url_uztracker
url_uztracker = "https://uztracker.net/tracker.php?nm="
def init_uztracker():
global up
global soup
try:
response = requests.get(url_uztracker, timeout=10)
if response.status_code == 200:
up = True
else:
up = False
consoleLog(f"Uztracker seems down, status code: {response.status_code}")
except requests.exceptions.RequestException as e:
consoleLog(f"Request Exception on {url_uztracker}:")
consoleLog(str(e))
consoleLog("Is the Site down?")
up = False
run_thread(threading.Thread(target=init_uztracker))
def scrape_uztracker(search):
if up:
search_url = url_uztracker + search
consoleLog(search_url)
result = False
global results
global resulttitles
results = []
resulttitles = []
try:
resultCount = 0
response = requests.get(search_url)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
links = soup.find_all('a', class_="genmed tLink", href=lambda x: x and x.startswith('./viewtopic'))
for link in links:
if link.b:
resultCount += 1
results.append(link['href'])
resulttitles.append(link.b.text)
result = True
if result:
return resulttitles, results
if not result:
# add popup in gui for no result
return None
except requests.RequestException as e:
if result:
consoleLog(f"Failed to fetch {search_url}: {e}")
return None
else:
consoleLog("Error: Uztracker down")
return None, None
def get_post_title(post_url):
if up:
response = requests.get(post_url)
response = requests.get(search_url)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
maintitle = soup.find(class_='tt-text')
if maintitle:
return maintitle.text
else:
consoleLog("Program not found")
else:
consoleLog("Error: Uztracker down")
return None
links = soup.find_all('tr', class_="tCenter hl-tr", id=lambda x: x and x.startswith('tor_'))
for link in links:
theme_link = link.find('a', class_="genmed tLink", href=lambda x: x and x.startswith('./viewtopic'))
url = urljoin(base_url, theme_link['href'])
title = theme_link.b.text
author_link = link.find('a', class_="med")
author = author_link.text.strip() if author_link else "Unknown"
posts.append(dict(
title=title,
url=url,
author=author
))
return posts
except requests.RequestException as e:
consoleLog(f"Failed to fetch {search_url}: {e}")
return None
+4 -1
View File
@@ -18,7 +18,7 @@ from PySide6.QtWidgets import (
QStyledItemDelegate,
)
from PySide6.QtGui import QIcon, QCloseEvent, QImage, QPixmap, QContextMenuEvent
from PySide6.QtGui import QIcon, QCloseEvent, QImage, QPixmap, QContextMenuEvent, QGuiApplication
import darkdetect
import threading
import platform
@@ -67,6 +67,9 @@ def download_update(latest_version):
sys.exit(0)
def windowCloseHelper():
QGuiApplication.quit()
class MainWindow(QtWidgets.QMainWindow, QWidget):
log_signal = Signal(str) # Thread-safe signal for logging
+12 -29
View File
@@ -2,10 +2,16 @@ from PySide6.QtWidgets import QTableWidgetItem
from core.utils.logging.logs import consoleLog
from core.data.scrapers.uztracker import scrape_uztracker
from core.data.scrapers.rutracker import scrape_rutracker
from core.data.scrapers.monkrus import scrape_monkrus_telegram
from core.utils.network.jsonhandler import split_data, format_data, format_data_m0nkrus
from core.data.scrapers.monkrus import scrape_m0nkrus
from core.utils.network.jsonhandler import split_data, format_data, format_data_minimal
from core.utils.data.state import state
scrapers = {
"uztracker": scrape_uztracker,
"rutracker": scrape_rutracker,
"m0nkrus": scrape_m0nkrus
}
def return_pressed(self):
search_text = self.searchbar.text()
if search_text == "":
@@ -13,29 +19,7 @@ def return_pressed(self):
return
consoleLog(f"User searched for: {search_text}")
if state.tracker == "uztracker":
response = scrape_uztracker(search_text)
if response:
state.post_titles, state.post_urls = response
state.tracker_list[state.tracker].clear()
if state.post_titles and len(state.post_titles) > 0:
state.tracker_list[state.tracker].setHorizontalHeaderLabels(["Post Title", "Author"])
state.tracker_list[state.tracker].setRowCount(len(state.post_titles))
for i, author in enumerate(state.post_author):
state.tracker_list[state.tracker].setItem(i, 1, QTableWidgetItem(author))
for i, title in enumerate(state.post_titles):
state.tracker_list[state.tracker].setItem(i, 0, QTableWidgetItem(title))
self.show_empty_results(False)
else:
consoleLog(f"No Results for {search_text}")
state.tracker_list[state.tracker].clear()
self.show_empty_results(True)
else:
consoleLog(f"No response from uztracker")
state.tracker_list[state.tracker].clear()
self.show_empty_results(True)
elif state.tracker == "rutracker":
if state.tracker == "rutracker":
response = scrape_rutracker(search_text)
if response:
_, state.posts, _, _, cached = split_data(response)
@@ -64,15 +48,14 @@ def return_pressed(self):
state.tracker_list[state.tracker].clear()
self.show_empty_results(True)
elif state.tracker == "m0nkrus":
state.posts = scrape_monkrus_telegram(search_text)
elif state.tracker is not None:
state.posts = scrapers[state.tracker](search_text)
if state.posts == []:
consoleLog(f"No Results for {search_text}")
state.tracker_list[state.tracker].clear()
self.show_empty_results(True)
else:
state.post_titles, _, state.post_author = format_data_m0nkrus(state.posts)
state.post_author, state.post_titles, state.post_urls = format_data_minimal(state.posts)
self.show_empty_results(False)
state.tracker_list[state.tracker].clear()
state.tracker_list[state.tracker].setHorizontalHeaderLabels(["Post Title", "Author"])
+1 -1
View File
@@ -8,7 +8,7 @@ class AppState(QObject):
def __init__(self):
super().__init__()
self.posts: List[Dict[str, Any]] = []
self.posts: list[Any] | None = None
self.post_titles: Optional[List] = None
self.post_urls: Optional[List] = None
self.post_author: List[str] = []
+2 -2
View File
@@ -20,12 +20,12 @@ def format_data(data):
return post_titles, post_links, post_author, post_seeders, post_leechers
def format_data_m0nkrus(data):
def format_data_minimal(data):
post_author = [post["author"] for post in data]
post_titles = [post["title"] for post in data]
post_links = [post["url"] for post in data]
return post_titles, post_links, post_author
return post_author, post_titles, post_links
+5 -10
View File
@@ -1,4 +1,4 @@
from core.interface.gui import MainWindow
from core.interface.gui import MainWindow, windowCloseHelper
from core.utils.data.state import state
from core.utils.logging.logs import consoleLog
from core.network.libtorrent_misc import send_notification, update_log
@@ -14,15 +14,9 @@ import qdarktheme
import threading
import platform
import signal
import argparse
import sys
import time
parser = argparse.ArgumentParser()
parser.add_argument("--debug", action="store_true")
args = parser.parse_args()
def run_gui():
app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv)
qdarktheme.setup_theme("auto")
@@ -39,14 +33,13 @@ def run_gui():
def keyboardinterrupthandler(signum, frame):
closehelper()
windowCloseHelper()
if __name__ == "__main__":
def main():
start_time = time.perf_counter()
read_config()
logs = get_download_logs()
_, downloads = split_data(logs)
if args.debug:
state.debug = args.debug # override of read_config
signal.signal(signal.SIGINT, keyboardinterrupthandler)
consoleLog("Starting SoftwareManager...")
consoleLog("Fetching Network Interfaces...")
@@ -65,3 +58,5 @@ if __name__ == "__main__":
consoleLog(f"Initialization completed in {elapsed:.2f}s. Launching GUI")
run_gui()
if __name__ == "__main__":
main()