Φωνητικός βοηθός (λέμε τώρα!)

...τα πάντα για το open source στον χώρο των gadgets, συζητήσεις, εργαλεία, open hardware, οδηγοί κ.ά.

Συντονιστής: adem1

Φωνητικός βοηθός (λέμε τώρα!)

Δημοσίευσηαπό malos » 21 Μαρ 2024, 23:43

Θέλησα να κάνω κάτι σαν βοηθό στο λειτουργικό μου.

(Επειδή ζηλεύω την Αλέξα και το γκουγκλ ασίσταντ - επειδή είμαι καμένος - επειδή είναι το μεράκι μου - πάντως σε καμία περίπτωση αυτό που λένε οι κανονικοί άνθρωποι "Χρειάζομαι... αυτό", "Είναι ανάγκη να έχω ένα εργαλείο για..." κλπ κλπ.
Καμία σχέση. Το χόμπι μου είναι. Οπότε δεν το προτείνω σοβαρά (κι έτσι θα γλιτώσω την κριτική χα! :clap: )

Έχω δει ότι όταν δημιουργούν πρότζεκτς οι προτζεκτοποιοί ( :P ) βάζουν καμιά δεκαριά φακέλους και καμιά πενηνταριά αρχεία, άλλα ρυθμίσεων, άλλα σημειώσεων, άλλα βιβλιοθήκες κλπ κλπ. Εδώ δεν έχει τέτοια. Εδώ έχει πλεμπέϊκες καταστάσεις. Ένας κώδικας όλο κι όλο περίπου 400 γραμμές κι αυτό είναι όλο!

Με παρακίνησε ο φίλος και αγαπημένος χρήστης, σε συζύητηση σχετικά με τον εκτυπωτή και σε αναφορά για φωνητική εντολή εκτύπωσης.
Maras έγραψε:Αναμένουμε τον κώδικα για την φωνητική εντολή!


Αυτό λοιπόν είναι ένα μόνο κομμάτι του όλου κώδικα και πιάνει τις γραμμές 298-310 και 375-381.

Όλος ο υπόλοιπος κώδικας κάνει διαφορετικές δουλίτσες. Αυτός είναι

Κώδικας: Επιλογή όλων

import mimetypes
import datetime
import subprocess
from fuzzywuzzy import process
import sys
import re
import os
import json
import sounddevice
import speech_recognition as sr
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QTextEdit, QPushButton, QGraphicsOpacityEffect, QMessageBox, QScrollArea, QFrame, QHBoxLayout
from PyQt5.QtCore import Qt, QTimer, QEvent, QUrl, pyqtSignal
from PyQt5.QtGui import QIcon, QPixmap, QKeyEvent, QMovie, QFont, QDesktopServices, QGuiApplication, QColor
from unidecode import unidecode
import unicodedata

class ResultsWindow(QWidget):  #Παράθυρο που ανοίγει αφού του πω την εντολή δείξε" και αφορά το να ψάξει και βρει αρχεία στον προσωπικό μου φάκελο και στους υποφακέςους του
    def __init__(self, results):
        super().__init__()
        self.setWindowTitle("Αποτελέσματα αναζήτησης")
        self.setGeometry(80, 450, 1200, 410)
        self.set_background_color("#D9B47B")  # Ορίζουμε το χρώμα του φόντου

        layout = QVBoxLayout()
        self.setLayout(layout)
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        layout.addWidget(scroll_area)
        content = QWidget()
        scroll_area.setWidget(content)
        content_layout = QVBoxLayout(content)
       
        #Στα αποτελέσματα (ονόματα και διαδρομές αρχείων) που θα μου βγάλει αυτό το παράθυρο, να κοτσάρει δίπλα κι ένα εικονίδιο ανάλογα τον τύπο αρχείου
        file_icons = {
            ".pdf": "./script-icons/pdf.png",
            ".txt": "./script-icons/text_icon.png",
            ".html": "./script-icons/html_icon.png",
            ".mp3": "./script-icons/mp3.png",
            ".mp4": "./script-icons/mp4.png",
            ".docx": "./script-icons/docx.png",
            ".doc": "./script-icons/doc.png",
            ".jpg": "./script-icons/other.png",
            ".odt": "./script-icons/odt.png",
            ".3gp": "./script-icons/other.png",
            ".avi": "./script-icons/other.png",
            ".mov": "./script-icons/other.png",
            ".wav": "./script-icons/other.png",
            ".ogg": "./script-icons/other.png",
            ".exe": "./script-icons/other.png",
            ".xml": "./script-icons/xml.png",
            ".html": "./script-icons/html.jpg",
            ".png": "./script-icons/png.png"
        }
        for result in results:
            file_extension = os.path.splitext(result)[1]
            if file_extension in file_icons:
                icon_label = QLabel()
                icon_label.setPixmap(QPixmap(file_icons[file_extension]))

                label = ClickableLabel(result)
                label.setFont(QFont("FreeSans", 14, QFont.Bold))
                label.setTextInteractionFlags(Qt.TextBrowserInteraction)
                label.setOpenExternalLinks(False)
                label.setOpenExternalLinks(True)
                label.clicked.connect(lambda link=result: self.open_file(link))
                label.setStyleSheet("color: black;")  # Ορίζουμε το χρώμα του κειμένου σε μαύρο

                label_layout = QHBoxLayout()  # Χρησιμοποιούμε οριζόντιο layout
                label_layout.addWidget(label)  # Προσθέτουμε πρώτα το label με το όνομα του αρχείου
                label_layout.addWidget(icon_label)  # Στη συνέχεια προσθέτουμε το εικονίδιο
                content_layout.addLayout(label_layout)  # Προσθέτουμε το οριζόντιο layout στον κατακόρυφο layout



    def set_background_color(self, color):
        self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), QColor(color))
        self.setPalette(p)

    def open_file(self, filepath):
        mime_type, _ = mimetypes.guess_type(filepath)
        if mime_type:
            if mime_type.startswith('text'):
                os.system(f"xdg-open {filepath}")  # Ανοίξτε το αρχείο με το προεπιλεγμένο κειμενογράφο
            else:
                subprocess.run(["xdg-open", filepath])  # Ανοίξτε το αρχείο με το προεπιλεγμένο πρόγραμμα
        else:
            os.system(f'notify-send "Τύπος αρχείου μη υποστηριζόμενο" ')

