moosicbox_library 0.3.0

MoosicBox Library Music API package
Documentation

MoosicBox Library

Music library management package providing database operations for artists, albums, and tracks with support for filtering, search, and pagination.

Features

  • Artist Management: List and retrieve artists from the library
  • Album Management: Browse albums with filtering, sorting, and pagination
  • Track Management: Access track information with detailed metadata
  • Search Functionality: Full-text search across artists, albums, and tracks
  • Pagination Support: Efficient browsing of large music collections
  • Filtering & Sorting: Filter albums by artist, name, source, and sort by various criteria
  • Database Integration: Async database operations with proper error handling
  • Version Support: Manage multiple album versions from different sources with varying quality levels

Installation

Add this to your Cargo.toml:

[dependencies]
moosicbox_library = "0.1.4"

Enable additional features:

[dependencies]
moosicbox_library = { version = "0.1.4", features = ["api"] }

Usage

Working with Artists

use moosicbox_library::favorite_artists;
use switchy_database::profiles::LibraryDatabase;

// LibraryDatabase is obtained from the PROFILES registry or via actix-web request extraction
async fn example(db: &LibraryDatabase) -> Result<(), Box<dyn std::error::Error>> {
    // Get favorite artists with pagination
    let artists_result = favorite_artists(
        &db,
        Some(0),    // offset
        Some(20),   // limit
        None,       // order
        None,       // order direction
    ).await?;

    println!("Found {} artists", artists_result.page.total().unwrap_or(0));

    for artist in artists_result.page.items() {
        println!("Artist: {} (ID: {})", artist.title, artist.id);
    }

    Ok(())
}

Album Operations

use moosicbox_library::{favorite_albums, album, album_tracks, album_versions};
use moosicbox_music_api_models::AlbumsRequest;
use moosicbox_music_models::id::Id;
use switchy_database::profiles::LibraryDatabase;

// LibraryDatabase is obtained from the PROFILES registry or via actix-web request extraction
async fn example(db: &LibraryDatabase) -> Result<(), Box<dyn std::error::Error>> {
    // Get favorite albums
    let request = AlbumsRequest::default();
    let albums_result = favorite_albums(&db, &request).await?;

    for album in albums_result.page.items() {
        println!("Album: {} by {}", album.title, album.artist);
        println!("  Date: {:?}", album.date_released);

        // Get album details
        let album_id = Id::Number(album.id);
        if let Some(album_detail) = album(&db, &album_id).await? {
            println!("  Detailed info: {} versions", album_detail.versions.len());
        }

        // Get album tracks
        let tracks_result = album_tracks(&db, &album_id, Some(0), Some(10)).await?;
        println!("  Tracks ({}):", tracks_result.page.items().len());

        for track in tracks_result.page.items() {
            println!("    {}: {} ({}s)", track.number, track.title, track.duration);
        }

        // Get album versions
        let versions = album_versions(&db, &album_id).await?;
        println!("  Available versions: {}", versions.len());
        for version in versions {
            println!("    Source: {:?}, Format: {:?}", version.source, version.format);
        }
    }

    Ok(())
}

Track Management

use moosicbox_library::{favorite_tracks, track};
use moosicbox_music_models::id::Id;
use switchy_database::profiles::LibraryDatabase;

// LibraryDatabase is obtained from the PROFILES registry or via actix-web request extraction
async fn example(db: &LibraryDatabase) -> Result<(), Box<dyn std::error::Error>> {
    // Get favorite tracks
    let tracks_result = favorite_tracks(
        &db,
        None,       // track_ids filter
        Some(0),    // offset
        Some(50),   // limit
        None,       // order
        None,       // order direction
    ).await?;

    println!("Favorite tracks: {}", tracks_result.page.items().len());

    for track in tracks_result.page.items() {
        println!("Track: {} - {} ({}s)", track.artist, track.title, track.duration);

        // Get detailed track info
        let track_id = Id::Number(track.id);
        if let Some(track_detail) = track(&db, &track_id).await? {
            println!("  Album: {}", track_detail.album);
            println!("  Track #: {}", track_detail.number);
        }
    }

    Ok(())
}

Filtering and Sorting Albums

use moosicbox_library::{filter_albums, sort_albums};
use moosicbox_music_api_models::{AlbumsRequest, AlbumFilters};
use moosicbox_music_models::{AlbumSort, id::Id};

fn example_filtering() {
    let albums = vec![]; // Your album collection

    // Create filter request
    let request = AlbumsRequest {
        sources: None,
        sort: Some(AlbumSort::ArtistAsc),
        filters: Some(AlbumFilters {
            name: Some("Dark Side".to_string()),
            artist_id: Some(Id::Number(123)),
            artist_api_id: None,
            artist: None,
            album_type: None,
            search: None,
        }),
        page: None,
    };

    // Filter albums
    let filtered: Vec<_> = filter_albums(&albums, &request).collect();
    println!("Filtered to {} albums", filtered.len());

    // Sort albums
    let sorted = sort_albums(filtered, &request);
    for album in sorted {
        println!("  {}: {}", album.artist, album.title);
    }
}

Search Operations

use moosicbox_library::{search, LibrarySearchType};
use moosicbox_music_api_models::search::api::ApiGlobalSearchResult;

