From f9ec284ec209d58e0e8a1c3bdab2c9bdee051a02 Mon Sep 17 00:00:00 2001 From: Axel Rafn Date: Sat, 13 Jul 2024 15:27:08 +0200 Subject: [PATCH] chore: Update translations for English and Icelandic languages, change icon colors, and add more icons --- app.py | 202 +++++++++++++++++++++++++-------------------------------- 1 file changed, 88 insertions(+), 114 deletions(-) diff --git a/app.py b/app.py index 4dd4ed8..7b64b95 100644 --- a/app.py +++ b/app.py @@ -1,15 +1,67 @@ import sys import json import os +import re from PyQt5.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QHBoxLayout, - QLineEdit, QPushButton, QTextEdit, QComboBox, - QMessageBox, QSpacerItem, QSizePolicy, QLabel, QFileDialog, QDialog, QFormLayout, QTableWidget, QTableWidgetItem, - QHeaderView + QLineEdit, QPushButton, QTextEdit, QMessageBox, + QSpacerItem, QSizePolicy, QLabel, QFileDialog, QDialog, + QFormLayout, QTableWidget, QTableWidgetItem, QHeaderView, + QComboBox ) from PyQt5.QtGui import QIcon -from PyQt5.QtCore import Qt, QDateTime +from PyQt5.QtCore import Qt, QDateTime, QUrl from PyQt5.QtSvg import QSvgWidget +from PyQt5.QtGui import QDesktopServices + + +class URLSearch: + def __init__(self, url, search_engine_url): + self.url = url + self.search_engine_url = search_engine_url + self.filters_dir = 'filters/' + self.available_filters = self.load_filters() + + def load_filters(self): + filters = {} + for file_name in os.listdir(self.filters_dir): + if file_name.endswith('.filter.py'): + domain = '.'.join(file_name.split('.')[:-2]) # Extracting domain.tld from domain.tld.filter.py + filters[domain] = os.path.join(self.filters_dir, file_name) + # print("Loaded filters:", filters) # Debug print + return filters + + def extract_terms(self): + parsed_url = QUrl(self.url) + host_parts = parsed_url.host().split('.') + domain = '.'.join(host_parts[-2:]) # Extract full domain including TLD + # print("Extracted domain:", domain) # Debug print + if domain in self.available_filters: + filter_file = self.available_filters[domain] + terms = self.apply_filter(filter_file) + if terms: + return terms + return None + + def apply_filter(self, filter_file): + try: + with open(filter_file, 'r') as file: + filter_code = file.read() + local_vars = {'url': self.url, 'terms': [], 'QUrl': QUrl} + exec(filter_code, {}, local_vars) + return local_vars['terms'] + except Exception as e: + print(f"Error applying filter: {e}") + return None + + def search(self): + terms = self.extract_terms() + if terms: + search_query = '+'.join(terms) + search_url = f"{self.search_engine_url}{search_query}" + QDesktopServices.openUrl(QUrl(search_url)) + else: + print("No valid search term extracted, search disabled.") class URLManager(QWidget): def __init__(self): @@ -49,26 +101,6 @@ class URLManager(QWidget): self.description_input.setMaximumHeight(100) self.layout.addWidget(self.description_input) - self.group_layout = QHBoxLayout() - - self.group_combobox = QComboBox() - self.group_combobox.addItem(self.translations['all_categories']) - self.group_combobox.addItem(self.translations['default_category']) - self.group_combobox.currentTextChanged.connect(self.filter_urls_by_category) - self.group_layout.addWidget(self.group_combobox) - - self.category_input = QLineEdit() - self.category_input.setPlaceholderText(self.translations['category_name']) - self.category_input.setFixedWidth(3 * 100) # Fixed width for the text input box, assuming "Save" button width is 100 - self.group_layout.addWidget(self.category_input) - - self.save_category_button = QPushButton(self.translations['save_category_button']) - self.save_category_button.setFixedWidth(100) # Fixed width for the "Save" button - self.save_category_button.clicked.connect(self.save_category) - self.group_layout.addWidget(self.save_category_button) - - self.layout.addLayout(self.group_layout) - self.add_button = QPushButton(self.translations['save_url_button']) self.add_button.clicked.connect(self.add_url) self.layout.addWidget(self.add_button) @@ -86,7 +118,7 @@ class URLManager(QWidget): self.url_list = QTableWidget() self.url_list.setColumnCount(3) - self.url_list.setHorizontalHeaderLabels(['URL', self.translations['column_date'], self.translations['column_actions']]) + self.url_list.setHorizontalHeaderLabels([self.translations['url_placeholder'], self.translations['column_date'], self.translations['column_actions']]) self.url_list.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.url_list.setColumnWidth(1, 150) self.url_list.setColumnWidth(2, 100) @@ -95,9 +127,7 @@ class URLManager(QWidget): self.setLayout(self.layout) self.urls = [] - self.groups = set() - self.load_categories() self.load_urls() self.search_engines = { @@ -122,17 +152,15 @@ class URLManager(QWidget): settings_icon_path = 'assets/cogwheel_dark.svg' info_icon_path = 'assets/info_dark.svg' self.action_icons = { - "edit": 'assets/edit_dark.svg', - "delete": 'assets/delete_dark.svg', - "search": 'assets/search_dark.svg' + "search": 'assets/search_dark.svg', + "delete": 'assets/delete_dark.svg' } else: settings_icon_path = 'assets/cogwheel_light.svg' info_icon_path = 'assets/info_light.svg' self.action_icons = { - "edit": 'assets/edit_light.svg', - "delete": 'assets/delete_light.svg', - "search": 'assets/search_light.svg' + "search": 'assets/search_light.svg', + "delete": 'assets/delete_light.svg' } self.settings_button.setIcon(QIcon(settings_icon_path)) @@ -141,10 +169,9 @@ class URLManager(QWidget): def add_url(self): url = self.url_input.text() description = self.description_input.toPlainText() - group = self.group_combobox.currentText() if url: date_added = QDateTime.currentDateTime().toString(Qt.ISODate) - url_data = {'url': url, 'description': description, 'date': date_added, 'group': group} + url_data = {'url': url, 'description': description, 'date': date_added} self.urls.append(url_data) self.save_url(url_data) self.update_url_list() @@ -152,17 +179,15 @@ class URLManager(QWidget): self.description_input.clear() def save_url(self, url_data): - category = url_data['group'] - category_filename = self.get_category_filename(category) - category_path = os.path.join(self.settings['data_directory'], category_filename) - if os.path.exists(category_path): - with open(category_path, 'r') as file: - category_urls = json.load(file) + url_path = os.path.join(self.settings['data_directory'], 'urls.json') + if os.path.exists(url_path): + with open(url_path, 'r') as file: + url_list = json.load(file) else: - category_urls = [] - category_urls.append(url_data) - with open(category_path, 'w') as file: - json.dump(category_urls, file) + url_list = [] + url_list.append(url_data) + with open(url_path, 'w') as file: + json.dump(url_list, file) def update_url(self): selected_item = self.url_list.currentItem() @@ -194,14 +219,6 @@ class URLManager(QWidget): filtered_urls = [url for url in self.urls if search_term in url['url'].lower() or search_term in url['description'].lower()] self.update_url_list(filtered_urls) - def filter_urls_by_category(self): - selected_category = self.group_combobox.currentText() - if selected_category == self.translations['all_categories']: - self.update_url_list(self.urls) - else: - filtered_urls = [url for url in self.urls if url['group'] == selected_category] - self.update_url_list(filtered_urls) - def update_url_list(self, urls=None): self.url_list.setRowCount(0) urls_to_display = urls if urls else self.urls @@ -213,12 +230,12 @@ class URLManager(QWidget): actions_layout = QHBoxLayout() - edit_button = QPushButton() - edit_button.setIcon(QIcon(self.action_icons["edit"])) - edit_button.setFixedSize(18, 18) - edit_button.setStyleSheet("border: none; padding: 0px;") - edit_button.clicked.connect(lambda _, row=row: self.edit_url(row)) - actions_layout.addWidget(edit_button) + search_button = QPushButton() + search_button.setIcon(QIcon(self.action_icons["search"])) + search_button.setFixedSize(18, 18) + search_button.setStyleSheet("border: none; padding: 0px;") + search_button.clicked.connect(lambda _, url=url['url']: self.search_url(url)) + actions_layout.addWidget(search_button) delete_button = QPushButton() delete_button.setIcon(QIcon(self.action_icons["delete"])) @@ -246,11 +263,10 @@ class URLManager(QWidget): else: return date_str - def edit_url(self, row): - url = self.urls[row]['url'] - description = self.urls[row]['description'] - self.url_input.setText(url) - self.description_input.setPlainText(description) + def search_url(self, url): + search_engine_url = self.search_engines[self.settings['search_engine']] + url_search = URLSearch(url, search_engine_url) + url_search.search() def load_settings(self): settings_path = 'data/settings.json' @@ -285,59 +301,17 @@ class URLManager(QWidget): with open(settings_path, 'w') as file: json.dump(settings, file) - def load_categories(self): - self.groups = set() - categories_path = os.path.join(self.settings['data_directory'], 'categories.json') - if os.path.exists(categories_path): - with open(categories_path, 'r') as file: - self.groups = set(json.load(file)) - self.update_group_combobox() - self.group_combobox.setCurrentText(self.translations['default_category']) - - def save_categories(self): - categories_path = os.path.join(self.settings['data_directory'], 'categories.json') - os.makedirs(os.path.dirname(categories_path), exist_ok=True) - with open(categories_path, 'w') as file: - json.dump(list(self.groups), file) - - def update_group_combobox(self): - self.group_combobox.clear() - self.group_combobox.addItem(self.translations['all_categories']) - self.group_combobox.addItem(self.translations['default_category']) - for group in sorted(self.groups): - self.group_combobox.addItem(group) - - def save_category(self): - new_category = self.category_input.text().strip() - if new_category and new_category not in self.groups: - self.groups.add(new_category) - self.save_categories() - self.update_group_combobox() - self.category_input.clear() - def load_urls(self): - self.urls = [] - for group in self.groups: - category_filename = self.get_category_filename(group) - category_path = os.path.join(self.settings['data_directory'], category_filename) - if os.path.exists(category_path): - with open(category_path, 'r') as file: - self.urls.extend(json.load(file)) + url_path = os.path.join(self.settings['data_directory'], 'urls.json') + if os.path.exists(url_path): + with open(url_path, 'r') as file: + self.urls = json.load(file) self.update_url_list() def save_urls(self): - for group in self.groups: - group_urls = [url for url in self.urls if url['group'] == group] - category_filename = self.get_category_filename(group) - category_path = os.path.join(self.settings['data_directory'], category_filename) - with open(category_path, 'w') as file: - json.dump(group_urls, file) - - def get_category_filename(self, category): - if ' ' in category: - return category.replace(' ', '_').lower() + '.json' - else: - return category.lower() + '.json' + url_path = os.path.join(self.settings['data_directory'], 'urls.json') + with open(url_path, 'w') as file: + json.dump(self.urls, file) def show_info_dialog(self): dialog = QDialog(self) @@ -363,7 +337,7 @@ class URLManager(QWidget): def show_settings_dialog(self): dialog = SettingsDialog(self) if dialog.exec_() == QDialog.Accepted: - self.load_settings() + self.settings = self.load_settings() self.update_url_list() class SettingsDialog(QDialog):