Initial workspace scaffold
Cargo workspace with 5 crates: buh-entity (pure data structs), buh-data (Turso/libsql data access), buh-util (scraper, rules, processor, sync modules), buh-cli (binary "buh" with client/daemon subcommands), and buh-ws (axum WebSocket server). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
39
crates/buh-entity/src/config.rs
Normal file
39
crates/buh-entity/src/config.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::media::MediaType;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct DaemonConfig {
|
||||
pub database: DatabaseConfig,
|
||||
pub indexers: Vec<IndexerConfig>,
|
||||
pub sync: Vec<SyncTarget>,
|
||||
pub routines: RoutineConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct DatabaseConfig {
|
||||
pub url: String,
|
||||
pub auth_token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct IndexerConfig {
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
pub api_key: Option<String>,
|
||||
pub media_types: Vec<MediaType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct SyncTarget {
|
||||
pub name: String,
|
||||
pub media_type: MediaType,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct RoutineConfig {
|
||||
pub scrape: bool,
|
||||
pub process: bool,
|
||||
pub sync: bool,
|
||||
}
|
||||
4
crates/buh-entity/src/lib.rs
Normal file
4
crates/buh-entity/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod config;
|
||||
pub mod media;
|
||||
pub mod rule;
|
||||
pub mod torrent;
|
||||
19
crates/buh-entity/src/media.rs
Normal file
19
crates/buh-entity/src/media.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum MediaType {
|
||||
Show,
|
||||
Movie,
|
||||
Music,
|
||||
Book,
|
||||
AudioBook,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MediaItem {
|
||||
pub id: Option<i64>,
|
||||
pub media_type: MediaType,
|
||||
pub title: String,
|
||||
pub year: Option<u16>,
|
||||
}
|
||||
20
crates/buh-entity/src/rule.rs
Normal file
20
crates/buh-entity/src/rule.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::media::MediaType;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum RuleAction {
|
||||
Ingest,
|
||||
Discard,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Rule {
|
||||
pub id: Option<i64>,
|
||||
pub name: String,
|
||||
pub media_type: MediaType,
|
||||
pub action: RuleAction,
|
||||
pub pattern: String,
|
||||
pub priority: i32,
|
||||
}
|
||||
25
crates/buh-entity/src/torrent.rs
Normal file
25
crates/buh-entity/src/torrent.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::media::MediaType;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum TorrentState {
|
||||
Discovered,
|
||||
Queued,
|
||||
Downloading,
|
||||
Downloaded,
|
||||
Processed,
|
||||
Synced,
|
||||
Discarded,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Torrent {
|
||||
pub id: Option<i64>,
|
||||
pub info_hash: String,
|
||||
pub name: String,
|
||||
pub media_type: Option<MediaType>,
|
||||
pub state: TorrentState,
|
||||
pub source_url: String,
|
||||
}
|
||||
Reference in New Issue
Block a user