#Κλάση στο Παράθυρο αποτελεσμάτων που λέγαμε προηγουμένως για να κάνεις κλικ τα αποτελέσματα και να ανοίγουν στο αντίστοιχο πρόγραμμα
class ClickableLabel(QLabel):
    clicked = pyqtSignal()

    def __init__(self, text):
        super().__init__(text)

    def mousePressEvent(self, event):
        self.clicked.emit()

    def enterEvent(self, event):
        if self.underMouse():
            self.setCursor(Qt.PointingHandCursor)

    def leaveEvent(self, event):
        self.unsetCursor()


class Separator(QFrame):
    def __init__(self):
        super().__init__()
        self.setFrameShape(QFrame.HLine)
        self.setFrameShadow(QFrame.Sunken)

#Κλάση για την εμφάνιση του παραθύρου και τις λειτουργίες του. Ο Βασιλιάς του κιτς λέμε.
class VasikoWindow(QWidget):
    #Ενέργειες. Αρχίζουν με μικρό γράμμα γιατί όταν εκφωνείς κείμενο και σε ακοιύει στο αποδίδει με μικρά. Έχω να προσθέσψ κι άλλες. Ενδεικτικά μόνο έβαλα αυτές και λειτουργούν άψογα. Αυτά: "αναγνώστης", "συνδυασμοί", "διαδικοί αριθμοί" είναι κώδικες επίσης python και ανοίγουν εφαρμογάκια για μετατροπή δεκαδικών σε διαδικό, ανάγνωση κειμένου με τη φωνή της google, συνδυασμοί ν αντικειμένων από τα κ. Θα βάλω τους κώδικες σε άλλα νήματα.
    actions = {
        "firefox": "firefox",
        "ubuntu forum": "firefox https://forum.ubuntu-gr.org/",
        "καιρός σαλαμίνα": "firefox https://www.meteo.gr/cf.cfm?city_id=60",
        "καιρός αθήνα": "firefox https://www.meteo.gr/cf.cfm",
        "καιρός πειραιάς": "firefox https://www.meteo.gr/cf.cfm?city_id=61",
        "ποσειδώνας": "firefox https://poseidon.hcmr.gr/el/map?model=meteo&param=cloud&date=2024-02-26T00:00:00Z&coords=38,24,5",
        "ποσειδών": "firefox https://poseidon.hcmr.gr/el/map?model=meteo&param=cloud&date=2024-02-26T00:00:00Z&coords=38,24,5",
        "zoom": "/home/family/scripts/pamp",
        "ζουμ": "/home/family/scripts/pamp",
        "ζουν": "/home/family/scripts/pamp",
        "zum": "/home/family/scripts/pamp",
        "ελαχιστοποίηση": "/home/family/scripts/pomp",
        "κανονική οθόνη": "/home/family/scripts/pimp",
        "αρνητικό": "/home/family/scripts/roc",
        "άναψε κουζίνα": "/home/family/scripts/routines/kitchenon",
        "κλείσε κουζίνα": "/home/family/scripts/routines/kitchenoff",
        "θερμοσίφωνας": "/home/family/scripts/routines/thermos-on",
        "κλείσε θερμοσίφωνα": "/home/family/scripts/routines/thermos-off",
        "εορτολόγιο": "/home/family/eortologio/giorti",
        "το κινητό μου": "/home/family/scripts/scrcpy/for-scrcpy",
        "δείξε το κινητό μου": "/home/family/scripts/scrcpy/for-scrcpy",
        "κινητό": "/home/family/scripts/scrcpy/for-scrcpy",
        "viber": "/opt/viber/Viber",
        "αναγνώστης": "/home/family/scripts/reader/Ανάγνωση",
        "αναγνώστρια": "/home/family/scripts/reader/Ανάγνωση",
        "ανάγνωση": "/home/family/scripts/reader/Ανάγνωση",
        "συνδυασμοί": "/home/family/scripts/combinations/compan.py",
        "διαδικός": "/home/family/scripts/convert-num/metatropi9.py",
        "διαδικός αριθμός": "/home/family/scripts/convert-num/metatropi9.py",
        "διαδικτή αριθμοί": "/home/family/scripts/convert-num/metatropi9.py",
        "διαδικοί αριθμοί": "/home/family/scripts/convert-num/metatropi9.py",
        "κάμερα": "mplayer tv:// -vf mirror",
        "spotify": "spotify",
        "caja": "caja",
        "κάτσε": "caja",
        "προσωπικός φάκελος": "caja /home/family",
        "λευτέρης": "caja /home/family/Επιφάνεια\ εργασίας/ΛΕΥΤΕΡΗΣ",
        "εικόνες": "caja /home/family/Εικόνες",
        "σελήνη": "caja /media/SELINI",
        "σε λίγη": "caja /media/SELINI",
        "τον πούλο": "shutdown now"
    }

    def __init__(self):
        super().__init__()
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setGeometry(1655, 350, 265, 115)
        self.setFixedSize(265, 115)
        self.setWindowFlag(Qt.WindowStaysOnTopHint)
        self.setStyleSheet("background-color: #040102;")
        self.recognizer = sr.Recognizer()
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        self.label_animation = QLabel(self)
        self.label_animation.setGeometry(0, 0, 265, 115) #Είπαμε το καρακιτσαριό του κερατά. Άμ δεν έχει ένα gifάκι για φόντο δεν κάνουμε δουλειά
        self.movie = QMovie("gifs/ink.gif")              #Σε υποφάκελο μέσα στο φάκελο που βρίσκεται ο κώδικας έχω διάφορα gifάκια
        self.label_animation.setMovie(self.movie)       
        self.movie.start()
        self.text_input = QTextEdit(self)
        font = QFont("FreeSans", 14, QFont.Bold)
        self.text_input.setFont(font)
        self.text_input.setStyleSheet("border: 3px double #FF00FD; background-color: #000000; color: yellow; font-weight: bold;")
        self.text_input.setFixedHeight(115)
        self.text_input.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        vbox.addWidget(self.text_input, stretch=5)
        self.start_recognition_button = QPushButton(self)
        pixmap = QPixmap("png/mic4.png") #εικονιδιάκι μικρόφωνο. Το πατάς και μιλάς.
        icon = QIcon(pixmap)
        self.start_recognition_button.setIcon(icon)
        self.start_recognition_button.setIconSize(pixmap.rect().size())
        self.start_recognition_button.setMaximumSize(40, 40)
        self.start_recognition_button.move(self.start_recognition_button.x() - 5, self.start_recognition_button.y() - 5)
        self.start_recognition_button.clicked.connect(self.start_recognition)

        self.history_file = "history-special.json" #Κρατάμε και ιστορικό εντολών άμα λάχει, έτσι για να γουστάρουμε
        self.load_history()

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_animation)
        self.timer.start(50)
        self.start_recognition_button.move(10, 70)
        self.opacity_effect = QGraphicsOpacityEffect(self.text_input)
        self.text_input.setGraphicsEffect(self.opacity_effect)
        self.opacity_effect.setOpacity(0.7)
        self.text_input.installEventFilter(self)

    #Είπαμε το καρακιτσαριό του κερατά. Άμ δεν έχει ένα gifάκι για φόντο δεν κάνουμε δουλειά
    def update_animation(self):
        if not self.movie.currentPixmap().isNull():
            self.repaint()

    def start_recognition(self): #και ξεκινάμε την εκφώνηση των εντολών.
        with sr.Microphone() as source:
            print("Ακούει...")
            audio = self.recognizer.listen(source, timeout=5, phrase_time_limit=6)

        try:
            recognized_text = self.recognizer.recognize_google(audio, language="el-GR")
            self.text_input.setPlainText(recognized_text)
            self.add_to_history(recognized_text)
            self.execute_command(recognized_text.lower())
        except sr.UnknownValueError:
            os.system(f'notify-send "η φωνητική αναγνώριση google δεν καταλαβαίνει τον ήχο" ')
            print("η φωνητική αναγνώριση google δεν καταλαβαίνει τον ήχο")
        except sr.RequestError as e:
            os.system(f'notify-send "Συνέβη ένα λάθος κατά τη φωνητική αναγνώριση" "{e}"')
            print(f"Συνέβη ένα λάθος κατά τη φωνητική αναγνώριση; {e}")

    def load_history(self): #Το ιστορικό εντολών μας. Το κουλαντρίζεις με τα βελάκια του πληκτρολογίου άνω και κάτω σαν το history του τερματικού
        try:
            with open(self.history_file, "r") as file:
                self.history = json.load(file)
        except FileNotFoundError:
            self.history = []
        self.history_index = len(self.history)

    def save_history(self):
        with open(self.history_file, "w") as json_file: #και σε Τζέσον
            json.dump(self.history, json_file)

        with open("history-special.txt", "w") as txt_file:#και σε τιεξτί
            for item in self.history:
                txt_file.write("%s\n" % item)

    def add_to_history(self, text):
        self.history.append(text)
        self.save_history()

    def retrieve_from_history(self, forward=True):
        if forward:
            if self.history_index < len(self.history) - 1:
                self.history_index += 1
        else:
            if self.history_index > 0:
                self.history_index -= 1

        if 0 <= self.history_index < len(self.history):
            self.text_input.setPlainText(self.history[self.history_index])

    def eventFilter(self, obj, event):
        if obj is self.text_input and event.type() == event.KeyPress:#Τα βελάκια που λέγαμε
            if event.key() == Qt.Key_Up:
                self.retrieve_from_history(forward=False)
                return False
            elif event.key() == Qt.Key_Down:
                self.retrieve_from_history(forward=True)
                return False
        return super().eventFilter(obj, event)

    def execute_command(self, command):
        if command:
            if command.startswith("ψάξε τοπικά") or command.startswith("δείξε") or command.startswith("μείξε") or command.startswith("λήξη") or command.startswith("ρίξε") or command.startswith("ληξε"): #Καμιά φορά δεςν ακούει καλά και γι αυτό του έβαλα κι άλλες πιθανές λέξεις που θα πιάσει
                query = command.split(" ", 2)[-1]  # Αφαιρούμε τις πρώτες δύο λέξεις
                period = None
                if "χθες" in command:                                          #ΠΡΟΣΠΑΘΕΙΑ ΝΑ ΚΑΝΕΙ
                    period = "yesterday"
                elif "πριν δυο μέρες" in command:                              #ΑΝΑΖΗΤΗΣΗ
                    period = "two days ago"
                elif "προηγούμενη εβδομάδα" in command:                        #ΜΕ ΚΡΙΤΗΡΙΟ ΤΙΣ ΗΜΕΡΟΜΗΝΙΕΣ
                    period = "last week"
                                                                               #ΑΠΟΘΗΚΕΥΣΗΣ
                search_results = self.search_files(query, period)
                if search_results:                                             #ΤΖΙΦΟΣ! ΑΥΤΟ ΔΕΝ ΜΟΥ ΔΟΥΛΕΨΕ. ΔΥΣΤΥΧΩΣ!
                    print("Αποτελέσματα αναζήτησης:")
                    for result in search_results:
                        print(result)
                    self.show_results_window(search_results)  # Εμφάνισε όλα τα αποτελέσματα μαζί
                else:
                    print("Δεν βρέθηκαν αρχεία που να ταιριάζουν στην αναζήτηση.")

            elif command.startswith("ψάξε") or command.startswith("δείξε"):     #Εδώ ανοίγει ο firefox και κάνει αναζήτηση google
                search_query = command.split(" ", 1)[1]  # Αφαιρούμε τη λέξη "ψάξε" ή "δείξε" και το κενό μετά από αυτήν
                search_url = f"https://www.google.com/search?q={search_query}"
                os.system(f"firefox \"{search_url}\"")
                print(f"Αναζήτηση στο Google για: {search_query}")

            elif command in self.actions:
                os.system(self.actions[command])
                print(f"Εκτέλεση εντολής: {self.actions[command]}")

            elif command.startswith(("εκτύπωσε", "τύπωσε", "εκτύπωση")):    #Εδώ τυπώνει αυτό που υποθέτει ότι του είπες. Ψάχνει μόνο σε ένα φάκελο.
                file_to_print = next((keyword for keyword in ["εκτύπωσε", "τύπωσε", "εκτύπωση"] if keyword in command), None)
                file_to_print = command.split(file_to_print, 1)[-1].strip()  # Παίρνουμε το όνομα του αρχείου που θέλει να εκτυπώσει ο χρήστη
                file_path = self.find_matching_file(file_to_print)
                if file_path:
                    os.system(f"lp {file_path}")  # Εκτελούμε την εντολή lp με το συγκεκριμένο αρχείο
                    print(f'Εκτύπωση αρχείου: "{file_path}" ')
                else:
                    print("Δεν βρέθηκε αρχείο προς εκτύπωση.")

            else:
                os.system(f'notify-send "Η εντολή δεν αναγνωρίζεται" ')
                print("Η εντολή δεν αναγνωρίζεται.")



    def search_files(self, query, period=None): #Εδώ ψάχνει αρχεία που του ζητήσαμε με την εντολή δείξε
        query = unidecode(query).lower()
        results = []

        # Αναζήτηση σε ολόκληρο τον φάκελο /home/family
        for root, dirs, files in os.walk("/home/family"):
            for file in files:
                file_name = unidecode(file).lower()
                if query in file_name:
                    if period:
                        today = datetime.date.today()
                        if period == "χθες":
                            search_date = today - datetime.timedelta(days=1)
                        elif period == "προχθές":
                            search_date = today - datetime.timedelta(days=2)
                        elif period == "προηγούμενη εβδομάδα":
                            search_date = today - datetime.timedelta(weeks=1)
                        else:
                            raise ValueError("Μη έγκυρη περίοδος αναζήτησης")
                       
                        # Ελέγχουμε αν το αρχείο ανήκει στην επιθυμητή περίοδο αλλά είπαμε...ΤΖΙΦΟΣ!
                        file_path = os.path.join(root, file)
                        file_creation_date = datetime.date.fromtimestamp(os.path.getctime(file_path))
                        if file_creation_date == search_date:
                            results.append(file_path)
                    else:
                        results.append(os.path.join(root, file))

        # Αναζήτηση στον φάκελο που έχω για αποθήκη. Είναι ntfs για να τον βλέπουν και τα windows.
        for root, dirs, files in os.walk("/media/family/SELINI"):
            for file in files:
                file_name = unidecode(file).lower()
                if query in file_name:
                    if period:
                        today = datetime.date.today()
                        if period == "σήμερα":
                            search_date = today - datetime.timedelta(days=0)
                        elif period == "χθες":
                            search_date = today - datetime.timedelta(days=1)
                        elif period == "προχθές":
                            search_date = today - datetime.timedelta(days=2)
                        elif period == "εβδομάδα":
                            search_date = today - datetime.timedelta(weeks=1)
                        else:
                            raise ValueError("Μη έγκυρη περίοδος αναζήτησης")
                       
                        # Ελέγχουμε αν το αρχείο ανήκει στην επιθυμητή περίοδο
                        file_path = os.path.join(root, file)
                        file_creation_date = datetime.date.fromtimestamp(os.path.getctime(file_path))
                        if file_creation_date == search_date:
                            results.append(file_path)
                    else:
                        results.append(os.path.join(root, file))

        return results

    def show_results_window(self, results):
        self.results_window = ResultsWindow(results)
        self.results_window.show()


    def find_matching_file(self, file_name):
        print("Αναζήτηση αρχείου:", file_name)
        printer_directory = "/home/family/zzzz-print"  # Ο φάκελος με τα αρχεία που μπορούν να εκτυπωθούν
        files = os.listdir(printer_directory)
        match, score = process.extractOne(file_name, files)
        print("Συμφωνία:", match, "Ποσοστό:", score)
        return os.path.join(printer_directory, match)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = VasikoWindow()
    window.show()
    sys.exit(app.exec_())

