Sunday, September 3, 2023

The SIEM Project: 01 Retrieving CVE Information

Today, I am going to start my own personal project which is a simple SIEM. In my previous posts, I have already created small python programs that could be essential part of this project which are as follows:

  1. Python: Count Source IP Addresses from Captured Packets And Display on a Table
  2. A Simple Event Log Viewer in Python
  3. 2 Python Programs that are useful in Cyber Security

Moving on, I will have to start the project by retrieving information of a CVE(Common Vulnerabilities and Exposure). To achieve this, I will be using  the library NVDLIB. Check out the documentation and how to use the library here. The documentation may seem to be outdated at most scenarios. So in real world scenarios, it would be better to download the CVE list from the NIST website which is well over a million so that the query can be easily flexible because they often make changes to their API, but in my case, I will just use simple queries.

The scenario I am going to simulate is to select 3 CVE's related to Windows 10 which is my I am currently using. I will just display the CVE number, reference URL, description, the severity, vulnerability score index and the vector.

According to ChatGPT, CVE's are as follows:

CVEs (Common Vulnerabilities and Exposures) typically contain information about vulnerabilities in software or hardware systems, including information about the affected operating systems and their versions. However, the level of detail provided in a CVE entry may vary.

Here are the key elements you can find in a typical CVE entry related to affected operating systems:

  1. CVE Identifier (CVE-ID): A unique identifier assigned to the vulnerability.
  2. Description: A description of the vulnerability, its impact, and how it can be exploited.
  3. References: Links to additional resources, such as advisories or patches, related to the vulnerability.
  4. CVSS (Common Vulnerability Scoring System) Score: A numerical score that represents the severity of the vulnerability.
  5. Affected Software: Information about the software or hardware affected by the vulnerability. This can include:
    • Vendor Name: The name of the vendor or organization that created the affected software or hardware.
    • Product Name: The name of the specific product or software component.
    • Version(s): The version(s) of the software or hardware that are affected by the vulnerability.
    • Update Version(s): The version(s) of the software or hardware that have been fixed or patched.
  6. Vulnerable Configurations: Information about how the vulnerability can be exploited in different configurations.
  7. Vulnerability Type: The type or category of the vulnerability (e.g., buffer overflow, SQL injection, etc.).
  8. CWE (Common Weakness Enumeration) ID: An identifier from the CWE database that categorizes the type of weakness or vulnerability.
  9. Publication Date: The date when the CVE entry was published.

It's important to note that while CVE entries strive to provide accurate and detailed information, the level of detail may vary depending on the information available at the time of publication. Some CVE entries may provide specific details about affected operating systems and versions, while others may provide more general information about affected software components.

Security researchers, vendors, and organizations often collaborate to provide additional information and context for CVEs, such as patches or workarounds. When assessing the impact of a CVE, it's important to refer to additional resources and advisories provided by relevant vendors and security organizations.

The Python program is very short, all I have to de is define the search parameters(retrieve all Window 10 related CVE's) and just display the first 3. And here is the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import nvdlib

r = nvdlib.searchCVE(cpeName = 'cpe:2.3:o:microsoft:windows_10:-:*:*:*:*:*:*:*')
print(len(r))
print(dir(r[0]))
x = 1
for r1 in r:
    if x <= 3:
        x +=1
        try:
            print(r1.id, str(r1.score[0]), r1.url)
            print(r1.v2severity + ' - ' + str(r1.v2score) + ' - ' + r1.v2vector)
            print(r1.descriptions[0].value)
        except:
            try:
                print(r1.v31severity + ' - ' + str(r1.v31score) + ' - ' + r1.v31vector)
                print(r1.descriptions[0].value)
            except:    
                print(dir(r1))

The search parameter is not very simple, it took me awhile to make it work, ChatGPT could not help me figure it out although it was able to explain the parts of the search parameter which is as follows:

In this CPE name:

  • cpe:2.3 indicates the CPE version.
  • o indicates that it is an operating system.
  • microsoft is the vendor (Microsoft).
  • windows_10 specifies the product (Windows 10).

The trailing * indicates that the CPE name is generic and does not specify a particular version or edition. The * is a wildcard character. And here is what ChatGPT suggested:

 cpe:2.3:o:microsoft:windows_10::version:1903:*

ChatGPT missed the '-' part, suggestion a version and it seems like the patch number which when missing('-'), the search parameter will not work and the versions and patch number doesn't seem to work as well, I figured that the search parameter can be found at the CVE NIST Details page, for example, CVE-2013-3900 can be found at NVD - CVE-2013-3900 (nist.gov) and check the section 'Known Affected Software Configurations', see screenshot below:


And furthermore, more information about CPE can be found at wikipedia. 

And that's all for now. Hire me if you have similar projects. 


Friday, August 25, 2023

Train Chat Bot With an Ebook in 5 mins

I see a lot of job openings about training a chatbot with the company's data so that it will be able to answer the questions of the company's employees, customers, or clients. I thought at first that training a chatbot would require a lot of computing power and a substantial amount of data. Then, I came across the Chainlet, Langchainin, and OpenAI libraries for Python purely by accident. A video appeared on my YouTube watch list, and I accidentally clicked on it. I was surprised to discover that such libraries exist. I've already forgotten the title of that video because upon learning about the capabilities of Chainlet, I immediately searched YouTube for tutorials, and yes, there are tons of them. I also browsed the Chainlet website. While the information there is very basic, one particular example caught my attention: Document QA. You can check it out here. All I did was copy the code, insert my OpenAI API, and run it. I obtained the ebook in TXT format from https://www.gutenberg.org.

To be honest, it didn't run immediately. I encountered several errors. One notable error I encountered was the version of SQLite3. I was using Python 3.8, and the built-in SQLite3 version is 3.14, which is not compatible with the version being used by Chainlet. I did some research and found out that SQLite3 is not upgradable on Windows 10. I would have to upgrade to version Python 3.10 because it uses SQLite3 version 3.10. However, I didn't want to upgrade to version 3.10 because my Machine Learning projects are only compatible with 3.8. I had to install 3.10 and run the program in a virtual environment. I used Pipenv, reinstalled all the libraries, and finally, it worked! Take a look at the screenshots below:

Inital Screen:



It answered several of m questions:




I noticed that it failed on one of my questions; it couldn't retrieve the ebook's title, which is weird. However, it was able to answer all the rest of my questions. This is cool. The tutorials and the source code can be found on Chainlet's website. Some of the tutorials on YouTube are already obsolete based on my experience, so I just followed Chainlet's example. However, I still find it a bit too basic; there's a lot to explore, like how to embed it in React, how to change the user name, and how to use user authentication, etc.

I also noticed that it lacks chat memory; perhaps that's another interesting topic to explore. But with all those huge topics to explore, I hope there will be tutorials, documentations and sample code snippets for developers to be able to learn how to use chainlet easily.



Wednesday, August 9, 2023

Top 5 Bot Detection Mechanisms and Services Used by Web Developers

 Introduction: In the ever-evolving digital realm, where websites serve as vital gateways to information and services, the persistent presence of bots has posed a multifaceted challenge for web developers. Bots, often automated scripts or software, can serve both beneficial and malicious purposes, influencing user experiences and website performance. As the online ecosystem becomes increasingly sophisticated, web developers are at the forefront of fortifying their platforms against the potential harm bots can inflict. To preserve the integrity of their websites, provide equitable user experiences, and safeguard against fraudulent activities, developers are turning to advanced bot detection mechanisms and services.

At its core, the dynamic between bots and


web developers encapsulates a delicate balance between enabling technological progress and preventing exploitation. Bots, when harnessed ethically, can enhance user interactions, automate routine tasks, and bolster data collection. Conversely, malevolent bots can disrupt services, infiltrate databases, and manipulate online activities, thereby jeopardizing user trust and damaging a website's reputation.

In response to this dichotomy, web developers are adopting a proactive stance, seeking out innovative ways to distinguish between genuine human users and automated agents. The intricacies of bot detection have grown to encompass a range of methodologies that delve into the nuanced behaviors, interactions, and attributes of users and bots alike. The solutions employed by developers are not merely reactionary measures; they exemplify a forward-thinking approach aimed at preserving the inclusivity and reliability of online spaces.

In this article, we will delve into five prominent bot detection mechanisms and services that have become indispensable tools in a web developer's arsenal. These approaches encompass a wide spectrum of technological ingenuity, from CAPTCHAs that test human cognitive capabilities to machine learning algorithms capable of deciphering intricate patterns of user engagement. As the digital landscape evolves, web developers continue to navigate the intricate realm of bot detection with the aim of ensuring a secure and seamless online experience for all users.

Key Points:

  • Bots play a dual role in the digital realm, offering utility and potential harm.
  • Web developers must balance technological innovation with security measures.
  • Bot detection mechanisms and services serve as proactive strategies.
  • The dynamic between human users and bots is complex and multifaceted.
  • The article will explore five essential bot detection methods and their significance.

1. CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart): CAPTCHA is one of the most recognizable and widely used bot detection mechanisms. It presents users with challenges that are easy for humans to solve but difficult for automated bots. CAPTCHAs can include distorted text, image recognition tasks, or puzzles that require reasoning skills. Leading services like Google reCAPTCHA offer variations such as the "I'm not a robot" checkbox, invisible CAPTCHAs, and reCAPTCHA v3, which assesses user behavior to determine the likelihood of bot activity.

