[voicerss] Hide the API key when logging API URL (#12096)
Also fix few typos Also small changes regarding log levels and exception handling Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
parent
d75baa59af
commit
5abea08da3
|
@ -64,10 +64,10 @@ public class VoiceRSSTTSService implements TTSService {
|
||||||
private static final Map<Long, String> FREQUENCY_MAP = Map.of(8_000L, "8khz", 11_025L, "11khz", 12_000L, "12khz",
|
private static final Map<Long, String> FREQUENCY_MAP = Map.of(8_000L, "8khz", 11_025L, "11khz", 12_000L, "12khz",
|
||||||
16_000L, "16khz", 22_050L, "22khz", 24_000L, "24khz", 32_000L, "32khz", 44_100L, "44khz", 48_000L, "48khz");
|
16_000L, "16khz", 22_050L, "22khz", 24_000L, "24khz", 32_000L, "32khz", 44_100L, "44khz", 48_000L, "48khz");
|
||||||
|
|
||||||
private String apiKey;
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(VoiceRSSTTSService.class);
|
private final Logger logger = LoggerFactory.getLogger(VoiceRSSTTSService.class);
|
||||||
|
|
||||||
|
private String apiKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We need the cached implementation to allow for FixedLengthAudioStream.
|
* We need the cached implementation to allow for FixedLengthAudioStream.
|
||||||
*/
|
*/
|
||||||
|
@ -95,7 +95,7 @@ public class VoiceRSSTTSService implements TTSService {
|
||||||
|
|
||||||
logger.debug("Using VoiceRSS cache folder {}", getCacheFolderName());
|
logger.debug("Using VoiceRSS cache folder {}", getCacheFolderName());
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
logger.error("Failed to activate VoiceRSS: {}", e.getMessage(), e);
|
logger.warn("Failed to activate VoiceRSS: {}", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,9 +141,6 @@ public class VoiceRSSTTSService implements TTSService {
|
||||||
File cacheAudioFile = voiceRssImpl.getTextToSpeechAsFile(apiKey, trimmedText,
|
File cacheAudioFile = voiceRssImpl.getTextToSpeechAsFile(apiKey, trimmedText,
|
||||||
voice.getLocale().toLanguageTag(), voice.getLabel(), getApiAudioCodec(requestedFormat),
|
voice.getLocale().toLanguageTag(), voice.getLabel(), getApiAudioCodec(requestedFormat),
|
||||||
getApiAudioFormat(requestedFormat));
|
getApiAudioFormat(requestedFormat));
|
||||||
if (cacheAudioFile == null) {
|
|
||||||
throw new TTSException("Could not read from VoiceRSS service");
|
|
||||||
}
|
|
||||||
return new VoiceRSSAudioStream(cacheAudioFile, requestedFormat);
|
return new VoiceRSSAudioStream(cacheAudioFile, requestedFormat);
|
||||||
} catch (AudioException ex) {
|
} catch (AudioException ex) {
|
||||||
throw new TTSException("Could not create AudioStream: " + ex.getMessage(), ex);
|
throw new TTSException("Could not create AudioStream: " + ex.getMessage(), ex);
|
||||||
|
@ -223,7 +220,7 @@ public class VoiceRSSTTSService implements TTSService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CachedVoiceRSSCloudImpl initVoiceImplementation() {
|
private CachedVoiceRSSCloudImpl initVoiceImplementation() throws IllegalStateException {
|
||||||
return new CachedVoiceRSSCloudImpl(getCacheFolderName());
|
return new CachedVoiceRSSCloudImpl(getCacheFolderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
package org.openhab.voice.voicerss.internal.cloudapi;
|
package org.openhab.voice.voicerss.internal.cloudapi;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -36,16 +35,16 @@ import org.slf4j.LoggerFactory;
|
||||||
*/
|
*/
|
||||||
public class CachedVoiceRSSCloudImpl extends VoiceRSSCloudImpl {
|
public class CachedVoiceRSSCloudImpl extends VoiceRSSCloudImpl {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(CachedVoiceRSSCloudImpl.class);
|
|
||||||
|
|
||||||
private final File cacheFolder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stream buffer size
|
* Stream buffer size
|
||||||
*/
|
*/
|
||||||
private static final int READ_BUFFER_SIZE = 4096;
|
private static final int READ_BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
public CachedVoiceRSSCloudImpl(String cacheFolderName) {
|
private final Logger logger = LoggerFactory.getLogger(CachedVoiceRSSCloudImpl.class);
|
||||||
|
|
||||||
|
private final File cacheFolder;
|
||||||
|
|
||||||
|
public CachedVoiceRSSCloudImpl(String cacheFolderName) throws IllegalStateException {
|
||||||
if (cacheFolderName == null) {
|
if (cacheFolderName == null) {
|
||||||
throw new IllegalStateException("Folder for cache must be defined");
|
throw new IllegalStateException("Folder for cache must be defined");
|
||||||
}
|
}
|
||||||
|
@ -59,6 +58,9 @@ public class CachedVoiceRSSCloudImpl extends VoiceRSSCloudImpl {
|
||||||
public File getTextToSpeechAsFile(String apiKey, String text, String locale, String voice, String audioCodec,
|
public File getTextToSpeechAsFile(String apiKey, String text, String locale, String voice, String audioCodec,
|
||||||
String audioFormat) throws IOException {
|
String audioFormat) throws IOException {
|
||||||
String fileNameInCache = getUniqueFilenameForText(text, locale, voice, audioFormat);
|
String fileNameInCache = getUniqueFilenameForText(text, locale, voice, audioFormat);
|
||||||
|
if (fileNameInCache == null) {
|
||||||
|
throw new IOException("Could not infer cache file name");
|
||||||
|
}
|
||||||
// check if in cache
|
// check if in cache
|
||||||
File audioFileInCache = new File(cacheFolder, fileNameInCache + "." + audioCodec.toLowerCase());
|
File audioFileInCache = new File(cacheFolder, fileNameInCache + "." + audioCodec.toLowerCase());
|
||||||
if (audioFileInCache.exists()) {
|
if (audioFileInCache.exists()) {
|
||||||
|
@ -75,12 +77,8 @@ public class CachedVoiceRSSCloudImpl extends VoiceRSSCloudImpl {
|
||||||
writeText(txtFileInCache, text);
|
writeText(txtFileInCache, text);
|
||||||
// return from cache
|
// return from cache
|
||||||
return audioFileInCache;
|
return audioFileInCache;
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
logger.warn("Could not write {} to cache", audioFileInCache, ex);
|
|
||||||
return null;
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.error("Could not write {} to cache", audioFileInCache, ex);
|
throw new IOException("Could not write to cache file: " + ex.getMessage(), ex);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ public interface VoiceRSSCloudAPI {
|
||||||
Set<String> getAvailableVoices(Locale locale);
|
Set<String> getAvailableVoices(Locale locale);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the given text in specified locale and auido format as input stream.
|
* Get the given text in specified locale and audio format as input stream.
|
||||||
*
|
*
|
||||||
* @param apiKey
|
* @param apiKey
|
||||||
* the API key to use for the cloud service
|
* the API key to use for the cloud service
|
||||||
|
|
|
@ -55,8 +55,6 @@ public class VoiceRSSCloudImpl implements VoiceRSSCloudAPI {
|
||||||
public static final String API_URL = "https://api.voicerss.org/?key=%s&hl=%s&c=%s&f=%s&src=%s";
|
public static final String API_URL = "https://api.voicerss.org/?key=%s&hl=%s&c=%s&f=%s&src=%s";
|
||||||
public static final String API_URL_WITH_VOICE = API_URL + "&v=%s";
|
public static final String API_URL_WITH_VOICE = API_URL + "&v=%s";
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(VoiceRSSCloudImpl.class);
|
|
||||||
|
|
||||||
private static final Set<AudioFormat> SUPPORTED_AUDIO_FORMATS = Set.of(
|
private static final Set<AudioFormat> SUPPORTED_AUDIO_FORMATS = Set.of(
|
||||||
new AudioFormat(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_MP3, null, 16, null, 44_100L),
|
new AudioFormat(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_MP3, null, 16, null, 44_100L),
|
||||||
new AudioFormat(AudioFormat.CONTAINER_OGG, AudioFormat.CODEC_VORBIS, null, 16, null, 44_100L),
|
new AudioFormat(AudioFormat.CONTAINER_OGG, AudioFormat.CODEC_VORBIS, null, 16, null, 44_100L),
|
||||||
|
@ -194,6 +192,8 @@ public class VoiceRSSCloudImpl implements VoiceRSSCloudAPI {
|
||||||
SUPPORTED_VOICES.put("zh-tw", Set.of("Akemi", "Lin", "Lee"));
|
SUPPORTED_VOICES.put("zh-tw", Set.of("Akemi", "Lin", "Lee"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(VoiceRSSCloudImpl.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<AudioFormat> getAvailableAudioFormats() {
|
public Set<AudioFormat> getAvailableAudioFormats() {
|
||||||
return SUPPORTED_AUDIO_FORMATS;
|
return SUPPORTED_AUDIO_FORMATS;
|
||||||
|
@ -231,7 +231,7 @@ public class VoiceRSSCloudImpl implements VoiceRSSCloudAPI {
|
||||||
return allvoxes;
|
return allvoxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* This method will return an input stream to an audio stream for the given
|
* This method will return an input stream to an audio stream for the given
|
||||||
* parameters.
|
* parameters.
|
||||||
*
|
*
|
||||||
|
@ -242,7 +242,7 @@ public class VoiceRSSCloudImpl implements VoiceRSSCloudAPI {
|
||||||
public InputStream getTextToSpeech(String apiKey, String text, String locale, String voice, String audioCodec,
|
public InputStream getTextToSpeech(String apiKey, String text, String locale, String voice, String audioCodec,
|
||||||
String audioFormat) throws IOException {
|
String audioFormat) throws IOException {
|
||||||
String url = createURL(apiKey, text, locale, voice, audioCodec, audioFormat);
|
String url = createURL(apiKey, text, locale, voice, audioCodec, audioFormat);
|
||||||
logger.debug("Call {}", url);
|
logger.debug("Call {}", url.replace(apiKey, "***"));
|
||||||
URLConnection connection = new URL(url).openConnection();
|
URLConnection connection = new URL(url).openConnection();
|
||||||
|
|
||||||
// we will check return codes. The service will ALWAYS return a HTTP
|
// we will check return codes. The service will ALWAYS return a HTTP
|
||||||
|
@ -250,7 +250,7 @@ public class VoiceRSSCloudImpl implements VoiceRSSCloudAPI {
|
||||||
// the error message in body
|
// the error message in body
|
||||||
int status = ((HttpURLConnection) connection).getResponseCode();
|
int status = ((HttpURLConnection) connection).getResponseCode();
|
||||||
if (HttpURLConnection.HTTP_OK != status) {
|
if (HttpURLConnection.HTTP_OK != status) {
|
||||||
logger.error("Call {} returned HTTP {}", url, status);
|
logger.warn("Call {} returned HTTP {}", url.replace(apiKey, "***"), status);
|
||||||
throw new IOException("Could not read from service: HTTP code " + status);
|
throw new IOException("Could not read from service: HTTP code " + status);
|
||||||
}
|
}
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
|
@ -271,7 +271,7 @@ public class VoiceRSSCloudImpl implements VoiceRSSCloudAPI {
|
||||||
logger.debug("Failed to close inputstream", ex);
|
logger.debug("Failed to close inputstream", ex);
|
||||||
}
|
}
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Could not read audio content, service return an error: " + new String(bytes, "UTF-8"));
|
"Could not read audio content, service returned an error: " + new String(bytes, "UTF-8"));
|
||||||
} else {
|
} else {
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue