Compare commits
8 Commits
import
...
message-qu
Author | SHA1 | Date | |
---|---|---|---|
7ada37f005 | |||
0a12cfcd57 | |||
a64b8fdceb | |||
a6b4f6917b | |||
585728de9d | |||
5a6346617a | |||
957858de59 | |||
f3c96e675b |
98
backend/public/Cargo.lock
generated
98
backend/public/Cargo.lock
generated
@ -104,7 +104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"axum-core 0.4.4",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
@ -113,7 +113,7 @@ dependencies = [
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"itoa",
|
||||
"matchit",
|
||||
"matchit 0.7.3",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
@ -123,9 +123,43 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper 1.0.1",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tower 0.5.1",
|
||||
"tower 0.5.2",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5"
|
||||
dependencies = [
|
||||
"axum-core 0.5.2",
|
||||
"bytes",
|
||||
"form_urlencoded",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"itoa",
|
||||
"matchit 0.8.4",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tower 0.5.2",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
@ -146,7 +180,27 @@ dependencies = [
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper 1.0.1",
|
||||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
@ -901,9 +955,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.158"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
@ -959,6 +1013,12 @@ version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.6"
|
||||
@ -1251,7 +1311,7 @@ dependencies = [
|
||||
name = "public"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
"dotenvy",
|
||||
"fred",
|
||||
@ -1920,12 +1980,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "1.0.1"
|
||||
@ -1992,9 +2046,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.40.0"
|
||||
version = "1.45.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
|
||||
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@ -2010,9 +2064,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -2061,14 +2115,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f"
|
||||
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"pin-project-lite",
|
||||
"sync_wrapper 0.1.2",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
@ -2109,7 +2163,7 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "313fa625fea5790ed56360a30ea980e41229cf482b4835801a67ef1922bf63b9"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"axum 0.7.6",
|
||||
"forwarded-header-value",
|
||||
"governor",
|
||||
"http",
|
||||
|
@ -7,7 +7,7 @@ authors = ["Wyatt J. Miller <wyatt@wyattjmiller.com"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
axum = { version = "0.7.6", features = ["http2", "tokio"] }
|
||||
axum = { version = "0.8.4", features = ["http2", "tokio"] }
|
||||
tower-http = { version = "0.6.1", features = ["trace", "cors"] }
|
||||
tower_governor = "0.4.2"
|
||||
tokio = { version = "1.40.0", features = ["full"] }
|
||||
|
@ -121,20 +121,11 @@ async fn main() {
|
||||
|
||||
// build our application with some routes
|
||||
let app = Router::new()
|
||||
.nest("/", routes::root::RootRoute::routes())
|
||||
.nest("/posts", routes::posts::PostsRoute::routes(&app_state))
|
||||
.nest(
|
||||
"/comments",
|
||||
routes::comments::CommentsRoute::routes(&app_state),
|
||||
)
|
||||
.nest(
|
||||
"/authors",
|
||||
routes::authors::AuthorsRoute::routes(&app_state),
|
||||
)
|
||||
.nest(
|
||||
"/projects",
|
||||
routes::projects::ProjectsRoute::routes(&app_state),
|
||||
)
|
||||
.merge(routes::root::RootRoute::routes())
|
||||
.merge(routes::posts::PostsRoute::routes(&app_state))
|
||||
.merge(routes::comments::CommentsRoute::routes(&app_state))
|
||||
.merge(routes::authors::AuthorsRoute::routes(&app_state))
|
||||
.merge(routes::projects::ProjectsRoute::routes(&app_state))
|
||||
.layer(CorsLayer::permissive())
|
||||
.layer(
|
||||
TraceLayer::new_for_http()
|
||||
|
@ -30,9 +30,9 @@ pub struct AuthorsRoute;
|
||||
impl AuthorsRoute {
|
||||
pub fn routes(app_state: &AppState) -> axum::Router {
|
||||
axum::Router::new()
|
||||
.route("/", get(AuthorsRoute::get_all))
|
||||
.route("/:id", get(AuthorsRoute::get_one))
|
||||
.route("/:id/posts", get(AuthorsRoute::get_authors_posts))
|
||||
.route("/authors", get(AuthorsRoute::get_all))
|
||||
.route("/authors/{id}", get(AuthorsRoute::get_one))
|
||||
.route("/authors/{id}/posts", get(AuthorsRoute::get_authors_posts))
|
||||
.with_state(app_state.clone())
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,9 @@ impl CommentsRoute {
|
||||
pub fn routes(app_state: &AppState) -> axum::Router {
|
||||
// add more comment routes here!
|
||||
axum::Router::new()
|
||||
.route("/post/:id", get(CommentsRoute::get_post_comments))
|
||||
.route("/add", post(CommentsRoute::insert_comment))
|
||||
.route("/index", get(CommentsRoute::get_comments_index))
|
||||
.route("/comments/post/{id}", get(CommentsRoute::get_post_comments))
|
||||
.route("/comments/add", post(CommentsRoute::insert_comment))
|
||||
.route("/comments/index", get(CommentsRoute::get_comments_index))
|
||||
.with_state(app_state.clone())
|
||||
}
|
||||
|
||||
|
@ -57,14 +57,14 @@ impl PostsRoute {
|
||||
pub fn routes(app_state: &AppState) -> Router {
|
||||
// add more post routes here!
|
||||
Router::new()
|
||||
.route("/all", get(PostsRoute::get_all))
|
||||
.route("/:id", get(PostsRoute::get_one))
|
||||
.route("/recent", get(PostsRoute::get_recent_posts))
|
||||
.route("/popular", get(PostsRoute::get_popular_posts))
|
||||
.route("/hot", get(PostsRoute::get_hot_posts))
|
||||
.route("/featured", get(PostsRoute::get_featured_posts))
|
||||
.route("/rss", get(PostsRoute::get_rss_posts))
|
||||
.route("/sitemap", get(PostsRoute::get_sitemap))
|
||||
.route("/posts/all", get(PostsRoute::get_all))
|
||||
.route("/posts/{id}", get(PostsRoute::get_one))
|
||||
.route("/posts/recent", get(PostsRoute::get_recent_posts))
|
||||
.route("/posts/popular", get(PostsRoute::get_popular_posts))
|
||||
.route("/posts/hot", get(PostsRoute::get_hot_posts))
|
||||
.route("/posts/featured", get(PostsRoute::get_featured_posts))
|
||||
.route("/posts/rss", get(PostsRoute::get_rss_posts))
|
||||
.route("/posts/sitemap", get(PostsRoute::get_sitemap))
|
||||
.with_state(app_state.clone())
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ pub struct ProjectsRoute;
|
||||
impl ProjectsRoute {
|
||||
pub fn routes(app_state: &AppState) -> Router {
|
||||
Router::new()
|
||||
.route("/", get(ProjectsRoute::get_all))
|
||||
.route("/projects", get(ProjectsRoute::get_all))
|
||||
.with_state(app_state.clone())
|
||||
}
|
||||
|
||||
|
2
backend/queue/.gitignore
vendored
Normal file
2
backend/queue/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target/
|
||||
.env
|
7
backend/queue/Cargo.lock
generated
Normal file
7
backend/queue/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "queue"
|
||||
version = "0.1.0"
|
6
backend/queue/Cargo.toml
Normal file
6
backend/queue/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "queue"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
14
backend/queue/src/lib.rs
Normal file
14
backend/queue/src/lib.rs
Normal file
@ -0,0 +1,14 @@
|
||||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
2
backend/storage/.gitignore
vendored
Normal file
2
backend/storage/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target/
|
||||
.env
|
3589
backend/storage/Cargo.lock
generated
Normal file
3589
backend/storage/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
backend/storage/Cargo.toml
Normal file
15
backend/storage/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "storage"
|
||||
description = "Internal object storage library"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
aws-sdk-s3 = "1.94.0"
|
||||
aws-config = "1.8"
|
||||
azure_core = "0.25.0"
|
||||
azure_storage = "0.21.0"
|
||||
azure_storage_blobs = "0.21.0"
|
||||
async-trait = "0.1"
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
thiserror = "2.0.12"
|
11
backend/storage/src/error.rs
Normal file
11
backend/storage/src/error.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use azure_core::error::HttpError;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AdapterError {
|
||||
#[error("Azure error: {0}")]
|
||||
Azure(#[from] azure_core::Error),
|
||||
#[error("HTTP error: {0}")]
|
||||
Http(#[from] HttpError),
|
||||
#[error("Serialization error: {0}")]
|
||||
Serialization(String),
|
||||
}
|
2
backend/storage/src/lib.rs
Normal file
2
backend/storage/src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod error;
|
||||
pub mod services;
|
101
backend/storage/src/services/aws.rs
Normal file
101
backend/storage/src/services/aws.rs
Normal file
@ -0,0 +1,101 @@
|
||||
use crate::{error::AdapterError, services::ObjectStorageClient};
|
||||
use async_trait::async_trait;
|
||||
use aws_config::{BehaviorVersion, Region};
|
||||
use aws_sdk_s3::{Client, Config, config::Credentials};
|
||||
use std::env;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct S3ClientConfig {
|
||||
pub access_key: String,
|
||||
secret_key: String,
|
||||
endpoint: String,
|
||||
pub bucket: String,
|
||||
region: String,
|
||||
}
|
||||
|
||||
pub struct S3Client {
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl S3ClientConfig {
|
||||
pub fn from_env() -> Result<Self, Box<dyn std::error::Error>> {
|
||||
Ok(S3ClientConfig {
|
||||
access_key: env::var("S3_ACCESS_KEY")
|
||||
.map_err(|_| "S3_ACCESS_KEY environment variable not set")?,
|
||||
secret_key: env::var("S3_SECRET_KEY")
|
||||
.map_err(|_| "S3_SECRET_KEY environment variable not set")?,
|
||||
endpoint: env::var("S3_ENDPOINT")
|
||||
.unwrap_or_else(|_| "us-ord-1.linodeobjects.com".to_string()),
|
||||
bucket: env::var("S3_BUCKET").map_err(|_| "S3_BUCKET environment variable not set")?,
|
||||
region: env::var("S3_REGION").unwrap_or_else(|_| "us-ord".to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl S3Client {
|
||||
pub fn new(config: &S3ClientConfig) -> Self {
|
||||
let credentials = Credentials::new(
|
||||
&config.access_key,
|
||||
&config.secret_key,
|
||||
None,
|
||||
None,
|
||||
"linode-object-storage",
|
||||
);
|
||||
|
||||
let s3_config = Config::builder()
|
||||
.behavior_version(BehaviorVersion::latest())
|
||||
.region(Region::new(config.region.clone()))
|
||||
.endpoint_url(format!("https://{}", config.endpoint))
|
||||
.credentials_provider(credentials)
|
||||
.force_path_style(false)
|
||||
.build();
|
||||
|
||||
Self {
|
||||
client: Client::from_conf(s3_config),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ObjectStorageClient for S3Client {
|
||||
type Error = AdapterError;
|
||||
|
||||
async fn put_object(&self, bucket: &str, key: &str, data: Vec<u8>) -> Result<(), Self::Error> {
|
||||
println!("Uploading to S3 (or S3 like) Object Storage...");
|
||||
println!("Bucket: {}", bucket);
|
||||
|
||||
let _ = self
|
||||
.client
|
||||
.put_object()
|
||||
.bucket(bucket)
|
||||
.key(key)
|
||||
.body(data.into())
|
||||
.acl(aws_sdk_s3::types::ObjectCannedAcl::PublicRead)
|
||||
.content_type("application/xml")
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_object(&self, _bucket: &str, _key: &str) -> Result<Vec<u8>, Self::Error> {
|
||||
todo!("not impl")
|
||||
}
|
||||
|
||||
async fn delete_object(&self, _bucket: &str, _key: &str) -> Result<(), Self::Error> {
|
||||
todo!("not impl")
|
||||
}
|
||||
|
||||
async fn list_objects(
|
||||
&self,
|
||||
_bucket: &str,
|
||||
_prefix: Option<&str>,
|
||||
) -> Result<Vec<String>, Self::Error> {
|
||||
todo!("not impl")
|
||||
}
|
||||
|
||||
async fn object_exists(&self, _bucket: &str, _key: &str) -> Result<bool, Self::Error> {
|
||||
todo!("not impl")
|
||||
}
|
||||
}
|
71
backend/storage/src/services/azure.rs
Normal file
71
backend/storage/src/services/azure.rs
Normal file
@ -0,0 +1,71 @@
|
||||
use crate::error::AdapterError;
|
||||
use async_trait::async_trait;
|
||||
use azure_storage::prelude::*;
|
||||
use azure_storage_blobs::prelude::*;
|
||||
|
||||
use super::ObjectStorageClient;
|
||||
|
||||
pub struct AzureBlobClient {
|
||||
client: BlobServiceClient,
|
||||
}
|
||||
|
||||
impl AzureBlobClient {
|
||||
pub fn new(account_name: &str, account_key: String) -> Self {
|
||||
let storage_credentials = StorageCredentials::access_key(account_name, account_key);
|
||||
let client = BlobServiceClient::new(account_name, storage_credentials);
|
||||
|
||||
Self { client }
|
||||
}
|
||||
|
||||
// Helper method to get container client
|
||||
fn get_container_client(&self, container_name: &str) -> ContainerClient {
|
||||
self.client.container_client(container_name)
|
||||
}
|
||||
|
||||
// Helper method to get blob client
|
||||
fn get_blob_client(&self, container_name: &str, blob_name: &str) -> BlobClient {
|
||||
self.get_container_client(container_name)
|
||||
.blob_client(blob_name)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ObjectStorageClient for AzureBlobClient {
|
||||
type Error = AdapterError;
|
||||
|
||||
async fn put_object(
|
||||
&self,
|
||||
bucket: &str, // container name
|
||||
key: &str, // blob name
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let blob_client = self.get_blob_client(bucket, key);
|
||||
let _request = blob_client.put_block_blob(data).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_object(&self, bucket: &str, key: &str) -> Result<Vec<u8>, Self::Error> {
|
||||
let blob_client = self.get_blob_client(bucket, key);
|
||||
|
||||
let response = blob_client.get_content().await.unwrap();
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
async fn delete_object(&self, bucket: &str, key: &str) -> Result<(), Self::Error> {
|
||||
let blob_client = self.get_blob_client(bucket, key);
|
||||
blob_client.delete().await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn list_objects(
|
||||
&self,
|
||||
_bucket: &str,
|
||||
_prefix: Option<&str>,
|
||||
) -> Result<Vec<String>, Self::Error> {
|
||||
todo!("not impl")
|
||||
}
|
||||
|
||||
async fn object_exists(&self, _bucket: &str, _key: &str) -> Result<bool, Self::Error> {
|
||||
todo!("not impl")
|
||||
}
|
||||
}
|
23
backend/storage/src/services/mod.rs
Normal file
23
backend/storage/src/services/mod.rs
Normal file
@ -0,0 +1,23 @@
|
||||
pub mod aws;
|
||||
pub mod azure;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait ObjectStorageClient {
|
||||
type Error;
|
||||
|
||||
async fn put_object(&self, bucket: &str, key: &str, data: Vec<u8>) -> Result<(), Self::Error>;
|
||||
|
||||
async fn get_object(&self, bucket: &str, key: &str) -> Result<Vec<u8>, Self::Error>;
|
||||
|
||||
async fn delete_object(&self, bucket: &str, key: &str) -> Result<(), Self::Error>;
|
||||
|
||||
async fn list_objects(
|
||||
&self,
|
||||
bucket: &str,
|
||||
prefix: Option<&str>,
|
||||
) -> Result<Vec<String>, Self::Error>;
|
||||
|
||||
async fn object_exists(&self, bucket: &str, key: &str) -> Result<bool, Self::Error>;
|
||||
}
|
@ -1 +0,0 @@
|
||||
DATABASE_URL=postgres://wyatt:wyattisawesome@192.168.100.253:5432/postgres
|
469
backend/task/Cargo.lock
generated
469
backend/task/Cargo.lock
generated
@ -2,6 +2,12 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "RustyXML"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b5ace29ee3216de37c0546865ad08edef58b0f9e76838ed8959a84a990e58c5"
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.1"
|
||||
@ -65,6 +71,52 @@ version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener 2.5.3",
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"futures-core",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
|
||||
dependencies = [
|
||||
"event-listener 5.3.1",
|
||||
"event-listener-strategy",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atoi"
|
||||
version = "2.0.0"
|
||||
@ -105,7 +157,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"aws-types",
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"hex",
|
||||
"http 1.2.0",
|
||||
"ring",
|
||||
@ -167,7 +219,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"aws-types",
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"percent-encoding",
|
||||
@ -196,7 +248,7 @@ dependencies = [
|
||||
"aws-smithy-xml",
|
||||
"aws-types",
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"hex",
|
||||
"hmac",
|
||||
"http 0.2.12",
|
||||
@ -226,7 +278,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"aws-types",
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"http 0.2.12",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
@ -248,7 +300,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"aws-types",
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"http 0.2.12",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
@ -271,7 +323,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"aws-smithy-xml",
|
||||
"aws-types",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"http 0.2.12",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
@ -438,7 +490,7 @@ dependencies = [
|
||||
"aws-smithy-runtime-api",
|
||||
"aws-smithy-types",
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"http 0.2.12",
|
||||
"http 1.2.0",
|
||||
"http-body 0.4.6",
|
||||
@ -515,6 +567,111 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "azure_core"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b552ad43a45a746461ec3d3a51dfb6466b4759209414b439c165eb6a6b7729e"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"dyn-clone",
|
||||
"futures",
|
||||
"getrandom 0.2.15",
|
||||
"hmac",
|
||||
"http-types",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"pin-project",
|
||||
"quick-xml",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"time",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid 1.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "azure_core"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82c33c072c9d87777262f35abfe2a64b609437076551d4dac8373e60f0e3fde9"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures",
|
||||
"pin-project",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
"typespec",
|
||||
"typespec_client_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "azure_storage"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59f838159f4d29cb400a14d9d757578ba495ae64feb07a7516bf9e4415127126"
|
||||
dependencies = [
|
||||
"RustyXML",
|
||||
"async-lock",
|
||||
"async-trait",
|
||||
"azure_core 0.21.0",
|
||||
"bytes",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"time",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid 1.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "azure_storage_blobs"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97e83c3636ae86d9a6a7962b2112e3b19eb3903915c50ce06ff54ff0a2e6a7e4"
|
||||
dependencies = [
|
||||
"RustyXML",
|
||||
"azure_core 0.21.0",
|
||||
"azure_storage",
|
||||
"azure_svc_blobstorage",
|
||||
"bytes",
|
||||
"futures",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"time",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid 1.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "azure_svc_blobstorage"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e6c6f20c5611b885ba94c7bae5e02849a267381aecb8aee577e8c35ff4064c6"
|
||||
dependencies = [
|
||||
"azure_core 0.21.0",
|
||||
"bytes",
|
||||
"futures",
|
||||
"log",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
@ -536,6 +693,12 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
@ -872,6 +1035,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -909,6 +1073,12 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.14.8"
|
||||
@ -995,6 +1165,12 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "5.3.1"
|
||||
@ -1006,6 +1182,25 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener-strategy"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
|
||||
dependencies = [
|
||||
"event-listener 5.3.1",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
@ -1022,6 +1217,16 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.11.0"
|
||||
@ -1134,6 +1339,21 @@ version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
|
||||
dependencies = [
|
||||
"fastrand 1.9.0",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"memchr",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
@ -1185,6 +1405,17 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
@ -1404,6 +1635,26 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-types"
|
||||
version = "2.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel",
|
||||
"base64 0.13.1",
|
||||
"futures-lite",
|
||||
"infer",
|
||||
"pin-project-lite",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_qs",
|
||||
"serde_urlencoded",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.10.0"
|
||||
@ -1676,6 +1927,21 @@ dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
@ -2137,6 +2403,26 @@ version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
@ -2229,6 +2515,16 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.8"
|
||||
@ -2299,6 +2595,19 @@ version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@ -2320,6 +2629,16 @@ dependencies = [
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
@ -2340,6 +2659,15 @@ dependencies = [
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
@ -2358,6 +2686,15 @@ dependencies = [
|
||||
"getrandom 0.3.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.4"
|
||||
@ -2423,10 +2760,12 @@ version = "0.12.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.4.10",
|
||||
"http 1.2.0",
|
||||
"http-body 1.0.1",
|
||||
@ -2451,12 +2790,14 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls 0.26.2",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"webpki-roots 1.0.1",
|
||||
]
|
||||
@ -2774,6 +3115,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_qs"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror 1.0.63",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
@ -2960,7 +3312,7 @@ dependencies = [
|
||||
"crc",
|
||||
"crossbeam-queue",
|
||||
"either",
|
||||
"event-listener",
|
||||
"event-listener 5.3.1",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-intrusive",
|
||||
@ -3141,6 +3493,20 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "storage"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"aws-config",
|
||||
"aws-sdk-s3",
|
||||
"azure_core 0.25.0",
|
||||
"azure_storage",
|
||||
"azure_storage_blobs",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.5"
|
||||
@ -3214,8 +3580,6 @@ dependencies = [
|
||||
name = "task"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aws-config",
|
||||
"aws-sdk-s3",
|
||||
"chrono",
|
||||
"dotenvy",
|
||||
"futures",
|
||||
@ -3226,6 +3590,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_yml",
|
||||
"sqlx",
|
||||
"storage",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
@ -3238,7 +3603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"fastrand 2.3.0",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
@ -3301,6 +3666,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"js-sys",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
@ -3551,6 +3918,56 @@ version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "typespec"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04c7a952f1f34257f945fc727b20defe7a3c01c05ddd42925977626cfa6e62ab"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typespec_client_core"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5879ce67ba9e525fe088c882ede1337c32c3f80e83e72d9fd3cc6c8e05bcb3d7"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"dyn-clone",
|
||||
"futures",
|
||||
"getrandom 0.2.15",
|
||||
"pin-project",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"typespec",
|
||||
"typespec_macros",
|
||||
"url",
|
||||
"uuid 1.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typespec_macros"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cbccdbe531c8d553812a609bdb70c0d1002ad91333498e18df42c98744b15cc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.15"
|
||||
@ -3605,6 +4022,7 @@ dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3633,6 +4051,10 @@ name = "uuid"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
|
||||
dependencies = [
|
||||
"getrandom 0.3.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
@ -3658,6 +4080,12 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
@ -3667,6 +4095,12 @@ dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
@ -3759,6 +4193,19 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.77"
|
||||
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
storage = { version = "0.1.0", path = "../storage" }
|
||||
tokio = { version = "1.19.2", features = ["full"] }
|
||||
reqwest = { version = "0.12.20", features = ["json", "rustls-tls"] }
|
||||
job_scheduler = "1.2.1"
|
||||
@ -21,7 +22,5 @@ futures = "0.3.30"
|
||||
markdown = "1.0.0-alpha.20"
|
||||
serde = { version = "*", features = ["derive"] }
|
||||
serde_yml = "*"
|
||||
aws-sdk-s3 = "1.94.0"
|
||||
aws-config = "1.8"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
|
@ -29,6 +29,7 @@ pub struct TaskLog {
|
||||
#[derive(Debug)]
|
||||
pub enum TaskStatus {
|
||||
Pending(String),
|
||||
Running(String),
|
||||
Completed(String),
|
||||
Failed(String),
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
use sqlx::{Pool, Postgres};
|
||||
|
||||
use crate::utils::{
|
||||
request::{Request, Response},
|
||||
task_log,
|
||||
{upload::S3ClientConfig, *},
|
||||
};
|
||||
use storage::services::{
|
||||
aws::{S3Client, S3ClientConfig},
|
||||
ObjectStorageClient,
|
||||
};
|
||||
|
||||
pub fn register(pool: &sqlx::Pool<sqlx::Postgres>) {
|
||||
@ -25,14 +26,14 @@ async fn upload_rss(pool: &sqlx::Pool<sqlx::Postgres>) -> Result<(), Box<dyn std
|
||||
// upload the sucker to obj storage
|
||||
if let Response::Xml(rss) = rss_result {
|
||||
let client_config = S3ClientConfig::from_env().unwrap();
|
||||
let s3_client = upload::create_s3_client(&client_config).await.unwrap();
|
||||
let _ = upload::upload(
|
||||
&s3_client,
|
||||
client_config.bucket.as_str(),
|
||||
"feed.xml",
|
||||
rss.as_str(),
|
||||
)
|
||||
.await;
|
||||
let s3_client = S3Client::new(&client_config);
|
||||
let _ = s3_client
|
||||
.put_object(
|
||||
client_config.bucket.as_str(),
|
||||
"feed.xml",
|
||||
rss.as_bytes().to_vec(),
|
||||
)
|
||||
.await;
|
||||
println!("Finished uploading RSS feed");
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
use crate::utils::{
|
||||
request::{Request, Response},
|
||||
task_log,
|
||||
{upload::S3ClientConfig, *},
|
||||
};
|
||||
use storage::services::{
|
||||
aws::{S3Client, S3ClientConfig},
|
||||
ObjectStorageClient,
|
||||
};
|
||||
|
||||
pub fn register(pool: &sqlx::Pool<sqlx::Postgres>) {
|
||||
@ -14,25 +17,25 @@ pub fn register(pool: &sqlx::Pool<sqlx::Postgres>) {
|
||||
async fn upload_sitemap(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
// TODO:: get sitemap and upload it to bucket??
|
||||
// start task logging
|
||||
task_log::start(3, pool).await?;
|
||||
|
||||
// get request and request the things
|
||||
let request = Request::new();
|
||||
let sitemap_url = format!("{}/posts/sitemap", request.base_url);
|
||||
let sitemap_result = request.request_url::<String>(&sitemap_url).await;
|
||||
let sitemap_result = request.request_url::<String>(&sitemap_url).await.unwrap();
|
||||
|
||||
// upload the sucker to obj storage
|
||||
if let Response::Xml(sitemap) = sitemap_result {
|
||||
let client_config = S3ClientConfig::from_env().unwrap();
|
||||
let s3_client = upload::create_s3_client(&client_config).await.unwrap();
|
||||
let _ = upload::upload(
|
||||
&s3_client,
|
||||
client_config.bucket.as_str(),
|
||||
"sitemap.xml",
|
||||
sitemap.as_str(),
|
||||
)
|
||||
.await;
|
||||
let s3_client = S3Client::new(&client_config);
|
||||
let _ = s3_client
|
||||
.put_object(
|
||||
client_config.bucket.as_str(),
|
||||
"sitemap.xml",
|
||||
sitemap.as_bytes().to_vec(),
|
||||
)
|
||||
.await;
|
||||
println!("Finished uploading sitemap!");
|
||||
}
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
use aws_config::{BehaviorVersion, Region};
|
||||
use aws_sdk_s3::{config::Credentials, Client, Config};
|
||||
use std::env;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct S3ClientConfig {
|
||||
pub access_key: String,
|
||||
secret_key: String,
|
||||
endpoint: String,
|
||||
pub bucket: String,
|
||||
region: String,
|
||||
}
|
||||
|
||||
impl S3ClientConfig {
|
||||
pub fn from_env() -> Result<Self, Box<dyn std::error::Error>> {
|
||||
Ok(S3ClientConfig {
|
||||
access_key: env::var("LINODE_ACCESS_KEY")
|
||||
.map_err(|_| "LINODE_ACCESS_KEY environment variable not set")?,
|
||||
secret_key: env::var("LINODE_SECRET_KEY")
|
||||
.map_err(|_| "LINODE_SECRET_KEY environment variable not set")?,
|
||||
endpoint: env::var("LINODE_ENDPOINT")
|
||||
.unwrap_or_else(|_| "us-ord-1.linodeobjects.com".to_string()),
|
||||
bucket: env::var("LINODE_BUCKET")
|
||||
.map_err(|_| "LINODE_BUCKET environment variable not set")?,
|
||||
region: env::var("LINODE_REGION").unwrap_or_else(|_| "us-ord".to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create_s3_client(
|
||||
config: &S3ClientConfig,
|
||||
) -> Result<Client, Box<dyn std::error::Error>> {
|
||||
let credentials = Credentials::new(
|
||||
&config.access_key,
|
||||
&config.secret_key,
|
||||
None,
|
||||
None,
|
||||
"linode-object-storage",
|
||||
);
|
||||
|
||||
let s3_config = Config::builder()
|
||||
.behavior_version(BehaviorVersion::latest())
|
||||
.region(Region::new(config.region.clone()))
|
||||
.endpoint_url(format!("https://{}", config.endpoint))
|
||||
.credentials_provider(credentials)
|
||||
.force_path_style(false)
|
||||
.build();
|
||||
|
||||
Ok(Client::from_conf(s3_config))
|
||||
}
|
||||
|
||||
pub async fn upload(
|
||||
client: &Client,
|
||||
bucket: &str,
|
||||
key: &str,
|
||||
content: &str,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Uploading to Linode Object Storage...");
|
||||
println!("Bucket: {}", bucket);
|
||||
|
||||
let put_object_req = client
|
||||
.put_object()
|
||||
.bucket(bucket)
|
||||
.key(key)
|
||||
.body(content.as_bytes().to_vec().into())
|
||||
.acl(aws_sdk_s3::types::ObjectCannedAcl::PublicRead)
|
||||
.content_type("application/rss+xml")
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
println!("Upload successful! ETag: {:?}", put_object_req.e_tag());
|
||||
Ok(())
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ export default function Footer() {
|
||||
<div class="space-y-2">
|
||||
<a
|
||||
class="mb-8 text-[#cdd6f4] transition-all duration-300 ease-in-out hover:text-[#cba6f7] hover:drop-shadow-[0_0_20px_rgba(96,165,250,0.7)] hover:scale-110 cursor-pointer visited:text-[#bac2de]"
|
||||
href={`${Deno.env.get("BASE_URI_API")}/posts/rss`}
|
||||
href={Deno.env.get("BASE_URI_RSS")}
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<hi.HiOutlineRss />
|
||||
@ -18,7 +18,7 @@ export default function Footer() {
|
||||
</a>
|
||||
<a
|
||||
class="mb-8 text-[#cdd6f4] transition-all duration-300 ease-in-out hover:text-[#cba6f7] hover:drop-shadow-[0_0_20px_rgba(96,165,250,0.7)] hover:scale-110 cursor-pointer visited:text-[#bac2de]"
|
||||
href="/sitemap.xml"
|
||||
href={Deno.env.get("BASE_URI_SITEMAP")}
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<hi.HiOutlineMap />
|
||||
@ -28,7 +28,10 @@ export default function Footer() {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a class="mb-8 text-[#cdd6f4] transition-all duration-300 ease-in-out hover:text-[#cba6f7] hover:drop-shadow-[0_0_20px_rgba(96,165,250,0.7)] hover:scale-110 cursor-pointer visited:text-[#bac2de]">
|
||||
<a
|
||||
class="mb-8 text-[#cdd6f4] transition-all duration-300 ease-in-out hover:text-[#cba6f7] hover:drop-shadow-[0_0_20px_rgba(96,165,250,0.7)] hover:scale-110 cursor-pointer visited:text-[#bac2de]"
|
||||
href="/resume.pdf"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<hi.HiOutlineBriefcase />
|
||||
Resume
|
||||
@ -43,12 +46,6 @@ export default function Footer() {
|
||||
Email me
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
class="mb-8 text-[#cdd6f4] transition-all duration-300 ease-in-out hover:text-[#cba6f7] hover:drop-shadow-[0_0_20px_rgba(96,165,250,0.7)] hover:scale-110 cursor-pointer visited:text-[#bac2de]"
|
||||
href="https://github.com/wymillerlinux"
|
||||
>
|
||||
<div class="flex items-center gap-2">GitHub</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2,10 +2,13 @@ import { Post } from "../types/index.ts";
|
||||
|
||||
export const PostBody = function PostBody({ post }: PostBodyOpts) {
|
||||
return (
|
||||
<div
|
||||
class="p-6 bg-[#313244] shadow-md text-[#f5e0dc] post-content"
|
||||
dangerouslySetInnerHTML={{ __html: post.body }}
|
||||
></div>
|
||||
<div class="mx-auto max-w-4xl p-4 bg-[#313244]">
|
||||
<div
|
||||
class="p-6 bg-[#45475a] shadow-md rounded-lg text-[#f5e0dc] post-content overflow-hidden break-words hyphens-auto max-w-full
|
||||
[&>*]:max-w-5xl [&>*]:overflow-wrap-anywhere"
|
||||
dangerouslySetInnerHTML={{ __html: post.body }}
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,7 @@ export const PostHeader = function PostHeader({ post }: PostHeaderOpts) {
|
||||
<Head>
|
||||
<title>Wyatt J. Miller | {post.title}</title>
|
||||
</Head>
|
||||
<div class="p-6 bg-[#313244] shadow-md">
|
||||
<div class="p-6 bg-[#313244]">
|
||||
<div class="min-w-screen flex flex-col items-center justify-between bg-[#45475a] rounded-lg shadow-md">
|
||||
<div class="sm:mt-14 sm:mb-14 mt-8 mb-8 flex flex-col items-center gap-y-5 gap-x-10 md:flex-row">
|
||||
<div class="space-y-2 text-center md:text-left">
|
||||
|
@ -8,7 +8,7 @@ export default function App({ Component }: PageProps) {
|
||||
<title>frontend</title>
|
||||
<link rel="stylesheet" href="/styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<body class="bg-[#313244]">
|
||||
<Component />
|
||||
</body>
|
||||
</html>
|
||||
|
Reference in New Issue
Block a user