Skip to content

Commit

Permalink
better network checks, import checks
Browse files Browse the repository at this point in the history
  • Loading branch information
grigi committed Sep 16, 2015
1 parent 898e385 commit 462eed8
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Simple Test-To-Speech (TTS) interface library with multi-language and multi-engi
Rationale
=========

I was really intruiqued by the concept of jasper, a voice-controlled interface.
I was really intrigued by the concept of jasper, a voice-controlled interface.
I needed it to be multi-lingual like me, so this library is my attempt to make having the
TTS engines multi-lingual. A lot of this code is based of code from the Jasper project,
just refactored to fit purpose and to be testable.
Expand Down
13 changes: 10 additions & 3 deletions talkey/plugins/google.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import os
import tempfile

import gtts
try:
import gtts
except ImportError: # pragma: no cover
pass

from talkey.base import AbstractTTSEngine, DETECTABLE_LANGS
from talkey.utils import memoize
from talkey.utils import memoize, check_network_connection, check_python_import


class GoogleTTS(AbstractTTSEngine):
Expand All @@ -19,8 +22,12 @@ class GoogleTTS(AbstractTTSEngine):
def get_init_options(cls):
return {}

@memoize
def is_available(self):
return True
return (
check_python_import('gtts')
and check_network_connection('translate.google.com', 80)
)

def get_options(self):
return {}
Expand Down
10 changes: 2 additions & 8 deletions talkey/plugins/mary.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from urllib.parse import urlunsplit, urlencode

from talkey.base import AbstractTTSEngine, DETECTABLE_LANGS
from talkey.utils import memoize
from talkey.utils import memoize, check_network_connection


class MaryTTS(AbstractTTSEngine):
Expand Down Expand Up @@ -50,13 +50,7 @@ def _makeurl(self, path, query={}):

@memoize
def is_available(self):
try:
res = requests.get(self._makeurl('version'))
if res.status_code == 200 and 'Mary TTS' in res.text:
return True
except requests.ConnectionError:
pass
return False
return check_network_connection(self.ioptions['host'], self.ioptions['port'])

def get_options(self):
return {}
Expand Down
10 changes: 10 additions & 0 deletions talkey/test_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,19 @@ class EspeakTTSTest(BaseTTSTest):
OBJ_ATTRS = ['words_per_minute', 'pitch_adjustment', 'variant']
EVAL_PLAY = True

def test_get_languages_options(self):
qtdt = self.CLS().get_languages()
qfdt = self.CLS().get_languages(quality=False)
qfdf = self.CLS().get_languages(quality=False, detectable=False)

assert len(qfdf.keys()) > len(qfdt.keys()) > len(qtdt.keys())


class PicoTTSTest(BaseTTSTest):
CLS = PicoTTS
SLUG = 'pico-tts'


class MaryTTSTest(BaseTTSTest):
CLS = MaryTTS
SLUG = 'mary-tts'
Expand All @@ -270,6 +279,7 @@ class MaryTTSTest(BaseTTSTest):
EVAL_PLAY = True
SKIP_IF_NOT_AVAILABLE = True


class GoogleTTSTest(BaseTTSTest):
CLS = GoogleTTS
SLUG = 'google-tts'
Expand Down
49 changes: 49 additions & 0 deletions talkey/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# -*- coding: utf-8-*-
import sys
import logging
import socket
import functools
import pkgutil
if sys.version_info < (3, 3):
from distutils.spawn import find_executable # pylint: disable=E0611
else:
Expand All @@ -27,6 +29,53 @@ def check_executable(executable):
return found


def check_network_connection(server, port):
"""
Checks if jasper can connect a network server.
Arguments:
server -- (optional) the server to connect with (Default:
"www.google.com")
Returns:
True or False
"""
logger = logging.getLogger(__name__)
logger.debug("Checking network connection to server '%s'...", server)
try:
# see if we can resolve the host name -- tells us if there is
# a DNS listening
host = socket.gethostbyname(server)
# connect to the host -- tells us if the host is actually
# reachable
sock = socket.create_connection((host, port), 2)
sock.close()
except Exception: # pragma: no cover
logger.debug("Network connection not working")
return False
logger.debug("Network connection working")
return True


def check_python_import(package_or_module):
"""
Checks if a python package or module is importable.
Arguments:
package_or_module -- the package or module name to check
Returns:
True or False
"""
logger = logging.getLogger(__name__)
logger.debug("Checking python import '%s'...", package_or_module)
loader = pkgutil.get_loader(package_or_module)
found = loader is not None
if found:
logger.debug("Python %s '%s' found",
"package" if loader.is_package(package_or_module)
else "module", package_or_module)
else: # pragma: no cover
logger.debug("Python import '%s' not found", package_or_module)
return found


def process_options(valid_options, _options, error):
unknown_options = set(_options.keys()).difference(valid_options.keys())
if unknown_options:
Expand Down

0 comments on commit 462eed8

Please sign in to comment.