Better video ID handling + Instance::new improvements
This commit is contained in:
parent
3fc3eb8d68
commit
461ccaa4b9
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -33,7 +33,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "almond"
|
||||
name = "almond-api"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "almond"
|
||||
name = "almond-api"
|
||||
version = "0.2.0"
|
||||
edition = "2024"
|
||||
|
||||
|
@ -4,13 +4,11 @@ use serde::{Deserialize, Serialize};
|
||||
use sqlx::SqlitePool;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::video::Video;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub password: Option<String>,
|
||||
pub password: String,
|
||||
pub videos_per_page: usize,
|
||||
}
|
||||
|
||||
@ -19,7 +17,7 @@ impl Default for Config {
|
||||
Self {
|
||||
host: "0.0.0.0".into(),
|
||||
port: 3000,
|
||||
password: None,
|
||||
password: "123456".into(),
|
||||
videos_per_page: 10,
|
||||
}
|
||||
}
|
||||
@ -36,10 +34,10 @@ pub struct Instance {
|
||||
pub enum NewInstanceError {
|
||||
#[error("Failed to open TOML configuration file")]
|
||||
ConfigLoad(#[from] io::Error),
|
||||
#[error("Could not parse TOML configuration: {0}")]
|
||||
#[error("Could not parse TOML configuration")]
|
||||
ConfigParse(#[from] toml::de::Error),
|
||||
#[error("Failed to fetch entries from database: {0}")]
|
||||
Populate(#[from] sqlx::Error),
|
||||
#[error("Failed to create connection pool")]
|
||||
PoolConnect(#[from] sqlx::Error),
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
@ -52,10 +50,4 @@ impl Instance {
|
||||
|
||||
Ok(Self { config, pool })
|
||||
}
|
||||
|
||||
pub async fn fetch_videos(&self) -> Result<Vec<Video>, sqlx::Error> {
|
||||
sqlx::query_as!(Video, "SELECT * FROM video")
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use axum::{
|
||||
routing::{get, post},
|
||||
};
|
||||
use instance::Instance;
|
||||
use routes::{list_entries, upload_video};
|
||||
use routes::{list_videos, upload_video};
|
||||
use tokio::signal;
|
||||
use tracing::info;
|
||||
|
||||
@ -30,7 +30,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let address = format!("{}:{}", instance.config.host, instance.config.port);
|
||||
|
||||
let almond = Router::new()
|
||||
.route("/", get(list_entries))
|
||||
.route("/", get(list_videos))
|
||||
.route("/upload", post(upload_video))
|
||||
.with_state(instance);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use axum::{
|
||||
Json, debug_handler,
|
||||
Json,
|
||||
extract::{Query, State},
|
||||
http::StatusCode,
|
||||
};
|
||||
@ -12,12 +12,12 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ListEntriesQuery {
|
||||
pub struct ListVideosQuery {
|
||||
page: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ListEntriesResponse {
|
||||
pub struct ListVideosResponse {
|
||||
videos: Vec<Video>,
|
||||
page: usize,
|
||||
per_page: usize,
|
||||
@ -26,12 +26,14 @@ pub struct ListEntriesResponse {
|
||||
}
|
||||
|
||||
/// Retrieve video list as JSON (paged)
|
||||
#[debug_handler]
|
||||
pub async fn list_entries(
|
||||
pub async fn list_videos(
|
||||
State(state): State<Instance>,
|
||||
Query(query): Query<ListEntriesQuery>,
|
||||
) -> Result<Json<ListEntriesResponse>, StatusCode> {
|
||||
let Ok(videos) = state.fetch_videos().await else {
|
||||
Query(query): Query<ListVideosQuery>,
|
||||
) -> Result<Json<ListVideosResponse>, StatusCode> {
|
||||
let Ok(videos) = sqlx::query_as!(Video, "SELECT * FROM video")
|
||||
.fetch_all(&state.pool)
|
||||
.await
|
||||
else {
|
||||
error!("Could not fetch videos from database!");
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
};
|
||||
@ -50,7 +52,7 @@ pub async fn list_entries(
|
||||
vec![]
|
||||
};
|
||||
|
||||
Ok(Json(ListEntriesResponse {
|
||||
Ok(Json(ListVideosResponse {
|
||||
videos,
|
||||
page,
|
||||
per_page,
|
||||
@ -70,12 +72,18 @@ pub async fn upload_video(
|
||||
State(state): State<Instance>,
|
||||
Query(query): Query<UploadVideoQuery>,
|
||||
) -> StatusCode {
|
||||
let Ok(videos) = state.fetch_videos().await else {
|
||||
error!("Could not fetch videos from database!");
|
||||
let id = match sqlx::query_scalar!("SELECT MAX(id) FROM video")
|
||||
.fetch_one(&state.pool)
|
||||
.await
|
||||
{
|
||||
Ok(Some(max_id)) => max_id + 1,
|
||||
Ok(None) => 0,
|
||||
Err(_) => {
|
||||
return StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
};
|
||||
|
||||
let new_video = Video::from_url(&query.url, videos.len(), query.cookie.as_deref())
|
||||
let new_video = Video::from_url(&query.url, id, query.cookie.as_deref())
|
||||
.await
|
||||
.map_err(|e| match e {
|
||||
VideoError::InvalidUrl | VideoError::UrlParse(_) => StatusCode::BAD_REQUEST,
|
||||
|
@ -95,8 +95,7 @@ impl Video {
|
||||
Some(query_v.1.to_string())
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
pub async fn from_url(url: &str, id: usize, cookie: Option<&str>) -> Result<Self, VideoError> {
|
||||
pub async fn from_url(url: &str, id: i64, cookie: Option<&str>) -> Result<Self, VideoError> {
|
||||
let url = Url::parse(url)?;
|
||||
info!("Parsed argument as URL");
|
||||
|
||||
@ -141,8 +140,6 @@ impl Video {
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let id = id as i64;
|
||||
|
||||
let url = url.to_string();
|
||||
let description = format!("{file_stem}.description");
|
||||
let title = get_info_value("title").to_string();
|
||||
@ -175,6 +172,7 @@ impl Video {
|
||||
};
|
||||
|
||||
let sha256 = format!("{:x}", Sha3_256::digest(&buffer));
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
let file_size = buffer.len() as i64;
|
||||
let author_id = get_info_value("channel_id").to_string();
|
||||
let author_url = get_info_value("channel_url").to_string();
|
||||
|
Loading…
x
Reference in New Issue
Block a user