2. Behavioral Analysis: Behavioral analysis leverages machine learning algorithms to detect deviations in user behavior. By analyzing mouse movements, keystrokes, navigation patterns, and interaction timings, these mechanisms establish a baseline of human behavior and identify anomalies indicative of bot activity. Services like Imperva Bot Management utilize advanced behavioral analytics to distinguish between genuine users and bots based on their interaction patterns.

3. Device Fingerprinting: Device fingerprinting is a technique that gathers unique attributes from a user's device, such as browser type, version, operating system, screen resolution, and installed plugins. This data is used to create a digital fingerprint that helps identify returning users and detect bots attempting to emulate human behavior. Services like Distil Networks use device fingerprinting to track and block malicious bots across different sessions and devices.

4. Machine Learning and AI-Powered Detection: Machine learning and artificial intelligence have revolutionized bot detection by enabling systems to continuously learn from new data and adapt to evolving bot tactics. These mechanisms analyze vast amounts of data to identify patterns and anomalies, helping differentiate between bots and legitimate users. Cloud-based services like Akamai Bot Manager utilize machine learning algorithms to provide real-time bot detection and mitigation.

5. Threat Intelligence Feeds: Threat intelligence feeds offer up-to-date information on known malicious IP addresses, user agents, and patterns associated with bot attacks. Web developers can integrate these feeds into their security solutions to proactively block suspicious traffic. Services like Radware Bot Manager offer threat intelligence feeds that help web developers stay ahead of emerging bot threats.

Conclusion: As bots become more sophisticated and prevalent, web developers face a continuous challenge to protect their online platforms. By implementing a combination of these top five bot detection mechanisms and services, developers can significantly enhance their ability to differentiate between genuine users and malicious bots. The evolving landscape of bot detection underscores the importance of staying up-to-date with the latest advancements to ensure secure and seamless user experiences on the web.

Tuesday, June 13, 2023

Unleash Your Voice: Empowering Self-Expression through Voice Cloning

Unlock the power of your unique voice with cutting-edge voice cloning technology. Now you can effortlessly clone your own voice, capturing every nuance and tone, without relying on any specific brand or product. Dive into the realm of personalized audio expression and bring your ideas to life like never before. With our innovative voice cloning solution, your voice becomes your ultimate tool for creativity and self-expression. Discover the freedom to mold your voice in exciting ways, opening up a world of endless possibilities. Embrace the future of voice cloning and unleash your voice's true potential.

In this article, I will show how to clone your own voice. It requires knowledge of Python though but I think some websites already offer  a paid subscription that will enable you to clone your own voice.

To create a Python voice cloner program using Real-Time-Voice-Cloning (RTVC), you'll need to install the necessary libraries and follow a step-by-step process. Here's a general outline of the steps involved:

Install dependencies:

  • Install Python 3.x (if not already installed)
  • Install the required libraries by running the following commands:

pip install tensorflow==1.15
pip install numba==0.48
pip install SoundFile
pip install unidecode
pip install librosa

Clone the Real-Time-Voice-Cloning repository:

git clone https://github.com/CorentinJ/Real-Time-Voice-Cloning.git

Download the pretrained models:

  • Download the "pretrained.zip" file from the following link: https://github.com/CorentinJ/Real-Time-Voice-Cloning/releases/tag/v1.1-pretrained
  • Extract the contents of the zip file into the cloned repository folder.

Create a Python script for the voice cloner:

Import the necessary modules
import sys
import os
import numpy as np
import librosa
import argparse
from synthesizer.inference import Synthesizer
from encoder import inference as encoder
from vocoder import inference as vocoder
from pathlib import Path

Set up paths to the model files:

encoder_weights = Path("pretrained/encoder/saved_models/pretrained.pt")
vocoder_weights = Path("pretrained/vocoder/saved_models/pretrained/pretrained.pt")
syn_dir = Path("pretrained/synthesizer/saved_models/logs-pretrained/taco_pretrained")

