mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-31 23:47:51 +00:00
new endpoint in rust
This commit is contained in:
1 parent
5a0751e0bc
commit
44d0efdd84
6 files changed
+177
No files matched your search
@@ -1,2 +1,3 @@
|
||||
pub mod notes;
|
||||
pub mod read_only;
|
||||
pub mod upload;
|
||||
@@ -0,0 +1,51 @@
|
||||
//! Request/response types for `POST /v1/video_info/notes`.
|
||||
//!
|
||||
//! A note is user-submitted context about an uploaded video (what model they
|
||||
//! believe it is, where it came from, free-form comments). Always tied to an
|
||||
//! [`UploadedVideoToken`]; pass a [`UploadVideoNoteToken`] to update an existing
|
||||
//! note instead of creating a new one.
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_model_type::UploadedVideoNoteReportedModelType;
|
||||
use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_website::UploadedVideoNoteReportedWebsite;
|
||||
use tokens::tokens::uploaded_video_notes::UploadVideoNoteToken;
|
||||
use tokens::tokens::uploaded_videos::UploadedVideoToken;
|
||||
|
||||
/// Request body for `POST /v1/video_info/notes`.
|
||||
#[derive(Deserialize, ToSchema, Debug, Clone)]
|
||||
pub struct VideoInfoNoteRequest {
|
||||
/// The uploaded video this note is about. Required.
|
||||
pub uploaded_video_token: UploadedVideoToken,
|
||||
|
||||
/// If present, update this existing note instead of creating a new one.
|
||||
pub maybe_uploaded_video_note_token: Option<UploadVideoNoteToken>,
|
||||
|
||||
/// Original filename of the submitted clip.
|
||||
pub maybe_filename: Option<String>,
|
||||
|
||||
/// The model type the submitter claims this video is (dropdown / enum).
|
||||
pub maybe_reported_model_type: Option<UploadedVideoNoteReportedModelType>,
|
||||
|
||||
/// Free-form custom model name (trimmed; empty becomes absent).
|
||||
pub maybe_reported_model_name: Option<String>,
|
||||
|
||||
/// The website / platform the video came from (dropdown / enum).
|
||||
pub maybe_website: Option<UploadedVideoNoteReportedWebsite>,
|
||||
|
||||
/// Free-form website (trimmed; empty becomes absent).
|
||||
pub maybe_other_website: Option<String>,
|
||||
|
||||
/// Free-form comments (trimmed; empty becomes absent).
|
||||
pub maybe_comments: Option<String>,
|
||||
}
|
||||
|
||||
/// Response body for `POST /v1/video_info/notes`.
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug, Clone)]
|
||||
pub struct VideoInfoNoteResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// The created or updated note's token (e.g. `uvnote_…`).
|
||||
pub uploaded_video_note_token: UploadVideoNoteToken,
|
||||
}
|
||||
@@ -366,8 +366,12 @@ use artcraft_api_defs::user_referral_codes::list_referral_codes::*;
|
||||
use artcraft_api_defs::web_referrals::log_web_referral::*;
|
||||
use artcraft_api_defs::video_info::read_only::*;
|
||||
use artcraft_api_defs::video_info::upload::*;
|
||||
use artcraft_api_defs::video_info::notes::*;
|
||||
use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_model_type::UploadedVideoNoteReportedModelType;
|
||||
use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_website::UploadedVideoNoteReportedWebsite;
|
||||
use crate::http_server::endpoints::video_info::video_info_read_info_handler::*;
|
||||
use crate::http_server::endpoints::video_info::video_info_upload_handler::*;
|
||||
use crate::http_server::endpoints::video_info::video_info_notes_handler::*;
|
||||
use crate::http_server::endpoints::web_referrals::log_web_referral_handler::*;
|
||||
use crate::http_server::endpoints::image_studio::update_gpt_image_job_status_handler::*;
|
||||
use crate::http_server::endpoints::voice_conversion::enqueue_seed_vc_inference_handler::*;
|
||||
@@ -623,6 +627,7 @@ use crate::http_server::endpoints::media_files::list::list_batch_generated_redux
|
||||
// Web Referrals
|
||||
crate::http_server::endpoints::video_info::video_info_read_info_handler::video_info_read_info_handler,
|
||||
crate::http_server::endpoints::video_info::video_info_upload_handler::video_info_upload_handler,
|
||||
crate::http_server::endpoints::video_info::video_info_notes_handler::video_info_notes_handler,
|
||||
crate::http_server::endpoints::web_referrals::log_web_referral_handler::log_web_referral_handler,
|
||||
// User Referral Codes
|
||||
crate::http_server::endpoints::user_referral_codes::create_referral_code_handler::create_referral_code_handler,
|
||||
@@ -1260,6 +1265,10 @@ use crate::http_server::endpoints::media_files::list::list_batch_generated_redux
|
||||
VideoInfoReadOnlyResponse,
|
||||
VideoInfoUploadForm,
|
||||
VideoInfoUploadResponse,
|
||||
VideoInfoNoteRequest,
|
||||
VideoInfoNoteResponse,
|
||||
UploadedVideoNoteReportedModelType,
|
||||
UploadedVideoNoteReportedWebsite,
|
||||
VideoProvenanceKind,
|
||||
SeedanceVideoInfo,
|
||||
VeoVideoInfo,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod provenance;
|
||||
pub mod video_info_notes_handler;
|
||||
pub mod video_info_read_info_handler;
|
||||
pub mod video_info_upload_handler;
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
//! `POST /v1/video_info/notes` — attach (or update) a user-submitted note about
|
||||
//! an uploaded video.
|
||||
//!
|
||||
//! Always tied to an `UploadedVideoToken`. If the request carries an
|
||||
//! `UploadVideoNoteToken`, the existing note is updated; otherwise a new note is
|
||||
//! created. The IP address is stamped on the create or update column accordingly.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web::Json;
|
||||
use actix_web::{web, HttpRequest};
|
||||
|
||||
use artcraft_api_defs::video_info::notes::{VideoInfoNoteRequest, VideoInfoNoteResponse};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use mysql_queries::queries::uploaded_video_notes::insert_uploaded_video_note::{
|
||||
insert_uploaded_video_note, InsertUploadedVideoNoteArgs,
|
||||
};
|
||||
use mysql_queries::queries::uploaded_video_notes::update_uploaded_video_note::{
|
||||
update_uploaded_video_note, UpdateUploadedVideoNoteArgs,
|
||||
};
|
||||
|
||||
use crate::http_server::common_responses::common_web_error::CommonWebError;
|
||||
use crate::http_server::web_utils::redis_rate_limiter::RateLimiterError;
|
||||
use crate::state::server_state::ServerState;
|
||||
|
||||
/// Create or update a note about an uploaded video.
|
||||
#[utoipa::path(
|
||||
post,
|
||||
tag = "Video Info",
|
||||
path = "/v1/video_info/notes",
|
||||
request_body = VideoInfoNoteRequest,
|
||||
responses(
|
||||
(status = 200, description = "Note created or updated", body = VideoInfoNoteResponse),
|
||||
(status = 400, description = "Bad input", body = CommonWebError),
|
||||
(status = 500, description = "Server error", body = CommonWebError),
|
||||
)
|
||||
)]
|
||||
pub async fn video_info_notes_handler(
|
||||
http_request: HttpRequest,
|
||||
server_state: web::Data<Arc<ServerState>>,
|
||||
Json(request): Json<VideoInfoNoteRequest>,
|
||||
) -> Result<Json<VideoInfoNoteResponse>, CommonWebError> {
|
||||
// IP-based rate limit (shared with the other video-info endpoints). Fails open.
|
||||
match server_state.redis_rate_limiters.video_info_read_only.rate_limit_request(&http_request).await {
|
||||
Ok(()) => {}
|
||||
Err(RateLimiterError::RateLimitExceededError) => return Err(CommonWebError::TooManyRequests),
|
||||
Err(RateLimiterError::ClientError) => {} // fail open
|
||||
}
|
||||
|
||||
let ip_address = get_request_ip(&http_request);
|
||||
|
||||
// Free-form text fields are trimmed; empty becomes absent.
|
||||
let maybe_filename = request.maybe_filename.as_deref();
|
||||
let maybe_reported_model_name = normalize_optional(&request.maybe_reported_model_name);
|
||||
let maybe_other_website = normalize_optional(&request.maybe_other_website);
|
||||
let maybe_comments = normalize_optional(&request.maybe_comments);
|
||||
|
||||
let mut mysql_connection = server_state.mysql_pool.acquire().await?;
|
||||
|
||||
let uploaded_video_note_token = match &request.maybe_uploaded_video_note_token {
|
||||
// Update an existing note.
|
||||
Some(note_token) => {
|
||||
update_uploaded_video_note(UpdateUploadedVideoNoteArgs {
|
||||
token: note_token,
|
||||
maybe_filename,
|
||||
maybe_reported_model_type: request.maybe_reported_model_type,
|
||||
maybe_reported_model_name: maybe_reported_model_name.as_deref(),
|
||||
maybe_website: request.maybe_website,
|
||||
maybe_other_website: maybe_other_website.as_deref(),
|
||||
maybe_comments: maybe_comments.as_deref(),
|
||||
maybe_comment_update_ip_address: Some(ip_address.as_str()),
|
||||
mysql_executor: &mut *mysql_connection,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
.await?;
|
||||
note_token.clone()
|
||||
}
|
||||
// Create a new note.
|
||||
None => {
|
||||
insert_uploaded_video_note(InsertUploadedVideoNoteArgs {
|
||||
uploaded_video_token: &request.uploaded_video_token,
|
||||
maybe_filename,
|
||||
maybe_reported_model_type: request.maybe_reported_model_type,
|
||||
maybe_reported_model_name: maybe_reported_model_name.as_deref(),
|
||||
maybe_website: request.maybe_website,
|
||||
maybe_other_website: maybe_other_website.as_deref(),
|
||||
maybe_comments: maybe_comments.as_deref(),
|
||||
comment_create_ip_address: &ip_address,
|
||||
mysql_executor: &mut *mysql_connection,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Json(VideoInfoNoteResponse {
|
||||
success: true,
|
||||
uploaded_video_note_token,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Trim a free-form text field; a missing or whitespace-only value becomes `None`.
|
||||
fn normalize_optional(value: &Option<String>) -> Option<String> {
|
||||
value
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|trimmed| !trimmed.is_empty())
|
||||
.map(str::to_string)
|
||||
}
|
||||
+5
@@ -4,6 +4,7 @@ use actix_web::dev::{ServiceRequest, ServiceResponse};
|
||||
use actix_web::error::Error;
|
||||
use actix_web::{web, App, HttpResponse};
|
||||
|
||||
use crate::http_server::endpoints::video_info::video_info_notes_handler::video_info_notes_handler;
|
||||
use crate::http_server::endpoints::video_info::video_info_read_info_handler::video_info_read_info_handler;
|
||||
use crate::http_server::endpoints::video_info::video_info_upload_handler::video_info_upload_handler;
|
||||
|
||||
@@ -27,5 +28,9 @@ where
|
||||
.route(web::post().to(video_info_upload_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::resource("/notes")
|
||||
.route(web::post().to(video_info_notes_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user