Add pre-commit config

This commit is contained in:
2023-09-24 22:55:14 +02:00
parent 8fa9684b02
commit 72ca7a07fe
13 changed files with 231 additions and 220 deletions

View File

@@ -23,15 +23,13 @@ pub struct Config {
pub files_api_key: String,
pub files_url: String,
pub sentry_dsn: String
pub sentry_dsn: String,
}
fn get_env(env: &'static str) -> String {
std::env::var(env).unwrap_or_else(|_| panic!("Cannot get the {} env variable", env))
}
impl Config {
pub fn load() -> Config {
Config {
@@ -57,12 +55,9 @@ impl Config {
files_api_key: get_env("FILES_SERVER_API_KEY"),
files_url: get_env("FILES_SERVER_URL"),
sentry_dsn: get_env("SENTRY_DSN")
sentry_dsn: get_env("SENTRY_DSN"),
}
}
}
pub static CONFIG: Lazy<Config> = Lazy::new(|| {
Config::load()
});
pub static CONFIG: Lazy<Config> = Lazy::new(Config::load);

View File

@@ -1,5 +1,4 @@
use crate::{prisma::PrismaClient, config::CONFIG};
use crate::{config::CONFIG, prisma::PrismaClient};
pub async fn get_prisma_client() -> PrismaClient {
let database_url: String = format!(

View File

@@ -1,16 +1,15 @@
pub mod config;
pub mod db;
pub mod prisma;
pub mod views;
pub mod services;
pub mod views;
use sentry::{integrations::debug_images::DebugImagesIntegration, types::Dsn, ClientOptions};
use std::{net::SocketAddr, str::FromStr};
use sentry::{ClientOptions, types::Dsn, integrations::debug_images::DebugImagesIntegration};
use tracing::info;
use crate::views::get_router;
#[tokio::main]
async fn main() {
let options = ClientOptions {

View File

@@ -1,7 +1,8 @@
// Code generated by Prisma Client Rust. DO NOT EDIT
pub static DATAMODEL_STR: &str =
include_str!("../prisma/schema.prisma");
#![allow(clippy::all)]
pub static DATAMODEL_STR: &str = include_str!("../prisma/schema.prisma");
static DATABASE_STR: &str = "postgresql";
pub async fn new_client() -> Result<PrismaClient, ::prisma_client_rust::NewClientError> {
PrismaClient::_builder().build().await
@@ -21,9 +22,7 @@ pub mod cached_file {
pub mod id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -92,9 +91,7 @@ pub mod cached_file {
pub mod object_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "object_id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -167,9 +164,7 @@ pub mod cached_file {
pub mod object_type {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "object_type";
pub struct Set(pub String);
impl From<Set> for SetParam {
@@ -234,9 +229,7 @@ pub mod cached_file {
pub mod message_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "message_id";
pub struct Set(pub i64);
impl From<Set> for SetParam {
@@ -309,9 +302,7 @@ pub mod cached_file {
pub mod chat_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "chat_id";
pub struct Set(pub i64);
impl From<Set> for SetParam {

View File

@@ -60,7 +60,7 @@ pub async fn get_books(
("page", page.to_string()),
("size", page_size.to_string()),
("uploaded_gte", uploaded_gte),
("uploaded_lte", uploaded_lte)
("uploaded_lte", uploaded_lte),
];
_make_request("/api/v1/books/base/", params).await

View File

@@ -1,6 +1,5 @@
use serde::Deserialize;
#[derive(Deserialize, Debug, Clone)]
pub struct Source {
pub id: u32,
@@ -41,7 +40,7 @@ pub struct BookWithRemote {
#[derive(Deserialize, Debug, Clone)]
pub struct BaseBook {
pub id: i32,
pub available_types: Vec<String>
pub available_types: Vec<String>,
}
impl BookWithRemote {
@@ -59,7 +58,6 @@ impl BookWithRemote {
}
}
impl BookAuthor {
pub fn get_caption(self) -> String {
let mut parts: Vec<String> = vec![];
@@ -82,21 +80,13 @@ impl BookAuthor {
}
}
impl BookWithRemote {
pub fn get_caption(self) -> String {
let BookWithRemote {
title,
authors,
..
} = self;
let BookWithRemote { title, authors, .. } = self;
let caption_title = format!("📖 {title}");
let author_captions: Vec<String> = authors
.into_iter()
.map(|a| a.get_caption())
.collect();
let author_captions: Vec<String> = authors.into_iter().map(|a| a.get_caption()).collect();
let mut author_parts: Vec<String> = vec![];
let mut author_parts_len = 3;
@@ -116,7 +106,6 @@ impl BookWithRemote {
}
}
#[derive(Deserialize, Debug, Clone)]
pub struct Page<T> {
pub items: Vec<T>,

View File

@@ -1,4 +1,4 @@
use std::io::{Write, Seek, SeekFrom};
use std::io::{Seek, SeekFrom, Write};
use bytes::Buf;
use futures::TryStreamExt;
@@ -7,7 +7,6 @@ use tempfile::SpooledTempFile;
use tokio::io::AsyncRead;
use tokio_util::compat::FuturesAsyncReadCompatExt;
pub struct DownloadResult {
pub response: Response,
pub filename: String,

View File

@@ -5,14 +5,12 @@ use serde::Deserialize;
use crate::config::CONFIG;
#[derive(Deserialize)]
pub struct FilenameData {
pub filename: String,
pub filename_ascii: String
pub filename_ascii: String,
}
#[derive(Debug, Clone)]
struct DownloadError {
status_code: StatusCode,
@@ -26,11 +24,10 @@ impl fmt::Display for DownloadError {
impl std::error::Error for DownloadError {}
pub async fn download_from_downloader(
source_id: u32,
remote_id: u32,
object_type: String
object_type: String,
) -> Result<Response, Box<dyn std::error::Error + Send + Sync>> {
let url = format!(
"{}/download/{source_id}/{remote_id}/{object_type}",
@@ -45,16 +42,17 @@ pub async fn download_from_downloader(
.error_for_status()?;
if response.status() == StatusCode::NO_CONTENT {
return Err(Box::new(DownloadError { status_code: StatusCode::NO_CONTENT }))
return Err(Box::new(DownloadError {
status_code: StatusCode::NO_CONTENT,
}));
};
Ok(response)
}
pub async fn get_filename(
object_id: i32,
object_type: String
object_type: String,
) -> Result<FilenameData, Box<dyn std::error::Error + Send + Sync>> {
let url = format!(
"{}/filename/{object_id}/{object_type}",
@@ -70,8 +68,6 @@ pub async fn get_filename(
match response.json::<FilenameData>().await {
Ok(v) => Ok(v),
Err(err) => {
Err(Box::new(err))
},
Err(err) => Err(Box::new(err)),
}
}

View File

@@ -2,17 +2,21 @@ use std::io::Read;
use async_stream::stream;
use bytes::Bytes;
use minio_rsc::{provider::StaticProvider, Minio, types::args::{ObjectArgs, PresignedArgs}, errors::MinioError};
use minio_rsc::{
errors::MinioError,
provider::StaticProvider,
types::args::{ObjectArgs, PresignedArgs},
Minio,
};
use tempfile::SpooledTempFile;
use crate::config;
pub fn get_minio() -> Minio {
let provider = StaticProvider::new(
&config::CONFIG.minio_access_key,
&config::CONFIG.minio_secret_key,
None
None,
);
Minio::builder()
@@ -23,8 +27,9 @@ pub fn get_minio() -> Minio {
.unwrap()
}
pub fn get_stream(mut temp_file: Box<dyn Read + Send>) -> impl futures_core::Stream<Item = Result<Bytes, MinioError>> {
pub fn get_stream(
mut temp_file: Box<dyn Read + Send>,
) -> impl futures_core::Stream<Item = Result<Bytes, MinioError>> {
stream! {
let mut buf = [0; 2048];
@@ -38,8 +43,10 @@ pub fn get_stream(mut temp_file: Box<dyn Read + Send>) -> impl futures_core::Str
}
}
pub async fn upload_to_minio(archive: SpooledTempFile, filename: String) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
pub async fn upload_to_minio(
archive: SpooledTempFile,
filename: String,
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
let minio = get_minio();
let is_bucket_exist = match minio.bucket_exists(&config::CONFIG.minio_bucket).await {
@@ -53,20 +60,24 @@ pub async fn upload_to_minio(archive: SpooledTempFile, filename: String) -> Resu
let data_stream = get_stream(Box::new(archive));
if let Err(err) = minio.put_object_stream(
ObjectArgs::new(&config::CONFIG.minio_bucket, filename.clone()),
Box::pin(data_stream)
).await {
if let Err(err) = minio
.put_object_stream(
ObjectArgs::new(&config::CONFIG.minio_bucket, filename.clone()),
Box::pin(data_stream),
)
.await
{
return Err(Box::new(err));
}
let link = match minio.presigned_get_object(
PresignedArgs::new(&config::CONFIG.minio_bucket, filename)
).await {
let link = match minio
.presigned_get_object(PresignedArgs::new(&config::CONFIG.minio_bucket, filename))
.await
{
Ok(v) => v,
Err(err) => {
return Err(Box::new(err));
},
}
};
Ok(link)

View File

@@ -1,8 +1,8 @@
pub mod book_library;
pub mod download_utils;
pub mod telegram_files;
pub mod downloader;
pub mod minio;
pub mod telegram_files;
use chrono::Duration;
use serde::Serialize;
@@ -10,16 +10,25 @@ use tracing::log;
use crate::{prisma::cached_file, views::Database};
use self::{download_utils::{DownloadResult, response_to_tempfile}, telegram_files::{download_from_telegram_files, UploadData, upload_to_telegram_files}, downloader::{get_filename, FilenameData, download_from_downloader}, book_library::{get_book, types::BaseBook, get_books}, minio::upload_to_minio};
use self::{
book_library::{get_book, get_books, types::BaseBook},
download_utils::{response_to_tempfile, DownloadResult},
downloader::{download_from_downloader, get_filename, FilenameData},
minio::upload_to_minio,
telegram_files::{download_from_telegram_files, upload_to_telegram_files, UploadData},
};
pub async fn get_cached_file_or_cache(
object_id: i32,
object_type: String,
db: Database
db: Database,
) -> Option<cached_file::Data> {
let cached_file = db.cached_file()
.find_unique(cached_file::object_id_object_type(object_id, object_type.clone()))
let cached_file = db
.cached_file()
.find_unique(cached_file::object_id_object_type(
object_id,
object_type.clone(),
))
.exec()
.await
.unwrap();
@@ -30,80 +39,77 @@ pub async fn get_cached_file_or_cache(
}
}
pub async fn cache_file(
object_id: i32,
object_type: String,
db: Database
db: Database,
) -> Option<cached_file::Data> {
let book = match get_book(object_id).await {
Ok(v) => v,
Err(err) => {
log::error!("{:?}", err);
return None;
},
}
};
let downloader_result = match download_from_downloader(
book.source.id,
book.remote_id,
object_type.clone()
).await {
let downloader_result =
match download_from_downloader(book.source.id, book.remote_id, object_type.clone()).await {
Ok(v) => v,
Err(err) => {
log::error!("{:?}", err);
return None;
}
};
let UploadData {
chat_id,
message_id,
} = match upload_to_telegram_files(downloader_result, book.get_caption()).await {
Ok(v) => v,
Err(err) => {
log::error!("{:?}", err);
return None;
},
};
let UploadData { chat_id, message_id } = match upload_to_telegram_files(
downloader_result,
book.get_caption()
).await {
Ok(v) => v,
Err(err) => {
log::error!("{:?}", err);
return None;
},
}
};
Some(
db
.cached_file()
.create(
object_id,
object_type,
message_id,
chat_id,
vec![]
)
.exec()
.await
.unwrap()
db.cached_file()
.create(object_id, object_type, message_id, chat_id, vec![])
.exec()
.await
.unwrap(),
)
}
pub async fn download_from_cache(
cached_data: cached_file::Data,
db: Database
db: Database,
) -> Option<DownloadResult> {
let response_task = tokio::task::spawn(download_from_telegram_files(cached_data.message_id, cached_data.chat_id));
let filename_task = tokio::task::spawn(get_filename(cached_data.object_id, cached_data.object_type.clone()));
let response_task = tokio::task::spawn(download_from_telegram_files(
cached_data.message_id,
cached_data.chat_id,
));
let filename_task = tokio::task::spawn(get_filename(
cached_data.object_id,
cached_data.object_type.clone(),
));
let book_task = tokio::task::spawn(get_book(cached_data.object_id));
let response = match response_task.await.unwrap() {
Ok(v) => v,
Err(err) => {
db.cached_file()
.delete(cached_file::object_id_object_type(cached_data.object_id, cached_data.object_type.clone()))
.delete(cached_file::object_id_object_type(
cached_data.object_id,
cached_data.object_type.clone(),
))
.exec()
.await
.unwrap();
log::error!("{:?}", err);
return None;
},
}
};
let filename_data = match filename_task.await.unwrap() {
@@ -122,14 +128,17 @@ pub async fn download_from_cache(
}
};
let FilenameData {filename, filename_ascii} = filename_data;
let FilenameData {
filename,
filename_ascii,
} = filename_data;
let caption = book.get_caption();
Some(DownloadResult {
response,
filename,
filename_ascii,
caption
caption,
})
}
@@ -138,13 +147,13 @@ pub struct FileLinkResult {
pub link: String,
pub filename: String,
pub filename_ascii: String,
pub caption: String
pub caption: String,
}
pub async fn get_download_link(
object_id: i32,
object_type: String,
db: Database
db: Database,
) -> Result<Option<FileLinkResult>, Box<dyn std::error::Error + Send + Sync>> {
let cached_file = match get_cached_file_or_cache(object_id, object_type, db.clone()).await {
Some(v) => v,
@@ -156,7 +165,12 @@ pub async fn get_download_link(
None => return Ok(None),
};
let DownloadResult { mut response, filename, filename_ascii, caption } = data;
let DownloadResult {
mut response,
filename,
filename_ascii,
caption,
} = data;
let tempfile = match response_to_tempfile(&mut response).await {
Some(v) => v.0,
@@ -172,11 +186,12 @@ pub async fn get_download_link(
link,
filename,
filename_ascii,
caption
caption,
}))
}
pub async fn get_books_for_update() -> Result<Vec<BaseBook>, Box<dyn std::error::Error + Send + Sync>> {
pub async fn get_books_for_update(
) -> Result<Vec<BaseBook>, Box<dyn std::error::Error + Send + Sync>> {
let mut result: Vec<BaseBook> = vec![];
let page_size = 50;
@@ -187,12 +202,8 @@ pub async fn get_books_for_update() -> Result<Vec<BaseBook>, Box<dyn std::error:
let uploaded_gte = subset_3.format("%Y-%m-%d").to_string();
let uploaded_lte = now.format("%Y-%m-%d").to_string();
let first_page = match get_books(
1,
page_size,
uploaded_gte.clone(),
uploaded_lte.clone()
).await {
let first_page = match get_books(1, page_size, uploaded_gte.clone(), uploaded_lte.clone()).await
{
Ok(v) => v,
Err(err) => return Err(err),
};
@@ -203,45 +214,51 @@ pub async fn get_books_for_update() -> Result<Vec<BaseBook>, Box<dyn std::error:
let page_count = first_page.pages;
while current_page <= page_count {
let page = match get_books(current_page, page_size, uploaded_gte.clone(), uploaded_lte.clone()).await {
let page = match get_books(
current_page,
page_size,
uploaded_gte.clone(),
uploaded_lte.clone(),
)
.await
{
Ok(v) => v,
Err(err) => return Err(err),
};
result.extend(page.items);
current_page += 1;
};
}
Ok(result)
}
pub async fn start_update_cache(
db: Database
) {
pub async fn start_update_cache(db: Database) {
let books = match get_books_for_update().await {
Ok(v) => v,
Err(err) => {
log::error!("{:?}", err);
return;
},
}
};
for book in books {
'types: for available_type in book.available_types {
let cached_file = match db
.cached_file()
.find_unique(
cached_file::object_id_object_type(book.id, available_type.clone())
)
.find_unique(cached_file::object_id_object_type(
book.id,
available_type.clone(),
))
.exec()
.await {
Ok(v) => v,
Err(err) => {
log::error!("{:?}", err);
continue 'types;
}
};
.await
{
Ok(v) => v,
Err(err) => {
log::error!("{:?}", err);
continue 'types;
}
};
if cached_file.is_some() {
continue 'types;

View File

@@ -1,27 +1,28 @@
use base64::{engine::general_purpose, Engine};
use reqwest::{Response, multipart::{Form, Part}, header};
use reqwest::{
header,
multipart::{Form, Part},
Response,
};
use serde::Deserialize;
use crate::config::CONFIG;
#[derive(Deserialize)]
pub struct UploadData {
pub chat_id: i64,
pub message_id: i64
pub message_id: i64,
}
#[derive(Deserialize)]
pub struct UploadResult {
pub backend: String,
pub data: UploadData
pub data: UploadData,
}
pub async fn download_from_telegram_files(
message_id: i64,
chat_id: i64
chat_id: i64,
) -> Result<Response, Box<dyn std::error::Error + Send + Sync>> {
let url = format!(
"{}/api/v1/files/download_by_message/{chat_id}/{message_id}",
@@ -38,15 +39,11 @@ pub async fn download_from_telegram_files(
Ok(response)
}
pub async fn upload_to_telegram_files(
data_response: Response,
caption: String
caption: String,
) -> Result<UploadData, Box<dyn std::error::Error + Send + Sync>> {
let url = format!(
"{}/api/v1/files/upload/",
CONFIG.files_url
);
let url = format!("{}/api/v1/files/upload/", CONFIG.files_url);
let headers = data_response.headers();
@@ -60,19 +57,14 @@ pub async fn upload_to_telegram_files(
let base64_encoder = general_purpose::STANDARD;
let filename = std::str::from_utf8(
&base64_encoder
.decode(
headers
.get("x-filename-b64-ascii")
.unwrap()
)
.unwrap(),
)
.unwrap()
.to_string();
&base64_encoder
.decode(headers.get("x-filename-b64-ascii").unwrap())
.unwrap(),
)
.unwrap()
.to_string();
let part = Part::stream(data_response)
.file_name(filename.clone());
let part = Part::stream(data_response).file_name(filename.clone());
let form = Form::new()
.text("caption", caption)
@@ -90,8 +82,6 @@ pub async fn upload_to_telegram_files(
match response.json::<UploadResult>().await {
Ok(v) => Ok(v.data),
Err(err) => {
Err(Box::new(err))
},
Err(err) => Err(Box::new(err)),
}
}

View File

@@ -1,13 +1,31 @@
use axum::{Router, response::{Response, IntoResponse, AppendHeaders}, http::{StatusCode, self, Request, header}, middleware::{Next, self}, Extension, routing::{get, delete, post}, extract::Path, Json, body::StreamBody};
use axum::{
body::StreamBody,
extract::Path,
http::{self, header, Request, StatusCode},
middleware::{self, Next},
response::{AppendHeaders, IntoResponse, Response},
routing::{delete, get, post},
Extension, Json, Router,
};
use axum_prometheus::PrometheusMetricLayer;
use tokio_util::io::ReaderStream;
use tower_http::trace::{TraceLayer, self};
use tracing::{Level, log};
use std::sync::Arc;
use base64::{engine::general_purpose, Engine};
use std::sync::Arc;
use tokio_util::io::ReaderStream;
use tower_http::trace::{self, TraceLayer};
use tracing::{log, Level};
use crate::{config::CONFIG, db::get_prisma_client, prisma::{PrismaClient, cached_file::{self}}, services::{get_cached_file_or_cache, download_from_cache, download_utils::get_response_async_read, start_update_cache, get_download_link}};
use crate::{
config::CONFIG,
db::get_prisma_client,
prisma::{
cached_file::{self},
PrismaClient,
},
services::{
download_from_cache, download_utils::get_response_async_read, get_cached_file_or_cache,
get_download_link, start_update_cache,
},
};
pub type Database = Arc<PrismaClient>;
@@ -15,7 +33,7 @@ pub type Database = Arc<PrismaClient>;
async fn get_cached_file(
Path((object_id, object_type)): Path<(i32, String)>,
Extension(Ext { db, .. }): Extension<Ext>
Extension(Ext { db, .. }): Extension<Ext>,
) -> impl IntoResponse {
match get_cached_file_or_cache(object_id, object_type, db).await {
Some(cached_file) => Json(cached_file).into_response(),
@@ -25,20 +43,22 @@ async fn get_cached_file(
async fn download_cached_file(
Path((object_id, object_type)): Path<(i32, String)>,
Extension(Ext { db }): Extension<Ext>
Extension(Ext { db }): Extension<Ext>,
) -> impl IntoResponse {
let cached_file = match get_cached_file_or_cache(object_id, object_type.clone(), db.clone()).await {
Some(cached_file) => cached_file,
None => return StatusCode::NO_CONTENT.into_response(),
};
let cached_file =
match get_cached_file_or_cache(object_id, object_type.clone(), db.clone()).await {
Some(cached_file) => cached_file,
None => return StatusCode::NO_CONTENT.into_response(),
};
let data = match download_from_cache(cached_file, db.clone()).await {
Some(v) => v,
None => {
let cached_file = match get_cached_file_or_cache(object_id, object_type, db.clone()).await {
Some(v) => v,
None => return StatusCode::NO_CONTENT.into_response(),
};
let cached_file =
match get_cached_file_or_cache(object_id, object_type, db.clone()).await {
Some(v) => v,
None => return StatusCode::NO_CONTENT.into_response(),
};
match download_from_cache(cached_file, db).await {
Some(v) => v,
@@ -68,8 +88,8 @@ async fn download_cached_file(
),
(
header::HeaderName::from_static("x-caption-b64"),
encoder.encode(caption)
)
encoder.encode(caption),
),
]);
(headers, body).into_response()
@@ -77,28 +97,30 @@ async fn download_cached_file(
async fn get_link(
Path((object_id, object_type)): Path<(i32, String)>,
Extension(Ext { db, .. }): Extension<Ext>
Extension(Ext { db, .. }): Extension<Ext>,
) -> impl IntoResponse {
match get_download_link(object_id, object_type.clone(), db.clone()).await {
Ok(data) => {
match data {
Some(data) => Json(data).into_response(),
None => StatusCode::NO_CONTENT.into_response(),
}
Ok(data) => match data {
Some(data) => Json(data).into_response(),
None => StatusCode::NO_CONTENT.into_response(),
},
Err(err) => {
log::error!("{:?}", err);
StatusCode::NO_CONTENT.into_response()
},
}
}
}
async fn delete_cached_file(
Path((object_id, object_type)): Path<(i32, String)>,
Extension(Ext { db, .. }): Extension<Ext>
Extension(Ext { db, .. }): Extension<Ext>,
) -> impl IntoResponse {
let cached_file = db.cached_file()
.find_unique(cached_file::object_id_object_type(object_id, object_type.clone()))
let cached_file = db
.cached_file()
.find_unique(cached_file::object_id_object_type(
object_id,
object_type.clone(),
))
.exec()
.await
.unwrap();
@@ -112,14 +134,12 @@ async fn delete_cached_file(
.unwrap();
Json(v).into_response()
},
}
None => StatusCode::NOT_FOUND.into_response(),
}
}
async fn update_cache(
Extension(Ext { db, .. }): Extension<Ext>
) -> impl IntoResponse {
async fn update_cache(Extension(Ext { db, .. }): Extension<Ext>) -> impl IntoResponse {
tokio::spawn(start_update_cache(db));
StatusCode::OK.into_response()
@@ -127,9 +147,9 @@ async fn update_cache(
//
async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode> {
let auth_header = req.headers()
let auth_header = req
.headers()
.get(http::header::AUTHORIZATION)
.and_then(|header| header.to_str().ok());
@@ -146,13 +166,11 @@ async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode>
Ok(next.run(req).await)
}
#[derive(Clone)]
struct Ext {
pub db: Arc<PrismaClient>,
}
pub async fn get_router() -> Router {
let db = Arc::new(get_prisma_client().await);
@@ -162,26 +180,26 @@ pub async fn get_router() -> Router {
let app_router = Router::new()
.route("/:object_id/:object_type/", get(get_cached_file))
.route("/download/:object_id/:object_type/", get(download_cached_file))
.route(
"/download/:object_id/:object_type/",
get(download_cached_file),
)
.route("/link/:object_id/:object_type/", get(get_link))
.route("/:object_id/:object_type/", delete(delete_cached_file))
.route("/update_cache", post(update_cache))
.layer(middleware::from_fn(auth))
.layer(Extension(ext))
.layer(prometheus_layer);
let metric_router = Router::new()
.route("/metrics", get(|| async move { metric_handle.render() }));
let metric_router =
Router::new().route("/metrics", get(|| async move { metric_handle.render() }));
Router::new()
.nest("/api/v1/", app_router)
.nest("/", metric_router)
.layer(
TraceLayer::new_for_http()
.make_span_with(trace::DefaultMakeSpan::new()
.level(Level::INFO))
.on_response(trace::DefaultOnResponse::new()
.level(Level::INFO)),
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
)
}