mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 10:11:31 +00:00
voice clone requests endpoints
This commit is contained in:
1 parent
9280ec11f7
commit
e6f0908a3d
8 files changed
+363
-34
No files matched your search
@@ -25,6 +25,10 @@ CREATE TABLE voice_clone_requests(
|
||||
|
||||
-- ========== REASON ==========
|
||||
|
||||
-- Visibility
|
||||
is_for_private_use BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_for_public_use BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- How they'll use
|
||||
is_for_studio BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_for_twitch_tts BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
@@ -34,13 +38,10 @@ CREATE TABLE voice_clone_requests(
|
||||
is_for_other BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
optional_notes_on_use MEDIUMTEXT DEFAULT NULL,
|
||||
|
||||
-- Visibility
|
||||
is_for_private_use BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_for_public_use BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Ownership
|
||||
-- Subject/Ownership
|
||||
is_own_voice BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_third_party_voice BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
optional_notes_on_subject VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- ========== RECORDING QUALITY / EQUIPMENT ==========
|
||||
|
||||
|
||||
+23
-18
@@ -33,6 +33,10 @@ pub struct VoiceCloneRequest {
|
||||
pub email_address: String,
|
||||
pub discord_username: String,
|
||||
|
||||
// Visibility
|
||||
pub is_for_private_use: bool,
|
||||
pub is_for_public_use: bool,
|
||||
|
||||
// Use
|
||||
pub is_for_studio: bool,
|
||||
pub is_for_twitch_tts: bool,
|
||||
@@ -42,13 +46,10 @@ pub struct VoiceCloneRequest {
|
||||
pub is_for_other: bool,
|
||||
pub optional_notes_on_use: Option<String>,
|
||||
|
||||
// Visibility
|
||||
pub is_for_private_use: bool,
|
||||
pub is_for_public_use: bool,
|
||||
|
||||
// Ownership
|
||||
// Subject/Ownership
|
||||
pub is_own_voice: bool,
|
||||
pub is_third_party_voice: bool,
|
||||
pub optional_notes_on_subject: Option<String>,
|
||||
|
||||
// Equipment
|
||||
pub has_clean_audio_recordings: bool,
|
||||
@@ -76,6 +77,9 @@ SELECT
|
||||
email_address,
|
||||
discord_username,
|
||||
|
||||
is_for_private_use,
|
||||
is_for_public_use,
|
||||
|
||||
is_for_studio,
|
||||
is_for_twitch_tts,
|
||||
is_for_api_use,
|
||||
@@ -84,11 +88,9 @@ SELECT
|
||||
is_for_other,
|
||||
optional_notes_on_use,
|
||||
|
||||
is_for_private_use,
|
||||
is_for_public_use,
|
||||
|
||||
is_own_voice,
|
||||
is_third_party_voice,
|
||||
optional_notes_on_subject,
|
||||
|
||||
has_clean_audio_recordings,
|
||||
has_good_microphone,
|
||||
@@ -124,6 +126,9 @@ SELECT
|
||||
email_address,
|
||||
discord_username,
|
||||
|
||||
is_for_private_use,
|
||||
is_for_public_use,
|
||||
|
||||
is_for_studio,
|
||||
is_for_twitch_tts,
|
||||
is_for_api_use,
|
||||
@@ -132,11 +137,9 @@ SELECT
|
||||
is_for_other,
|
||||
optional_notes_on_use,
|
||||
|
||||
is_for_private_use,
|
||||
is_for_public_use,
|
||||
|
||||
is_own_voice,
|
||||
is_third_party_voice,
|
||||
optional_notes_on_subject,
|
||||
|
||||
has_clean_audio_recordings,
|
||||
has_good_microphone,
|
||||
@@ -172,6 +175,8 @@ fn handle_result(
|
||||
maybe_user_token: record.maybe_user_token,
|
||||
email_address: record.email_address,
|
||||
discord_username: record.discord_username,
|
||||
is_for_private_use: i8_to_bool(record.is_for_private_use),
|
||||
is_for_public_use: i8_to_bool(record.is_for_public_use),
|
||||
is_for_studio: i8_to_bool(record.is_for_studio),
|
||||
is_for_twitch_tts: i8_to_bool(record.is_for_twitch_tts),
|
||||
is_for_api_use: i8_to_bool(record.is_for_api_use),
|
||||
@@ -179,10 +184,9 @@ fn handle_result(
|
||||
is_for_games: i8_to_bool(record.is_for_games),
|
||||
is_for_other: i8_to_bool(record.is_for_other),
|
||||
optional_notes_on_use: record.optional_notes_on_use,
|
||||
is_for_private_use: i8_to_bool(record.is_for_private_use),
|
||||
is_for_public_use: i8_to_bool(record.is_for_public_use),
|
||||
is_own_voice: i8_to_bool(record.is_own_voice),
|
||||
is_third_party_voice: i8_to_bool(record.is_third_party_voice),
|
||||
optional_notes_on_subject: record.optional_notes_on_subject,
|
||||
has_clean_audio_recordings: i8_to_bool(record.has_clean_audio_recordings),
|
||||
has_good_microphone: i8_to_bool(record.has_good_microphone),
|
||||
optional_questions: record.optional_questions,
|
||||
@@ -201,6 +205,10 @@ struct VoiceCloneRequestInternal {
|
||||
pub email_address: String,
|
||||
pub discord_username: String,
|
||||
|
||||
// Visibility
|
||||
pub is_for_private_use: i8,
|
||||
pub is_for_public_use: i8,
|
||||
|
||||
// Use
|
||||
pub is_for_studio: i8,
|
||||
pub is_for_twitch_tts: i8,
|
||||
@@ -210,13 +218,10 @@ struct VoiceCloneRequestInternal {
|
||||
pub is_for_other: i8,
|
||||
pub optional_notes_on_use: Option<String>,
|
||||
|
||||
// Visibility
|
||||
pub is_for_private_use: i8,
|
||||
pub is_for_public_use: i8,
|
||||
|
||||
// Ownership
|
||||
// Subject/Ownership
|
||||
pub is_own_voice: i8,
|
||||
pub is_third_party_voice: i8,
|
||||
pub optional_notes_on_subject: Option<String>,
|
||||
|
||||
// Equipment
|
||||
pub has_clean_audio_recordings: i8,
|
||||
|
||||
+14
-11
@@ -12,6 +12,10 @@ pub struct InsertVoiceCloneRequestBuilder {
|
||||
pub email_address: String,
|
||||
pub discord_username: String,
|
||||
|
||||
// Visibility
|
||||
pub is_for_private_use: bool,
|
||||
pub is_for_public_use: bool,
|
||||
|
||||
// Use
|
||||
pub is_for_studio: bool,
|
||||
pub is_for_twitch_tts: bool,
|
||||
@@ -21,13 +25,10 @@ pub struct InsertVoiceCloneRequestBuilder {
|
||||
pub is_for_other: bool,
|
||||
pub optional_notes_on_use: Option<String>,
|
||||
|
||||
// Visibility
|
||||
pub is_for_private_use: bool,
|
||||
pub is_for_public_use: bool,
|
||||
|
||||
// Ownership
|
||||
// Subject/Ownership
|
||||
pub is_own_voice: bool,
|
||||
pub is_third_party_voice: bool,
|
||||
pub optional_notes_on_subject: Option<String>,
|
||||
|
||||
// Equipment
|
||||
pub has_clean_audio_recordings: bool,
|
||||
@@ -58,6 +59,9 @@ SET
|
||||
email_address = ?,
|
||||
discord_username = ?,
|
||||
|
||||
is_for_private_use = ?,
|
||||
is_for_public_use = ?,
|
||||
|
||||
is_for_studio = ?,
|
||||
is_for_twitch_tts = ?,
|
||||
is_for_api_use = ?,
|
||||
@@ -66,11 +70,9 @@ SET
|
||||
is_for_other = ?,
|
||||
optional_notes_on_use = ?,
|
||||
|
||||
is_for_private_use = ?,
|
||||
is_for_public_use = ?,
|
||||
|
||||
is_own_voice = ?,
|
||||
is_third_party_voice = ?,
|
||||
optional_notes_on_subject = ?,
|
||||
|
||||
has_clean_audio_recordings = ?,
|
||||
has_good_microphone = ?,
|
||||
@@ -87,6 +89,9 @@ SET
|
||||
&self.email_address,
|
||||
&self.discord_username,
|
||||
|
||||
&self.is_for_private_use,
|
||||
&self.is_for_public_use,
|
||||
|
||||
&self.is_for_studio,
|
||||
&self.is_for_twitch_tts,
|
||||
&self.is_for_api_use,
|
||||
@@ -95,11 +100,9 @@ SET
|
||||
&self.is_for_other,
|
||||
&self.optional_notes_on_use,
|
||||
|
||||
&self.is_for_private_use,
|
||||
&self.is_for_public_use,
|
||||
|
||||
&self.is_own_voice,
|
||||
&self.is_third_party_voice,
|
||||
&self.optional_notes_on_subject,
|
||||
|
||||
&self.has_clean_audio_recordings,
|
||||
&self.has_good_microphone,
|
||||
|
||||
@@ -7,4 +7,5 @@ pub mod moderation;
|
||||
pub mod tts;
|
||||
pub mod twitch;
|
||||
pub mod users;
|
||||
pub mod voice_clone_requests;
|
||||
pub mod w2l;
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
use actix_http::Error;
|
||||
use actix_http::http::header;
|
||||
use actix_web::HttpResponseBuilder;
|
||||
use actix_web::cookie::Cookie;
|
||||
use actix_web::error::ResponseError;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::web::{Path, Json};
|
||||
use actix_web::{Responder, web, HttpResponse, error, HttpRequest};
|
||||
use crate::http_server::web_utils::ip_address::get_request_ip;
|
||||
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
|
||||
use crate::http_server::web_utils::response_success_helpers::simple_json_success;
|
||||
use crate::server_state::ServerState;
|
||||
use database_queries::queries::voice_clone_requests::get_voice_clone_request::{get_voice_clone_request_by_user_token, get_voice_clone_request_by_token};
|
||||
use database_queries::queries::voice_clone_requests::insert_voice_clone_requests_builder::InsertVoiceCloneRequestBuilder;
|
||||
use http_server_common::response::serialize_as_json_error::serialize_as_json_error;
|
||||
use log::{info, warn, log};
|
||||
use regex::Regex;
|
||||
use sqlx::MySqlPool;
|
||||
use sqlx::error::DatabaseError;
|
||||
use sqlx::error::Error::Database;
|
||||
use sqlx::mysql::MySqlDatabaseError;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
||||
// =============== Request ===============
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CheckIfVoiceRequestSubmittedRequest {
|
||||
/// Though we look up logged in users by user token, we can also look up non-logged-in users
|
||||
/// with a token lookup. We can store this in frontend state or a cookie.
|
||||
pub maybe_request_token: Option<String>,
|
||||
}
|
||||
|
||||
// =============== Success Response ===============
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct CheckIfVoiceRequestSubmittedResponse {
|
||||
pub success: bool,
|
||||
pub has_submitted: bool,
|
||||
}
|
||||
|
||||
// =============== Error Response ===============
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum CheckIfVoiceRequestSubmittedError {
|
||||
BadInput(String),
|
||||
NotAuthorized,
|
||||
ServerError,
|
||||
}
|
||||
|
||||
impl ResponseError for CheckIfVoiceRequestSubmittedError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match *self {
|
||||
CheckIfVoiceRequestSubmittedError::BadInput(_) => StatusCode::BAD_REQUEST,
|
||||
CheckIfVoiceRequestSubmittedError::NotAuthorized => StatusCode::UNAUTHORIZED,
|
||||
CheckIfVoiceRequestSubmittedError::ServerError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
serialize_as_json_error(self)
|
||||
}
|
||||
}
|
||||
|
||||
// NB: Not using DeriveMore since Clion doesn't understand it.
|
||||
impl fmt::Display for CheckIfVoiceRequestSubmittedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
// =============== Handler ===============
|
||||
|
||||
pub async fn check_if_voice_clone_request_submitted_handler(
|
||||
http_request: HttpRequest,
|
||||
request: web::Json<CheckIfVoiceRequestSubmittedRequest>,
|
||||
server_state: web::Data<Arc<ServerState>>) -> Result<HttpResponse, CheckIfVoiceRequestSubmittedError>
|
||||
{
|
||||
let maybe_user_session = server_state
|
||||
.session_checker
|
||||
.maybe_get_user_session(&http_request, &server_state.mysql_pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Session checker error: {:?}", e);
|
||||
CheckIfVoiceRequestSubmittedError::ServerError
|
||||
})?;
|
||||
|
||||
let mut submitted_by_token = false;
|
||||
let mut submitted_by_user = false;
|
||||
|
||||
// Non-logged in accounts (via cookie or frontend mechanism)
|
||||
if let Some(token) = request.maybe_request_token.as_deref() {
|
||||
let request = get_voice_clone_request_by_token(
|
||||
token, &server_state.mysql_pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Database error: {:?}", e);
|
||||
CheckIfVoiceRequestSubmittedError::ServerError
|
||||
})?;
|
||||
|
||||
submitted_by_token = request.is_some();
|
||||
}
|
||||
|
||||
// Logged in users
|
||||
if let Some(user) = maybe_user_session.as_ref() {
|
||||
let request = get_voice_clone_request_by_user_token(
|
||||
&user.user_token, &server_state.mysql_pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Database error: {:?}", e);
|
||||
CheckIfVoiceRequestSubmittedError::ServerError
|
||||
})?;
|
||||
|
||||
submitted_by_user = request.is_some();
|
||||
}
|
||||
|
||||
let has_submitted = submitted_by_token || submitted_by_user;
|
||||
|
||||
let response = CheckIfVoiceRequestSubmittedResponse {
|
||||
success: true,
|
||||
has_submitted,
|
||||
};
|
||||
|
||||
let body = serde_json::to_string(&response)
|
||||
.map_err(|e| CheckIfVoiceRequestSubmittedError::ServerError)?;
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("application/json")
|
||||
.body(body))
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
use actix_http::Error;
|
||||
use actix_http::http::header;
|
||||
use actix_web::HttpResponseBuilder;
|
||||
use actix_web::cookie::Cookie;
|
||||
use actix_web::error::ResponseError;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::web::{Path, Json};
|
||||
use actix_web::{Responder, web, HttpResponse, error, HttpRequest};
|
||||
use crate::http_server::web_utils::ip_address::get_request_ip;
|
||||
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
|
||||
use crate::http_server::web_utils::response_success_helpers::simple_json_success;
|
||||
use crate::server_state::ServerState;
|
||||
use database_queries::queries::voice_clone_requests::insert_voice_clone_requests_builder::InsertVoiceCloneRequestBuilder;
|
||||
use http_server_common::response::serialize_as_json_error::serialize_as_json_error;
|
||||
use log::{info, warn, log};
|
||||
use regex::Regex;
|
||||
use sqlx::MySqlPool;
|
||||
use sqlx::error::DatabaseError;
|
||||
use sqlx::error::Error::Database;
|
||||
use sqlx::mysql::MySqlDatabaseError;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
||||
// =============== Request ===============
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CreateVoiceRequestRequest {
|
||||
pub idempotency_token: String,
|
||||
|
||||
// Contact
|
||||
pub email_address: String,
|
||||
pub discord_username: String,
|
||||
|
||||
// TODO: Make enum.
|
||||
// Visibility
|
||||
pub is_for_private_use: bool,
|
||||
pub is_for_public_use: bool,
|
||||
|
||||
// Use
|
||||
pub is_for_studio: bool,
|
||||
pub is_for_twitch_tts: bool,
|
||||
pub is_for_api_use: bool,
|
||||
pub is_for_music: bool,
|
||||
pub is_for_games: bool,
|
||||
pub is_for_other: bool,
|
||||
pub optional_notes_on_use: Option<String>,
|
||||
|
||||
// Subject/Ownership
|
||||
pub is_own_voice: bool,
|
||||
pub is_third_party_voice: bool,
|
||||
pub optional_notes_on_subject: Option<String>,
|
||||
|
||||
// Equipment
|
||||
pub has_clean_audio_recordings: bool,
|
||||
pub has_good_microphone: bool,
|
||||
|
||||
// Comments
|
||||
pub optional_questions: Option<String>,
|
||||
pub optional_extra_comments: Option<String>,
|
||||
}
|
||||
|
||||
// =============== Success Response ===============
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct CreateVoiceRequestResponse {
|
||||
pub success: bool,
|
||||
}
|
||||
|
||||
// =============== Error Response ===============
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum CreateVoiceRequestError {
|
||||
BadInput(String),
|
||||
NotAuthorized,
|
||||
ServerError,
|
||||
}
|
||||
|
||||
impl ResponseError for CreateVoiceRequestError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match *self {
|
||||
CreateVoiceRequestError::BadInput(_) => StatusCode::BAD_REQUEST,
|
||||
CreateVoiceRequestError::NotAuthorized => StatusCode::UNAUTHORIZED,
|
||||
CreateVoiceRequestError::ServerError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
serialize_as_json_error(self)
|
||||
}
|
||||
}
|
||||
|
||||
// NB: Not using DeriveMore since Clion doesn't understand it.
|
||||
impl fmt::Display for CreateVoiceRequestError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
// =============== Handler ===============
|
||||
|
||||
pub async fn create_voice_clone_request_handler(
|
||||
http_request: HttpRequest,
|
||||
request: web::Json<CreateVoiceRequestRequest>,
|
||||
server_state: web::Data<Arc<ServerState>>) -> Result<HttpResponse, CreateVoiceRequestError>
|
||||
{
|
||||
let maybe_user_session = server_state
|
||||
.session_checker
|
||||
.maybe_get_user_session(&http_request, &server_state.mysql_pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Session checker error: {:?}", e);
|
||||
CreateVoiceRequestError::ServerError
|
||||
})?;
|
||||
|
||||
let creator_ip_address = get_request_ip(&http_request);
|
||||
|
||||
let builder = InsertVoiceCloneRequestBuilder {
|
||||
uuid_idempotency_token: request.idempotency_token.clone(),
|
||||
maybe_user_token: maybe_user_session.map(|user| user.user_token.clone()),
|
||||
email_address: request.email_address.clone(),
|
||||
discord_username: request.discord_username.clone(),
|
||||
is_for_private_use: request.is_for_private_use,
|
||||
is_for_public_use: request.is_for_public_use,
|
||||
is_for_studio: request.is_for_studio,
|
||||
is_for_twitch_tts: request.is_for_twitch_tts,
|
||||
is_for_api_use: request.is_for_api_use,
|
||||
is_for_music: request.is_for_music,
|
||||
is_for_games: request.is_for_games,
|
||||
is_for_other: request.is_for_other,
|
||||
optional_notes_on_use: request.optional_notes_on_use.clone(),
|
||||
is_own_voice: request.is_own_voice,
|
||||
is_third_party_voice: request.is_third_party_voice,
|
||||
optional_notes_on_subject: request.optional_notes_on_subject.clone(),
|
||||
has_clean_audio_recordings: request.has_clean_audio_recordings,
|
||||
has_good_microphone: request.has_good_microphone,
|
||||
optional_questions: request.optional_questions.clone(),
|
||||
optional_extra_comments: request.optional_extra_comments.clone(),
|
||||
ip_address_creation: creator_ip_address,
|
||||
};
|
||||
|
||||
builder.insert(&server_state.mysql_pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("creation error: {:?}", e);
|
||||
CreateVoiceRequestError::ServerError
|
||||
})?;
|
||||
|
||||
let response = CreateVoiceRequestResponse {
|
||||
success: true,
|
||||
};
|
||||
|
||||
let body = serde_json::to_string(&response)
|
||||
.map_err(|e| CreateVoiceRequestError::ServerError)?;
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("application/json")
|
||||
.body(body))
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod create_voice_clone_request;
|
||||
pub mod check_if_voice_clone_request_submitted;
|
||||
@@ -79,6 +79,8 @@ use crate::http_server::endpoints::twitch::event_rules::create_event_rule::creat
|
||||
use crate::http_server::endpoints::twitch::event_rules::list_event_rules_for_user::list_twitch_event_rules_for_user_handler;
|
||||
use crate::http_server::endpoints::twitch::event_rules::delete_event_rule::delete_twitch_event_rule_handler;
|
||||
use crate::http_server::endpoints::twitch::event_rules::edit_event_rule::edit_twitch_event_rule_handler;
|
||||
use crate::http_server::endpoints::voice_clone_requests::create_voice_clone_request::create_voice_clone_request_handler;
|
||||
use crate::http_server::endpoints::voice_clone_requests::check_if_voice_clone_request_submitted::check_if_voice_clone_request_submitted_handler;
|
||||
|
||||
pub fn add_routes<T, B> (app: App<T, B>) -> App<T, B>
|
||||
where
|
||||
@@ -97,6 +99,7 @@ pub fn add_routes<T, B> (app: App<T, B>) -> App<T, B>
|
||||
app = add_category_routes(app); /* /category */
|
||||
app = add_user_profile_routes(app); /* /user */
|
||||
app = add_api_token_routes(app); /* /api_tokens */
|
||||
app = add_voice_clone_request_routes(app); /* /voice_clone_requests */
|
||||
app = add_twitch_oauth_routes(app); /* /twitch */ // TODO: MAYBE TEMPORARY
|
||||
|
||||
// ==================== ACCOUNT CREATION / SESSION MANAGEMENT ====================
|
||||
@@ -571,6 +574,32 @@ fn add_api_token_routes<T, B> (app: App<T, B>) -> App<T, B>
|
||||
)
|
||||
}
|
||||
|
||||
// ==================== API TOKEN ROUTES ====================
|
||||
|
||||
fn add_voice_clone_request_routes<T, B> (app: App<T, B>) -> App<T, B>
|
||||
where
|
||||
B: MessageBody,
|
||||
T: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
app.service(web::scope("/voice_clone_requests")
|
||||
.service(web::resource("/create")
|
||||
.route(web::post().to(create_voice_clone_request_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::resource("/check")
|
||||
.route(web::post().to(check_if_voice_clone_request_submitted_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// ==================== TWITCH ROUTES ====================
|
||||
|
||||
// TODO: Maybe move these into an "oauth-gateway" type http service.
|
||||
|
||||
Reference in new issue
Block a user