Skip to content

Commit ecddfb7

Browse files
abstract another endpoint into api module
1 parent 7a4d428 commit ecddfb7

File tree

3 files changed

+70
-71
lines changed

3 files changed

+70
-71
lines changed

apps/desktop/src-tauri/src/api.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,55 @@ pub async fn upload_multipart_complete(
160160
.map_err(|err| format!("api/upload_multipart_complete/response: {err}"))
161161
.map(|data| data.location)
162162
}
163+
164+
#[derive(Serialize)]
165+
#[serde(rename_all = "lowercase")]
166+
pub enum PresignedS3PutRequestMethod {
167+
#[allow(unused)]
168+
Post,
169+
Put,
170+
}
171+
172+
#[derive(Serialize)]
173+
#[serde(rename_all = "camelCase")]
174+
pub struct PresignedS3PutRequest {
175+
pub video_id: String,
176+
pub subpath: String,
177+
pub method: PresignedS3PutRequestMethod,
178+
#[serde(flatten)]
179+
pub meta: Option<S3VideoMeta>,
180+
}
181+
182+
pub async fn upload_signed(app: &AppHandle, body: PresignedS3PutRequest) -> Result<String, String> {
183+
#[derive(Deserialize)]
184+
struct Data {
185+
url: String,
186+
}
187+
188+
#[derive(Deserialize)]
189+
#[serde(rename_all = "camelCase")]
190+
pub struct Response {
191+
presigned_put_data: Data,
192+
}
193+
194+
let resp = app
195+
.authed_api_request("/api/upload/signed", |client, url| {
196+
client.post(url).json(&body)
197+
})
198+
.await
199+
.map_err(|err| format!("api/upload_signed/request: {err}"))?;
200+
201+
if !resp.status().is_success() {
202+
let status = resp.status();
203+
let error_body = resp
204+
.text()
205+
.await
206+
.unwrap_or_else(|_| "<no response body>".to_string());
207+
return Err(format!("api/upload_signed/{status}: {error_body}"));
208+
}
209+
210+
resp.json::<Response>()
211+
.await
212+
.map_err(|err| format!("api/upload_signed/response: {err}"))
213+
.map(|data| data.presigned_put_data.url)
214+
}

apps/desktop/src-tauri/src/recording.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ use tracing::{debug, error, info};
2424
use crate::{
2525
App, CurrentRecordingChanged, MutableState, NewStudioRecordingAdded, RecordingState,
2626
RecordingStopped, VideoUploadInfo,
27+
api::{PresignedS3PutRequest, PresignedS3PutRequestMethod},
2728
audio::AppSounds,
2829
auth::AuthStore,
2930
create_screenshot,
3031
general_settings::{GeneralSettingsStore, PostDeletionBehaviour, PostStudioRecordingBehaviour},
3132
open_external_link,
3233
presets::PresetsStore,
3334
upload::{
34-
InstantMultipartUpload, PresignedS3PutRequest, PresignedS3PutRequestMethod,
35-
build_video_meta, bytes_into_stream, compress_image, create_or_get_video,
36-
do_presigned_upload, upload_video,
35+
InstantMultipartUpload, build_video_meta, bytes_into_stream, compress_image,
36+
create_or_get_video, do_presigned_upload, upload_video,
3737
},
3838
web_api::ManagerExt,
3939
windows::{CapWindowId, ShowCapWindow},
@@ -817,7 +817,7 @@ async fn handle_recording_finish(
817817
&app,
818818
stream,
819819
total_size,
820-
crate::upload::PresignedS3PutRequest {
820+
crate::api::PresignedS3PutRequest {
821821
video_id: video_upload_info.id.clone(),
822822
subpath: "screenshot/screen-capture.jpg".to_string(),
823823
method: PresignedS3PutRequestMethod::Put,

apps/desktop/src-tauri/src/upload.rs

Lines changed: 14 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// credit @filleduchaos
22

3-
use crate::api::{S3VideoMeta, UploadedPart};
3+
use crate::api::{PresignedS3PutRequest, PresignedS3PutRequestMethod, S3VideoMeta, UploadedPart};
44
use crate::web_api::ManagerExt;
55
use crate::{UploadProgress, VideoUploadInfo, api};
66
use async_stream::{stream, try_stream};
@@ -290,7 +290,7 @@ pub async fn do_presigned_upload(
290290
) -> Result<(), String> {
291291
set_progress(UploadPartProgress::Presigning);
292292
let client = reqwest::Client::new();
293-
let presigned_url = presigned_s3_put(app, request).await?;
293+
let presigned_url = api::upload_signed(app, request).await?;
294294

295295
set_progress(UploadPartProgress::Uploading {
296296
uploaded: 0,
@@ -423,55 +423,6 @@ pub async fn create_or_get_video(
423423
Ok(config)
424424
}
425425

426-
#[derive(Serialize)]
427-
#[serde(rename_all = "camelCase")]
428-
pub struct PresignedS3PutRequest {
429-
pub video_id: String,
430-
pub subpath: String,
431-
pub method: PresignedS3PutRequestMethod,
432-
#[serde(flatten)]
433-
pub meta: Option<S3VideoMeta>,
434-
}
435-
436-
#[derive(Serialize)]
437-
#[serde(rename_all = "lowercase")]
438-
pub enum PresignedS3PutRequestMethod {
439-
#[allow(unused)]
440-
Post,
441-
Put,
442-
}
443-
444-
async fn presigned_s3_put(app: &AppHandle, body: PresignedS3PutRequest) -> Result<String, String> {
445-
#[derive(Deserialize, Debug)]
446-
struct Data {
447-
url: String,
448-
}
449-
450-
#[derive(Deserialize, Debug)]
451-
#[serde(rename_all = "camelCase")]
452-
struct Wrapper {
453-
presigned_put_data: Data,
454-
}
455-
456-
let response = app
457-
.authed_api_request("/api/upload/signed", |client, url| {
458-
client.post(url).json(&body)
459-
})
460-
.await
461-
.map_err(|e| format!("Failed to send request to Next.js handler: {e}"))?;
462-
463-
if response.status() == StatusCode::UNAUTHORIZED {
464-
return Err("Failed to authenticate request; please log in again".into());
465-
}
466-
467-
let Wrapper { presigned_put_data } = response
468-
.json::<Wrapper>()
469-
.await
470-
.map_err(|e| format!("Failed to deserialize server response: {e}"))?;
471-
472-
Ok(presigned_put_data.url)
473-
}
474-
475426
pub fn build_video_meta(path: &PathBuf) -> Result<S3VideoMeta, String> {
476427
let input =
477428
ffmpeg::format::input(path).map_err(|e| format!("Failed to read input file: {e}"))?;
@@ -678,29 +629,25 @@ pub fn from_pending_file(
678629
match realtime_receiver.try_recv() {
679630
Ok(_) => realtime_is_done = Some(true),
680631
Err(flume::TryRecvError::Empty) => {},
681-
Err(_) => {
682-
todo!(); // TODO
683-
// return Err(std::io::Error::new(
684-
// std::io::ErrorKind::Interrupted,
685-
// "Realtime generation failed"
686-
// ));
687-
}
688-
}
632+
Err(_) => yield Err(std::io::Error::new(
633+
std::io::ErrorKind::Interrupted,
634+
"Realtime generation failed"
635+
))?,
636+
};
689637
}
690638
}
691639

692640
// Check file existence and size
693641
if !path.exists() {
694-
todo!();
695-
// return Err(std::io::Error::new(
696-
// std::io::ErrorKind::NotFound,
697-
// "File no longer exists"
698-
// ));
642+
yield Err(std::io::Error::new(
643+
std::io::ErrorKind::NotFound,
644+
"File no longer exists"
645+
))?;
699646
}
700647

701648
let file_size = match tokio::fs::metadata(&path).await {
702649
Ok(metadata) => metadata.len(),
703-
Err(e) => {
650+
Err(_) => {
704651
// Retry on metadata errors (file might be temporarily locked)
705652
tokio::time::sleep(Duration::from_millis(500)).await;
706653
continue;
@@ -727,7 +674,7 @@ pub fn from_pending_file(
727674
match file.read(&mut chunk[total_read..]).await {
728675
Ok(0) => break, // EOF
729676
Ok(n) => total_read += n,
730-
Err(e) => todo!(), // TODO: return Err(e),
677+
Err(e) => yield Err(e)?,
731678
}
732679
}
733680

@@ -762,7 +709,7 @@ pub fn from_pending_file(
762709
match file.read(&mut first_chunk[total_read..]).await {
763710
Ok(0) => break,
764711
Ok(n) => total_read += n,
765-
Err(e) => todo!(), // TODO: return Err(e),
712+
Err(e) => yield Err(e)?,
766713
}
767714
}
768715

0 commit comments

Comments
 (0)