tsk-212: Identify type of CoverArt (#214)

* tsk-212: icarus_meta version bump

* tsk-212: icarus_meta version bump

* tsk-212: Got functionality working

* tsk-212: Migration changes

Added file_type to CoverArtQueue

* tsk-212: Add support to save file_type from CoverArtQueue

* tsk-212: Warning fix

* tsk-212: Version bump

* tsk-212: icarus_meta version bump

* tsk-212: icarus_meta version bump

* tsk-212: icarus_meta related changes

* tsk-212: Replaced code with constants
This commit was merged in pull request #214.
This commit is contained in:
KD
2025-10-21 22:24:52 -04:00
committed by GitHub
parent e461e78661
commit fb360c8269
5 changed files with 109 additions and 25 deletions
Generated
+32 -3
View File
@@ -193,6 +193,17 @@ dependencies = [
"shlex", "shlex",
] ]
[[package]]
name = "cfb"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
dependencies = [
"byteorder",
"fnv",
"uuid",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.4" version = "1.0.4"
@@ -823,7 +834,7 @@ dependencies = [
[[package]] [[package]]
name = "icarus" name = "icarus"
version = "0.3.1" version = "0.3.2"
dependencies = [ dependencies = [
"axum", "axum",
"axum-extra", "axum-extra",
@@ -864,10 +875,13 @@ dependencies = [
[[package]] [[package]]
name = "icarus_meta" name = "icarus_meta"
version = "0.4.0" version = "0.4.3"
source = "git+ssh://git@git.kundeng.us/phoenix/icarus_meta.git?tag=v0.4.0#f372d059155691c0bac52594fa0d14867078e461" source = "git+ssh://git@git.kundeng.us/phoenix/icarus_meta.git?tag=v0.4.3-48-8acf220fc4-680#8acf220fc4a646090cfb54eff78aaa2f172bf882"
dependencies = [ dependencies = [
"imghdr",
"infer",
"lofty", "lofty",
"rand 0.9.2",
] ]
[[package]] [[package]]
@@ -991,6 +1005,12 @@ dependencies = [
"icu_properties", "icu_properties",
] ]
[[package]]
name = "imghdr"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8b35f3ad95576ac81603375dfe47a0450b70a368aa34d2b6e5bb0a0d7f02428"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.12.0" version = "2.12.0"
@@ -1003,6 +1023,15 @@ dependencies = [
"serde_core", "serde_core",
] ]
[[package]]
name = "infer"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7"
dependencies = [
"cfb",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.15"
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "icarus" name = "icarus"
version = "0.3.1" version = "0.3.2"
edition = "2024" edition = "2024"
rust-version = "1.90" rust-version = "1.90"
@@ -25,7 +25,7 @@ jsonwebtoken = { version = "9.3.1" }
josekit = { version = "0.10.3" } josekit = { version = "0.10.3" }
utoipa = { version = "5.4.0", features = ["axum_extras"] } utoipa = { version = "5.4.0", features = ["axum_extras"] }
utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] } utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] }
icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.4.0" } icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.4.3-48-8acf220fc4-680" }
icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.8.0" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.8.0" }
icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.5.0" } icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.5.0" }
@@ -22,6 +22,7 @@ CREATE TABLE IF NOT EXISTS "metadataQueue" (
CREATE TABLE IF NOT EXISTS "coverartQueue" ( CREATE TABLE IF NOT EXISTS "coverartQueue" (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(), id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data BYTEA NULL, data BYTEA NULL,
file_type TEXT NOT NULL,
song_queue_id UUID NULL song_queue_id UUID NULL
); );
+60 -7
View File
@@ -2,6 +2,7 @@
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)] #[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct CoverArtQueue { pub struct CoverArtQueue {
pub id: uuid::Uuid, pub id: uuid::Uuid,
pub file_type: String,
pub song_queue_id: uuid::Uuid, pub song_queue_id: uuid::Uuid,
} }
@@ -131,13 +132,18 @@ pub mod response {
pub mod db { pub mod db {
use sqlx::Row; use sqlx::Row;
pub async fn insert(pool: &sqlx::PgPool, data: &Vec<u8>) -> Result<uuid::Uuid, sqlx::Error> { pub async fn insert(
pool: &sqlx::PgPool,
data: &Vec<u8>,
file_type: &str,
) -> Result<uuid::Uuid, sqlx::Error> {
let result = sqlx::query( let result = sqlx::query(
r#" r#"
INSERT INTO "coverartQueue" (data) VALUES($1) RETURNING id; INSERT INTO "coverartQueue" (data, file_type) VALUES($1, $2) RETURNING id;
"#, "#,
) )
.bind(data) .bind(data)
.bind(file_type)
.fetch_one(pool) .fetch_one(pool)
.await .await
.map_err(|e| { .map_err(|e| {
@@ -183,7 +189,7 @@ pub mod db {
) -> Result<super::CoverArtQueue, sqlx::Error> { ) -> Result<super::CoverArtQueue, sqlx::Error> {
let result = sqlx::query( let result = sqlx::query(
r#" r#"
SELECT id, song_queue_id FROM "coverartQueue" WHERE id = $1; SELECT id, file_type, song_queue_id FROM "coverartQueue" WHERE id = $1;
"#, "#,
) )
.bind(id) .bind(id)
@@ -199,6 +205,10 @@ pub mod db {
.try_get("id") .try_get("id")
.map_err(|_e| sqlx::Error::RowNotFound) .map_err(|_e| sqlx::Error::RowNotFound)
.unwrap(), .unwrap(),
file_type: row
.try_get("file_type")
.map_err(|_e| sqlx::Error::RowNotFound)
.unwrap(),
song_queue_id: row song_queue_id: row
.try_get("song_queue_id") .try_get("song_queue_id")
.map_err(|_e| sqlx::Error::RowNotFound) .map_err(|_e| sqlx::Error::RowNotFound)
@@ -214,7 +224,7 @@ pub mod db {
) -> Result<super::CoverArtQueue, sqlx::Error> { ) -> Result<super::CoverArtQueue, sqlx::Error> {
let result = sqlx::query( let result = sqlx::query(
r#" r#"
SELECT id, song_queue_id FROM "coverartQueue" WHERE song_queue_id = $1; SELECT id, file_type, song_queue_id FROM "coverartQueue" WHERE song_queue_id = $1;
"#, "#,
) )
.bind(song_queue_id) .bind(song_queue_id)
@@ -230,6 +240,10 @@ pub mod db {
.try_get("id") .try_get("id")
.map_err(|_e| sqlx::Error::RowNotFound) .map_err(|_e| sqlx::Error::RowNotFound)
.unwrap(), .unwrap(),
file_type: row
.try_get("file_type")
.map_err(|_e| sqlx::Error::RowNotFound)
.unwrap(),
song_queue_id: row song_queue_id: row
.try_get("song_queue_id") .try_get("song_queue_id")
.map_err(|_e| sqlx::Error::RowNotFound) .map_err(|_e| sqlx::Error::RowNotFound)
@@ -485,6 +499,24 @@ pub mod cov_db {
} }
} }
mod helper {
pub fn is_coverart_file_type_valid(file_type: &String) -> bool {
let valid_file_types = vec![
String::from(icarus_meta::detection::coverart::constants::JPEG_TYPE),
String::from(icarus_meta::detection::coverart::constants::JPG_TYPE),
String::from(icarus_meta::detection::coverart::constants::PNG_TYPE),
];
for valid_file_type in valid_file_types {
if valid_file_type == *file_type {
return true;
}
}
false
}
}
pub mod endpoint { pub mod endpoint {
use axum::response::IntoResponse; use axum::response::IntoResponse;
@@ -516,16 +548,36 @@ pub mod endpoint {
let content_type = field.content_type().unwrap().to_string(); let content_type = field.content_type().unwrap().to_string();
let data = field.bytes().await.unwrap(); let data = field.bytes().await.unwrap();
let raw_data = data.to_vec(); let raw_data = data.to_vec();
let file_type =
match icarus_meta::detection::coverart::file_type_from_data(&raw_data) {
Ok(file_type) => file_type,
Err(err) => {
eprintln!("Error: {err:?}");
response.message = err.to_string();
return (
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
axum::Json(response),
);
}
};
if !super::helper::is_coverart_file_type_valid(&file_type.file_type) {
response.message = format!("CoverArt file type not supported: {file_type:?}");
(
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
axum::Json(response),
)
} else {
println!( println!(
"Received file '{}' (name = '{}', content-type = '{}', size = {})", "Received file '{}' (name = '{}', content-type = '{}', size = {}, file-type = {:?})",
file_name, file_name,
name, name,
content_type, content_type,
data.len() data.len(),
file_type
); );
match super::db::insert(&pool, &raw_data).await { match super::db::insert(&pool, &raw_data, &file_type.file_type).await {
Ok(id) => { Ok(id) => {
response.message = String::from("Successful"); response.message = String::from("Successful");
response.data.push(id); response.data.push(id);
@@ -537,6 +589,7 @@ pub mod endpoint {
} }
} }
} }
}
Ok(None) => (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)), Ok(None) => (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)),
Err(err) => { Err(err) => {
response.message = err.to_string(); response.message = err.to_string();
+1
View File
@@ -22,6 +22,7 @@ CREATE TABLE IF NOT EXISTS "metadataQueue" (
CREATE TABLE IF NOT EXISTS "coverartQueue" ( CREATE TABLE IF NOT EXISTS "coverartQueue" (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(), id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data BYTEA NULL, data BYTEA NULL,
file_type TEXT NOT NULL,
song_queue_id UUID NULL song_queue_id UUID NULL
); );