mirror of
https://github.com/Kareadita/Kavita.git
synced 2026-06-06 06:45:18 -04:00
Social interactions with annotations (#4068)
Co-authored-by: Joe Milazzo <josephmajora@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using API.Data.Misc;
|
||||
using API.Entities;
|
||||
@@ -151,4 +152,199 @@ public static class RestrictByAgeExtensions
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
private static IQueryable<AppUserRating> RestrictAgainstAgeRestriction(this IQueryable<AppUserRating> queryable, AgeRestriction restriction, int userId)
|
||||
{
|
||||
if (restriction.AgeRating == AgeRating.NotApplicable) return queryable;
|
||||
var q = queryable.Where(r => r.Series.Metadata.AgeRating <= restriction.AgeRating || r.AppUserId == userId);
|
||||
|
||||
if (!restriction.IncludeUnknowns)
|
||||
{
|
||||
return q.Where(a => a.Series.Metadata.AgeRating != AgeRating.Unknown || a.AppUserId == userId);
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
private static IQueryable<AppUserChapterRating> RestrictAgainstAgeRestriction(this IQueryable<AppUserChapterRating> queryable, AgeRestriction restriction, int userId)
|
||||
{
|
||||
if (restriction.AgeRating == AgeRating.NotApplicable) return queryable;
|
||||
var q = queryable.Where(r => r.Series.Metadata.AgeRating <= restriction.AgeRating || r.AppUserId == userId);
|
||||
|
||||
if (!restriction.IncludeUnknowns)
|
||||
{
|
||||
return q.Where(a => a.Series.Metadata.AgeRating != AgeRating.Unknown || a.AppUserId == userId);
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
private static IQueryable<AppUserAnnotation> RestrictAgainstAgeRestriction(this IQueryable<AppUserAnnotation> queryable, AgeRestriction restriction, int userId)
|
||||
{
|
||||
if (restriction.AgeRating == AgeRating.NotApplicable) return queryable;
|
||||
var q = queryable.Where(a => a.Series.Metadata.AgeRating <= restriction.AgeRating || a.AppUserId == userId);
|
||||
|
||||
if (!restriction.IncludeUnknowns)
|
||||
{
|
||||
return q.Where(a => a.Series.Metadata.AgeRating != AgeRating.Unknown || a.AppUserId == userId);
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
// TODO: After updating to .net 10, leverage new Complex Data type queries to inline all db operations here
|
||||
/// <summary>
|
||||
/// Filter annotations by social preferences of users
|
||||
/// </summary>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="userPreferences">List of user preferences for every user on the server</param>
|
||||
/// <returns></returns>
|
||||
public static IQueryable<AppUserAnnotation> RestrictBySocialPreferences(this IQueryable<AppUserAnnotation> queryable, int userId, IList<AppUserPreferences> userPreferences)
|
||||
{
|
||||
var preferencesById = userPreferences.ToDictionary(p => p.AppUserId, p => p.SocialPreferences);
|
||||
var socialPreferences = preferencesById[userId];
|
||||
|
||||
if (socialPreferences.ViewOtherAnnotations)
|
||||
{
|
||||
// We are unable to do dictionary lookups in Sqlite; This means we need to translate them to X IN Y.
|
||||
var sharingUserIds = userPreferences
|
||||
.Where(p => p.SocialPreferences.ShareAnnotations)
|
||||
.Select(p => p.AppUserId)
|
||||
.ToHashSet();
|
||||
|
||||
// Only include the users' annotations, or those of users that are sharing
|
||||
queryable = queryable.Where(a => a.AppUserId == userId || sharingUserIds.Contains(a.AppUserId));
|
||||
|
||||
// For other users' annotation
|
||||
foreach (var sharingUserId in sharingUserIds.Where(id => id != userId))
|
||||
{
|
||||
// Filter out libs if enabled
|
||||
var libs = preferencesById[sharingUserId].SocialLibraries;
|
||||
if (libs.Count > 0)
|
||||
{
|
||||
queryable = queryable.Where(a => a.AppUserId != sharingUserId || libs.Contains(a.LibraryId));
|
||||
}
|
||||
|
||||
// Filter on age rating
|
||||
var ageRating = preferencesById[sharingUserId].SocialMaxAgeRating;
|
||||
var includeUnknowns = preferencesById[sharingUserId].SocialIncludeUnknowns;
|
||||
if (ageRating != AgeRating.NotApplicable)
|
||||
{
|
||||
queryable = queryable.Where(a => a.AppUserId != sharingUserId || a.Series.Metadata.AgeRating <= ageRating)
|
||||
.WhereIf(!includeUnknowns,
|
||||
a => a.AppUserId != sharingUserId || a.Series.Metadata.AgeRating != AgeRating.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
queryable = queryable.Where(a => a.AppUserId == userId);
|
||||
}
|
||||
|
||||
return queryable
|
||||
.WhereIf(socialPreferences.SocialLibraries.Count > 0,
|
||||
a => a.AppUserId == userId || socialPreferences.SocialLibraries.Contains(a.LibraryId))
|
||||
.RestrictAgainstAgeRestriction(new AgeRestriction
|
||||
{
|
||||
AgeRating = socialPreferences.SocialMaxAgeRating,
|
||||
IncludeUnknowns = socialPreferences.SocialIncludeUnknowns,
|
||||
}, userId);
|
||||
}
|
||||
|
||||
// TODO: After updating to .net 10, leverage new Complex Data type queries to inline all db operations here
|
||||
/// <summary>
|
||||
/// Filter user reviews social preferences of users
|
||||
/// </summary>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="userPreferences">List of user preferences for every user on the server</param>
|
||||
/// <returns></returns>
|
||||
public static IQueryable<AppUserRating> RestrictBySocialPreferences(this IQueryable<AppUserRating> queryable, int userId, IList<AppUserPreferences> userPreferences)
|
||||
{
|
||||
var preferencesById = userPreferences.ToDictionary(p => p.AppUserId, p => p.SocialPreferences);
|
||||
var socialPreferences = preferencesById[userId];
|
||||
|
||||
var sharingUserIds = userPreferences
|
||||
.Where(p => p.SocialPreferences.ShareReviews)
|
||||
.Select(p => p.AppUserId)
|
||||
.ToHashSet();
|
||||
|
||||
queryable = queryable.Where(r => r.AppUserId == userId || sharingUserIds.Contains(r.AppUserId));
|
||||
|
||||
foreach (var sharingUserId in sharingUserIds.Where(id => id != userId))
|
||||
{
|
||||
var libs = preferencesById[sharingUserId].SocialLibraries;
|
||||
if (libs.Count > 0)
|
||||
{
|
||||
queryable = queryable.Where(r => r.AppUserId != sharingUserId || libs.Contains(r.Series.LibraryId));
|
||||
}
|
||||
|
||||
var ageRating = preferencesById[sharingUserId].SocialMaxAgeRating;
|
||||
var includeUnknowns = preferencesById[sharingUserId].SocialIncludeUnknowns;
|
||||
if (ageRating != AgeRating.NotApplicable)
|
||||
{
|
||||
queryable = queryable.Where(r => r.AppUserId != sharingUserId || r.Series.Metadata.AgeRating <= ageRating)
|
||||
.WhereIf(!includeUnknowns,
|
||||
r => r.AppUserId != sharingUserId || r.Series.Metadata.AgeRating != AgeRating.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
return queryable
|
||||
.WhereIf(socialPreferences.SocialLibraries.Count > 0,
|
||||
r => r.AppUserId == userId || socialPreferences.SocialLibraries.Contains(r.Series.LibraryId))
|
||||
.RestrictAgainstAgeRestriction(new AgeRestriction
|
||||
{
|
||||
AgeRating = socialPreferences.SocialMaxAgeRating,
|
||||
IncludeUnknowns = socialPreferences.SocialIncludeUnknowns,
|
||||
}, userId);
|
||||
}
|
||||
|
||||
// TODO: After updating to .net 10, leverage new Complex Data type queries to inline all db operations here
|
||||
/// <summary>
|
||||
/// Filter user chapter reviews social preferences of users
|
||||
/// </summary>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="userPreferences">List of user preferences for every user on the server</param>
|
||||
/// <returns></returns>
|
||||
public static IQueryable<AppUserChapterRating> RestrictBySocialPreferences(this IQueryable<AppUserChapterRating> queryable, int userId, IList<AppUserPreferences> userPreferences)
|
||||
{
|
||||
var preferencesById = userPreferences.ToDictionary(p => p.AppUserId, p => p.SocialPreferences);
|
||||
var socialPreferences = preferencesById[userId];
|
||||
|
||||
var sharingUserIds = userPreferences
|
||||
.Where(p => p.SocialPreferences.ShareReviews)
|
||||
.Select(p => p.AppUserId)
|
||||
.ToHashSet();
|
||||
|
||||
queryable = queryable.Where(r => r.AppUserId == userId || sharingUserIds.Contains(r.AppUserId));
|
||||
|
||||
foreach (var sharingUserId in sharingUserIds.Where(id => id != userId))
|
||||
{
|
||||
var libs = preferencesById[sharingUserId].SocialLibraries;
|
||||
if (libs.Count > 0)
|
||||
{
|
||||
queryable = queryable.Where(r => r.AppUserId != sharingUserId || libs.Contains(r.Series.LibraryId));
|
||||
}
|
||||
|
||||
var ageRating = preferencesById[sharingUserId].SocialMaxAgeRating;
|
||||
var includeUnknowns = preferencesById[sharingUserId].SocialIncludeUnknowns;
|
||||
if (ageRating != AgeRating.NotApplicable)
|
||||
{
|
||||
queryable = queryable.Where(r => r.AppUserId != sharingUserId || r.Series.Metadata.AgeRating <= ageRating)
|
||||
.WhereIf(!includeUnknowns,
|
||||
r => r.AppUserId != sharingUserId || r.Series.Metadata.AgeRating != AgeRating.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
return queryable
|
||||
.WhereIf(socialPreferences.SocialLibraries.Count > 0,
|
||||
r => r.AppUserId == userId || socialPreferences.SocialLibraries.Contains(r.Series.LibraryId))
|
||||
.RestrictAgainstAgeRestriction(new AgeRestriction
|
||||
{
|
||||
AgeRating = socialPreferences.SocialMaxAgeRating,
|
||||
IncludeUnknowns = socialPreferences.SocialIncludeUnknowns,
|
||||
}, userId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user