Επεξεργαστής: AMD Ryzen 9 5900x
Μνήμη Gskill 16gb (2X8gb), 3200 mh, CL 14
Μητρική: Asrock X570 phantom gaming X
Τροφοδοτικό: Corsair 850 platinum
Δίσκος: SSD Corsair MP600 (1 TB)
Άβαταρ μέλους
malos
saintTUX
saintTUX
 
Δημοσιεύσεις: 1230
Εγγραφή: 02 Νοέμ 2008, 12:00
Εκτύπωση

Re: Φωνητικός βοηθός (λέμε τώρα!)

Δημοσίευσηαπό malos » 22 Μαρ 2024, 13:25

και να πως δουλεύει. (ΠΡΟΣΟΧΗ χάλια βίντεο :eh: )


https://youtu.be/F4Cgdg5eiK8

Η λέξη που έψαχνα είναι "wake word". Όταν το φτιάξω με wake word και να μη χρειάζεται κανένα κλικ οπότε να μπορώ να το λέω από μακριά, θα το λέω ¨Σουλτάνα". Εναλλακτικά "Φανούρη".
Επεξεργαστής: AMD Ryzen 9 5900x
Μνήμη Gskill 16gb (2X8gb), 3200 mh, CL 14
Μητρική: Asrock X570 phantom gaming X
Τροφοδοτικό: Corsair 850 platinum
Δίσκος: SSD Corsair MP600 (1 TB)
Άβαταρ μέλους
malos
saintTUX
saintTUX
 
