Skip to content

Commit

Permalink
Merge pull request #20 from mydroidandi/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
estebanways authored Jan 17, 2024
2 parents dbd3004 + cb18b04 commit 45d4dd2
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 60 deletions.
128 changes: 68 additions & 60 deletions commbase_tts_pyttsx3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
################################################################################
# commbase_tts_pyttsx3.py #
# #
# Conversational AI Assistant and AI Hub for Computers and Droids #
# Command-line application that transforms written text into spoken words #
# #
# Change History #
# 06/10/2023 Esteban Herrera Original code. #
Expand Down Expand Up @@ -36,77 +36,85 @@

# Requirements
import argparse
import fileinput
import os.path
import pyttsx3
import sys


class TextToSpeech:
def __init__(self):
self.engine = None
self.voices = None
def __init__(self):
self.engine = None
self.voices = None

def set_up_text_to_speech(self, rate, voice_index):
"""
Initializes the text-to-speech engine, retrieves the available voices, and
sets properties for the engine's rate and voice.
"""
self.engine = pyttsx3.init()
self.voices = self.engine.getProperty('voices')
self.engine.setProperty('rate', rate)
self.engine.setProperty('voice', self.voices[voice_index].id)
def set_up_text_to_speech(self, rate, voice_index):
"""
Initializes the text-to-speech engine, retrieves the available voices,
and sets properties for the engine's rate and voice.
"""
self.engine = pyttsx3.init()
self.voices = self.engine.getProperty("voices")
self.engine.setProperty("rate", rate)
self.engine.setProperty("voice", self.voices[voice_index].id)

def talk(self, text):
"""
Sets up the text-to-speech engine, utilizes it to speak out the provided
text, and ensures the speech synthesis is completed before proceeding.
"""
self.engine.say(text)
self.engine.runAndWait()
def talk(self, text):
"""
Sets up the text-to-speech engine, utilizes it to speak out the provided
text, and ensures the speech synthesis is completed before proceeding.
"""
if not text:
print("No input text provided.")
self.engine.say(text)
self.engine.runAndWait()

def read_file(self, file_path):
"""
Attempts to read the contents of the specified file, handles potential
errors such as file not found or IO errors, and returns the file's content
if it is successfully read.
"""
try:
with open(file_path, 'r') as file:
content = file.read()
return content
except FileNotFoundError:
print("File not found!")
return None
except IOError:
print("An error occurred while reading the file!")
return None
def read_file(self, file_path):
"""
Attempts to read the contents of the specified file, handles potential
errors such as file not found or IO errors, and returns the file's
content if it is successfully read.
"""
try:
with open(file_path, "r") as file:
content = file.read()
return content
except FileNotFoundError:
print("File not found!")
raise # Raise the FileNotFoundError here
except IOError:
print("An error occurred while reading the file!")
raise # Raise the IOError here

def main(self):
"""
Serves as the entry point of the program.
This method is responsible for reading input text from either a file or
standard input, storing it in the file_content variable, and then passing it
to the talk() method for speech synthesis. If no input text is provided, it
displays an appropriate message.
"""
parser = argparse.ArgumentParser(description='Text-to-Speech with pyttsx3')
parser.add_argument('--rate', type=int, default=145, help='Voice speed', metavar='RATE')
parser.add_argument('--voice-index', type=int, default=0, help='Index of the voice to use', metavar='INDEX')
args = parser.parse_args()
def main(self):
"""
Serves as the entry point of the program.
This method is responsible for reading input text from either a file or
standard input, storing it in the file_content variable, and then
passing it to the talk() method for speech synthesis. If no input text
is provided, it displays an appropriate message.
"""
parser = argparse.ArgumentParser(description="Text-to-Speech with pyttsx3")
parser.add_argument(
"--rate", type=int, default=145, help="Voice speed", metavar="RATE"
)
parser.add_argument(
"--voice-index",
type=int,
default=0,
help="Index of the voice to use",
metavar="INDEX",
)
args = parser.parse_args()

self.set_up_text_to_speech(args.rate, args.voice_index)
self.set_up_text_to_speech(args.rate, args.voice_index)

file_content = ''
for line in sys.stdin:
file_content += line
file_content = ""
for line in sys.stdin:
file_content += line

if file_content:
self.talk(file_content)
else:
print("No input text provided.")
if file_content:
self.talk(file_content)
else:
print("No input text provided.")


if __name__ == '__main__':
if __name__ == "__main__":
tts = TextToSpeech()
tts.main()

102 changes: 102 additions & 0 deletions test_commbase_tts_pyttsx3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python
################################################################################
# commbase_tts_pyttsx3.py #
# #
# Command-line application that transforms written text into spoken words #
# #
# Change History #
# 10/06/2023 Esteban Herrera Original code. #
# Add new history entries as needed. #
# #
# #
################################################################################
################################################################################
################################################################################
# #
# Copyright (c) 2022-present Esteban Herrera C. #
# [email protected] #
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #

# test_commbase_tts_pyttsx3.py
# Test file for the script commbase_tts_pyttsx3.py

import os
import pytest
import tempfile
from commbase_tts_pyttsx3 import TextToSpeech


# Create a fixture to set up the TextToSpeech object
@pytest.fixture
def text_to_speech_instance():
"""
Fixture to create an instance of the TextToSpeech class for testing.
"""
tts = TextToSpeech()
return tts


def test_read_file_not_found(text_to_speech_instance):
"""
Test whether the read_file method raises FileNotFoundError for a non-
existent file.
"""
with pytest.raises(FileNotFoundError):
text_to_speech_instance.read_file("non_existent_file.txt")


def test_read_file_io_error(text_to_speech_instance):
"""
Test whether the read_file method raises IOError for an unreadable file.
"""
with pytest.raises(IOError):
text_to_speech_instance.read_file("/root/unreadable_file.txt")


def test_read_file_success(text_to_speech_instance):
"""
Test whether the read_file method successfully reads the content of an
existing file.
"""
# Create a temporary file with the desired content
with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_file:
temp_file.write("Hello, World!")

try:
# Get the temporary file path and pass it to the read_file method
temp_file_path = temp_file.name
content = text_to_speech_instance.read_file(temp_file_path)
assert content == "Hello, World!"
finally:
# Clean up by deleting the temporary file
if temp_file_path:
os.remove(temp_file_path)


def test_set_up_text_to_speech(text_to_speech_instance):
"""Test the set_up_text_to_speech method."""
text_to_speech_instance.set_up_text_to_speech(rate=100, voice_index=1)
assert text_to_speech_instance.engine is not None
assert text_to_speech_instance.voices is not None


def test_talk_with_input(text_to_speech_instance, capsys):
"""Test the talk method with input."""
text_to_speech_instance.set_up_text_to_speech(rate=100, voice_index=1)
text_to_speech_instance.talk("Hello, this is a test input.")

captured = capsys.readouterr()
assert captured.out.strip() == ""

0 comments on commit 45d4dd2

Please sign in to comment.