diff --git a/CHANGELOG.md b/CHANGELOG.md index e58c1429a..a23ed6887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## (unreleased) + +### **Fixes** + +- Small memory improvements in the Plex Sync. [Jamie] + +- Fixed the sort issue on the user Management page. Also added sorting to the Movie Requests page. [tidusjar] + +- Downgraded the angular2-jwt library since it has a bug in it. #2064. [tidusjar] + +- Fixed an issue when Plex decideds to reuse the Plex Key for a different media item... #2038. [tidusjar] + +- Fixed an issue where we might show the Imdb link when we do not have a imdbid #1797. [tidusjar] + +- Fixed the issue where we can no longer select Pending Approval in the filters #2057. [tidusjar] + +- Fixed the API key not working when attempting to get requests #2058. [tidusjar] + +- Fixed #2056. [tidusjar] + +- Experimental, set the Webpack base root to the ombi base path if we have it. This should hopefully fix the reverse proxy issues. [Jamie] + + ## v3.0.3000 (2018-03-09) ### **New Features** diff --git a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs index 32f08e2b1..e608ffebb 100644 --- a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs @@ -1,4 +1,5 @@ -using Ombi.Core.Rule; +using System; +using Ombi.Core.Rule; using System.Collections.Generic; using System.Security.Principal; using System.Threading.Tasks; @@ -10,6 +11,7 @@ using Microsoft.AspNetCore.Identity; using System.Linq; using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; +using Ombi.Helpers; namespace Ombi.Core.Engine.Interfaces { @@ -30,6 +32,13 @@ namespace Ombi.Core.Engine.Interfaces private OmbiUser _user; protected async Task GetUser() { + if (IsApiUser) + { + return new OmbiUser + { + UserName = Username, + }; + } return _user ?? (_user = await UserManager.Users.FirstOrDefaultAsync(x => x.UserName == Username)); } @@ -40,6 +49,10 @@ namespace Ombi.Core.Engine.Interfaces protected async Task IsInRole(string roleName) { + if (IsApiUser && roleName != OmbiRoles.Disabled) + { + return true; + } return await UserManager.IsInRoleAsync(await GetUser(), roleName); } @@ -59,5 +72,7 @@ namespace Ombi.Core.Engine.Interfaces var ruleResults = await Rules.StartSpecificRules(model, rule); return ruleResults; } + + private bool IsApiUser => Username.Equals("Api", StringComparison.CurrentCultureIgnoreCase); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index 1ba4e812a..3c00a7a29 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -93,217 +93,155 @@ namespace Ombi.Schedule.Jobs.Plex { foreach (var servers in plexSettings.Servers ?? new List()) { + try + { + Logger.LogInformation("Starting to cache the content on server {0}", servers.Name); + await ProcessServer(servers); + } + catch (Exception e) + { + Logger.LogWarning(LoggingEvents.PlexContentCacher, e, "Exception thrown when attempting to cache the Plex Content in server {0}", servers.Name); + } + } + } - Logger.LogInformation("Getting all content from server {0}", servers.Name); - var allContent = await GetAllContent(servers); - Logger.LogInformation("We found {0} items", allContent.Count); + private async Task ProcessServer(PlexServers servers) + { + Logger.LogInformation("Getting all content from server {0}", servers.Name); + var allContent = await GetAllContent(servers); + Logger.LogInformation("We found {0} items", allContent.Count); - // Let's now process this. - var contentToAdd = new List(); - foreach (var content in allContent) + // Let's now process this. + var contentToAdd = new HashSet(); + foreach (var content in allContent) + { + if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)) { - if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)) + // Process Shows + Logger.LogInformation("Processing TV Shows"); + foreach (var show in content.Metadata ?? new Metadata[] { }) { - // Process Shows - Logger.LogInformation("Processing TV Shows"); - foreach (var show in content.Metadata ?? new Metadata[] { }) + var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, + show.ratingKey); + var seasonsContent = new List(); + foreach (var season in seasonList.MediaContainer.Metadata) { - var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, - show.ratingKey); - var seasonsContent = new List(); - foreach (var season in seasonList.MediaContainer.Metadata) + seasonsContent.Add(new PlexSeasonsContent { - seasonsContent.Add(new PlexSeasonsContent - { - ParentKey = season.parentRatingKey, - SeasonKey = season.ratingKey, - SeasonNumber = season.index, - PlexContentId = show.ratingKey - }); - } + ParentKey = season.parentRatingKey, + SeasonKey = season.ratingKey, + SeasonNumber = season.index, + PlexContentId = show.ratingKey + }); + } - // Do we already have this item? - // Let's try and match - var existingContent = await Repo.GetFirstContentByCustom(x => x.Title == show.title - && x.ReleaseYear == show.year.ToString() - && x.Type == PlexMediaTypeEntity.Show); + // Do we already have this item? + // Let's try and match + var existingContent = await Repo.GetFirstContentByCustom(x => x.Title == show.title + && x.ReleaseYear == show.year.ToString() + && x.Type == PlexMediaTypeEntity.Show); - if (existingContent != null) + // Just double check the rating key, since this is our unique constraint + var existingKey = await Repo.GetByKey(show.ratingKey); + + if (existingKey != null) + { + // Damn son. + // Let's check if they match up + var doesMatch = show.title.Equals(existingKey.Title, + StringComparison.CurrentCulture); + if (!doesMatch) { - // Just check the key - var existingKey = await Repo.GetByKey(show.ratingKey); - if (existingKey != null) - { - // The rating key is all good! - } - else - { - // This means the rating key has changed somehow. - // Should probably delete this and get the new one - var oldKey = existingContent.Key; - Repo.DeleteWithoutSave(existingContent); - - // Because we have changed the rating key, we need to change all children too - var episodeToChange = Repo.GetAllEpisodes().Where(x => x.GrandparentKey == oldKey); - if (episodeToChange.Any()) - { - foreach (var e in episodeToChange) - { - Repo.DeleteWithoutSave(e); - } - } - await Repo.SaveChangesAsync(); - existingContent = null; - } + // Something fucked up on Plex at somepoint... Damn, rebuild of lib maybe? + // Lets delete the matching key + await Repo.Delete(existingKey); + existingKey = null; + } + } + if (existingContent != null) + { + // Just check the key + if (existingKey != null) + { + // The rating key is all good! } - // The ratingKey keeps changing... - //var existingContent = await Repo.GetByKey(show.ratingKey); - if (existingContent != null) + else { - try + // This means the rating key has changed somehow. + // Should probably delete this and get the new one + var oldKey = existingContent.Key; + Repo.DeleteWithoutSave(existingContent); + + // Because we have changed the rating key, we need to change all children too + var episodeToChange = Repo.GetAllEpisodes().Where(x => x.GrandparentKey == oldKey); + if (episodeToChange.Any()) { - Logger.LogInformation("We already have show {0} checking for new seasons", existingContent.Title); - // Ok so we have it, let's check if there are any new seasons - var itemAdded = false; - foreach (var season in seasonsContent) + foreach (var e in episodeToChange) { - var seasonExists = existingContent.Seasons.FirstOrDefault(x => x.SeasonKey == season.SeasonKey); - - if (seasonExists != null) - { - // We already have this season - continue; - } - - existingContent.Seasons.Add(season); - itemAdded = true; + Repo.DeleteWithoutSave(e); } - - if (itemAdded) await Repo.Update(existingContent); - } - catch (Exception e) - { - Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new seasons to title {0}", existingContent.Title); } + await Repo.SaveChangesAsync(); + existingContent = null; } - else + } + // The ratingKey keeps changing... + //var existingContent = await Repo.GetByKey(show.ratingKey); + if (existingContent != null) + { + try { - try + Logger.LogInformation("We already have show {0} checking for new seasons", + existingContent.Title); + // Ok so we have it, let's check if there are any new seasons + var itemAdded = false; + foreach (var season in seasonsContent) { + var seasonExists = + existingContent.Seasons.FirstOrDefault(x => x.SeasonKey == season.SeasonKey); - Logger.LogInformation("New show {0}, so add it", show.title); - - // Get the show metadata... This sucks since the `metadata` var contains all information about the show - // But it does not contain the `guid` property that we need to pull out thetvdb id... - var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, - show.ratingKey); - var providerIds = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata.FirstOrDefault().guid); - - var item = new PlexServerContent - { - AddedAt = DateTime.Now, - Key = show.ratingKey, - ReleaseYear = show.year.ToString(), - Type = PlexMediaTypeEntity.Show, - Title = show.title, - Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey), - Seasons = new List() - }; - if (providerIds.Type == ProviderType.ImdbId) - { - item.ImdbId = providerIds.ImdbId; - } - if (providerIds.Type == ProviderType.TheMovieDbId) + if (seasonExists != null) { - item.TheMovieDbId = providerIds.TheMovieDb; - } - if (providerIds.Type == ProviderType.TvDbId) - { - item.TvDbId = providerIds.TheTvDb; - } - - // Let's just double check to make sure we do not have it now we have some id's - var existingImdb = false; - var existingMovieDbId = false; - var existingTvDbId = false; - if (item.ImdbId.HasValue()) - { - existingImdb = await Repo.GetAll().AnyAsync(x => - x.ImdbId == item.ImdbId && x.Type == PlexMediaTypeEntity.Show); - } - if (item.TheMovieDbId.HasValue()) - { - existingMovieDbId = await Repo.GetAll().AnyAsync(x => - x.TheMovieDbId == item.TheMovieDbId && x.Type == PlexMediaTypeEntity.Show); - } - if (item.TvDbId.HasValue()) - { - existingTvDbId = await Repo.GetAll().AnyAsync(x => - x.TvDbId == item.TvDbId && x.Type == PlexMediaTypeEntity.Show); - } - if (existingImdb || existingTvDbId || existingMovieDbId) - { - // We already have it! + // We already have this season continue; } - item.Seasons.ToList().AddRange(seasonsContent); - - contentToAdd.Add(item); - - } - catch (Exception e) - { - Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding tv show {0}", show.title); + existingContent.Seasons.Add(season); + itemAdded = true; } + if (itemAdded) await Repo.Update(existingContent); + } + catch (Exception e) + { + Logger.LogError(LoggingEvents.PlexContentCacher, e, + "Exception when adding new seasons to title {0}", existingContent.Title); } } - } - if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)) - { - Logger.LogInformation("Processing Movies"); - foreach (var movie in content?.Metadata ?? new Metadata[] { }) + else { - // Let's check if we have this movie - try { - var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title - && x.ReleaseYear == movie.year.ToString() - && x.Type == PlexMediaTypeEntity.Movie); - // The rating key keeps changing - //var existing = await Repo.GetByKey(movie.ratingKey); - if (existing != null) - { - Logger.LogInformation("We already have movie {0}", movie.title); - continue; - } - - var hasSameKey = await Repo.GetByKey(movie.ratingKey); - if (hasSameKey != null) - { - await Repo.Delete(hasSameKey); - } + Logger.LogInformation("New show {0}, so add it", show.title); - Logger.LogInformation("Adding movie {0}", movie.title); - var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, - movie.ratingKey); - var providerIds = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata - .FirstOrDefault() - .guid); + // Get the show metadata... This sucks since the `metadata` var contains all information about the show + // But it does not contain the `guid` property that we need to pull out thetvdb id... + var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, + show.ratingKey); + var providerIds = + PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata.FirstOrDefault() + .guid); var item = new PlexServerContent { AddedAt = DateTime.Now, - Key = movie.ratingKey, - ReleaseYear = movie.year.ToString(), - Type = PlexMediaTypeEntity.Movie, - Title = movie.title, - Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), - Seasons = new List(), - Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty + Key = show.ratingKey, + ReleaseYear = show.year.ToString(), + Type = PlexMediaTypeEntity.Show, + Title = show.title, + Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey), + Seasons = new List() }; if (providerIds.Type == ProviderType.ImdbId) { @@ -317,26 +255,130 @@ namespace Ombi.Schedule.Jobs.Plex { item.TvDbId = providerIds.TheTvDb; } + + // Let's just double check to make sure we do not have it now we have some id's + var existingImdb = false; + var existingMovieDbId = false; + var existingTvDbId = false; + if (item.ImdbId.HasValue()) + { + existingImdb = await Repo.GetAll().AnyAsync(x => + x.ImdbId == item.ImdbId && x.Type == PlexMediaTypeEntity.Show); + } + if (item.TheMovieDbId.HasValue()) + { + existingMovieDbId = await Repo.GetAll().AnyAsync(x => + x.TheMovieDbId == item.TheMovieDbId && x.Type == PlexMediaTypeEntity.Show); + } + if (item.TvDbId.HasValue()) + { + existingTvDbId = await Repo.GetAll().AnyAsync(x => + x.TvDbId == item.TvDbId && x.Type == PlexMediaTypeEntity.Show); + } + if (existingImdb || existingTvDbId || existingMovieDbId) + { + // We already have it! + continue; + } + + item.Seasons.ToList().AddRange(seasonsContent); + contentToAdd.Add(item); } catch (Exception e) { - Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}", movie.title); + Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding tv show {0}", + show.title); } } + if (contentToAdd.Count > 500) + { + await Repo.AddRange(contentToAdd); + contentToAdd.Clear(); + } } - if (contentToAdd.Count > 500) + } + if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)) + { + Logger.LogInformation("Processing Movies"); + foreach (var movie in content?.Metadata ?? new Metadata[] { }) { - await Repo.AddRange(contentToAdd); - contentToAdd = new List(); + // Let's check if we have this movie + + try + { + var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title + && x.ReleaseYear == movie.year.ToString() + && x.Type == PlexMediaTypeEntity.Movie); + // The rating key keeps changing + //var existing = await Repo.GetByKey(movie.ratingKey); + if (existing != null) + { + Logger.LogInformation("We already have movie {0}", movie.title); + continue; + } + + var hasSameKey = await Repo.GetByKey(movie.ratingKey); + if (hasSameKey != null) + { + await Repo.Delete(hasSameKey); + } + + Logger.LogInformation("Adding movie {0}", movie.title); + var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, + movie.ratingKey); + var providerIds = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata + .FirstOrDefault() + .guid); + + var item = new PlexServerContent + { + AddedAt = DateTime.Now, + Key = movie.ratingKey, + ReleaseYear = movie.year.ToString(), + Type = PlexMediaTypeEntity.Movie, + Title = movie.title, + Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), + Seasons = new List(), + Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty + }; + if (providerIds.Type == ProviderType.ImdbId) + { + item.ImdbId = providerIds.ImdbId; + } + if (providerIds.Type == ProviderType.TheMovieDbId) + { + item.TheMovieDbId = providerIds.TheMovieDb; + } + if (providerIds.Type == ProviderType.TvDbId) + { + item.TvDbId = providerIds.TheTvDb; + } + contentToAdd.Add(item); + } + catch (Exception e) + { + Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}", + movie.title); + } + + if (contentToAdd.Count > 500) + { + await Repo.AddRange(contentToAdd); + contentToAdd.Clear(); + } } } - - if (contentToAdd.Any()) + if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); + contentToAdd.Clear(); } + } + if (contentToAdd.Any()) + { + await Repo.AddRange(contentToAdd); } } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index f9fc3fbf8..7d0fde4c7 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -62,7 +62,6 @@ namespace Ombi.Schedule.Jobs.Plex { if (!Validate(settings)) { - _log.LogWarning("Validation failed"); return; } @@ -101,21 +100,25 @@ namespace Ombi.Schedule.Jobs.Plex { var currentPosition = 0; var resultCount = settings.EpisodeBatchSize == 0 ? 150 : settings.EpisodeBatchSize; + var currentEpisodes = _repo.GetAllEpisodes(); var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, resultCount); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}"); // Delete all the episodes because we cannot uniquly match an episode to series every time, // see comment below. - await _repo.ExecuteSql("DELETE FROM PlexEpisode"); - await ProcessEpsiodes(episodes); + // 12.03.2017 - I think we should be able to match them now + //await _repo.ExecuteSql("DELETE FROM PlexEpisode"); + + await ProcessEpsiodes(episodes, currentEpisodes); currentPosition += resultCount; while (currentPosition < episodes.MediaContainer.totalSize) { var ep = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, resultCount); - await ProcessEpsiodes(ep); + + await ProcessEpsiodes(ep, currentEpisodes); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Processed {resultCount} more episodes. Total Remaining {episodes.MediaContainer.totalSize - currentPosition}"); currentPosition += resultCount; } @@ -125,58 +128,56 @@ namespace Ombi.Schedule.Jobs.Plex await _repo.SaveChangesAsync(); } - private async Task ProcessEpsiodes(PlexContainer episodes) + private async Task ProcessEpsiodes(PlexContainer episodes, IQueryable currentEpisodes) { var ep = new HashSet(); try { - - - foreach (var episode in episodes?.MediaContainer?.Metadata ?? new Metadata[]{}) - { - // I don't think we need to get the metadata, we only need to get the metadata if we need the provider id (TheTvDbid). Why do we need it for episodes? - // We have the parent and grandparent rating keys to link up to the season and series - //var metadata = _api.GetEpisodeMetaData(server.PlexAuthToken, server.FullUri, episode.ratingKey); - - // This does seem to work, it looks like we can somehow get different rating, grandparent and parent keys with episodes. Not sure how. - //var epExists = currentEpisodes.Any(x => episode.ratingKey == x.Key && - // episode.grandparentRatingKey == x.GrandparentKey); - //if (epExists) - //{ - // continue; - //} - - // Let's check if we have the parent - var seriesExists = await _repo.GetByKey(episode.grandparentRatingKey); - if (seriesExists == null) + foreach (var episode in episodes?.MediaContainer?.Metadata ?? new Metadata[] { }) { - // Ok let's try and match it to a title. TODO (This is experimental) - var seriesMatch = await _repo.GetAll().FirstOrDefaultAsync(x => - x.Title.Equals(episode.grandparentTitle, StringComparison.CurrentCultureIgnoreCase)); - if (seriesMatch == null) + // I don't think we need to get the metadata, we only need to get the metadata if we need the provider id (TheTvDbid). Why do we need it for episodes? + // We have the parent and grandparent rating keys to link up to the season and series + //var metadata = _api.GetEpisodeMetaData(server.PlexAuthToken, server.FullUri, episode.ratingKey); + + // This does seem to work, it looks like we can somehow get different rating, grandparent and parent keys with episodes. Not sure how. + var epExists = currentEpisodes.Any(x => episode.ratingKey == x.Key && + episode.grandparentRatingKey == x.GrandparentKey); + if (epExists) { - _log.LogWarning( - "The episode title {0} we cannot find the parent series. The episode grandparentKey = {1}, grandparentTitle = {2}", - episode.title, episode.grandparentRatingKey, episode.grandparentTitle); continue; } - // Set the rating key to the correct one - episode.grandparentRatingKey = seriesMatch.Key; - } + // Let's check if we have the parent + var seriesExists = await _repo.GetByKey(episode.grandparentRatingKey); + if (seriesExists == null) + { + // Ok let's try and match it to a title. TODO (This is experimental) + seriesExists = await _repo.GetAll().FirstOrDefaultAsync(x => + x.Title.Equals(episode.grandparentTitle, StringComparison.CurrentCultureIgnoreCase)); + if (seriesExists == null) + { + _log.LogWarning( + "The episode title {0} we cannot find the parent series. The episode grandparentKey = {1}, grandparentTitle = {2}", + episode.title, episode.grandparentRatingKey, episode.grandparentTitle); + continue; + } - ep.Add(new PlexEpisode - { - EpisodeNumber = episode.index, - SeasonNumber = episode.parentIndex, - GrandparentKey = episode.grandparentRatingKey, - ParentKey = episode.parentRatingKey, - Key = episode.ratingKey, - Title = episode.title - }); - } + // Set the rating key to the correct one + episode.grandparentRatingKey = seriesExists.Key; + } + + ep.Add(new PlexEpisode + { + EpisodeNumber = episode.index, + SeasonNumber = episode.parentIndex, + GrandparentKey = episode.grandparentRatingKey, + ParentKey = episode.parentRatingKey, + Key = episode.ratingKey, + Title = episode.title + }); + } - await _repo.AddRange(ep); + await _repo.AddRange(ep); } catch (Exception e) { @@ -189,7 +190,7 @@ namespace Ombi.Schedule.Jobs.Plex { if (string.IsNullOrEmpty(settings.PlexAuthToken)) { - return false ; + return false; } return true; diff --git a/src/Ombi/ClientApp/app/app.component.ts b/src/Ombi/ClientApp/app/app.component.ts index fff816537..28672c789 100644 --- a/src/Ombi/ClientApp/app/app.component.ts +++ b/src/Ombi/ClientApp/app/app.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from "@angular/core"; +import { PlatformLocation } from "@angular/common"; +import { Component, OnInit } from "@angular/core"; import { NavigationStart, Router } from "@angular/router"; import { TranslateService } from "@ngx-translate/core"; import { AuthService } from "./auth/auth.service"; @@ -32,7 +33,14 @@ export class AppComponent implements OnInit { private readonly settingsService: SettingsService, private readonly jobService: JobService, public readonly translate: TranslateService, - private readonly identityService: IdentityService) { + private readonly identityService: IdentityService, + private readonly platformLocation: PlatformLocation) { + + const base = this.platformLocation.getBaseHrefFromDOM(); + if (base.length > 1) { + __webpack_public_path__ = base + "/dist/"; + } + this.translate.addLangs(["en", "de", "fr","da","es","it","nl","sv","no"]); // this language will be used as a fallback when a translation isn't found in the current language this.translate.setDefaultLang("en"); diff --git a/src/Ombi/ClientApp/app/issues/issuestable.component.html b/src/Ombi/ClientApp/app/issues/issuestable.component.html index f1b686c19..f98d6eb0e 100644 --- a/src/Ombi/ClientApp/app/issues/issuestable.component.html +++ b/src/Ombi/ClientApp/app/issues/issuestable.component.html @@ -13,15 +13,15 @@ - + - + - + - + diff --git a/src/Ombi/ClientApp/app/requests/movierequests.component.html b/src/Ombi/ClientApp/app/requests/movierequests.component.html index c00d908cf..a4bdf0aed 100644 --- a/src/Ombi/ClientApp/app/requests/movierequests.component.html +++ b/src/Ombi/ClientApp/app/requests/movierequests.component.html @@ -4,9 +4,49 @@ - + {{ 'Requests.Filter' | translate }} + + + + + @@ -19,7 +59,7 @@
-
+
@@ -203,8 +243,8 @@
- - + +
diff --git a/src/Ombi/ClientApp/app/requests/movierequests.component.ts b/src/Ombi/ClientApp/app/requests/movierequests.component.ts index 72c229f1c..fc695c898 100644 --- a/src/Ombi/ClientApp/app/requests/movierequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/movierequests.component.ts @@ -36,7 +36,8 @@ export class MovieRequestsComponent implements OnInit { public filter: IFilter; public filterType = FilterType; - public sortDisplay: boolean; + public order: string = "requestedDate"; + public reverse = false; private currentlyLoaded: number; private amountToLoad: number; @@ -174,6 +175,14 @@ export class MovieRequestsComponent implements OnInit { }); } + public setOrder(value: string) { + if (this.order === value) { + this.reverse = !this.reverse; + } + + this.order = value; + } + private loadRequests(amountToLoad: number, currentlyLoaded: number) { this.requestService.getMovieRequests(amountToLoad, currentlyLoaded + 1) .subscribe(x => { diff --git a/src/Ombi/ClientApp/app/requests/requests.module.ts b/src/Ombi/ClientApp/app/requests/requests.module.ts index 6bbb3ca01..7bddee71c 100644 --- a/src/Ombi/ClientApp/app/requests/requests.module.ts +++ b/src/Ombi/ClientApp/app/requests/requests.module.ts @@ -2,6 +2,7 @@ import { RouterModule, Routes } from "@angular/router"; import { NgbModule } from "@ng-bootstrap/ng-bootstrap"; +import { OrderModule } from "ngx-order-pipe"; import { InfiniteScrollModule } from "ngx-infinite-scroll"; @@ -34,6 +35,7 @@ const routes: Routes = [ TreeTableModule, SharedModule, SidebarModule, + OrderModule, ], declarations: [ RequestComponent, diff --git a/src/Ombi/ClientApp/app/search/tvsearch.component.html b/src/Ombi/ClientApp/app/search/tvsearch.component.html index 9632f7cbe..fb1729e50 100644 --- a/src/Ombi/ClientApp/app/search/tvsearch.component.html +++ b/src/Ombi/ClientApp/app/search/tvsearch.component.html @@ -62,7 +62,7 @@
- +

{{node.data.title}} ({{node.data.firstAired | date: 'yyyy'}})

diff --git a/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html b/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html index ed9dbde86..ae33598f1 100644 --- a/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html +++ b/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html @@ -16,44 +16,45 @@ - + Username - + - + Alias - + - + Email - - + + + Roles - + Last Logged In - + - + User Type - + diff --git a/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.ts b/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.ts index 09b86a31e..3620e0f20 100644 --- a/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.ts +++ b/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.ts @@ -13,7 +13,7 @@ export class UserManagementComponent implements OnInit { public emailSettings: IEmailNotificationSettings; public customizationSettings: ICustomizationSettings; - public order: string = "u.userName"; + public order: string = "userName"; public reverse = false; public showBulkEdit = false; diff --git a/src/Ombi/package-lock.json b/src/Ombi/package-lock.json index 71c8c5489..de4e14487 100644 --- a/src/Ombi/package-lock.json +++ b/src/Ombi/package-lock.json @@ -4972,9 +4972,9 @@ "integrity": "sha512-7lASze8zHSDdAAFO3VNop1TY60rs8A7sm8DzQfU33VNcJI27F6mtxwjILIH339s7m6HVC08AS7I64HBjBMw/QQ==" }, "ngx-order-pipe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ngx-order-pipe/-/ngx-order-pipe-1.1.1.tgz", - "integrity": "sha512-hIfdUONbKG14/S5zEyGjr1ukAd2XdUUnUsvA80ct3pyoBCh5aQ7XhBz7N9jCsVzMGTGUPK6R59KYkEPB3n5hbQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ngx-order-pipe/-/ngx-order-pipe-2.0.1.tgz", + "integrity": "sha512-t0IUqoNs3705yZQeohmhUQvpiRTj5RX7AhFXkx3PMfq7G6h7GNNrR3x27XbXEsjKgBo5hPgfEfW5OljRYa1VVw==" }, "ngx-window-token": { "version": "0.0.4", diff --git a/src/Ombi/package.json b/src/Ombi/package.json index 5bc22c190..4e4fe485f 100644 --- a/src/Ombi/package.json +++ b/src/Ombi/package.json @@ -22,7 +22,7 @@ "@angular/platform-browser-dynamic": "^5.1.2", "@angular/platform-server": "5.0.0", "@angular/router": "^5.1.2", - "@auth0/angular-jwt": "^1.0.0-beta.9", + "@auth0/angular-jwt": "1.0.0-beta.9", "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.8", "@ngx-translate/core": "^8.0.0", "@ngx-translate/http-loader": "^2.0.1", @@ -55,7 +55,7 @@ "ng2-cookies": "^1.0.12", "ngx-clipboard": "8.1.1", "ngx-infinite-scroll": "^0.6.1", - "ngx-order-pipe": "^1.1.1", + "ngx-order-pipe": "^2.0.1", "node-sass": "^4.7.2", "npm": "^5.6.0", "pace-progress": "^1.0.2", diff --git a/src/Ombi/typings/globals/globals.d.ts b/src/Ombi/typings/globals/globals.d.ts index 7fd31b87a..84ca1bc2d 100644 --- a/src/Ombi/typings/globals/globals.d.ts +++ b/src/Ombi/typings/globals/globals.d.ts @@ -5,6 +5,8 @@ declare var require: any; declare var localStorage: any; declare var introJs: any; +declare var __webpack_public_path__: any; + declare module "pace-progress"; declare module "webpack-bundle-analyzer"; declare module "uglifyjs-webpack-plugin"; \ No newline at end of file diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index e4c944dd0..c2d8cedc0 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -117,6 +117,7 @@ "RequestStatus": "Request status:", "Denied": " Denied:", "TheatricalRelease": "Theatrical Release: {{date}}", + "TheatricalReleaseSort": "Theatrical Release", "DigitalRelease": "Digital Release: {{date}}", "RequestDate": "Request Date:", "QualityOverride": "Quality Override:", @@ -134,7 +135,11 @@ "ReportIssue":"Report Issue", "Filter":"Filter", "Sort":"Sort", - "SeasonNumberHeading":"Season: {seasonNumber}" + "SeasonNumberHeading":"Season: {seasonNumber}", + "SortTitle":"Title", + "SortRequestDate": "Request Date", + "SortRequestedBy":"Requested By", + "SortStatus":"Status" }, "Issues":{ "Title":"Issues",