Δημοσιεύσεις: 1230
Εγγραφή: 02 Νοέμ 2008, 12:00
Εκτύπωση

Re: Φωνητικός βοηθός (λέμε τώρα!)

Δημοσίευσηαπό Maras » 22 Μαρ 2024, 13:48

Ωραίος, θα τον τσεκάρω όταν βρω χρόνο!
Μήπως, να φτιάξεις κάτι τέτοιο?
Κώδικας: Επιλογή όλων
https://www.youtube.com/watch?v=bO-DWWFolPw
“Long is the way, and hard, that out of hell leads up to light.”
Άβαταρ μέλους
Maras
saintTUX
saintTUX
 
Δημοσιεύσεις: 1465
Εγγραφή: 25 Ιούλ 2017, 12:49
Εκτύπωση

Re: Φωνητικός βοηθός (λέμε τώρα!)

Δημοσίευσηαπό malos » 22 Μαρ 2024, 14:11

Μη με σκανδαλίζεις :D

Ωραίος ο τύπος. Να κάτι τέτοιο θέλω να είμαι. :roll:
Επεξεργαστής: AMD Ryzen 9 5900x
Μνήμη Gskill 16gb (2X8gb), 3200 mh, CL 14
Μητρική: Asrock X570 phantom gaming X
Τροφοδοτικό: Corsair 850 platinum
Δίσκος: SSD Corsair MP600 (1 TB)
Άβαταρ μέλους
malos
saintTUX
saintTUX
 
