<commit_before>#!/usr/bin/env python
# encoding: utf-8

"""Pyvona : an IVONA python library
Author: <NAME>
Contact Email: <EMAIL>
Note: Full operation of this library requires the requests and pygame libraries
"""

# TODO switch to urllib instead of requests
import base64
import datetime
import hashlib
import hmac
import json
import os
import sys
import uuid


try:
    import pygame
except ImportError:
    pygame_available = False
else:
    pygame_available = True

try:
    import requests
except ImportError:
    msg = 'The requests library is essential for Pyvonaoperation. '
    msg += 'Without it, Pyvona will not function correctly.'
    raise PyvonaException(msg)


_amazon_date_format = '%Y%m%dT%H%M%SZ'
_date_format = '%Y%m%d'


def create_voice(access_key, secret_key):
    """Creates and returns a voice object to interact with
    """
    return Voice(access_key, secret_key)


class Voice(object):
    """An object that contains all the required methods for interacting
    with the IVONA text-to-speech system
    """
    voice_name = None
    speech_rate = None
    sentence_break = None
    paragraph_break = None
    region_options = {
        'us-east': 'us-east-1',
        'us-west': 'us-west-2',
        'eu-west': 'eu-west-1',
    }
    access_key = ''
    secret_key = ''

    algorithm = 'AWS4-HMAC-SHA256'
    signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date'
    _region = None
    _host = None

    @property
    def region(self):
        return self._region

    @region.setter
    def region(self, region_name):
        self._region = self.region_options.get(region_name, 'us-east-1')
        self._host = 'tts.{}.ivonacloud.com'.format(self._region)

    def fetch_voice_ogg(self, text_to_speak, filename):
        """Fetch an ogg file for given text and save it to the given file name
        """
        filename += ".ogg" if not filename.endswith(".ogg") else ""
        r = self._send_amazon_auth_packet_v4('POST', 'tts', 'application/json', '/CreateSpeech', '',
                                             self._generate_payload(text_to_speak), self._region, self._host)
        with open(filename, 'wb') as f:
            f.write(r.content)

    def speak(self, text_to_speak):
        """Speak a given text
        """
        if not pygame_available:
            raise PyvonaException("Pygame not installed. Please install to use speech.")

        temp_fname = '{}.ogg'.format(str(uuid.uuid4()))
        self.fetch_voice_ogg(text_to_speak, temp_fname)
        channel = pygame.mixer.Channel(5)
        sound = pygame.mixer.Sound(temp_fname)
        channel.play(sound)
        while channel.get_busy():
            pass
        os.remove(os.getcwd()+'/'+temp_fname)

    def list_voices(self):<commit_msg>Added voice response error checking.<commit_after>#!/usr/bin/env python
# encoding: utf-8

"""Pyvona : an IVONA python library
Author: <NAME>
Contact Email: <EMAIL>
Note: Full operation of this library requires the requests and pygame libraries
"""

import base64
import datetime
import hashlib
import hmac
import json
import os
import sys
import uuid


try:
    import pygame
except ImportError:
    pygame_available = False
else:
    pygame_available = True

try:
    import requests
except ImportError:
    msg = 'The requests library is essential for Pyvona operation. '
    msg += 'Without it, Pyvona will not function correctly.'
    raise PyvonaException(msg)


_amazon_date_format = '%Y%m%dT%H%M%SZ'
_date_format = '%Y%m%d'


def create_voice(access_key, secret_key):
    """Creates and returns a voice object to interact with
    """
    return Voice(access_key, secret_key)


class Voice(object):
    """An object that contains all the required methods for interacting
    with the IVONA text-to-speech system
    """
    voice_name = None
    speech_rate = None
    sentence_break = None
    paragraph_break = None
    region_options = {
        'us-east': 'us-east-1',
        'us-west': 'us-west-2',
        'eu-west': 'eu-west-1',
    }
    access_key = None
    secret_key = None

    algorithm = 'AWS4-HMAC-SHA256'
    signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date'
    _region = None
    _host = None

    @property
    def region(self):
        return self._region

    @region.setter
    def region(self, region_name):
        self._region = self.region_options.get(region_name, 'us-east-1')
        self._host = 'tts.{}.ivonacloud.com'.format(self._region)

    def fetch_voice_ogg(self, text_to_speak, filename):
        """Fetch an ogg file for given text and save it to the given file name
        """
        filename += ".ogg" if not filename.endswith(".ogg") else ""
        r = self._send_amazon_auth_packet_v4('POST', 'tts', 'application/json', '/CreateSpeech', '',
                                             self._generate_payload(text_to_speak), self._region, self._host)
        if r.content.startswith('{'):
            raise PyvonaException('Error fetching voice: {}'.format(r.content))
        else:
            with open(filename, 'wb') as f:
                f.write(r.content)


    def speak(self, text_to_speak):
        """Speak a given text
        """
        if not pygame_available:
            raise PyvonaException("Pygame not installed. Please install to use speech.")

        temp_fname = '{}.ogg'.format(str(uuid.uuid4()))
        self.fetch_voice_ogg(text_to_speak, temp_fname)
        channel = pygame.mixer.Channel(5)
        sound = pygame.mixer.Sound(temp_fname)
        channel.play(sound)
        while channel.get_busy():
            pass
        os.remove(os.getcwd()+'/'+temp_fname)

    def list_voices(self):
{'fraction_non_alphanumeric': 0.11093446387564035, 'fraction_numerical': 0.006006006006006006, 'mean_word_length': 2.7696404793608522, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3124844', 'n_tokens_mistral': 1798, 'n_tokens_neox': 1757, 'n_words': 467}