Bug fix release #35

Merged
phoenix merged 6 commits from devel into main 2025-07-23 22:07:54 +00:00
8 changed files with 164 additions and 94 deletions

View File

@@ -17,7 +17,7 @@ jobs:
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.86.0
toolchain: 1.88.0
components: cargo
- name: Extract Version from Cargo.toml

View File

@@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.86.0
toolchain: 1.88.0
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key
@@ -36,7 +36,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.86.0
toolchain: 1.88.0
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key
@@ -54,7 +54,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.86.0
toolchain: 1.88.0
- run: rustup component add rustfmt
- run: |
mkdir -p ~/.ssh
@@ -73,7 +73,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.86.0
toolchain: 1.88.0
- run: rustup component add clippy
- run: |
mkdir -p ~/.ssh
@@ -92,7 +92,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.86.0
toolchain: 1.88.0
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key
@@ -100,4 +100,4 @@ jobs:
ssh-keyscan ${{ vars.MYHOST }} >> ~/.ssh/known_hosts
eval $(ssh-agent -s)
ssh-add -v ~/.ssh/gitlab_deploy_key
cargo build --release
cargo build --release

6
Cargo.lock generated
View File

@@ -81,7 +81,7 @@ dependencies = [
[[package]]
name = "icarus_meta"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"lofty",
"tempfile",
@@ -211,9 +211,9 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.19.1"
version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom",

View File

@@ -1,11 +1,11 @@
[package]
name = "icarus_meta"
version = "0.2.0"
version = "0.3.0"
edition = "2024"
rust-version = "1.86"
rust-version = "1.88"
[dependencies]
lofty = { version = "0.22.3" }
lofty = { version = "0.22.4" }
[dev-dependencies]
tempfile = { version = "3.19.1" }
tempfile = { version = "3.20.0" }

View File

@@ -1,2 +1,66 @@
pub mod meta;
pub mod properties;
pub mod types;
pub mod test_util {
pub mod util {
use std::io::{self, Write};
// Function to save a Vec<u8> to a file
pub fn save_bytes_to_file(bytes: &[u8], file_path: &String) -> io::Result<()> {
let file = std::path::Path::new(file_path);
let mut file = std::fs::File::create(file)?;
match file.write_all(bytes) {
Ok(_res) => Ok(()),
Err(err) => Err(err),
}
}
pub fn get_full_path(
directory: &String,
filename: &String,
) -> Result<String, std::io::Error> {
match path_buf(directory, filename) {
Ok(pf) => Ok(pf.display().to_string()),
Err(err) => Err(err),
}
}
pub fn copy_file(
source_path: &String,
destination_path: &String,
) -> Result<u64, std::io::Error> {
let src_path = std::path::Path::new(source_path);
let dest_path = std::path::Path::new(destination_path);
std::fs::copy(src_path, dest_path)
}
pub fn file_exists(directory: &String, filename: &String) -> Result<bool, std::io::Error> {
match path_buf(directory, filename) {
Ok(pf) => Ok(pf.exists()),
Err(err) => Err(err),
}
}
fn path_buf(
directory: &String,
filename: &String,
) -> Result<std::path::PathBuf, std::io::Error> {
let dir_path = std::path::Path::new(&directory);
Ok(dir_path.join(filename))
}
pub const TESTFILEDIRECTORY: &str = "tests/sample_tracks3";
pub fn get_filename(track: i32) -> String {
const FLAC_EXTENSION: &str = ".flac";
if track < 10 {
format!("track0{track}{FLAC_EXTENSION}")
} else {
format!("track{track}{FLAC_EXTENSION}")
}
}
}
}

View File

@@ -21,7 +21,17 @@ pub mod coverart {
match lofty::picture::PictureInformation::from_picture(&pic) {
Ok(info) => {
flac_file.set_picture(0, pic.clone(), info);
Ok(pic.into_data())
match flac_file.save_to_path(
song_filepath,
lofty::config::WriteOptions::default(),
) {
Ok(_) => Ok(pic.into_data()),
Err(err) => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
err.to_string(),
)),
}
}
Err(err) => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
@@ -265,83 +275,10 @@ pub mod metadata {
#[cfg(test)]
mod tests {
use util::{file_exists, get_full_path};
use super::*;
mod util {
use std::io::{self, Write};
// Function to save a Vec<u8> to a file
pub fn save_bytes_to_file(bytes: &[u8], file_path: &String) -> io::Result<()> {
let file = std::path::Path::new(file_path);
let mut file = std::fs::File::create(file)?;
match file.write_all(bytes) {
Ok(_res) => Ok(()),
Err(err) => Err(err),
}
}
pub fn get_full_path(
directory: &String,
filename: &String,
) -> Result<String, std::io::Error> {
match path_buf(directory, filename) {
Ok(pf) => Ok(pf.display().to_string()),
Err(err) => Err(err),
}
}
pub fn copy_file(
source_path: &String,
destination_path: &String,
) -> Result<u64, std::io::Error> {
let src_path = std::path::Path::new(source_path);
let dest_path = std::path::Path::new(destination_path);
match std::fs::copy(src_path, dest_path) {
Ok(bytes) => Ok(bytes),
Err(err) => Err(err),
}
}
pub fn file_exists(directory: &String, filename: &String) -> Result<bool, std::io::Error> {
match path_buf(directory, filename) {
Ok(pf) => Ok(pf.exists()),
Err(err) => Err(err),
}
}
fn path_buf(
directory: &String,
filename: &String,
) -> Result<std::path::PathBuf, std::io::Error> {
let dir_path = std::path::Path::new(&directory);
Ok(dir_path.join(filename))
}
pub const TESTFILEDIRECTORY: &str = "tests/sample_tracks3";
pub fn get_filename(track: i32) -> String {
let mut filename = String::from("track");
if track < 10 {
filename += "0";
filename += &track.to_string();
} else {
filename += &track.to_string();
}
filename += ".flac";
filename
}
}
mod get {
use super::metadata::get_meta;
use super::*;
use super::super::metadata::get_meta;
use crate::test_util::util;
use crate::test_util::util::{file_exists, get_full_path};
use crate::types;
#[test]
@@ -595,8 +532,9 @@ mod tests {
}
mod set {
use super::metadata::{get_meta, set_meta};
use super::*;
use super::super::metadata::{get_meta, set_meta};
use crate::test_util::util;
use crate::test_util::util::{file_exists, get_full_path};
use crate::types;
#[test]
@@ -1132,7 +1070,9 @@ mod tests {
mod pictures {
use super::*;
use super::super::*;
use crate::test_util::util;
use crate::test_util::util::{file_exists, get_full_path};
#[test]
fn test_get_picture() {

51
src/properties.rs Normal file
View File

@@ -0,0 +1,51 @@
use lofty::file::AudioFile;
pub fn get_duration(song_path: &String) -> Result<std::time::Duration, std::io::Error> {
match std::fs::File::open(song_path) {
Ok(mut content) => {
match lofty::flac::FlacFile::read_from(&mut content, lofty::config::ParseOptions::new())
{
Ok(flac_file) => {
let properties = flac_file.properties();
Ok(properties.duration())
}
Err(err) => Err(std::io::Error::other(err.to_string())),
}
}
Err(err) => Err(err),
}
}
#[cfg(test)]
mod tests {
use crate::test_util;
#[test]
fn test_get_duration() {
let filename = test_util::util::get_filename(1);
let dir = String::from(test_util::util::TESTFILEDIRECTORY);
match test_util::util::file_exists(&dir, &filename) {
Ok(_) => {
let filepath = test_util::util::get_full_path(&dir, &filename).unwrap();
match super::get_duration(&filepath) {
Ok(duration) => {
let song_duration: u64 = 41;
let fetched_song_duration = duration.as_secs();
assert_eq!(
song_duration, fetched_song_duration,
"Durations should match, but they don't {song_duration} {fetched_song_duration} ({duration:?})"
);
}
Err(err) => {
assert!(false, "Error: {err:?}");
}
}
}
Err(err) => {
assert!(false, "Error: {err:?}");
}
}
}
}

View File

@@ -32,6 +32,21 @@ impl MetadataType {
}
}
pub fn all_metadata_types() -> Vec<Type> {
vec![
Type::Album,
Type::Artist,
Type::AlbumArtist,
Type::Date,
Type::Disc,
Type::Genre,
Type::Title,
Type::Track,
Type::TrackCount,
Type::DiscCount,
]
}
pub mod access {
pub fn get_type(t: super::Type) -> Result<String, std::io::Error> {
match t {