Δημοσιεύσεις: 1230
Εγγραφή: 02 Νοέμ 2008, 12:00
Εκτύπωση

Re: Φωνητικός βοηθός (λέμε τώρα!)

Δημοσίευσηαπό malos » 28 Μαρ 2024, 00:43

Διόρθωσα την συνάρτηση search_files.
Κώδικας: Επιλογή όλων
    def search_files(self, query, period=None):
        query = unidecode(query).lower()
        results = []

        try:
            if period:
                find_command_family = f"find /home/family -type f -not -path '*/\.*' -mtime {period} -exec stat -c '%y %n' {{}} +"
                find_command_selini = f"find /media/SELINI -type f -not -path '*/\.*' -mtime {period} -exec stat -c '%y %n' {{}} +"
            else:
                find_command_family = "find /home/family -type f -not -path '*/\.*' -exec stat -c '%y %n' {{}} +"
                find_command_selini = "find /media/SELINI -type f -not -path '*/\.*' -exec stat -c '%y %n' {{}} +"

            result_family = subprocess.run(find_command_family, shell=True, capture_output=True, text=True)
            if result_family.returncode == 0:
                results.extend(result_family.stdout.split('\n'))

            result_selini = subprocess.run(find_command_selini, shell=True, capture_output=True, text=True)
            if result_selini.returncode == 0:
                results.extend(result_selini.stdout.split('\n'))
        except Exception as e:
            print(f"An error occurred while executing find command: {e}")

        # Αναζήτηση με βάση το όνομα του αρχείου στον φάκελο family
        for root, dirs, files in os.walk("/home/family"):
            for file in files:
                file_name = unidecode(file).lower()
                if query in file_name:
                    file_path = os.path.join(root, file)
                    results.append(file_path)

        # Αναζήτηση με βάση το όνομα του αρχείου στον φάκελο family
        for root, dirs, files in os.walk("/media/SELINI"):
            for file in files:
                file_name = unidecode(file).lower()
                if query in file_name:
                    file_path = os.path.join(root, file)
                    results.append(file_path)
        return results

    def show_results_window(self, results):
        self.results_window = ResultsWindow(results)
        self.results_window.show()



Πλέον εμφανίζει αρχεία που τροποποιήθηκαν σήμερα, ή χθες, ή προχθές, ή τριήμερο ... μέχρι και δέκα μέρες.

Κώδικας: Επιλογή όλων
    def execute_command(self, command):
        if command:
            if command.startswith("ψάξε τοπικά") or command.startswith("δείξε") or command.startswith("μείξε") or command.startswith("λήξη") or command.startswith("ρίξε") or command.startswith("ληξε"):
                query = command.split(" ", 2)[-1]
                period = None
                if "σήμερα" in command:               
                    period = "0"
                elif "χθες" in command:
                    period = "1"
                elif "χτες" in command:
                    period = "1"
                elif "προχθές" in command:
                    period = "2"
                elif "προχτές" in command:
                    period = "2"
                elif "τριήμερο" in command:
                    period = "3"
                elif "τετραήμερο" in command:
                    period = "4"
                elif "πενθήμερο" in command:
                    period = "5"
                elif "πενταήμερο" in command:
                    period = "5"
                elif "εξαήμερο" in command:
                    period = "6"
                elif "εβδομάδα" in command:
                    period = "7"
                elif "βδομάδα" in command:
                    period = "7"
                elif "οκταήμερο" in command:
                    period = "8"
                elif "οxταήμερο" in command:
                    period = "8"
                elif "8ήμερο" in command:
                    period = "8"
                elif "9ήμερο" in command:
                    period = "9"
                elif "9 ήμερο" in command:
                    period = "9"
                elif "ένα ήμερο" in command:
                    period = "9"
                elif "δεκαήμερο" in command:
                    period = "10"


                search_results = self.search_files(query, period)
                if search_results:
                    print("Αποτελέσματα αναζήτησης:")
                    for result in search_results:
                        print(result)
                    self.show_results_window(search_results)
                else:
                    print("Δεν βρέθηκαν αρχεία που να ταιριάζουν στην αναζήτηση.")
                    os.system('notify-send "Δεν βρέθηκαν αρχεία που να ταιριάζουν στην αναζήτηση." --icon=/home/family/Εικόνες/χρήση/icons/desperate4.png')



Εικόνα


Γενικά στην αναζήτηση πετάει. Μου είναι σίγουρα πρωτόγωρο το να βρίσκω ´τοσο γρήγορα ένα αρχείο. Είτε τοιυ βάζεις ως κριτήριο το όνομα έιτε του βάζεις ημέρα.
Βέβαια μόνο για 10 μέρες έχω κάνει. Θα το επεικτείνω κάποια στιγμή


Επίσης του πρόσθεσα δυνατότητα να στέλνει sms αμέσως με την εντολή
"στείλε μύνημα στην μαρία καλημέρα τι κάνεις"

Φυσικά ερωτηματικό δεν μπορώ να το κάνω να βάζει στο τέλος. Ούτε να αρχίζει με κεφαλαίο. Αλλά και πάλι είναι λειτουργικό.
Το sms το στέλνει μέ το kdeconnect-cli.

Τα κομμάτια που πρόσθεσα

Κώδικας: Επιλογή όλων
    def execute_command(self, command):
        if command:   

.........................................................................................................................................
.........................................................................................................................................
υπόλοιπες γραμμές για τις λειτουργίες της αναζήτησης και εμφάνισης τοπικών αρχείων
καθώς
αναζήτησης στο google με την εντολή "ψάξε"
.........................................................................................................................................
.........................................................................................................................................

           elif command.startswith(("στείλε μήνυμα στον", "στείλε μήνυμα στην")):
                parts = command.split("στον" if "στείλε μήνυμα στον" in command else "στην")
                if len(parts) == 2:
                    contact_name, message = parts[1].strip().split(" ", 1) if " " in parts[1].strip() else (parts[1].strip(), "")
                    contact_number = self.find_contact(contact_name)
                    if contact_number:
                        self.send_sms(contact_number, message)
                    else:
                        print("Η επαφή δε βρέθηκε στον κατάλογο.")
                        os.system('notify-send "Η επαφή δε βρέθηκε στον κατάλογο." --icon=/home/family/Εικόνες/χρήση/icons/desperate.png')
                else:
                    print("Σφάλμα: Παρακαλώ προσδιορίστε την επαφή και το μήνυμα.")
                    os.system('notify-send "Σφάλμα: Παρακαλώ προσδιορίστε την επαφή και το μήνυμα." --icon=/home/family/Εικόνες/χρήση/icons/oh.png')
            else:
                print("Η εντολή δεν αναγνωρίζεται.")
                os.system(f'notify-send "Η εντολή δεν αναγνωρίζεται" --icon=/home/family/Εικόνες/χρήση/icons/desperate2.png')

