Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata group export #737

Merged
merged 21 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,6 @@ services:
POSTGRES_USER: postgres
POSTGRES_DB: postgres

mail:
image: axllent/mailpit
ports:
- 8025:8025
environment:
MP_SMTP_AUTH_ACCEPT_ANY: "1"
MP_SMTP_AUTH_ALLOW_INSECURE: "1"
MP_VERBOSE: "1"

volumes:
minio_storage:
postgres_storage:
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ryot"
version = "4.3.16"
version = "4.3.17"
edition = "2021"
repository = "https://github.com/IgnisDa/ryot"
license = "GPL-3.0"
Expand Down
1 change: 1 addition & 0 deletions apps/backend/src/entities/seen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub struct Model {
// Generated columns
pub last_updated_on: DateTimeUtc,
pub num_times_updated: i32,
pub total_time_spent: Option<i32>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
Expand Down
5 changes: 5 additions & 0 deletions apps/backend/src/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ impl ExporterService {
.export_media(user_id, &mut writer)
.await?;
}
ExportItem::MediaGroup => {
self.media_service
.export_media_group(user_id, &mut writer)
.await?;
}
ExportItem::People => {
self.media_service
.export_people(user_id, &mut writer)
Expand Down
5 changes: 1 addition & 4 deletions apps/backend/src/importer/audiobookshelf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,6 @@ pub async fn import(input: DeployAudiobookshelfImportInput) -> Result<ImportResu
Ok(ImportResult {
media,
failed_items,
people: vec![],
workouts: vec![],
collections: vec![],
measurements: vec![],
..Default::default()
})
}
5 changes: 1 addition & 4 deletions apps/backend/src/importer/goodreads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,6 @@ pub async fn import(
Ok(ImportResult {
media,
failed_items,
people: vec![],
workouts: vec![],
collections: vec![],
measurements: vec![],
..Default::default()
})
}
36 changes: 15 additions & 21 deletions apps/backend/src/importer/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use crate::{
fitness::resolver::ExerciseService,
importer::{DeployJsonImportInput, ImportResult},
models::media::{
ImportOrExportItemIdentifier, ImportOrExportMediaItem, ImportOrExportPersonItem,
ImportOrExportItemIdentifier, ImportOrExportMediaGroupItem, ImportOrExportMediaItem,
ImportOrExportPersonItem,
},
};

Expand All @@ -26,11 +27,7 @@ pub async fn media_import(input: DeployJsonImportInput) -> Result<ImportResult>
});
Ok(ImportResult {
media,
people: vec![],
workouts: vec![],
collections: vec![],
failed_items: vec![],
measurements: vec![],
..Default::default()
})
}

Expand All @@ -39,11 +36,7 @@ pub async fn measurements_import(input: DeployJsonImportInput) -> Result<ImportR
let measurements = serde_json::from_str::<Vec<user_measurement::Model>>(&export).unwrap();
Ok(ImportResult {
measurements,
people: vec![],
media: vec![],
workouts: vec![],
collections: vec![],
failed_items: vec![],
..Default::default()
})
}

Expand All @@ -52,11 +45,7 @@ pub async fn people_import(input: DeployJsonImportInput) -> Result<ImportResult>
let people = serde_json::from_str::<Vec<ImportOrExportPersonItem>>(&export).unwrap();
Ok(ImportResult {
people,
media: vec![],
workouts: vec![],
collections: vec![],
measurements: vec![],
failed_items: vec![],
..Default::default()
})
}

Expand All @@ -72,10 +61,15 @@ pub async fn workouts_import(
.collect();
Ok(ImportResult {
workouts,
people: vec![],
media: vec![],
collections: vec![],
measurements: vec![],
failed_items: vec![],
..Default::default()
})
}

pub async fn media_groups_import(input: DeployJsonImportInput) -> Result<ImportResult> {
let export = fs::read_to_string(input.export)?;
let media_groups = serde_json::from_str::<Vec<ImportOrExportMediaGroupItem>>(&export).unwrap();
Ok(ImportResult {
media_groups,
..Default::default()
})
}
6 changes: 1 addition & 5 deletions apps/backend/src/importer/mal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,7 @@ pub async fn import(input: DeployMalImportInput) -> Result<ImportResult> {
}
Ok(ImportResult {
media,
people: vec![],
workouts: vec![],
collections: vec![],
failed_items: vec![],
measurements: vec![],
..Default::default()
})
}

