From 5e140ab6183b887a7665f5e870eb0bd05d487ace Mon Sep 17 00:00:00 2001
From: sephrat <34862846+sephrat@users.noreply.github.com>
Date: Tue, 2 Nov 2021 16:00:25 +0100
Subject: [PATCH] =?UTF-8?q?fix(translations):=20=F0=9F=8C=90=20Localizatio?=
=?UTF-8?q?n=20-=20Ensuring=20all=20of=20the=20app=20including=20backend?=
=?UTF-8?q?=20are=20localized=20#4366?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Localize TV and movies titles in requests
* Add missing release statuses
* Localize collection request
* Localize TV shows in newsletter
Uses TMDB instead of TVMaze for title, genres and synopsis
* Localize error messages
* Localize albums requests
* Use current language for TV and movies requests
* Remove unecessary console log
---
src/Ombi.Core/Engine/MovieRequestEngine.cs | 9 +-
src/Ombi.Core/Engine/RequestEngineResult.cs | 22 +++-
src/Ombi.Core/Engine/TvRequestEngine.cs | 12 +-
.../Helpers/TvShowRequestBuilderV2.cs | 4 +-
.../Models/Requests/TvRequestViewModelV2.cs | 1 +
src/Ombi.Core/Rule/BaseRequestRule.cs | 7 +-
src/Ombi.Core/Rule/RuleResult.cs | 4 +-
.../Rule/Rules/Request/CanRequestRule.cs | 7 +-
.../Rules/Request/ExistingMovieRequestRule.cs | 3 +-
.../Rules/Request/ExistingPlexRequestRule.cs | 3 +-
.../Rules/Request/ExistingTVRequestRule.cs | 3 +-
.../Rule/Rules/Request/RequestLimitRule.cs | 6 +-
src/Ombi.Core/Rule/Rules/SonarrCacheRule.cs | 3 +-
src/Ombi.Core/Rule/SpecificRule.cs | 7 +-
src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs | 122 +++++++-----------
.../card/discover-card.component.ts | 8 +-
.../discover-collections.component.ts | 2 +-
.../app/interfaces/IRequestEngineResult.ts | 16 +++
.../src/app/interfaces/ISearchTvResult.ts | 1 +
.../artist/artist-details.component.ts | 16 ++-
.../artist-information-panel.component.html | 8 +-
.../movie/movie-details.component.ts | 16 +--
.../deny-dialog/deny-dialog.component.ts | 2 +-
.../tv-request-grid.component.ts | 9 +-
.../tv-requests-panel.component.ts | 4 +-
.../src/app/services/message.service.ts | 13 +-
.../episode-request.component.ts | 4 +-
src/Ombi/wwwroot/translations/en.json | 30 ++++-
28 files changed, 205 insertions(+), 137 deletions(-)
diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs
index bf694a262..63aa0d376 100644
--- a/src/Ombi.Core/Engine/MovieRequestEngine.cs
+++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs
@@ -120,11 +120,13 @@ namespace Ombi.Core.Engine
?.FirstOrDefault(x => x.Type == ReleaseDateType.Digital)?.ReleaseDate;
var ruleResults = (await RunRequestRules(requestModel)).ToList();
- if (ruleResults.Any(x => !x.Success))
+ var ruleResultInError = ruleResults.Find(x => !x.Success);
+ if (ruleResultInError != null)
{
return new RequestEngineResult
{
- ErrorMessage = ruleResults.FirstOrDefault(x => x.Message.HasValue()).Message
+ ErrorMessage = ruleResultInError.Message,
+ ErrorCode = ruleResultInError.ErrorCode
};
}
@@ -573,7 +575,8 @@ namespace Ombi.Core.Engine
{
results.Add(await RequestMovie(new MovieRequestViewModel
{
- TheMovieDbId = collection.id
+ TheMovieDbId = collection.id,
+ LanguageCode = langCode
}));
}
diff --git a/src/Ombi.Core/Engine/RequestEngineResult.cs b/src/Ombi.Core/Engine/RequestEngineResult.cs
index 08f6d5129..08c61b7ae 100644
--- a/src/Ombi.Core/Engine/RequestEngineResult.cs
+++ b/src/Ombi.Core/Engine/RequestEngineResult.cs
@@ -1,4 +1,7 @@
-namespace Ombi.Core.Engine
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+
+namespace Ombi.Core.Engine
{
public class RequestEngineResult
{
@@ -6,6 +9,23 @@
public string Message { get; set; }
public bool IsError => !string.IsNullOrEmpty(ErrorMessage);
public string ErrorMessage { get; set; }
+ public ErrorCode? ErrorCode { get; set; }
public int RequestId { get; set; }
}
+
+ [JsonConverter(typeof(StringEnumConverter))]
+ public enum ErrorCode {
+ AlreadyRequested,
+ EpisodesAlreadyRequested,
+ NoPermissionsOnBehalf,
+ NoPermissions,
+ RequestDoesNotExist,
+ ChildRequestDoesNotExist,
+ NoPermissionsRequestMovie,
+ NoPermissionsRequestTV,
+ NoPermissionsRequestAlbum,
+ MovieRequestQuotaExceeded,
+ TvRequestQuotaExceeded,
+ AlbumRequestQuotaExceeded,
+ }
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs
index d0d139d0c..fd306f951 100644
--- a/src/Ombi.Core/Engine/TvRequestEngine.cs
+++ b/src/Ombi.Core/Engine/TvRequestEngine.cs
@@ -144,6 +144,7 @@ namespace Ombi.Core.Engine
return new RequestEngineResult
{
Result = false,
+ ErrorCode = ErrorCode.AlreadyRequested,
ErrorMessage = "This has already been requested"
};
}
@@ -166,6 +167,7 @@ namespace Ombi.Core.Engine
return new RequestEngineResult
{
Result = false,
+ ErrorCode = ErrorCode.NoPermissionsOnBehalf,
Message = "You do not have the correct permissions to request on behalf of users!",
ErrorMessage = $"You do not have the correct permissions to request on behalf of users!"
};
@@ -176,6 +178,7 @@ namespace Ombi.Core.Engine
return new RequestEngineResult
{
Result = false,
+ ErrorCode = ErrorCode.NoPermissions,
Message = "You do not have the correct permissions!",
ErrorMessage = $"You do not have the correct permissions!"
};
@@ -183,7 +186,7 @@ namespace Ombi.Core.Engine
var tvBuilder = new TvShowRequestBuilderV2(MovieDbApi);
(await tvBuilder
- .GetShowInfo(tv.TheMovieDbId))
+ .GetShowInfo(tv.TheMovieDbId, tv.languageCode))
.CreateTvList(tv)
.CreateChild(tv, canRequestOnBehalf ? tv.RequestOnBehalf : user.Id);
@@ -250,6 +253,7 @@ namespace Ombi.Core.Engine
return new RequestEngineResult
{
Result = false,
+ ErrorCode = ErrorCode.AlreadyRequested,
ErrorMessage = "This has already been requested"
};
}
@@ -685,6 +689,7 @@ namespace Ombi.Core.Engine
{
return new RequestEngineResult
{
+ ErrorCode = ErrorCode.ChildRequestDoesNotExist,
ErrorMessage = "Child Request does not exist"
};
}
@@ -722,6 +727,7 @@ namespace Ombi.Core.Engine
{
return new RequestEngineResult
{
+ ErrorCode = ErrorCode.ChildRequestDoesNotExist,
ErrorMessage = "Child Request does not exist"
};
}
@@ -781,6 +787,7 @@ namespace Ombi.Core.Engine
{
return new RequestEngineResult
{
+ ErrorCode = ErrorCode.ChildRequestDoesNotExist,
ErrorMessage = "Child Request does not exist"
};
}
@@ -808,6 +815,7 @@ namespace Ombi.Core.Engine
{
return new RequestEngineResult
{
+ ErrorCode = ErrorCode.ChildRequestDoesNotExist,
ErrorMessage = "Child Request does not exist"
};
}
@@ -905,6 +913,7 @@ namespace Ombi.Core.Engine
return new RequestEngineResult
{
Result = false,
+ ErrorCode = ErrorCode.RequestDoesNotExist,
ErrorMessage = "Request does not exist"
};
}
@@ -965,6 +974,7 @@ namespace Ombi.Core.Engine
return new RequestEngineResult
{
Result = false,
+ ErrorCode = ErrorCode.RequestDoesNotExist,
ErrorMessage = "Request does not exist"
};
}
diff --git a/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs b/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs
index 7a45e9f09..6843332c0 100644
--- a/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs
+++ b/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs
@@ -30,9 +30,9 @@ namespace Ombi.Core.Helpers
public TvRequests NewRequest { get; protected set; }
protected TvInfo TheMovieDbRecord { get; set; }
- public async Task GetShowInfo(int id)
+ public async Task GetShowInfo(int id, string langCode = "en")
{
- TheMovieDbRecord = await MovieDbApi.GetTVInfo(id.ToString());
+ TheMovieDbRecord = await MovieDbApi.GetTVInfo(id.ToString(), langCode);
// Remove 'Specials Season'
var firstSeason = TheMovieDbRecord.seasons.OrderBy(x => x.season_number).FirstOrDefault();
diff --git a/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs b/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs
index d967993ec..a9742fb32 100644
--- a/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs
+++ b/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs
@@ -6,5 +6,6 @@ namespace Ombi.Core.Models.Requests
public class TvRequestViewModelV2 : TvRequestViewModelBase
{
public int TheMovieDbId { get; set; }
+ public string languageCode { get; set; } = "en";
}
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Rule/BaseRequestRule.cs b/src/Ombi.Core/Rule/BaseRequestRule.cs
index fe4daa7ff..3def16d7d 100644
--- a/src/Ombi.Core/Rule/BaseRequestRule.cs
+++ b/src/Ombi.Core/Rule/BaseRequestRule.cs
@@ -1,4 +1,5 @@
-namespace Ombi.Core.Rule
+using Ombi.Core.Engine;
+namespace Ombi.Core.Rule
{
public abstract class BaseRequestRule
{
@@ -7,9 +8,9 @@
return new RuleResult {Success = true};
}
- public RuleResult Fail(string message)
+ public RuleResult Fail(ErrorCode errorCode, string message = "")
{
- return new RuleResult { Message = message };
+ return new RuleResult { ErrorCode = errorCode, Message = message };
}
}
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Rule/RuleResult.cs b/src/Ombi.Core/Rule/RuleResult.cs
index ea73cbd88..3cbc6f4a7 100644
--- a/src/Ombi.Core/Rule/RuleResult.cs
+++ b/src/Ombi.Core/Rule/RuleResult.cs
@@ -1,8 +1,10 @@
-namespace Ombi.Core.Rule
+using Ombi.Core.Engine;
+namespace Ombi.Core.Rule
{
public class RuleResult
{
public bool Success { get; set; }
public string Message { get; set; }
+ public ErrorCode ErrorCode { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs
index 23ad86dc0..1c720a385 100644
--- a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs
@@ -6,6 +6,7 @@ using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Authentication;
+using Ombi.Core.Engine;
using Ombi.Core.Rule.Interfaces;
using Ombi.Helpers;
using Ombi.Store.Entities.Requests;
@@ -34,7 +35,7 @@ namespace Ombi.Core.Rule.Rules.Request
{
if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMovie) || await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie))
return Success();
- return Fail("You do not have permissions to Request a Movie");
+ return Fail(ErrorCode.NoPermissionsRequestMovie, "You do not have permissions to Request a Movie");
}
if (obj.RequestType == RequestType.TvShow)
@@ -44,7 +45,7 @@ namespace Ombi.Core.Rule.Rules.Request
return Success();
}
- return Fail("You do not have permissions to Request a TV Show");
+ return Fail(ErrorCode.NoPermissionsRequestTV, "You do not have permissions to Request a TV Show");
}
if (obj.RequestType == RequestType.Album)
@@ -54,7 +55,7 @@ namespace Ombi.Core.Rule.Rules.Request
return Success();
}
- return Fail("You do not have permissions to Request an Album");
+ return Fail(ErrorCode.NoPermissionsRequestAlbum, "You do not have permissions to Request an Album");
}
throw new InvalidDataException("Permission check failed: unknown RequestType");
diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs
index 15861ca27..c837c42d1 100644
--- a/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs
@@ -6,6 +6,7 @@ using Ombi.Helpers;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository;
+using Ombi.Core.Engine;
using Ombi.Store.Repository.Requests;
namespace Ombi.Core.Rule.Rules.Request
@@ -49,7 +50,7 @@ namespace Ombi.Core.Rule.Rules.Request
}
if(found)
{
- return Fail($"\"{obj.Title}\" has already been requested");
+ return Fail(ErrorCode.AlreadyRequested, $"\"{obj.Title}\" has already been requested");
}
}
return Success();
diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs
index 10ab93bed..ef38fb973 100644
--- a/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
+using Ombi.Core.Engine;
using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
@@ -87,7 +88,7 @@ namespace Ombi.Core.Rule.Rules.Request
if (!anyEpisodes)
{
- return Fail($"We already have episodes requested from series {child.Title}");
+ return Fail(ErrorCode.EpisodesAlreadyRequested, $"We already have episodes requested from series {child.Title}");
}
return Success();
diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs
index 7973f664b..a9be6a016 100644
--- a/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs
@@ -3,6 +3,7 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Rule.Interfaces;
+using Ombi.Core.Engine;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository.Requests;
@@ -63,7 +64,7 @@ namespace Ombi.Core.Rule.Rules.Request
if (!anyEpisodes)
{
- return Fail($"We already have episodes requested from series {tv.Title}");
+ return Fail(ErrorCode.EpisodesAlreadyRequested, $"We already have episodes requested from series {tv.Title}");
}
}
diff --git a/src/Ombi.Core/Rule/Rules/Request/RequestLimitRule.cs b/src/Ombi.Core/Rule/Rules/Request/RequestLimitRule.cs
index efa738601..ddf4c1cbf 100644
--- a/src/Ombi.Core/Rule/Rules/Request/RequestLimitRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Request/RequestLimitRule.cs
@@ -54,7 +54,7 @@ namespace Ombi.Core.Rule.Rules.Request
if (remainingLimitsModel.Remaining < 1)
{
- return Fail("You have exceeded your Movie request quota!");
+ return Fail(Engine.ErrorCode.MovieRequestQuotaExceeded, "You have exceeded your Movie request quota!");
}
}
if (obj.RequestType == RequestType.TvShow)
@@ -75,7 +75,7 @@ namespace Ombi.Core.Rule.Rules.Request
if ((remainingLimitsModel.Remaining - requestCount) < 0)
{
- return Fail("You have exceeded your Episode request quota!");
+ return Fail(Engine.ErrorCode.TvRequestQuotaExceeded, "You have exceeded your Episode request quota!");
}
}
if (obj.RequestType == RequestType.Album)
@@ -88,7 +88,7 @@ namespace Ombi.Core.Rule.Rules.Request
if (remainingLimitsModel.Remaining < 1)
{
- return Fail("You have exceeded your Album request quota!");
+ return Fail(Engine.ErrorCode.AlbumRequestQuotaExceeded, "You have exceeded your Album request quota!");
}
}
return Success();
diff --git a/src/Ombi.Core/Rule/Rules/SonarrCacheRule.cs b/src/Ombi.Core/Rule/Rules/SonarrCacheRule.cs
index 325b7cc8d..2bb2fd128 100644
--- a/src/Ombi.Core/Rule/Rules/SonarrCacheRule.cs
+++ b/src/Ombi.Core/Rule/Rules/SonarrCacheRule.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
+using Ombi.Core.Engine;
using Ombi.Core.Models.Search;
using Ombi.Helpers;
using Ombi.Store.Context;
@@ -56,7 +57,7 @@ namespace Ombi.Core.Rule.Rules
if (!anyEpisodes)
{
- return new RuleResult { Message = $"We already have episodes requested from series {vm.Title}" };
+ return new RuleResult { ErrorCode = ErrorCode.EpisodesAlreadyRequested, Message = $"We already have episodes requested from series {vm.Title}" };
}
}
}
diff --git a/src/Ombi.Core/Rule/SpecificRule.cs b/src/Ombi.Core/Rule/SpecificRule.cs
index 071bce292..990f6168d 100644
--- a/src/Ombi.Core/Rule/SpecificRule.cs
+++ b/src/Ombi.Core/Rule/SpecificRule.cs
@@ -1,4 +1,5 @@
-using Ombi.Core.Rule.Interfaces;
+using Ombi.Core.Engine;
+using Ombi.Core.Rule.Interfaces;
namespace Ombi.Core.Rule
{
@@ -9,9 +10,9 @@ namespace Ombi.Core.Rule
return new RuleResult { Success = true };
}
- public RuleResult Fail(string message)
+ public RuleResult Fail(ErrorCode errorCode, string message = "")
{
- return new RuleResult { Message = message };
+ return new RuleResult { ErrorCode = errorCode, Message = message };
}
public abstract SpecificRules Rule { get; }
diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs
index cd24cda8b..7752d298d 100644
--- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs
+++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs
@@ -615,17 +615,17 @@ namespace Ombi.Schedule.Jobs.Ombi
sb.Append("");
if (plexSettings.Enable)
{
- await ProcessPlexTv(plexEpisodes, sb, plexSettings.Servers.FirstOrDefault().ServerHostname ?? string.Empty);
+ await ProcessPlexTv(plexEpisodes, sb, ombiSettings.DefaultLanguageCode, plexSettings.Servers.FirstOrDefault().ServerHostname ?? string.Empty);
}
if (embySettings.Enable)
{
- await ProcessEmbyTv(embyEp, sb, embySettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
+ await ProcessEmbyTv(embyEp, sb, ombiSettings.DefaultLanguageCode, embySettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
}
if (jellyfinSettings.Enable)
{
- await ProcessJellyfinTv(jellyfinEp, sb, jellyfinSettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
+ await ProcessJellyfinTv(jellyfinEp, sb, ombiSettings.DefaultLanguageCode, jellyfinSettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
}
sb.Append("
");
@@ -908,7 +908,7 @@ namespace Ombi.Schedule.Jobs.Ombi
AddGenres(sb, $"Type: {info.albumType}");
}
- private async Task ProcessPlexTv(HashSet plexContent, StringBuilder sb, string serverHostname)
+ private async Task ProcessPlexTv(HashSet plexContent, StringBuilder sb, string languageCode, string serverHostname)
{
var series = new List();
foreach (var plexEpisode in plexContent)
@@ -975,7 +975,7 @@ namespace Ombi.Schedule.Jobs.Ombi
banner = banner.ToHttpsUrl(); // Always use the Https banners
}
- var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId);
+ var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode);
if (tvInfo != null && tvInfo.backdrop_path.HasValue())
{
@@ -989,16 +989,7 @@ namespace Ombi.Schedule.Jobs.Ombi
AddMediaServerUrl(sb, PlexHelper.BuildPlexMediaUrl(t.Url, serverHostname), banner);
AddInfoTable(sb);
- var title = "";
- if (!string.IsNullOrEmpty(info.premiered) && info.premiered.Length > 4)
- {
- title = $"{t.Title} ({info.premiered.Remove(4)})";
- }
- else
- {
- title = $"{t.Title}";
- }
- AddTitle(sb, $"https://www.imdb.com/title/{info.externals.imdb}/", title);
+ AddTvTitle(sb, info, tvInfo);
// Group by the season number
var results = t.Episodes.GroupBy(p => p.SeasonNumber,
@@ -1021,18 +1012,7 @@ namespace Ombi.Schedule.Jobs.Ombi
finalsb.Append("
");
}
- var summary = info.summary;
- if (summary.Length > 280)
- {
- summary = summary.Remove(280);
- summary = summary + "...
";
- }
- AddTvParagraph(sb, finalsb.ToString(), summary);
-
- if (info.genres.Any())
- {
- AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
- }
+ AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo);
}
catch (Exception e)
@@ -1056,7 +1036,7 @@ namespace Ombi.Schedule.Jobs.Ombi
- private async Task ProcessEmbyTv(HashSet embyContent, StringBuilder sb, string serverUrl)
+ private async Task ProcessEmbyTv(HashSet embyContent, StringBuilder sb, string languageCode, string serverUrl)
{
var series = new List();
foreach (var episode in embyContent)
@@ -1100,7 +1080,7 @@ namespace Ombi.Schedule.Jobs.Ombi
banner = banner.ToHttpsUrl(); // Always use the Https banners
}
- var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId);
+ var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode);
if (tvInfo != null && tvInfo.backdrop_path.HasValue())
{
@@ -1114,16 +1094,7 @@ namespace Ombi.Schedule.Jobs.Ombi
AddMediaServerUrl(sb, serverUrl.HasValue() ? serverUrl : t.Url, banner);
AddInfoTable(sb);
- var title = "";
- if (!String.IsNullOrEmpty(info.premiered) && info.premiered.Length > 4)
- {
- title = $"{t.Title} ({info.premiered.Remove(4)})";
- }
- else
- {
- title = $"{t.Title}";
- }
- AddTitle(sb, $"https://www.imdb.com/title/{info.externals.imdb}/", title);
+ AddTvTitle(sb, info, tvInfo);
// Group by the season number
var results = t.Episodes?.GroupBy(p => p.SeasonNumber,
@@ -1146,18 +1117,7 @@ namespace Ombi.Schedule.Jobs.Ombi
finalsb.Append("
");
}
- var summary = info.summary;
- if (summary.Length > 280)
- {
- summary = summary.Remove(280);
- summary = summary + "...";
- }
- AddTvParagraph(sb, finalsb.ToString(), summary);
-
- if (info.genres.Any())
- {
- AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
- }
+ AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo);
}
catch (Exception e)
@@ -1179,10 +1139,10 @@ namespace Ombi.Schedule.Jobs.Ombi
}
}
- private async Task ProcessJellyfinTv(HashSet embyContent, StringBuilder sb, string serverUrl)
+ private async Task ProcessJellyfinTv(HashSet jellyfinContent, StringBuilder sb, string languageCode, string serverUrl)
{
var series = new List();
- foreach (var episode in embyContent)
+ foreach (var episode in jellyfinContent)
{
var alreadyAdded = series.FirstOrDefault(x => x.JellyfinId == episode.Series.JellyfinId);
if (alreadyAdded != null)
@@ -1223,7 +1183,7 @@ namespace Ombi.Schedule.Jobs.Ombi
banner = banner.ToHttpsUrl(); // Always use the Https banners
}
- var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId);
+ var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode);
if (tvInfo != null && tvInfo.backdrop_path.HasValue())
{
@@ -1237,16 +1197,7 @@ namespace Ombi.Schedule.Jobs.Ombi
AddMediaServerUrl(sb, serverUrl.HasValue() ? serverUrl : t.Url, banner);
AddInfoTable(sb);
- var title = "";
- if (!String.IsNullOrEmpty(info.premiered) && info.premiered.Length > 4)
- {
- title = $"{t.Title} ({info.premiered.Remove(4)})";
- }
- else
- {
- title = $"{t.Title}";
- }
- AddTitle(sb, $"https://www.imdb.com/title/{info.externals.imdb}/", title);
+ AddTvTitle(sb, info, tvInfo);
// Group by the season number
var results = t.Episodes?.GroupBy(p => p.SeasonNumber,
@@ -1269,18 +1220,7 @@ namespace Ombi.Schedule.Jobs.Ombi
finalsb.Append("
");
}
- var summary = info.summary;
- if (summary.Length > 280)
- {
- summary = summary.Remove(280);
- summary = summary + "...";
- }
- AddTvParagraph(sb, finalsb.ToString(), summary);
-
- if (info.genres.Any())
- {
- AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
- }
+ AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo);
}
catch (Exception e)
@@ -1302,6 +1242,36 @@ namespace Ombi.Schedule.Jobs.Ombi
}
}
+ private void AddTvTitle(StringBuilder sb, Api.TvMaze.Models.TvMazeShow info, TvInfo tvInfo)
+ {
+ var title = "";
+ if (!String.IsNullOrEmpty(info.premiered) && info.premiered.Length > 4)
+ {
+ title = $"{tvInfo.name} ({info.premiered.Remove(4)})";
+ }
+ else
+ {
+ title = $"{tvInfo.name}";
+ }
+ AddTitle(sb, $"https://www.imdb.com/title/{info.externals.imdb}/", title);
+ }
+
+ private void AddTvEpisodesSummaryGenres(StringBuilder sb, string episodes, TvInfo tvInfo)
+ {
+ var summary = tvInfo.overview;
+ if (summary.Length > 280)
+ {
+ summary = summary.Remove(280);
+ summary = summary + "...";
+ }
+ AddTvParagraph(sb, episodes, summary);
+
+ if (tvInfo.genres.Any())
+ {
+ AddGenres(sb, $"Genres: {string.Join(", ", tvInfo.genres.Select(x => x.name.ToString()).ToArray())}");
+ }
+ }
+
private void EndLoopHtml(StringBuilder sb)
{
//NOTE: BR have to be in TD's as per html spec or it will be put outside of the table...
diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts
index 0907404a8..1bd2546bc 100644
--- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts
+++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts
@@ -124,7 +124,7 @@ export class DiscoverCardComponent implements OnInit {
dialog.afterClosed().subscribe((result) => {
if (result) {
this.requestService.requestMovie({ theMovieDbId: +this.result.id,
- languageCode: null,
+ languageCode: this.translate.currentLang,
qualityPathOverride: result.radarrPathId,
requestOnBehalf: result.username?.id,
rootFolderOverride: result.radarrFolderId, }).subscribe(x => {
@@ -132,18 +132,18 @@ export class DiscoverCardComponent implements OnInit {
this.result.requested = true;
this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.result.title }), "Ok");
} else {
- this.messageService.send(x.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(x);
}
});
}
});
} else {
- this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: null, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null }).subscribe(x => {
+ this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: this.translate.currentLang, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null }).subscribe(x => {
if (x.result) {
this.result.requested = true;
this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.result.title }), "Ok");
} else {
- this.messageService.send(x.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(x);
}
this.loading = false;
});
diff --git a/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts b/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts
index 4b5c93b05..9e84ea7d0 100644
--- a/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts
+++ b/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts
@@ -46,7 +46,7 @@ export class DiscoverCollectionsComponent implements OnInit {
if (result.result) {
this.messageService.send(this.translate.instant("Requests.CollectionSuccesfullyAdded", { name: this.collection.name }));
} else {
- this.messageService.send(result.errorMessage);
+ this.messageService.sendRequestEngineResultError(result);
}
this.finishLoading();
});
diff --git a/src/Ombi/ClientApp/src/app/interfaces/IRequestEngineResult.ts b/src/Ombi/ClientApp/src/app/interfaces/IRequestEngineResult.ts
index 87ed1bf61..d121eb1a2 100644
--- a/src/Ombi/ClientApp/src/app/interfaces/IRequestEngineResult.ts
+++ b/src/Ombi/ClientApp/src/app/interfaces/IRequestEngineResult.ts
@@ -2,5 +2,21 @@
result: boolean;
message: string;
errorMessage: string;
+ errorCode: ErrorCode;
requestId: number | undefined;
}
+
+export enum ErrorCode {
+ AlreadyRequested,
+ EpisodesAlreadyRequested,
+ NoPermissionsOnBehalf,
+ NoPermissions,
+ RequestDoesNotExist,
+ ChildRequestDoesNotExist,
+ NoPermissionsRequestMovie,
+ NoPermissionsRequestTV,
+ NoPermissionsRequestAlbum,
+ MovieRequestQuotaExceeded,
+ TvRequestQuotaExceeded,
+ AlbumRequestQuotaExceeded,
+}
\ No newline at end of file
diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResult.ts b/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResult.ts
index 8928c188b..42fa11e53 100644
--- a/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResult.ts
+++ b/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResult.ts
@@ -44,6 +44,7 @@ export interface ISearchTvResult {
export interface ITvRequestViewModelV2 extends ITvRequestViewModelBase {
theMovieDbId: number;
+ languageCode: string;
}
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/artist/artist-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/artist/artist-details.component.ts
index ff6e1e436..5aebde2e5 100644
--- a/src/Ombi/ClientApp/src/app/media-details/components/artist/artist-details.component.ts
+++ b/src/Ombi/ClientApp/src/app/media-details/components/artist/artist-details.component.ts
@@ -8,6 +8,7 @@ import { AuthService } from "../../../auth/auth.service";
import { DenyDialogComponent } from "../shared/deny-dialog/deny-dialog.component";
import { NewIssueComponent } from "../shared/new-issue/new-issue.component";
import { IArtistSearchResult, IReleaseGroups } from "../../../interfaces/IMusicSearchResultV2";
+import { TranslateService } from "@ngx-translate/core";
@Component({
templateUrl: "./artist-details.component.html",
@@ -26,7 +27,8 @@ export class ArtistDetailsComponent {
constructor(private searchService: SearchV2Service, private route: ActivatedRoute,
private sanitizer: DomSanitizer, private imageService: ImageService,
public dialog: MatDialog, private requestService: RequestService,
- public messageService: MessageService, private auth: AuthService) {
+ public messageService: MessageService, private auth: AuthService,
+ private translate: TranslateService) {
this.route.params.subscribe((params: any) => {
this.artistId = params.artistId;
this.load();
@@ -92,16 +94,16 @@ export class ArtistDetailsComponent {
.then(r => {
if (r.result) {
a.monitored = true;
- this.messageService.send(r.message);
+ this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", {title: a.title}));
} else {
- this.messageService.send(r.errorMessage);
+ this.messageService.sendRequestEngineResultError(r);
}
a.selected = false;
})
.catch(r => {
console.log(r);
- this.messageService.send("Error when requesting album");
+ this.messageService.sendRequestEngineResultError(r);
});
});
} else {
@@ -115,16 +117,16 @@ export class ArtistDetailsComponent {
.then(r => {
if (r.result) {
a.monitored = true;
- this.messageService.send(r.message);
+ this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", {title: a.title}));
} else {
- this.messageService.send(r.errorMessage);
+ this.messageService.sendRequestEngineResultError(r);
}
a.selected = false;
})
.catch(r => {
console.log(r);
- this.messageService.send("Error when requesting album");
+ this.messageService.sendRequestEngineResultError(r);
});
})
}
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/artist/panels/artist-information-panel/artist-information-panel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/artist/panels/artist-information-panel/artist-information-panel.component.html
index a50b59039..4a454fe01 100644
--- a/src/Ombi/ClientApp/src/app/media-details/components/artist/panels/artist-information-panel/artist-information-panel.component.html
+++ b/src/Ombi/ClientApp/src/app/media-details/components/artist/panels/artist-information-panel/artist-information-panel.component.html
@@ -1,18 +1,18 @@
-
Type:
+
{{ 'MediaDetails.Music.Type' | translate }}
{{artist.type}}
-
Country
+
{{ 'MediaDetails.Music.Country' | translate }}
{{artist.country}}
-
Start Date
+
{{ 'MediaDetails.Music.StartDate' | translate }}
{{artist.startYear}}
-
End Date
+
{{ 'MediaDetails.Music.EndDate' | translate }}
{{artist.endYear}}
\ No newline at end of file
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts
index ea9b24b1d..d0e2fa1ef 100644
--- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts
+++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts
@@ -92,7 +92,7 @@ export class MovieDetailsComponent {
dialog.afterClosed().subscribe(async (result) => {
if (result) {
const requestResult = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId,
- languageCode: null,
+ languageCode: this.translate.currentLang,
qualityPathOverride: result.radarrPathId,
requestOnBehalf: result.username?.id,
rootFolderOverride: result.radarrFolderId, }).toPromise();
@@ -102,19 +102,19 @@ export class MovieDetailsComponent {
this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.movie.title }), "Ok");
this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId);
} else {
- this.messageService.send(requestResult.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(requestResult);
}
}
});
} else {
- const result = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: null, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined }).toPromise();
+ const result = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: this.translate.currentLang, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined }).toPromise();
if (result.result) {
this.movie.requested = true;
this.movie.requestId = result.requestId;
this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId);
this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.movie.title }), "Ok");
} else {
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
}
}
}
@@ -156,7 +156,7 @@ export class MovieDetailsComponent {
this.messageService.send(this.translate.instant("Requests.SuccessfullyApproved"), "Ok");
} else {
this.movie.approved = false;
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
}
}
@@ -166,7 +166,7 @@ export class MovieDetailsComponent {
this.movie.available = true;
this.messageService.send(this.translate.instant("Requests.NowAvailable"), "Ok");
} else {
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
}
}
@@ -177,7 +177,7 @@ export class MovieDetailsComponent {
this.movie.available = false;
this.messageService.send(this.translate.instant("Requests.NowUnavailable"), "Ok");
} else {
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
}
}
@@ -208,7 +208,7 @@ export class MovieDetailsComponent {
if (result.result) {
this.messageService.send(result.message ? result.message : this.translate.instant("Requests.SuccessfullyReprocessed"), "Ok");
} else {
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
}
});
}
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/shared/deny-dialog/deny-dialog.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/shared/deny-dialog/deny-dialog.component.ts
index 2970c142b..3132ac84f 100644
--- a/src/Ombi/ClientApp/src/app/media-details/components/shared/deny-dialog/deny-dialog.component.ts
+++ b/src/Ombi/ClientApp/src/app/media-details/components/shared/deny-dialog/deny-dialog.component.ts
@@ -35,7 +35,7 @@ export class DenyDialogComponent {
this.messageService.send(this.translate.instant("Requests.DeniedRequest"), "Ok");
this.data.denied = true;
} else {
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
this.data.denied = false;
}
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts
index 3e34b98f9..7d1304eff 100644
--- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts
+++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts
@@ -4,6 +4,7 @@ import { RequestService } from "../../../../../services/request.service";
import { MessageService } from "../../../../../services";
import { DenyDialogComponent } from "../../../shared/deny-dialog/deny-dialog.component";
import { ISearchTvResultV2 } from "../../../../../interfaces/ISearchTvResultV2";
+import { TranslateService } from "@ngx-translate/core";
import { MatDialog } from "@angular/material/dialog";
import { SelectionModel } from "@angular/cdk/collections";
import { RequestServiceV2 } from "../../../../../services/requestV2.service";
@@ -27,7 +28,7 @@ export class TvRequestGridComponent {
public displayedColumns: string[] = ['select', 'number', 'title', 'airDate', 'status'];
constructor(private requestService: RequestService, private requestServiceV2: RequestServiceV2, private notificationService: MessageService,
- private dialog: MatDialog) {
+ private dialog: MatDialog, private translate: TranslateService) {
}
@@ -43,7 +44,7 @@ export class TvRequestGridComponent {
const viewModel = {
firstSeason: this.tv.firstSeason, latestSeason: this.tv.latestSeason, requestAll: this.tv.requestAll, theMovieDbId: this.tv.id,
- requestOnBehalf: null
+ requestOnBehalf: null, languageCode: this.translate.currentLang
};
viewModel.seasons = [];
this.tv.seasonRequests.forEach((season) => {
@@ -236,7 +237,7 @@ export class TvRequestGridComponent {
private postRequest(requestResult: IRequestEngineResult) {
if (requestResult.result) {
this.notificationService.send(
- `Request for ${this.tv.title} has been added successfully`);
+ this.translate.instant("Requests.RequestAddedSuccessfully", { title:this.tv.title }));
this.selection.clear();
@@ -262,7 +263,7 @@ export class TvRequestGridComponent {
}
} else {
- this.notificationService.send(requestResult.errorMessage ? requestResult.errorMessage : requestResult.message);
+ this.notificationService.sendRequestEngineResultError(requestResult);
}
}
}
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts
index d4e8f894c..10eee3989 100644
--- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts
+++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts
@@ -41,7 +41,7 @@ export class TvRequestsPanelComponent {
});
this.messageService.send("Request has been approved", "Ok");
} else {
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
}
}
@@ -104,7 +104,7 @@ export class TvRequestsPanelComponent {
if (result.result) {
this.messageService.send(result.message ? result.message : "Successfully Re-processed the request", "Ok");
} else {
- this.messageService.send(result.errorMessage, "Ok");
+ this.messageService.sendRequestEngineResultError(result);
}
});
}
diff --git a/src/Ombi/ClientApp/src/app/services/message.service.ts b/src/Ombi/ClientApp/src/app/services/message.service.ts
index 1c4e6eded..be1df37be 100644
--- a/src/Ombi/ClientApp/src/app/services/message.service.ts
+++ b/src/Ombi/ClientApp/src/app/services/message.service.ts
@@ -1,9 +1,11 @@
import { Injectable } from "@angular/core";
import { MatSnackBar, MatSnackBarConfig } from "@angular/material/snack-bar";
+import { TranslateService } from "@ngx-translate/core";
+import { IRequestEngineResult } from "../interfaces/IRequestEngineResult";
@Injectable()
export class MessageService {
- constructor(private snackBar: MatSnackBar) {
+ constructor(private snackBar: MatSnackBar, private translate: TranslateService) {
this.config = {
duration: 4000,
}
@@ -18,4 +20,13 @@ export class MessageService {
this.snackBar.open(message, "OK", this.config)
}
}
+ public sendRequestEngineResultError(result: IRequestEngineResult, action: string = "Ok") {
+ const textKey = 'Requests.ErrorCodes.' + result.errorCode;
+ const text = this.translate.instant(textKey);
+ if (text !== textKey) {
+ this.send(text, action);
+ } else {
+ this.send(result.errorMessage ? result.errorMessage : result.message, action);
+ }
+ }
}
diff --git a/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts b/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts
index 4f02a74b4..7da0fc238 100644
--- a/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts
+++ b/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts
@@ -45,7 +45,7 @@ export class EpisodeRequestComponent {
const viewModel = {
firstSeason: this.data.series.firstSeason, latestSeason: this.data.series.latestSeason, requestAll: this.data.series.requestAll, theMovieDbId: this.data.series.id,
- requestOnBehalf: this.data.requestOnBehalf
+ requestOnBehalf: this.data.requestOnBehalf, languageCode: this.translate.currentLang
};
viewModel.seasons = [];
this.data.series.seasonRequests.forEach((season) => {
@@ -134,7 +134,7 @@ export class EpisodeRequestComponent {
});
} else {
- this.notificationService.send(requestResult.errorMessage ? requestResult.errorMessage : requestResult.message);
+ this.notificationService.sendRequestEngineResultError(requestResult);
}
}
}
diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json
index 959ddaade..ad9ee1ba2 100644
--- a/src/Ombi/wwwroot/translations/en.json
+++ b/src/Ombi/wwwroot/translations/en.json
@@ -37,7 +37,8 @@
"Submit": "Submit",
"Update": "Update",
"tvShow": "TV Show",
- "movie": "Movie"
+ "movie": "Movie",
+ "album": "Album"
},
"PasswordReset": {
"EmailAddressPlaceholder": "Email Address",
@@ -204,7 +205,21 @@
"RequestCollection": "Request Collection",
"CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!",
"NeedToSelectEpisodes": "You need to select some episodes!",
- "RequestAddedSuccessfully": "Request for {{title}} has been added successfully"
+ "RequestAddedSuccessfully": "Request for {{title}} has been added successfully",
+ "ErrorCodes": {
+ "AlreadyRequested": "This has already been requested",
+ "EpisodesAlreadyRequested": "We already have episodes requested from this series",
+ "NoPermissionsOnBehalf":"You do not have the correct permissions to request on behalf of users!",
+ "NoPermissions":"You do not have the correct permissions!",
+ "RequestDoesNotExist":"Request does not exist",
+ "ChildRequestDoesNotExist":"Child Request does not exist",
+ "NoPermissionsRequestMovie":"You do not have permissions to Request a Movie",
+ "NoPermissionsRequestTV":"You do not have permissions to Request a TV Show",
+ "NoPermissionsRequestAlbum":"You do not have permissions to Request an Album",
+ "MovieRequestQuotaExceeded":"You have exceeded your Movie request quota!",
+ "TvRequestQuotaExceeded":"You have exceeded your Episode request quota!",
+ "AlbumRequestQuotaExceeded":"You have exceeded your Album request quota!"
+ }
},
"Issues": {
"Title": "Issues",
@@ -284,9 +299,12 @@
"LanguageProfileSelect":"Select A Language Profile",
"Status":"Status:",
"StatusValues" : {
+ "Rumored" : "Rumored",
"Planned": "Planned",
"In Production": "In Production",
+ "Post Production": "Post Production",
"Released": "Released",
+ "Running": "Running",
"Returning Series": "Returning Series",
"Ended": "Ended",
"Canceled": "Canceled"
@@ -327,7 +345,13 @@
"RequestedBy": "Requested By:",
"RequestDate": "Request Date:",
"DeniedReason": "Denied Reason:",
- "ReProcessRequest": "Re-Process Request"
+ "ReProcessRequest": "Re-Process Request",
+ "Music": {
+ "Type": "Type:",
+ "Country": "Country:",
+ "StartDate": "Start Date:",
+ "EndDate": "EndDate:"
+ }
},
"Discovery": {
"PopularTab": "Popular",