#Και έξω από την συνάρτηση execute-command

    def send_sms(self, contact_number, message):
        try:
            command = f"kdeconnect-cli -n 'Redmi Note 8 Pro' --send-sms '{message}' --destination '{contact_number}'"
            subprocess.run(command, shell=True)
            print(f"Το μήνυμα '{message}' στάλθηκε στον αριθμό {contact_number}.")
            os.system(f'notify-send "Το μήνυμα {message} στάλθηκε στον αριθμό {contact_number}." --icon=/home/family/Εικόνες/χρήση/icons/hey8.png')
        except Exception as e:
            print("Προέκυψε σφάλμα κατά την αποστολή SMS:", str(e))
            os.system('notify-send "Προέκυψε σφάλμα κατά την αποστολή SMS:" --icon=/home/family/Εικόνες/χρήση/icons/oh.png')

#και
    def find_contact(self, contact_name):
        contact_name_lower = contact_name.lower()
        try:
            with open("contacts.txt", "r") as file:
                for line in file:
                    name, number = line.strip().split()
                    if name.lower() == contact_name_lower:
                        return number  # Επιστρέφουμε τον αριθμό επαφής αν βρεθεί η επαφή
        except FileNotFoundError:
            print("Το αρχείο contacts.txt δεν βρέθηκε.")
        return None  # Επιστρέφουμε None αν δεν βρεθεί η επαφή
Επεξεργαστής: AMD Ryzen 9 5900x
Μνήμη Gskill 16gb (2X8gb), 3200 mh, CL 14
Μητρική: Asrock X570 phantom gaming X
Τροφοδοτικό: Corsair 850 platinum
Δίσκος: SSD Corsair MP600 (1 TB)
Άβαταρ μέλους
malos
saintTUX
saintTUX
 
Δημοσιεύσεις: 1230
Εγγραφή: 02 Νοέμ 2008, 12:00
Εκτύπωση


Επιστροφή στο Gadgets με Λογισμικό Ανοιχτού Κώδικα