Skip to content

Commit b8a4f25

Browse files
committed
mutuelle
1 parent 42ec0cb commit b8a4f25

File tree

23 files changed

+682
-1603
lines changed

23 files changed

+682
-1603
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ sha2 = "0.10"
7373
axum-extra = { version = "0.9.2", features = ["query"] }
7474
http = "1.1.0"
7575
extism = "1.10.0"
76-
rs-plugin-common-interfaces = { version = "0.33.0", features = ["rusqlite",] }
76+
rs-plugin-common-interfaces = { version = "0.34.0", features = ["rusqlite",] }
7777
async-recursion = "1.1.0"
7878
async-compression = { version = "0.4.6", features = ["tokio"] }
7979
youtube_dl = { version = "0.10.0", features = ["tokio", "downloader-rustls-tls"] }

src/domain/mod.rs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,11 @@ pub trait RsIdsExt {
2020

2121
impl RsIdsExt for RsIds {
2222
fn into_all_external(self) -> Vec<String> {
23-
let mut ids = Vec::new();
24-
if let Some(imdb) = self.imdb {
25-
ids.push(format!("imdb:{}", imdb));
26-
}
27-
if let Some(trakt) = self.trakt {
28-
ids.push(format!("trakt:{}", trakt));
29-
}
30-
if let Some(tmdb) = self.tmdb {
31-
ids.push(format!("tmdb:{}", tmdb));
32-
}
33-
if let Some(tvdb) = self.tvdb {
34-
ids.push(format!("tvdb:{}", tvdb));
35-
}
36-
if let Some(slug) = self.slug {
37-
ids.push(format!("slug:{}", slug));
38-
}
39-
ids
23+
self.as_all_external_ids()
4024
}
4125

4226
fn into_all_external_or_local(self) -> Vec<String> {
43-
let redseat = self.redseat.clone();
44-
let mut ids = self.into_all_external();
45-
if let Some(redseat) = redseat {
46-
ids.push(format!("redseat:{}", redseat));
47-
}
48-
ids
27+
self.as_all_ids()
4928
}
5029
}
5130

src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use model::{server::AuthMessage, store::SqliteStore, ModelController};
2020
use plugins::{
2121
medias::{
2222
imdb::ImdbContext,
23-
tmdb::{tmdb_configuration::TmdbConfiguration, TmdbContext},
2423
trakt::TraktContext,
2524
},
2625
PluginManager,

src/model/books.rs

Lines changed: 30 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use std::io::Cursor;
22

33
use async_recursion::async_recursion;
4-
use futures::TryStreamExt;
54
use nanoid::nanoid;
65
use rs_plugin_common_interfaces::{
7-
ExternalImage, ImageType, domain::{ItemWithRelations, other_ids::OtherIds, rs_ids::{ApplyRsIds, RsIds}}, lookup::{RsLookupBook, RsLookupMetadataResult, RsLookupQuery}, request::RsRequest
6+
ExternalImage, ImageType, domain::{ItemWithRelations, other_ids::OtherIds, rs_ids::{ApplyRsIds, RsIds}}, lookup::{RsLookupBook, RsLookupMetadataResult, RsLookupQuery},
87
};
98
use serde::{Deserialize, Serialize};
109
use strum_macros::EnumString;
11-
use tokio::io::AsyncWriteExt;
1210

1311
use crate::{
1412
domain::{
@@ -23,13 +21,14 @@ use crate::{
2321
tags::TagForAdd,
2422
},
2523
plugins::sources::{
26-
error::SourcesError, AsyncReadPinBox, FileStreamResult, Source, SourceRead,
24+
error::SourcesError, AsyncReadPinBox, FileStreamResult,
2725
},
2826
routes::sse::SseEvent,
29-
tools::image_tools::{convert_image_reader, resize_image_reader, ImageSize},
27+
tools::image_tools::{convert_image_reader, ImageSize},
3028
};
3129

3230
use super::{
31+
entity_images::EntityImageConfig,
3332
error::{Error, Result},
3433
store::sql::SqlOrder,
3534
users::ConnectedUser,
@@ -69,19 +68,6 @@ pub struct BookQuery {
6968
}
7069

7170
impl ModelController {
72-
fn select_book_image_url(images: Vec<ExternalImage>, kind: &ImageType) -> Option<RsRequest> {
73-
let exact_images: Vec<_> = images.into_iter().filter(|image| image.match_type.is_some()).collect();
74-
let first_kind_match = exact_images
75-
.iter()
76-
.find(|image| image.kind.as_ref() == Some(kind))
77-
.map(|image| image.url.clone());
78-
if first_kind_match.is_some() {
79-
first_kind_match
80-
} else {
81-
exact_images.into_iter().next().map(|image| image.url)
82-
}
83-
}
84-
8571
pub async fn get_books(
8672
&self,
8773
library_id: &str,
@@ -217,11 +203,11 @@ impl ModelController {
217203
new_book.apply_rs_ids(&ids);
218204
println!("Adding book with ids: {:?}", ids);
219205
println!("Adding book {:?}", new_book);
220-
if ids.isbn13.is_some()
221-
|| ids.openlibrary_edition_id.is_some()
222-
|| ids.openlibrary_work_id.is_some()
223-
|| ids.google_books_volume_id.is_some()
224-
|| ids.asin.is_some()
206+
if ids.isbn13().is_some()
207+
|| ids.openlibrary_edition_id().is_some()
208+
|| ids.openlibrary_work_id().is_some()
209+
|| ids.google_books_volume_id().is_some()
210+
|| ids.asin().is_some()
225211
{
226212
if let Some(existing) = self
227213
.get_book_by_external_id(library_id, ids, requesting_user)
@@ -449,99 +435,25 @@ impl ModelController {
449435
requesting_user: &ConnectedUser,
450436
) -> RsResult<FileStreamResult<AsyncReadPinBox>> {
451437
let target_kind = kind.unwrap_or(ImageType::Poster);
452-
438+
let config = EntityImageConfig { folder: ".books", cache_prefix: "book" };
453439
if RsIds::is_id(book_id) {
454440
let book_ids: RsIds = book_id.to_string().try_into()?;
455441
let store = self.store.get_library_store(library_id)?;
456442
let existing_book = store.get_book_by_external_id(book_ids.clone()).await?;
457-
458443
if let Some(existing_book) = existing_book {
459-
self.book_image(
460-
library_id,
461-
&existing_book.item.id,
462-
Some(target_kind),
463-
size,
464-
requesting_user,
465-
)
466-
.await
467-
} else {
468-
// Book not in DB — fetch image from plugin lookup and cache it
469-
let local_provider = self.library_source_for_library(library_id).await?;
470-
let image_path = format!(
471-
"cache/book-{}-{}.avif",
472-
book_id.replace(':', "-"),
473-
target_kind
474-
);
475-
476-
if !local_provider.exists(&image_path).await {
477-
let lookup_query = RsLookupBook {
478-
name: None,
479-
ids: Some(book_ids),
480-
page_key: None,
481-
};
482-
let image_request = self
483-
.get_book_image_url(
484-
lookup_query,
485-
Some(library_id.to_string()),
486-
&target_kind,
487-
requesting_user,
488-
)
489-
.await?
490-
.ok_or(crate::Error::NotFound(format!(
491-
"Unable to get book image url: {} kind {:?}",
492-
book_id, target_kind
493-
)))?;
494-
let (_, mut writer) = local_provider.get_file_write_stream(&image_path).await?;
495-
let image_reader = SourceRead::Request(image_request)
496-
.into_reader(
497-
Some(library_id),
498-
None,
499-
None,
500-
Some((self.clone(), requesting_user)),
501-
None,
502-
)
503-
.await?;
504-
let resized = resize_image_reader(
505-
image_reader.stream,
506-
ImageSize::Large.to_size(),
507-
image::ImageFormat::Avif,
508-
Some(70),
509-
false,
510-
)
511-
.await?;
512-
writer.write_all(&resized).await?;
513-
}
514-
515-
let source = local_provider.get_file(&image_path, None).await?;
516-
match source {
517-
SourceRead::Stream(s) => Ok(s),
518-
SourceRead::Request(_) => Err(crate::Error::GenericRedseatError),
519-
}
444+
return self.book_image(library_id, &existing_book.item.id, Some(target_kind), size, requesting_user).await;
520445
}
446+
let lookup_query = RsLookupQuery::Book(RsLookupBook {
447+
name: None,
448+
ids: Some(book_ids),
449+
page_key: None,
450+
});
451+
self.serve_cached_entity_image(library_id, book_id, lookup_query, &target_kind, &config, requesting_user).await
521452
} else {
522-
if !self
523-
.has_library_image(
524-
library_id,
525-
".books",
526-
book_id,
527-
Some(target_kind.clone()),
528-
requesting_user,
529-
)
530-
.await?
531-
{
532-
self.refresh_book_image(library_id, book_id, &target_kind, requesting_user)
533-
.await?;
534-
}
535-
536-
self.library_image(
537-
library_id,
538-
".books",
539-
book_id,
540-
Some(target_kind),
541-
size,
542-
requesting_user,
543-
)
544-
.await
453+
self.serve_local_entity_image(
454+
library_id, book_id, &target_kind, size, &config, requesting_user,
455+
async { self.refresh_book_image(library_id, book_id, &target_kind, requesting_user).await.map(|_| ()) },
456+
).await
545457
}
546458
}
547459

@@ -551,24 +463,7 @@ impl ModelController {
551463
library_id: Option<String>,
552464
requesting_user: &ConnectedUser,
553465
) -> RsResult<Vec<ExternalImage>> {
554-
let lookup_query = RsLookupQuery::Book(query);
555-
println!("Executing book image lookup with query: {:?}", lookup_query);
556-
let images = match self
557-
.exec_lookup_images(lookup_query, library_id, requesting_user, None)
558-
.await
559-
{
560-
Ok(images) => images,
561-
Err(error) => {
562-
crate::tools::log::log_error(
563-
crate::tools::log::LogServiceType::Plugin,
564-
format!("book image lookup failed: {:#}", error),
565-
);
566-
Vec::new()
567-
}
568-
};
569-
570-
//println!("result: {:?}", images);
571-
Ok(images)
466+
self.get_entity_images(RsLookupQuery::Book(query), library_id, requesting_user).await
572467
}
573468

574469
pub async fn get_book_image_url(
@@ -577,11 +472,8 @@ impl ModelController {
577472
library_id: Option<String>,
578473
kind: &ImageType,
579474
requesting_user: &ConnectedUser,
580-
) -> RsResult<Option<RsRequest>> {
581-
let images = self
582-
.get_book_images(query, library_id, requesting_user)
583-
.await?;
584-
Ok(Self::select_book_image_url(images, kind))
475+
) -> RsResult<Option<rs_plugin_common_interfaces::RsRequest>> {
476+
self.get_entity_image_url(RsLookupQuery::Book(query), library_id, kind, requesting_user).await
585477
}
586478

587479
pub async fn download_book_image(
@@ -591,23 +483,7 @@ impl ModelController {
591483
kind: &ImageType,
592484
requesting_user: &ConnectedUser,
593485
) -> RsResult<AsyncReadPinBox> {
594-
let request = self
595-
.get_book_image_url(query, library_id.clone(), kind, requesting_user)
596-
.await?
597-
.ok_or(crate::Error::NotFound(format!(
598-
"Unable to get book image url for kind: {:?}",
599-
kind
600-
)))?;
601-
let reader = SourceRead::Request(request)
602-
.into_reader(
603-
library_id.as_deref(),
604-
None,
605-
None,
606-
Some((self.clone(), requesting_user)),
607-
None,
608-
)
609-
.await?;
610-
Ok(reader.stream)
486+
self.download_entity_image(RsLookupQuery::Book(query), library_id, kind, requesting_user).await
611487
}
612488

613489
pub async fn refresh_book_image(
@@ -622,31 +498,16 @@ impl ModelController {
622498
.await?
623499
.item;
624500
let ids: RsIds = book.clone().into();
625-
let lookup_query = RsLookupBook {
501+
let lookup_query = RsLookupQuery::Book(RsLookupBook {
626502
name: Some(book.name.clone()),
627503
ids: Some(ids),
628504
page_key: None,
629-
};
505+
});
630506
let reader = self
631-
.download_book_image(
632-
lookup_query,
633-
Some(library_id.to_string()),
634-
kind,
635-
requesting_user,
636-
)
507+
.download_entity_image(lookup_query, Some(library_id.to_string()), kind, requesting_user)
637508
.await?;
638-
self.update_book_image(
639-
library_id,
640-
&book.id,
641-
kind,
642-
reader,
643-
&ConnectedUser::ServerAdmin,
644-
)
645-
.await?;
646-
Ok(self
647-
.get_book(library_id, book.id, requesting_user)
648-
.await?
649-
.item)
509+
self.update_book_image(library_id, &book.id, kind, reader, &ConnectedUser::ServerAdmin).await?;
510+
Ok(self.get_book(library_id, book.id, requesting_user).await?.item)
650511
}
651512

652513
pub async fn update_book_image(

0 commit comments

Comments
 (0)