mirror of https://github.com/Ombi-app/Ombi
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1244 lines
42 KiB
1244 lines
42 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
using AutoMapper;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Ombi.Api.Emby;
|
|
using Ombi.Api.Jellyfin;
|
|
using Ombi.Api.Github;
|
|
using Ombi.Attributes;
|
|
using Ombi.Core.Engine;
|
|
using Ombi.Core.Models.UI;
|
|
using Ombi.Core.Settings;
|
|
using Ombi.Core.Settings.Models;
|
|
using Ombi.Core.Settings.Models.External;
|
|
using Ombi.Helpers;
|
|
using Ombi.Models;
|
|
using Ombi.Schedule.Jobs.Radarr;
|
|
using Ombi.Settings.Settings.Models;
|
|
using Ombi.Settings.Settings.Models.External;
|
|
using Ombi.Settings.Settings.Models.Notifications;
|
|
using Ombi.Store.Entities;
|
|
using Ombi.Store.Repository;
|
|
using Ombi.Extensions;
|
|
using Quartz;
|
|
using Ombi.Schedule.Jobs;
|
|
using Ombi.Schedule.Jobs.Emby;
|
|
using Ombi.Schedule.Jobs.Jellyfin;
|
|
using Ombi.Schedule.Jobs.Sonarr;
|
|
using Ombi.Schedule.Jobs.Lidarr;
|
|
|
|
namespace Ombi.Controllers.V1
|
|
{
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// The Settings Controller
|
|
/// </summary>
|
|
[Admin]
|
|
[ApiV1]
|
|
[Produces("application/json")]
|
|
[ApiController]
|
|
public class SettingsController : ControllerBase
|
|
{
|
|
public SettingsController(ISettingsResolver resolver,
|
|
IMapper mapper,
|
|
INotificationTemplatesRepository templateRepo,
|
|
IEmbyApiFactory embyApi,
|
|
IJellyfinApiFactory jellyfinApi,
|
|
ICacheService memCache,
|
|
IGithubApi githubApi,
|
|
IRecentlyAddedEngine engine)
|
|
{
|
|
SettingsResolver = resolver;
|
|
Mapper = mapper;
|
|
TemplateRepository = templateRepo;
|
|
_embyApi = embyApi;
|
|
_jellyfinApi = jellyfinApi;
|
|
_cache = memCache;
|
|
_githubApi = githubApi;
|
|
_recentlyAdded = engine;
|
|
}
|
|
|
|
private ISettingsResolver SettingsResolver { get; }
|
|
private IMapper Mapper { get; }
|
|
private INotificationTemplatesRepository TemplateRepository { get; }
|
|
private readonly IEmbyApiFactory _embyApi;
|
|
private readonly IJellyfinApiFactory _jellyfinApi;
|
|
private readonly ICacheService _cache;
|
|
private readonly IGithubApi _githubApi;
|
|
private readonly IRecentlyAddedEngine _recentlyAdded;
|
|
|
|
/// <summary>
|
|
/// Gets the Ombi settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("ombi")]
|
|
public async Task<OmbiSettings> OmbiSettings()
|
|
{
|
|
return await Get<OmbiSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the base url.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("baseurl")]
|
|
[AllowAnonymous]
|
|
public async Task<string> GetBaseUrl()
|
|
{
|
|
var s = await Get<OmbiSettings>();
|
|
var baseUrl = s?.BaseUrl ?? string.Empty;
|
|
if (!baseUrl.EndsWith("/"))
|
|
{
|
|
baseUrl = baseUrl.TrimEnd('/');
|
|
}
|
|
if (baseUrl.StartsWith("/"))
|
|
{
|
|
baseUrl = baseUrl.TrimStart('/');
|
|
}
|
|
return baseUrl;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Ombi settings.
|
|
/// </summary>
|
|
/// <param name="ombi">The ombi.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("ombi")]
|
|
public async Task<bool> OmbiSettings([FromBody]OmbiSettings ombi)
|
|
{
|
|
ombi.Wizard = true;
|
|
_cache.Remove(CacheKeys.OmbiSettings);
|
|
return await Save(ombi);
|
|
}
|
|
|
|
[HttpGet("about")]
|
|
public AboutViewModel About()
|
|
{
|
|
var dbConfiguration = DatabaseExtensions.GetDatabaseConfiguration();
|
|
var storage = StartupSingleton.Instance;
|
|
var model = new AboutViewModel
|
|
{
|
|
FrameworkDescription = RuntimeInformation.FrameworkDescription,
|
|
OsArchitecture = RuntimeInformation.OSArchitecture.ToString(),
|
|
OsDescription = RuntimeInformation.OSDescription,
|
|
ProcessArchitecture = RuntimeInformation.ProcessArchitecture.ToString(),
|
|
ApplicationBasePath = Directory.GetCurrentDirectory(),
|
|
ExternalDatabaseType = dbConfiguration.ExternalDatabase.Type,
|
|
OmbiDatabaseType = dbConfiguration.OmbiDatabase.Type,
|
|
SettingsDatabaseType = dbConfiguration.SettingsDatabase.Type,
|
|
StoragePath = storage.StoragePath.HasValue() ? storage.StoragePath : "None Specified",
|
|
NotSupported = Directory.GetCurrentDirectory().Contains("qpkg")
|
|
};
|
|
|
|
|
|
var version = AssemblyHelper.GetRuntimeVersion();
|
|
var productArray = version.Split('-');
|
|
model.Version = productArray[0];
|
|
//model.Branch = productArray[1];
|
|
return model;
|
|
}
|
|
|
|
[HttpPost("ombi/resetApi")]
|
|
public async Task<string> ResetApiKey()
|
|
{
|
|
var currentSettings = await Get<OmbiSettings>();
|
|
currentSettings.ApiKey = Guid.NewGuid().ToString("N");
|
|
await Save(currentSettings);
|
|
|
|
return currentSettings.ApiKey;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Plex Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("plex")]
|
|
public async Task<PlexSettings> PlexSettings()
|
|
{
|
|
var s = await Get<PlexSettings>();
|
|
return s;
|
|
}
|
|
|
|
[HttpGet("clientid")]
|
|
[AllowAnonymous]
|
|
public async Task<string> GetClientId()
|
|
{
|
|
var s = await Get<PlexSettings>();
|
|
if (s.InstallId == Guid.Empty)
|
|
{
|
|
s.InstallId = Guid.NewGuid();
|
|
// Save it
|
|
await PlexSettings(s);
|
|
}
|
|
return s.InstallId.ToString("N");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Plex settings.
|
|
/// </summary>
|
|
/// <param name="plex">The plex.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("plex")]
|
|
public async Task<bool> PlexSettings([FromBody]PlexSettings plex)
|
|
{
|
|
if (plex?.InstallId == Guid.Empty || plex.InstallId == Guid.Empty)
|
|
{
|
|
plex.InstallId = Guid.NewGuid();
|
|
}
|
|
var result = await Save(plex);
|
|
|
|
if (result)
|
|
{
|
|
// Kick off the plex sync
|
|
await OmbiQuartz.TriggerJob(nameof(IPlexContentSync), "Plex");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Emby Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("emby")]
|
|
public async Task<EmbySettings> EmbySettings()
|
|
{
|
|
return await Get<EmbySettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Emby settings.
|
|
/// </summary>
|
|
/// <param name="emby">The emby.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("emby")]
|
|
public async Task<bool> EmbySettings([FromBody]EmbySettings emby)
|
|
{
|
|
if (emby.Enable)
|
|
{
|
|
var client = await _embyApi.CreateClient();
|
|
foreach (var server in emby.Servers)
|
|
{
|
|
var users = await client.GetUsers(server.FullUri, server.ApiKey);
|
|
var admin = users.FirstOrDefault(x => x.Policy.IsAdministrator);
|
|
server.AdministratorId = admin?.Id;
|
|
}
|
|
}
|
|
var result = await Save(emby);
|
|
if (result)
|
|
{
|
|
await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync), "Emby");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Jellyfin Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("jellyfin")]
|
|
public async Task<JellyfinSettings> JellyfinSettings()
|
|
{
|
|
return await Get<JellyfinSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Jellyfin settings.
|
|
/// </summary>
|
|
/// <param name="jellyfin">The jellyfin.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("jellyfin")]
|
|
public async Task<bool> JellyfinSettings([FromBody]JellyfinSettings jellyfin)
|
|
{
|
|
if (jellyfin.Enable)
|
|
{
|
|
var client = await _jellyfinApi.CreateClient();
|
|
foreach (var server in jellyfin.Servers)
|
|
{
|
|
var users = await client.GetUsers(server.FullUri, server.ApiKey);
|
|
var admin = users.FirstOrDefault(x => x.Policy.IsAdministrator);
|
|
server.AdministratorId = admin?.Id;
|
|
}
|
|
}
|
|
var result = await Save(jellyfin);
|
|
if (result)
|
|
{
|
|
await OmbiQuartz.TriggerJob(nameof(IJellyfinContentSync), "Jellyfin");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Landing Page Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("landingpage")]
|
|
[AllowAnonymous]
|
|
public async Task<LandingPageSettings> LandingPageSettings()
|
|
{
|
|
return await Get<LandingPageSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Landing Page settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("landingpage")]
|
|
public async Task<bool> LandingPageSettings([FromBody]LandingPageSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Customization Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("customization")]
|
|
[AllowAnonymous]
|
|
public async Task<CustomizationSettings> CustomizationSettings()
|
|
{
|
|
return await Get<CustomizationSettings>();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Gets the default language set in Ombi
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("defaultlanguage")]
|
|
[AllowAnonymous]
|
|
public async Task<string> GetDefaultLanguage()
|
|
{
|
|
var s = await Get<OmbiSettings>();
|
|
return s.DefaultLanguageCode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Customization settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("customization")]
|
|
public async Task<bool> CustomizationSettings([FromBody]CustomizationSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
[ApiExplorerSettings(IgnoreApi = true)]
|
|
[HttpPost("customization/urlverify")]
|
|
[AllowAnonymous]
|
|
public bool VerifyUrl([FromBody]UrlVerifyModel url)
|
|
{
|
|
return Uri.TryCreate(url.Url, UriKind.Absolute, out var __);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get's the preset themes available
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("themes")]
|
|
public async Task<IEnumerable<PresetThemeViewModel>> GetThemes()
|
|
{
|
|
var themes = await _githubApi.GetCakeThemes();
|
|
var cssThemes = themes.Where(x => x.name.Contains(".css", CompareOptions.IgnoreCase)
|
|
&& x.type.Equals("file", StringComparison.CurrentCultureIgnoreCase));
|
|
|
|
// 001-theBlur-leram84-1.0.css
|
|
// Number-Name-Author-Version.css
|
|
var model = new List<PresetThemeViewModel>();
|
|
foreach (var theme in cssThemes)
|
|
{
|
|
var parts = theme.name.Split("-");
|
|
model.Add(new PresetThemeViewModel
|
|
{
|
|
DisplayName = parts[1],
|
|
FullName = theme.name,
|
|
Version = parts[3].Replace(".css", string.Empty, StringComparison.CurrentCultureIgnoreCase),
|
|
Url = theme.download_url
|
|
});
|
|
}
|
|
|
|
// Display on UI - Current Theme = theBlur 1.0
|
|
// In dropdown display as "theBlur 1.1"
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Sonarr Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("sonarr")]
|
|
public async Task<SonarrSettings> SonarrSettings()
|
|
{
|
|
return await Get<SonarrSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Sonarr settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("sonarr")]
|
|
public async Task<bool> SonarrSettings([FromBody]SonarrSettings settings)
|
|
{
|
|
var result = await Save(settings);
|
|
if (result)
|
|
{
|
|
await OmbiQuartz.TriggerJob(nameof(ISonarrSync), "DVR");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Radarr Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("radarr")]
|
|
public async Task<RadarrCombinedModel> RadarrSettings()
|
|
{
|
|
return new RadarrCombinedModel
|
|
{
|
|
Radarr = await Get<RadarrSettings>(),
|
|
Radarr4K = await Get<Radarr4KSettings>(),
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Lidarr Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("lidarr")]
|
|
public async Task<LidarrSettings> LidarrSettings()
|
|
{
|
|
return await Get<LidarrSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Lidarr Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("lidarrenabled")]
|
|
[AllowAnonymous]
|
|
public async Task<bool> LidarrEnabled()
|
|
{
|
|
var settings = await Get<LidarrSettings>();
|
|
return settings.Enabled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Lidarr settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("lidarr")]
|
|
public async Task<bool> LidarrSettings([FromBody]LidarrSettings settings)
|
|
{
|
|
var lidarr = await Save(settings);
|
|
if (lidarr)
|
|
{
|
|
await OmbiQuartz.TriggerJob(nameof(ILidarrArtistSync), "DVR");
|
|
}
|
|
return lidarr;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Authentication settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("authentication")]
|
|
public async Task<bool> AuthenticationsSettings([FromBody]AuthenticationSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Authentication Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("authentication")]
|
|
[AllowAnonymous]
|
|
public async Task<AuthenticationSettings> AuthenticationsSettings()
|
|
{
|
|
return await Get<AuthenticationSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Radarr settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("radarr")]
|
|
public async Task<bool> RadarrSettings([FromBody]RadarrCombinedModel settings)
|
|
{
|
|
var radarrResult = await Save(settings.Radarr);
|
|
var radarr4kResult = await Save(settings.Radarr4K);
|
|
var result = radarr4kResult && radarrResult;
|
|
if (result)
|
|
{
|
|
_cache.Remove(CacheKeys.RadarrRootProfiles);
|
|
_cache.Remove(CacheKeys.RadarrQualityProfiles);
|
|
|
|
await OmbiQuartz.TriggerJob(nameof(IRadarrSync), "DVR");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Update settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("Update")]
|
|
public async Task<bool> UpdateSettings([FromBody]UpdateSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the UserManagement Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("UserManagement")]
|
|
public async Task<UserManagementSettings> UserManagementSettings()
|
|
{
|
|
return await Get<UserManagementSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the UserManagement settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("UserManagement")]
|
|
public async Task<bool> UserManagementSettings([FromBody]UserManagementSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Update Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("Update")]
|
|
public async Task<UpdateSettings> UpdateSettings()
|
|
{
|
|
var settings = await Get<UpdateSettings>();
|
|
|
|
return Mapper.Map<UpdateSettingsViewModel>(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the CouchPotatoSettings Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("CouchPotato")]
|
|
public async Task<CouchPotatoSettings> CouchPotatoSettings()
|
|
{
|
|
return await Get<CouchPotatoSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the CouchPotatoSettings settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("CouchPotato")]
|
|
public async Task<bool> CouchPotatoSettings([FromBody]CouchPotatoSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the DogNzbSettings Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("DogNzb")]
|
|
public async Task<DogNzbSettings> DogNzbSettings()
|
|
{
|
|
return await Get<DogNzbSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the DogNzbSettings settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("DogNzb")]
|
|
public async Task<bool> DogNzbSettings([FromBody]DogNzbSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the SickRage settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("SickRage")]
|
|
public async Task<bool> SickRageSettings([FromBody]SickRageSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the SickRage Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("SickRage")]
|
|
public async Task<SickRageSettings> SickRageSettings()
|
|
{
|
|
return await Get<SickRageSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the JobSettings Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("jobs")]
|
|
public async Task<JobSettings> JobSettings()
|
|
{
|
|
var j = await Get<JobSettings>();
|
|
// Get the defaults if the jobs are not set
|
|
j.RadarrSync = j.RadarrSync.HasValue() ? j.RadarrSync : JobSettingsHelper.Radarr(j);
|
|
j.SonarrSync = j.SonarrSync.HasValue() ? j.SonarrSync : JobSettingsHelper.Sonarr(j);
|
|
j.AutomaticUpdater = j.AutomaticUpdater.HasValue() ? j.AutomaticUpdater : JobSettingsHelper.Updater(j);
|
|
j.CouchPotatoSync = j.CouchPotatoSync.HasValue() ? j.CouchPotatoSync : JobSettingsHelper.CouchPotato(j);
|
|
j.EmbyContentSync = j.EmbyContentSync.HasValue() ? j.EmbyContentSync : JobSettingsHelper.EmbyContent(j);
|
|
j.JellyfinContentSync = j.JellyfinContentSync.HasValue() ? j.JellyfinContentSync : JobSettingsHelper.JellyfinContent(j);
|
|
j.PlexContentSync = j.PlexContentSync.HasValue() ? j.PlexContentSync : JobSettingsHelper.PlexContent(j);
|
|
j.UserImporter = j.UserImporter.HasValue() ? j.UserImporter : JobSettingsHelper.UserImporter(j);
|
|
j.SickRageSync = j.SickRageSync.HasValue() ? j.SickRageSync : JobSettingsHelper.SickRageSync(j);
|
|
j.PlexRecentlyAddedSync = j.PlexRecentlyAddedSync.HasValue() ? j.PlexRecentlyAddedSync : JobSettingsHelper.PlexRecentlyAdded(j);
|
|
j.Newsletter = j.Newsletter.HasValue() ? j.Newsletter : JobSettingsHelper.Newsletter(j);
|
|
j.LidarrArtistSync = j.LidarrArtistSync.HasValue() ? j.LidarrArtistSync : JobSettingsHelper.LidarrArtistSync(j);
|
|
j.IssuesPurge = j.IssuesPurge.HasValue() ? j.IssuesPurge : JobSettingsHelper.IssuePurge(j);
|
|
j.RetryRequests = j.RetryRequests.HasValue() ? j.RetryRequests : JobSettingsHelper.ResendFailedRequests(j);
|
|
j.MediaDatabaseRefresh = j.MediaDatabaseRefresh.HasValue() ? j.MediaDatabaseRefresh : JobSettingsHelper.MediaDatabaseRefresh(j);
|
|
j.AutoDeleteRequests = j.AutoDeleteRequests.HasValue() ? j.AutoDeleteRequests : JobSettingsHelper.AutoDeleteRequests(j);
|
|
j.EmbyRecentlyAddedSync = j.EmbyRecentlyAddedSync.HasValue() ? j.EmbyRecentlyAddedSync : JobSettingsHelper.EmbyRecentlyAddedSync(j);
|
|
j.PlexWatchlistImport = j.PlexWatchlistImport.HasValue() ? j.PlexWatchlistImport : JobSettingsHelper.PlexWatchlistImport(j);
|
|
|
|
return j;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the JobSettings settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("jobs")]
|
|
public async Task<JobSettingsViewModel> JobSettings([FromBody]JobSettings settings)
|
|
{
|
|
// Verify that we have correct CRON's
|
|
foreach (var propertyInfo in settings.GetType()
|
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
|
{
|
|
if (propertyInfo.Name.Equals("Id", StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
continue;
|
|
}
|
|
var expression = (string)propertyInfo.GetValue(settings, null);
|
|
|
|
try
|
|
{
|
|
var isValid = CronExpression.IsValidExpression(expression);
|
|
CronExpression cron = new CronExpression(expression);
|
|
DateTimeOffset? nextFireUTCTime = cron.GetNextValidTimeAfter(DateTime.Now);
|
|
if (!isValid || nextFireUTCTime == null)
|
|
{
|
|
return new JobSettingsViewModel
|
|
{
|
|
Message = $"{propertyInfo.Name} does not have a valid CRON Expression"
|
|
};
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return new JobSettingsViewModel
|
|
{
|
|
Message = $"{propertyInfo.Name} does not have a valid CRON Expression"
|
|
};
|
|
}
|
|
}
|
|
var result = await Save(settings);
|
|
|
|
return new JobSettingsViewModel
|
|
{
|
|
Result = result
|
|
};
|
|
}
|
|
|
|
[HttpPost("testcron")]
|
|
public CronTestModel TestCron([FromBody] CronViewModelBody body)
|
|
{
|
|
var model = new CronTestModel();
|
|
try
|
|
{
|
|
var isValid = CronExpression.IsValidExpression(body.Expression);
|
|
if (!isValid)
|
|
{
|
|
return new CronTestModel
|
|
{
|
|
Message = $"CRON Expression {body.Expression} is not valid"
|
|
};
|
|
}
|
|
|
|
model.Success = true;
|
|
return model;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return new CronTestModel
|
|
{
|
|
Message = $"CRON Expression {body.Expression} is not valid"
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Save the Vote settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("Issues")]
|
|
public async Task<bool> IssueSettings([FromBody]IssueSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Issues Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("Issues")]
|
|
[AllowAnonymous]
|
|
public async Task<IssueSettings> IssueSettings()
|
|
{
|
|
return await Get<IssueSettings>();
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpGet("issuesenabled")]
|
|
public async Task<bool> IssuesEnabled()
|
|
{
|
|
var issues = await Get<IssueSettings>();
|
|
return issues.Enabled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save the Vote settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("vote")]
|
|
public async Task<bool> VoteSettings([FromBody]VoteSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Vote Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("vote")]
|
|
public async Task<VoteSettings> VoteSettings()
|
|
{
|
|
return await Get<VoteSettings>();
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpGet("voteenabled")]
|
|
public async Task<bool> VoteEnabled()
|
|
{
|
|
var vote = await Get<VoteSettings>();
|
|
return vote.Enabled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save The Movie DB settings.
|
|
/// </summary>
|
|
/// <param name="settings">The settings.</param>
|
|
[HttpPost("themoviedb")]
|
|
public async Task<bool> TheMovieDbSettings([FromBody]TheMovieDbSettings settings)
|
|
{
|
|
return await Save(settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get The Movie DB settings.
|
|
/// </summary>
|
|
[HttpGet("themoviedb")]
|
|
public async Task<TheMovieDbSettings> TheMovieDbSettings()
|
|
{
|
|
return await Get<TheMovieDbSettings>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the email notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/email")]
|
|
public async Task<bool> EmailNotificationSettings([FromBody] EmailNotificationsViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<EmailNotificationSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Email Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/email")]
|
|
public async Task<EmailNotificationsViewModel> EmailNotificationSettings()
|
|
{
|
|
var emailSettings = await Get<EmailNotificationSettings>();
|
|
var model = Mapper.Map<EmailNotificationsViewModel>(emailSettings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Email);
|
|
|
|
return model;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Gets the Email Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/email/enabled")]
|
|
[AllowAnonymous]
|
|
public async Task<bool> EmailNotificationSettingsEnabled()
|
|
{
|
|
var emailSettings = await Get<EmailNotificationSettings>();
|
|
return emailSettings.Enabled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the discord notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/discord")]
|
|
public async Task<bool> DiscordNotificationSettings([FromBody] DiscordNotificationsViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<DiscordNotificationSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the discord Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/discord")]
|
|
public async Task<DiscordNotificationsViewModel> DiscordNotificationSettings()
|
|
{
|
|
var emailSettings = await Get<DiscordNotificationSettings>();
|
|
var model = Mapper.Map<DiscordNotificationsViewModel>(emailSettings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Discord);
|
|
|
|
return model;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Saves the telegram notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/telegram")]
|
|
public async Task<bool> TelegramNotificationSettings([FromBody] TelegramNotificationsViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<TelegramSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the telegram Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/telegram")]
|
|
public async Task<TelegramNotificationsViewModel> TelegramNotificationSettings()
|
|
{
|
|
var emailSettings = await Get<TelegramSettings>();
|
|
var model = Mapper.Map<TelegramNotificationsViewModel>(emailSettings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Telegram);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the pushbullet notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/pushbullet")]
|
|
public async Task<bool> PushbulletNotificationSettings([FromBody] PushbulletNotificationViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<PushbulletSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the pushbullet Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/pushbullet")]
|
|
public async Task<PushbulletNotificationViewModel> PushbulletNotificationSettings()
|
|
{
|
|
var settings = await Get<PushbulletSettings>();
|
|
var model = Mapper.Map<PushbulletNotificationViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Pushbullet);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the pushover notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/pushover")]
|
|
public async Task<bool> PushoverNotificationSettings([FromBody] PushoverNotificationViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<PushoverSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the pushover Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/pushover")]
|
|
public async Task<PushoverNotificationViewModel> PushoverNotificationSettings()
|
|
{
|
|
var settings = await Get<PushoverSettings>();
|
|
var model = Mapper.Map<PushoverNotificationViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Pushover);
|
|
|
|
return model;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Saves the slack notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/slack")]
|
|
public async Task<bool> SlacktNotificationSettings([FromBody] SlackNotificationsViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<SlackNotificationSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the slack Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/slack")]
|
|
public async Task<SlackNotificationsViewModel> SlackNotificationSettings()
|
|
{
|
|
var settings = await Get<SlackNotificationSettings>();
|
|
var model = Mapper.Map<SlackNotificationsViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Slack);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the Mattermost notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/mattermost")]
|
|
public async Task<bool> MattermostNotificationSettings([FromBody] MattermostNotificationsViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<MattermostNotificationSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Mattermost Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/mattermost")]
|
|
public async Task<MattermostNotificationsViewModel> MattermostNotificationSettings()
|
|
{
|
|
var settings = await Get<MattermostNotificationSettings>();
|
|
var model = Mapper.Map<MattermostNotificationsViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Mattermost);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Twilio Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/twilio")]
|
|
public async Task<TwilioSettingsViewModel> TwilioNotificationSettings()
|
|
{
|
|
var settings = await Get<TwilioSettings>();
|
|
var model = Mapper.Map<TwilioSettingsViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
if (model.WhatsAppSettings == null)
|
|
{
|
|
model.WhatsAppSettings = new WhatsAppSettingsViewModel();
|
|
}
|
|
model.WhatsAppSettings.NotificationTemplates = BuildTemplates(NotificationAgent.WhatsApp);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the Mattermost notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/twilio")]
|
|
public async Task<bool> TwilioNotificationSettings([FromBody] TwilioSettingsViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<TwilioSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.WhatsAppSettings.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the Mobile notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/mobile")]
|
|
public async Task<bool> MobileNotificationSettings([FromBody] MobileNotificationsViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<MobileNotificationSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Mobile Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/mobile")]
|
|
public async Task<MobileNotificationsViewModel> MobileNotificationSettings()
|
|
{
|
|
var settings = await Get<MobileNotificationSettings>();
|
|
var model = Mapper.Map<MobileNotificationsViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Mobile);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the gotify notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/gotify")]
|
|
public async Task<bool> GotifyNotificationSettings([FromBody] GotifyNotificationViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<GotifySettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the gotify Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/gotify")]
|
|
public async Task<GotifyNotificationViewModel> GotifyNotificationSettings()
|
|
{
|
|
var settings = await Get<GotifySettings>();
|
|
var model = Mapper.Map<GotifyNotificationViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Gotify);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the webhook notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/webhook")]
|
|
public async Task<bool> WebhookNotificationSettings([FromBody] WebhookNotificationViewModel model)
|
|
{
|
|
var settings = Mapper.Map<WebhookSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the webhook notification settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/webhook")]
|
|
public async Task<WebhookNotificationViewModel> WebhookNotificationSettings()
|
|
{
|
|
var settings = await Get<WebhookSettings>();
|
|
var model = Mapper.Map<WebhookNotificationViewModel>(settings);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the Newsletter notification settings.
|
|
/// </summary>
|
|
/// <param name="model">The model.</param>
|
|
/// <returns></returns>
|
|
[HttpPost("notifications/newsletter")]
|
|
public async Task<bool> NewsletterSettings([FromBody] NewsletterNotificationViewModel model)
|
|
{
|
|
// Save the email settings
|
|
var settings = Mapper.Map<NewsletterSettings>(model);
|
|
var result = await Save(settings);
|
|
|
|
// Save the templates
|
|
await TemplateRepository.Update(model.NotificationTemplate);
|
|
|
|
return result;
|
|
}
|
|
|
|
[ApiExplorerSettings(IgnoreApi = true)]
|
|
[HttpPost("notifications/newsletterdatabase")]
|
|
public async Task<bool> UpdateNewsletterDatabase()
|
|
{
|
|
return await _recentlyAdded.UpdateRecentlyAddedDatabase();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Newsletter Notification Settings.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("notifications/newsletter")]
|
|
public async Task<NewsletterNotificationViewModel> NewsletterSettings()
|
|
{
|
|
var settings = await Get<NewsletterSettings>();
|
|
var model = Mapper.Map<NewsletterNotificationViewModel>(settings);
|
|
|
|
// Lookup to see if we have any templates saved
|
|
var templates = BuildTemplates(NotificationAgent.Email, true);
|
|
model.NotificationTemplate = templates.FirstOrDefault(x => x.NotificationType == NotificationType.Newsletter);
|
|
return model;
|
|
}
|
|
|
|
private List<NotificationTemplates> BuildTemplates(NotificationAgent agent, bool showNewsletter = false)
|
|
{
|
|
var templates = TemplateRepository.GetAllTemplates(agent);
|
|
if (!showNewsletter)
|
|
{
|
|
// Make sure we do not display the newsletter
|
|
templates = templates.Where(x => x.NotificationType != NotificationType.Newsletter);
|
|
}
|
|
if (agent != NotificationAgent.Email)
|
|
{
|
|
templates = templates.Where(x => x.NotificationType != NotificationType.WelcomeEmail);
|
|
}
|
|
|
|
var tem = templates.ToList();
|
|
return tem.OrderBy(x => x.NotificationType.ToString()).ToList();
|
|
}
|
|
|
|
private async Task<T> Get<T>()
|
|
{
|
|
var settings = SettingsResolver.Resolve<T>();
|
|
return await settings.GetSettingsAsync();
|
|
}
|
|
|
|
private async Task<bool> Save<T>(T settingsModel)
|
|
{
|
|
var settings = SettingsResolver.Resolve<T>();
|
|
return await settings.SaveSettingsAsync(settingsModel);
|
|
}
|
|
}
|
|
}
|