this is GUI.py of linkedin automation sofotware  written in python. I want it to save cookies location in settings.yaml once loaded  so next time when open this software , it should ask for cookie again if already loaded previous time
just etll what parts to be changed or added in order to achieve, instead of writing whole code again. 


import sys
from threading import Thread
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget, QFileDialog, QAction, QMenu, QLineEdit, QComboBox, QGroupBox, QSpinBox, QProgressBar
from PyQt5.QtCore import Qt, QObject, pyqtSignal, QThread
import json
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
import time
import yaml
import os
import linkedin_automation_logic

class WorkerSignals(QObject):
    status_update = pyqtSignal(str)
    progress_update = pyqtSignal(int)

class LinkedInAutomationWorker(QThread):
    def __init__(self, cookie, settings):
        super().__init__()
        self.cookie = cookie
        self.settings = settings
        self.signals = WorkerSignals()

    def run(self):
        try:
            keywords = [
                self.settings.get('keyword_1', ''),
                self.settings.get('keyword_2', ''),
                self.settings.get('keyword_3', '')
            ]
            comments_per_day = self.settings.get('comments_per_day', 10)

            # Ensure cookie_data is in JSON format
            if self.cookie:
                linkedin_automation_logic.start_linkedin_automation(
                    self.cookie,
                    keywords,
                    comments_per_day,
                    global_comments=0,
                    headless=False
                )
                self.signals.status_update.emit("Status: Automation Completed Successfully")
            else:
                self.signals.status_update.emit("Status: Cookie Data Not Found in Settings")
        except FileNotFoundError as e:
            self.signals.status_update.emit(f"Status: {str(e)}")
        except Exception as e:
            self.signals.status_update.emit(f"Status: Unexpected error occurred: {str(e)}")