Initialize the models:

encoder.load_model(encoder_weights)
synthesizer = Synthesizer(syn_dir)
vocoder.load_model(vocoder_weights)

Define a function for cloning the voice:

def clone_voice(input_file, output_file):

    # Load input audio
    audio, sr = librosa.load(input_file, 22050)
    # Preprocess audio
    wav = encoder.preprocess_wav(audio, sr)
    # Extract speaker embeddings
    speaker_embed = encoder.embed_utterance(wav)
    # Synthesize cloned voice
    specs = synthesizer.synthesize_spectrograms([input_text], [speaker_embed])
    generated_wav = vocoder.infer_waveform(specs[0])
    # Save synthesized audio
    librosa.output.write_wav(output_file, generated_wav, synthesize_sample_rate)

Parse command-line arguments:

parser = argparse.ArgumentParser(description="Python Voice Cloner")
parser.add_argument("--input_file", help="Path to input audio file")
parser.add_argument("--output_file", help="Path to output cloned audio file")
args = parser.parse_args()

Clone the voice:

clone_voice(args.input_file, args.output_file)

Run the Python script:

Open a terminal or command prompt and navigate to the cloned repository folder.
Execute the Python script with the appropriate command-line arguments:
python voice_cloner.py --input_file path/to/input.wav --output_file path/to/output.wav

Ensure that you have a suitable input audio file and specify the paths to the input and output files accordingly. The script will generate a cloned version of the input voice in the specified output file.

Please note that Real-Time 


Reference:



Tuesday, May 30, 2023

Building a Product Information Retrieval System with ChatGPT, Flask, and PyQt6

 Introduction:

In this article, we will explore how to train ChatGPT, a powerful language model, to retrieve specific product information. We will build a web API using Flask and create a user interface using PyQt6. Users will be able to enter questions about a product, and ChatGPT will generate responses with relevant product information.

Section 1: Setting up the Flask API

  1. Install Flask and set up a new Flask project.
  2. Define the necessary routes for handling API requests, such as /retrieve_info for retrieving product information.
  3. Implement the logic for processing user questions and generating responses using ChatGPT.
  4. Integrate the ChatGPT model into the Flask API by calling the model and generating responses based on user input.

Section 2: Creating the PyQt6 User Interface

  1. Install PyQt6 and set up a new PyQt6 project.
  2. Design the user interface using the appropriate PyQt6 widgets, including a QLineEdit for entering questions, a QPushButton to execute the question, and a QTextEdit to display the conversation history.
  3. Connect the button's click event to a function that sends the user's question to the Flask API and updates the QTextEdit with the response from ChatGPT.
  4. Implement error handling and display appropriate messages to the user in case of API failures or other issues.

Section 3: Running the Application

  1. Launch the Flask API using a development server.
  2. Start the PyQt6 application and display the user interface to the user.
  3. Allow the user to enter questions and interact with ChatGPT to retrieve product information.
  4. Continuously update the QTextEdit widget with the conversation history, including the user's questions and ChatGPT's responses.

Conclusion:

By combining the power of ChatGPT, Flask, and PyQt6, we have built a robust system for retrieving specific product information. Users can now enter questions through the PyQt6 user interface, and ChatGPT will generate informative responses based on the product data. This system can be further enhanced with more training data and improved user experience features.

Additional Considerations:

  • It's important to handle security and authentication measures when deploying the Flask API to protect sensitive product information.
  • Training the ChatGPT model specifically for product information retrieval may require a dataset containing relevant product details and associated questions.
  • Implementing data caching or other optimization techniques can improve the response time of the API and enhance the user experience.

By following the steps outlined in this article, you'll be able to develop a product information retrieval system using ChatGPT, Flask, and PyQt6. Users can interact with the system through the PyQt6 user interface, and ChatGPT will provide accurate and helpful product information based on their queries.

Here is an example of a Python-Flask Program:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from flask import Flask, jsonify, request

app = Flask(__name__)

# Sample product data
products = [
    {
        'id': 1,
        'name': 'Product 1',
        'description': 'Description of Product 1',
        'price': 10.99
    },
    {
        'id': 2,
        'name': 'Product 2',
        'description': 'Description of Product 2',
        'price': 19.99
    }
]

# Endpoint to retrieve all products
@app.route('/products', methods=['GET'])
def get_all_products():
    return jsonify(products)

# Endpoint to retrieve a specific product by ID
@app.route('/products/<int:product_id>', methods=['GET'])
def get_product_by_id(product_id):
    product = next((product for product in products if product['id'] == product_id), None)
    if product:
        return jsonify(product)
    else:
        return jsonify({'message': 'Product not found'}), 404