fn search_library() -> Result<(), Box<dyn std::error::Error>> {
    let query = "Pink Floyd";
    let search_types = vec![
        LibrarySearchType::Artists,
        LibrarySearchType::Albums,
        LibrarySearchType::Tracks,
    ];

    let results = search(
        query,
        Some(0),    // offset
        Some(20),   // limit
        Some(&search_types),
    )?;

    println!("Search results for '{}':", query);
    println!("Found {} results", results.results.len());

    for result in &results.results {
        match result {
            ApiGlobalSearchResult::Artist(artist) => {
                println!("  Artist: {}", artist.title);
            }
            ApiGlobalSearchResult::Album(album) => {
                println!("  Album: {} - {}", album.artist, album.title);
            }
            ApiGlobalSearchResult::Track(track) => {
                println!("  Track: {} - {}", track.artist, track.title);
            }
        }
    }

    Ok(())
}

Artist Albums

use moosicbox_library::artist_albums;
use moosicbox_library_models::LibraryAlbumType;
use moosicbox_music_models::id::Id;
use switchy_database::profiles::LibraryDatabase;

// LibraryDatabase is obtained from the PROFILES registry or via actix-web request extraction
async fn example(db: &LibraryDatabase) -> Result<(), Box<dyn std::error::Error>> {
    let artist_id = Id::Number(123);

    // Get all albums by artist
    let albums_result = artist_albums(
        &db,
        &artist_id,
        Some(0),    // offset
        Some(10),   // limit
        None,       // album type filter
    ).await?;

    println!("Albums by artist: {}", albums_result.page.items().len());

    for album in albums_result.page.items() {
        println!("  {} ({})", album.title, album.date_released.unwrap_or_default());
    }

    // Get only LP albums
    let lp_albums = artist_albums(
        &db,
        &artist_id,
        Some(0),
        Some(10),
        Some(LibraryAlbumType::Lp),
    ).await?;

    println!("LP albums: {}", lp_albums.page.items().len());

    Ok(())
}

Track File URLs

use moosicbox_library::{track_file_url, LibraryAudioQuality};
use moosicbox_music_models::id::Id;
use switchy_database::profiles::LibraryDatabase;

// LibraryDatabase is obtained from the PROFILES registry or via actix-web request extraction
async fn example(db: &LibraryDatabase) -> Result<(), Box<dyn std::error::Error>> {
    let track_id = Id::Number(456);

    // Get high quality track URL
    let url = track_file_url(
        &db,
        LibraryAudioQuality::High,
        &track_id,
    ).await?;

    println!("Track URL: {}", url);

    Ok(())
}

API Reference

Core Functions

  • favorite_artists() - Get paginated artists from the library
  • favorite_albums() - Get paginated albums with filtering and sorting
  • favorite_tracks() - Get paginated tracks with optional ID filtering
  • artist() - Get artist by ID
  • album() - Get album by ID
  • album_from_source() - Get album by ID and API source
  • track() - Get track by ID
  • artist_albums() - Get albums by specific artist with optional type filtering
  • album_tracks() - Get tracks in specific album
  • album_versions() - Get available versions of an album grouped by quality

Utility Functions

  • filter_albums() - Filter albums by criteria
  • sort_albums() - Sort albums by specified order
  • search() - Search across library content
  • track_file_url() - Get file URL for track playback
  • reindex_global_search_index() - Rebuild the search index from library data

API Integration (api feature)

  • api::bind_services() - Register all library HTTP endpoints on an Actix-web scope

Management Functions

Note: The following functions are currently non-functional placeholders that return Ok(()):

  • add_favorite_artist() - Placeholder: Add artist to favorites
  • remove_favorite_artist() - Placeholder: Remove artist from favorites
  • add_favorite_album() - Placeholder: Add album to favorites
  • remove_favorite_album() - Placeholder: Remove album from favorites
  • add_favorite_track() - Placeholder: Add track to favorites
  • remove_favorite_track() - Placeholder: Remove track from favorites

Error Handling

The library provides specific error types for different operations:

  • LibraryFavoriteArtistsError - Errors when fetching favorite artists
  • LibraryFavoriteAlbumsError - Errors when fetching favorite albums
  • LibraryFavoriteTracksError - Errors when fetching favorite tracks
  • LibraryArtistError - Errors when fetching artist information
  • LibraryAlbumError - Errors when fetching album information
  • LibraryTrackError - Errors when fetching track information
  • SearchError - Errors during search operations

Enums and Types

Order and Direction

  • LibraryArtistOrder, LibraryAlbumOrder, LibraryTrackOrder
  • LibraryArtistOrderDirection, LibraryAlbumOrderDirection, LibraryTrackOrderDirection

Search Types

  • LibrarySearchType - Artists, Albums, Tracks, Videos, Playlists, UserProfiles
  • SearchType - Enum variants for search filtering

Audio Quality

  • LibraryAudioQuality - High, Lossless, HiResLossless

Features

The following cargo features are available:

  • api - Enable API integration features (actix-web support)
  • openapi - Enable OpenAPI/utoipa schema generation
  • fail-on-warnings - Treat warnings as errors during compilation
  • all-encoders - Enable all audio encoders
  • all-formats - Enable all audio format support
  • Format-specific features: format-aac, format-flac, format-mp3, format-opus
  • Encoder-specific features: encoder-aac, encoder-flac, encoder-mp3, encoder-opus

Dependencies

  • switchy_database - Database connection and operations
  • moosicbox_music_models - Core music data models
  • moosicbox_library_models - Library-specific data models
  • moosicbox_paging - Pagination utilities
  • moosicbox_search - Search functionality