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

Sync episodes played states from Emby #4928

Merged
merged 4 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 19 additions & 7 deletions src/Ombi.Api.Emby/EmbyApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,18 +249,30 @@ private static void AddHeaders(Request req, string apiKey)
req.AddHeader("Device", "Ombi");
}

public async Task<EmbyItemContainer<EmbyMovie>> GetMoviesPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri)
{
return await GetPlayed<EmbyMovie>("Movie", apiKey, userId, baseUri, startIndex, count, parentIdFilder);
}

private async Task<EmbyItemContainer<T>> GetPlayed<T>(string type, string apiKey, string userId, string baseUri, int startIndex, int count, string parentIdFilder = default)
public async Task<EmbyItemContainer<EmbyMovie>> GetMoviesPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) =>
await GetPlayed<EmbyMovie>("Movie", apiKey, userId, baseUri, startIndex, count, parentIdFilder, "ProviderIds");

public async Task<EmbyItemContainer<EmbyEpisodes>> GetTvPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) =>
await GetPlayed<EmbyEpisodes>("Episode", apiKey, userId, baseUri, startIndex, count, parentIdFilder);

private async Task<EmbyItemContainer<T>> GetPlayed<T>(
string type,
string apiKey,
string userId,
string baseUri,
int startIndex,
int count,
string parentIdFilder = default,
string fields = default)
{
var request = new Request($"emby/items", baseUri, HttpMethod.Get);

request.AddQueryString("Recursive", true.ToString());
request.AddQueryString("IncludeItemTypes", type);
request.AddQueryString("Fields", "ProviderIds");
if (!string.IsNullOrEmpty(fields))
{
request.AddQueryString("Fields", fields);
}
request.AddQueryString("UserId", userId);
request.AddQueryString("isPlayed", true.ToString());

Expand Down
1 change: 1 addition & 0 deletions src/Ombi.Api.Emby/IBaseEmbyApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ Task<EmbyItemContainer<EmbyMovie>> GetCollection(string mediaId,
Task<EmbyItemContainer<EmbySeries>> RecentlyAddedShows(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);

Task<EmbyItemContainer<EmbyMovie>> GetMoviesPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);
Task<EmbyItemContainer<EmbyEpisodes>> GetTvPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);
}
}
81 changes: 68 additions & 13 deletions src/Ombi.Core/Engine/TvRequestEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine
public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, ICurrentUser user,
INotificationHelper helper, IRuleEvaluator rule, OmbiUserManager manager, ILogger<TvRequestEngine> logger,
ITvSender sender, IRepository<RequestLog> rl, ISettingsService<OmbiSettings> settings, ICacheService cache,
IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService) : base(user, requestService, rule, manager, cache, settings, sub)
IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService,
IUserPlayedEpisodeRepository userPlayedEpisodeRepository) : base(user, requestService, rule, manager, cache, settings, sub)
{
TvApi = tvApi;
MovieDbApi = movApi;
Expand All @@ -44,6 +45,7 @@ public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain
TvSender = sender;
_requestLog = rl;
_mediaCacheService = mediaCacheService;
_userPlayedEpisodeRepository = userPlayedEpisodeRepository;
}

private INotificationHelper NotificationHelper { get; }
Expand All @@ -54,6 +56,7 @@ public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain
private readonly ILogger<TvRequestEngine> _logger;
private readonly IRepository<RequestLog> _requestLog;
private readonly IMediaCacheService _mediaCacheService;
private readonly IUserPlayedEpisodeRepository _userPlayedEpisodeRepository;

public async Task<RequestEngineResult> RequestTvShow(TvRequestViewModel tv)
{
Expand Down Expand Up @@ -292,7 +295,7 @@ public async Task<RequestsViewModel<TvRequests>> GetRequests(int count, int posi
.Skip(position).Take(count).ToListAsync();

}
await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);

return new RequestsViewModel<TvRequests>
{
Expand Down Expand Up @@ -328,7 +331,7 @@ public async Task<RequestsViewModel<TvRequests>> GetRequestsLite(int count, int
return new RequestsViewModel<TvRequests>();
}

await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);

return new RequestsViewModel<TvRequests>
{
Expand All @@ -351,7 +354,7 @@ public async Task<IEnumerable<TvRequests>> GetRequests()
allRequests = await TvRepository.Get().ToListAsync();
}

await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);
return allRequests;
}

Expand Down Expand Up @@ -396,7 +399,7 @@ public async Task<RequestsViewModel<ChildRequests>> GetRequests(int count, int p
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();

await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);

// Make sure we do not show duplicate child requests
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
Expand Down Expand Up @@ -469,7 +472,7 @@ public async Task<RequestsViewModel<ChildRequests>> GetRequests(int count, int p
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();

await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);

