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:
2026-03-20 09:46:15 +02:00
commit b11a0b7c56
26 changed files with 4131 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
[package]
name = "buh-entity"
edition.workspace = true
version.workspace = true
[dependencies]
serde = { workspace = true }

View 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,
}

View File

@@ -0,0 +1,4 @@
pub mod config;
pub mod media;
pub mod rule;
pub mod torrent;

View 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>,
}

View 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,
}

View 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,
}