mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 08:16:05 -07:00
parent
bad109c862
commit
ffab4b7981
26 changed files with 602 additions and 267 deletions
|
@ -1,5 +1,4 @@
|
|||
using Ombi.Core.Claims;
|
||||
using Ombi.Core.Rule;
|
||||
using Ombi.Core.Rule;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -18,9 +17,7 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
}
|
||||
|
||||
protected IPrincipal User { get; }
|
||||
|
||||
protected IRuleEvaluator Rules { get; }
|
||||
|
||||
protected string Username => User.Identity.Name;
|
||||
|
||||
protected bool HasRole(string roleName)
|
||||
|
@ -28,15 +25,6 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
return User.IsInRole(roleName);
|
||||
}
|
||||
|
||||
protected bool ShouldSendNotification(BaseRequest req)
|
||||
{
|
||||
var sendNotification = !req.Approved; /*|| !prSettings.IgnoreNotifyForAutoApprovedRequests;*/
|
||||
|
||||
if (HasRole(OmbiClaims.Admin))
|
||||
sendNotification = false; // Don't bother sending a notification if the user is an admin
|
||||
return sendNotification;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RuleResult>> RunRequestRules(BaseRequest model)
|
||||
{
|
||||
var ruleResults = await Rules.StartRequestRules(model);
|
||||
|
|
|
@ -182,7 +182,8 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
await MovieRepository.Add(model);
|
||||
|
||||
if (ShouldSendNotification(model))
|
||||
var result = await RunSpecificRule(model, SpecificRules.CanSendNotification);
|
||||
if (result.Success)
|
||||
{
|
||||
NotificationHelper.NewRequest(model);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ using System.Security.Principal;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.IdentityResolver;
|
||||
using Ombi.Core.Rule;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -42,128 +43,17 @@ namespace Ombi.Core.Engine
|
|||
|
||||
public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv)
|
||||
{
|
||||
var showInfo = await TvApi.ShowLookupByTheTvDbId(tv.Id);
|
||||
DateTime.TryParse(showInfo.premiered, out DateTime firstAir);
|
||||
|
||||
// For some reason the poster path is always http
|
||||
var posterPath = showInfo.image?.medium.Replace("http:", "https:");
|
||||
|
||||
var tvRequests = new List<SeasonRequests>();
|
||||
// Only have the TV requests we actually requested and not everything
|
||||
foreach (var season in tv.SeasonRequests)
|
||||
{
|
||||
for (int i = season.Episodes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!season.Episodes[i].Requested)
|
||||
{
|
||||
season.Episodes.RemoveAt(i); // Remove the episode since it's not requested
|
||||
}
|
||||
}
|
||||
|
||||
if (season.Episodes.Any())
|
||||
{
|
||||
tvRequests.Add(season);
|
||||
}
|
||||
}
|
||||
|
||||
var user = await UserManager.GetUser(User.Identity.Name);
|
||||
var childRequest = new ChildRequests
|
||||
{
|
||||
Id = tv.Id,
|
||||
RequestType = RequestType.TvShow,
|
||||
RequestedDate = DateTime.UtcNow,
|
||||
Approved = false,
|
||||
RequestedUserId = user.Id,
|
||||
SeasonRequests = new List<SeasonRequests>()
|
||||
};
|
||||
|
||||
if (tv.RequestAll)
|
||||
{
|
||||
var episodes = await TvApi.EpisodeLookup(showInfo.id);
|
||||
foreach (var ep in episodes)
|
||||
{
|
||||
var season = childRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||
if (season == null)
|
||||
{
|
||||
childRequest.SeasonRequests.Add(new SeasonRequests
|
||||
{
|
||||
Episodes = new List<EpisodeRequests>{
|
||||
new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
}
|
||||
},
|
||||
SeasonNumber = ep.season,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
season.Episodes.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
});
|
||||
}
|
||||
}
|
||||
var tvBuilder = new TvShowRequestBuilder(TvApi);
|
||||
(await tvBuilder
|
||||
.GetShowInfo(tv.Id))
|
||||
.CreateTvList(tv)
|
||||
.CreateChild(tv, user.Id);
|
||||
|
||||
}
|
||||
else if (tv.LatestSeason)
|
||||
{
|
||||
var episodes = await TvApi.EpisodeLookup(showInfo.id);
|
||||
var latest = episodes.OrderBy(x => x.season).FirstOrDefault();
|
||||
var episodesRequests = new List<EpisodeRequests>();
|
||||
foreach (var ep in episodes)
|
||||
{
|
||||
episodesRequests.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
});
|
||||
}
|
||||
childRequest.SeasonRequests.Add(new SeasonRequests
|
||||
{
|
||||
Episodes = episodesRequests,
|
||||
SeasonNumber = latest.season,
|
||||
});
|
||||
}
|
||||
else if (tv.FirstSeason)
|
||||
{
|
||||
var episodes = await TvApi.EpisodeLookup(showInfo.id);
|
||||
var first = episodes.OrderByDescending(x => x.season).FirstOrDefault();
|
||||
var episodesRequests = new List<EpisodeRequests>();
|
||||
foreach (var ep in episodes)
|
||||
{
|
||||
if (ep.season == first.season)
|
||||
{
|
||||
episodesRequests.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
});
|
||||
}
|
||||
}
|
||||
childRequest.SeasonRequests.Add(new SeasonRequests
|
||||
{
|
||||
Episodes = episodesRequests,
|
||||
SeasonNumber = first.season,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's a custom request
|
||||
childRequest.SeasonRequests = tvRequests;
|
||||
}
|
||||
await tvBuilder.BuildEpisodes(tv);
|
||||
|
||||
var ruleResults = await RunRequestRules(childRequest);
|
||||
var ruleResults = await RunRequestRules(tvBuilder.ChildRequest);
|
||||
var results = ruleResults as RuleResult[] ?? ruleResults.ToArray();
|
||||
if (results.Any(x => !x.Success))
|
||||
{
|
||||
|
@ -180,7 +70,7 @@ namespace Ombi.Core.Engine
|
|||
foreach (var existingSeason in existingRequest.ChildRequests)
|
||||
foreach (var existing in existingSeason.SeasonRequests)
|
||||
{
|
||||
var newChild = childRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == existing.SeasonNumber);
|
||||
var newChild = tvBuilder.ChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == existing.SeasonNumber);
|
||||
if (newChild != null)
|
||||
{
|
||||
// We have some requests in this season...
|
||||
|
@ -197,32 +87,19 @@ namespace Ombi.Core.Engine
|
|||
if (!newChild.Episodes.Any())
|
||||
{
|
||||
// We may have removed all episodes
|
||||
childRequest.SeasonRequests.Remove(newChild);
|
||||
tvBuilder.ChildRequest.SeasonRequests.Remove(newChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the ID since this is a new child
|
||||
childRequest.Id = 0;
|
||||
return await AddExistingRequest(childRequest, existingRequest);
|
||||
tvBuilder.ChildRequest.Id = 0;
|
||||
return await AddExistingRequest(tvBuilder.ChildRequest, existingRequest);
|
||||
}
|
||||
// This is a new request
|
||||
|
||||
var model = new TvRequests
|
||||
{
|
||||
Id = tv.Id,
|
||||
Overview = showInfo.summary.RemoveHtml(),
|
||||
PosterPath = posterPath,
|
||||
Title = showInfo.name,
|
||||
ReleaseDate = firstAir,
|
||||
Status = showInfo.status,
|
||||
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
||||
TvDbId = tv.Id,
|
||||
ChildRequests = new List<ChildRequests>(),
|
||||
TotalSeasons = tv.SeasonRequests.Count()
|
||||
};
|
||||
model.ChildRequests.Add(childRequest);
|
||||
return await AddRequest(model);
|
||||
var newRequest = tvBuilder.CreateNewRequest(tv);
|
||||
return await AddRequest(newRequest.NewRequest);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TvRequests>> GetRequests(int count, int position)
|
||||
|
|
197
src/Ombi.Core/Helpers/TvShowRequestBuilder.cs
Normal file
197
src/Ombi.Core/Helpers/TvShowRequestBuilder.cs
Normal file
|
@ -0,0 +1,197 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TvMaze;
|
||||
using Ombi.Api.TvMaze.Models;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
|
||||
namespace Ombi.Core.Helpers
|
||||
{
|
||||
public class TvShowRequestBuilder
|
||||
{
|
||||
|
||||
public TvShowRequestBuilder(ITvMazeApi tvApi)
|
||||
{
|
||||
TvApi = tvApi;
|
||||
}
|
||||
|
||||
private ITvMazeApi TvApi { get; }
|
||||
|
||||
public ChildRequests ChildRequest { get; set; }
|
||||
public List<SeasonRequests> TvRequests { get; protected set; }
|
||||
public string PosterPath { get; protected set; }
|
||||
public DateTime FirstAir { get; protected set; }
|
||||
public TvRequests NewRequest { get; protected set; }
|
||||
protected TvMazeShow ShowInfo { get; set; }
|
||||
|
||||
public async Task<TvShowRequestBuilder> GetShowInfo(int id)
|
||||
{
|
||||
ShowInfo = await TvApi.ShowLookupByTheTvDbId(id);
|
||||
|
||||
DateTime.TryParse(ShowInfo.premiered, out DateTime dt);
|
||||
|
||||
FirstAir = dt;
|
||||
|
||||
// For some reason the poster path is always http
|
||||
PosterPath = ShowInfo.image?.medium.Replace("http:", "https:");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TvShowRequestBuilder CreateChild(SearchTvShowViewModel model, int userId)
|
||||
{
|
||||
ChildRequest = new ChildRequests
|
||||
{
|
||||
Id = model.Id,
|
||||
RequestType = RequestType.TvShow,
|
||||
RequestedDate = DateTime.UtcNow,
|
||||
Approved = false,
|
||||
RequestedUserId = userId,
|
||||
SeasonRequests = new List<SeasonRequests>()
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TvShowRequestBuilder CreateTvList(SearchTvShowViewModel tv)
|
||||
{
|
||||
TvRequests = new List<SeasonRequests>();
|
||||
// Only have the TV requests we actually requested and not everything
|
||||
foreach (var season in tv.SeasonRequests)
|
||||
{
|
||||
for (int i = season.Episodes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!season.Episodes[i].Requested)
|
||||
{
|
||||
season.Episodes.RemoveAt(i); // Remove the episode since it's not requested
|
||||
}
|
||||
}
|
||||
|
||||
if (season.Episodes.Any())
|
||||
{
|
||||
TvRequests.Add(season);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public async Task<TvShowRequestBuilder> BuildEpisodes(SearchTvShowViewModel tv)
|
||||
{
|
||||
if (tv.RequestAll)
|
||||
{
|
||||
var episodes = await TvApi.EpisodeLookup(ShowInfo.id);
|
||||
foreach (var ep in episodes)
|
||||
{
|
||||
var season = ChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||
if (season == null)
|
||||
{
|
||||
ChildRequest.SeasonRequests.Add(new SeasonRequests
|
||||
{
|
||||
Episodes = new List<EpisodeRequests>{
|
||||
new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
}
|
||||
},
|
||||
SeasonNumber = ep.season,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
season.Episodes.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (tv.LatestSeason)
|
||||
{
|
||||
var episodes = await TvApi.EpisodeLookup(ShowInfo.id);
|
||||
var latest = episodes.OrderBy(x => x.season).FirstOrDefault();
|
||||
var episodesRequests = new List<EpisodeRequests>();
|
||||
foreach (var ep in episodes)
|
||||
{
|
||||
episodesRequests.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
});
|
||||
}
|
||||
ChildRequest.SeasonRequests.Add(new SeasonRequests
|
||||
{
|
||||
Episodes = episodesRequests,
|
||||
SeasonNumber = latest.season,
|
||||
});
|
||||
}
|
||||
else if (tv.FirstSeason)
|
||||
{
|
||||
var episodes = await TvApi.EpisodeLookup(ShowInfo.id);
|
||||
var first = episodes.OrderByDescending(x => x.season).FirstOrDefault();
|
||||
var episodesRequests = new List<EpisodeRequests>();
|
||||
foreach (var ep in episodes)
|
||||
{
|
||||
if (ep.season == first.season)
|
||||
{
|
||||
episodesRequests.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = DateTime.Parse(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url
|
||||
});
|
||||
}
|
||||
}
|
||||
ChildRequest.SeasonRequests.Add(new SeasonRequests
|
||||
{
|
||||
Episodes = episodesRequests,
|
||||
SeasonNumber = first.season,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's a custom request
|
||||
ChildRequest.SeasonRequests = TvRequests;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TvShowRequestBuilder CreateNewRequest(SearchTvShowViewModel tv)
|
||||
{
|
||||
NewRequest = new TvRequests
|
||||
{
|
||||
Id = tv.Id,
|
||||
Overview = ShowInfo.summary.RemoveHtml(),
|
||||
PosterPath = PosterPath,
|
||||
Title = ShowInfo.name,
|
||||
ReleaseDate = FirstAir,
|
||||
Status = ShowInfo.status,
|
||||
ImdbId = ShowInfo.externals?.imdb ?? string.Empty,
|
||||
TvDbId = tv.Id,
|
||||
ChildRequests = new List<ChildRequests>(),
|
||||
TotalSeasons = tv.SeasonRequests.Count()
|
||||
};
|
||||
NewRequest.ChildRequests.Add(ChildRequest);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
//using System.Linq;
|
||||
//using Ombi.Store.Entities;
|
||||
//using Xunit;
|
||||
//using Xunit.Abstractions;
|
||||
|
||||
//namespace Ombi.Notifications.Tests
|
||||
//{
|
||||
// public class NotificationMessageResolverTests
|
||||
// {
|
||||
// public NotificationMessageResolverTests(ITestOutputHelper helper)
|
||||
// {
|
||||
// _resolver = new NotificationMessageResolver();
|
||||
// output = helper;
|
||||
// }
|
||||
|
||||
// private readonly NotificationMessageResolver _resolver;
|
||||
// private readonly ITestOutputHelper output;
|
||||
|
||||
// [Fact]
|
||||
// public void Resolved_ShouldResolve_RequestedUser()
|
||||
// {
|
||||
// var result = _resolver.ParseMessage(new NotificationTemplates
|
||||
// {
|
||||
// Subject = "This is a {RequestedUser}"
|
||||
// }, new NotificationMessageCurlys {RequestedUser = "Abc"});
|
||||
// output.WriteLine(result.Message);
|
||||
// //Assert.True(result.Message.Equals("This is a Abc"));
|
||||
|
||||
// Assert.Contains("11a", result.Message);
|
||||
// }
|
||||
// }
|
||||
//}
|
19
src/Ombi.Notifications.Tests/Ombi.Notifications.Tests.csproj
Normal file
19
src/Ombi.Notifications.Tests/Ombi.Notifications.Tests.csproj
Normal file
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.7.10" />
|
||||
<PackageReference Include="xunit" Version="2.2.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
9
src/Ombi.Notifications/NotificationMessageContent.cs
Normal file
9
src/Ombi.Notifications/NotificationMessageContent.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Ombi.Notifications
|
||||
{
|
||||
public class NotificationMessageContent
|
||||
{
|
||||
public string Subject { get; set; }
|
||||
public string Message { get; set; }
|
||||
public string Image { get; set; }
|
||||
}
|
||||
}
|
73
src/Ombi.Notifications/NotificationMessageCurlys.cs
Normal file
73
src/Ombi.Notifications/NotificationMessageCurlys.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
||||
namespace Ombi.Notifications
|
||||
{
|
||||
public class NotificationMessageCurlys
|
||||
{
|
||||
|
||||
public void Setup(FullBaseRequest req)
|
||||
{
|
||||
RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias)
|
||||
? req.RequestedUser.Username
|
||||
: req.RequestedUser.Alias;
|
||||
Title = req.Title;
|
||||
RequestedDate = req.RequestedDate.ToString("D");
|
||||
Type = req.RequestType.ToString();
|
||||
Overview = req.Overview;
|
||||
Year = req.ReleaseDate.Year.ToString();
|
||||
PosterImage = req.PosterPath;
|
||||
}
|
||||
|
||||
public void Setup(ChildRequests req)
|
||||
{
|
||||
RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias)
|
||||
? req.RequestedUser.Username
|
||||
: req.RequestedUser.Alias;
|
||||
Title = req.ParentRequest.Title;
|
||||
RequestedDate = req.RequestedDate.ToString("D");
|
||||
Type = req.RequestType.ToString();
|
||||
Overview = req.ParentRequest.Overview;
|
||||
Year = req.ParentRequest.ReleaseDate.Year.ToString();
|
||||
PosterImage = req.ParentRequest.PosterPath;
|
||||
// DO Episode and Season Lists
|
||||
}
|
||||
|
||||
// User Defined
|
||||
public string RequestedUser { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string RequestedDate { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string Issue { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public string Year { get; set; }
|
||||
public string EpisodesList { get; set; }
|
||||
public string SeasonsList { get; set; }
|
||||
public string PosterImage { get; set; }
|
||||
|
||||
// System Defined
|
||||
private string LongDate => DateTime.Now.ToString("D");
|
||||
private string ShortDate => DateTime.Now.ToString("d");
|
||||
private string LongTime => DateTime.Now.ToString("T");
|
||||
private string ShortTime => DateTime.Now.ToString("t");
|
||||
|
||||
public Dictionary<string, string> Curlys => new Dictionary<string, string>
|
||||
{
|
||||
{nameof(RequestedUser), RequestedUser },
|
||||
{nameof(Title), Title },
|
||||
{nameof(RequestedDate), RequestedDate },
|
||||
{nameof(Type), Type },
|
||||
{nameof(Issue), Issue },
|
||||
{nameof(LongDate),LongDate},
|
||||
{nameof(ShortDate),ShortDate},
|
||||
{nameof(LongTime),LongTime},
|
||||
{nameof(ShortTime),ShortTime},
|
||||
{nameof(Overview),Overview},
|
||||
{nameof(Year),Year},
|
||||
{nameof(EpisodesList),EpisodesList},
|
||||
{nameof(SeasonsList),SeasonsList},
|
||||
{nameof(PosterImage),PosterImage},
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,84 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
||||
namespace Ombi.Notifications
|
||||
{
|
||||
public class NotificationMessageContent
|
||||
{
|
||||
public string Subject { get; set; }
|
||||
public string Message { get; set; }
|
||||
public string Image { get; set; }
|
||||
}
|
||||
public class NotificationMessageCurlys
|
||||
{
|
||||
|
||||
public void Setup(FullBaseRequest req)
|
||||
{
|
||||
RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias)
|
||||
? req.RequestedUser.Username
|
||||
: req.RequestedUser.Alias;
|
||||
Title = req.Title;
|
||||
RequestedDate = req.RequestedDate.ToString("D");
|
||||
Type = req.RequestType.ToString();
|
||||
Overview = req.Overview;
|
||||
Year = req.ReleaseDate.Year.ToString();
|
||||
PosterImage = req.PosterPath;
|
||||
}
|
||||
|
||||
public void Setup(ChildRequests req)
|
||||
{
|
||||
RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias)
|
||||
? req.RequestedUser.Username
|
||||
: req.RequestedUser.Alias;
|
||||
Title = req.ParentRequest.Title;
|
||||
RequestedDate = req.RequestedDate.ToString("D");
|
||||
Type = req.RequestType.ToString();
|
||||
Overview = req.ParentRequest.Overview;
|
||||
Year = req.ParentRequest.ReleaseDate.Year.ToString();
|
||||
PosterImage = req.ParentRequest.PosterPath;
|
||||
// DO Episode and Season Lists
|
||||
}
|
||||
|
||||
// User Defined
|
||||
public string RequestedUser { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string RequestedDate { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string Issue { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public string Year { get; set; }
|
||||
public string EpisodesList { get; set; }
|
||||
public string SeasonsList { get; set; }
|
||||
public string PosterImage { get; set; }
|
||||
|
||||
// System Defined
|
||||
private string LongDate => DateTime.Now.ToString("D");
|
||||
private string ShortDate => DateTime.Now.ToString("d");
|
||||
private string LongTime => DateTime.Now.ToString("T");
|
||||
private string ShortTime => DateTime.Now.ToString("t");
|
||||
|
||||
public Dictionary<string, string> Curlys => new Dictionary<string, string>
|
||||
{
|
||||
{nameof(RequestedUser), RequestedUser },
|
||||
{nameof(Title), Title },
|
||||
{nameof(RequestedDate), RequestedDate },
|
||||
{nameof(Type), Type },
|
||||
{nameof(Issue), Issue },
|
||||
{nameof(LongDate),LongDate},
|
||||
{nameof(ShortDate),ShortDate},
|
||||
{nameof(LongTime),LongTime},
|
||||
{nameof(ShortTime),ShortTime},
|
||||
{nameof(Overview),Overview},
|
||||
{nameof(Year),Year},
|
||||
{nameof(EpisodesList),EpisodesList},
|
||||
{nameof(SeasonsList),SeasonsList},
|
||||
{nameof(PosterImage),PosterImage},
|
||||
};
|
||||
}
|
||||
|
||||
public class NotificationMessageResolver
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -113,20 +39,99 @@ namespace Ombi.Notifications
|
|||
private NotificationMessageContent Resolve(string body, string subject, IReadOnlyDictionary<string, string> parameters)
|
||||
{
|
||||
// Find the fields
|
||||
var bodyFields = FindCurlyFields(body);
|
||||
var subjectFields = FindCurlyFields(subject);
|
||||
var bodyFields = FindFields(body, StartChar, EndChar);
|
||||
var subjectFields = FindFields(subject, StartChar, EndChar);
|
||||
|
||||
//var conditionalFields = FindFields(body, '<', '>');
|
||||
//ProcessConditions(conditionalFields, parameters);
|
||||
|
||||
body = ReplaceFields(bodyFields, parameters, body);
|
||||
subject = ReplaceFields(subjectFields, parameters, subject);
|
||||
return new NotificationMessageContent { Message = body ?? string.Empty, Subject = subject ?? string.Empty};
|
||||
}
|
||||
|
||||
public IEnumerable<string> ProcessConditions(IEnumerable<string> conditionalFields, IReadOnlyDictionary<string, string> parameters)
|
||||
{
|
||||
foreach (var f in conditionalFields)
|
||||
{
|
||||
var field = f.ToLower();
|
||||
if (field.StartsWith("if"))
|
||||
{
|
||||
var ifPosition = field.IndexOf("if", StringComparison.Ordinal);
|
||||
Console.WriteLine(ifPosition);
|
||||
var identifierStart = field.Substring(ifPosition + 3);
|
||||
Console.WriteLine(identifierStart);
|
||||
var identifierEnd = identifierStart.IndexOf(' ');
|
||||
Console.WriteLine(identifierEnd);
|
||||
|
||||
var identitifier = identifierStart.Substring(ifPosition, identifierEnd);
|
||||
|
||||
if (identitifier.Equals("type"))
|
||||
{
|
||||
// Find the operator == or !=
|
||||
var stringWithoutIdentifier = identifierStart.Substring(identitifier.Length + 1);
|
||||
var operatorValue = stringWithoutIdentifier.Substring(0,2);
|
||||
|
||||
var stringWithoutOperator = stringWithoutIdentifier.Substring(operatorValue.Length + 1);
|
||||
var endPosition = stringWithoutOperator.IndexOf(' ');
|
||||
var comparison = stringWithoutOperator.Substring(0, endPosition);
|
||||
|
||||
if (operatorValue == "==")
|
||||
{
|
||||
var type = (RequestType)int.Parse(parameters["Type"]);
|
||||
if (comparison.Equals("Movie", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
if (type == RequestType.Movie)
|
||||
{
|
||||
// Get the text
|
||||
var stringWithoutComparison = stringWithoutOperator.Substring(comparison.Length + 2);
|
||||
var endString = stringWithoutComparison.IndexOf(' ');
|
||||
var text = stringWithoutComparison.Substring(0, endString - 1);
|
||||
field = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the text in the ELSE
|
||||
var stringWithoutComparison = stringWithoutOperator.Substring(comparison.Length + 2);
|
||||
var elseIndex = stringWithoutComparison.IndexOf("else", StringComparison.CurrentCultureIgnoreCase);
|
||||
var endIndex = stringWithoutComparison.IndexOf(' ');
|
||||
if (elseIndex >= 0)
|
||||
{
|
||||
var elseString = stringWithoutComparison.Substring(elseIndex, endIndex);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// No else
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(comparison.Equals("TvShow", StringComparison.CurrentCultureIgnoreCase) || comparison.Equals("Tv", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
if (type == RequestType.TvShow)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (operatorValue == "!=")
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return conditionalFields;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the curly fields.
|
||||
/// </summary>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <returns></returns>
|
||||
private IEnumerable<string> FindCurlyFields(string message)
|
||||
private IEnumerable<string> FindFields(string message, char start, char end)
|
||||
{
|
||||
if (string.IsNullOrEmpty(message))
|
||||
{
|
||||
|
@ -145,13 +150,13 @@ namespace Ombi.Notifications
|
|||
continue;
|
||||
}
|
||||
|
||||
if (c == StartChar) // Start of curly '{'
|
||||
if (c == start) // Start of curly '{'
|
||||
{
|
||||
insideCurly = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == EndChar) // End of curly '}'
|
||||
if (c == end) // End of curly '}'
|
||||
{
|
||||
fields.Add(currentWord); // We have finished the curly, add the word into the list
|
||||
currentWord = string.Empty;
|
||||
|
|
45
src/Ombi.sln
45
src/Ombi.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.6
|
||||
VisualStudioVersion = 15.0.26430.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
|
||||
EndProject
|
||||
|
@ -13,58 +13,60 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
Build\publish.bat = Build\publish.bat
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core", "Ombi.Core\Ombi.Core.csproj", "{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Core", "Ombi.Core\Ombi.Core.csproj", "{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Api", "Api", "{9293CA11-360A-4C20-A674-B9E794431BF5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.TheMovieDb", "Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj", "{132DA282-5894-4570-8916-D8C18ED2CE84}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.TheMovieDb", "Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj", "{132DA282-5894-4570-8916-D8C18ED2CE84}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api", "Ombi.Api\Ombi.Api.csproj", "{EA31F915-31F9-4318-B521-1500CDF40DDF}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api", "Ombi.Api\Ombi.Api.csproj", "{EA31F915-31F9-4318-B521-1500CDF40DDF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Helpers", "Ombi.Helpers\Ombi.Helpers.csproj", "{C182B435-1FAB-49C5-9BF9-F7F5C6EF3C94}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Store", "Ombi.Store\Ombi.Store.csproj", "{68086581-1EFD-4390-8100-47F87D1CB628}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.DependencyInjection", "Ombi.DependencyInjection\Ombi.DependencyInjection.csproj", "{B39E4558-C557-48E7-AA74-19C5CD809617}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.DependencyInjection", "Ombi.DependencyInjection\Ombi.DependencyInjection.csproj", "{B39E4558-C557-48E7-AA74-19C5CD809617}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Mapping", "Ombi.Mapping\Ombi.Mapping.csproj", "{63E63511-1C7F-4162-8F92-8F7391B3C8A3}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Mapping", "Ombi.Mapping\Ombi.Mapping.csproj", "{63E63511-1C7F-4162-8F92-8F7391B3C8A3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mappers", "Mappers", "{025FB189-2FFB-4F43-A64B-6F1B5A0D2065}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DI", "DI", "{410F36CF-9C60-428A-B191-6FD90610991A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Plex", "Ombi.Api.Plex\Ombi.Api.Plex.csproj", "{2E1A7B91-F29B-42BC-8F1E-1CF2DCC389BA}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Plex", "Ombi.Api.Plex\Ombi.Api.Plex.csproj", "{2E1A7B91-F29B-42BC-8F1E-1CF2DCC389BA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Schedule", "Ombi.Schedule\Ombi.Schedule.csproj", "{5B42ADD4-757A-47C1-9CC5-320829C5E665}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Schedule", "Ombi.Schedule\Ombi.Schedule.csproj", "{5B42ADD4-757A-47C1-9CC5-320829C5E665}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Emby", "Ombi.Api.Emby\Ombi.Api.Emby.csproj", "{08FF107D-31E1-470D-AF86-E09B015CEE06}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Emby", "Ombi.Api.Emby\Ombi.Api.Emby.csproj", "{08FF107D-31E1-470D-AF86-E09B015CEE06}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Sonarr", "Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj", "{CFB5E008-D0D0-43C0-AA06-89E49D17F384}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Sonarr", "Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj", "{CFB5E008-D0D0-43C0-AA06-89E49D17F384}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{6F42AB98-9196-44C4-B888-D5E409F415A1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.TvMaze", "Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj", "{0E8EF835-E4F0-4EE5-A2B6-678DEE973721}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.TvMaze", "Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj", "{0E8EF835-E4F0-4EE5-A2B6-678DEE973721}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Notifications", "Ombi.Notifications\Ombi.Notifications.csproj", "{E6EE2830-E4AC-4F2E-AD93-2C9305605761}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Notifications", "Ombi.Notifications\Ombi.Notifications.csproj", "{E6EE2830-E4AC-4F2E-AD93-2C9305605761}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notifications", "Notifications", "{EA30DD15-6280-4687-B370-2956EC2E54E5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Notifications.Templates", "Ombi.Notifications.Templates\Ombi.Notifications.Templates.csproj", "{6EE01B17-0966-4E11-8BC1-A5318A92AB1D}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Notifications.Templates", "Ombi.Notifications.Templates\Ombi.Notifications.Templates.csproj", "{6EE01B17-0966-4E11-8BC1-A5318A92AB1D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Settings", "Ombi.Settings\Ombi.Settings.csproj", "{AE3AA23D-5B66-42AF-B44E-B9B4D8856C6F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Settings", "Ombi.Settings\Ombi.Settings.csproj", "{AE3AA23D-5B66-42AF-B44E-B9B4D8856C6F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Trakt", "Ombi.Api.Trakt\Ombi.Api.Trakt.csproj", "{3880375C-1A7E-4D75-96EC-63B954C42FEA}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Trakt", "Ombi.Api.Trakt\Ombi.Api.Trakt.csproj", "{3880375C-1A7E-4D75-96EC-63B954C42FEA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core.Tests", "Ombi.Core.Tests\Ombi.Core.Tests.csproj", "{FC6A8F7C-9722-4AE4-960D-277ACB0E81CB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Core.Tests", "Ombi.Core.Tests\Ombi.Core.Tests.csproj", "{FC6A8F7C-9722-4AE4-960D-277ACB0E81CB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Radarr", "Ombi.Api.Radarr\Ombi.Api.Radarr.csproj", "{94D04C1F-E35A-499C-B0A0-9FADEBDF8336}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Radarr", "Ombi.Api.Radarr\Ombi.Api.Radarr.csproj", "{94D04C1F-E35A-499C-B0A0-9FADEBDF8336}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Discord", "Ombi.Api.Discord\Ombi.Api.Discord.csproj", "{5AF2B6D2-5CC6-49FE-928A-BA27AF52B194}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Discord", "Ombi.Api.Discord\Ombi.Api.Discord.csproj", "{5AF2B6D2-5CC6-49FE-928A-BA27AF52B194}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Updater", "Ombi.Updater\Ombi.Updater.csproj", "{6294A82D-4915-4FC3-B301-8F985716F34C}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Updater", "Ombi.Updater\Ombi.Updater.csproj", "{6294A82D-4915-4FC3-B301-8F985716F34C}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Update", "Update", "{D11FE57E-1E57-491D-A1D4-01AEF4BE5CB6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Notifications.Tests", "Ombi.Notifications.Tests\Ombi.Notifications.Tests.csproj", "{2C7836E7-B120-40A6-B641-DDAA02FBAE23}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -155,6 +157,10 @@ Global
|
|||
{6294A82D-4915-4FC3-B301-8F985716F34C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6294A82D-4915-4FC3-B301-8F985716F34C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6294A82D-4915-4FC3-B301-8F985716F34C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C7836E7-B120-40A6-B641-DDAA02FBAE23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C7836E7-B120-40A6-B641-DDAA02FBAE23}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C7836E7-B120-40A6-B641-DDAA02FBAE23}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C7836E7-B120-40A6-B641-DDAA02FBAE23}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -175,5 +181,6 @@ Global
|
|||
{94D04C1F-E35A-499C-B0A0-9FADEBDF8336} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{5AF2B6D2-5CC6-49FE-928A-BA27AF52B194} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{6294A82D-4915-4FC3-B301-8F985716F34C} = {D11FE57E-1E57-491D-A1D4-01AEF4BE5CB6}
|
||||
{2C7836E7-B120-40A6-B641-DDAA02FBAE23} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -16,11 +16,8 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
|||
|
||||
// Components
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
// Search
|
||||
import { SearchComponent } from './search/search.component';
|
||||
import { MovieSearchComponent } from './search/moviesearch.component';
|
||||
import { TvSearchComponent } from './search/tvsearch.component';
|
||||
import { SeriesInformationComponent } from './search/seriesinformation.component';
|
||||
|
||||
// Request
|
||||
import { RequestComponent } from './requests/request.component';
|
||||
|
@ -32,10 +29,10 @@ import { RequestCardComponent } from './request-grid/request-card.component';
|
|||
import { LoginComponent } from './login/login.component';
|
||||
import { LandingPageComponent } from './landingpage/landingpage.component';
|
||||
import { UserManagementComponent } from './usermanagement/usermanagement.component';
|
||||
import { UserManagementEditComponent } from './usermanagement/usermanagement-edit.component';
|
||||
import { PageNotFoundComponent } from './errors/not-found.component';
|
||||
|
||||
// Services
|
||||
import { SearchService } from './services/search.service';
|
||||
import { RequestService } from './services/request.service';
|
||||
import { NotificationService } from './services/notification.service';
|
||||
import { SettingsService } from './services/settings.service';
|
||||
|
@ -49,17 +46,17 @@ import { StatusService } from './services/status.service';
|
|||
// Modules
|
||||
import { SettingsModule } from './settings/settings.module';
|
||||
import { WizardModule } from './wizard/wizard.module';
|
||||
import { SearchModule } from './search/search.module';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '*', component: PageNotFoundComponent },
|
||||
{ path: '', redirectTo: '/search', pathMatch: 'full' },
|
||||
{ path: 'search', component: SearchComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'search/show/:id', component: SeriesInformationComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'requests', component: RequestComponent, canActivate: [AuthGuard] },
|
||||
//{ path: 'requests-grid', component: RequestGridComponent },
|
||||
{ path: 'login', component: LoginComponent },
|
||||
{ path: 'landingpage', component: LandingPageComponent },
|
||||
{ path: 'usermanagement', component: UserManagementComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'usermanagement/edit/:id', component: UserManagementEditComponent, canActivate: [AuthGuard] },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -77,6 +74,7 @@ const routes: Routes = [
|
|||
InfiniteScrollModule,
|
||||
AuthModule,
|
||||
WizardModule,
|
||||
SearchModule,
|
||||
DialogModule,
|
||||
MdButtonModule,
|
||||
NgbModule.forRoot(),
|
||||
|
@ -89,21 +87,17 @@ const routes: Routes = [
|
|||
declarations: [
|
||||
AppComponent,
|
||||
PageNotFoundComponent,
|
||||
SearchComponent,
|
||||
RequestComponent,
|
||||
LoginComponent,
|
||||
MovieSearchComponent,
|
||||
TvSearchComponent,
|
||||
LandingPageComponent,
|
||||
UserManagementComponent,
|
||||
MovieRequestsComponent,
|
||||
TvRequestsComponent,
|
||||
SeriesInformationComponent,
|
||||
//RequestGridComponent,
|
||||
RequestCardComponent,
|
||||
UserManagementEditComponent,
|
||||
],
|
||||
providers: [
|
||||
SearchService,
|
||||
RequestService,
|
||||
NotificationService,
|
||||
AuthService,
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
you can substitue the span of reauth email for a input with the email and
|
||||
include the remember me checkbox
|
||||
-->
|
||||
<div *ngIf="form">
|
||||
<div *ngIf="form && customizationSettings">
|
||||
<div class="container" id="login">
|
||||
<div class="card card-container">
|
||||
<!-- <img class="profile-img-card" src="//lh3.googleusercontent.com/-6V8xOA6M7BA/AAAAAAAAAAI/AAAAAAAAAAA/rzlHcD0KYwo/photo.jpg?sz=120" alt="" /> -->
|
||||
<div *ngIf="!customizationSettings.logo"><img id="profile-img" class="profile-img-card" src="/images/logo.png" /></div>
|
||||
<div *ngIf="!customizationSettings.logo"><img id="profile-img" class="profile-img-card" src="/images/ms-icon-150x150.png" /></div>
|
||||
<div *ngIf="customizationSettings.logo"><img id="profile-img" class="profile-img-card" [src]="customizationSettings.logo" /></div>
|
||||
<p id="profile-name" class="profile-name-card"></p>
|
||||
|
||||
|
|
45
src/Ombi/ClientApp/app/search/search.module.ts
Normal file
45
src/Ombi/ClientApp/app/search/search.module.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { NgModule, } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
import { SearchComponent } from './search.component';
|
||||
import { MovieSearchComponent } from './moviesearch.component';
|
||||
import { TvSearchComponent } from './tvsearch.component';
|
||||
import { SeriesInformationComponent } from './seriesinformation.component';
|
||||
|
||||
import { SearchService } from '../services/search.service';
|
||||
import { RequestService } from '../services/request.service';
|
||||
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'search', component: SearchComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'search/show/:id', component: SeriesInformationComponent, canActivate: [AuthGuard] },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
RouterModule.forChild(routes),
|
||||
NgbModule.forRoot(),
|
||||
],
|
||||
declarations: [
|
||||
SearchComponent,
|
||||
MovieSearchComponent,
|
||||
TvSearchComponent,
|
||||
SeriesInformationComponent
|
||||
],
|
||||
exports: [
|
||||
RouterModule
|
||||
],
|
||||
providers: [
|
||||
SearchService,
|
||||
RequestService
|
||||
],
|
||||
|
||||
})
|
||||
export class SearchModule { }
|
|
@ -20,6 +20,10 @@ export class IdentityService extends ServiceAuthHelpers {
|
|||
return this.http.get(this.url).map(this.extractData);
|
||||
}
|
||||
|
||||
getUserById(id: number): Observable<IUser> {
|
||||
return this.http.get(`${this.url}User/${id}`).map(this.extractData);
|
||||
}
|
||||
|
||||
getUsers(): Observable<IUser[]> {
|
||||
return this.http.get(`${this.url}Users`).map(this.extractData);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<h1>User Management</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
<div *ngIf="user">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" (click)="showEditDialog=false">×</button>
|
||||
<h4 class="modal-title">Editing User {{user?.username}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="username" class="control-label">Username</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="selectedUser.username" [readonly]="true" class="form-control form-control-custom " id="username" name="username" value="{{selectedUser?.username}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="alias" class="control-label">Alias</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="selectedUser.alias" class="form-control form-control-custom " id="alias" name="alias" value="{{selectedUser?.alias}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="alias" class="control-label">Email Address</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="selectedUser.emailAddress" class="form-control form-control-custom " id="emailAddress" name="emailAddress" value="{{selectedUser?.emailAddress}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let c of selectedUser.claims">
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" [(ngModel)]="c.enabled" [value]="c.value" id="create{{c.value}}" [attr.name]="'create' + c.value" ng-checked="c.enabled">
|
||||
<label for="create{{c.value}}">{{c.value}}</label>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger-outline" (click)="showEditDialog=false">Close</button>
|
||||
<button type="button" class="btn btn-primary-outline" (click)="updateUser()">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,31 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { IUser, ICheckbox } from '../interfaces/IUser';
|
||||
import { IdentityService } from '../services/identity.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
|
||||
templateUrl: './usermanagement-edit.component.html'
|
||||
})
|
||||
export class UserManagementEditComponent implements OnInit {
|
||||
constructor(private identityService: IdentityService, private route: ActivatedRoute) {
|
||||
this.route.params
|
||||
.subscribe(params => {
|
||||
this.userId = +params['id']; // (+) converts string 'id' to a number
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
this.identityService.getAllAvailableClaims().subscribe(x => this.availableClaims = x);
|
||||
this.identityService.getUserById(this.userId).subscribe(x => this.user = x);
|
||||
}
|
||||
|
||||
user: IUser;
|
||||
userId: number;
|
||||
|
||||
|
||||
availableClaims : ICheckbox[];
|
||||
|
||||
}
|
|
@ -112,7 +112,7 @@ namespace Ombi.Controllers
|
|||
/// Gets the user by the user id.
|
||||
/// </summary>
|
||||
/// <returns>Information about the user</returns>
|
||||
[HttpGet("Users/{id}")]
|
||||
[HttpGet("User/{id}")]
|
||||
public async Task<UserViewModel> GetUser(int id)
|
||||
{
|
||||
var type = typeof(OmbiClaims);
|
||||
|
@ -121,7 +121,7 @@ namespace Ombi.Controllers
|
|||
|
||||
var fields = fieldInfos.Where(fi => fi.IsLiteral && !fi.IsInitOnly).ToList();
|
||||
var allClaims = fields.Select(x => x.Name).ToList();
|
||||
var user = Mapper.Map<UserViewModel>(await IdentityManager.GetUser(id)).ToList();
|
||||
var user = Mapper.Map<UserViewModel>(await IdentityManager.GetUser(id));
|
||||
|
||||
|
||||
var userClaims = user.Claims.Select(x => x.Value);
|
||||
|
|
BIN
src/Ombi/wwwroot/images/ms-icon-150x150.png
Normal file
BIN
src/Ombi/wwwroot/images/ms-icon-150x150.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
src/Ombi/wwwroot/images/ms-icon-310x310.png
Normal file
BIN
src/Ombi/wwwroot/images/ms-icon-310x310.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
Loading…
Add table
Add a link
Reference in a new issue