mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 11:03:27 +00:00
Mostly working Cloud Uploading
This commit is contained in:
parent
bc847f6994
commit
913d178170
|
@ -66,7 +66,7 @@ once_cell = { workspace = true }
|
|||
pin-project-lite = { workspace = true }
|
||||
prisma-client-rust = { workspace = true, features = ["rspc"] }
|
||||
regex = { workspace = true }
|
||||
reqwest = { workspace = true, features = ["json", "native-tls-vendored"] }
|
||||
reqwest = { workspace = true, features = ["json", "native-tls-vendored","stream"] }
|
||||
rmp-serde = { workspace = true }
|
||||
rmpv = { workspace = true }
|
||||
rspc = { workspace = true, features = [
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use crate::p2p::{operations, ConnectionMethod, DiscoveryMethod, Header, P2PEvent, PeerMetadata};
|
||||
use crate::{
|
||||
api::utils::library,
|
||||
location::LocationPubId,
|
||||
p2p::{operations, ConnectionMethod, DiscoveryMethod, Header, P2PEvent, PeerMetadata},
|
||||
};
|
||||
|
||||
use sd_p2p::{PeerConnectionCandidate, RemoteIdentity};
|
||||
|
||||
|
@ -7,6 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||
use specta::Type;
|
||||
use std::{path::PathBuf, sync::PoisonError};
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tracing::{debug, info};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{Ctx, R};
|
||||
|
@ -175,4 +180,132 @@ pub(crate) fn mount() -> AlphaRouter<Ctx> {
|
|||
Ok(())
|
||||
})
|
||||
})
|
||||
.procedure("spacedropCloud", {
|
||||
#[derive(Type, Deserialize, Debug)]
|
||||
pub struct SpacedropCloudArgs {
|
||||
file_paths: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
R.with2(library())
|
||||
.mutation(|(node, library), args: SpacedropCloudArgs| async move {
|
||||
debug!("spacedropCloud args: {:?}", args);
|
||||
// For each file, return a dictionary with the file path, size, name and mime type
|
||||
let files = args
|
||||
.file_paths
|
||||
.into_iter()
|
||||
.map(|path| {
|
||||
let file = std::fs::File::open(&path).unwrap();
|
||||
let metadata = file.metadata().unwrap();
|
||||
// let extension = path.extension().unwrap().to_str().unwrap();
|
||||
let name = path.file_name().unwrap().to_str().unwrap().to_string();
|
||||
|
||||
(name, metadata.len(), path)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let json = serde_json::json!({
|
||||
"name": files[0].0,
|
||||
"size": files[0].1,
|
||||
});
|
||||
|
||||
debug!("spacedropCloud json: {:?}", json);
|
||||
|
||||
let req = reqwest::Client::new()
|
||||
.post("https://app.spacedrive.com/api/v1/spacedrop")
|
||||
.json(&json);
|
||||
|
||||
let req_with_auth = node.add_auth_header(req).await;
|
||||
|
||||
let res_1 = req_with_auth.send().await.map_err(|err| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error sending request: {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
|
||||
if res_1.status() != 200 {
|
||||
return Err(rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error creating spacedrop for cloud: {:?}", res_1.status()),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
let res = &res_1.text().await.map_err(|err| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error reading response: {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
let res_obj =
|
||||
serde_json::from_str::<serde_json::Value>(&res).map_err(|err| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error parsing response: {:?}", err),
|
||||
)
|
||||
})?;
|
||||
let id = res_obj["id"].as_str().ok_or_else(|| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
"missing id in response".into(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let upload_url = res_obj["url"].as_str().ok_or_else(|| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
"missing url in response".into(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let file_stream = std::fs::File::open(&files[0].2).map_err(|err| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error opening file: {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
let file_stream = tokio::fs::File::from_std(file_stream);
|
||||
let _ = reqwest::Client::new()
|
||||
.put(upload_url)
|
||||
.header("content-length", files[0].1)
|
||||
.body(reqwest::Body::wrap_stream(
|
||||
tokio_util::io::ReaderStream::new(file_stream),
|
||||
)).send().await.map_err(|err| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error sending request: {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
debug!("spacedropCloud finalize url: {}", "https://app.spacedrive.com/api/v1/spacedrop/".to_owned() + id);
|
||||
let req = reqwest::Client::new()
|
||||
.put("https://app.spacedrive.com/api/v1/spacedrop/".to_owned() + id);
|
||||
|
||||
let req_with_auth = node.add_auth_header(req).await;
|
||||
|
||||
let res = req_with_auth.send().await.map_err(|err| {
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error sending request: {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
if res.status() != 200 {
|
||||
return Err(rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
format!("error finalizing spacedrop: {:?}", res.status()),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
debug!("spacedropCloud finalize response: {:?}", res);
|
||||
|
||||
info!("spacedropCloud implement");
|
||||
|
||||
Ok(vec!["https://app.spacedrive.com/api/v1/spacedrop/".to_owned() + id])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { FileX, Share as ShareIcon } from '@phosphor-icons/react';
|
||||
import { useMemo } from 'react';
|
||||
import { useBridgeMutation, useDiscoveredPeers, useSelector } from '@sd/client';
|
||||
import { ContextMenu, ModifierKeys } from '@sd/ui';
|
||||
import { useBridgeMutation, useDiscoveredPeers, useLibraryMutation, useSelector } from '@sd/client';
|
||||
import { ContextMenu, ModifierKeys, toast } from '@sd/ui';
|
||||
import { Menu } from '~/components/Menu';
|
||||
import { useLocale, useOperatingSystem } from '~/hooks';
|
||||
import { useKeybindFactory } from '~/hooks/useKeybindFactory';
|
||||
|
@ -215,22 +215,47 @@ const SpacedropNodes = () => {
|
|||
const discoveredPeers = useDiscoveredPeers();
|
||||
|
||||
const spacedrop = useBridgeMutation('p2p.spacedrop');
|
||||
const spacedropCloud = useLibraryMutation('p2p.spacedropCloud', {
|
||||
onSuccess: (links) => {
|
||||
console.log('success');
|
||||
console.log(links);
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log('error');
|
||||
toast.error(error.message);
|
||||
}
|
||||
});
|
||||
|
||||
if (discoveredPeers.size === 0) {
|
||||
return <p className="p-1 text-center text-sm">{t('no_nodes_found')}</p>;
|
||||
}
|
||||
// if (discoveredPeers.size === 0) {
|
||||
// // return <p className="p-1 text-center text-sm">{t('no_nodes_found')}</p>;
|
||||
// return <button className="p-1 text-center text-sm text-white" onClick={() => {
|
||||
|
||||
return Array.from(discoveredPeers).map(([id, peer]) => (
|
||||
<Menu.Item
|
||||
key={id}
|
||||
label={peer.metadata.name}
|
||||
disabled={spacedrop.isLoading}
|
||||
onClick={async () => {
|
||||
spacedrop.mutateAsync({
|
||||
identity: id,
|
||||
file_path: await getPaths([...explorer.selectedItems])
|
||||
});
|
||||
}}
|
||||
/>
|
||||
));
|
||||
// }}>Send to Cloud [TEMP]</button>;
|
||||
// }
|
||||
|
||||
return (
|
||||
<>
|
||||
{Array.from(discoveredPeers).map(([id, peer]) => (
|
||||
<Menu.Item
|
||||
key={id}
|
||||
label={peer.metadata.name}
|
||||
disabled={spacedrop.isLoading}
|
||||
onClick={async () => {
|
||||
spacedrop.mutateAsync({
|
||||
identity: id,
|
||||
file_path: await getPaths([...explorer.selectedItems]),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<Menu.Item
|
||||
label={'Send to Cloud [TEMP]'}
|
||||
onClick={async () => {
|
||||
spacedropCloud.mutateAsync({
|
||||
file_paths: await getPaths([...explorer.selectedItems]),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -121,6 +121,7 @@ export type Procedures = {
|
|||
{ key: "p2p.cancelSpacedrop", input: string, result: null } |
|
||||
{ key: "p2p.debugConnect", input: RemoteIdentity, result: string } |
|
||||
{ key: "p2p.spacedrop", input: SpacedropArgs, result: string } |
|
||||
{ key: "p2p.spacedropCloud", input: LibraryArgs<SpacedropCloudArgs>, result: string[] } |
|
||||
{ key: "preferences.update", input: LibraryArgs<LibraryPreferences>, result: null } |
|
||||
{ key: "search.saved.create", input: LibraryArgs<{ name: string; target?: SearchTarget; search?: string | null; filters?: string | null; description?: string | null; icon?: string | null }>, result: null } |
|
||||
{ key: "search.saved.delete", input: LibraryArgs<number>, result: null } |
|
||||
|
@ -573,6 +574,8 @@ export type SortOrder = "Asc" | "Desc"
|
|||
|
||||
export type SpacedropArgs = { identity: RemoteIdentity; file_path: string[] }
|
||||
|
||||
export type SpacedropCloudArgs = { file_paths: string[] }
|
||||
|
||||
export type Statistics = { id: number; date_captured: string; total_object_count: number; library_db_size: string; total_bytes_used: string; total_bytes_capacity: string; total_unique_bytes: string; total_bytes_free: string; preview_media_bytes: string }
|
||||
|
||||
export type StatisticsResponse = { statistics: Statistics | null }
|
||||
|
|
Loading…
Reference in a new issue