Initial commit

This commit is contained in:
Connor Johnstone
2026-03-17 14:14:46 -04:00
commit 305ddff278
27 changed files with 1897 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "albums")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
pub album_artist: String,
#[sea_orm(nullable)]
pub year: Option<i32>,
#[sea_orm(nullable)]
pub genre: Option<String>,
#[sea_orm(nullable)]
pub cover_art_path: Option<String>,
#[sea_orm(nullable)]
pub musicbrainz_id: Option<String>,
#[sea_orm(nullable)]
pub artist_id: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::artist::Entity",
from = "Column::ArtistId",
to = "super::artist::Column::Id",
on_delete = "SetNull"
)]
Artist,
#[sea_orm(has_many = "super::track::Entity")]
Tracks,
#[sea_orm(has_many = "super::wanted_item::Entity")]
WantedItems,
}
impl Related<super::artist::Entity> for Entity {
fn to() -> RelationDef {
Relation::Artist.def()
}
}
impl Related<super::track::Entity> for Entity {
fn to() -> RelationDef {
Relation::Tracks.def()
}
}
impl Related<super::wanted_item::Entity> for Entity {
fn to() -> RelationDef {
Relation::WantedItems.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
+47
View File
@@ -0,0 +1,47 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "artists")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
#[sea_orm(nullable)]
pub musicbrainz_id: Option<String>,
pub added_at: chrono::NaiveDateTime,
/// JSON-serialized Vec of top song info
pub top_songs: String,
/// JSON-serialized Vec of similar artist info
pub similar_artists: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::album::Entity")]
Albums,
#[sea_orm(has_many = "super::track::Entity")]
Tracks,
#[sea_orm(has_many = "super::wanted_item::Entity")]
WantedItems,
}
impl Related<super::album::Entity> for Entity {
fn to() -> RelationDef {
Relation::Albums.def()
}
}
impl Related<super::track::Entity> for Entity {
fn to() -> RelationDef {
Relation::Tracks.def()
}
}
impl Related<super::wanted_item::Entity> for Entity {
fn to() -> RelationDef {
Relation::WantedItems.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
+55
View File
@@ -0,0 +1,55 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "Text")]
pub enum DownloadStatus {
#[sea_orm(string_value = "pending")]
Pending,
#[sea_orm(string_value = "downloading")]
Downloading,
#[sea_orm(string_value = "completed")]
Completed,
#[sea_orm(string_value = "failed")]
Failed,
#[sea_orm(string_value = "cancelled")]
Cancelled,
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "download_queue")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
#[sea_orm(nullable)]
pub wanted_item_id: Option<i32>,
pub query: String,
#[sea_orm(nullable)]
pub source_url: Option<String>,
pub source_backend: String,
pub status: DownloadStatus,
#[sea_orm(nullable)]
pub error_message: Option<String>,
pub retry_count: i32,
pub created_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::wanted_item::Entity",
from = "Column::WantedItemId",
to = "super::wanted_item::Column::Id",
on_delete = "Cascade"
)]
WantedItem,
}
impl Related<super::wanted_item::Entity> for Entity {
fn to() -> RelationDef {
Relation::WantedItem.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
+13
View File
@@ -0,0 +1,13 @@
pub mod album;
pub mod artist;
pub mod download_queue;
pub mod search_cache;
pub mod track;
pub mod wanted_item;
pub use album::Entity as Albums;
pub use artist::Entity as Artists;
pub use download_queue::Entity as DownloadQueue;
pub use search_cache::Entity as SearchCache;
pub use track::Entity as Tracks;
pub use wanted_item::Entity as WantedItems;
+20
View File
@@ -0,0 +1,20 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "search_cache")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
#[sea_orm(unique)]
pub query_key: String,
pub provider: String,
pub result_json: String,
pub created_at: chrono::NaiveDateTime,
pub expires_at: chrono::NaiveDateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
+86
View File
@@ -0,0 +1,86 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "tracks")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
#[sea_orm(unique)]
pub file_path: String,
#[sea_orm(nullable)]
pub title: Option<String>,
#[sea_orm(nullable)]
pub artist: Option<String>,
#[sea_orm(nullable)]
pub album: Option<String>,
#[sea_orm(nullable)]
pub album_artist: Option<String>,
#[sea_orm(nullable)]
pub track_number: Option<i32>,
#[sea_orm(nullable)]
pub disc_number: Option<i32>,
#[sea_orm(nullable, column_type = "Double")]
pub duration: Option<f64>,
#[sea_orm(nullable)]
pub genre: Option<String>,
#[sea_orm(nullable)]
pub year: Option<i32>,
#[sea_orm(nullable)]
pub codec: Option<String>,
#[sea_orm(nullable)]
pub bitrate: Option<i32>,
pub file_size: i64,
#[sea_orm(nullable)]
pub fingerprint: Option<String>,
#[sea_orm(nullable)]
pub musicbrainz_id: Option<String>,
#[sea_orm(nullable)]
pub artist_id: Option<i32>,
#[sea_orm(nullable)]
pub album_id: Option<i32>,
#[sea_orm(nullable)]
pub file_mtime: Option<chrono::NaiveDateTime>,
pub added_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::artist::Entity",
from = "Column::ArtistId",
to = "super::artist::Column::Id",
on_delete = "SetNull"
)]
Artist,
#[sea_orm(
belongs_to = "super::album::Entity",
from = "Column::AlbumId",
to = "super::album::Column::Id",
on_delete = "SetNull"
)]
Album,
#[sea_orm(has_many = "super::wanted_item::Entity")]
WantedItems,
}
impl Related<super::artist::Entity> for Entity {
fn to() -> RelationDef {
Relation::Artist.def()
}
}
impl Related<super::album::Entity> for Entity {
fn to() -> RelationDef {
Relation::Album.def()
}
}
impl Related<super::wanted_item::Entity> for Entity {
fn to() -> RelationDef {
Relation::WantedItems.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
+94
View File
@@ -0,0 +1,94 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "Text")]
pub enum WantedStatus {
#[sea_orm(string_value = "wanted")]
Wanted,
#[sea_orm(string_value = "available")]
Available,
#[sea_orm(string_value = "downloaded")]
Downloaded,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "Text")]
pub enum ItemType {
#[sea_orm(string_value = "artist")]
Artist,
#[sea_orm(string_value = "album")]
Album,
#[sea_orm(string_value = "track")]
Track,
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "wanted_items")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub item_type: ItemType,
#[sea_orm(nullable)]
pub artist_id: Option<i32>,
#[sea_orm(nullable)]
pub album_id: Option<i32>,
#[sea_orm(nullable)]
pub track_id: Option<i32>,
pub status: WantedStatus,
pub added_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::artist::Entity",
from = "Column::ArtistId",
to = "super::artist::Column::Id",
on_delete = "Cascade"
)]
Artist,
#[sea_orm(
belongs_to = "super::album::Entity",
from = "Column::AlbumId",
to = "super::album::Column::Id",
on_delete = "Cascade"
)]
Album,
#[sea_orm(
belongs_to = "super::track::Entity",
from = "Column::TrackId",
to = "super::track::Column::Id",
on_delete = "Cascade"
)]
Track,
#[sea_orm(has_many = "super::download_queue::Entity")]
Downloads,
}
impl Related<super::artist::Entity> for Entity {
fn to() -> RelationDef {
Relation::Artist.def()
}
}
impl Related<super::album::Entity> for Entity {
fn to() -> RelationDef {
Relation::Album.def()
}
}
impl Related<super::track::Entity> for Entity {
fn to() -> RelationDef {
Relation::Track.def()
}
}
impl Related<super::download_queue::Entity> for Entity {
fn to() -> RelationDef {
Relation::Downloads.def()
}
}
impl ActiveModelBehavior for ActiveModel {}