class LinkedInAutomationTool(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("LinkedIn Automation Tool")
        self.setGeometry(100, 100, 800, 500)  # Adjust window size for better UX
        self.initUI()
        self.driver = None  # Initialize driver as None
        self.browser_shown = False  # To track if the browser is visible
        self.worker = None

    def initUI(self):
        # Central Widget to hold all other widgets
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # Layout for the central widget
        layout = QVBoxLayout(central_widget)
        layout.setContentsMargins(20, 20, 20, 20)  # Set margins for better UX
        layout.setSpacing(15)  # Set spacing between widgets for better UX
        central_widget.setLayout(layout)

        # Button to load cookie from a file
        self.load_cookie_button = QPushButton("Load Cookie from File")
        self.load_cookie_button.setIcon(self.style().standardIcon(QPushButton().style().SP_DialogOpenButton))
        self.load_cookie_button.setToolTip("Load LinkedIn cookie in JSON format")
        self.load_cookie_button.clicked.connect(self.load_cookie)
        layout.addWidget(self.load_cookie_button)

        # Button to start the commenting automation process
        self.start_button = QPushButton("Start Commenting Automation")
        self.start_button.setIcon(self.style().standardIcon(QPushButton().style().SP_ArrowRight))
        self.start_button.setToolTip("Start the LinkedIn commenting automation")
        self.start_button.clicked.connect(self.start_automation)
        layout.addWidget(self.start_button)

        # Button to show the browser
        self.show_browser_button = QPushButton("Show Browser")
        self.show_browser_button.setIcon(self.style().standardIcon(QPushButton().style().SP_ComputerIcon))
        self.show_browser_button.setToolTip("Show the browser window")
        self.show_browser_button.clicked.connect(self.show_browser)
        self.show_browser_button.setEnabled(False)  # Disable initially
        layout.addWidget(self.show_browser_button)

        # Button to hide the browser
        self.hide_browser_button = QPushButton("Hide Browser")
        self.hide_browser_button.setIcon(self.style().standardIcon(QPushButton().style().SP_DesktopIcon))
        self.hide_browser_button.setToolTip("Hide the browser window")
        self.hide_browser_button.clicked.connect(self.hide_browser)
        self.hide_browser_button.setEnabled(False)  # Disable initially
        layout.addWidget(self.hide_browser_button)

        # Button to close the browser
        self.close_browser_button = QPushButton("Close Browser")
        self.close_browser_button.setIcon(self.style().standardIcon(QPushButton().style().SP_BrowserStop))
        self.close_browser_button.setToolTip("Close the browser instance")
        self.close_browser_button.clicked.connect(self.close_browser)
        self.close_browser_button.setEnabled(False)  # Disable initially
        layout.addWidget(self.close_browser_button)

        # Label to display the current status of the tool
        self.status_label = QLabel("Status: Waiting to start...")
        layout.addWidget(self.status_label)

        # Progress bar for automation
        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)
        layout.addWidget(self.progress_bar)

        # Create Settings Menu
        self.settings_menu = QMenu("Settings", self)
        self.settings_action = QAction("Open Settings", self)
        self.settings_action.setShortcut("Ctrl+S")
        self.settings_action.triggered.connect(self.open_settings)
        self.settings_menu.addAction(self.settings_action)
        self.menuBar().addMenu(self.settings_menu)

    def open_settings(self):
        # Function to open settings for LinkedIn automation
        if hasattr(self, 'settings_window') and self.settings_window is not None:
            self.settings_window.show()  # Ensure the window is displayed properly and stays open
            return
        
        # Load existing settings if available
        script_dir = os.path.dirname(os.path.abspath(__file__))
        settings_path = os.path.join(script_dir, 'settings.yaml')
        if os.path.exists(settings_path):
            with open(settings_path, 'r') as file:
                settings_data = yaml.safe_load(file)
        else:
            settings_data = {
                'keyword_1': 'en Empowerment OR Female Empowerment',
                'keyword_2': 'Online business',
                'keyword_3': 'Startup',
                'comment_length': '30 Words',
                'question_frequency': 'Never',
                'formality_level': 'Semi-formal',
                'personality': 'Whimsical',
                'tone': 'Professional',
                'like_commented_post': 'No',
                'hashtags': '#binteahan',
                'comments_per_day': 100,
                'profile_pages_to_mention': 'Bint e Ahan',
                'comment_as_page': 'No'
            }
        
        self.settings_window = QWidget()
        self.settings_window.setWindowTitle("Settings")
        self.settings_window.setGeometry(150, 150, 500, 700)
        settings_layout = QVBoxLayout(self.settings_window)
        settings_layout.setContentsMargins(20, 20, 20, 20)  # Set margins for better UX
        settings_layout.setSpacing(15)  # Set spacing between widgets for better UX

        # Group Box for Keywords
        keywords_group = QGroupBox("Keywords Settings")
        keywords_layout = QVBoxLayout()
        self.keyword_1_input = QLineEdit(settings_data.get('keyword_1', 'en Empowerment OR Female Empowerment'))
        keywords_layout.addWidget(QLabel("Keyword - 1:"))
        keywords_layout.addWidget(self.keyword_1_input)

        self.keyword_2_input = QLineEdit(settings_data.get('keyword_2', 'Online business'))
        keywords_layout.addWidget(QLabel("Keyword - 2:"))
        keywords_layout.addWidget(self.keyword_2_input)

        self.keyword_3_input = QLineEdit(settings_data.get('keyword_3', 'Startup'))
        keywords_layout.addWidget(QLabel("Keyword - 3:"))
        keywords_layout.addWidget(self.keyword_3_input)
        keywords_group.setLayout(keywords_layout)
        settings_layout.addWidget(keywords_group)

        # Group Box for Personalization Settings
        personalization_group = QGroupBox("Personalization Settings")
        personalization_layout = QVBoxLayout()

        # Comment Length Dropdown
        self.comment_length_input = QComboBox()
        self.comment_length_input.addItems(["10 Words", "20 Words", "30 Words", "50 Words", "100 Words"])
        self.comment_length_input.setCurrentText(settings_data.get('comment_length', '30 Words'))
        personalization_layout.addWidget(QLabel("Personalized Tone - Comments Length:"))
        personalization_layout.addWidget(self.comment_length_input)

        # Question Frequency Dropdown
        self.question_frequency_input = QComboBox()
        self.question_frequency_input.addItems(["Sometimes", "Rarely", "Never"])
        self.question_frequency_input.setCurrentText(settings_data.get('question_frequency', 'Never'))
        personalization_layout.addWidget(QLabel("Questions Frequency:"))
        personalization_layout.addWidget(self.question_frequency_input)

        # Formality Level Dropdown
        self.formality_level_input = QComboBox()
        self.formality_level_input.addItems(["Formal", "Semi-formal", "Informal"])
        self.formality_level_input.setCurrentText(settings_data.get('formality_level', 'Semi-formal'))
        personalization_layout.addWidget(QLabel("Formality Level:"))
        personalization_layout.addWidget(self.formality_level_input)

        # Personality Dropdown
        self.personality_input = QComboBox()
        self.personality_input.addItems(["Humouristic", "Analytical", "Serious", "Whimsical", "Irreverant", "Sarcastic", "Sincere", "Playful", "Optimistic", "Pessimistic", "Neutral"])
        self.personality_input.setCurrentText(settings_data.get('personality', 'Whimsical'))
        personalization_layout.addWidget(QLabel("Personality:"))
        personalization_layout.addWidget(self.personality_input)

        # Tone Dropdown
        self.tone_input = QComboBox()
        self.tone_input.addItems(["Friendly", "Professional", "Casual"])
        self.tone_input.setCurrentText(settings_data.get('tone', 'Professional'))
        personalization_layout.addWidget(QLabel("Tone:"))
        personalization_layout.addWidget(self.tone_input)

        personalization_group.setLayout(personalization_layout)
        settings_layout.addWidget(personalization_group)

        # Other Settings
        other_group = QGroupBox("Other Settings")
        other_layout = QVBoxLayout()

        # Like Commented Post Checkbox
        self.like_commented_post_input = QComboBox()
        self.like_commented_post_input.addItems(["Yes", "No"])
        self.like_commented_post_input.setCurrentText(settings_data.get('like_commented_post', 'No'))
        other_layout.addWidget(QLabel("Like the Commented Post:"))
        other_layout.addWidget(self.like_commented_post_input)

        # Hashtags Input
        self.hashtags_input = QLineEdit(settings_data.get('hashtags', '#binteahan'))
        other_layout.addWidget(QLabel("Hashtags:"))
        other_layout.addWidget(self.hashtags_input)

        # Number of Comments Per Day Input (SpinBox)
        self.comments_per_day_input = QSpinBox()
        self.comments_per_day_input.setRange(1, 1000)
        self.comments_per_day_input.setValue(settings_data.get('comments_per_day', 100))
        other_layout.addWidget(QLabel("Number of Comments Per Day:"))
        other_layout.addWidget(self.comments_per_day_input)

        # Profile/Pages to Mention Input
        self.profile_pages_to_mention_input = QLineEdit(settings_data.get('profile_pages_to_mention', 'Bint e Ahan'))
        other_layout.addWidget(QLabel("Profile/Pages to Mention:"))
        other_layout.addWidget(self.profile_pages_to_mention_input)

        # Comment as Page Input
        self.comment_as_page_input = QComboBox()
        self.comment_as_page_input.addItems(["No", "Yes"])
        self.comment_as_page_input.setCurrentText(settings_data.get('comment_as_page', 'No'))
        other_layout.addWidget(QLabel("Comment as Page?:"))
        other_layout.addWidget(self.comment_as_page_input)

        other_group.setLayout(other_layout)
        settings_layout.addWidget(other_group)

        # Save Button
        self.save_settings_button = QPushButton("Save Settings")
        self.save_settings_button.clicked.connect(self.save_settings)
        settings_layout.addWidget(self.save_settings_button)

        self.settings_window.setLayout(settings_layout)
        self.settings_window.show()

    def save_settings(self):
        # Function to save settings from the Settings Window
        self.keyword_1_value = self.keyword_1_input.text()
        self.keyword_2_value = self.keyword_2_input.text()
        self.keyword_3_value = self.keyword_3_input.text()
        self.comment_length_value = self.comment_length_input.currentText()
        self.question_frequency_value = self.question_frequency_input.currentText()
        self.formality_level_value = self.formality_level_input.currentText()
        self.personality_value = self.personality_input.currentText()
        self.tone_value = self.tone_input.currentText()
        self.like_commented_post_value = self.like_commented_post_input.currentText()
        self.hashtags_value = self.hashtags_input.text()
        self.comments_per_day_value = self.comments_per_day_input.value()
        self.profile_pages_to_mention_value = self.profile_pages_to_mention_input.text()
        self.comment_as_page_value = self.comment_as_page_input.currentText()

        # Save settings to YAML file
        settings_data = {
            'keyword_1': self.keyword_1_value,
            'keyword_2': self.keyword_2_value,
            'keyword_3': self.keyword_3_value,
            'comment_length': self.comment_length_value,
            'question_frequency': self.question_frequency_value,
            'formality_level': self.formality_level_value,
            'personality': self.personality_value,
            'tone': self.tone_value,
            'like_commented_post': self.like_commented_post_value,
            'hashtags': self.hashtags_value,
            'comments_per_day': self.comments_per_day_value,
            'profile_pages_to_mention': self.profile_pages_to_mention_value,
            'comment_as_page': self.comment_as_page_value
        }
        script_dir = os.path.dirname(os.path.abspath(__file__))
        settings_path = os.path.join(script_dir, 'settings.yaml')
        with open(settings_path, 'w') as file:
            yaml.dump(settings_data, file)
        print(f"Settings saved to {settings_path}")

        # Update status to indicate settings have been saved
        self.status_label.setText("Status: Settings Saved")
        self.status_label.setStyleSheet("color: green;")


    def load_cookie(self):
        # Function to load cookie from a file
        options = QFileDialog.Options()
        file_name, _ = QFileDialog.getOpenFileName(self, "Open Cookie File", "", "JSON Files (*.json);;All Files (*)", options=options)
        if file_name:
            # Read cookie data from the file and check format
            try:
                with open(file_name, 'r') as file:
                    cookie_data = json.load(file)  # Load as JSON to validate format
                self.cookie = cookie_data  # Store the cookie data
                self.status_label.setText("Status: Cookie Loaded Successfully")
                self.status_label.setStyleSheet("color: green;")  # Set text color to green
            except json.JSONDecodeError:
                self.status_label.setText("Status: Invalid Cookie Format")
                self.status_label.setStyleSheet("color: red;")  # Set text color to red

    def start_automation(self):
        # Function to start the automation process
        if hasattr(self, 'cookie') and self.cookie:
            self.status_label.setText("Status: Automation Started...")
            self.status_label.setStyleSheet("color: black;")
            # Start the automation in a separate thread
            Thread(target=self.run_automation_logic).start()
        else:
            # If no cookie data is provided, prompt the user to load a cookie
            self.status_label.setText("Status: Please Load a Cookie First")
            self.status_label.setStyleSheet("color: red;")

    def run_automation_logic(self):
        # Load settings
        try:
            settings = linkedin_automation_logic.load_settings()
            cookie_data = self.cookie
            keywords = [settings.get('keyword_1', ''), settings.get('keyword_2', ''), settings.get('keyword_3', '')]
            comments_per_day = settings.get('comments_per_day', 10)

            # Ensure cookie_data is in JSON format
            if cookie_data:
                linkedin_automation_logic.start_linkedin_automation(
                    cookie_data,
                    keywords,
                    comments_per_day,
                    global_comments=0,
                    headless=False
                )
                self.status_label.setText("Status: Automation Completed Successfully")
                self.status_label.setStyleSheet("color: green;")
            else:
                self.status_label.setText("Status: Cookie Data Not Found in Settings")
                self.status_label.setStyleSheet("color: red;")
        except FileNotFoundError as e:
            self.status_label.setText(f"Status: {str(e)}")
            self.status_label.setStyleSheet("color: red;")
        except Exception as e:
            self.status_label.setText(f"Status: Unexpected error occurred: {str(e)}")
            self.status_label.setStyleSheet("color: red;")

    def show_browser(self):
        # Show the browser window
        if self.driver and not self.browser_shown:
            try:
                self.driver.maximize_window()
            except Exception as e:
                print(f"Error during maximizing window: {e}")
                self.status_label.setText(f"Error: Could not maximize browser window")
                self.status_label.setStyleSheet("color: red;")
            self.browser_shown = True

    def hide_browser(self):
        # Hide the browser window
        if self.driver and self.browser_shown:
            try:
                self.driver.minimize_window()
            except Exception as e:
                print(f"Error during minimizing window: {e}")
                self.status_label.setText(f"Error: Could not minimize browser window")
                self.status_label.setStyleSheet("color: red;")
            self.browser_shown = False

    def close_browser(self):
        # Close the browser
        if self.driver:
            try:
                self.driver.quit()

            except Exception as e:
                print(f"Error during closing browser: {e}")
                self.status_label.setText(f"Error: Could not close browser properly")
                self.status_label.setStyleSheet("color: red;")
            self.driver = None
            self.browser_shown = False
            # Disable buttons for browser control after closing
            self.show_browser_button.setEnabled(False)
            self.hide_browser_button.setEnabled(False)
            self.close_browser_button.setEnabled(False)
            self.status_label.setText("Status: Browser closed.")
            self.status_label.setStyleSheet("color: black;")

if __name__ == '__main__':
    # Main entry point of the application
    app = QApplication(sys.argv)
    window = LinkedInAutomationTool()
    window.show()
    sys.exit(app.exec_())