// Make sure we do not show duplicate child requests
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
Expand Down Expand Up @@ -523,7 +526,7 @@ public async Task<RequestsViewModel<ChildRequests>> GetUnavailableRequests(int c
allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();
await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);

// Make sure we do not show duplicate child requests
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
Expand Down Expand Up @@ -551,7 +554,7 @@ public async Task<IEnumerable<TvRequests>> GetRequestsLite()
allRequests = await TvRepository.GetLite().ToListAsync();
}

await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);
return allRequests;
}

Expand All @@ -570,7 +573,7 @@ public async Task<TvRequests> GetTvRequest(int requestId)
request = await TvRepository.Get().Where(x => x.Id == requestId).FirstOrDefaultAsync();
}

await CheckForSubscription(shouldHide, new List<TvRequests>{request});
await FillAdditionalFields(shouldHide, new List<TvRequests>{request});
return request;
}

Expand Down Expand Up @@ -624,7 +627,7 @@ public async Task<IEnumerable<ChildRequests>> GetAllChldren(int tvId)
allRequests = await TvRepository.GetChild().Include(x => x.SeasonRequests).Where(x => x.ParentRequestId == tvId).ToListAsync();
}

await CheckForSubscription(shouldHide, allRequests);
await FillAdditionalFields(shouldHide, allRequests);

return allRequests;
}
Expand All @@ -643,7 +646,7 @@ public async Task<IEnumerable<TvRequests>> SearchTvRequest(string search)
}
var results = await allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToListAsync();

await CheckForSubscription(shouldHide, results);
await FillAdditionalFields(shouldHide, results);
return results;
}

Expand Down Expand Up @@ -864,14 +867,20 @@ public async Task<int> GetTotal()
}
}

private async Task CheckForSubscription(HideResult shouldHide, List<TvRequests> x)
private async Task FillAdditionalFields(HideResult shouldHide, List<TvRequests> x)
{
foreach (var tvRequest in x)
{
await CheckForSubscription(shouldHide, tvRequest.ChildRequests);
await FillAdditionalFields(shouldHide, tvRequest.ChildRequests);
}
}

private async Task FillAdditionalFields(HideResult shouldHide, List<ChildRequests> childRequests)
{
await CheckForSubscription(shouldHide, childRequests);
CheckForPlayed(shouldHide, childRequests);
}

private async Task CheckForSubscription(HideResult shouldHide, List<ChildRequests> childRequests)
{
var sub = _subscriptionRepository.GetAll();
Expand All @@ -896,6 +905,52 @@ private async Task CheckForSubscription(HideResult shouldHide, List<ChildRequest
}
}

private class EpisodeKey
{
public int SeasonNumber;
public int EpisodeNumber;
}

private void CheckForPlayed(HideResult shouldHide, List<ChildRequests> childRequests)
{
var theMovieDbIds = childRequests.Select(x => x.Id);
foreach (var request in childRequests)
{
var requestedEpisodes = GetEpisodesKeys(request);

var playedEpisodes = _userPlayedEpisodeRepository
.GetAll()
.Where(x => x.TheMovieDbId == request.Id && x.UserId == request.RequestedUserId)
.AsEnumerable()
.Join(requestedEpisodes,
played => new { played.SeasonNumber, played.EpisodeNumber },
requested => new { requested.SeasonNumber, requested.EpisodeNumber },
(played, requested) => new { played });
tidusjar marked this conversation as resolved.
Show resolved Hide resolved

var playedCount = playedEpisodes.Count();
var toWatchCount = requestedEpisodes.Count();
request.RequestedUserPlayedProgress = 100 * playedCount / toWatchCount;

}
}

private List<EpisodeKey> GetEpisodesKeys(ChildRequests request)
{
List<EpisodeKey> result = new List<EpisodeKey>();
foreach(var season in request.SeasonRequests)
{
foreach(var episode in season.Episodes)
{
result.Add(new EpisodeKey
{
SeasonNumber = season.SeasonNumber,
EpisodeNumber = episode.EpisodeNumber
});
}
}
return result;
}

private async Task<RequestEngineResult> AddExistingRequest(ChildRequests newRequest, TvRequests existingRequest, string requestOnBehalf, int rootFolder, int qualityProfile)
{
// Add the child
Expand Down
1 change: 1 addition & 0 deletions src/Ombi.DependencyInjection/IocExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ public static void RegisterStore(this IServiceCollection services)
services.AddScoped<IJellyfinContentRepository, JellyfinContentRepository>();
services.AddScoped<INotificationTemplatesRepository, NotificationTemplatesRepository>();
services.AddScoped<IUserPlayedMovieRepository, UserPlayedMovieRepository>();
services.AddScoped<IUserPlayedEpisodeRepository, UserPlayedEpisodeRepository>();

services.AddScoped<ITvRequestRepository, TvRequestRepository>();
services.AddScoped<IMovieRequestRepository, MovieRequestRepository>();
Expand Down
Loading