From 9d1c441fc215967a3c26f4b00d995597ebe6b121 Mon Sep 17 00:00:00 2001 From: Faisal Shahzad <84210709+seowings@users.noreply.github.com> Date: Sun, 8 Oct 2023 19:00:38 +0200 Subject: [PATCH 1/5] detached project from mainwindow --- src/staticwordpress/core/project.py | 2 +- src/staticwordpress/core/utils.py | 13 +- src/staticwordpress/core/workflow.py | 6 +- src/staticwordpress/gui/config.py | 4 +- src/staticwordpress/gui/mainwindow.py | 516 +++--------------- src/staticwordpress/gui/project.py | 459 ++++++++++++++++ src/staticwordpress/gui/rawtext.py | 4 +- src/staticwordpress/share/_ignore | 1 + src/staticwordpress/share/config.json | 2 +- src/staticwordpress/share/gui.json | 77 ++- .../share/icons/project_close.svg | 38 ++ .../share/icons/project_settings.svg | 38 ++ .../share/icons/visibility.svg | 38 ++ .../share/icons/visibility_lock.svg | 38 ++ tests/test_project.py | 2 +- 15 files changed, 745 insertions(+), 493 deletions(-) create mode 100644 src/staticwordpress/gui/project.py create mode 100644 src/staticwordpress/share/_ignore create mode 100644 src/staticwordpress/share/icons/project_close.svg create mode 100644 src/staticwordpress/share/icons/project_settings.svg create mode 100644 src/staticwordpress/share/icons/visibility.svg create mode 100644 src/staticwordpress/share/icons/visibility_lock.svg diff --git a/src/staticwordpress/core/project.py b/src/staticwordpress/core/project.py index 01448ca..0bbcf99 100644 --- a/src/staticwordpress/core/project.py +++ b/src/staticwordpress/core/project.py @@ -86,7 +86,7 @@ def __init__(self, path_: str = None) -> None: self["wordpress"] = {"user": "", "api-token": ""} self["github"] = {"token": "", "repository": ""} - self["redirects"] = REDIRECTS.REDIRECTION + self["redirects"] = REDIRECTS.NONE self["sitemap"] = "sitemap_index.xml" self["search"] = "search" self["404"] = "404-error" diff --git a/src/staticwordpress/core/utils.py b/src/staticwordpress/core/utils.py index 24a624b..22f05fe 100644 --- a/src/staticwordpress/core/utils.py +++ b/src/staticwordpress/core/utils.py @@ -125,9 +125,9 @@ def rm_dir_tree(dir_path: str = None, delete_root: bool = False) -> None: return for _path in dir_path.glob("**/*"): - if _path.is_file(): + if _path.is_file() and _path.stem not in [".gitignore", ".project"]: _path.unlink() - elif _path.is_dir(): + elif _path.is_dir() and _path.stem != "._data": shutil.rmtree(_path, onerror=rmtree_permission_error) if delete_root: @@ -222,3 +222,12 @@ def extract_zip_file(zip_file_path: Path, output_location: Path) -> None: if output_location.is_dir() and zip_file_path.exists(): with ZipFile(zip_file_path, "r") as zf: zf.extractall(output_location) + + +def is_url_valid(url_: str) -> bool: + url_parsed_ = parse.urlparse(url_) + + if all([url_parsed_.scheme, url_parsed_.netloc]): + return get_remote_content(url_parsed_, max_retires=1).status_code < 399 + + return False diff --git a/src/staticwordpress/core/workflow.py b/src/staticwordpress/core/workflow.py index 9e3cde7..b145d66 100644 --- a/src/staticwordpress/core/workflow.py +++ b/src/staticwordpress/core/workflow.py @@ -97,10 +97,14 @@ def create_project( output_folder_: str = "", custom_404_: str = "", custom_search_: str = "", - src_type_: SOURCE = SOURCE.CRAWL, + src_type_: SOURCE = SOURCE.ZIP, host_type_: HOST = HOST.NETLIFY, ) -> None: self._project.status = PROJECT.NEW + + if src_type_ == SOURCE.ZIP: + self._project.redirects = REDIRECTS.REDIRECTION + self._project.name = project_name_ self._project.path = project_path_ self._project._404 = custom_404_ diff --git a/src/staticwordpress/gui/config.py b/src/staticwordpress/gui/config.py index 2d84732..8968053 100644 --- a/src/staticwordpress/gui/config.py +++ b/src/staticwordpress/gui/config.py @@ -102,9 +102,9 @@ def paintEvent(self, event: QPaintEvent) -> None: return -class ConfigWidget(QDialog): +class ConfigDialog(QDialog): def __init__(self): - super(ConfigWidget, self).__init__() + super(ConfigDialog, self).__init__() self.appConfigurations = QSettings( CONFIGS["APPLICATION_NAME"], CONFIGS["APPLICATION_NAME"] ) diff --git a/src/staticwordpress/gui/mainwindow.py b/src/staticwordpress/gui/mainwindow.py index ddac545..0534c34 100644 --- a/src/staticwordpress/gui/mainwindow.py +++ b/src/staticwordpress/gui/mainwindow.py @@ -30,6 +30,7 @@ import sys import logging import os +import shutil from pathlib import Path from datetime import date @@ -39,21 +40,12 @@ # +++++++++++++++++++++++++++++++++++++++++++++++++++++ from PyQt5.QtWidgets import ( - QLabel, QLineEdit, QMainWindow, - QTextEdit, - QVBoxLayout, - QHBoxLayout, - QToolButton, QAction, QApplication, - QDockWidget, - QWidget, QFileDialog, QMessageBox, - QComboBox, - QFormLayout, QProgressBar, QMenu, QToolBar, @@ -69,13 +61,8 @@ from ..core.constants import ( VERISON, CONFIGS, - ENUMS_MAP, SHARE_FOLDER_PATH, - HOST, - REDIRECTS, - PROJECT, SOURCE, - USER_AGENT, ) from ..core.project import Project from ..core.utils import ( @@ -85,9 +72,10 @@ ) from .workflow import WorkflowGUI from ..gui.logger import LoggerWidget -from ..gui.rawtext import RawTextWidget -from ..gui.config import ConfigWidget -from ..gui.utils import logging_decorator, GUI_SETTINGS +from ..gui.rawtext import RawTextDialog +from ..gui.config import ConfigDialog +from ..gui.project import ProjectDialog +from ..gui.utils import GUI_SETTINGS, logging_decorator # +++++++++++++++++++++++++++++++++++++++++++++++++++++ # IMPLEMENATIONS @@ -100,223 +88,19 @@ def __init__(self): self.appConfigurations = QSettings( CONFIGS["APPLICATION_NAME"], CONFIGS["APPLICATION_NAME"] ) - self.appConfigurations.setValue("icon_path", SHARE_FOLDER_PATH) self._project = Project() self._bg_thread = QThread(parent=self) self._bg_worker = WorkflowGUI() - self.docked_widget_project_properties = QDockWidget("Project Properties", self) - self.docked_widget_project_properties.setMinimumSize(QSize(400, 100)) - - widget_project_properties = QWidget() - form_layout_project_properties = QFormLayout() - - self.lineedit_project_name = QLineEdit() - self.lineedit_project_name.setObjectName("name") - self.lineedit_project_name.textChanged.connect(self.update_windows_title) - form_layout_project_properties.addRow( - QLabel("Project Name:"), self.lineedit_project_name - ) - - horizontal_Layout_project_scource = QHBoxLayout() - self.combobox_source_type = QComboBox() - self.combobox_source_type.setObjectName("source") - self.combobox_source_type.currentTextChanged.connect(self.update_windows_title) - self.combobox_source_type.setMinimumWidth(120) - self.combobox_source_type.addItems([item.value for item in list(SOURCE)]) - horizontal_Layout_project_scource.addWidget(self.combobox_source_type) - horizontal_Layout_project_scource.addStretch() - self.combobox_user_agent = QComboBox() - self.combobox_user_agent.setObjectName("user-agent") - self.combobox_user_agent.setMinimumWidth(120) - self.combobox_user_agent.addItems([item.value for item in list(USER_AGENT)]) - self.combobox_user_agent.currentTextChanged.connect(self.update_windows_title) - horizontal_Layout_project_scource.addWidget(QLabel("User Agent")) - horizontal_Layout_project_scource.addWidget(self.combobox_user_agent) - form_layout_project_properties.addRow( - QLabel("Project Source"), horizontal_Layout_project_scource - ) - self.lineedit_src_url = QLineEdit() - self.lineedit_src_url.setObjectName("src-url") - self.lineedit_src_url.textChanged.connect(self.update_windows_title) - form_layout_project_properties.addRow( - QLabel("Source Url"), self.lineedit_src_url - ) - self.combobox_project_destination = QComboBox() - self.combobox_project_destination.setObjectName("host") - self.combobox_project_destination.currentTextChanged.connect( - self.update_windows_title - ) - - self.combobox_project_destination.addItems([item.value for item in list(HOST)]) - form_layout_project_properties.addRow( - QLabel("Destination Host"), self.combobox_project_destination - ) - - self.lineedit_dest_url = QLineEdit() - self.lineedit_dest_url.setObjectName("dst-url") - self.lineedit_dest_url.textChanged.connect(self.update_windows_title) - form_layout_project_properties.addRow( - QLabel("Destination Url"), self.lineedit_dest_url - ) - - horizontal_Layout_output_directory = QHBoxLayout() - self.lineedit_output = QLineEdit() - self.lineedit_output.setObjectName("output") - self.lineedit_output.textChanged.connect(self.update_windows_title) - self.toolbutton_output_directory = QToolButton() - self.toolbutton_output_directory.setIcon( - QIcon(f"{SHARE_FOLDER_PATH}/icons/three-dots.svg") - ) - horizontal_Layout_output_directory.addWidget(self.lineedit_output) - horizontal_Layout_output_directory.addWidget(self.toolbutton_output_directory) - self.toolbutton_output_directory.clicked.connect(self.get_output_directory) - form_layout_project_properties.addRow( - QLabel("Output Directory"), horizontal_Layout_output_directory - ) - - vertical_layout_additional_properties = QVBoxLayout() - vertical_layout_additional_properties.addLayout(form_layout_project_properties) - widget_project_properties.setLayout(vertical_layout_additional_properties) - self.docked_widget_project_properties.setWidget(widget_project_properties) - self.docked_widget_project_properties.setFeatures( - QDockWidget.NoDockWidgetFeatures - ) - - self.docked_widget_project_properties.setMaximumHeight(200) - self.addDockWidget(Qt.LeftDockWidgetArea, self.docked_widget_project_properties) - - # ============================= - # Github Properties dock - # ============================= - self.docked_widget_github_properties = QDockWidget("Github Setttings", self) - self.docked_widget_github_properties.setMaximumHeight(100) - - widget_github_properties = QWidget() - form_layout_github_properties = QFormLayout() - - self.lineedit_gh_repo = QLineEdit() - self.lineedit_gh_repo.setObjectName("github-repository") - self.lineedit_gh_repo.textChanged.connect(self.update_windows_title) - form_layout_github_properties.addRow( - QLabel("Repository Name"), self.lineedit_gh_repo - ) - self.lineedit_gh_token = QLineEdit() - self.lineedit_gh_token.setObjectName("github-token") - self.lineedit_gh_token.textChanged.connect(self.update_windows_title) - form_layout_github_properties.addRow( - QLabel("GitHub Token"), self.lineedit_gh_token - ) - - vertical_layout_github_properties = QVBoxLayout() - vertical_layout_github_properties.addLayout(form_layout_github_properties) - widget_github_properties.setLayout(vertical_layout_github_properties) - self.docked_widget_github_properties.setWidget(widget_github_properties) - self.docked_widget_github_properties.setFeatures( - QDockWidget.NoDockWidgetFeatures - ) - self.addDockWidget(Qt.LeftDockWidgetArea, self.docked_widget_github_properties) - - # ============================= - # Crawl Properties dock - # ============================= - self.docked_widget_crawl_properties = QDockWidget("Crawl Settings", self) - self.docked_widget_crawl_properties.setMinimumSize(QSize(400, 100)) - - widget_crawl_properties = QWidget() - form_layout_crawl_properties = QFormLayout() - - horizontal_Layout_wordpress = QHBoxLayout() - self.lineedit_wp_user = QLineEdit() - self.lineedit_wp_user.setMaximumWidth(80) - self.lineedit_wp_user.setObjectName("wordpress-user") - self.lineedit_wp_user.textChanged.connect(self.update_windows_title) - horizontal_Layout_wordpress.addWidget(self.lineedit_wp_user) - self.lineedit_wp_api_token = QLineEdit() - self.lineedit_wp_api_token.setObjectName("wordpress-api-token") - self.lineedit_wp_api_token.textChanged.connect(self.update_windows_title) - horizontal_Layout_wordpress.addWidget(QLabel("API Token")) - horizontal_Layout_wordpress.addWidget(self.lineedit_wp_api_token) - form_layout_crawl_properties.addRow( - QLabel("WordPress User"), horizontal_Layout_wordpress - ) - - horizontal_Layout_redirects = QHBoxLayout() - self.combobox_redirects = QComboBox() - self.combobox_redirects.setObjectName("redirects") - self.combobox_redirects.currentTextChanged.connect(self.update_windows_title) - self.combobox_redirects.addItems([item.value for item in list(REDIRECTS)]) - horizontal_Layout_redirects.addWidget(self.combobox_redirects) - form_layout_crawl_properties.addRow( - QLabel("Redirects Source"), horizontal_Layout_redirects - ) - - horizontal_Layout_sitemap = QHBoxLayout() - self.lineedit_sitemap = QLineEdit() - self.lineedit_sitemap.setObjectName("sitemap") - self.lineedit_sitemap.textChanged.connect(self.update_windows_title) - self.toolbutton_output_sitemap = QToolButton() - self.toolbutton_output_sitemap.setIcon( - QIcon(f"{SHARE_FOLDER_PATH}/icons/search.svg") - ) - horizontal_Layout_sitemap.addWidget(self.lineedit_sitemap) - horizontal_Layout_sitemap.addWidget(self.toolbutton_output_sitemap) - self.toolbutton_output_sitemap.clicked.connect(self.get_sitemap_location) - form_layout_crawl_properties.addRow( - QLabel("Sitemap Location"), horizontal_Layout_sitemap - ) - - horizontal_Layout_search_404 = QHBoxLayout() - self.lineedit_search = QLineEdit() - self.lineedit_search.setObjectName("search") - self.lineedit_search.textChanged.connect(self.update_windows_title) - horizontal_Layout_search_404.addWidget(self.lineedit_search) - horizontal_Layout_search_404.addWidget(QLabel("404 Page")) - self.lineedit_404_page = QLineEdit() - self.lineedit_404_page.setObjectName("404-error") - self.lineedit_404_page.textChanged.connect(self.update_windows_title) - horizontal_Layout_search_404.addWidget(self.lineedit_404_page) - form_layout_crawl_properties.addRow( - QLabel("Search Page"), horizontal_Layout_search_404 - ) - - self.lineedit_delay = QLineEdit() - self.lineedit_delay.setObjectName("delay") - self.lineedit_delay.textChanged.connect(self.update_windows_title) - form_layout_crawl_properties.addRow( - QLabel("Delay (Seconds)"), self.lineedit_delay - ) - - form_layout_crawl_properties.addRow(QLabel("Additional Files")) - self.textedit_additional = QTextEdit() - self.textedit_additional.setObjectName("additional") - self.textedit_additional.textChanged.connect(self.update_windows_title) - form_layout_crawl_properties.addRow(self.textedit_additional) - - form_layout_crawl_properties.addRow(QLabel("Exclude Patterns")) - self.textedit_exclude = QTextEdit() - self.textedit_exclude.setObjectName("exclude") - self.textedit_exclude.textChanged.connect(self.update_windows_title) - form_layout_crawl_properties.addRow(self.textedit_exclude) - - vertical_layout_wp_properties = QVBoxLayout() - vertical_layout_wp_properties.addLayout(form_layout_crawl_properties) - widget_crawl_properties.setLayout(vertical_layout_wp_properties) - self.docked_widget_crawl_properties.setWidget(widget_crawl_properties) - self.docked_widget_crawl_properties.setFeatures( - QDockWidget.NoDockWidgetFeatures - ) - self.addDockWidget(Qt.LeftDockWidgetArea, self.docked_widget_crawl_properties) - self.text_edit_logging = LoggerWidget(self) self.text_edit_logging.setFormatter( logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") ) logging.getLogger().addHandler(self.text_edit_logging) logging.getLogger().setLevel(logging.INFO) - self.setCentralWidget(self.text_edit_logging.plainTextEdit) + self.setCentralWidget(self.text_edit_logging.plainTextEdit) self.statusBar().showMessage(f"{CONFIGS['APPLICATION_NAME']} is Ready") self.progressBar = QProgressBar() self.progressBar.setAlignment(Qt.AlignCenter) @@ -415,19 +199,6 @@ def inner(self): return inner - @is_new_project - @logging_decorator - def get_output_directory(self): - """""" - output_directory = QFileDialog.getExistingDirectory( - self, - "Select Output Directory", - self.appConfigurations.value("output-directory"), - ) - if output_directory: - self.lineedit_output.setText(output_directory) - self.appConfigurations.setValue("output-directory", output_directory) - @is_project_open @logging_decorator def clean_output_directory(self): @@ -463,27 +234,23 @@ def get_sitemap_location(self): def update_sitemap_location(self, sitemap_location): self._project.sitemap = sitemap_location logging.info(f"Found Sitemap location: {sitemap_location}") - self.update_properties_widgets() + self.update_widgets() @is_new_project @logging_decorator def extract_url_from_raw_text(self): - rtp = RawTextWidget( + rtp = RawTextDialog( src_url=self._project.src_url, dest_url=self._project.dst_url ) if rtp.exec_(): raw_text = rtp.textedit_raw_text_with_links.toPlainText() - current_additional_urls = self.textedit_additional.toPlainText().split("\n") - if raw_text: new_additional_links = extract_urls_from_raw_text( raw_text, rtp.lineedit_dest_url.text(), rtp.linedit_src_url.text() ) logging.info(f" {len(new_additional_links)} Additional Urls Found") - current_additional_urls += new_additional_links - self.textedit_additional.setText( - "\n".join(set(current_additional_urls)) - ) + self._project.additional += new_additional_links + self._project.save() @is_new_project @logging_decorator @@ -547,7 +314,7 @@ def help(self): @logging_decorator def show_configs(self): """Interface with System Configurations""" - w = ConfigWidget() + w = ConfigDialog() if w.exec_(): logging.info("Saved/Updated Default Configurations") @@ -567,39 +334,63 @@ def about(self): msgBox.exec() @logging_decorator - def create_project(self): + def new_project(self): """Closing current project will automatically start a new project.""" self.close_project() - self._project.create() - self.update_properties_widgets() + + pdialog = ProjectDialog(self._project, title_="New Project") + if pdialog.exec_(): + self._project = pdialog._project + self.appConfigurations.setValue("last-project", self._project.output) + + if Path(self._project.output).is_dir(): + self._project.path.parent.mkdir(parents=True, exist_ok=True) + src = Path(f"{SHARE_FOLDER_PATH}/_ignore") + dst = Path(f"{self._project.output}/.gitignore") + if src.exists(): + shutil.copyfile(src, dst) + else: + return + + self.update_widgets() + logging.info("Saved/Update Project") + self._project.save() @logging_decorator def open_project(self): """Opening static-wordpress Project File""" self.close_project() if not self._project.is_open(): - options = QFileDialog.Options() - project_path, _ = QFileDialog.getOpenFileName( + project_folder = QFileDialog.getExistingDirectory( self, - "Select Static-WordPress Project File", - self.appConfigurations.value("last-project"), - "JSON Files (*.json)", - options=options, + "Select Static-WordPress Project Directory", + str(self.appConfigurations.value("last-project")), + QFileDialog.ShowDirsOnly, ) - if project_path: - self._project.open(Path(project_path)) + project_path = Path(f"{project_folder}/._data/.project.json") + if project_path.exists(): + self._project.open(project_path) if self._project.is_open(): + pdialog = ProjectDialog(self._project, title_="Project Properties") + + if pdialog.exec_(): + self._project = pdialog._project + if not self._project.is_older_version(): logging.warning( f"Your Project was saved with an older version : {self._project.version}." ) + logging.info(f"Open Project {self._project.path} Successfully") - self.appConfigurations.setValue("last-project", project_path) + self.appConfigurations.setValue("last-project", project_folder) else: msgBox = QMessageBox() - msgBox.setText(f"Project cannot be opened." f"Please try again.") + msgBox.setText( + f"Project cannot be opened or selected path invalid." + f"
Please try again with project folder." + ) msgBox.setWindowIcon( QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg") ) @@ -612,8 +403,19 @@ def open_project(self): "No New Project Opened. Unsaved project properties will be lost." ) - self.update_windows_title() - self.update_properties_widgets() + self.update_widgets() + self._project.save() + + @logging_decorator + def show_project(self): + """showing static-wordpress Project File""" + if self._project.is_open(): + pdialog = ProjectDialog(self._project, title_="Current Project") + if pdialog.exec_(): + self._project = pdialog._project + + self._project.save() + self.update_widgets() @is_project_open @logging_decorator @@ -629,88 +431,7 @@ def close_project(self): ) if reply == QMessageBox.Yes: self._project = Project() - self.update_properties_widgets() - verifications = { - "name": None, - "src-url": None, - "wordpress-user": None, - "wordpress-api-token": None, - "sitemap": None, - "github-token": None, - "github-repository": None, - } - self.update_expert_mode_widgets(verifications) - - @is_project_open - @logging_decorator - def save_project(self): - """Saving Current static-wordpress Project""" - if self.lineedit_project_name.text(): - new_project_path = self.appConfigurations.value("last-project") - if self._project.is_new(): - options = QFileDialog.Options() - new_project_path, _ = QFileDialog.getSaveFileName( - self, - "Select StaticWordPress Project File", - self.appConfigurations.value("last-project"), - "JSON Files (*.json)", - options=options, - ) - if new_project_path: - self._project.path = Path(new_project_path) - else: - return - - self.appConfigurations.setValue("last-project", new_project_path) - self._project.name = self.lineedit_project_name.text() - self._project.path = Path(new_project_path) - self._project.src_url = self.lineedit_src_url.text() - self._project.sitemap = self.lineedit_sitemap.text() - self._project.wp_user = self.lineedit_wp_user.text() - self._project.wp_api_token = self.lineedit_wp_api_token.text() - self._project.search = self.lineedit_search.text() - self._project._404 = self.lineedit_404_page.text() - self._project.delay = float(self.lineedit_delay.text()) - self._project.redirects = REDIRECTS[self.combobox_redirects.currentText()] - self._project.src_type = SOURCE[self.combobox_source_type.currentText()] - self._project.user_agent = USER_AGENT[ - self.combobox_user_agent.currentText() - ] - self._project.host = HOST[self.combobox_project_destination.currentText()] - self._project.output = Path(self.lineedit_output.text()) - self._project.dst_url = self.lineedit_dest_url.text() - self._project.gh_token = self.lineedit_gh_token.text() - self._project.gh_repo = self.lineedit_gh_repo.text() - self._project.additional = self.textedit_additional.toPlainText().split( - "\n" - ) - self._project.exclude = self.textedit_exclude.toPlainText().split("\n") - if not self._project.is_older_version(): - logging.warning( - f"Your Project will be saved with new version number : {VERISON}." - ) - self._project.version = VERISON - - # save project - self._project.save() - if self._project.is_saved(): - logging.info(f"Project Saved Successfully at {self._project.path}") - self.update_properties_widgets() - self.update_windows_title() - - def check_project(self) -> None: - if self._bg_thread.isRunning(): - self._bg_thread.quit() - - self._bg_thread = QThread(parent=self) - self._bg_worker = WorkflowGUI() - self._bg_worker.set_project(project_=self._project) - self._bg_worker.moveToThread(self._bg_thread) - self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalVerification.connect(self.update_expert_mode_widgets) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) - self._bg_thread.started.connect(self._bg_worker.verify_project) - self._bg_thread.start() + self.update_widgets() @is_project_open def start_batch_process(self): @@ -748,7 +469,7 @@ def start_batch_process(self): self._bg_thread = QThread(parent=self) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.batch_processing) self._bg_thread.start() @@ -764,7 +485,7 @@ def stop_process(self) -> None: if reply == QMessageBox.Yes: self._bg_worker.stop_calcualations() - self.update_statusbar_widgets("Stoping Processing", 100) + self.update_statusbar("Stoping Processing", 100) @is_project_open def crawl_website(self) -> None: @@ -776,7 +497,7 @@ def crawl_website(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.pre_processing) self._bg_thread.start() @@ -790,7 +511,7 @@ def crawl_additional_files(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.crawl_additional_files) self._bg_thread.start() @@ -804,7 +525,7 @@ def create_search_index(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.add_search) self._bg_thread.start() @@ -818,7 +539,7 @@ def create_404_page(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.add_404_page) self._bg_thread.start() @@ -832,7 +553,7 @@ def create_redirects(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.add_redirects) self._bg_thread.start() @@ -846,7 +567,7 @@ def create_robots_txt(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.add_robots_txt) self._bg_thread.start() @@ -861,7 +582,7 @@ def create_github_repositoy(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.create_github_repositoy) self._bg_thread.start() @@ -884,7 +605,7 @@ def delete_github_repository(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.delete_github_repositoy) self._bg_thread.start() @@ -899,7 +620,7 @@ def initialize_repository(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.init_git_repositoy) self._bg_thread.start() @@ -914,7 +635,7 @@ def commit_repository(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.commit_git_repositoy) self._bg_thread.start() @@ -929,11 +650,11 @@ def publish_repository(self) -> None: self._bg_worker.set_project(project_=self._project) self._bg_worker.moveToThread(self._bg_thread) self._bg_thread.finished.connect(self._bg_worker.deleteLater) - self._bg_worker.signalProgress.connect(self.update_statusbar_widgets) + self._bg_worker.signalProgress.connect(self.update_statusbar) self._bg_thread.started.connect(self._bg_worker.publish_github_repositoy) self._bg_thread.start() - def update_statusbar_widgets(self, message_, percent_) -> None: + def update_statusbar(self, message_, percent_) -> None: if percent_ >= 0: self.progressBar.setValue(percent_) self.statusBar().showMessage(message_) @@ -943,26 +664,7 @@ def update_statusbar_widgets(self, message_, percent_) -> None: if percent_ >= 100: self.progressBar.setFormat(message_) - def update_properties_widgets(self) -> None: - self.lineedit_project_name.setText(self._project.name) - self.lineedit_src_url.setText(self._project.src_url) - self.lineedit_sitemap.setText(self._project.sitemap) - self.lineedit_search.setText(self._project.search) - self.lineedit_404_page.setText(self._project._404) - self.lineedit_delay.setText(f"{self._project.delay}") - self.combobox_source_type.setCurrentText(self._project.src_type.value) - self.combobox_user_agent.setCurrentText(self._project.user_agent.value) - self.lineedit_output.setText(str(self._project.output)) - self.lineedit_dest_url.setText(self._project.dst_url) - self.lineedit_wp_user.setText(self._project.wp_user) - self.lineedit_wp_api_token.setText(self._project.wp_api_token) - self.lineedit_gh_token.setText(self._project.gh_token) - self.lineedit_gh_repo.setText(self._project.gh_repo) - self.textedit_additional.setText("\n".join(self._project.additional)) - self.textedit_exclude.setText("\n".join(self._project.exclude)) - self.combobox_redirects.setCurrentText(self._project.redirects.value) - self.combobox_redirects.setEnabled(True) - + def update_widgets(self) -> None: self.findChild(QMenu, "menu_github").setEnabled(self._project.has_github()) self.findChild(QMenu, "menu_wordpress").setEnabled( self._project.has_wordpress() @@ -990,71 +692,9 @@ def update_properties_widgets(self) -> None: self.findChild(QAction, "action_edit_expert_mode").isChecked() ) - def update_expert_mode_widgets(self, verifications) -> None: - for key, value in verifications.items(): - if value is not None: - bg_color = ( - CONFIGS["COLOR"]["SUCCESS"] if value else CONFIGS["COLOR"]["ERROR"] - ) - else: - bg_color = value - - self.findChild(QLineEdit, key).setStyleSheet( - f"background-color: {bg_color}" - ) - - def update_windows_title(self) -> None: - sender = self.sender() - if ( - type(sender) in [QLineEdit, QComboBox, QTextEdit] - and self._project.is_open() - ): - gui_value = sender.property("text") - - if type(sender) == QLineEdit: - gui_value = sender.property("text") - if sender.objectName() == "output": - gui_value = Path(sender.property("text")) - elif sender.objectName() == "delay": - try: - gui_value = float(sender.property("text")) - except: # mostly value error e.g. 0.^ as input - pass - - elif type(sender) == QComboBox: - gui_value = ENUMS_MAP[sender.objectName()][ - sender.property("currentText") - ] - elif type(sender) == QTextEdit: - gui_value = [url for url in sender.toPlainText().split("\n") if url] - - project_value = self._project.get(sender.objectName()) - project_functions_dict = { - "github-repository": self._project.gh_repo, - "github-token": self._project.gh_token, - "wordpress-user": self._project.wp_user, - "wordpress-api-token": self._project.wp_api_token, - "src-url": self._project.src_url, - "source": self._project.src_type, - "output": self._project.output, - "dst-url": self._project.dst_url, - "404-error": self._project._404, - } - - if sender.objectName() in project_functions_dict: - project_value = project_functions_dict[sender.objectName()] - - if gui_value != project_value and not self._project.is_new(): - self._project.status = PROJECT.UPDATE - - status_string = ( - f"{'' if self._project.is_saved() else '*'} {self._project.name}" - ) new_window_title = ( - f"{status_string} - {CONFIGS['APPLICATION_NAME']} Version - {VERISON}" + f"{self._project.name} - {CONFIGS['APPLICATION_NAME']} Version - {VERISON}" ) - if self._project.status == PROJECT.NOT_FOUND: - new_window_title = f"{CONFIGS['APPLICATION_NAME']} Version - {VERISON}" self.setWindowTitle(new_window_title) diff --git a/src/staticwordpress/gui/project.py b/src/staticwordpress/gui/project.py new file mode 100644 index 0000000..c206c6e --- /dev/null +++ b/src/staticwordpress/gui/project.py @@ -0,0 +1,459 @@ +# -*- coding: utf-8 -*- + +""" +STATIC WORDPRESS: WordPress as Static Site Generator +A Python Package for Converting WordPress Installation to a Static Website +https://github.com/serpwings/staticwordpress + + src\staticwordpress\gui\project.py + + Copyright (C) 2020-2023 Faisal Shahzad + + +The contents of this file are subject to version 3 of the +GNU General Public License (GPL-3.0). You may not use this file except in +compliance with the License. You may obtain a copy of the License at +https://www.gnu.org/licenses/gpl-3.0.txt +https://github.com/serpwings/staticwordpress/blob/master/LICENSE + + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the +specific language governing rights and limitations under the License. + +""" +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ +# STANDARD LIBARY IMPORTS +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +import logging +from pathlib import Path + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ +# 3rd PARTY LIBRARY IMPORTS +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +from PyQt5.QtWidgets import ( + QTabWidget, + QWidget, + QDialog, + QVBoxLayout, + QHBoxLayout, + QFormLayout, + QLineEdit, + QComboBox, + QTextEdit, + QLabel, + QGroupBox, + QToolButton, + QButtonGroup, + QRadioButton, + QDoubleSpinBox, + QMessageBox, + QFileDialog, + QPushButton, + QAction, +) +from PyQt5.QtCore import QSettings, QSize, QThread +from PyQt5.QtGui import QIcon + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ +# INTERNAL IMPORTS +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +from ..core.constants import ( + REDIRECTS, + USER_AGENT, + CONFIGS, + SHARE_FOLDER_PATH, + SOURCE, + HOST, +) + +from ..core.utils import is_url_valid + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ +# IMPLEMENATIONS +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +class ProjectDialog(QDialog): + def __init__(self, project_, title_="Project Settings"): + super(ProjectDialog, self).__init__() + self.appConfigurations = QSettings( + CONFIGS["APPLICATION_NAME"], CONFIGS["APPLICATION_NAME"] + ) + + self._project = project_ + vertical_layout_project = QVBoxLayout() + groupbox_general_settings = QGroupBox("General Settings") + form_layout_general_settings = QFormLayout() + + self.lineedit_project_name = QLineEdit(self._project.name) + self.lineedit_project_name.setObjectName("name") + form_layout_general_settings.addRow( + QLabel("Project Name"), self.lineedit_project_name + ) + + self.lineedit_src_url = QLineEdit(self._project.src_url) + self.lineedit_src_url.setObjectName("src-url") + form_layout_general_settings.addRow(QLabel("Source Url"), self.lineedit_src_url) + + horizontal_Layout_output_directory = QHBoxLayout() + self.lineedit_output = QLineEdit(str(self._project.output)) + self.lineedit_output.setObjectName("output") + self.toolbutton_output_directory = QToolButton() + self.toolbutton_output_directory.setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/three-dots.svg") + ) + self.toolbutton_output_directory.clicked.connect(self.get_output_directory) + horizontal_Layout_output_directory.addWidget(self.lineedit_output) + horizontal_Layout_output_directory.addWidget(self.toolbutton_output_directory) + form_layout_general_settings.addRow( + QLabel("Output Directory"), horizontal_Layout_output_directory + ) + + horizontal_layout_crawl_delay_user_agent = QHBoxLayout() + self.double_spinbox_delay = QDoubleSpinBox() + self.double_spinbox_delay.setMinimumWidth(120) + self.double_spinbox_delay.setMinimum(0) + self.double_spinbox_delay.setSingleStep(0.05) + self.double_spinbox_delay.setMaximum(2) + self.double_spinbox_delay.setMinimumWidth(120) + self.double_spinbox_delay.setValue(self._project.delay) + self.double_spinbox_delay.setObjectName("delay") + horizontal_layout_crawl_delay_user_agent.addWidget(self.double_spinbox_delay) + + self.combobox_user_agent = QComboBox() + self.combobox_user_agent.setObjectName("user-agent") + self.combobox_user_agent.setMinimumWidth(120) + self.combobox_user_agent.addItems([item.value for item in list(USER_AGENT)]) + self.combobox_user_agent.setCurrentText(self._project.user_agent.value) + horizontal_layout_crawl_delay_user_agent.addWidget(QLabel("User Agent")) + horizontal_layout_crawl_delay_user_agent.addWidget(self.combobox_user_agent) + + form_layout_general_settings.addRow( + QLabel("Crawl Delay(sec)"), horizontal_layout_crawl_delay_user_agent + ) + + horitzontal_layout_project_type = QHBoxLayout() + button_group_project_type = QButtonGroup() + + self.radiobutton_seo = QRadioButton("SEO", self) + self.radiobutton_seo.setObjectName("radio-seo") + self.radiobutton_seo.setEnabled(False) + self.radiobutton_seo.toggled.connect(self.update_widgets) + + self.radiobutton_static_website = QRadioButton("Static Website", self) + self.radiobutton_static_website.setObjectName("radio-static-website") + self.radiobutton_static_website.setChecked(True) + self.radiobutton_static_website.toggled.connect(self.update_widgets) + + button_group_project_type.addButton(self.radiobutton_seo) + button_group_project_type.addButton(self.radiobutton_static_website) + + horitzontal_layout_project_type.addWidget(self.radiobutton_seo) + horitzontal_layout_project_type.addWidget(self.radiobutton_static_website) + horitzontal_layout_project_type.addStretch() + form_layout_general_settings.addRow( + QLabel("Project Type"), horitzontal_layout_project_type + ) + + groupbox_general_settings.setLayout(form_layout_general_settings) + + widget_static_website_tab = QWidget() + form_layout_static_website_properties = QFormLayout() + + horizontal_Layout_project_scource = QHBoxLayout() + self.combobox_source_type = QComboBox() + self.combobox_source_type.setObjectName("source") + self.combobox_source_type.setMinimumWidth(120) + self.combobox_source_type.addItems([item.value for item in list(SOURCE)]) + self.combobox_source_type.setCurrentText(self._project.src_type.value) + horizontal_Layout_project_scource.addWidget(self.combobox_source_type) + horizontal_Layout_project_scource.addStretch() + + form_layout_static_website_properties.addRow( + QLabel("Data Source"), horizontal_Layout_project_scource + ) + + horizontal_Layout_project_redirects = QHBoxLayout() + self.combobox_redirects = QComboBox() + self.combobox_redirects.setObjectName("redirects") + self.combobox_redirects.setMinimumWidth(120) + self.combobox_redirects.addItems([item.value for item in list(REDIRECTS)]) + self.combobox_redirects.setCurrentText(self._project.redirects.value) + + horizontal_Layout_project_redirects.addWidget(self.combobox_redirects) + horizontal_Layout_project_redirects.addStretch() + form_layout_static_website_properties.addRow( + QLabel("Redirects Source"), horizontal_Layout_project_redirects + ) + + horizontal_Layout_project_destination = QHBoxLayout() + self.combobox_project_destination = QComboBox() + self.combobox_project_destination.setObjectName("host") + self.combobox_project_destination.setMinimumWidth(120) + self.combobox_project_destination.addItems([item.value for item in list(HOST)]) + self.combobox_project_destination.setCurrentText(self._project.host.value) + + horizontal_Layout_project_destination.addWidget( + self.combobox_project_destination + ) + horizontal_Layout_project_destination.addStretch() + form_layout_static_website_properties.addRow( + QLabel("Destination Host"), horizontal_Layout_project_destination + ) + + self.lineedit_dest_url = QLineEdit(self._project.dst_url) + self.lineedit_dest_url.setObjectName("dst-url") + form_layout_static_website_properties.addRow( + QLabel("Destination Url"), self.lineedit_dest_url + ) + + self.lineedit_search = QLineEdit(self._project.search) + self.lineedit_search.setObjectName("search") + form_layout_static_website_properties.addRow( + QLabel("Search Page"), self.lineedit_search + ) + + self.lineedit_404_page = QLineEdit(self._project._404) + self.lineedit_404_page.setObjectName("404-error") + form_layout_static_website_properties.addRow( + QLabel("404 Page"), self.lineedit_404_page + ) + widget_static_website_tab.setLayout(form_layout_static_website_properties) + + horizontal_Layout_sitemap = QHBoxLayout() + self.lineedit_sitemap = QLineEdit(self._project.sitemap) + self.lineedit_sitemap.setObjectName("sitemap") + self.toolbutton_output_sitemap = QToolButton() + self.toolbutton_output_sitemap.setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/search.svg") + ) + horizontal_Layout_sitemap.addWidget(self.lineedit_sitemap) + horizontal_Layout_sitemap.addWidget(self.toolbutton_output_sitemap) + form_layout_static_website_properties.addRow( + QLabel("Sitemap Location"), horizontal_Layout_sitemap + ) + + self.textedit_additional_urls = QTextEdit() + self.textedit_additional_urls.setText("\n".join(self._project.additional)) + self.textedit_additional_urls.setObjectName("additional") + self.textedit_exclude_patterns = QTextEdit() + self.textedit_exclude_patterns.setText("\n".join(self._project.exclude)) + self.textedit_exclude_patterns.setObjectName("exclude") + + widget_project_api_tab = QWidget() + vertical_layout_project_api = QVBoxLayout() + + groupbox_wp_api = QGroupBox("WordPress") + form_layout_wp_api = QFormLayout() + self.lineedit_wp_user = QLineEdit(self._project.wp_user) + self.lineedit_wp_user.setObjectName("wordpress-user") + form_layout_wp_api.addRow(QLabel("User Name"), self.lineedit_wp_user) + + self.lineedit_wp_api_token = QLineEdit(self._project.wp_api_token) + self.lineedit_wp_api_token.setEchoMode(QLineEdit.Password) + self.lineedit_wp_api_token.setObjectName("wordpress-api-token") + + toolbutton_show_wp_api_token = QToolButton() + toolbutton_show_wp_api_token.setObjectName("toolbutton_show_wp_api_token") + toolbutton_show_wp_api_token.setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/visibility.svg") + ) + toolbutton_show_wp_api_token.setCheckable(True) + toolbutton_show_wp_api_token.clicked.connect(self.change_password_visiblity) + + horizontal_layout_wp_api_token = QHBoxLayout() + horizontal_layout_wp_api_token.addWidget(self.lineedit_wp_api_token) + horizontal_layout_wp_api_token.addWidget(toolbutton_show_wp_api_token) + + form_layout_wp_api.addRow(QLabel("API Token"), horizontal_layout_wp_api_token) + groupbox_wp_api.setLayout(form_layout_wp_api) + + groupbox_gh_api = QGroupBox("GitHub") + form_layout_gh_api = QFormLayout() + + self.lineedit_gh_repo = QLineEdit(self._project.gh_repo) + self.lineedit_gh_repo.setObjectName("github-repository") + form_layout_gh_api.addRow(QLabel("Repository"), self.lineedit_gh_repo) + + self.lineedit_gh_token = QLineEdit(self._project.gh_token) + self.lineedit_gh_token.setEchoMode(QLineEdit.Password) + self.lineedit_gh_token.setObjectName("github-token") + horizontal_layout_gh_token = QHBoxLayout() + horizontal_layout_gh_token.addWidget(self.lineedit_gh_token) + + toolbutton_show_gh_token = QToolButton() + toolbutton_show_gh_token.setObjectName("toolbutton_show_gh_token") + toolbutton_show_gh_token.setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/visibility.svg") + ) + toolbutton_show_gh_token.setCheckable(True) + toolbutton_show_gh_token.clicked.connect(self.change_password_visiblity) + horizontal_layout_gh_token.addWidget(toolbutton_show_gh_token) + form_layout_gh_api.addRow(QLabel("API Token"), horizontal_layout_gh_token) + + groupbox_gh_api.setLayout(form_layout_gh_api) + vertical_layout_project_api.addWidget(groupbox_wp_api) + vertical_layout_project_api.addWidget(groupbox_gh_api) + + widget_project_api_tab.setLayout(vertical_layout_project_api) + + self.tabwidget_dialog = QTabWidget() + self.tabwidget_dialog.addTab(widget_static_website_tab, "Static &Website") + self.tabwidget_dialog.addTab(widget_project_api_tab, "&API") + self.tabwidget_dialog.addTab(self.textedit_additional_urls, "Additional &Files") + self.tabwidget_dialog.addTab( + self.textedit_exclude_patterns, "Exclude &Patterns" + ) + + vertical_layout_project.addWidget(groupbox_general_settings) + vertical_layout_project.addWidget(self.tabwidget_dialog) + vertical_layout_project.addStretch() + + self.pushbutton_verify = QPushButton("&Verify") + self.pushbutton_verify.setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/check_project.svg") + ) + self.pushbutton_verify.clicked.connect(self.check_project) + + self.pushbutton_save = QPushButton("&Save") + self.pushbutton_save.setIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg")) + self.pushbutton_save.setDefault(True) + self.pushbutton_save.clicked.connect(self.accept) + + self.pushbutton_cancel = QPushButton("&Cancel") + self.pushbutton_cancel.setIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg")) + self.pushbutton_cancel.clicked.connect(self.reject) + + horizontal_layout_buttons = QHBoxLayout() + horizontal_layout_buttons.addWidget(self.pushbutton_verify) + horizontal_layout_buttons.addStretch() + horizontal_layout_buttons.addWidget(self.pushbutton_save) + horizontal_layout_buttons.addWidget(self.pushbutton_cancel) + vertical_layout_project.addLayout(horizontal_layout_buttons) + + self.setLayout(vertical_layout_project) + self.setWindowTitle(title_) + self.setWindowIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg")) + + def change_password_visiblity(self): + if not self.sender().isChecked(): + self.sender().setIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/visibility.svg")) + self.sender().setChecked(False) + if self.sender().objectName() == "toolbutton_show_gh_token": + self.lineedit_gh_token.setEchoMode(QLineEdit.Password) + elif self.sender().objectName() == "toolbutton_show_wp_api_token": + self.lineedit_wp_api_token.setEchoMode(QLineEdit.Password) + + else: + self.sender().setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/visibility_lock.svg") + ) + self.sender().setChecked(True) + if self.sender().objectName() == "toolbutton_show_gh_token": + self.lineedit_gh_token.setEchoMode(QLineEdit.Normal) + elif self.sender().objectName() == "toolbutton_show_wp_api_token": + self.lineedit_wp_api_token.setEchoMode(QLineEdit.Normal) + + def update_widgets(self): + if self.sender().objectName() == "radio-static-website": + self.tabwidget_dialog.setVisible(True) + self.setFixedSize(QSize(448, 437)) + elif self.sender().objectName() == "radio-seo": + self.tabwidget_dialog.setVisible(False) + self.setFixedSize(QSize(448, 208)) + else: + pass + + def get_output_directory(self): + """""" + output_directory = QFileDialog.getExistingDirectory( + self, + "Select Output Directory", + str(self.appConfigurations.value("last-project")), + ) + if output_directory: + self.lineedit_output.setText(output_directory) + self.appConfigurations.setValue("last-project", output_directory) + + def check_project(self): + """""" + # TODO: Add checks for WP_API and Gh_API and if not present then disable them. + # TODO: Move these checks to background thread + if not (self.lineedit_wp_api_token.text() and self.lineedit_wp_user.text()): + self.combobox_redirects.setCurrentText(REDIRECTS.NONE.value) + + if self.lineedit_project_name.text(): + self.lineedit_project_name.setStyleSheet( + f"background-color: {CONFIGS['COLOR']['SUCCESS']}" + ) + else: + self.lineedit_project_name.setStyleSheet( + f"background-color: {CONFIGS['COLOR']['ERROR']}" + ) + + if is_url_valid(self.lineedit_src_url.text()): + self.lineedit_src_url.setStyleSheet( + f"background-color: {CONFIGS['COLOR']['SUCCESS']}" + ) + else: + self.lineedit_src_url.setStyleSheet( + f"background-color: {CONFIGS['COLOR']['ERROR']}" + ) + + if self.lineedit_output.text() and Path(self.lineedit_output.text()).is_dir(): + self.lineedit_output.setStyleSheet( + f"background-color: {CONFIGS['COLOR']['SUCCESS']}" + ) + else: + self.lineedit_output.setStyleSheet( + f"background-color: {CONFIGS['COLOR']['ERROR']}" + ) + + def accept(self) -> None: + """""" + if all( + [ + self.lineedit_project_name.text(), + self.lineedit_output.text(), + is_url_valid(self.lineedit_src_url.text()), + Path(self.lineedit_output.text()).is_dir(), + ] + ): + self._project.create() + self._project.output = Path(self.lineedit_output.text()) + self._project.path = Path(f"{self._project.output}/._data/.project.json") + self._project.name = self.lineedit_project_name.text() + self._project.src_url = self.lineedit_src_url.text() + self._project.sitemap = self.lineedit_sitemap.text() + self._project.wp_user = self.lineedit_wp_user.text() + self._project.wp_api_token = self.lineedit_wp_api_token.text() + self._project.search = self.lineedit_search.text() + self._project._404 = self.lineedit_404_page.text() + self._project.delay = self.double_spinbox_delay.value() + self._project.redirects = REDIRECTS[self.combobox_redirects.currentText()] + self._project.src_type = SOURCE[self.combobox_source_type.currentText()] + self._project.user_agent = USER_AGENT[ + self.combobox_user_agent.currentText() + ] + self._project.host = HOST[self.combobox_project_destination.currentText()] + self._project.dst_url = self.lineedit_dest_url.text() + self._project.gh_token = self.lineedit_gh_token.text() + self._project.gh_repo = self.lineedit_gh_repo.text() + self._project.additional = ( + self.textedit_additional_urls.toPlainText().split("\n") + ) + self._project.exclude = self.textedit_exclude_patterns.toPlainText().split( + "\n" + ) + return super().accept() + else: + QMessageBox.information( + self, + "Invalid Project Settings", + "Cannot create new project.
Please check project settings.", + QMessageBox.Yes, + ) diff --git a/src/staticwordpress/gui/rawtext.py b/src/staticwordpress/gui/rawtext.py index f30fe2a..98065dd 100644 --- a/src/staticwordpress/gui/rawtext.py +++ b/src/staticwordpress/gui/rawtext.py @@ -51,9 +51,9 @@ # +++++++++++++++++++++++++++++++++++++++++++++++++++++ -class RawTextWidget(QDialog): +class RawTextDialog(QDialog): def __init__(self, src_url: str, dest_url: str): - super(RawTextWidget, self).__init__() + super(RawTextDialog, self).__init__() self.appConfigurations = QSettings( CONFIGS["APPLICATION_NAME"], CONFIGS["APPLICATION_NAME"] ) diff --git a/src/staticwordpress/share/_ignore b/src/staticwordpress/share/_ignore new file mode 100644 index 0000000..e0b03fb --- /dev/null +++ b/src/staticwordpress/share/_ignore @@ -0,0 +1 @@ +._data/ \ No newline at end of file diff --git a/src/staticwordpress/share/config.json b/src/staticwordpress/share/config.json index 054d50b..228165d 100644 --- a/src/staticwordpress/share/config.json +++ b/src/staticwordpress/share/config.json @@ -44,7 +44,7 @@ "xmlns:image": "http://www.google.com/schemas/sitemap-image/1.1" }, "COLOR": { - "SUCCESS": "#005500", + "SUCCESS": "#aaff7f", "WARNING": "#ffff7f", "ERROR": "#ff557f" }, diff --git a/src/staticwordpress/share/gui.json b/src/staticwordpress/share/gui.json index 1645a55..28c5c22 100644 --- a/src/staticwordpress/share/gui.json +++ b/src/staticwordpress/share/gui.json @@ -1,8 +1,8 @@ { "MENUS": [ { - "name": "menu_file", - "text": "&File", + "name": "menu_project", + "text": "&Project", "enable": true, "icon": "", "parent": "" @@ -56,85 +56,85 @@ "text": "Project", "enable": true }, + { + "name": "toolbar_edit", + "text": "Edit", + "enable": true + }, { "name": "toolbar_wordpres", "text": "WordPress", - "enable": true + "enable": false }, { "name": "toolbar_github", "text": "GitHub", - "enable": true - }, - { - "name": "toolbar_edit", - "text": "Edit", - "enable": true + "enable": false } ], "ACTIONS": [ { "icon": "/icons/file-outline.svg", - "name": "action_file_project_new", + "name": "action_project_new", "visible": true, - "text": "&New Project", + "text": "&New", "shortcut": "Ctrl+N", - "tooltip": "New Project (Ctrl+N)", - "function": "self.create_project", + "tooltip": "New (Ctrl+N)", + "function": "self.new_project", "setCheckable": false, - "menu": "menu_file", + "menu": "menu_project", "seperator": false, "toolbar": "toolbar_project" }, { "icon": "/icons/folder-outline.svg", - "name": "action_file_project_open", + "name": "action_project_open", "visible": true, - "text": "&Open Project", + "text": "&Open", "shortcut": "Ctrl+O", - "tooltip": "Open Project (Ctrl+O)", + "tooltip": "Open (Ctrl+O)", "function": "self.open_project", "setCheckable": false, - "menu": "menu_file", + "menu": "menu_project", "seperator": false, "toolbar": "toolbar_project" }, { - "icon": "/icons/content-save-outline.svg", - "name": "action_file_project_save", + "icon": "/icons/project_settings.svg", + "name": "action_project_settings", "visible": true, - "text": "&Save Project", - "shortcut": "Ctrl+S", - "tooltip": "Save Project (Ctrl+S)", - "function": "self.save_project", + "text": "&Settings", + "shortcut": "Ctrl+C", + "tooltip": "Check (Ctrl+C)", + "function": "self.show_project", "setCheckable": false, - "menu": "menu_file", + "menu": "menu_project", "seperator": false, "toolbar": "toolbar_project" }, { - "icon": "/icons/file-document-remove-outline.svg", - "name": "action_file_project_close", + "icon": "/icons/project_close.svg", + "name": "action_project_close", "visible": true, - "text": "&Close Project", + "text": "&Close", "shortcut": "Ctrl+X", - "tooltip": "Close Project (Ctrl+X)", + "tooltip": "Close (Ctrl+X)", "function": "self.close_project", "setCheckable": false, - "menu": "menu_file", + "menu": "menu_project", "seperator": true, "toolbar": "toolbar_project" }, { "icon": "/icons/exit-to-app.svg", - "name": "action_file_exit", + "name": "action_project_exit", "visible": true, "text": "&Exit", "shortcut": "Ctrl+Q", "tooltip": "Exit (Ctrl+Q)", "function": "self.close", "setCheckable": false, - "menu": "menu_file", + "menu": "menu_project", "seperator": false, "toolbar": "" }, @@ -359,19 +359,6 @@ "menu": "menu_tools", "toolbar": "" }, - { - "icon": "/icons/check_project.svg", - "name": "action_file_check_project", - "visible": true, - "text": "&Check Project", - "shortcut": "Ctrl+F3", - "tooltip": "Check Project (Ctrl+F3)", - "function": "self.check_project", - "setCheckable": false, - "menu": "menu_tools", - "seperator": false, - "toolbar": false - }, { "icon": "/icons/text-recognition.svg", "name": "action_utilities_extract_url_from_raw_text", diff --git a/src/staticwordpress/share/icons/project_close.svg b/src/staticwordpress/share/icons/project_close.svg new file mode 100644 index 0000000..d9f6b9c --- /dev/null +++ b/src/staticwordpress/share/icons/project_close.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/src/staticwordpress/share/icons/project_settings.svg b/src/staticwordpress/share/icons/project_settings.svg new file mode 100644 index 0000000..af1a0dc --- /dev/null +++ b/src/staticwordpress/share/icons/project_settings.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/src/staticwordpress/share/icons/visibility.svg b/src/staticwordpress/share/icons/visibility.svg new file mode 100644 index 0000000..f7e15dd --- /dev/null +++ b/src/staticwordpress/share/icons/visibility.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/src/staticwordpress/share/icons/visibility_lock.svg b/src/staticwordpress/share/icons/visibility_lock.svg new file mode 100644 index 0000000..0a6d371 --- /dev/null +++ b/src/staticwordpress/share/icons/visibility_lock.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/tests/test_project.py b/tests/test_project.py index 80f757e..c4af89e 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -34,5 +34,5 @@ def test_project_create(): p = Project() assert p.status == PROJECT.NOT_FOUND - assert p.redirects == REDIRECTS.REDIRECTION + assert p.redirects == REDIRECTS.NONE assert p.host == HOST.NETLIFY From 75fc5a6244ede92bfdbde1804ea02219fcc39bbe Mon Sep 17 00:00:00 2001 From: Faisal Shahzad Date: Tue, 10 Oct 2023 08:07:08 +0200 Subject: [PATCH 2/5] Updated wordpress menu if wordpress can be crawled --- .gitignore | 1 + src/staticwordpress/core/project.py | 2 +- src/staticwordpress/gui/mainwindow.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index dbd935f..981373b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST +.vscode # PyInstaller # Usually these files are written by a python script from a template diff --git a/src/staticwordpress/core/project.py b/src/staticwordpress/core/project.py index 0bbcf99..cc42a86 100644 --- a/src/staticwordpress/core/project.py +++ b/src/staticwordpress/core/project.py @@ -143,7 +143,7 @@ def has_wordpress(self) -> bool: def can_crawl(self) -> bool: return all( [ - self["source"]["type"] != SOURCE.CRAWL, + self["source"]["type"] == SOURCE.CRAWL, self["source"]["url"] != "", self["destination"]["output"] != "", ] diff --git a/src/staticwordpress/gui/mainwindow.py b/src/staticwordpress/gui/mainwindow.py index 0534c34..5c73293 100644 --- a/src/staticwordpress/gui/mainwindow.py +++ b/src/staticwordpress/gui/mainwindow.py @@ -667,7 +667,7 @@ def update_statusbar(self, message_, percent_) -> None: def update_widgets(self) -> None: self.findChild(QMenu, "menu_github").setEnabled(self._project.has_github()) self.findChild(QMenu, "menu_wordpress").setEnabled( - self._project.has_wordpress() + self._project.has_wordpress() or self._project.can_crawl() ) self.findChild(QToolBar, "toolbar_github").setEnabled( self._project.has_github() From 5ceecd3f3a77a86fa2adcbe15c5024e72b2a2096 Mon Sep 17 00:00:00 2001 From: Faisal Shahzad Date: Tue, 10 Oct 2023 11:24:43 +0200 Subject: [PATCH 3/5] fix parent widget for dilogs --- src/staticwordpress/gui/config.py | 4 ++-- src/staticwordpress/gui/mainwindow.py | 16 +++++++++------- src/staticwordpress/gui/project.py | 4 ++-- src/staticwordpress/gui/rawtext.py | 4 ++-- src/staticwordpress/gui/workflow.py | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/staticwordpress/gui/config.py b/src/staticwordpress/gui/config.py index 8968053..f0aa358 100644 --- a/src/staticwordpress/gui/config.py +++ b/src/staticwordpress/gui/config.py @@ -103,8 +103,8 @@ def paintEvent(self, event: QPaintEvent) -> None: class ConfigDialog(QDialog): - def __init__(self): - super(ConfigDialog, self).__init__() + def __init__(self, parent=None): + super(ConfigDialog, self).__init__(parent=parent) self.appConfigurations = QSettings( CONFIGS["APPLICATION_NAME"], CONFIGS["APPLICATION_NAME"] ) diff --git a/src/staticwordpress/gui/mainwindow.py b/src/staticwordpress/gui/mainwindow.py index 5c73293..2a7c88a 100644 --- a/src/staticwordpress/gui/mainwindow.py +++ b/src/staticwordpress/gui/mainwindow.py @@ -240,7 +240,7 @@ def update_sitemap_location(self, sitemap_location): @logging_decorator def extract_url_from_raw_text(self): rtp = RawTextDialog( - src_url=self._project.src_url, dest_url=self._project.dst_url + parent=self, src_url=self._project.src_url, dest_url=self._project.dst_url ) if rtp.exec_(): raw_text = rtp.textedit_raw_text_with_links.toPlainText() @@ -314,13 +314,13 @@ def help(self): @logging_decorator def show_configs(self): """Interface with System Configurations""" - w = ConfigDialog() + w = ConfigDialog(parent=self) if w.exec_(): logging.info("Saved/Updated Default Configurations") def about(self): """ """ - msgBox = QMessageBox() + msgBox = QMessageBox(parent=self) msgBox.setText( f"Copyright {date.today().year} - SERP Wings" f"

{CONFIGS['APPLICATION_NAME']} Version - {VERISON}" @@ -338,7 +338,7 @@ def new_project(self): """Closing current project will automatically start a new project.""" self.close_project() - pdialog = ProjectDialog(self._project, title_="New Project") + pdialog = ProjectDialog(self, self._project, title_="New Project") if pdialog.exec_(): self._project = pdialog._project self.appConfigurations.setValue("last-project", self._project.output) @@ -373,7 +373,9 @@ def open_project(self): if project_path.exists(): self._project.open(project_path) if self._project.is_open(): - pdialog = ProjectDialog(self._project, title_="Project Properties") + pdialog = ProjectDialog( + self, self._project, title_="Project Properties" + ) if pdialog.exec_(): self._project = pdialog._project @@ -386,7 +388,7 @@ def open_project(self): logging.info(f"Open Project {self._project.path} Successfully") self.appConfigurations.setValue("last-project", project_folder) else: - msgBox = QMessageBox() + msgBox = QMessageBox(parent=self) msgBox.setText( f"Project cannot be opened or selected path invalid." f"
Please try again with project folder." @@ -410,7 +412,7 @@ def open_project(self): def show_project(self): """showing static-wordpress Project File""" if self._project.is_open(): - pdialog = ProjectDialog(self._project, title_="Current Project") + pdialog = ProjectDialog(self, self._project, title_="Current Project") if pdialog.exec_(): self._project = pdialog._project diff --git a/src/staticwordpress/gui/project.py b/src/staticwordpress/gui/project.py index c206c6e..18cda88 100644 --- a/src/staticwordpress/gui/project.py +++ b/src/staticwordpress/gui/project.py @@ -78,8 +78,8 @@ class ProjectDialog(QDialog): - def __init__(self, project_, title_="Project Settings"): - super(ProjectDialog, self).__init__() + def __init__(self, parent, project_, title_="Project Settings"): + super(ProjectDialog, self).__init__(parent=parent) self.appConfigurations = QSettings( CONFIGS["APPLICATION_NAME"], CONFIGS["APPLICATION_NAME"] ) diff --git a/src/staticwordpress/gui/rawtext.py b/src/staticwordpress/gui/rawtext.py index 98065dd..6f422d9 100644 --- a/src/staticwordpress/gui/rawtext.py +++ b/src/staticwordpress/gui/rawtext.py @@ -52,8 +52,8 @@ class RawTextDialog(QDialog): - def __init__(self, src_url: str, dest_url: str): - super(RawTextDialog, self).__init__() + def __init__(self, parent, src_url: str, dest_url: str): + super(RawTextDialog, self).__init__(parent=parent) self.appConfigurations = QSettings( CONFIGS["APPLICATION_NAME"], CONFIGS["APPLICATION_NAME"] ) diff --git a/src/staticwordpress/gui/workflow.py b/src/staticwordpress/gui/workflow.py index 2bc4daf..fba1b90 100644 --- a/src/staticwordpress/gui/workflow.py +++ b/src/staticwordpress/gui/workflow.py @@ -36,7 +36,7 @@ from ..core.project import Project from ..core.constants import SOURCE from ..core.workflow import Workflow -from .utils import logging_decorator, progress_decorator +from ..gui.utils import logging_decorator, progress_decorator # +++++++++++++++++++++++++++++++++++++++++++++++++++++ From e4b72da7f3f6ebd90dba4285348be8cb09d07201 Mon Sep 17 00:00:00 2001 From: Faisal Shahzad Date: Sat, 14 Oct 2023 14:25:51 +0200 Subject: [PATCH 4/5] Updated MessageBox icons --- src/staticwordpress/gui/mainwindow.py | 170 +++++++++++++++++++------- src/staticwordpress/gui/project.py | 19 ++- 2 files changed, 140 insertions(+), 49 deletions(-) diff --git a/src/staticwordpress/gui/mainwindow.py b/src/staticwordpress/gui/mainwindow.py index 2a7c88a..67d3989 100644 --- a/src/staticwordpress/gui/mainwindow.py +++ b/src/staticwordpress/gui/mainwindow.py @@ -203,13 +203,24 @@ def inner(self): @logging_decorator def clean_output_directory(self): """Clean Output Directory""" - reply = QMessageBox.question( - self, - "Clean Output Folder Content", - f"Existing content in Output folder will be delete?\n {self._project.output}", - QMessageBox.Yes | QMessageBox.No, + + msgBox = QMessageBox(parent=self) + msgBox.setWindowTitle("Clean Output Folder Content") + msgBox.setText( + f"Existing content in Output folder will be delete?
{self._project.output}", ) - if reply == QMessageBox.Yes: + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) + msgBox.addButton(QMessageBox.Cancel).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg") + ) + msgBox.setWindowIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg")) + msgBox.setDefaultButton(QMessageBox.Ok) + msgBox.setTextFormat(Qt.RichText) + msgBox.exec_() + + if msgBox.clickedButton().text() == "&OK": rm_dir_tree(self._project.output) logging.info( f"Content of output folder at {self._project.output} are deleted" @@ -261,14 +272,24 @@ def clear_cache(self): def closeEvent(self, event): """ """ - reply = QMessageBox.question( - self, - "Exiting static-wordpress", - "Do you really want to exit?.\nAny unsaved changes will be lost!", - QMessageBox.Yes | QMessageBox.No, + msgBox = QMessageBox(parent=self) + msgBox.setWindowTitle(f"Exiting {CONFIGS['APPLICATION_NAME']}") + msgBox.setIcon(QMessageBox.Question) + msgBox.setText( + "Do you really want to exit?.
Any unsaved changes will be lost!", + ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") ) + msgBox.addButton(QMessageBox.Cancel).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg") + ) + msgBox.setDefaultButton(QMessageBox.Ok) + msgBox.setWindowIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg")) + msgBox.setTextFormat(Qt.RichText) + msgBox.exec_() - if reply == QMessageBox.Yes: + if msgBox.clickedButton().text() == "&OK": if self._bg_thread.isRunning(): self._bg_thread.quit() del self._bg_thread @@ -327,10 +348,12 @@ def about(self): "

This work is an opensource project under
GNU General Public License v3 or later (GPLv3+)" f"
More Information at {CONFIGS['ORGANIZATION_NAME']}" ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) msgBox.setWindowIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg")) msgBox.setTextFormat(Qt.RichText) msgBox.setWindowTitle("About Us") - msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() @logging_decorator @@ -393,12 +416,14 @@ def open_project(self): f"Project cannot be opened or selected path invalid." f"
Please try again with project folder." ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) msgBox.setWindowIcon( QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg") ) msgBox.setTextFormat(Qt.RichText) msgBox.setWindowTitle("Open Project") - msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() logging.info( @@ -425,28 +450,51 @@ def close_project(self): """Assign new project and old properties will be lost. Default is assigned as CLOSED project """ - reply = QMessageBox.question( - self, - "Close Existing Project", - "Are you sure to close current project and open new one?.\n All existing project properties will be lost!", - QMessageBox.Yes | QMessageBox.No, + msgBox = QMessageBox(parent=self) + msgBox.setWindowTitle("Close Existing Project") + msgBox.setText( + "Are you sure to close current project and open new one?.
All existing project properties will be lost!", + ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) + msgBox.addButton(QMessageBox.Cancel).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg") ) - if reply == QMessageBox.Yes: + msgBox.setDefaultButton(QMessageBox.Ok) + msgBox.setWindowIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg")) + msgBox.setTextFormat(Qt.RichText) + msgBox.exec_() + + if msgBox.clickedButton().text() == "&OK": self._project = Project() self.update_widgets() @is_project_open def start_batch_process(self): """Start Crawling""" + if not self._project.output.exists(): - reply = QMessageBox.question( - self, - f"Output Folder", - f"Following Output Folder doesnt not exit?.\n{self._project.output}\nDo You want to create it now?", - QMessageBox.Yes | QMessageBox.No, + msgBox = QMessageBox(parent=self) + msgBox.setIcon(QMessageBox.Question) + msgBox.setWindowTitle("Output Folder") + msgBox.setText( + f"Following Output Folder doesnt not exit?.
{self._project.output}
Do You want to create it now?", + ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) + msgBox.addButton(QMessageBox.Cancel).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg") + ) + msgBox.setWindowIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg") ) + msgBox.setDefaultButton(QMessageBox.Ok) + msgBox.setTextFormat(Qt.RichText) + msgBox.exec_() - if reply == QMessageBox.Yes: + if msgBox.clickedButton().text() == "&OK": os.mkdir(self._project.output) else: return @@ -459,13 +507,26 @@ def start_batch_process(self): if self._project.src_type == SOURCE.ZIP: if not self._bg_worker._work_flow.verify_simply_static(): - reply = QMessageBox.question( - self, - f"ZIP File Missing", - f"ZIP File not found. Please check your project configurations?", - QMessageBox.Yes, + msgBox = QMessageBox(parent=self) + msgBox.setWindowTitle("ZIP File Missing") + msgBox.setIcon(QMessageBox.Question) + msgBox.setText( + "ZIP File not found. Please check your project configurations?", ) - if reply == QMessageBox.Yes: + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) + msgBox.addButton(QMessageBox.Cancel).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg") + ) + msgBox.setWindowIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg") + ) + msgBox.setDefaultButton(QMessageBox.Ok) + msgBox.setTextFormat(Qt.RichText) + msgBox.exec_() + + if msgBox.clickedButton().text() == "&OK": return self._bg_thread = QThread(parent=self) @@ -478,14 +539,25 @@ def start_batch_process(self): @is_project_open def stop_process(self) -> None: if self._bg_worker.is_running(): - reply = QMessageBox.question( - self, - "Stop Crawling Process", - "Do you really want to Stop Crawling Thrad?", - QMessageBox.Yes | QMessageBox.No, + msgBox = QMessageBox(parent=self) + msgBox.setWindowTitle("Stop Crawling Process") + msgBox.setText( + "Do you really want to Stop Crawling Thread?", ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) + msgBox.addButton(QMessageBox.Cancel).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg") + ) + msgBox.setWindowIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg") + ) + msgBox.setTextFormat(Qt.RichText) + msgBox.setDefaultButton(QMessageBox.Ok) + msgBox.exec_() - if reply == QMessageBox.Yes: + if msgBox.clickedButton().text() == "&OK": self._bg_worker.stop_calcualations() self.update_statusbar("Stoping Processing", 100) @@ -591,14 +663,24 @@ def create_github_repositoy(self) -> None: @is_project_open def delete_github_repository(self) -> None: """""" - reply = QMessageBox.question( - self, - "Deleting Repository on GitHub", - f"Do you really want to delete {self._project.gh_repo} on GitHub?\nThis deletion is not reversible.", - QMessageBox.Yes | QMessageBox.No, + + msgBox = QMessageBox(parent=self) + msgBox.setWindowTitle("Deleting Repository on GitHub") + msgBox.setText( + f"Do you really want to delete {self._project.gh_repo} on GitHub?
This deletion is not reversible.", + ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) + msgBox.addButton(QMessageBox.Cancel).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/cancel.svg") ) + msgBox.setDefaultButton(QMessageBox.Ok) + msgBox.setWindowIcon(QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg")) + msgBox.setTextFormat(Qt.RichText) + msgBox.exec_() - if reply == QMessageBox.Yes: + if msgBox.clickedButton().text() == "&OK": if self._bg_thread.isRunning(): self._bg_thread.quit() diff --git a/src/staticwordpress/gui/project.py b/src/staticwordpress/gui/project.py index 18cda88..304ae2a 100644 --- a/src/staticwordpress/gui/project.py +++ b/src/staticwordpress/gui/project.py @@ -54,7 +54,7 @@ QPushButton, QAction, ) -from PyQt5.QtCore import QSettings, QSize, QThread +from PyQt5.QtCore import Qt, QSettings, QSize, QThread from PyQt5.QtGui import QIcon # +++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -451,9 +451,18 @@ def accept(self) -> None: ) return super().accept() else: - QMessageBox.information( - self, + msgBox = QMessageBox(parent=self) + msgBox.setText( + "Cannot start this project.
Please check project settings." + ) + msgBox.addButton(QMessageBox.Ok).setIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/ok.svg") + ) + msgBox.setWindowIcon( + QIcon(f"{SHARE_FOLDER_PATH}/icons/static-wordpress.svg") + ) + msgBox.setTextFormat(Qt.RichText) + msgBox.setWindowTitle( "Invalid Project Settings", - "Cannot create new project.
Please check project settings.", - QMessageBox.Yes, ) + msgBox.exec() From 4432bf9ff2c880f8714e3cd0283c8940f6ad6008 Mon Sep 17 00:00:00 2001 From: Faisal Shahzad <84210709+seowings@users.noreply.github.com> Date: Sat, 14 Oct 2023 16:00:30 +0200 Subject: [PATCH 5/5] updated crawling checks --- src/staticwordpress/core/project.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/staticwordpress/core/project.py b/src/staticwordpress/core/project.py index cc42a86..845399a 100644 --- a/src/staticwordpress/core/project.py +++ b/src/staticwordpress/core/project.py @@ -135,10 +135,12 @@ def is_valid(self) -> bool: ) def has_github(self) -> bool: - return self["github"]["token"] != "" or self["github"]["repository"] != "" + return self["github"]["token"] != "" and self["github"]["repository"] != "" def has_wordpress(self) -> bool: - return self["wordpress"]["api-token"] != "" or self["wordpress"]["user"] != "" + return self["source"]["type"] == SOURCE.CRAWL or ( + self["wordpress"]["api-token"] != "" and self["wordpress"]["user"] != "" + ) def can_crawl(self) -> bool: return all(