Expand Down
8 changes: 3 additions & 5 deletions apps/backend/src/importer/media_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ pub async fn import(input: DeployMediaTrackerImportInput) -> Result<ImportResult
.unwrap();
let mut lists: Vec<ListResponse> = rsp.body_json().await.unwrap();

let all_collections = lists
let collections = lists
.iter()
.map(|l| CreateOrUpdateCollectionInput {
name: l.name.clone(),
Expand Down Expand Up @@ -368,9 +368,7 @@ pub async fn import(input: DeployMediaTrackerImportInput) -> Result<ImportResult
Ok(ImportResult {
media: final_data,
failed_items,
collections: all_collections,
people: vec![],
workouts: vec![],
measurements: vec![],
collections,
..Default::default()
})
}
128 changes: 123 additions & 5 deletions apps/backend/src/importer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ use crate::{
fitness::UserWorkoutInput,
media::{
CommitPersonInput, CreateOrUpdateCollectionInput, ImportOrExportItemIdentifier,
ImportOrExportItemRating, ImportOrExportMediaItem, ImportOrExportPersonItem,
PartialMetadataWithoutId, PostReviewInput, ProgressUpdateInput,
ImportOrExportItemRating, ImportOrExportMediaGroupItem, ImportOrExportMediaItem,
ImportOrExportPersonItem, PartialMetadataWithoutId, PostReviewInput,
ProgressUpdateInput,
},
BackgroundJob, ChangeCollectionToEntityInput, IdObject,
},
Expand Down Expand Up @@ -159,10 +160,11 @@ pub struct ImportDetails {
pub total: usize,
}

#[derive(Debug)]
#[derive(Debug, Default)]
pub struct ImportResult {
collections: Vec<CreateOrUpdateCollectionInput>,
media: Vec<ImportOrExportMediaItem>,
media_groups: Vec<ImportOrExportMediaGroupItem>,
failed_items: Vec<ImportFailedItem>,
people: Vec<ImportOrExportPersonItem>,
workouts: Vec<UserWorkoutInput>,
Expand Down Expand Up @@ -286,6 +288,7 @@ impl ImporterService {
}
ImportSource::PeopleJson => self.import_people(user_id, input).await?,
ImportSource::MeasurementsJson => self.import_measurements(user_id, input).await?,
ImportSource::MediaGroupJson => self.import_media_groups(user_id, input).await?,
_ => self.import_media(user_id, input).await?,
};
self.media_service
Expand Down Expand Up @@ -328,7 +331,7 @@ impl ImporterService {
.await?;
for review in item.reviews.iter() {
if let Some(input) =
convert_review_into_input(review, &preferences, None, Some(person.id))
convert_review_into_input(review, &preferences, None, Some(person.id), None)
{
if let Err(e) = self.media_service.post_review(user_id, input).await {
import.failed_items.push(ImportFailedItem {
Expand Down Expand Up @@ -434,6 +437,119 @@ impl ImporterService {
Ok(())
}

#[instrument(skip(self, input))]
async fn import_media_groups(
&self,
user_id: i32,
input: Box<DeployImportJobInput>,
) -> Result<()> {
let db_import_job = self.start_import_job(user_id, input.source).await?;
let mut import = match input.source {
ImportSource::MediaGroupJson => json::media_groups_import(input.json.unwrap())
.await
.unwrap(),
_ => unreachable!(),
};
let preferences =
partial_user_by_id::<UserWithOnlyPreferences>(&self.media_service.db, user_id)
.await?
.preferences;
import.media = import
.media
.into_iter()
.sorted_unstable_by_key(|m| {
m.seen_history.len() + m.reviews.len() + m.collections.len()
})
.rev()
.collect_vec();
for col_details in import.collections.into_iter() {
self.media_service
.create_or_update_collection(user_id, col_details)
.await?;
}
for (idx, item) in import.media_groups.iter().enumerate() {
tracing::debug!(
"Importing media group with identifier = {iden}",
iden = &item.title
);
let rev_length = item.reviews.len();
let data = self
.media_service
.commit_metadata_group_internal(&item.identifier, item.lot, item.source)
.await;
let metadata_id = match data {
Ok(r) => r.0,
Err(e) => {
tracing::error!("{e:?}");
import.failed_items.push(ImportFailedItem {
lot: Some(item.lot),
step: ImportFailStep::MediaDetailsFromProvider,
identifier: item.title.to_owned(),
error: Some(e.message),
});
continue;
}
};
for review in item.reviews.iter() {
if let Some(input) =
convert_review_into_input(review, &preferences, None, None, Some(metadata_id))
{
if let Err(e) = self.media_service.post_review(user_id, input).await {
import.failed_items.push(ImportFailedItem {
lot: Some(item.lot),
step: ImportFailStep::ReviewConversion,
identifier: item.title.to_owned(),
error: Some(e.message),
});
};
}
}
for col in item.collections.iter() {
self.media_service
.create_or_update_collection(
user_id,
CreateOrUpdateCollectionInput {
name: col.to_string(),
..Default::default()
},
)
.await?;
self.media_service
.add_entity_to_collection(
user_id,
ChangeCollectionToEntityInput {
collection_name: col.to_string(),
metadata_id: Some(metadata_id),
..Default::default()
},
)
.await
.ok();
}
tracing::debug!(
"Imported item: {idx}/{total}, lot: {lot}, review count: {rev}, collection count: {col}",
idx = idx + 1,
total = import.media.len(),
lot = item.lot,
rev = rev_length,
col = item.collections.len(),
);
}
tracing::debug!(
"Imported {total} media group items from {source}",
total = import.media.len(),
source = db_import_job.source
);
let details = ImportResultResponse {
import: ImportDetails {
total: import.media.len(),
},
failed_items: import.failed_items,
};
self.finish_import_job(db_import_job, details).await?;
Ok(())
}

#[instrument(skip(self, input))]
async fn import_media(&self, user_id: i32, input: Box<DeployImportJobInput>) -> Result<()> {
let db_import_job = self.start_import_job(user_id, input.source).await?;
Expand Down Expand Up @@ -555,7 +671,7 @@ impl ImporterService {
}
for review in item.reviews.iter() {
if let Some(input) =
convert_review_into_input(review, &preferences, Some(metadata.id), None)
convert_review_into_input(review, &preferences, Some(metadata.id), None, None)
{
if let Err(e) = self.media_service.post_review(user_id, input).await {
import.failed_items.push(ImportFailedItem {
Expand Down Expand Up @@ -648,6 +764,7 @@ fn convert_review_into_input(
preferences: &UserPreferences,
metadata_id: Option<i32>,
person_id: Option<i32>,
metadata_group_id: Option<i32>,
) -> Option<PostReviewInput> {
if review.review.is_none() && review.rating.is_none() {
tracing::debug!("Skipping review since it has no content");
Expand All @@ -668,6 +785,7 @@ fn convert_review_into_input(
date: date.flatten(),
metadata_id,
person_id,
metadata_group_id,
show_season_number: review.show_season_number,
show_episode_number: review.show_episode_number,
podcast_episode_number: review.podcast_episode_number,
Expand Down
5 changes: 1 addition & 4 deletions apps/backend/src/importer/movary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,6 @@ pub async fn import(input: DeployMovaryImportInput) -> Result<ImportResult> {
Ok(ImportResult {
media,
failed_items,
people: vec![],
workouts: vec![],
collections: vec![],
measurements: vec![],
..Default::default()
})
}
5 changes: 1 addition & 4 deletions apps/backend/src/importer/story_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,6 @@ pub async fn import(
Ok(ImportResult {
media,
failed_items,
people: vec![],
workouts: vec![],
collections: vec![],
measurements: vec![],
..Default::default()
})
}
6 changes: 1 addition & 5 deletions apps/backend/src/importer/strong_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,6 @@ pub async fn import(
}
Ok(ImportResult {
workouts,
media: vec![],
people: vec![],
collections: vec![],
failed_items: vec![],
measurements: vec![],
..Default::default()
})
}
Loading