diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 89a09a164..c25d9f709 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -8,10 +8,12 @@ using Ombi.Api.Emby; using Ombi.Api.Emby.Models; using Ombi.Api.Emby.Models.Media.Tv; using Ombi.Api.Emby.Models.Movie; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; using Ombi.Hubs; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Quartz; @@ -21,14 +23,20 @@ namespace Ombi.Schedule.Jobs.Emby { public class EmbyContentSync : EmbyLibrarySync, IEmbyContentSync { - public EmbyContentSync(ISettingsService settings, IEmbyApiFactory api, ILogger logger, - IEmbyContentRepository repo, INotificationHubService notification): + public EmbyContentSync( + ISettingsService settings, + IEmbyApiFactory api, + ILogger logger, + IEmbyContentRepository repo, + INotificationHubService notification, + IFeatureService feature): base(settings, api, logger, notification) { _repo = repo; } private readonly IEmbyContentRepository _repo; + private readonly IFeatureService _feature; public async override Task Execute(IJobExecutionContext context) @@ -38,6 +46,13 @@ namespace Ombi.Schedule.Jobs.Emby // Episodes await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IEmbyEpisodeSync), "Emby"), new JobDataMap(new Dictionary { { JobDataKeys.EmbyRecentlyAddedSearch, recentlyAdded.ToString() } })); + + // Played state + var isPlayedSyncEnabled = await _feature.FeatureEnabled(FeatureNames.PlayedSync); + if(isPlayedSyncEnabled) + { + await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IEmbyPlayedSync), "Emby"), new JobDataMap(new Dictionary { { JobDataKeys.EmbyRecentlyAddedSearch, recentlyAdded.ToString() } })); + } } diff --git a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs index 46f3a7e56..e3573e6c8 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs @@ -15,15 +15,22 @@ namespace Ombi.Schedule.Jobs.Ombi { public class MediaDatabaseRefresh : IMediaDatabaseRefresh { - public MediaDatabaseRefresh(ISettingsService s, ILogger log, - IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo, IJellyfinContentRepository jellyfinRepo, - ISettingsService embySettings, ISettingsService jellyfinSettings) + public MediaDatabaseRefresh( + ISettingsService s, + ILogger log, + IPlexContentRepository plexRepo, + IEmbyContentRepository embyRepo, + IJellyfinContentRepository jellyfinRepo, + IUserPlayedMovieRepository userPlayedRepo, + ISettingsService embySettings, + ISettingsService jellyfinSettings) { _plexSettings = s; _log = log; _plexRepo = plexRepo; _embyRepo = embyRepo; _jellyfinRepo = jellyfinRepo; + _userPlayedRepo = userPlayedRepo; _embySettings = embySettings; _jellyfinSettings = jellyfinSettings; _plexSettings.ClearCache(); @@ -34,6 +41,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly IPlexContentRepository _plexRepo; private readonly IEmbyContentRepository _embyRepo; private readonly IJellyfinContentRepository _jellyfinRepo; + private readonly IUserPlayedMovieRepository _userPlayedRepo; private readonly ISettingsService _embySettings; private readonly ISettingsService _jellyfinSettings; @@ -41,6 +49,7 @@ namespace Ombi.Schedule.Jobs.Ombi { try { + await RemovePlayedData(); await RemovePlexData(); await RemoveEmbyData(); await RemoveJellyfinData(); @@ -52,6 +61,20 @@ namespace Ombi.Schedule.Jobs.Ombi } + private async Task RemovePlayedData() + { + try + { + const string movieSql = "DELETE FROM UserPlayedMovie"; + await _userPlayedRepo.ExecuteSql(movieSql); + } + catch (Exception e) + { + _log.LogError(LoggingEvents.MediaReferesh, e, "Refreshing Played Data Failed"); + } + } + + private async Task RemoveEmbyData() { try diff --git a/src/Ombi.Settings/Settings/Models/FeatureSettings.cs b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs index 9d0149e5d..f541d1e0d 100644 --- a/src/Ombi.Settings/Settings/Models/FeatureSettings.cs +++ b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs @@ -21,5 +21,6 @@ namespace Ombi.Settings.Settings.Models { public const string Movie4KRequests = nameof(Movie4KRequests); public const string OldTrendingSource = nameof(OldTrendingSource); + public const string PlayedSync = nameof(PlayedSync); } } diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts index ad2f76c2e..1db29de12 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts @@ -24,10 +24,11 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { public dataSource: MatTableDataSource; public resultsLength: number; public isLoadingResults = true; - public displayedColumns: string[] = ['title', 'requestedUser.requestedBy', 'status', 'requestStatus','requestedDate', 'watchedByRequestedUser', 'actions']; + public displayedColumns: string[] = ['title', 'requestedUser.requestedBy', 'status', 'requestStatus','requestedDate']; public gridCount: string = "15"; public isAdmin: boolean; public is4kEnabled = false; + public isPlayedSyncEnabled = false; public manageOwnRequests: boolean; public defaultSort: string = "requestedDate"; public defaultOrder: string = "desc"; @@ -65,10 +66,9 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { } this.is4kEnabled = this.featureFacade.is4kEnabled(); - if ((this.isAdmin || this.auth.hasRole("Request4KMovie")) - && this.is4kEnabled) { - this.displayedColumns.splice(4, 0, 'has4kRequest'); - } + this.isPlayedSyncEnabled = this.featureFacade.isPlayedSyncEnabled(); + + this.addDynamicColumns(); const defaultCount = this.storageService.get(this.storageKeyGridCount); const defaultSort = this.storageService.get(this.storageKey); @@ -88,6 +88,20 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { } } + addDynamicColumns() { + if ((this.isAdmin || this.auth.hasRole("Request4KMovie")) + && this.is4kEnabled) { + this.displayedColumns.splice(4, 0, 'has4kRequest'); + } + + if (this.isPlayedSyncEnabled) { + this.displayedColumns.push('watchedByRequestedUser'); + } + + // always put the actions column at the end + this.displayedColumns.push('actions'); + } + public async ngAfterViewInit() { this.storageService.save(this.storageKeyGridCount, this.gridCount); diff --git a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts index 10e229eba..9b5091cba 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts @@ -23,4 +23,6 @@ export class FeaturesFacade { public is4kEnabled = (): boolean => this.store.selectSnapshot(FeaturesSelectors.is4kEnabled); -} \ No newline at end of file + public isPlayedSyncEnabled = (): boolean => this.store.selectSnapshot(FeaturesSelectors.isPlayedSyncEnabled); + +} diff --git a/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts index 143dfb875..bbea921e5 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts @@ -15,4 +15,9 @@ export class FeaturesSelectors { return features.filter(x => x.name === "Movie4KRequests")[0].enabled; } -} \ No newline at end of file + @Selector([FeaturesSelectors.features]) + public static isPlayedSyncEnabled(features: IFeatureEnablement[]): boolean { + return features.filter(x => x.name === "PlayedSync")[0].enabled; + } + +}