if __name__ == '__main__':
    app.run(debug=True)

In this example, we define two endpoints: /products to retrieve all products and /products/{id} to retrieve a specific product by ID. We use a simple list of dictionaries to store the product data.


To run the example, save the code in a file (e.g., app.py) and execute it using Python. The API will be available at http://localhost:5000. You can access the endpoints using tools like curl or Postman.


Here are a few example requests you can make:


  • GET http://localhost:5000/products: Retrieves all products.
  • GET http://localhost:5000/products/1: Retrieves the product with ID 1.
  • GET http://localhost:5000/products/3: Returns a "Product not found" message as there is no product with ID 3.

Feel free to modify the code according to your specific requirements and integrate it with your trading platform's existing infrastructure.

And Lastly, here is the Python-Pyqt6 program:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit, QTextEdit, QPushButton
from PyQt6.QtGui import QTextCursor
import requests

class ChatGPTApp(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('ChatGPT Product Information')
        self.setGeometry(100, 100, 400, 400)

        self.question_label = QLabel('Enter your question:')
        self.question_input = QLineEdit()
        self.chatlog_label = QLabel('Chat Log:')
        self.chatlog_output = QTextEdit()
        self.chatlog_output.setReadOnly(True)
        self.ask_button = QPushButton('Ask')
        self.ask_button.clicked.connect(self.process_question)

        layout = QVBoxLayout()
        layout.addWidget(self.question_label)
        layout.addWidget(self.question_input)
        layout.addWidget(self.ask_button)
        layout.addWidget(self.chatlog_label)
        layout.addWidget(self.chatlog_output)

        self.setLayout(layout)

        self.base_url = 'http://127.0.0.1:5000/products'

    def process_question(self):
        question = self.question_input.text()
        if question:
            product_id = self.extract_product_code(question)
            if product_id:
                response = self.get_product_info(product_id)
                if 'message' in response:
                    answer = response['message']
                else:
                    print(response)
                    answer = response['description']
            else:
                answer = 'Invalid question format. Please enter a valid product code.'
            self.update_chatlog(question, answer)
            self.question_input.clear()

    def extract_product_code(self, question):
        # Extract numeric product code from the question
        product_code = ''.join(filter(str.isdigit, question))
        if product_code:
            return product_code
        return None

    def get_product_info(self, product_id):
        url = f'{self.base_url}/{product_id}'
        response = requests.get(url)
        if response.status_code == 200:
            return response.json()
        elif response.status_code == 404:
            return {'message': 'Product not found'}
        else:
            return {'message': 'Error occurred'}

    def update_chatlog(self, question, answer):
        log = f'User: {question}\nChatGPT: {answer}\n\n'
        self.chatlog_output.insertPlainText(log)
        self.chatlog_output.moveCursor(QTextCursor.MoveOperation.End)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    chatgpt_app = ChatGPTApp()
    chatgpt_app.show()
    sys.exit(app.exec())

To run this program, make sure you replace 'YOUR_OPENAI_API_KEY' with your actual OpenAI API key. Save the program in a Python file, for example, chatgpt_product_info.py, and execute it. You will see a PyQt6 window with an input field to enter questions, a "Ask" button to send the question to ChatGPT, and a chat log area to display the conversation history between the user and ChatGPT.

The program only answers the question "What is the description or product 1?", Feel free to modify the program to return the price, etc. Also it only detects numeric numbers in the question, so it is not really that intelligent, you need to create a Machine Learning Model to identify intelligently the product id in the question. But in this example, users are like having conversation with a human.



Note: The Python Codes in this article is generated by ChatGPT and I have yet to verify if the program is working. But do note that it is very useful already and it is meant to give an idea on how to create the program

Thursday, April 6, 2023

Hover over a word to select it then click it to print it

 Another good feature of an integrated development environment (IDE) is its ability to go to the definition of that function/variable/method/class when clicked or double clicked. It saves a lot of time especially when the project involves several thousands of lines of codes spread out over several files. To implement this function, a word must be able to be identified as the mouse hovers it and when selected, it should be clickable, In todays post, I have prepared a simple code snippet to do just that. What the program basically do is in the title itself, select a word by hovering the mouse pointer over it then click it to print it. To take this further, the program must be able to identify the word as a defined variable in the program or a class/method/function. I have already prepared a code snippet to identify if a word is a defined variable as stated on the planner in my chat application project, you may visit the logs here. The portion where I specifically mentioned this can be found at 'Plans for 03/08/2023'

Here is the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from PyQt6.QtWidgets import QApplication, QTextEdit
from PyQt6.QtGui import QTextCursor
class HoverTextEdit(QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setMouseTracking(True)
        self.mousePressEvent = self.onMouseClick
        
        
    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        cursor = self.cursorForPosition(event.pos())
        cursor.select(QTextCursor.SelectionType.WordUnderCursor)
        self.setTextCursor(cursor)
        
    def onMouseClick(self, event):
        super().mousePressEvent(event)
        cursor = self.textCursor()
        if cursor.hasSelection():
            selected_word = cursor.selectedText()
            print(selected_word)
if __name__ == '__main__':
    app = QApplication([])
    widget = HoverTextEdit()
    widget.show()
    app.exec()

Monday, April 3, 2023

Simple Find Function for my IDE Project

One of the key functions of a good IDE is the find function. This function is very important because based on my experience, I am having  such a hard time searching for a particular word in a 1000+ lines of codes. There are many ways to implement this like highlight all found words with the syntax hilighter so that all found words can be immediately be seen or create a small pane that enumerates the location of each found word and when clicked, the cursor will be positioned to that found word, or a combination of both, and many others. In this post I just implemented a simple way of searching a word in a QTextEdit widget by pressing contrl+f to enter the searchstring and the program will position the cursor to the first found word and select it. It is a very simple implementation and can be further modified with tons of features. 

Here is the screenshot:



Here is the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QDialog, QVBoxLayout, QLabel, QLineEdit, QPushButton, QShortcut, QInputDialog, QMessageBox
from PyQt5.QtGui import QKeySequence, QTextCursor, QTextCharFormat, QTextDocument
from PyQt5.QtCore import Qt

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
    
    def initUI(self):
        # Create a QTextEdit widget
        self.textEdit = QTextEdit(self)
        self.setCentralWidget(self.textEdit)
        
        # Create a shortcut for the "Find" action
        findShortcut = QShortcut(QKeySequence("Ctrl+F"), self)
        findShortcut.activated.connect(self.findText)
        
        # Show the main window
        self.show() 
    def findText(self):
        # Show the find dialog box
        searchString, ok = QInputDialog.getText(self, "Find", "Find:")

        if not ok:
            return

        # Get the QTextCursor and QTextDocument
        cursor = self.textEdit.textCursor()
        document = self.textEdit.document()

        # Set the search options
        options = QTextDocument.FindFlags()
        options |= QTextDocument.FindCaseSensitively
        options |= QTextDocument.FindWholeWords  # Add this line

        # Search for the text
        count = 0
        #while True:
        cursor = document.find(searchString, cursor, options)
        #if cursor is None:
        #   break

        count += 1

        # Move the cursor to the beginning of the match and select the text
        cursor.movePosition(QTextCursor.StartOfWord)
        char_after_word = document.characterAt(cursor.position())
        print(char_after_word)
        if searchString[0] != char_after_word:
           cursor.movePosition(QTextCursor.Left, QTextCursor.MoveAnchor, len(searchString))
        cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor)
        
        self.textEdit.setTextCursor(cursor)
        self.textEdit.setFocus()

        if count == 0:
            QMessageBox.information(self, "Find", "No match found.")
        #else:
        #    QMessageBox.information(self, "Find", f"{count} matches found.")
# Create the QApplication
app = QApplication([])
# Create the MainWindow
mainWindow = MainWindow()
# Run the event loop
app.exec_()

In case where you just pressed the contro+v to paste a block of codes and you want the cursor to go back to the start(0,0) of the QTextEdit widget, you may add a keypress event. Here is the method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    def onTextChanged(self):
        # Do something when the text changes
        global paste
        #print(paste)
        #pass
    
        if paste == 1:
            self.textEdit.moveCursor(QTextCursor.Start)
            paste = 0
    def keyPressEvent(self, event):
        global paste
        # If Ctrl+V is pressed, move the cursor to the beginning of the QTextEdit widget        
        if event.modifiers() == Qt.ControlModifier and event.key() == 16777249:
            self.textEdit.moveCursor(QTextCursor.Start)
            paste = 1
        # Call the parent class's keyPressEvent to handle other key events
        super().keyPressEvent(event)  

The keypress event will not be able to move the cursor to the start position so I added another method ontextchanged to handle the cursor position and I used global variable paste to store the result in keypressevent.