Skip to content

Commit 94a8be7

Browse files
authored
Metadata group search (#721)
* feat(migrations): add column for metadata group id * feat(database): dedent the constraint SQL * feat(frontend): redirect if not authenticated * feat(backend): generate entities for new db schema * feat(migrations): migration data for user_to_metadata_group * feat(backend): return only metadata groups related to user in list page * fix(frontend): send auth details for media group list * fix(backend): join correct table * feat(backend): do not send version in coredetails * fix(frontend): do not display version in frontend * refactor(backend): allow associating user_to_entity with metadata group * chore(frontend): adapt to new gql schema * refactor(frontend): move media ownership modal to common action * feat(frontend): allow creating media ownership for metadata groups * fix(frontend): post to correct endpoint * feat(frontend): allow owning media groups * fix(backend): case export attributes correctly * feat(migrations): change name of column * feat(backend): change name of column in entity * fix(migrations): user_to_entity will now be updated * feat(backend): store correct media to entity reason * fix(backend): update correctly * fix(frontend): add correct imports * feat(backend): return monitored and ownership details for metadata group * feat(backend): return ownership details for metadata group * fix(frontend): display correct data * feat(backend): display media ownership status for metadata group * ci: change order of tool installation * fix(frontend): prevent infinite loop of setting cookies * ci: update changelog * feat(*): merge main branch * feat(*): lowercase all cookie extractions Also lowercase all cookie insertions. This change affects both frontend and backend. * refactor(frontend): remove useless application key declarations * feat(backend): add trait for searching metadata groups * fix(frontend): bring back common action * fix(backend): mask server smtp credentials * feat(frontend): allow associating reminders with groups * refactor(frontend): change name of prop * refactor(frontend): no useless ternary * feat(frontend): allow monitoring groups * fix(backend): add validation before updating dashboard elements * fix(backend): add validation before notifications to send * fix(backend): do not preform validation for notifs to send * feat(backend): store config variables for other prefs * feat(database): migrations for new user preferences * fix(database): set to correct value for new prefs * feat(frontend): allow updating other prefs * feat(frontend): respect new user preferences * feat(backend): add resolver to get metadata group search * feat(backend): start implementing tmdb movie group search * feat(backend): handle including nsfw in people search * feat(backend): allow searching for tmdb movie groups * chore(backend): change types of models * feat(backend): allow searching for igdb collections * feat(backend): allow committing metadata groups to database * fix(backend): filter by correct attribute * fix(backend): do not do an existence check for metadata groups * build(backend): bump version * style(frontend): change order of elements * feat(frontend): change route location * feat(frontend): start support for metadata group search * chore(frontend): further search logic * fix(frontend): correctly nest search tab * feat(frontend): allow committing metadata groups * refactor(backend): change name of core enum * chore(frontend): adapt to new gql schema * refactor(backend): change name of fn args * fix(backend): make suggestion filter more accurate * perf(backend): more accurate query for cleaning ute * fix(backend): get correct frontend url * feat(database): add migration for partial metadata groups * feat(backend): allow saving partial metadata groups * feat(frontend): display info about partial metadata * fix(database): add check before rename * style(frontend): change order of imports * fix(frontend): new style for episodes for shows * fix(backend): add logging when getting openlibrary books * fix(backend): do not update person specifics
1 parent e7b4747 commit 94a8be7

File tree

87 files changed

+2329
-1146
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+2329
-1146
lines changed

.devcontainer/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
FROM ignisda/archlinux:latest
22

3+
RUN npm install --global yaml-language-server@next
34
RUN paru -Syy --noconfirm caddy postgresql
45
RUN cargo binstall sea-orm-cli cargo-dist --locked --secure --no-confirm
56
RUN curl -L https://fly.io/install.sh | sh
67
RUN fish_add_path -Ua "/home/$USERNAME/.fly/bin"
7-
RUN proto install-global node yaml-language-server@next
88
RUN curl -sSL https://install.python-poetry.org | python3 -

Cargo.lock

+8-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/backend/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ryot"
3-
version = "4.3.11"
3+
version = "4.3.12"
44
edition = "2021"
55
repository = "https://github.com/IgnisDa/ryot"
66
license = "GPL-3.0"

apps/backend/src/background.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{env, sync::Arc, time::Instant};
33
use apalis::prelude::{Job, JobContext, JobError};
44
use chrono::DateTime;
55
use chrono_tz::Tz;
6-
use database::{MediaSource, MetadataLot};
6+
use database::{MediaLot, MediaSource};
77
use serde::{Deserialize, Serialize};
88
use strum::Display;
99

@@ -14,7 +14,7 @@ use crate::{
1414
miscellaneous::resolver::MiscellaneousService,
1515
models::{
1616
fitness::Exercise,
17-
media::{ProgressUpdateInput, ReviewPostedEvent},
17+
media::{CommitMediaInput, ProgressUpdateInput, ReviewPostedEvent},
1818
ExportItem,
1919
},
2020
};
@@ -153,7 +153,7 @@ pub enum ApplicationJob {
153153
UpdateExerciseJob(Exercise),
154154
UpdatePerson(i32),
155155
RecalculateCalendarEvents,
156-
AssociateGroupWithMetadata(MetadataLot, MediaSource, String),
156+
AssociateGroupWithMetadata(MediaLot, MediaSource, String),
157157
ReviewPosted(ReviewPostedEvent),
158158
PerformExport(i32, Vec<ExportItem>),
159159
RecalculateUserSummary(i32),
@@ -201,8 +201,12 @@ pub async fn perform_application_job(
201201
ApplicationJob::RecalculateCalendarEvents => {
202202
misc_service.recalculate_calendar_events().await.is_ok()
203203
}
204-
ApplicationJob::AssociateGroupWithMetadata(lot, source, group_identifier) => misc_service
205-
.associate_group_with_metadata(lot, source, group_identifier)
204+
ApplicationJob::AssociateGroupWithMetadata(lot, source, identifier) => misc_service
205+
.commit_metadata_group(CommitMediaInput {
206+
lot,
207+
source,
208+
identifier,
209+
})
206210
.await
207211
.is_ok(),
208212
ApplicationJob::ReviewPosted(event) => {

apps/backend/src/entities/collection_to_entity.rs

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ impl ActiveModelBehavior for ActiveModel {
111111
model.metadata_id,
112112
model.person_id,
113113
model.exercise_id.clone(),
114+
model.metadata_group_id,
114115
db,
115116
)
116117
.await

apps/backend/src/entities/metadata.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.2
22
33
use chrono::NaiveDate;
4-
use database::{MediaSource, MetadataLot};
4+
use database::{MediaLot, MediaSource};
55
use rust_decimal::Decimal;
66
use sea_orm::entity::prelude::*;
77
use serde::{Deserialize, Serialize};
@@ -18,7 +18,7 @@ pub struct Model {
1818
#[sea_orm(primary_key)]
1919
pub id: i32,
2020
pub created_on: DateTimeUtc,
21-
pub lot: MetadataLot,
21+
pub lot: MediaLot,
2222
pub last_updated_on: DateTimeUtc,
2323
pub title: String,
2424
pub identifier: String,

apps/backend/src/entities/metadata_group.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.2
1+
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.14
22
33
use async_graphql::SimpleObject;
44
use boilermates::boilermates;
5-
use database::{MediaSource, MetadataLot};
5+
use database::{MediaLot, MediaSource};
66
use sea_orm::entity::prelude::*;
77
use serde::{Deserialize, Serialize};
88

@@ -16,17 +16,19 @@ pub struct Model {
1616
#[boilermates(not_in("MetadataGroupWithoutId"))]
1717
#[sea_orm(primary_key)]
1818
pub id: i32,
19-
pub parts: i32,
2019
pub identifier: String,
20+
pub lot: MediaLot,
21+
pub source: MediaSource,
22+
pub parts: i32,
2123
pub title: String,
22-
pub description: Option<String>,
2324
#[sea_orm(column_type = "Json")]
2425
#[graphql(skip)]
2526
pub images: Vec<MetadataImage>,
2627
#[sea_orm(ignore)]
2728
pub display_images: Vec<String>,
28-
pub lot: MetadataLot,
29-
pub source: MediaSource,
29+
#[boilermates(not_in("MetadataGroupWithoutId"))]
30+
pub is_partial: Option<bool>,
31+
pub description: Option<String>,
3032
}
3133

3234
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@@ -37,6 +39,8 @@ pub enum Relation {
3739
MetadataToMetadataGroup,
3840
#[sea_orm(has_many = "super::review::Entity")]
3941
Review,
42+
#[sea_orm(has_many = "super::user_to_entity::Entity")]
43+
UserToEntity,
4044
}
4145

4246
impl Related<super::collection_to_entity::Entity> for Entity {
@@ -57,6 +61,12 @@ impl Related<super::review::Entity> for Entity {
5761
}
5862
}
5963

64+
impl Related<super::user_to_entity::Entity> for Entity {
65+
fn to() -> RelationDef {
66+
Relation::UserToEntity.def()
67+
}
68+
}
69+
6070
impl Related<super::metadata::Entity> for Entity {
6171
fn to() -> RelationDef {
6272
super::metadata_to_metadata_group::Relation::Metadata.def()

apps/backend/src/entities/review.rs

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ impl ActiveModelBehavior for ActiveModel {
123123
model.metadata_id,
124124
model.person_id,
125125
None,
126+
model.metadata_group_id,
126127
db,
127128
)
128129
.await

apps/backend/src/entities/seen.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,16 @@ impl ActiveModelBehavior for ActiveModel {
9393
C: ConnectionTrait,
9494
{
9595
if insert {
96-
associate_user_with_entity(&model.user_id, Some(model.metadata_id), None, None, db)
97-
.await
98-
.ok();
96+
associate_user_with_entity(
97+
&model.user_id,
98+
Some(model.metadata_id),
99+
None,
100+
None,
101+
None,
102+
db,
103+
)
104+
.await
105+
.ok();
99106
}
100107
Ok(model)
101108
}

apps/backend/src/entities/user_measurement.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::models::fitness::UserMeasurementStats;
2323
Schematic,
2424
)]
2525
#[graphql(name = "UserMeasurement", input_name = "UserMeasurementInput")]
26-
#[schematic(rename = "UserMeasurement")]
26+
#[schematic(rename = "UserMeasurement", rename_all = "snake_case")]
2727
#[sea_orm(table_name = "user_measurement")]
2828
pub struct Model {
2929
/// The date and time this measurement was made.

apps/backend/src/entities/user_to_entity.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3
1+
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.14
22
33
use async_graphql::SimpleObject;
44
use sea_orm::entity::prelude::*;
@@ -21,7 +21,7 @@ pub struct Model {
2121
pub person_id: Option<i32>,
2222
pub metadata_id: Option<i32>,
2323
pub exercise_id: Option<String>,
24-
pub metadata_ownership: Option<UserMediaOwnership>,
24+
pub media_ownership: Option<UserMediaOwnership>,
2525
pub metadata_units_consumed: Option<i32>,
2626
pub exercise_extra_information: Option<UserToExerciseExtraInformation>,
2727
pub exercise_num_times_interacted: Option<i32>,
@@ -31,6 +31,7 @@ pub struct Model {
3131
pub media_monitored: Option<bool>,
3232
#[graphql(skip)]
3333
pub needs_to_be_updated: Option<bool>,
34+
pub metadata_group_id: Option<i32>,
3435
}
3536

3637
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@@ -51,6 +52,14 @@ pub enum Relation {
5152
on_delete = "Cascade"
5253
)]
5354
Metadata,
55+
#[sea_orm(
56+
belongs_to = "super::metadata_group::Entity",
57+
from = "Column::MetadataGroupId",
58+
to = "super::metadata_group::Column::Id",
59+
on_update = "Cascade",
60+
on_delete = "Cascade"
61+
)]
62+
MetadataGroup,
5463
#[sea_orm(
5564
belongs_to = "super::person::Entity",
5665
from = "Column::PersonId",
@@ -81,6 +90,12 @@ impl Related<super::metadata::Entity> for Entity {
8190
}
8291
}
8392

93+
impl Related<super::metadata_group::Entity> for Entity {
94+
fn to() -> RelationDef {
95+
Relation::MetadataGroup.def()
96+
}
97+
}
98+
8499
impl Related<super::person::Entity> for Entity {
85100
fn to() -> RelationDef {
86101
Relation::Person.def()

apps/backend/src/entities/workout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
)]
2121
#[sea_orm(table_name = "workout")]
2222
#[graphql(name = "Workout")]
23-
#[schematic(rename = "Workout")]
23+
#[schematic(rename = "Workout", rename_all = "snake_case")]
2424
pub struct Model {
2525
#[sea_orm(primary_key, auto_increment = false)]
2626
pub id: String,

apps/backend/src/importer/audiobookshelf.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::anyhow;
22
use async_graphql::Result;
33
use data_encoding::BASE64;
4-
use database::{MediaSource, MetadataLot};
4+
use database::{MediaLot, MediaSource};
55
use serde::{Deserialize, Serialize};
66
use serde_json::json;
77
use strum::Display;
@@ -80,7 +80,7 @@ pub async fn import(input: DeployAudiobookshelfImportInput) -> Result<ImportResu
8080
let metadata = item.media.unwrap().metadata.unwrap();
8181
match item.media_type.unwrap() {
8282
MediaType::Book => {
83-
let lot = MetadataLot::AudioBook;
83+
let lot = MediaLot::AudioBook;
8484
if let Some(asin) = metadata.asin {
8585
media.push(ImportOrExportMediaItem {
8686
internal_identifier: Some(ImportOrExportItemIdentifier::NeedsDetails {

apps/backend/src/importer/goodreads.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use async_graphql::Result;
44
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
55
use convert_case::{Case, Casing};
66
use csv::Reader;
7-
use database::{MediaSource, MetadataLot};
7+
use database::{MediaLot, MediaSource};
88
use itertools::Itertools;
99
use rust_decimal::Decimal;
1010
use rust_decimal_macros::dec;
@@ -43,7 +43,7 @@ pub async fn import(
4343
input: DeployGoodreadsImportInput,
4444
isbn_service: &GoogleBooksService,
4545
) -> Result<ImportResult> {
46-
let lot = MetadataLot::Book;
46+
let lot = MediaLot::Book;
4747
let source = MediaSource::GoogleBooks;
4848
let mut media = vec![];
4949
let mut failed_items = vec![];

apps/backend/src/importer/mal.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
};
55

66
use async_graphql::Result;
7-
use database::{MediaSource, MetadataLot};
7+
use database::{MediaLot, MediaSource};
88
use flate2::bufread::GzDecoder;
99
use rs_utils::{convert_naive_to_utc, convert_string_to_date};
1010
use rust_decimal::{prelude::FromPrimitive, Decimal};
@@ -40,7 +40,7 @@ fn get_date(date: String) -> Option<DateTimeUtc> {
4040
}
4141
}
4242

43-
fn convert_to_format(item: Item, lot: MetadataLot) -> ImportOrExportMediaItem {
43+
fn convert_to_format(item: Item, lot: MediaLot) -> ImportOrExportMediaItem {
4444
let progress = if item.done != 0 && item.total != 0 {
4545
Some(item.done / item.total)
4646
} else {
@@ -82,10 +82,10 @@ pub async fn import(input: DeployMalImportInput) -> Result<ImportResult> {
8282
let manga_data = decode_data::<DataRoot>(&input.manga_path)?;
8383
let mut media = vec![];
8484
for item in anime_data.items.into_iter() {
85-
media.push(convert_to_format(item, MetadataLot::Anime));
85+
media.push(convert_to_format(item, MediaLot::Anime));
8686
}
8787
for item in manga_data.items.into_iter() {
88-
media.push(convert_to_format(item, MetadataLot::Manga));
88+
media.push(convert_to_format(item, MediaLot::Manga));
8989
}
9090
Ok(ImportResult {
9191
media,

apps/backend/src/importer/media_tracker.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use async_graphql::Result;
2-
use database::{MediaSource, MetadataLot, Visibility};
2+
use database::{MediaLot, MediaSource, Visibility};
33
use rust_decimal::Decimal;
44
use rust_decimal_macros::dec;
55
use sea_orm::prelude::DateTimeUtc;
@@ -35,7 +35,7 @@ enum MediaType {
3535
Audiobook,
3636
}
3737

38-
impl From<MediaType> for MetadataLot {
38+
impl From<MediaType> for MediaLot {
3939
fn from(value: MediaType) -> Self {
4040
match value {
4141
MediaType::Book => Self::Book,
@@ -222,7 +222,7 @@ pub async fn import(input: DeployMediaTrackerImportInput) -> Result<ImportResult
222222
continue;
223223
}
224224
};
225-
let lot = MetadataLot::from(media_type.clone());
225+
let lot = MediaLot::from(media_type.clone());
226226
let mut rsp = client.get(format!("details/{}", d.id)).await.unwrap();
227227
let details: ItemDetails = match rsp.body_json().await {
228228
Ok(s) => s,

apps/backend/src/importer/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33
use apalis::prelude::Storage;
44
use async_graphql::{Context, Enum, InputObject, Object, Result, SimpleObject};
55
use chrono::{Duration, Utc};
6-
use database::{ImportSource, MetadataLot};
6+
use database::{ImportSource, MediaLot};
77
use itertools::Itertools;
88
use rust_decimal::Decimal;
99
use rust_decimal_macros::dec;
@@ -149,7 +149,7 @@ pub enum ImportFailStep {
149149
Debug, SimpleObject, FromJsonQueryResult, Serialize, Deserialize, Eq, PartialEq, Clone,
150150
)]
151151
pub struct ImportFailedItem {
152-
lot: Option<MetadataLot>,
152+
lot: Option<MediaLot>,
153153
step: ImportFailStep,
154154
identifier: String,
155155
error: Option<String>,

apps/backend/src/importer/movary.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::fs;
33
use async_graphql::Result;
44
use chrono::NaiveDate;
55
use csv::Reader;
6-
use database::{MediaSource, MetadataLot};
6+
use database::{MediaLot, MediaSource};
77
use rs_utils::convert_naive_to_utc;
88
use rust_decimal::Decimal;
99
use rust_decimal_macros::dec;
@@ -48,7 +48,7 @@ pub async fn import(input: DeployMovaryImportInput) -> Result<ImportResult> {
4848
let ratings = fs::read_to_string(&input.ratings)?;
4949
let history = fs::read_to_string(&input.history)?;
5050
let watchlist = fs::read_to_string(&input.watchlist)?;
51-
let lot = MetadataLot::Movie;
51+
let lot = MediaLot::Movie;
5252
let source = MediaSource::Tmdb;
5353
let mut media = vec![];
5454
let mut failed_items = vec![];

0 commit comments

Comments
 (0)