mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 05:13:18 -07:00
Merge branch 'develop' of https://github.com/tidusjar/ombi into develop
This commit is contained in:
commit
c8d49faee5
48 changed files with 3148 additions and 1252 deletions
|
@ -35,7 +35,10 @@ after_build:
|
|||
|
||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.2\linux.tar.gz"
|
||||
|
||||
|
||||
|
||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.2\linux-arm.tar.gz"
|
||||
|
||||
|
||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.2\windows-32bit.zip"
|
||||
|
||||
|
||||
|
|
17
build.cake
17
build.cake
|
@ -47,6 +47,7 @@ var windowsArtifactsFolder = artifactsFolder + "win10-x64/published";
|
|||
var windows32BitArtifactsFolder = artifactsFolder + "win10-x86/published";
|
||||
var osxArtifactsFolder = artifactsFolder + "osx-x64/published";
|
||||
var linuxArtifactsFolder = artifactsFolder + "linux-x64/published";
|
||||
var linuxArmArtifactsFolder = artifactsFolder + "linux-arm/published";
|
||||
var linuxArm64BitArtifactsFolder = artifactsFolder + "linux-arm64/published";
|
||||
|
||||
|
||||
|
@ -149,6 +150,7 @@ Task("Package")
|
|||
Zip(windows32BitArtifactsFolder +"/",artifactsFolder + "windows-32bit.zip");
|
||||
GZipCompress(osxArtifactsFolder, artifactsFolder + "osx.tar.gz");
|
||||
GZipCompress(linuxArtifactsFolder, artifactsFolder + "linux.tar.gz");
|
||||
GZipCompress(linuxArmArtifactsFolder, artifactsFolder + "linux-arm.tar.gz");
|
||||
GZipCompress(linuxArm64BitArtifactsFolder, artifactsFolder + "linux-arm64.tar.gz");
|
||||
});
|
||||
|
||||
|
@ -158,6 +160,7 @@ Task("Publish")
|
|||
.IsDependentOn("Publish-Windows-32bit")
|
||||
.IsDependentOn("Publish-OSX")
|
||||
.IsDependentOn("Publish-Linux")
|
||||
.IsDependentOn("Publish-Linux-ARM")
|
||||
.IsDependentOn("Publish-Linux-ARM-64Bit")
|
||||
.IsDependentOn("Package");
|
||||
|
||||
|
@ -214,6 +217,20 @@ Task("Publish-Linux")
|
|||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||
});
|
||||
|
||||
Task("Publish-Linux-ARM")
|
||||
.Does(() =>
|
||||
{
|
||||
publishSettings.Runtime = "linux-arm";
|
||||
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer+"/linux-arm/published");
|
||||
|
||||
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
||||
CopyFile(
|
||||
buildDir + "/"+frameworkVer+"/linux-arm/Swagger.xml",
|
||||
buildDir + "/"+frameworkVer+"/linux-arm/published/Swagger.xml");
|
||||
|
||||
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer +"/linux-arm/published/updater");
|
||||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||
});
|
||||
|
||||
Task("Publish-Linux-ARM-64Bit")
|
||||
.Does(() =>
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace Ombi.Api.Sonarr.Models
|
|||
public DateTime added { get; set; }
|
||||
public Ratings ratings { get; set; }
|
||||
public int qualityProfileId { get; set; }
|
||||
public int languageProfileId { get; set; }
|
||||
public int id { get; set; }
|
||||
public DateTime nextAiring { get; set; }
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@ namespace Ombi.Core
|
|||
|
||||
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
|
||||
|
||||
Task<IEnumerable<SearchMovieViewModel>> Search(string search);
|
||||
Task<IEnumerable<SearchMovieViewModel>> Search(string search, int? year, string languageCode);
|
||||
|
||||
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
|
||||
|
||||
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
|
||||
|
||||
Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId);
|
||||
Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId, string langCode = "en");
|
||||
|
||||
Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId);
|
||||
}
|
||||
|
|
|
@ -36,14 +36,16 @@ namespace Ombi.Core.Engine
|
|||
private IMapper Mapper { get; }
|
||||
private ILogger<MovieSearchEngine> Logger { get; }
|
||||
|
||||
private const int MovieLimit = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Lookups the imdb information.
|
||||
/// </summary>
|
||||
/// <param name="theMovieDbId">The movie database identifier.</param>
|
||||
/// <returns></returns>
|
||||
public async Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId)
|
||||
public async Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId, string langCode = "en")
|
||||
{
|
||||
var movieInfo = await MovieApi.GetMovieInformationWithExtraInfo(theMovieDbId);
|
||||
var movieInfo = await MovieApi.GetMovieInformationWithExtraInfo(theMovieDbId, langCode);
|
||||
var viewMovie = Mapper.Map<SearchMovieViewModel>(movieInfo);
|
||||
|
||||
return await ProcessSingleMovie(viewMovie, true);
|
||||
|
@ -54,13 +56,13 @@ namespace Ombi.Core.Engine
|
|||
/// </summary>
|
||||
/// <param name="search">The search.</param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> Search(string search)
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> Search(string search, int? year, string langaugeCode)
|
||||
{
|
||||
var result = await MovieApi.SearchMovie(search);
|
||||
var result = await MovieApi.SearchMovie(search, year, langaugeCode);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
|
||||
return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -76,7 +78,7 @@ namespace Ombi.Core.Engine
|
|||
if (result != null)
|
||||
{
|
||||
Logger.LogDebug("Search Result: {result}", result);
|
||||
return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
|
||||
return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -90,7 +92,7 @@ namespace Ombi.Core.Engine
|
|||
var result = await Cache.GetOrAdd(CacheKeys.PopularMovies, async () => await MovieApi.PopularMovies(), DateTime.Now.AddHours(12));
|
||||
if (result != null)
|
||||
{
|
||||
return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
|
||||
return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -104,7 +106,7 @@ namespace Ombi.Core.Engine
|
|||
var result = await Cache.GetOrAdd(CacheKeys.TopRatedMovies, async () => await MovieApi.TopRated(), DateTime.Now.AddHours(12));
|
||||
if (result != null)
|
||||
{
|
||||
return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
|
||||
return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -119,7 +121,7 @@ namespace Ombi.Core.Engine
|
|||
if (result != null)
|
||||
{
|
||||
Logger.LogDebug("Search Result: {result}", result);
|
||||
return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
|
||||
return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -133,7 +135,7 @@ namespace Ombi.Core.Engine
|
|||
var result = await Cache.GetOrAdd(CacheKeys.NowPlayingMovies, async () => await MovieApi.NowPlaying(), DateTime.Now.AddHours(12));
|
||||
if (result != null)
|
||||
{
|
||||
return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
|
||||
return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -348,16 +348,16 @@ namespace Ombi.Core.Senders
|
|||
if (!existingSeason.monitored)
|
||||
{
|
||||
// We need to monitor it, problem being is all episodes will now be monitored
|
||||
// So we need to monior the series but unmonitor every episode
|
||||
// Except the episodes that are already monitored before we update the series (we do not want to unmonitor episodes that are monitored beforehand)
|
||||
// So we need to monitor the series but unmonitor every episode
|
||||
// Except the episodes that are already monitored before we update the series (we do not want to unmonitored episodes that are monitored beforehand)
|
||||
existingSeason.monitored = true;
|
||||
var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber);
|
||||
sea.monitored = true;
|
||||
//var previouslyMonitoredEpisodes = sonarrEpList.Where(x =>
|
||||
// x.seasonNumber == existingSeason.seasonNumber && x.monitored).Select(x => x.episodeNumber).ToList(); // We probably don't actually care about this
|
||||
result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||
var epToUnmonitor = new List<Episode>();
|
||||
var newEpList = sonarrEpList.ConvertAll(ep => new Episode(ep)); // Clone it so we don't modify the orignal member
|
||||
var epToUnmonitored = new List<Episode>();
|
||||
var newEpList = sonarrEpList.ConvertAll(ep => new Episode(ep)); // Clone it so we don't modify the original member
|
||||
foreach (var ep in newEpList.Where(x => x.seasonNumber == existingSeason.seasonNumber).ToList())
|
||||
{
|
||||
//if (previouslyMonitoredEpisodes.Contains(ep.episodeNumber))
|
||||
|
@ -366,10 +366,10 @@ namespace Ombi.Core.Senders
|
|||
// continue;
|
||||
//}
|
||||
ep.monitored = false;
|
||||
epToUnmonitor.Add(ep);
|
||||
epToUnmonitored.Add(ep);
|
||||
}
|
||||
|
||||
foreach (var epToUpdate in epToUnmonitor)
|
||||
foreach (var epToUpdate in epToUnmonitored)
|
||||
{
|
||||
await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri);
|
||||
}
|
||||
|
|
19
src/Ombi.Helpers.Tests/Ombi.Helpers.Tests.csproj
Normal file
19
src/Ombi.Helpers.Tests/Ombi.Helpers.Tests.csproj
Normal file
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="nunit" Version="3.11.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
52
src/Ombi.Helpers.Tests/PlexHelperTests.cs
Normal file
52
src/Ombi.Helpers.Tests/PlexHelperTests.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Helpers.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class PlexHelperTests
|
||||
{
|
||||
|
||||
[TestCaseSource(nameof(ProviderIdGuidData))]
|
||||
public string GetProviderIdFromPlexGuidTests(string guidInput, ProviderIdType type)
|
||||
{
|
||||
var result = PlexHelper.GetProviderIdFromPlexGuid(guidInput);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ProviderIdType.Imdb:
|
||||
Assert.That(result.ImdbId, Is.Not.Null);
|
||||
return result.ImdbId;
|
||||
case ProviderIdType.TvDb:
|
||||
Assert.That(result.TheTvDb, Is.Not.Null);
|
||||
return result.TheTvDb;
|
||||
case ProviderIdType.MovieDb:
|
||||
Assert.That(result.TheMovieDb, Is.Not.Null);
|
||||
return result.TheMovieDb;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<TestCaseData> ProviderIdGuidData
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData("com.plexapp.agents.thetvdb://269586/2/8?lang=en", ProviderIdType.TvDb).Returns("269586").SetName("Regular TvDb Id");
|
||||
yield return new TestCaseData("com.plexapp.agents.themoviedb://390043?lang=en", ProviderIdType.MovieDb).Returns("390043").SetName("Regular MovieDb Id");
|
||||
yield return new TestCaseData("com.plexapp.agents.imdb://tt2543164?lang=en", ProviderIdType.Imdb).Returns("tt2543164").SetName("Regular Imdb Id");
|
||||
yield return new TestCaseData("com.plexapp.agents.agent47://tt2543456?lang=en", ProviderIdType.Imdb).Returns("tt2543456").SetName("Unknown IMDB agent");
|
||||
yield return new TestCaseData("com.plexapp.agents.agent47://456822/1/1?lang=en", ProviderIdType.TvDb).Returns("456822").SetName("Unknown TvDb agent");
|
||||
yield return new TestCaseData("com.plexapp.agents.agent47://456822/999/999?lang=en", ProviderIdType.TvDb).Returns("456822").SetName("Unknown TvDb agent, large episode and season");
|
||||
}
|
||||
}
|
||||
|
||||
public enum ProviderIdType
|
||||
{
|
||||
Imdb,
|
||||
TvDb,
|
||||
MovieDb
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,12 +27,15 @@
|
|||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Ombi.Helpers
|
||||
{
|
||||
public class PlexHelper
|
||||
{
|
||||
|
||||
private const string ImdbMatchExpression = "tt([0-9]{1,10})";
|
||||
private const string TvDbIdMatchExpression = "//[0-9]+/([0-9]{1,3})/([0-9]{1,3})";
|
||||
|
||||
public static ProviderId GetProviderIdFromPlexGuid(string guid)
|
||||
{
|
||||
//com.plexapp.agents.thetvdb://269586/2/8?lang=en
|
||||
|
@ -52,7 +55,7 @@ namespace Ombi.Helpers
|
|||
{
|
||||
TheTvDb = guidSplit[1]
|
||||
};
|
||||
}
|
||||
} else
|
||||
if (guid.Contains("themoviedb", CompareOptions.IgnoreCase))
|
||||
{
|
||||
return new ProviderId
|
||||
|
@ -60,6 +63,7 @@ namespace Ombi.Helpers
|
|||
TheMovieDb = guidSplit[1]
|
||||
};
|
||||
}
|
||||
else
|
||||
if (guid.Contains("imdb", CompareOptions.IgnoreCase))
|
||||
{
|
||||
return new ProviderId
|
||||
|
@ -67,6 +71,31 @@ namespace Ombi.Helpers
|
|||
ImdbId = guidSplit[1]
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var imdbRegex = new Regex(ImdbMatchExpression, RegexOptions.Compiled);
|
||||
var tvdbRegex = new Regex(TvDbIdMatchExpression, RegexOptions.Compiled);
|
||||
var imdbMatch = imdbRegex.IsMatch(guid);
|
||||
if (imdbMatch)
|
||||
{
|
||||
return new ProviderId
|
||||
{
|
||||
ImdbId = guidSplit[1]
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if it matches the TvDb pattern
|
||||
var tvdbMatch = tvdbRegex.IsMatch(guid);
|
||||
if (tvdbMatch)
|
||||
{
|
||||
return new ProviderId
|
||||
{
|
||||
TheTvDb = guidSplit[1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ProviderId();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
<!doctype html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Ombi</title>
|
||||
<style type="text/css">
|
||||
<style>
|
||||
/* -------------------------------------
|
||||
GLOBAL RESETS
|
||||
------------------------------------- */
|
||||
|
||||
/*All the styling goes here*/
|
||||
|
||||
img {
|
||||
border: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
|
@ -12,6 +19,7 @@
|
|||
}
|
||||
|
||||
body {
|
||||
background-color: #1f1f1f;
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
|
@ -20,6 +28,8 @@
|
|||
padding: 0;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
|
@ -31,39 +41,54 @@
|
|||
|
||||
table td {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
BODY & CONTAINER
|
||||
------------------------------------- */
|
||||
|
||||
.body {
|
||||
color: #FFF;
|
||||
background-color: #1f1f1f;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
|
||||
|
||||
.container {
|
||||
display: block;
|
||||
margin: 0 auto !important;
|
||||
max-width: 1042px;
|
||||
Margin: 0 auto !important;
|
||||
/* makes it centered */
|
||||
max-width: 1036px;
|
||||
padding: 10px;
|
||||
width: 1042px;
|
||||
width: 1036px;
|
||||
}
|
||||
|
||||
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
Margin: 0 auto;
|
||||
max-width: 1037px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
HEADER, FOOTER, MAIN
|
||||
------------------------------------- */
|
||||
|
||||
.main {
|
||||
color: #FFF;
|
||||
background: #1f1f1f;
|
||||
border-radius: 3px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.content-block {
|
||||
|
@ -71,58 +96,241 @@
|
|||
padding-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
.media-card {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
vertical-align: top;
|
||||
padding: 3px;
|
||||
width: 500px;
|
||||
min-width: 500px;
|
||||
max-width: 500px;
|
||||
height: 252px;
|
||||
max-height: 252px;
|
||||
min-height: 252px;
|
||||
}
|
||||
|
||||
.card-bg {
|
||||
background-image: url({0});
|
||||
border-collapse: separate;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
width: 500px;
|
||||
background-color: #1f1f1f;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-clip: padding-box;
|
||||
border: 2px solid rgba(255, 118, 27, .4);
|
||||
height: 252px;
|
||||
max-height: 252px;
|
||||
}
|
||||
|
||||
.bg-tint {
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
}
|
||||
|
||||
.poster-container {
|
||||
vertical-align: top;
|
||||
width: 150px;
|
||||
min-width: 150px;
|
||||
height: 225px;
|
||||
max-height: 225px;
|
||||
min-height: 225px;
|
||||
}
|
||||
|
||||
.poster-img {}
|
||||
|
||||
.poster-overlay {}
|
||||
|
||||
.movie-info {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
vertical-align: top;
|
||||
padding-left: 4px;
|
||||
text-align: left;
|
||||
height: 227px;
|
||||
}
|
||||
|
||||
.title h1 {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-size: 22px;
|
||||
line-height: 24px;
|
||||
vertical-align: top;
|
||||
max-width: 320px;
|
||||
white-space: normal;
|
||||
display: block;
|
||||
height: 50px;
|
||||
min-height: 50px;
|
||||
max-height: 50px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
height: 130px;
|
||||
max-height: 130px;
|
||||
max-width: 320px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
font-size: 14px !important;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.meta {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
max-width: 300px;
|
||||
min-width: 300px;
|
||||
padding: 3px 7px;
|
||||
margin-top: 10px;
|
||||
font-size: 14px !important;
|
||||
line-height: 1;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
background-color: rgba(255, 118, 27, 0.5);
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.footer {
|
||||
clear: both;
|
||||
margin-top: 10px;
|
||||
Margin-top: 10px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footer td,
|
||||
.footer p,
|
||||
.footer span,
|
||||
.footer a {
|
||||
color: #fff;
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #ffffff;
|
||||
/* -------------------------------------
|
||||
TYPOGRAPHY
|
||||
------------------------------------- */
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
color: #ff761b;
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
color: #ff761b;
|
||||
font-size: 22px;
|
||||
line-height: 24px;
|
||||
margin: 0 auto;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
p {
|
||||
p,
|
||||
ul,
|
||||
ol {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p li,
|
||||
ul li {
|
||||
ul li,
|
||||
ol li {
|
||||
list-style-position: inside;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ff761b !important;
|
||||
text-decoration: none;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
OTHER STYLES THAT MIGHT BE USEFUL
|
||||
------------------------------------- */
|
||||
|
||||
.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.mt0 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.mb0 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.preheader {
|
||||
color: transparent;
|
||||
display: none;
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
mso-hide: all;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.powered-by a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1040px) {
|
||||
.media-card {
|
||||
display: block !important;
|
||||
margin-top: 0 !important;
|
||||
margin-right: auto !important;
|
||||
margin-bottom: 10px !important;
|
||||
margin-left: auto !important;
|
||||
hr {
|
||||
border: 0;
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
Margin: 20px 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||
------------------------------------- */
|
||||
|
||||
@media only screen and (max-width: 1059px) {
|
||||
table[class=body] h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
table[class=body] h1 {
|
||||
font-size: 28px !important;
|
||||
table[class=body] p,
|
||||
table[class=body] ul,
|
||||
table[class=body] ol,
|
||||
table[class=body] td,
|
||||
table[class=body] span,
|
||||
table[class=body] a {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
table[class=body] .wrapper,
|
||||
table[class=body] .article {
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
table[class=body] .content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
table[class=body] .container {
|
||||
|
@ -135,9 +343,52 @@
|
|||
border-radius: 0 !important;
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
|
||||
table[class=body] .btn table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table[class=body] .btn a {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table[class=body] .img-responsive {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.media-card {
|
||||
display: flex !important;
|
||||
margin-top: 0 !important;
|
||||
margin-right: auto !important;
|
||||
margin-bottom: 10px !important;
|
||||
margin-left: auto !important;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
width: 500px !important;
|
||||
max-width: 500px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
PRESERVE THESE STYLES IN THE HEAD
|
||||
------------------------------------- */
|
||||
|
||||
@media all {
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.apple-link a {
|
||||
color: inherit !important;
|
||||
font-family: inherit !important;
|
||||
|
@ -146,66 +397,78 @@
|
|||
line-height: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.btn-primary table td:hover {
|
||||
background-color: #34495e !important;
|
||||
}
|
||||
|
||||
.btn-primary a:hover {
|
||||
background-color: #34495e !important;
|
||||
border-color: #34495e !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body class="" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;font-size: 14px;line-height: 1.4;margin: 0;padding: 0;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%; background-color: #1f1f1f; color: #fff;">
|
||||
<tr>
|
||||
<td class="container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;display: block;max-width: 1042px;padding: 10px;width: 1042px;margin: 0 auto !important;">
|
||||
<div class="content" style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 1037px; padding: 10px;">
|
||||
|
||||
<!-- START CENTERED WHITE CONTAINER -->
|
||||
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Ombi Recently Added</span>
|
||||
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-radius: 3px;">
|
||||
|
||||
<!-- START MAIN CONTENT AREA -->
|
||||
<tr>
|
||||
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;" valign="top">
|
||||
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; max-width: 1042px; width: 100%;">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="{@LOGO}" width="400px" text-align="center"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top">
|
||||
<br />
|
||||
<br />
|
||||
<p style="color: #fff; font-family: sans-serif; font-size: 20px; font-weight: normal; margin: 0; Margin-bottom: 15px; text-align: center;">{@INTRO}</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@RECENTLYADDED}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- END MAIN CONTENT AREA -->
|
||||
</table>
|
||||
|
||||
<!-- START FOOTER -->
|
||||
<div class="footer" style="clear: both; padding-top: 10px; text-align: center; width: 100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
||||
<tr>
|
||||
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-top: 10px; padding-bottom: 10px; font-size: 12px; color: #999999; text-align: center;" valign="top" align="center">
|
||||
Powered by <a href="https://github.com/tidusjar/Ombi" style="color: #999999; font-size: 12px; text-align: center; text-decoration: underline;">Ombi</a>
|
||||
</td>
|
||||
</tr>
|
||||
<body class="" style="background-color: #1f1f1f; font-family: 'Open Sans', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #FFF; text-align: center;">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body" width="100%" bgcolor="#1f1f1f" align="center" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #FFF; background-color: #1f1f1f; width: 100%; text-align: center;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="container" width="1036" valign="top" style="font-family: sans-serif; font-size: 14px; vertical-align: top; max-width: 1036px; padding: 10px; width: 1036px; Margin: 0 auto;">
|
||||
<div class="content" style="box-sizing: border-box; Margin: 0 auto; max-width: 1037px; padding: 10px;">
|
||||
<!-- START CENTERED WHITE CONTAINER -->
|
||||
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Ombi recently added</span>
|
||||
<table role="presentation" class="main" width="100%" align="center" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #FFF; background: #1f1f1f; border-radius: 3px; width: 100%; text-align: center;">
|
||||
<!-- START MAIN CONTENT AREA -->
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="wrapper" valign="top" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif; vertical-align: top;">
|
||||
<img src="{@LOGO}" style="border: none; -ms-interpolation-mode: bicubic; max-width: 100%;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif; vertical-align: top;">
|
||||
<p style="font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: normal; margin: 0; margin-bottom: 15px;">{@INTRO}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif; vertical-align: top;">
|
||||
{@RECENTLYADDED}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- END MAIN CONTENT AREA -->
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- START FOOTER -->
|
||||
<div class="footer" style="clear: both; Margin-top: 10px; text-align: center; width: 100%;">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="content-block powered-by" valign="top" align="center" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #999999; font-size: 12px; text-align: center;">
|
||||
Powered by <a href="https://github.com/tidusjar/Ombi" style="font-weight: 400; font-size: 12px; text-align: center; text-decoration: none; color: #ff761b;">Ombi</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- END FOOTER -->
|
||||
<!-- END CENTERED WHITE CONTAINER -->
|
||||
</div>
|
||||
|
||||
<!-- END FOOTER -->
|
||||
<!-- END CENTERED WHITE CONTAINER -->
|
||||
</div>
|
||||
</td>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top"> </td>
|
||||
</tr>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -17,10 +17,6 @@ namespace Ombi.Notifications
|
|||
public void Setup(NotificationOptions opts, FullBaseRequest req, CustomizationSettings s, UserNotificationPreferences pref)
|
||||
{
|
||||
LoadIssues(opts);
|
||||
if (pref != null)
|
||||
{
|
||||
UserPreference = pref.Value;
|
||||
}
|
||||
|
||||
string title;
|
||||
if (req == null)
|
||||
|
@ -41,6 +37,10 @@ namespace Ombi.Notifications
|
|||
}
|
||||
|
||||
Alias = (req?.RequestedUser?.Alias.HasValue() ?? false) ? req?.RequestedUser?.Alias : req?.RequestedUser?.UserName;
|
||||
if (pref != null)
|
||||
{
|
||||
UserPreference = pref.Enabled ? pref.Value : Alias;
|
||||
}
|
||||
Title = title;
|
||||
RequestedDate = req?.RequestedDate.ToString("D");
|
||||
if (Type.IsNullOrEmpty())
|
||||
|
@ -50,6 +50,7 @@ namespace Ombi.Notifications
|
|||
Overview = req?.Overview;
|
||||
Year = req?.ReleaseDate.Year.ToString();
|
||||
DenyReason = req?.DeniedReason;
|
||||
AvailableDate = req?.MarkedAsAvailable?.ToString("D") ?? string.Empty;
|
||||
if (req?.RequestType == RequestType.Movie)
|
||||
{
|
||||
PosterImage = string.Format((req?.PosterPath ?? string.Empty).StartsWith("/", StringComparison.InvariantCultureIgnoreCase)
|
||||
|
@ -66,10 +67,7 @@ namespace Ombi.Notifications
|
|||
public void Setup(NotificationOptions opts, AlbumRequest req, CustomizationSettings s, UserNotificationPreferences pref)
|
||||
{
|
||||
LoadIssues(opts);
|
||||
if (pref != null)
|
||||
{
|
||||
UserPreference = pref.Enabled ? pref.Value : string.Empty;
|
||||
}
|
||||
|
||||
string title;
|
||||
if (req == null)
|
||||
{
|
||||
|
@ -88,8 +86,13 @@ namespace Ombi.Notifications
|
|||
UserName = req?.RequestedUser?.UserName;
|
||||
}
|
||||
|
||||
AvailableDate = req?.MarkedAsAvailable?.ToString("D") ?? string.Empty;
|
||||
DenyReason = req?.DeniedReason;
|
||||
Alias = (req?.RequestedUser?.Alias.HasValue() ?? false) ? req?.RequestedUser?.Alias : req?.RequestedUser?.UserName;
|
||||
if (pref != null)
|
||||
{
|
||||
UserPreference = pref.Enabled ? pref.Value : Alias;
|
||||
}
|
||||
Title = title;
|
||||
RequestedDate = req?.RequestedDate.ToString("D");
|
||||
if (Type.IsNullOrEmpty())
|
||||
|
@ -114,10 +117,6 @@ namespace Ombi.Notifications
|
|||
public void Setup(NotificationOptions opts, ChildRequests req, CustomizationSettings s, UserNotificationPreferences pref)
|
||||
{
|
||||
LoadIssues(opts);
|
||||
if (pref != null)
|
||||
{
|
||||
UserPreference = pref.Enabled ? pref.Value : string.Empty;
|
||||
}
|
||||
string title;
|
||||
if (req == null)
|
||||
{
|
||||
|
@ -136,7 +135,12 @@ namespace Ombi.Notifications
|
|||
// Can be set if it's an issue
|
||||
UserName = req?.RequestedUser?.UserName;
|
||||
}
|
||||
AvailableDate = req?.MarkedAsAvailable?.ToString("D") ?? string.Empty;
|
||||
Alias = (req?.RequestedUser?.Alias.HasValue() ?? false) ? req?.RequestedUser?.Alias : req?.RequestedUser?.UserName;
|
||||
if (pref != null)
|
||||
{
|
||||
UserPreference = pref.Enabled ? pref.Value : Alias;
|
||||
}
|
||||
Title = title;
|
||||
RequestedDate = req?.RequestedDate.ToString("D");
|
||||
if (Type.IsNullOrEmpty())
|
||||
|
@ -237,6 +241,7 @@ namespace Ombi.Notifications
|
|||
public string NewIssueComment { get; set; }
|
||||
public string UserPreference { get; set; }
|
||||
public string DenyReason { get; set; }
|
||||
public string AvailableDate { get; set; }
|
||||
|
||||
// System Defined
|
||||
private string LongDate => DateTime.Now.ToString("D");
|
||||
|
@ -272,6 +277,7 @@ namespace Ombi.Notifications
|
|||
{nameof(Alias),Alias},
|
||||
{nameof(UserPreference),UserPreference},
|
||||
{nameof(DenyReason),DenyReason},
|
||||
{nameof(AvailableDate),AvailableDate},
|
||||
};
|
||||
}
|
||||
}
|
|
@ -7,18 +7,18 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
protected virtual void AddBackgroundInsideTable(StringBuilder sb, string url)
|
||||
{
|
||||
sb.Append("<td align=\"center\" valign=\"top\" class=\"media-card\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 12px; vertical-align: top; padding: 3px; width: 502px; min-width: 500px; max-width: 500px; height: 235px; \">");
|
||||
sb.AppendFormat("<table class=\"card-bg\" style=\"background-image: url({0}); border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 500px; background-color: #1f1f1f; background-position: center; background-size: cover; background-repeat: no-repeat; background-clip: padding-box; border: 2px solid rgba(255,118,27,.4); height: 248px; max-height: 500px; \">", url);
|
||||
sb.Append("<td align=\"center\" valign=\"top\" width=\"500\" height=\"252\" class=\"media-card\" style=\"font-size: 14px; font-family: 'Open Sans', Helvetica, Arial, sans-serif; vertical-align: top; padding: 3px; width: 500px; min-width: 500px; max-width: 500px; height: 252px; max-height: 252px; \">");
|
||||
sb.AppendFormat("<table class=\"card-bg\" width=\"500\" height=\"252\" background=\"url(0)\" bgcolor=\"#1f1f1f\" style=\"background-image: url(0); border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 500px; background-color: #1f1f1f; background-position: center; background-size: cover; background-repeat: no-repeat; background-clip: padding-box; border: 2px solid rgba(255, 118, 27, .4); height: 252px; max-height: 252px; \">", url);
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td>");
|
||||
sb.Append("<table class=\"bg-tint\" style=\"background-color: rgba(0, 0, 0, .6); position: absolute; width: 490px; height: 239px; \">");
|
||||
sb.Append("<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">");
|
||||
sb.Append("<table class=\"bg-tint\" width=\"100%\" bgcolor=\"rgba(0, 0, 0, .6)\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: rgba(0, 0, 0, .6); \">");
|
||||
}
|
||||
|
||||
protected virtual void AddPosterInsideTable(StringBuilder sb, string url)
|
||||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td class=\"poster-container\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; width: 150px; min-width: 15px; height: 225px; \">");
|
||||
sb.AppendFormat("<table class=\"poster-img\" style=\"background-image: url({0}); border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: transparent; background-position: center; background-size: cover; background-repeat: no-repeat; background-clip: padding-box; border: 1px solid rgba(255,255,255,.1); \">", url);
|
||||
sb.Append("<td class=\"poster-container\" width=\"150\" height=\"225\" valign=\"top\" style=\"ont-family: sans-serif; font-size: 14px; vertical-align: top; width: 150px; min-width: 150px; height: 225px; max-height: 225px; min-height: 225px; \">");
|
||||
sb.AppendFormat("<table class=\"poster-img\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">", url);
|
||||
}
|
||||
|
||||
protected virtual void AddMediaServerUrl(StringBuilder sb, string mediaurl, string url)
|
||||
|
@ -27,10 +27,10 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append(
|
||||
"<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
"<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
sb.AppendFormat("<a href=\"{0}\" target=\"_blank\">", mediaurl);
|
||||
sb.AppendFormat(
|
||||
"<img class=\"poster-overlay\" src=\"{0}\" width=\"150\" height=\"225\" style=\"border: none;-ms-interpolation-mode: bicubic; max-width: 100%;display: block; visibility: hidden; \">",
|
||||
"<img class=\"poster-overlay\" src=\"{0}\" width=\"150\" height=\"225\" style=\"border: none; -ms-interpolation-mode: bicubic; max-width: 100%; \">",
|
||||
url);
|
||||
sb.Append("</a>");
|
||||
sb.Append("</td>");
|
||||
|
@ -44,16 +44,16 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
protected virtual void AddInfoTable(StringBuilder sb)
|
||||
{
|
||||
sb.Append(
|
||||
"<td class=\"movie-info\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; padding-left: 4px; text-align: left; height: 227px; \">");
|
||||
"<td class=\"movie-info\" height=\"227\" valign=\"top\" align=\"left\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; padding-left: 4px; text-align: left; height: 227px; \">");
|
||||
sb.Append("<table style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; height: 100%; \">");
|
||||
}
|
||||
|
||||
protected virtual void AddTitle(StringBuilder sb, string url, string title)
|
||||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td class=\"title\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 0.9rem; vertical-align: top; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; line-height: 1.2rem; padding: 5px; \">");
|
||||
if(url.HasValue()) sb.AppendFormat("<a href=\"{0}\" target=\"_blank\">", url);
|
||||
sb.AppendFormat("<h1 style=\"white-space: normal; line-height: 1;\" >{0}</h1>", title);
|
||||
sb.Append("<tr class=\"title\" valign=\"top\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 22px;line-height: 24px;vertical-align: top;max-width: 320px;display: block;height: 50px;min-height: 50px;max-height: 50px; \">");
|
||||
sb.Append("<td>");
|
||||
if(url.HasValue()) sb.AppendFormat("<a href=\"{0}\" target=\"_blank\" style=\"text-decoration: none; font-weight: 400; color: #ff761b;\">", url);
|
||||
sb.AppendFormat("<h1 style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 22px;line-height: 24px;vertical-align: top;max-width: 320px;display: block;height: 50px;min-height: 50px;max-height: 50px;\" >{0}</h1>", title);
|
||||
if (url.HasValue()) sb.Append("</a>");
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
|
@ -61,30 +61,30 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
|
||||
protected virtual void AddParagraph(StringBuilder sb, string text)
|
||||
{
|
||||
sb.Append("<tr class=\"description\">");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 0.75rem; vertical-align: top; padding: 5px; height: 100%; \">");
|
||||
sb.AppendFormat("<p style=\"color: #fff; font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0; max-width: 325px; text-align: justify; \">{0}</p>", text);
|
||||
sb.Append("<tr class=\"description\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif;height: 130px;max-height: 130px;max-width: 320px;overflow: hidden;text-overflow: ellipsis;display: block;font-size: 14px !important;text-align: justify;\" valign=\"top\">");
|
||||
sb.Append("<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
sb.AppendFormat("<p style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: normal; margin: 0; margin-bottom: 15px; \">{0}</p>", text);
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void AddTvParagraph(StringBuilder sb, string episodes, string summary)
|
||||
{
|
||||
sb.Append("<tr class=\"description\">");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 0.75rem; vertical-align: top; padding: 5px; height: 100%; \">");
|
||||
sb.AppendFormat("<p style=\"color: #fff; font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0; max-width: 325px; margin-bottom: 10px; \">{0}</p>", episodes);
|
||||
sb.AppendFormat("<div style=\"color: #fff; font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0; max-width: 325px; overflow: hidden; text-align: justify; \">{0}</div>", summary);
|
||||
sb.Append("<tr class=\"description\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif;height: 130px;max-height: 130px;max-width: 320px;overflow: hidden;text-overflow: ellipsis;display: block;font-size: 14px !important;text-align: justify;\" valign=\"top\">");
|
||||
sb.Append("<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
sb.AppendFormat("<p style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: normal; margin: 0; margin-bottom: 15px; \">{0}</p>", episodes);
|
||||
sb.AppendFormat("<div>{0}</div>", summary);
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void AddGenres(StringBuilder sb, string text)
|
||||
{
|
||||
sb.Append("<tr class=\"meta\">");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; max-width: 265px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; \">");
|
||||
sb.AppendFormat("<span style=\"display: inline-block; min-width: 10px; padding: 3px 7px; font-size: 11px; line-height: 1; text-align: center; white-space: nowrap; vertical-align: middle; background-color: rgba(255, 118, 27, 0.5); color: #fff; border-radius: 2px; text-overflow: ellipsis; overflow: hidden; \">{0}</span>", text);
|
||||
sb.Append("<tr class=\"meta\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; max-width: 300px; min-width: 300px; padding: 3px 7px; margin-top: 10px; line-height: 1; text-align: left; white-space: nowrap; vertical-align: middle; background-color: rgba(255, 118, 27, 0.5); color: #fff; border-radius: 2px; overflow: hidden; display: block; font-size: 0.9rem;\" align=\"left\" valign=\"middle\" bgcolor=\"rgba(255, 118, 27, 0.5)\">");
|
||||
sb.Append("<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
sb.AppendFormat("<span>{0}</span>", text);
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{
|
||||
public string BaseUrl { get; set; }
|
||||
public bool CollectAnalyticData { get; set; }
|
||||
public bool Set { get; set; }
|
||||
public bool Wizard { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
public bool IgnoreCertificateErrors { get; set; }
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Ombi.Store.Context;
|
||||
|
||||
namespace Ombi.Store.Migrations
|
||||
|
@ -14,7 +13,7 @@ namespace Ombi.Store.Migrations
|
|||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.4-rtm-31024");
|
||||
.HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
|
@ -530,6 +529,24 @@ namespace Ombi.Store.Migrations
|
|||
b.ToTable("RequestQueue");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("RequestId");
|
||||
|
||||
b.Property<int>("RequestType");
|
||||
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("RequestSubscription");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -800,24 +817,6 @@ namespace Ombi.Store.Migrations
|
|||
b.ToTable("TvRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("RequestId");
|
||||
|
||||
b.Property<int>("RequestType");
|
||||
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("RequestSubscription");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -1082,6 +1081,13 @@ namespace Ombi.Store.Migrations
|
|||
.HasForeignKey("PlexServerContentId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||
|
@ -1146,13 +1152,6 @@ namespace Ombi.Store.Migrations
|
|||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Ombi.Store.Migrations.Settings
|
|||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.3-rtm-32065");
|
||||
.HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b =>
|
||||
{
|
||||
|
|
|
@ -8,10 +8,10 @@ namespace Ombi.Api.TheMovieDb
|
|||
public interface IMovieDbApi
|
||||
{
|
||||
Task<MovieResponseDto> GetMovieInformation(int movieId);
|
||||
Task<MovieResponseDto> GetMovieInformationWithExtraInfo(int movieId);
|
||||
Task<MovieResponseDto> GetMovieInformationWithExtraInfo(int movieId, string langCode = "en");
|
||||
Task<List<MovieSearchResult>> NowPlaying();
|
||||
Task<List<MovieSearchResult>> PopularMovies();
|
||||
Task<List<MovieSearchResult>> SearchMovie(string searchTerm);
|
||||
Task<List<MovieSearchResult>> SearchMovie(string searchTerm, int? year, string languageCode);
|
||||
Task<List<TvSearchResult>> SearchTv(string searchTerm);
|
||||
Task<List<MovieSearchResult>> TopRated();
|
||||
Task<List<MovieSearchResult>> Upcoming();
|
||||
|
|
|
@ -73,21 +73,27 @@ namespace Ombi.Api.TheMovieDb
|
|||
return Mapper.Map<List<MovieSearchResult>>(result.results);
|
||||
}
|
||||
|
||||
public async Task<MovieResponseDto> GetMovieInformationWithExtraInfo(int movieId)
|
||||
public async Task<MovieResponseDto> GetMovieInformationWithExtraInfo(int movieId, string langCode = "en")
|
||||
{
|
||||
var request = new Request($"movie/{movieId}", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("append_to_response", "videos,release_dates");
|
||||
request.FullUri = request.FullUri.AddQueryParameter("language", langCode);
|
||||
AddRetry(request);
|
||||
var result = await Api.Request<MovieResponse>(request);
|
||||
return Mapper.Map<MovieResponseDto>(result);
|
||||
}
|
||||
|
||||
public async Task<List<MovieSearchResult>> SearchMovie(string searchTerm)
|
||||
public async Task<List<MovieSearchResult>> SearchMovie(string searchTerm, int? year, string langageCode)
|
||||
{
|
||||
var request = new Request($"search/movie", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("query", searchTerm);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("language", langageCode);
|
||||
if (year.HasValue && year.Value > 0)
|
||||
{
|
||||
request.FullUri = request.FullUri.AddQueryParameter("year", year.Value.ToString());
|
||||
}
|
||||
AddRetry(request);
|
||||
|
||||
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
|
||||
|
|
|
@ -94,7 +94,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.SickRage", "Ombi.A
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Notifications", "Ombi.Api.Notifications\Ombi.Api.Notifications.csproj", "{10D1FE9D-9124-42B7-B1E1-CEB99B832618}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Lidarr", "Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj", "{4FA21A20-92F4-462C-B929-2C517A88CC56}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Lidarr", "Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj", "{4FA21A20-92F4-462C-B929-2C517A88CC56}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Helpers.Tests", "Ombi.Helpers.Tests\Ombi.Helpers.Tests.csproj", "{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -250,6 +252,10 @@ Global
|
|||
{4FA21A20-92F4-462C-B929-2C517A88CC56}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4FA21A20-92F4-462C-B929-2C517A88CC56}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4FA21A20-92F4-462C-B929-2C517A88CC56}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -286,6 +292,7 @@ Global
|
|||
{94C9A366-2595-45EA-AABB-8E4A2E90EC5B} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{10D1FE9D-9124-42B7-B1E1-CEB99B832618} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{4FA21A20-92F4-462C-B929-2C517A88CC56} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
background: any;
|
||||
}
|
||||
|
||||
export interface ILanguageRefine {
|
||||
code: string;
|
||||
name: string;
|
||||
nativeName: string;
|
||||
}
|
||||
|
||||
export interface ISearchMovieResultContainer {
|
||||
movies: ISearchMovieResult[];
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ export class MusicRequestsComponent implements OnInit {
|
|||
public rejectionReason: string;
|
||||
|
||||
public totalAlbums: number = 100;
|
||||
private currentlyLoaded: number;
|
||||
public currentlyLoaded: number;
|
||||
private amountToLoad: number;
|
||||
|
||||
constructor(
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<!-- Movie tab -->
|
||||
<div role="tabpanel" class="tab-pane active" id="MoviesTab">
|
||||
|
||||
<div class="input-group">
|
||||
<div class="input-group search-bar-background">
|
||||
<input id="search" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons"
|
||||
(keyup)="search($event)">
|
||||
<div class="input-group-addon right-radius">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" role="group">
|
||||
<a href="#" class="btn btn-sm btn-primary-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
||||
{{ 'Search.Suggestions' | translate }}
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
|
@ -16,10 +16,43 @@
|
|||
<li><a (click)="topRatedMovies()" [translate]="'Search.Movies.TopRatedMovies'"></a></li>
|
||||
<li><a (click)="nowPlayingMovies()" [translate]="'Search.Movies.NowPlayingMovies'"></a></li>
|
||||
</ul>
|
||||
<button class="btn btn-sm btn-primary-outline" (click)="refineOpen()">
|
||||
{{ 'Search.Refine' | translate }}
|
||||
<i class="fa" [ngClass]="{'fa-chevron-down': !refineSearchEnabled, 'fa-chevron-up': refineSearchEnabled}"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<i class="fa fa-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Refine search options -->
|
||||
<div class="row top-spacing form-group vcenter" *ngIf="refineSearchEnabled">
|
||||
<div class="col-md-1">
|
||||
<div class="form-group">
|
||||
<label class="control-label">Year</label>
|
||||
|
||||
<input [(ngModel)]="searchYear" class="form-control form-control-custom refine-option">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <label for="name" class="col-xs-2 col-md-1">Language:</label> -->
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label for="select" class="control-label">Language</label>
|
||||
<div id="profiles">
|
||||
<select [(ngModel)]="selectedLanguage" class="form-control form-control-custom refine-option"
|
||||
id="select">
|
||||
<option *ngFor="let lang of langauges" value="{{lang.code}}">{{lang.nativeName}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<button class="btn pull-right btn-success-outline" (click)="applyRefinedSearch()">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<remaining-requests [movie]="true" [quotaRefreshEvents]="movieRequested.asObservable()" #remainingFilms></remaining-requests>
|
||||
|
||||
|
@ -111,11 +144,15 @@
|
|||
|
||||
<br />
|
||||
<div *ngIf="result.available">
|
||||
<a *ngIf="result.plexUrl" style="text-align: right" class="btn btn-sm btn-success-outline" href="{{result.plexUrl}}" target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnPlex' | translate}}</a>
|
||||
<a *ngIf="result.embyUrl" style="text-align: right" id="embybtn" class="btn btn-sm btn-success-outline" href="{{result.embyUrl}}" target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnEmby' | translate}}</a>
|
||||
<a *ngIf="result.plexUrl" style="text-align: right" class="btn btn-sm btn-success-outline" href="{{result.plexUrl}}"
|
||||
target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnPlex' | translate}}</a>
|
||||
<a *ngIf="result.embyUrl" style="text-align: right" id="embybtn" class="btn btn-sm btn-success-outline"
|
||||
href="{{result.embyUrl}}" target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnEmby' |
|
||||
translate}}</a>
|
||||
</div>
|
||||
<div class="dropdown" *ngIf="result.available && issueCategories && issuesEnabled">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> {{'Requests.ReportIssue' | translate}}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
|
|
|
@ -6,12 +6,15 @@ import { Subject } from "rxjs";
|
|||
import { debounceTime, distinctUntilChanged } from "rxjs/operators";
|
||||
|
||||
import { AuthService } from "../auth/auth.service";
|
||||
import { IIssueCategory, IRequestEngineResult, ISearchMovieResult } from "../interfaces";
|
||||
import { IIssueCategory, ILanguageRefine, IRequestEngineResult, ISearchMovieResult } from "../interfaces";
|
||||
import { NotificationService, RequestService, SearchService } from "../services";
|
||||
|
||||
import * as languageData from "../../other/iso-lang.json";
|
||||
|
||||
@Component({
|
||||
selector: "movie-search",
|
||||
templateUrl: "./moviesearch.component.html",
|
||||
styleUrls: ["./search.component.scss"],
|
||||
})
|
||||
export class MovieSearchComponent implements OnInit {
|
||||
|
||||
|
@ -22,6 +25,10 @@ export class MovieSearchComponent implements OnInit {
|
|||
public result: IRequestEngineResult;
|
||||
|
||||
public searchApplied = false;
|
||||
public refineSearchEnabled = false;
|
||||
public searchYear?: number;
|
||||
public selectedLanguage: string;
|
||||
public langauges: ILanguageRefine[];
|
||||
|
||||
@Input() public issueCategories: IIssueCategory[];
|
||||
@Input() public issuesEnabled: boolean;
|
||||
|
@ -37,23 +44,13 @@ export class MovieSearchComponent implements OnInit {
|
|||
private notificationService: NotificationService, private authService: AuthService,
|
||||
private readonly translate: TranslateService, private sanitizer: DomSanitizer,
|
||||
private readonly platformLocation: PlatformLocation) {
|
||||
this.langauges = <ILanguageRefine[]><any>languageData;
|
||||
this.searchChanged.pipe(
|
||||
debounceTime(600), // Wait Xms after the last event before emitting last event
|
||||
distinctUntilChanged(), // only emit if value is different from previous value
|
||||
).subscribe(x => {
|
||||
this.searchText = x as string;
|
||||
if (this.searchText === "") {
|
||||
this.clearResults();
|
||||
return;
|
||||
}
|
||||
this.searchService.searchMovie(this.searchText)
|
||||
.subscribe(x => {
|
||||
this.movieResults = x;
|
||||
this.searchApplied = true;
|
||||
// Now let's load some extra info including IMDB Id
|
||||
// This way the search is fast at displaying results.
|
||||
this.getExtraInfo();
|
||||
});
|
||||
this.runSearch();
|
||||
});
|
||||
this.defaultPoster = "../../../images/default_movie_poster.png";
|
||||
const base = this.platformLocation.getBaseHrefFromDOM();
|
||||
|
@ -184,6 +181,18 @@ export class MovieSearchComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
public refineOpen() {
|
||||
this.refineSearchEnabled = !this.refineSearchEnabled;
|
||||
if (!this.refineSearchEnabled) {
|
||||
this.searchYear = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public applyRefinedSearch() {
|
||||
console.log(this.selectedLanguage);
|
||||
this.runSearch();
|
||||
}
|
||||
|
||||
private getExtraInfo() {
|
||||
|
||||
this.movieResults.forEach((val, index) => {
|
||||
|
@ -194,10 +203,18 @@ export class MovieSearchComponent implements OnInit {
|
|||
}
|
||||
val.background = this.sanitizer.bypassSecurityTrustStyle
|
||||
("url(" + "https://image.tmdb.org/t/p/w1280" + val.backdropPath + ")");
|
||||
this.searchService.getMovieInformation(val.id)
|
||||
|
||||
if (this.applyRefinedSearch) {
|
||||
this.searchService.getMovieInformationWithRefined(val.id, this.selectedLanguage)
|
||||
.subscribe(m => {
|
||||
this.updateItem(val, m);
|
||||
});
|
||||
} else {
|
||||
this.searchService.getMovieInformation(val.id)
|
||||
.subscribe(m => {
|
||||
this.updateItem(val, m);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -214,4 +231,30 @@ export class MovieSearchComponent implements OnInit {
|
|||
this.movieResults = [];
|
||||
this.searchApplied = false;
|
||||
}
|
||||
|
||||
private runSearch() {
|
||||
if (this.searchText === "") {
|
||||
this.clearResults();
|
||||
return;
|
||||
}
|
||||
if (this.refineOpen) {
|
||||
this.searchService.searchMovieWithRefined(this.searchText, this.searchYear, this.selectedLanguage)
|
||||
.subscribe(x => {
|
||||
this.movieResults = x;
|
||||
this.searchApplied = true;
|
||||
// Now let's load some extra info including IMDB Id
|
||||
// This way the search is fast at displaying results.
|
||||
this.getExtraInfo();
|
||||
});
|
||||
} else {
|
||||
this.searchService.searchMovie(this.searchText)
|
||||
.subscribe(x => {
|
||||
this.movieResults = x;
|
||||
this.searchApplied = true;
|
||||
// Now let's load some extra info including IMDB Id
|
||||
// This way the search is fast at displaying results.
|
||||
this.getExtraInfo();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
30
src/Ombi/ClientApp/app/search/search.component.scss
Normal file
30
src/Ombi/ClientApp/app/search/search.component.scss
Normal file
|
@ -0,0 +1,30 @@
|
|||
@media (max-width: 978px) {
|
||||
.top-spacing {
|
||||
padding-top: 5%
|
||||
}
|
||||
.form-control-search {
|
||||
width: 77%;
|
||||
}
|
||||
|
||||
}
|
||||
@media (min-width: 979px) {
|
||||
.top-spacing {
|
||||
padding-top: 2%
|
||||
}
|
||||
.form-control-search {
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
.search-bar-background {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.vcenter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.refine-option {
|
||||
box-shadow: inset 0 1px 5px rgba(0,0,0,1.0);
|
||||
}
|
|
@ -18,8 +18,13 @@ export class SearchService extends ServiceHelpers {
|
|||
|
||||
// Movies
|
||||
public searchMovie(searchTerm: string): Observable<ISearchMovieResult[]> {
|
||||
return this.http.get<ISearchMovieResult[]>(`${this.url}/Movie/` + searchTerm);
|
||||
return this.http.get<ISearchMovieResult[]>(`${this.url}/Movie/${searchTerm}`);
|
||||
}
|
||||
|
||||
public searchMovieWithRefined(searchTerm: string, year: number | undefined, langCode: string): Observable<ISearchMovieResult[]> {
|
||||
return this.http.post<ISearchMovieResult[]>(`${this.url}/Movie/`, { searchTerm, year, languageCode: langCode });
|
||||
}
|
||||
|
||||
public similarMovies(theMovieDbId: number): Observable<ISearchMovieResult[]> {
|
||||
return this.http.get<ISearchMovieResult[]>(`${this.url}/Movie/${theMovieDbId}/similar`);
|
||||
}
|
||||
|
@ -40,34 +45,38 @@ export class SearchService extends ServiceHelpers {
|
|||
return this.http.get<ISearchMovieResult>(`${this.url}/Movie/info/${theMovieDbId}`);
|
||||
}
|
||||
|
||||
public getMovieInformationWithRefined(theMovieDbId: number, langCode: string): Observable<ISearchMovieResult> {
|
||||
return this.http.post<ISearchMovieResult>(`${this.url}/Movie/info`, { theMovieDbId, languageCode: langCode });
|
||||
}
|
||||
|
||||
// TV
|
||||
public searchTv(searchTerm: string): Observable<ISearchTvResult[]> {
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/${searchTerm}`, {headers: this.headers});
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/${searchTerm}`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public searchTvTreeNode(searchTerm: string): Observable<TreeNode[]> {
|
||||
return this.http.get<TreeNode[]>(`${this.url}/Tv/${searchTerm}/tree`, {headers: this.headers});
|
||||
return this.http.get<TreeNode[]>(`${this.url}/Tv/${searchTerm}/tree`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public getShowInformationTreeNode(theTvDbId: number): Observable<TreeNode> {
|
||||
return this.http.get<TreeNode>(`${this.url}/Tv/info/${theTvDbId}/Tree`, {headers: this.headers});
|
||||
return this.http.get<TreeNode>(`${this.url}/Tv/info/${theTvDbId}/Tree`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public getShowInformation(theTvDbId: number): Observable<ISearchTvResult> {
|
||||
return this.http.get<ISearchTvResult>(`${this.url}/Tv/info/${theTvDbId}`, {headers: this.headers});
|
||||
return this.http.get<ISearchTvResult>(`${this.url}/Tv/info/${theTvDbId}`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public popularTv(): Observable<ISearchTvResult[]> {
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/popular`, {headers: this.headers});
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/popular`, { headers: this.headers });
|
||||
}
|
||||
public mostWatchedTv(): Observable<ISearchTvResult[]> {
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/mostwatched`, {headers: this.headers});
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/mostwatched`, { headers: this.headers });
|
||||
}
|
||||
public anticipatedTv(): Observable<ISearchTvResult[]> {
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/anticipated`, {headers: this.headers});
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/anticipated`, { headers: this.headers });
|
||||
}
|
||||
public trendingTv(): Observable<ISearchTvResult[]> {
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/trending`, {headers: this.headers});
|
||||
return this.http.get<ISearchTvResult[]>(`${this.url}/Tv/trending`, { headers: this.headers });
|
||||
}
|
||||
// Music
|
||||
public searchArtist(searchTerm: string): Observable<ISearchArtistResult[]> {
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="CollectAnalyticData" name="CollectAnalyticData" formControlName="collectAnalyticData">
|
||||
<label for="CollectAnalyticData">Allow us to collect anonymous analytical data e.g. browser used</label>
|
||||
<label for="CollectAnalyticData" tooltipPosition="top" pTooltip="This will allow us to have a better understanding of the userbase so we know what we should be supporting">Allow us to collect anonymous analytical data e.g. browser used</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<div class="text-center">If you do not yet want to setup a media server you can use the
|
||||
skip below. You can later setup your media servers via the settings.</div>
|
||||
<div class="row">
|
||||
<button routerLink="Wizard/CreateAdmin" data-test="skipbtn" class="btn btn-primary-outline wizard-img"
|
||||
<button routerLink="/Wizard/CreateAdmin" data-test="skipbtn" class="btn btn-primary-outline wizard-img"
|
||||
id="plexImg">
|
||||
Skip
|
||||
</button>
|
||||
|
|
184
src/Ombi/ClientApp/other/iso-lang.json
Normal file
184
src/Ombi/ClientApp/other/iso-lang.json
Normal file
|
@ -0,0 +1,184 @@
|
|||
[
|
||||
{"code":"ab","name":"Abkhaz","nativeName":"аҧсуа"},
|
||||
{"code":"aa","name":"Afar","nativeName":"Afaraf"},
|
||||
{"code":"af","name":"Afrikaans","nativeName":"Afrikaans"},
|
||||
{"code":"ak","name":"Akan","nativeName":"Akan"},
|
||||
{"code":"sq","name":"Albanian","nativeName":"Shqip"},
|
||||
{"code":"am","name":"Amharic","nativeName":"አማርኛ"},
|
||||
{"code":"ar","name":"Arabic","nativeName":"العربية"},
|
||||
{"code":"an","name":"Aragonese","nativeName":"Aragonés"},
|
||||
{"code":"hy","name":"Armenian","nativeName":"Հայերեն"},
|
||||
{"code":"as","name":"Assamese","nativeName":"অসমীয়া"},
|
||||
{"code":"av","name":"Avaric","nativeName":"авар мацӀ, магӀарул мацӀ"},
|
||||
{"code":"ae","name":"Avestan","nativeName":"avesta"},
|
||||
{"code":"ay","name":"Aymara","nativeName":"aymar aru"},
|
||||
{"code":"az","name":"Azerbaijani","nativeName":"azərbaycan dili"},
|
||||
{"code":"bm","name":"Bambara","nativeName":"bamanankan"},
|
||||
{"code":"ba","name":"Bashkir","nativeName":"башҡорт теле"},
|
||||
{"code":"eu","name":"Basque","nativeName":"euskara, euskera"},
|
||||
{"code":"be","name":"Belarusian","nativeName":"Беларуская"},
|
||||
{"code":"bn","name":"Bengali","nativeName":"বাংলা"},
|
||||
{"code":"bh","name":"Bihari","nativeName":"भोजपुरी"},
|
||||
{"code":"bi","name":"Bislama","nativeName":"Bislama"},
|
||||
{"code":"bs","name":"Bosnian","nativeName":"bosanski jezik"},
|
||||
{"code":"br","name":"Breton","nativeName":"brezhoneg"},
|
||||
{"code":"bg","name":"Bulgarian","nativeName":"български език"},
|
||||
{"code":"my","name":"Burmese","nativeName":"ဗမာစာ"},
|
||||
{"code":"ca","name":"Catalan; Valencian","nativeName":"Català"},
|
||||
{"code":"ch","name":"Chamorro","nativeName":"Chamoru"},
|
||||
{"code":"ce","name":"Chechen","nativeName":"нохчийн мотт"},
|
||||
{"code":"ny","name":"Chichewa; Chewa; Nyanja","nativeName":"chiCheŵa, chinyanja"},
|
||||
{"code":"zh","name":"Chinese","nativeName":"中文 (Zhōngwén), 汉语, 漢語"},
|
||||
{"code":"cv","name":"Chuvash","nativeName":"чӑваш чӗлхи"},
|
||||
{"code":"kw","name":"Cornish","nativeName":"Kernewek"},
|
||||
{"code":"co","name":"Corsican","nativeName":"corsu, lingua corsa"},
|
||||
{"code":"cr","name":"Cree","nativeName":"ᓀᐦᐃᔭᐍᐏᐣ"},
|
||||
{"code":"hr","name":"Croatian","nativeName":"hrvatski"},
|
||||
{"code":"cs","name":"Czech","nativeName":"česky, čeština"},
|
||||
{"code":"da","name":"Danish","nativeName":"dansk"},
|
||||
{"code":"dv","name":"Divehi; Dhivehi; Maldivian;","nativeName":"ދިވެހި"},
|
||||
{"code":"nl","name":"Dutch","nativeName":"Nederlands, Vlaams"},
|
||||
{"code":"en","name":"English","nativeName":"English"},
|
||||
{"code":"eo","name":"Esperanto","nativeName":"Esperanto"},
|
||||
{"code":"et","name":"Estonian","nativeName":"eesti, eesti keel"},
|
||||
{"code":"ee","name":"Ewe","nativeName":"Eʋegbe"},
|
||||
{"code":"fo","name":"Faroese","nativeName":"føroyskt"},
|
||||
{"code":"fj","name":"Fijian","nativeName":"vosa Vakaviti"},
|
||||
{"code":"fi","name":"Finnish","nativeName":"suomi, suomen kieli"},
|
||||
{"code":"fr","name":"French","nativeName":"français, langue française"},
|
||||
{"code":"ff","name":"Fula; Fulah; Pulaar; Pular","nativeName":"Fulfulde, Pulaar, Pular"},
|
||||
{"code":"gl","name":"Galician","nativeName":"Galego"},
|
||||
{"code":"ka","name":"Georgian","nativeName":"ქართული"},
|
||||
{"code":"de","name":"German","nativeName":"Deutsch"},
|
||||
{"code":"el","name":"Greek, Modern","nativeName":"Ελληνικά"},
|
||||
{"code":"gn","name":"Guaraní","nativeName":"Avañeẽ"},
|
||||
{"code":"gu","name":"Gujarati","nativeName":"ગુજરાતી"},
|
||||
{"code":"ht","name":"Haitian; Haitian Creole","nativeName":"Kreyòl ayisyen"},
|
||||
{"code":"ha","name":"Hausa","nativeName":"Hausa, هَوُسَ"},
|
||||
{"code":"he","name":"Hebrew (modern)","nativeName":"עברית"},
|
||||
{"code":"hz","name":"Herero","nativeName":"Otjiherero"},
|
||||
{"code":"hi","name":"Hindi","nativeName":"हिन्दी, हिंदी"},
|
||||
{"code":"ho","name":"Hiri Motu","nativeName":"Hiri Motu"},
|
||||
{"code":"hu","name":"Hungarian","nativeName":"Magyar"},
|
||||
{"code":"ia","name":"Interlingua","nativeName":"Interlingua"},
|
||||
{"code":"id","name":"Indonesian","nativeName":"Bahasa Indonesia"},
|
||||
{"code":"ie","name":"Interlingue","nativeName":"Originally called Occidental; then Interlingue after WWII"},
|
||||
{"code":"ga","name":"Irish","nativeName":"Gaeilge"},
|
||||
{"code":"ig","name":"Igbo","nativeName":"Asụsụ Igbo"},
|
||||
{"code":"ik","name":"Inupiaq","nativeName":"Iñupiaq, Iñupiatun"},
|
||||
{"code":"io","name":"Ido","nativeName":"Ido"},
|
||||
{"code":"is","name":"Icelandic","nativeName":"Íslenska"},
|
||||
{"code":"it","name":"Italian","nativeName":"Italiano"},
|
||||
{"code":"iu","name":"Inuktitut","nativeName":"ᐃᓄᒃᑎᑐᑦ"},
|
||||
{"code":"ja","name":"Japanese","nativeName":"日本語 (にほんご/にっぽんご)"},
|
||||
{"code":"jv","name":"Javanese","nativeName":"basa Jawa"},
|
||||
{"code":"kl","name":"Kalaallisut, Greenlandic","nativeName":"kalaallisut, kalaallit oqaasii"},
|
||||
{"code":"kn","name":"Kannada","nativeName":"ಕನ್ನಡ"},
|
||||
{"code":"kr","name":"Kanuri","nativeName":"Kanuri"},
|
||||
{"code":"ks","name":"Kashmiri","nativeName":"कश्मीरी, كشميري"},
|
||||
{"code":"kk","name":"Kazakh","nativeName":"Қазақ тілі"},
|
||||
{"code":"km","name":"Khmer","nativeName":"ភាសាខ្មែរ"},
|
||||
{"code":"ki","name":"Kikuyu, Gikuyu","nativeName":"Gĩkũyũ"},
|
||||
{"code":"rw","name":"Kinyarwanda","nativeName":"Ikinyarwanda"},
|
||||
{"code":"ky","name":"Kirghiz, Kyrgyz","nativeName":"кыргыз тили"},
|
||||
{"code":"kv","name":"Komi","nativeName":"коми кыв"},
|
||||
{"code":"kg","name":"Kongo","nativeName":"KiKongo"},
|
||||
{"code":"ko","name":"Korean","nativeName":"한국어 (韓國語), 조선말 (朝鮮語)"},
|
||||
{"code":"ku","name":"Kurdish","nativeName":"Kurdî, كوردی"},
|
||||
{"code":"kj","name":"Kwanyama, Kuanyama","nativeName":"Kuanyama"},
|
||||
{"code":"la","name":"Latin","nativeName":"latine, lingua latina"},
|
||||
{"code":"lb","name":"Luxembourgish, Letzeburgesch","nativeName":"Lëtzebuergesch"},
|
||||
{"code":"lg","name":"Luganda","nativeName":"Luganda"},
|
||||
{"code":"li","name":"Limburgish, Limburgan, Limburger","nativeName":"Limburgs"},
|
||||
{"code":"ln","name":"Lingala","nativeName":"Lingála"},
|
||||
{"code":"lo","name":"Lao","nativeName":"ພາສາລາວ"},
|
||||
{"code":"lt","name":"Lithuanian","nativeName":"lietuvių kalba"},
|
||||
{"code":"lu","name":"Luba-Katanga","nativeName":"Luba-Katanga"},
|
||||
{"code":"lv","name":"Latvian","nativeName":"latviešu valoda"},
|
||||
{"code":"gv","name":"Manx","nativeName":"Gaelg, Gailck"},
|
||||
{"code":"mk","name":"Macedonian","nativeName":"македонски јазик"},
|
||||
{"code":"mg","name":"Malagasy","nativeName":"Malagasy fiteny"},
|
||||
{"code":"ms","name":"Malay","nativeName":"bahasa Melayu, بهاس ملايو"},
|
||||
{"code":"ml","name":"Malayalam","nativeName":"മലയാളം"},
|
||||
{"code":"mt","name":"Maltese","nativeName":"Malti"},
|
||||
{"code":"mi","name":"Māori","nativeName":"te reo Māori"},
|
||||
{"code":"mr","name":"Marathi (Marāṭhī)","nativeName":"मराठी"},
|
||||
{"code":"mh","name":"Marshallese","nativeName":"Kajin M̧ajeļ"},
|
||||
{"code":"mn","name":"Mongolian","nativeName":"монгол"},
|
||||
{"code":"na","name":"Nauru","nativeName":"Ekakairũ Naoero"},
|
||||
{"code":"nv","name":"Navajo, Navaho","nativeName":"Diné bizaad, Dinékʼehǰí"},
|
||||
{"code":"nb","name":"Norwegian Bokmål","nativeName":"Norsk bokmål"},
|
||||
{"code":"nd","name":"North Ndebele","nativeName":"isiNdebele"},
|
||||
{"code":"ne","name":"Nepali","nativeName":"नेपाली"},
|
||||
{"code":"ng","name":"Ndonga","nativeName":"Owambo"},
|
||||
{"code":"nn","name":"Norwegian Nynorsk","nativeName":"Norsk nynorsk"},
|
||||
{"code":"no","name":"Norwegian","nativeName":"Norsk"},
|
||||
{"code":"ii","name":"Nuosu","nativeName":"ꆈꌠ꒿ Nuosuhxop"},
|
||||
{"code":"nr","name":"South Ndebele","nativeName":"isiNdebele"},
|
||||
{"code":"oc","name":"Occitan","nativeName":"Occitan"},
|
||||
{"code":"oj","name":"Ojibwe, Ojibwa","nativeName":"ᐊᓂᔑᓈᐯᒧᐎᓐ"},
|
||||
{"code":"cu","name":"Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic","nativeName":"ѩзыкъ словѣньскъ"},
|
||||
{"code":"om","name":"Oromo","nativeName":"Afaan Oromoo"},
|
||||
{"code":"or","name":"Oriya","nativeName":"ଓଡ଼ିଆ"},
|
||||
{"code":"os","name":"Ossetian, Ossetic","nativeName":"ирон æвзаг"},
|
||||
{"code":"pa","name":"Panjabi, Punjabi","nativeName":"ਪੰਜਾਬੀ, پنجابی"},
|
||||
{"code":"pi","name":"Pāli","nativeName":"पाऴि"},
|
||||
{"code":"fa","name":"Persian","nativeName":"فارسی"},
|
||||
{"code":"pl","name":"Polish","nativeName":"polski"},
|
||||
{"code":"ps","name":"Pashto, Pushto","nativeName":"پښتو"},
|
||||
{"code":"pt","name":"Portuguese","nativeName":"Português"},
|
||||
{"code":"qu","name":"Quechua","nativeName":"Runa Simi, Kichwa"},
|
||||
{"code":"rm","name":"Romansh","nativeName":"rumantsch grischun"},
|
||||
{"code":"rn","name":"Kirundi","nativeName":"kiRundi"},
|
||||
{"code":"ro","name":"Romanian, Moldavian, Moldovan","nativeName":"română"},
|
||||
{"code":"ru","name":"Russian","nativeName":"русский язык"},
|
||||
{"code":"sa","name":"Sanskrit (Saṁskṛta)","nativeName":"संस्कृतम्"},
|
||||
{"code":"sc","name":"Sardinian","nativeName":"sardu"},
|
||||
{"code":"sd","name":"Sindhi","nativeName":"सिन्धी, سنڌي، سندھی"},
|
||||
{"code":"se","name":"Northern Sami","nativeName":"Davvisámegiella"},
|
||||
{"code":"sm","name":"Samoan","nativeName":"gagana faa Samoa"},
|
||||
{"code":"sg","name":"Sango","nativeName":"yângâ tî sängö"},
|
||||
{"code":"sr","name":"Serbian","nativeName":"српски језик"},
|
||||
{"code":"gd","name":"Scottish Gaelic; Gaelic","nativeName":"Gàidhlig"},
|
||||
{"code":"sn","name":"Shona","nativeName":"chiShona"},
|
||||
{"code":"si","name":"Sinhala, Sinhalese","nativeName":"සිංහල"},
|
||||
{"code":"sk","name":"Slovak","nativeName":"slovenčina"},
|
||||
{"code":"sl","name":"Slovene","nativeName":"slovenščina"},
|
||||
{"code":"so","name":"Somali","nativeName":"Soomaaliga, af Soomaali"},
|
||||
{"code":"st","name":"Southern Sotho","nativeName":"Sesotho"},
|
||||
{"code":"es","name":"Spanish; Castilian","nativeName":"español, castellano"},
|
||||
{"code":"su","name":"Sundanese","nativeName":"Basa Sunda"},
|
||||
{"code":"sw","name":"Swahili","nativeName":"Kiswahili"},
|
||||
{"code":"ss","name":"Swati","nativeName":"SiSwati"},
|
||||
{"code":"sv","name":"Swedish","nativeName":"svenska"},
|
||||
{"code":"ta","name":"Tamil","nativeName":"தமிழ்"},
|
||||
{"code":"te","name":"Telugu","nativeName":"తెలుగు"},
|
||||
{"code":"tg","name":"Tajik","nativeName":"тоҷикӣ, toğikī, تاجیکی"},
|
||||
{"code":"th","name":"Thai","nativeName":"ไทย"},
|
||||
{"code":"ti","name":"Tigrinya","nativeName":"ትግርኛ"},
|
||||
{"code":"bo","name":"Tibetan Standard, Tibetan, Central","nativeName":"བོད་ཡིག"},
|
||||
{"code":"tk","name":"Turkmen","nativeName":"Türkmen, Түркмен"},
|
||||
{"code":"tl","name":"Tagalog","nativeName":"Wikang Tagalog"},
|
||||
{"code":"tn","name":"Tswana","nativeName":"Setswana"},
|
||||
{"code":"to","name":"Tonga (Tonga Islands)","nativeName":"faka Tonga"},
|
||||
{"code":"tr","name":"Turkish","nativeName":"Türkçe"},
|
||||
{"code":"ts","name":"Tsonga","nativeName":"Xitsonga"},
|
||||
{"code":"tt","name":"Tatar","nativeName":"татарча, tatarça, تاتارچا"},
|
||||
{"code":"tw","name":"Twi","nativeName":"Twi"},
|
||||
{"code":"ty","name":"Tahitian","nativeName":"Reo Tahiti"},
|
||||
{"code":"ug","name":"Uighur, Uyghur","nativeName":"Uyƣurqə, ئۇيغۇرچە"},
|
||||
{"code":"uk","name":"Ukrainian","nativeName":"українська"},
|
||||
{"code":"ur","name":"Urdu","nativeName":"اردو"},
|
||||
{"code":"uz","name":"Uzbek","nativeName":"zbek, Ўзбек, أۇزبېك"},
|
||||
{"code":"ve","name":"Venda","nativeName":"Tshivenḓa"},
|
||||
{"code":"vi","name":"Vietnamese","nativeName":"Tiếng Việt"},
|
||||
{"code":"vo","name":"Volapük","nativeName":"Volapük"},
|
||||
{"code":"wa","name":"Walloon","nativeName":"Walon"},
|
||||
{"code":"cy","name":"Welsh","nativeName":"Cymraeg"},
|
||||
{"code":"wo","name":"Wolof","nativeName":"Wollof"},
|
||||
{"code":"fy","name":"Western Frisian","nativeName":"Frysk"},
|
||||
{"code":"xh","name":"Xhosa","nativeName":"isiXhosa"},
|
||||
{"code":"yi","name":"Yiddish","nativeName":"ייִדיש"},
|
||||
{"code":"yo","name":"Yoruba","nativeName":"Yorùbá"},
|
||||
{"code":"za","name":"Zhuang, Chuang","nativeName":"Saɯ cueŋƅ, Saw cuengh"}
|
||||
]
|
|
@ -28,3 +28,40 @@ $bg-colour-disabled: #252424;
|
|||
.label {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
@media (max-width: 924px) {
|
||||
.navbar-header {
|
||||
float: none;
|
||||
}
|
||||
.navbar-left,.navbar-right {
|
||||
float: none !important;
|
||||
}
|
||||
.navbar-toggle {
|
||||
display: block;
|
||||
}
|
||||
.navbar-collapse {
|
||||
border-top: 1px solid transparent;
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
|
||||
}
|
||||
.navbar-fixed-top {
|
||||
top: 0;
|
||||
border-width: 0 0 1px;
|
||||
}
|
||||
.navbar-collapse.collapse {
|
||||
display: none!important;
|
||||
}
|
||||
.navbar-nav {
|
||||
float: none!important;
|
||||
margin-top: 7.5px;
|
||||
}
|
||||
.navbar-nav>li {
|
||||
float: none;
|
||||
}
|
||||
.navbar-nav>li>a {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.collapse.in{
|
||||
display:block !important;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Api.Lidarr.Models;
|
||||
using Ombi.Core;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Models;
|
||||
using StackExchange.Profiling;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
{
|
||||
|
@ -18,7 +17,7 @@ namespace Ombi.Controllers
|
|||
[ApiV1]
|
||||
[Produces("application/json")]
|
||||
[ApiController]
|
||||
public class SearchController : ControllerBase
|
||||
public class SearchController : Controller
|
||||
{
|
||||
public SearchController(IMovieEngine movie, ITvSearchEngine tvEngine, ILogger<SearchController> logger, IMusicSearchEngine music)
|
||||
{
|
||||
|
@ -40,13 +39,40 @@ namespace Ombi.Controllers
|
|||
/// <param name="searchTerm">The search term.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("movie/{searchTerm}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> SearchMovie(string searchTerm)
|
||||
{
|
||||
using (MiniProfiler.Current.Step("SearchingMovie"))
|
||||
{
|
||||
Logger.LogDebug("Searching : {searchTerm}", searchTerm);
|
||||
|
||||
return await MovieEngine.Search(searchTerm);
|
||||
return await MovieEngine.Search(searchTerm, null, "en");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for a movie.
|
||||
/// </summary>
|
||||
/// <remarks>We use TheMovieDb as the Movie Provider</remarks>
|
||||
/// <param name="model">The refinement model, language code and year are both optional. Language code uses ISO 639-1</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("movie")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> SearchMovie([FromBody] SearchMovieRefineModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
using (MiniProfiler.Current.Step("SearchingMovie"))
|
||||
{
|
||||
Logger.LogDebug("Searching : {0}, Year: {1}, Lang: {2}", model.SearchTerm, model.Year, model.LanguageCode);
|
||||
|
||||
return Json(await MovieEngine.Search(model.SearchTerm, model.Year, model.LanguageCode));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,11 +85,35 @@ namespace Ombi.Controllers
|
|||
/// We use TheMovieDb as the Movie Provider
|
||||
/// </remarks>
|
||||
[HttpGet("movie/info/{theMovieDbId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<SearchMovieViewModel> GetExtraMovieInfo(int theMovieDbId)
|
||||
{
|
||||
return await MovieEngine.LookupImdbInformation(theMovieDbId);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets extra information on the movie e.g. IMDBId
|
||||
/// </summary>
|
||||
/// <param name="model">TheMovieDb and Language Code, Pass in the language code (ISO 639-1) to get it back in a different lang </param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// We use TheMovieDb as the Movie Provider
|
||||
/// </remarks>
|
||||
[HttpPost("movie/info")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> GetExtraMovieInfo([FromBody] SearchMovieExtraInfoRefineModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
return Json(await MovieEngine.LookupImdbInformation(model.TheMovieDbId, model.LanguageCode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns similar movies to the movie id passed in
|
||||
/// </summary>
|
||||
|
@ -72,6 +122,8 @@ namespace Ombi.Controllers
|
|||
/// We use TheMovieDb as the Movie Provider
|
||||
/// </remarks>
|
||||
[HttpGet("movie/{theMovieDbId}/similar")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId)
|
||||
{
|
||||
return await MovieEngine.SimilarMovies(theMovieDbId);
|
||||
|
@ -83,6 +135,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use TheMovieDb as the Movie Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("movie/popular")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> Popular()
|
||||
{
|
||||
return await MovieEngine.PopularMovies();
|
||||
|
@ -93,6 +147,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use TheMovieDb as the Movie Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("movie/nowplaying")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
|
||||
{
|
||||
return await MovieEngine.NowPlayingMovies();
|
||||
|
@ -103,6 +159,8 @@ namespace Ombi.Controllers
|
|||
/// <returns></returns>
|
||||
/// <remarks>We use TheMovieDb as the Movie Provider</remarks>
|
||||
[HttpGet("movie/toprated")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
|
||||
{
|
||||
return await MovieEngine.TopRatedMovies();
|
||||
|
@ -113,6 +171,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use TheMovieDb as the Movie Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("movie/upcoming")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
|
||||
{
|
||||
return await MovieEngine.UpcomingMovies();
|
||||
|
@ -125,6 +185,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use TvMaze as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("tv/{searchTerm}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchTvShowViewModel>> SearchTv(string searchTerm)
|
||||
{
|
||||
return await TvEngine.Search(searchTerm);
|
||||
|
@ -137,6 +199,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use TvMaze as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("tv/info/{tvdbId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<SearchTvShowViewModel> GetShowInfo(int tvdbId)
|
||||
{
|
||||
return await TvEngine.GetShowInformation(tvdbId);
|
||||
|
@ -148,6 +212,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("tv/popular")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchTvShowViewModel>> PopularTv()
|
||||
{
|
||||
return await TvEngine.Popular();
|
||||
|
@ -159,6 +225,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("tv/anticipated")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchTvShowViewModel>> AnticipatedTv()
|
||||
{
|
||||
return await TvEngine.Anticipated();
|
||||
|
@ -171,6 +239,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("tv/mostwatched")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatched()
|
||||
{
|
||||
return await TvEngine.MostWatches();
|
||||
|
@ -182,6 +252,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("tv/trending")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchTvShowViewModel>> Trending()
|
||||
{
|
||||
return await TvEngine.Trending();
|
||||
|
@ -193,6 +265,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use Lidarr as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("music/artist/{searchTerm}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchArtistViewModel>> SearchArtist(string searchTerm)
|
||||
{
|
||||
return await MusicEngine.SearchArtist(searchTerm);
|
||||
|
@ -204,6 +278,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use Lidarr as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("music/album/{searchTerm}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchAlbumViewModel>> SearchAlbum(string searchTerm)
|
||||
{
|
||||
return await MusicEngine.SearchAlbum(searchTerm);
|
||||
|
@ -215,6 +291,8 @@ namespace Ombi.Controllers
|
|||
/// <remarks>We use Lidarr as the Provider</remarks>
|
||||
/// <returns></returns>
|
||||
[HttpGet("music/artist/album/{foreignArtistId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchAlbumViewModel>> GetAlbumsByArtist(string foreignArtistId)
|
||||
{
|
||||
return await MusicEngine.GetArtistAlbums(foreignArtistId);
|
||||
|
|
8
src/Ombi/Models/SearchMovieExtraInfoRefineModel.cs
Normal file
8
src/Ombi/Models/SearchMovieExtraInfoRefineModel.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Ombi.Models
|
||||
{
|
||||
public class SearchMovieExtraInfoRefineModel
|
||||
{
|
||||
public int TheMovieDbId { get; set; }
|
||||
public string LanguageCode { get; set; } = "en";
|
||||
}
|
||||
}
|
9
src/Ombi/Models/SearchMovieRefineModel.cs
Normal file
9
src/Ombi/Models/SearchMovieRefineModel.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Ombi.Models
|
||||
{
|
||||
public class SearchMovieRefineModel
|
||||
{
|
||||
public string SearchTerm { get; set; }
|
||||
public int? Year { get; set; }
|
||||
public string LanguageCode { get; set; } = "en";
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<RuntimeIdentifiers>win10-x64;win10-x86;osx-x64;linux-x64;linux-arm64;</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win10-x64;win10-x86;osx-x64;linux-x64;linux-arm;linux-arm64;</RuntimeIdentifiers>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||
<AssemblyVersion>$(SemVer)</AssemblyVersion>
|
||||
<FileVersion>$(SemVer)</FileVersion>
|
||||
<Version>$(FullVer)</Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<TypeScriptToolsVersion>3.0</TypeScriptToolsVersion>
|
||||
<TypeScriptToolsVersion>3.1</TypeScriptToolsVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ServerGarbageCollection>false</ServerGarbageCollection>
|
||||
|
|
|
@ -175,6 +175,15 @@ namespace Ombi
|
|||
{
|
||||
// Generate a API Key
|
||||
settings.ApiKey = Guid.NewGuid().ToString("N");
|
||||
settings.CollectAnalyticData = true; // Since this is a first setup, enable analytical data collection
|
||||
settings.Set = true;
|
||||
ombiService.SaveSettings(settings);
|
||||
}
|
||||
|
||||
if (!settings.Set)
|
||||
{
|
||||
settings.Set = true;
|
||||
settings.CollectAnalyticData = true;
|
||||
ombiService.SaveSettings(settings);
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,19 @@
|
|||
<meta name="theme-color" content="#df691a">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
|
||||
@if (s?.CollectAnalyticData ?? true)
|
||||
{
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-89270627-3"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-89270627-3');
|
||||
</script>
|
||||
}
|
||||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
"angular2-template-loader": "^0.6.2",
|
||||
"aspnet-webpack": "^3.0.0",
|
||||
"awesome-typescript-loader": "^5.2.0",
|
||||
"bootstrap": "3.3.7",
|
||||
"bootswatch": "3.3.7",
|
||||
"bootstrap": "3.4.0",
|
||||
"bootswatch": "3.4.0",
|
||||
"copy-webpack-plugin": "^4.5.2",
|
||||
"core-js": "^2.5.7",
|
||||
"css": "^2.2.3",
|
||||
|
@ -60,6 +60,7 @@
|
|||
"jquery": "^3.3.1",
|
||||
"mini-css-extract-plugin": "^0.4.1",
|
||||
"moment": "^2.22.2",
|
||||
"natives": "1.1.6",
|
||||
"ng2-cookies": "^1.0.12",
|
||||
"ngx-clipboard": "^11.1.1",
|
||||
"ngx-infinite-scroll": "^6.0.1",
|
||||
|
|
5
src/Ombi/typings/globals.d.ts
vendored
5
src/Ombi/typings/globals.d.ts
vendored
|
@ -2,3 +2,8 @@
|
|||
|
||||
declare module "pace-progress";
|
||||
declare var __webpack_public_path__: any;
|
||||
|
||||
declare module "*.json" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Se på Emby",
|
||||
"RequestAdded": "{{title}} er anmodet med succes",
|
||||
"Similar": "Lignende",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Populære film",
|
||||
"UpcomingMovies": "Kommende film",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Stemt",
|
||||
"VotesTab": "Nødvendige stemmer"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "In Emby anschauen",
|
||||
"RequestAdded": "Anfrage für {{title}} wurde erfolgreich hinzugefügt",
|
||||
"Similar": "Ähnliche",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Beliebte Filme",
|
||||
"UpcomingMovies": "Kommende Filme",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Bewertet",
|
||||
"VotesTab": "Erforderliche Bewertungen"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
"ViewOnEmby": "View On Emby",
|
||||
"RequestAdded": "Request for {{title}} has been added successfully",
|
||||
"Similar":"Similar",
|
||||
"Refine":"Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Popular Movies",
|
||||
"UpcomingMovies": "Upcoming Movies",
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Ver en Emby",
|
||||
"RequestAdded": "La solicitud de {{title}} se ha agregado con éxito",
|
||||
"Similar": "Similar",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Películas populares",
|
||||
"UpcomingMovies": "Próximas películas",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Voted",
|
||||
"VotesTab": "Votes Needed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Regarder sur Emby",
|
||||
"RequestAdded": "La demande pour {{title}} a été ajoutée avec succès",
|
||||
"Similar": "Similaires",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Films populaires",
|
||||
"UpcomingMovies": "Films à venir",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Voté",
|
||||
"VotesTab": "Votes nécessaires"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Guarda su Emby",
|
||||
"RequestAdded": "La richiesta per {{title}} è stata aggiunta correttamente",
|
||||
"Similar": "Similar",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Film popolari",
|
||||
"UpcomingMovies": "Film in arrivo",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Voted",
|
||||
"VotesTab": "Votes Needed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"Common": {
|
||||
"ContinueButton": "Doorgaan",
|
||||
"Available": "Beschikbaar",
|
||||
"PartiallyAvailable": "Partially Available",
|
||||
"Monitored": "Monitored",
|
||||
"PartiallyAvailable": "Deels Beschikbaar",
|
||||
"Monitored": "Gecontroleerd",
|
||||
"NotAvailable": "Niet Beschikbaar",
|
||||
"ProcessingRequest": "Verzoek wordt verwerkt",
|
||||
"PendingApproval": "Wacht op goedkeuring",
|
||||
|
@ -25,7 +25,7 @@
|
|||
"Approve": "Accepteer",
|
||||
"PartlyAvailable": "Deels Beschikbaar",
|
||||
"Errors": {
|
||||
"Validation": "Fout: Controleer de ingevulde waardes"
|
||||
"Validation": "Controleer de ingevulde waardes"
|
||||
}
|
||||
},
|
||||
"PasswordReset": {
|
||||
|
@ -48,7 +48,7 @@
|
|||
"Requests": "Verzoeklijst",
|
||||
"UserManagement": "Gebruikersbeheer",
|
||||
"Issues": "Problemen",
|
||||
"Vote": "Vote",
|
||||
"Vote": "Stem",
|
||||
"Donate": "Doneer!",
|
||||
"DonateLibraryMaintainer": "Doneren aan bibliotheek beheerder",
|
||||
"DonateTooltip": "Zo heb ik mijn vrouw overtuigd dat ik Ombi mag ontwikkelen ;)",
|
||||
|
@ -56,9 +56,9 @@
|
|||
"Settings": "Instellingen",
|
||||
"Welcome": "Welkom {{username}}",
|
||||
"UpdateDetails": "Update gegevens",
|
||||
"Logout": "Logout",
|
||||
"Logout": "Afmelden",
|
||||
"OpenMobileApp": "Open Mobiele App",
|
||||
"RecentlyAdded": "Recently Added"
|
||||
"RecentlyAdded": "Onlangs Toegevoegd"
|
||||
},
|
||||
"Search": {
|
||||
"Title": "Zoeken",
|
||||
|
@ -68,12 +68,13 @@
|
|||
"MusicTab": "Muziek",
|
||||
"Suggestions": "Suggesties",
|
||||
"NoResults": "Sorry, we hebben geen resultaten gevonden!",
|
||||
"DigitalDate": "Digital Release: {{date}}",
|
||||
"TheatricalRelease": "Theatrical Release: {{date}}",
|
||||
"DigitalDate": "Digitale Uitgave: {{date}}",
|
||||
"TheatricalRelease": "Bioscoop Uitgave: {{date}}",
|
||||
"ViewOnPlex": "Bekijk op Plex",
|
||||
"ViewOnEmby": "Bekijk op Emby",
|
||||
"RequestAdded": "Aanvraag voor {{title}} is succesvol toegevoegd",
|
||||
"Similar": "Similar",
|
||||
"Similar": "Vergelijkbaar",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Populaire films",
|
||||
"UpcomingMovies": "Aankomende Films",
|
||||
|
@ -108,10 +109,10 @@
|
|||
"Status": "Status:",
|
||||
"RequestStatus": "Aanvraagstatus:",
|
||||
"Denied": " Geweigerd:",
|
||||
"TheatricalRelease": "Theatrical Release: {{date}}",
|
||||
"ReleaseDate": "Released: {{date}}",
|
||||
"TheatricalReleaseSort": "Theatrical Release",
|
||||
"DigitalRelease": "Digital Release: {{date}}",
|
||||
"TheatricalRelease": "Cinema Uitgave: {{date}}",
|
||||
"ReleaseDate": "Uitgekomen: {{date}}",
|
||||
"TheatricalReleaseSort": "Bioscoop Uitgave",
|
||||
"DigitalRelease": "Digitale Uitgave: {{date}}",
|
||||
"RequestDate": "Aanvraag Datum:",
|
||||
"QualityOverride": "Kwaliteit overschrijven:",
|
||||
"RootFolderOverride": "Hoofdmap overschrijven:",
|
||||
|
@ -127,20 +128,20 @@
|
|||
"GridStatus": "Status",
|
||||
"ReportIssue": "Probleem Melden",
|
||||
"Filter": "Filter",
|
||||
"Sort": "Sort",
|
||||
"Sort": "Sorteer",
|
||||
"SeasonNumberHeading": "Seizoen: {seasonNumber}",
|
||||
"SortTitleAsc": "Titel ▲",
|
||||
"SortTitleDesc": "Titel ▼",
|
||||
"SortRequestDateAsc": "Request Date ▲",
|
||||
"SortRequestDateDesc": "Request Date ▼",
|
||||
"SortRequestDateAsc": "Aanvraag Datum ▲",
|
||||
"SortRequestDateDesc": "Aanvraag Datum ▼",
|
||||
"SortStatusAsc": "Status ▲",
|
||||
"SortStatusDesc": "Status ▼",
|
||||
"Remaining": {
|
||||
"Quota": "{{remaining}}/{{total}} requests remaining",
|
||||
"NextDays": "Another request will be added in {{time}} days",
|
||||
"NextHours": "Another request will be added in {{time}} hours",
|
||||
"NextMinutes": "Another request will be added in {{time}} minutes",
|
||||
"NextMinute": "Another request will be added in {{time}} minute"
|
||||
"Quota": "{{remaining}}/{{total}} resterende aanvragen",
|
||||
"NextDays": "Een ander verzoek zal worden toegevoegd in {{time}} Dagen",
|
||||
"NextHours": "Een ander verzoek zal worden toegevoegd in {{time}} Uren",
|
||||
"NextMinutes": "Een ander verzoek zal worden toegevoegd in {{time}} Minuten",
|
||||
"NextMinute": "Een ander verzoek zal worden toegevoegd in {{time}} Minuut"
|
||||
}
|
||||
},
|
||||
"Issues": {
|
||||
|
@ -167,18 +168,18 @@
|
|||
"FilterHeaderAvailability": "Beschikbaarheid",
|
||||
"FilterHeaderRequestStatus": "Status",
|
||||
"Approved": "Goedgekeurd",
|
||||
"PendingApproval": "Pending Approval"
|
||||
"PendingApproval": "In afwachting van goedkeuring"
|
||||
},
|
||||
"UserManagment": {
|
||||
"TvRemaining": "TV: {{remaining}}/{{total}} remaining",
|
||||
"MovieRemaining": "Movies: {{remaining}}/{{total}} remaining",
|
||||
"MusicRemaining": "Music: {{remaining}}/{{total}} remaining",
|
||||
"TvDue": "TV: {{date}}",
|
||||
"TvRemaining": "Tv: {{remaining}}/{{total}} Resterend",
|
||||
"MovieRemaining": "Tv: {{remaining}}/{{total}} Resterend",
|
||||
"MusicRemaining": "Muziek: {{remaining}}/{{total}} Resterend",
|
||||
"TvDue": "Tv: {{date}}",
|
||||
"MovieDue": "Film: {{date}}",
|
||||
"MusicDue": "Muziek: {{date}}"
|
||||
},
|
||||
"Votes": {
|
||||
"CompletedVotesTab": "Voted",
|
||||
"VotesTab": "Votes Needed"
|
||||
"CompletedVotesTab": "Gestemd",
|
||||
"VotesTab": "Stemmen nodig"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Spill av på Emby",
|
||||
"RequestAdded": "Forespørsel om {{title}} er lagt til",
|
||||
"Similar": "Lignende",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Populære filmer",
|
||||
"UpcomingMovies": "Kommende filmer",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Voted",
|
||||
"VotesTab": "Votes Needed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Obejrzyj na Emby",
|
||||
"RequestAdded": "Zgłoszenie dla {{title}} zostało dodane",
|
||||
"Similar": "Podobne",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Popularne filmy",
|
||||
"UpcomingMovies": "Wkrótce w kinach",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Voted",
|
||||
"VotesTab": "Votes Needed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Assistir no Emby",
|
||||
"RequestAdded": "Pedido de {{title}} foi adicionado com sucesso",
|
||||
"Similar": "Semelhante",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Filmes populares",
|
||||
"UpcomingMovies": "Próximos filmes",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Voted",
|
||||
"VotesTab": "Votes Needed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"ViewOnEmby": "Visa på Emby",
|
||||
"RequestAdded": "Efterfrågan om {{title}} har lagts till",
|
||||
"Similar": "Liknande",
|
||||
"Refine": "Refine",
|
||||
"Movies": {
|
||||
"PopularMovies": "Populära filmer",
|
||||
"UpcomingMovies": "Kommande filmer",
|
||||
|
@ -181,4 +182,4 @@
|
|||
"CompletedVotesTab": "Voted",
|
||||
"VotesTab": "Votes Needed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
3006
src/Ombi/yarn.lock
3006
src/Ombi/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue