diff --git a/app-new.py b/app-new.py deleted file mode 100644 index 0de47ee..0000000 --- a/app-new.py +++ /dev/null @@ -1,503 +0,0 @@ -import sys -import json -import os -from PyQt6.QtWidgets import ( - QApplication, QWidget, QVBoxLayout, QHBoxLayout, - QLineEdit, QPushButton, QTextEdit, QMessageBox, - QSpacerItem, QSizePolicy, QLabel, QFileDialog, QDialog, - QFormLayout, QTableWidget, QTableWidgetItem, QHeaderView, - QComboBox, QAbstractItemView -) -from PyQt6.QtGui import QIcon, QDesktopServices -from PyQt6.QtCore import Qt, QDateTime, QUrl -from PyQt6.QtSvgWidgets import QSvgWidget - -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: - QDesktopServices.openUrl(QUrl(self.url)) # Open the URL directly if no valid search term is extracted - -class URLManager(QWidget): - def __init__(self): - super().__init__() - - self.settings = self.load_settings() - self.translations = {} - self.load_translations(f'lang/translations_{self.settings["language"].lower()[:2]}.json') - self.setWindowTitle(self.get_translation('title', 'URL Manager')) - self.setGeometry(100, 100, 600, 600) - self.setWindowIcon(QIcon('assets/logo.png')) - - self.layout = QVBoxLayout() - - # URL input and settings button layout - self.url_layout = QHBoxLayout() - self.url_input = QLineEdit() - self.url_input.setPlaceholderText(self.get_translation('url_placeholder', 'Enter URL')) - self.url_layout.addWidget(self.url_input) - - self.settings_button = QPushButton() - self.settings_button.setFixedSize(28, 28) - self.settings_button.setStyleSheet("padding: 5px;") - self.settings_button.clicked.connect(self.show_settings_dialog) - self.url_layout.addWidget(self.settings_button) - - self.info_button = QPushButton() - self.info_button.setFixedSize(28, 28) - self.info_button.setStyleSheet("padding: 5px;") - self.info_button.clicked.connect(self.show_info_dialog) - self.url_layout.addWidget(self.info_button) - - self.layout.addLayout(self.url_layout) - - self.update_icon_color() - - self.description_input = QTextEdit() - self.description_input.setPlaceholderText(self.get_translation('description_placeholder', 'Enter Description or Thoughts')) - self.description_input.setMaximumHeight(100) - self.layout.addWidget(self.description_input) - - self.add_button = QPushButton(self.get_translation('save_url_button', 'Save URL')) - self.add_button.clicked.connect(self.add_url) - self.layout.addWidget(self.add_button) - - self.layout.addSpacerItem(QSpacerItem(0, 10, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)) - - self.search_layout = QHBoxLayout() - self.search_input = QLineEdit() - self.search_input.setPlaceholderText(self.get_translation('search_placeholder', 'Search...')) - self.search_input.textChanged.connect(self.filter_urls) - self.search_layout.addWidget(self.search_input) - self.layout.addLayout(self.search_layout) - - self.search_input.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred) - - self.url_list = QTableWidget() - self.url_list.setColumnCount(3) - self.url_list.setHorizontalHeaderLabels([ - self.get_translation('column_url', 'URL'), - self.get_translation('column_date', 'Date'), - self.get_translation('column_actions', 'Actions') - ]) - self.url_list.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch) - self.url_list.setColumnWidth(1, 150) - self.url_list.setColumnWidth(2, 100) - self.url_list.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) - self.layout.addWidget(self.url_list) - - self.setLayout(self.layout) - - self.urls = [] - - self.load_urls() - - self.search_engines = { - "Bing": "https://www.bing.com/search?q=", - "Brave": "https://search.brave.com/search?q=", - "DuckDuckGo": "https://duckduckgo.com/?q=", - "Ecosia": "https://www.ecosia.org/search?q=", - "Google": "https://www.google.com/search?q=", - "Startpage": "https://www.startpage.com/do/search?q=", - "Swisscows": "https://swisscows.com/web?query=" - } - - def load_translations(self, file_path): - if os.path.exists(file_path): - with open(file_path, 'r') as file: - data = json.load(file) - self.translations = data['translations'] - - def get_translation(self, key, default): - return self.translations.get(key, default) - - def update_icon_color(self): - palette = self.palette() - if palette.color(palette.ColorRole.Window).value() < 128: - settings_icon_path = 'assets/cogwheel_dark.svg' - info_icon_path = 'assets/info_dark.svg' - self.action_icons = { - "visit": 'assets/visit_dark.svg', - "info": 'assets/info_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 = { - "visit": 'assets/visit_light.svg', - "info": 'assets/info_light.svg', - "search": 'assets/search_light.svg', - "delete": 'assets/delete_light.svg' - } - - self.settings_button.setIcon(QIcon(settings_icon_path)) - self.info_button.setIcon(QIcon(info_icon_path)) - - def add_url(self): - url = self.url_input.text() - description = self.description_input.toPlainText() - if url: - date_added = QDateTime.currentDateTime().toString(Qt.DateFormat.ISODate) - url_data = {'url': url, 'description': description, 'date': date_added} - self.urls.append(url_data) - self.save_url(url_data) - self.update_url_list() - self.url_input.clear() - self.description_input.clear() - - def save_url(self, url_data): - 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: - url_list = [] - url_list.append(url_data) - with open(url_path, 'w') as file: - json.dump(url_list, file) - - def update_url(self, row, new_url, new_description): - self.urls[row]['url'] = new_url - self.urls[row]['description'] = new_description - self.save_urls() - self.update_url_list() - - def delete_url(self, row): - reply = QMessageBox.question(self, self.get_translation('delete_confirmation_title', 'Delete URL'), self.get_translation('delete_confirmation', 'Are you sure you want to delete this URL?'), - QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No) - if reply == QMessageBox.StandardButton.Yes: - del self.urls[row] - self.save_urls() - self.update_url_list() - - def filter_urls(self): - search_term = self.search_input.text().strip().lower() - if not search_term: - self.update_url_list() - return - - 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 update_url_list(self, urls=None): - self.url_list.setRowCount(0) - urls_to_display = urls if urls else self.urls - for row, url in enumerate(urls_to_display): - self.url_list.insertRow(row) - self.url_list.setItem(row, 0, QTableWidgetItem(url['url'])) - formatted_date = self.format_date(url['date']) - date_item = QTableWidgetItem(formatted_date) - date_item.setTextAlignment(Qt.AlignmentFlag.AlignVCenter) - self.url_list.setItem(row, 1, date_item) - - actions_layout = QHBoxLayout() - actions_layout.setContentsMargins(0, 0, 0, 0) - actions_layout.setAlignment(Qt.AlignmentFlag.AlignCenter) - - visit_button = QPushButton() - visit_button.setIcon(QIcon(self.action_icons["visit"])) - visit_button.setFixedSize(22, 22) - visit_button.setStyleSheet("border: none; padding: 3px;") - visit_button.clicked.connect(lambda _, url=url['url']: self.visit_url(url)) - actions_layout.addWidget(visit_button) - - info_button = QPushButton() - info_button.setIcon(QIcon(self.action_icons["info"])) - info_button.setFixedSize(22, 22) - info_button.setStyleSheet("border: none; padding: 3px;") - info_button.clicked.connect(lambda _, row=row: self.view_description(row)) - actions_layout.addWidget(info_button) - - search_button = QPushButton() - search_button.setIcon(QIcon(self.action_icons["search"])) - search_button.setFixedSize(22, 22) - search_button.setStyleSheet("border: none; padding: 3px;") - 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"])) - delete_button.setFixedSize(22, 22) - delete_button.setStyleSheet("border: none; padding: 3px;") - delete_button.clicked.connect(lambda _, row=row: self.delete_url(row)) - actions_layout.addWidget(delete_button) - - actions_widget = QWidget() - actions_widget.setLayout(actions_layout) - - self.url_list.setCellWidget(row, 2, actions_widget) - - vertical_header = self.url_list.verticalHeader() - vertical_header.setVisible(False) - - def format_date(self, date_str): - date = QDateTime.fromString(date_str, Qt.DateFormat.ISODate) - if self.settings['date_format'] == 'Nerdy': - return date.toString("yyyy-MM-ddTHH:mm:ss") - elif self.settings['date_format'] == 'Normal': - return date.toString("dd/MM/yy @ HH:mm") - elif self.settings['date_format'] == 'Murica!': - return date.toString("MM/dd/yyyy hh:mm AP") - else: - return date_str - - def visit_url(self, url): - QDesktopServices.openUrl(QUrl(url)) - - def view_description(self, row): - dialog = DescriptionDialog(self, row) - dialog.exec() - - 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' - if os.path.exists(settings_path): - with open(settings_path, 'r') as file: - settings = json.load(file) - self.data_directory = settings['data_directory'] - self.search_engine = settings['search_engine'] - self.date_format = settings.get('date_format', 'Nerdy') - self.language = settings.get('language', 'English') - return settings - else: - default_settings = { - 'data_directory': 'data/', - 'search_engine': 'Google', - 'date_format': 'Nerdy', - 'language': 'English' - } - self.save_settings(default_settings) - return default_settings - - def save_settings(self, settings=None): - settings_path = 'data/settings.json' - os.makedirs(os.path.dirname(settings_path), exist_ok=True) - if settings is None: - settings = { - 'data_directory': self.data_directory, - 'search_engine': self.search_engine, - 'date_format': self.date_format, - 'language': self.language - } - with open(settings_path, 'w') as file: - json.dump(settings, file) - - def load_urls(self): - 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): - 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) - dialog.setWindowTitle(self.get_translation('about_title', 'About URL Manager')) - - layout = QVBoxLayout() - - svg_widget = QSvgWidget('assets/logo.svg') - svg_widget.setFixedSize(256, 256) - layout.addWidget(svg_widget, alignment=Qt.AlignmentFlag.AlignCenter) - - written_by_label = QLabel(self.get_translation('developed_by', 'Developed by Axel Rafn')) - layout.addWidget(written_by_label, alignment=Qt.AlignmentFlag.AlignCenter) - - link_label = QLabel() - link_label.setText(f'{self.get_translation("repository_link_name", "Project Home")}') - link_label.setOpenExternalLinks(True) - layout.addWidget(link_label, alignment=Qt.AlignmentFlag.AlignCenter) - - dialog.setLayout(layout) - dialog.exec() - - def show_settings_dialog(self): - dialog = SettingsDialog(self) - if dialog.exec() == QDialog.DialogCode.Accepted: - self.settings = self.load_settings() - self.update_url_list() - -class DescriptionDialog(QDialog): - def __init__(self, parent, row): - super().__init__(parent) - self.parent = parent - self.row = row - self.setWindowTitle(self.parent.get_translation('description_title', 'URL Description')) - - layout = QVBoxLayout() - - self.url_input = QLineEdit(self.parent.urls[row]['url']) - layout.addWidget(self.url_input) - - self.description_input = QTextEdit(self.parent.urls[row]['description']) - layout.addWidget(self.description_input) - - button_layout = QHBoxLayout() - self.update_button = QPushButton(self.parent.get_translation('update_button', 'Update')) - self.update_button.clicked.connect(self.update_url) - self.close_button = QPushButton(self.parent.get_translation('close_button', 'Close')) - self.close_button.clicked.connect(self.close) - button_layout.addWidget(self.update_button) - button_layout.addWidget(self.close_button) - layout.addLayout(button_layout) - - self.setLayout(layout) - - def update_url(self): - new_url = self.url_input.text() - new_description = self.description_input.toPlainText() - self.parent.update_url(self.row, new_url, new_description) - self.accept() - -class SettingsDialog(QDialog): - def __init__(self, parent=None): - super().__init__(parent) - self.setWindowTitle(parent.get_translation('settings_title', 'Settings')) - self.setFixedWidth(360) - - self.parent = parent - - layout = QVBoxLayout() - - directory_label = QLabel(parent.get_translation('data_directory_label', 'Data Directory:')) - layout.addWidget(directory_label) - - directory_layout = QHBoxLayout() - self.directory_input = QLineEdit(self.parent.settings['data_directory']) - self.browse_button = QPushButton(self.parent.get_translation('browse_button', 'Browse...')) - self.browse_button.clicked.connect(self.browse_directory) - directory_layout.addWidget(self.directory_input) - directory_layout.addWidget(self.browse_button) - layout.addLayout(directory_layout) - - layout.addSpacerItem(QSpacerItem(0, 4, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)) - - form_layout = QFormLayout() - - # Populate Search Engine Combobox - self.search_engine_combobox = QComboBox() - search_engines = sorted(self.parent.search_engines.keys()) - self.search_engine_combobox.addItems(search_engines) - self.search_engine_combobox.setCurrentText(self.parent.settings['search_engine']) - form_layout.addRow(self.parent.get_translation('search_engine_label', 'Search Engine:'), self.search_engine_combobox) - - # Populate Date Format Combobox - self.date_format_combobox = QComboBox() - self.date_format_combobox.addItems(["Nerdy", "Normal", "Murica!"]) - self.date_format_combobox.setCurrentText(self.parent.settings['date_format']) - form_layout.addRow(self.parent.get_translation('date_format_label', 'Date Format:'), self.date_format_combobox) - - # Populate Language Combobox - self.language_combobox = QComboBox() - self.populate_language_combobox() - current_language_code = self.parent.settings['language'] - self.set_current_language(current_language_code) - form_layout.addRow(self.parent.get_translation('language_label', 'Language:'), self.language_combobox) - - layout.addLayout(form_layout) - - self.save_button = QPushButton(self.parent.get_translation('save_button', 'Save')) - self.save_button.clicked.connect(self.save_settings) - layout.addWidget(self.save_button) - - self.setLayout(layout) - - def browse_directory(self): - directory = QFileDialog.getExistingDirectory(self, "Select Directory") - if directory: - self.directory_input.setText(directory) - - def populate_language_combobox(self): - lang_dir = 'lang/' - language_files = [f for f in os.listdir(lang_dir) if f.startswith('translations_') and f.endswith('.json')] - self.language_map = {} - - for file_name in language_files: - file_path = os.path.join(lang_dir, file_name) - with open(file_path, 'r') as file: - data = json.load(file) - language_name = data.get('language', 'Unknown') - language_code = file_name[len('translations_'):-len('.json')] - display_text = f"{language_name} ({language_code})" - self.language_combobox.addItem(display_text) - self.language_map[language_code] = display_text - - def set_current_language(self, language_code): - if language_code in self.language_map: - display_text = self.language_map[language_code] - index = self.language_combobox.findText(display_text) - if index != -1: - self.language_combobox.setCurrentIndex(index) - - def save_settings(self): - selected_language = self.language_combobox.currentText() - language_code = selected_language.split('(')[-1].strip(' )') # Extract language code from "(en)" format - old_language = self.parent.settings['language'] - self.parent.settings['data_directory'] = self.directory_input.text() - self.parent.settings['search_engine'] = self.search_engine_combobox.currentText() - self.parent.settings['date_format'] = self.date_format_combobox.currentText() - self.parent.settings['language'] = language_code - self.parent.save_settings(self.parent.settings) - - if old_language != language_code: - QMessageBox.information(self, self.parent.get_translation('restart_required_title', 'Restart Required'), self.parent.get_translation('restart_required_message', 'You need to restart the application for the language changes to take effect.')) - - self.accept() - -if __name__ == '__main__': - app = QApplication(sys.argv) - window = URLManager() - window.show() - sys.exit(app.exec()) diff --git a/app.py b/app.py index 9a0baec..0de47ee 100644 --- a/app.py +++ b/app.py @@ -58,7 +58,7 @@ class URLSearch: search_url = f"{self.search_engine_url}{search_query}" QDesktopServices.openUrl(QUrl(search_url)) else: - print("No valid search term extracted, search disabled.") + QDesktopServices.openUrl(QUrl(self.url)) # Open the URL directly if no valid search term is extracted class URLManager(QWidget): def __init__(self):