pinakes-server: import directly from extracted crates
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Id43ab8edfd56196d376d72ecc136f6086a6a6964
This commit is contained in:
parent
934fcba8ca
commit
047801a9da
9 changed files with 77 additions and 59 deletions
|
|
@ -7,6 +7,11 @@ license.workspace = true
|
|||
[dependencies]
|
||||
pinakes-core = { workspace = true }
|
||||
pinakes-plugin-api = { workspace = true }
|
||||
pinakes-types = { workspace = true }
|
||||
pinakes-enrichment = { workspace = true }
|
||||
pinakes-metadata = { workspace = true }
|
||||
pinakes-plugin = { workspace = true }
|
||||
pinakes-sync = { workspace = true }
|
||||
|
||||
tokio = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -13,10 +13,8 @@ pub struct ExternalMetadataResponse {
|
|||
pub last_updated: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl From<pinakes_core::enrichment::ExternalMetadata>
|
||||
for ExternalMetadataResponse
|
||||
{
|
||||
fn from(m: pinakes_core::enrichment::ExternalMetadata) -> Self {
|
||||
impl From<pinakes_enrichment::ExternalMetadata> for ExternalMetadataResponse {
|
||||
fn from(m: pinakes_enrichment::ExternalMetadata) -> Self {
|
||||
let metadata = serde_json::from_str(&m.metadata_json).unwrap_or_else(|e| {
|
||||
tracing::warn!(
|
||||
"failed to deserialize external metadata JSON for media {}: {}",
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ pub struct DeviceResponse {
|
|||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl From<pinakes_core::sync::SyncDevice> for DeviceResponse {
|
||||
fn from(d: pinakes_core::sync::SyncDevice) -> Self {
|
||||
impl From<pinakes_sync::SyncDevice> for DeviceResponse {
|
||||
fn from(d: pinakes_sync::SyncDevice) -> Self {
|
||||
Self {
|
||||
id: d.id.0.to_string(),
|
||||
name: d.name,
|
||||
|
|
@ -72,8 +72,8 @@ pub struct SyncChangeResponse {
|
|||
pub timestamp: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl From<pinakes_core::sync::SyncLogEntry> for SyncChangeResponse {
|
||||
fn from(e: pinakes_core::sync::SyncLogEntry) -> Self {
|
||||
impl From<pinakes_sync::SyncLogEntry> for SyncChangeResponse {
|
||||
fn from(e: pinakes_sync::SyncLogEntry) -> Self {
|
||||
Self {
|
||||
id: e.id.to_string(),
|
||||
sequence: e.sequence,
|
||||
|
|
@ -124,8 +124,8 @@ pub struct ConflictResponse {
|
|||
pub detected_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl From<pinakes_core::sync::SyncConflict> for ConflictResponse {
|
||||
fn from(c: pinakes_core::sync::SyncConflict) -> Self {
|
||||
impl From<pinakes_sync::SyncConflict> for ConflictResponse {
|
||||
fn from(c: pinakes_sync::SyncConflict) -> Self {
|
||||
Self {
|
||||
id: c.id.to_string(),
|
||||
path: c.path,
|
||||
|
|
@ -162,8 +162,8 @@ pub struct UploadSessionResponse {
|
|||
pub expires_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl From<pinakes_core::sync::UploadSession> for UploadSessionResponse {
|
||||
fn from(s: pinakes_core::sync::UploadSession) -> Self {
|
||||
impl From<pinakes_sync::UploadSession> for UploadSessionResponse {
|
||||
fn from(s: pinakes_sync::UploadSession) -> Self {
|
||||
Self {
|
||||
id: s.id.to_string(),
|
||||
target_path: s.target_path,
|
||||
|
|
|
|||
|
|
@ -236,10 +236,27 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Initialize plugin manager if plugins are enabled (needed before job queue)
|
||||
let plugin_manager = if config.plugins.enabled {
|
||||
match pinakes_core::plugin::PluginManager::new(
|
||||
let pm_cfg = {
|
||||
let p = &config.plugins;
|
||||
pinakes_plugin::PluginManagerConfig {
|
||||
plugin_dirs: p.plugin_dirs.clone(),
|
||||
enable_hot_reload: p.enable_hot_reload,
|
||||
allow_unsigned: p.allow_unsigned,
|
||||
max_concurrent_ops: p.max_concurrent_ops,
|
||||
plugin_timeout_secs: p.plugin_timeout_secs,
|
||||
timeouts: pinakes_types::config::PluginTimeoutConfig {
|
||||
capability_query_secs: p.timeouts.capability_query_secs,
|
||||
processing_secs: p.timeouts.processing_secs,
|
||||
event_handler_secs: p.timeouts.event_handler_secs,
|
||||
},
|
||||
max_consecutive_failures: p.max_consecutive_failures,
|
||||
trusted_keys: p.trusted_keys.clone(),
|
||||
}
|
||||
};
|
||||
match pinakes_plugin::PluginManager::new(
|
||||
config.plugins.data_dir.clone(),
|
||||
config.plugins.cache_dir.clone(),
|
||||
config.plugins.clone().into(),
|
||||
pm_cfg,
|
||||
) {
|
||||
Ok(pm) => {
|
||||
tracing::info!("Plugin manager initialized");
|
||||
|
|
@ -538,15 +555,13 @@ async fn main() -> Result<()> {
|
|||
}
|
||||
},
|
||||
JobKind::Enrich { media_ids } => {
|
||||
use pinakes_core::{
|
||||
enrichment::{
|
||||
MetadataEnricher,
|
||||
books::BookEnricher,
|
||||
lastfm::LastFmEnricher,
|
||||
musicbrainz::MusicBrainzEnricher,
|
||||
tmdb::TmdbEnricher,
|
||||
},
|
||||
media_type::MediaCategory,
|
||||
use pinakes_core::media_type::MediaCategory;
|
||||
use pinakes_enrichment::{
|
||||
MetadataEnricher,
|
||||
books::BookEnricher,
|
||||
lastfm::LastFmEnricher,
|
||||
musicbrainz::MusicBrainzEnricher,
|
||||
tmdb::TmdbEnricher,
|
||||
};
|
||||
|
||||
let enrich_cfg = &config.enrichment;
|
||||
|
|
@ -598,7 +613,7 @@ async fn main() -> Result<()> {
|
|||
let category = item.media_type.category();
|
||||
for enricher in &enrichers {
|
||||
let source = enricher.source();
|
||||
use pinakes_core::enrichment::EnrichmentSourceType;
|
||||
use pinakes_enrichment::EnrichmentSourceType;
|
||||
let applicable = match source {
|
||||
EnrichmentSourceType::MusicBrainz
|
||||
| EnrichmentSourceType::LastFm => {
|
||||
|
|
@ -758,7 +773,7 @@ async fn main() -> Result<()> {
|
|||
let chunked_upload_manager = {
|
||||
let config_read = config_arc.read().await;
|
||||
if config_read.sync.enabled {
|
||||
let manager = pinakes_core::sync::ChunkedUploadManager::new(
|
||||
let manager = pinakes_sync::ChunkedUploadManager::new(
|
||||
config_read.sync.temp_upload_dir.clone(),
|
||||
);
|
||||
match manager.init().await {
|
||||
|
|
|
|||
|
|
@ -1258,10 +1258,10 @@ pub async fn rename_media(
|
|||
|
||||
// Record in sync log
|
||||
let item = state.storage.get_media(media_id).await?;
|
||||
let change = pinakes_core::sync::SyncLogEntry {
|
||||
let change = pinakes_sync::SyncLogEntry {
|
||||
id: uuid::Uuid::now_v7(),
|
||||
sequence: 0,
|
||||
change_type: pinakes_core::sync::SyncChangeType::Moved,
|
||||
change_type: pinakes_sync::SyncChangeType::Moved,
|
||||
media_id: Some(media_id),
|
||||
path: item.path.to_string_lossy().to_string(),
|
||||
content_hash: Some(item.content_hash.clone()),
|
||||
|
|
@ -1319,10 +1319,10 @@ pub async fn move_media_endpoint(
|
|||
|
||||
// Record in sync log
|
||||
let item = state.storage.get_media(media_id).await?;
|
||||
let change = pinakes_core::sync::SyncLogEntry {
|
||||
let change = pinakes_sync::SyncLogEntry {
|
||||
id: uuid::Uuid::now_v7(),
|
||||
sequence: 0,
|
||||
change_type: pinakes_core::sync::SyncChangeType::Moved,
|
||||
change_type: pinakes_sync::SyncChangeType::Moved,
|
||||
media_id: Some(media_id),
|
||||
path: item.path.to_string_lossy().to_string(),
|
||||
content_hash: Some(item.content_hash.clone()),
|
||||
|
|
@ -1404,10 +1404,10 @@ pub async fn batch_move_media(
|
|||
continue;
|
||||
};
|
||||
let new_path = req.destination.join(file_name);
|
||||
let change = pinakes_core::sync::SyncLogEntry {
|
||||
let change = pinakes_sync::SyncLogEntry {
|
||||
id: uuid::Uuid::now_v7(),
|
||||
sequence: 0,
|
||||
change_type: pinakes_core::sync::SyncChangeType::Moved,
|
||||
change_type: pinakes_sync::SyncChangeType::Moved,
|
||||
media_id: Some(*media_id),
|
||||
path: new_path.to_string_lossy().to_string(),
|
||||
content_hash: None,
|
||||
|
|
@ -1464,10 +1464,10 @@ pub async fn soft_delete_media(
|
|||
state.storage.soft_delete_media(media_id).await?;
|
||||
|
||||
// Record in sync log
|
||||
let change = pinakes_core::sync::SyncLogEntry {
|
||||
let change = pinakes_sync::SyncLogEntry {
|
||||
id: uuid::Uuid::now_v7(),
|
||||
sequence: 0,
|
||||
change_type: pinakes_core::sync::SyncChangeType::Deleted,
|
||||
change_type: pinakes_sync::SyncChangeType::Deleted,
|
||||
media_id: Some(media_id),
|
||||
path: item.path.to_string_lossy().to_string(),
|
||||
content_hash: Some(item.content_hash.clone()),
|
||||
|
|
@ -1524,10 +1524,10 @@ pub async fn restore_media(
|
|||
let item = state.storage.get_media(media_id).await?;
|
||||
|
||||
// Record in sync log
|
||||
let change = pinakes_core::sync::SyncLogEntry {
|
||||
let change = pinakes_sync::SyncLogEntry {
|
||||
id: uuid::Uuid::now_v7(),
|
||||
sequence: 0,
|
||||
change_type: pinakes_core::sync::SyncChangeType::Created,
|
||||
change_type: pinakes_sync::SyncChangeType::Created,
|
||||
media_id: Some(media_id),
|
||||
path: item.path.to_string_lossy().to_string(),
|
||||
content_hash: Some(item.content_hash.clone()),
|
||||
|
|
@ -1681,10 +1681,10 @@ pub async fn permanent_delete_media(
|
|||
state.storage.delete_media(media_id).await?;
|
||||
|
||||
// Record in sync log
|
||||
let change = pinakes_core::sync::SyncLogEntry {
|
||||
let change = pinakes_sync::SyncLogEntry {
|
||||
id: uuid::Uuid::now_v7(),
|
||||
sequence: 0,
|
||||
change_type: pinakes_core::sync::SyncChangeType::Deleted,
|
||||
change_type: pinakes_sync::SyncChangeType::Deleted,
|
||||
media_id: Some(media_id),
|
||||
path: item.path.to_string_lossy().to_string(),
|
||||
content_hash: Some(item.content_hash.clone()),
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use axum::{
|
|||
Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use pinakes_core::plugin::PluginManager;
|
||||
use pinakes_plugin::PluginManager;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::{
|
||||
|
|
|
|||
|
|
@ -11,19 +11,17 @@ use chrono::Utc;
|
|||
use pinakes_core::{
|
||||
config::ConflictResolution,
|
||||
model::ContentHash,
|
||||
sync::{
|
||||
DeviceId,
|
||||
DeviceType,
|
||||
SyncChangeType,
|
||||
SyncConflict,
|
||||
SyncDevice,
|
||||
SyncLogEntry,
|
||||
UploadSession,
|
||||
UploadStatus,
|
||||
generate_device_token,
|
||||
hash_device_token,
|
||||
update_device_cursor,
|
||||
},
|
||||
sync::{generate_device_token, hash_device_token, update_device_cursor},
|
||||
};
|
||||
use pinakes_sync::{
|
||||
DeviceId,
|
||||
DeviceType,
|
||||
SyncChangeType,
|
||||
SyncConflict,
|
||||
SyncDevice,
|
||||
SyncLogEntry,
|
||||
UploadSession,
|
||||
UploadStatus,
|
||||
};
|
||||
use tokio::io::{AsyncReadExt, AsyncSeekExt};
|
||||
use tokio_util::io::ReaderStream;
|
||||
|
|
@ -176,7 +174,7 @@ pub async fn get_device(
|
|||
.map_err(|e| ApiError::not_found(format!("Device not found: {e}")))?;
|
||||
|
||||
// Verify ownership
|
||||
if device.user_id != user_id {
|
||||
if device.user_id.0 != user_id.0 {
|
||||
return Err(ApiError::forbidden("Not authorized to access this device"));
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +211,7 @@ pub async fn update_device(
|
|||
.map_err(|e| ApiError::not_found(format!("Device not found: {e}")))?;
|
||||
|
||||
// Verify ownership
|
||||
if device.user_id != user_id {
|
||||
if device.user_id.0 != user_id.0 {
|
||||
return Err(ApiError::forbidden("Not authorized to update this device"));
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +259,7 @@ pub async fn delete_device(
|
|||
.map_err(|e| ApiError::not_found(format!("Device not found: {e}")))?;
|
||||
|
||||
// Verify ownership
|
||||
if device.user_id != user_id {
|
||||
if device.user_id.0 != user_id.0 {
|
||||
return Err(ApiError::forbidden("Not authorized to delete this device"));
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +300,7 @@ pub async fn regenerate_token(
|
|||
.map_err(|e| ApiError::not_found(format!("Device not found: {e}")))?;
|
||||
|
||||
// Verify ownership
|
||||
if device.user_id != user_id {
|
||||
if device.user_id.0 != user_id.0 {
|
||||
return Err(ApiError::forbidden(
|
||||
"Not authorized to regenerate token for this device",
|
||||
));
|
||||
|
|
|
|||
|
|
@ -5,14 +5,15 @@ use pinakes_core::{
|
|||
config::Config,
|
||||
jobs::JobQueue,
|
||||
managed_storage::ManagedStorageService,
|
||||
plugin::{PluginManager, PluginPipeline},
|
||||
plugin::PluginPipeline,
|
||||
scan::ScanProgress,
|
||||
scheduler::TaskScheduler,
|
||||
storage::DynStorageBackend,
|
||||
sync::ChunkedUploadManager,
|
||||
transcode::TranscodeService,
|
||||
webhooks::WebhookDispatcher,
|
||||
};
|
||||
use pinakes_plugin::PluginManager;
|
||||
use pinakes_sync::ChunkedUploadManager;
|
||||
use tokio::sync::{RwLock, Semaphore};
|
||||
|
||||
// Note: Sessions are now stored in the database via StorageBackend
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ use common::{
|
|||
test_addr,
|
||||
};
|
||||
use http_body_util::BodyExt;
|
||||
use pinakes_core::{config::PluginsConfig, plugin::PluginManager};
|
||||
use pinakes_core::config::PluginsConfig;
|
||||
use pinakes_plugin::PluginManager;
|
||||
use tower::ServiceExt;
|
||||
|
||||
async fn setup_app_with_plugins()
|
||||
|
|
@ -50,7 +51,7 @@ async fn setup_app_with_plugins()
|
|||
max_concurrent_ops: 2,
|
||||
plugin_timeout_secs: 10,
|
||||
timeouts:
|
||||
pinakes_core::config::PluginTimeoutConfig::default(),
|
||||
pinakes_types::config::PluginTimeoutConfig::default(),
|
||||
max_consecutive_failures: 5,
|
||||
trusted_keys: vec![],
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue