mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-11 04:16:55 +00:00
Cleanup, error handling
This commit is contained in:
1 parent
c983e88a0b
commit
1b4e220b52
7 files changed
+75
-47
No files matched your search
@@ -42,6 +42,10 @@ Scaling
|
||||
4. Prevent others from calling it
|
||||
5. Caching strategy
|
||||
|
||||
Server
|
||||
1. Favicon, .ico and apple icon
|
||||
2. robots.txt
|
||||
|
||||
Hardening
|
||||
1. Reduce API surface
|
||||
2. Limit length of input sentences
|
||||
|
||||
@@ -12,8 +12,7 @@ rsync -utrv config.toml bt@jungle.horse:/home/bt/dev/trumpet
|
||||
|
||||
# Frontend
|
||||
rsync -utrv web/images bt@jungle.horse:/home/bt/dev/trumpet/web
|
||||
rsync -utrv web/*css bt@jungle.horse:/home/bt/dev/trumpet/web
|
||||
rsync -utrv web/*html bt@jungle.horse:/home/bt/dev/trumpet/web
|
||||
rsync -utrv web/{*css,*html,*txt} bt@jungle.horse:/home/bt/dev/trumpet/web
|
||||
pushd frontend
|
||||
webpack
|
||||
popd
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
use hound::Error as HoundError;
|
||||
use std::convert::From;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
|
||||
/** The common error type used throughout the synthesizer. */
|
||||
@@ -13,6 +15,9 @@ pub enum SynthError {
|
||||
/// The file was empty or did not have parsable contents.
|
||||
EmptyFile,
|
||||
|
||||
/// Could not obtain the lock.
|
||||
LockError,
|
||||
|
||||
/// Wraps an IoError.
|
||||
IoError { cause: io::Error },
|
||||
|
||||
@@ -20,6 +25,23 @@ pub enum SynthError {
|
||||
AudioError { cause: HoundError },
|
||||
}
|
||||
|
||||
impl fmt::Display for SynthError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Synthesis Error")
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for SynthError {
|
||||
fn description(&self) -> &str {
|
||||
"Synthesis Error" // TODO
|
||||
}
|
||||
|
||||
/*fn cause(&self) -> Option<&Error> {
|
||||
Some(&self)
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
impl From<io::Error> for SynthError {
|
||||
fn from(error: io::Error) -> SynthError {
|
||||
SynthError::IoError { cause: error }
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
use config::Config;
|
||||
use crypto::digest::Digest;
|
||||
use crypto::sha1::Sha1;
|
||||
use error::SynthError;
|
||||
use iron::Handler;
|
||||
use iron::IronError;
|
||||
use iron::Plugin;
|
||||
use iron::headers::ETag;
|
||||
use iron::headers::EntityTag;
|
||||
@@ -317,7 +319,7 @@ impl Handler for AudioSynthHandler {
|
||||
}
|
||||
|
||||
let start = PreciseTime::now();
|
||||
let result = self.create_audio(request);
|
||||
let result = try!(self.create_audio(request));
|
||||
|
||||
info!(target: "timing",
|
||||
"Total parsing and synthesis took: {}", start.to(PreciseTime::now()));
|
||||
@@ -340,39 +342,29 @@ impl AudioSynthHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Return errors.
|
||||
/// Create audio from the sentence.
|
||||
fn create_audio(&self, request: SpeakRequest) -> Vec<u8> {
|
||||
match self.synthesizer.read() {
|
||||
Err(_) => Vec::new(), // TODO Actual error.
|
||||
Ok(synth) => {
|
||||
let params = SynthesisParams {
|
||||
use_words: request.use_words,
|
||||
use_phonemes: request.use_phonemes,
|
||||
use_diphones: request.use_diphones,
|
||||
use_n_phones: request.use_n_phones,
|
||||
use_ends: request.use_ends,
|
||||
volume: request.volume,
|
||||
speed: request.speed,
|
||||
monophone_padding_start: request.monophone_padding_start,
|
||||
monophone_padding_end: request.monophone_padding_end,
|
||||
polyphone_padding_end: request.polyphone_padding_end,
|
||||
word_padding_start: request.word_padding_start,
|
||||
word_padding_end: request.word_padding_end,
|
||||
};
|
||||
fn create_audio(&self, request: SpeakRequest) -> Result<Vec<u8>, SynthError> {
|
||||
let synth = match self.synthesizer.read() {
|
||||
Err(_) => { return Err(SynthError::LockError); },
|
||||
Ok(synth) => synth,
|
||||
};
|
||||
|
||||
let generated = synth.generate(&request.sentence, &request.speaker,
|
||||
params);
|
||||
let params = SynthesisParams {
|
||||
use_words: request.use_words,
|
||||
use_phonemes: request.use_phonemes,
|
||||
use_diphones: request.use_diphones,
|
||||
use_n_phones: request.use_n_phones,
|
||||
use_ends: request.use_ends,
|
||||
volume: request.volume,
|
||||
speed: request.speed,
|
||||
monophone_padding_start: request.monophone_padding_start,
|
||||
monophone_padding_end: request.monophone_padding_end,
|
||||
polyphone_padding_end: request.polyphone_padding_end,
|
||||
word_padding_start: request.word_padding_start,
|
||||
word_padding_end: request.word_padding_end,
|
||||
};
|
||||
|
||||
match generated {
|
||||
Err(e) => {
|
||||
warn!("Error synthesizing: {:?}", e);
|
||||
Vec::new() // TODO FIXME
|
||||
},
|
||||
Ok(wav) => wav,
|
||||
}
|
||||
}
|
||||
}
|
||||
synth.generate(&request.sentence, &request.speaker, params)
|
||||
}
|
||||
|
||||
fn sha_digest(&self, request: &SpeakRequest) -> String {
|
||||
@@ -416,3 +408,10 @@ fn get_u16(params: &QueryParams, param_name: &str) -> Option<u16> {
|
||||
.and_then(|d| if d == 0 { None } else { Some(d) } )
|
||||
}
|
||||
|
||||
impl From<SynthError> for IronError {
|
||||
fn from(error: SynthError) -> IronError {
|
||||
let mime = "text/plain".parse::<Mime>().unwrap();
|
||||
let response = (mime, status::InternalServerError, "Service Error");
|
||||
IronError::new(error, response)
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,11 @@ impl Handler for FileServerHandler {
|
||||
let filename = self.get_filename(&req);
|
||||
|
||||
let mime = match &filename {
|
||||
s if s.ends_with(".css") => { "text/css" },
|
||||
s if s.ends_with(".html") => { "text/html" },
|
||||
s if s.ends_with(".js") => { "application/javascript" },
|
||||
_ => { "text/plain" },
|
||||
s if s.ends_with(".css") => "text/css",
|
||||
s if s.ends_with(".html") => "text/html",
|
||||
s if s.ends_with(".js") => "application/javascript",
|
||||
s if s.ends_with(".txt") => "text/plain",
|
||||
_ => "text/plain",
|
||||
};
|
||||
|
||||
match self.open_file(&filename) {
|
||||
|
||||
+11
-10
@@ -1,20 +1,21 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Jungle Horse</title>
|
||||
<title>Jungle Horse — Text to Trump</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<meta name="description" content="Jungle Horse is a Trump text to speech engine.">
|
||||
<link rel="stylesheet" href="/assets/demo.css" type="text/css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Coming+Soon|Dosis|Happy+Monkey|Kaushan+Script|Lobster|Lobster+Two|Oxygen|Righteous" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Fira+Sans|Open+Sans" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/assets/demo_jon.css" type="text/css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Fira+Sans" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<div id="animation"></div>
|
||||
<div id="logo">
|
||||
<h1>Text to Trump</h1>
|
||||
|
||||
<div id="image-box">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="main">
|
||||
<form>
|
||||
<div id="input-box">
|
||||
<input id="jungle" name="jungle" autocomplete="off">
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Reference in new issue
Block a user