From b287c8655fecdafb18fd3331486d0ad9e3f2a97d Mon Sep 17 00:00:00 2001 From: anonaut Date: Mon, 13 Mar 2017 23:43:42 +0100 Subject: [PATCH 01/42] Implemented mattermost notifications based on slack notification --- Ombi.Api.Interfaces/IMattermostApi.cs | 37 +++++ .../Ombi.Api.Interfaces.csproj | 1 + .../MattermostNotificationBody.cs | 54 ++++++ Ombi.Api.Models/Ombi.Api.Models.csproj | 1 + Ombi.Api/MattermostApi.cs | 58 +++++++ Ombi.Api/Ombi.Api.csproj | 1 + .../NotificationMessageResolver.cs | 3 + Ombi.Core/Notification/TransportType.cs | 3 +- Ombi.Core/Ombi.Core.csproj | 1 + .../MattermostNotificationSettings.cs | 12 ++ .../SettingModels/NotificationSettingsV2.cs | 2 + .../Notification/MattermostNotification.cs | 156 ++++++++++++++++++ Ombi.Services/Ombi.Services.csproj | 1 + Ombi.UI.Tests/AdminModuleTests.cs | 6 + Ombi.UI/Modules/Admin/AdminModule.cs | 76 ++++++++- Ombi.UI/NinjectModules/ApiModule.cs | 1 + Ombi.UI/Ombi.UI.csproj | 4 + Ombi.UI/Startup.cs | 4 + .../Validators/MattermostSettingsValidator.cs | 40 +++++ .../Admin/MattermostNotifications.cshtml | 119 +++++++++++++ Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml | 1 + 21 files changed, 579 insertions(+), 2 deletions(-) create mode 100644 Ombi.Api.Interfaces/IMattermostApi.cs create mode 100644 Ombi.Api.Models/Notifications/MattermostNotificationBody.cs create mode 100644 Ombi.Api/MattermostApi.cs create mode 100644 Ombi.Core/SettingModels/MattermostNotificationSettings.cs create mode 100644 Ombi.Services/Notification/MattermostNotification.cs create mode 100644 Ombi.UI/Validators/MattermostSettingsValidator.cs create mode 100644 Ombi.UI/Views/Admin/MattermostNotifications.cshtml diff --git a/Ombi.Api.Interfaces/IMattermostApi.cs b/Ombi.Api.Interfaces/IMattermostApi.cs new file mode 100644 index 000000000..e7db46b75 --- /dev/null +++ b/Ombi.Api.Interfaces/IMattermostApi.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: IMattermostApi.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System.Threading.Tasks; +using Ombi.Api.Models.Notifications; + +namespace Ombi.Api.Interfaces +{ + public interface IMattermostApi + { + Task PushAsync(string webhook, MattermostNotificationBody message); + } +} \ No newline at end of file diff --git a/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj b/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj index c8c1ca938..3d6e285bf 100644 --- a/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj +++ b/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj @@ -63,6 +63,7 @@ + diff --git a/Ombi.Api.Models/Notifications/MattermostNotificationBody.cs b/Ombi.Api.Models/Notifications/MattermostNotificationBody.cs new file mode 100644 index 000000000..a179019cd --- /dev/null +++ b/Ombi.Api.Models/Notifications/MattermostNotificationBody.cs @@ -0,0 +1,54 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: MattermostNotificationBody.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using Newtonsoft.Json; + +namespace Ombi.Api.Models.Notifications +{ + public class MattermostNotificationBody + { + [JsonConstructor] + public MattermostNotificationBody() + { + username = "Ombi"; + } + + [JsonIgnore] + private string _username; + public string username + { + get { return _username; } + set + { + if (!string.IsNullOrEmpty(value)) + _username = value; + } + } + public string channel { get; set; } + public string text { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Ombi.Api.Models.csproj b/Ombi.Api.Models/Ombi.Api.Models.csproj index 39df12460..92e4447ba 100644 --- a/Ombi.Api.Models/Ombi.Api.Models.csproj +++ b/Ombi.Api.Models/Ombi.Api.Models.csproj @@ -69,6 +69,7 @@ + diff --git a/Ombi.Api/MattermostApi.cs b/Ombi.Api/MattermostApi.cs new file mode 100644 index 000000000..c777e824b --- /dev/null +++ b/Ombi.Api/MattermostApi.cs @@ -0,0 +1,58 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: PlexApi.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; +using System.Threading.Tasks; +using Ombi.Api.Interfaces; +using Ombi.Api.Models.Notifications; +using RestSharp; + +namespace Ombi.Api +{ + public class MattermostApi : IMattermostApi + { + public async Task PushAsync(string webhook, MattermostNotificationBody message) + { + var request = new RestRequest + { + Method = Method.POST, + Resource = "/" + }; + + request.AddJsonBody(message); + + var api = new ApiRequest(); + return await Task.Run( + () => + { + var result = api.Execute(request, new Uri(webhook)); + return result.Content; + }); + } + } +} + diff --git a/Ombi.Api/Ombi.Api.csproj b/Ombi.Api/Ombi.Api.csproj index b9e674cc2..ba4a0e7ec 100644 --- a/Ombi.Api/Ombi.Api.csproj +++ b/Ombi.Api/Ombi.Api.csproj @@ -80,6 +80,7 @@ + diff --git a/Ombi.Core/Notification/NotificationMessageResolver.cs b/Ombi.Core/Notification/NotificationMessageResolver.cs index f5f0b90f9..fee5eeb00 100644 --- a/Ombi.Core/Notification/NotificationMessageResolver.cs +++ b/Ombi.Core/Notification/NotificationMessageResolver.cs @@ -70,6 +70,9 @@ namespace Ombi.Core.Notification case TransportType.Slack: content = notification.SlackNotification; break; + case TransportType.Mattermost: + content = notification.MattermostNotification; + break; default: throw new ArgumentOutOfRangeException(nameof(transportType), transportType, null); } diff --git a/Ombi.Core/Notification/TransportType.cs b/Ombi.Core/Notification/TransportType.cs index f37ab4404..fbed9b3b0 100644 --- a/Ombi.Core/Notification/TransportType.cs +++ b/Ombi.Core/Notification/TransportType.cs @@ -31,6 +31,7 @@ namespace Ombi.Core.Notification Email, Pushbullet, Pushover, - Slack + Slack, + Mattermost } } \ No newline at end of file diff --git a/Ombi.Core/Ombi.Core.csproj b/Ombi.Core/Ombi.Core.csproj index f3f05b9da..747921e79 100644 --- a/Ombi.Core/Ombi.Core.csproj +++ b/Ombi.Core/Ombi.Core.csproj @@ -135,6 +135,7 @@ + diff --git a/Ombi.Core/SettingModels/MattermostNotificationSettings.cs b/Ombi.Core/SettingModels/MattermostNotificationSettings.cs new file mode 100644 index 000000000..3ae1eeb8b --- /dev/null +++ b/Ombi.Core/SettingModels/MattermostNotificationSettings.cs @@ -0,0 +1,12 @@ +using System; +using Newtonsoft.Json; + +namespace Ombi.Core.SettingModels +{ + public sealed class MattermostNotificationSettings : NotificationSettings + { + public string WebhookUrl { get; set; } + public string Channel { get; set; } + public string Username { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Core/SettingModels/NotificationSettingsV2.cs b/Ombi.Core/SettingModels/NotificationSettingsV2.cs index 2380d70f1..cf0209692 100644 --- a/Ombi.Core/SettingModels/NotificationSettingsV2.cs +++ b/Ombi.Core/SettingModels/NotificationSettingsV2.cs @@ -51,11 +51,13 @@ namespace Ombi.Core.SettingModels } }; SlackNotification = new List(); + MattermostNotification = new List(); PushoverNotification = new List(); PushbulletNotification = new List(); } public List EmailNotification { get; set; } public List SlackNotification { get; set; } + public List MattermostNotification { get; set; } public List PushbulletNotification { get; set; } public List PushoverNotification { get; set; } } diff --git a/Ombi.Services/Notification/MattermostNotification.cs b/Ombi.Services/Notification/MattermostNotification.cs new file mode 100644 index 000000000..9d8cdbaf9 --- /dev/null +++ b/Ombi.Services/Notification/MattermostNotification.cs @@ -0,0 +1,156 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: MattermostNotification.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; +using System.Threading.Tasks; +using NLog; +using Ombi.Api.Interfaces; +using Ombi.Api.Models.Notifications; +using Ombi.Core; +using Ombi.Core.Models; +using Ombi.Core.SettingModels; +using Ombi.Services.Interfaces; + +namespace Ombi.Services.Notification +{ + public class MattermostNotification : INotification + { + public MattermostNotification(IMattermostApi api, ISettingsService sn) + { + Api = api; + Settings = sn; + } + + public string NotificationName => "MattermostNotification"; + + private IMattermostApi Api { get; } + private ISettingsService Settings { get; } + private static Logger Log = LogManager.GetCurrentClassLogger(); + + + public async Task NotifyAsync(NotificationModel model) + { + var settings = Settings.GetSettings(); + + await NotifyAsync(model, settings); + } + + public async Task NotifyAsync(NotificationModel model, Settings settings) + { + if (settings == null) await NotifyAsync(model); + + var pushSettings = (MattermostNotificationSettings)settings; + if (!ValidateConfiguration(pushSettings)) + { + Log.Error("Settings for Mattermost was not correct, we cannot push a notification"); + return; + } + + switch (model.NotificationType) + { + case NotificationType.NewRequest: + await PushNewRequestAsync(model, pushSettings); + break; + case NotificationType.Issue: + await PushIssueAsync(model, pushSettings); + break; + case NotificationType.RequestAvailable: + break; + case NotificationType.RequestApproved: + break; + case NotificationType.AdminNote: + break; + case NotificationType.Test: + await PushTest(pushSettings); + break; + case NotificationType.RequestDeclined: + break; + case NotificationType.ItemAddedToFaultQueue: + await PushFaultQueue(model, pushSettings); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private async Task PushNewRequestAsync(NotificationModel model, MattermostNotificationSettings settings) + { + var message = $"{model.Title} has been requested by user: {model.User}"; + await Push(settings, message); + } + + private async Task PushIssueAsync(NotificationModel model, MattermostNotificationSettings settings) + { + var message = $"A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}"; + await Push(settings, message); + } + + private async Task PushTest(MattermostNotificationSettings settings) + { + var message = $"This is a test from Ombi, if you can see this then we have successfully pushed a notification!"; + await Push(settings, message); + } + + private async Task PushFaultQueue(NotificationModel model, MattermostNotificationSettings settings) + { + var message = $"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying"; + await Push(settings, message); + } + + private async Task Push(MattermostNotificationSettings config, string message) + { + try + { + var notification = new MattermostNotificationBody { username = config.Username, channel = config.Channel ?? string.Empty, text = message }; + + var result = await Api.PushAsync(config.WebhookUrl, notification); + if (!result.Equals("ok")) + { + Log.Error("Mattermost returned a message that was not 'ok', the notification did not get pushed"); + Log.Error($"Message that mattermost returned: {result}"); + } + } + catch (Exception e) + { + Log.Error(e); + } + } + + private bool ValidateConfiguration(MattermostNotificationSettings settings) + { + if (!settings.Enabled) + { + return false; + } + if (string.IsNullOrEmpty(settings.WebhookUrl)) + { + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/Ombi.Services/Ombi.Services.csproj b/Ombi.Services/Ombi.Services.csproj index 6705cf939..d59173d7d 100644 --- a/Ombi.Services/Ombi.Services.csproj +++ b/Ombi.Services/Ombi.Services.csproj @@ -136,6 +136,7 @@ + diff --git a/Ombi.UI.Tests/AdminModuleTests.cs b/Ombi.UI.Tests/AdminModuleTests.cs index 62e4bf514..c612f92de 100644 --- a/Ombi.UI.Tests/AdminModuleTests.cs +++ b/Ombi.UI.Tests/AdminModuleTests.cs @@ -72,8 +72,10 @@ namespace Ombi.UI.Tests private Mock Cache { get; set; } private Mock> Log { get; set; } private Mock> SlackSettings { get; set; } + private Mock> MattermostSettings { get; set; } private Mock> LandingPageSettings { get; set; } private Mock SlackApi { get; set; } + private Mock MattermostApi { get; set; } private Mock Analytics { get; set; } private Mock> NotifyV2 { get; set; } private Mock RecentlyAdded { get; set; } @@ -113,6 +115,8 @@ namespace Ombi.UI.Tests Log = new Mock>(); SlackApi = new Mock(); SlackSettings = new Mock>(); + MattermostApi = new Mock(); + MattermostSettings = new Mock>(); LandingPageSettings = new Mock>(); ScheduledJobsSettingsMock = new Mock>(); RecorderMock = new Mock(); @@ -146,8 +150,10 @@ namespace Ombi.UI.Tests with.Dependency(Cache.Object); with.Dependency(Log.Object); with.Dependency(SlackApi.Object); + with.Dependency(MattermostApi.Object); with.Dependency(LandingPageSettings.Object); with.Dependency(SlackSettings.Object); + with.Dependency(MattermostSettings.Object); with.Dependency(ScheduledJobsSettingsMock.Object); with.Dependency(RecorderMock.Object); with.Dependency(RecentlyAdded.Object); diff --git a/Ombi.UI/Modules/Admin/AdminModule.cs b/Ombi.UI/Modules/Admin/AdminModule.cs index 97a610441..8fd242769 100644 --- a/Ombi.UI/Modules/Admin/AdminModule.cs +++ b/Ombi.UI/Modules/Admin/AdminModule.cs @@ -86,9 +86,11 @@ namespace Ombi.UI.Modules.Admin private INotificationService NotificationService { get; } private ICacheProvider Cache { get; } private ISettingsService SlackSettings { get; } + private ISettingsService MattermostSettings { get; } private ISettingsService LandingSettings { get; } private ISettingsService ScheduledJobSettings { get; } private ISlackApi SlackApi { get; } + private IMattermostApi MattermostApi { get; } private IJobRecord JobRecorder { get; } private IAnalytics Analytics { get; } private IRecentlyAdded RecentlyAdded { get; } @@ -119,7 +121,8 @@ namespace Ombi.UI.Modules.Admin ISettingsService headphones, ISettingsService logs, ICacheProvider cache, ISettingsService slackSettings, - ISlackApi slackApi, ISettingsService lp, + ISlackApi slackApi, ISettingsService mattermostSettings, + IMattermostApi mattermostApi, ISettingsService lp, ISettingsService scheduler, IJobRecord rec, IAnalytics analytics, ISettingsService notifyService, IRecentlyAdded recentlyAdded, ISettingsService watcherSettings , @@ -149,6 +152,8 @@ namespace Ombi.UI.Modules.Admin Cache = cache; SlackSettings = slackSettings; SlackApi = slackApi; + MattermostSettings = mattermostSettings; + MattermostApi = mattermostApi; LandingSettings = lp; ScheduledJobSettings = scheduler; JobRecorder = rec; @@ -222,6 +227,10 @@ namespace Ombi.UI.Modules.Admin Get["/slacknotification"] = _ => SlackNotifications(); Post["/slacknotification"] = _ => SaveSlackNotifications(); + Post["/testmattermostnotification", true] = async (x, ct) => await TestMattermostNotification(); + Get["/mattermostnotification"] = _ => MattermostNotifications(); + Post["/mattermostnotification"] = _ => SaveMattermostNotifications(); + Post["/testdiscordnotification", true] = async (x, ct) => await TestDiscordNotification(); Get["/discordnotification", true] = async (x, ct) => await DiscordNotification(); Post["/discordnotification", true] = async (x, ct) => await SaveDiscordNotifications(); @@ -957,6 +966,71 @@ namespace Ombi.UI.Modules.Admin : new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." }); } + private async Task TestMattermostNotification() + { + var settings = this.BindAndValidate(); + if (!ModelValidationResult.IsValid) + { + return Response.AsJson(ModelValidationResult.SendJsonError()); + } + var notificationModel = new NotificationModel + { + NotificationType = NotificationType.Test, + DateTime = DateTime.Now + }; + + var currentMattermostSettings = await MattermostSettings.GetSettingsAsync(); + try + { + NotificationService.Subscribe(new MattermostNotification(MattermostApi, MattermostSettings)); + settings.Enabled = true; + await NotificationService.Publish(notificationModel, settings); + Log.Info("Sent mattermost notification test"); + } + catch (Exception e) + { + Log.Error(e, "Failed to subscribe and publish test Mattermost Notification"); + } + finally + { + if (!currentMattermostSettings.Enabled) + { + NotificationService.UnSubscribe(new MattermostNotification(MattermostApi, MattermostSettings)); + } + } + return Response.AsJson(new JsonResponseModel { Result = true, Message = "Successfully sent a test Mattermost Notification! If you do not receive it please check the logs." }); + } + + private Negotiator MattermostNotifications() + { + var settings = MattermostSettings.GetSettings(); + return View["MattermostNotifications", settings]; + } + + private Response SaveMattermostNotifications() + { + var settings = this.BindAndValidate(); + if (!ModelValidationResult.IsValid) + { + return Response.AsJson(ModelValidationResult.SendJsonError()); + } + + var result = MattermostSettings.SaveSettings(settings); + if (settings.Enabled) + { + NotificationService.Subscribe(new MattermostNotification(MattermostApi, MattermostSettings)); + } + else + { + NotificationService.UnSubscribe(new MattermostNotification(MattermostApi, MattermostSettings)); + } + + Log.Info("Saved mattermost settings, result: {0}", result); + return Response.AsJson(result + ? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Mattermost Notifications!" } + : new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." }); + } + private async Task DiscordNotification() { var settings = await DiscordSettings.GetSettingsAsync(); diff --git a/Ombi.UI/NinjectModules/ApiModule.cs b/Ombi.UI/NinjectModules/ApiModule.cs index 1a45764c7..39291e84d 100644 --- a/Ombi.UI/NinjectModules/ApiModule.cs +++ b/Ombi.UI/NinjectModules/ApiModule.cs @@ -44,6 +44,7 @@ namespace Ombi.UI.NinjectModules Bind().To(); Bind().To(); Bind().To(); + Bind().To(); Bind().To(); Bind().To(); Bind().To(); diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj index 24fa57f52..f080929d5 100644 --- a/Ombi.UI/Ombi.UI.csproj +++ b/Ombi.UI/Ombi.UI.csproj @@ -298,6 +298,7 @@ + @@ -737,6 +738,9 @@ Always + + Always + Always diff --git a/Ombi.UI/Startup.cs b/Ombi.UI/Startup.cs index ff8590da4..85da67a1a 100644 --- a/Ombi.UI/Startup.cs +++ b/Ombi.UI/Startup.cs @@ -125,6 +125,10 @@ namespace Ombi.UI var slackSettings = slackService.GetSettings(); SubScribeOvserver(slackSettings, notificationService, new SlackNotification(container.Get(), slackService)); + var mattermostService = container.Get>(); + var mattermostSettings = mattermostService.GetSettings(); + SubScribeOvserver(mattermostSettings, notificationService, new MattermostNotification(container.Get(), mattermostService)); + var discordSettings = container.Get>(); var discordService = discordSettings.GetSettings(); SubScribeOvserver(discordService, notificationService, new DiscordNotification(container.Get(), discordSettings)); diff --git a/Ombi.UI/Validators/MattermostSettingsValidator.cs b/Ombi.UI/Validators/MattermostSettingsValidator.cs new file mode 100644 index 000000000..d6c34c434 --- /dev/null +++ b/Ombi.UI/Validators/MattermostSettingsValidator.cs @@ -0,0 +1,40 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: MattermostSettingsValidator.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using FluentValidation; +using Ombi.Core.SettingModels; + +namespace Ombi.UI.Validators +{ + public class MattermostSettingsValidator : AbstractValidator + { + public MattermostSettingsValidator() + { + RuleFor(request => request.WebhookUrl).NotEmpty().WithMessage("You must specify a Webhook Url"); + } + } +} \ No newline at end of file diff --git a/Ombi.UI/Views/Admin/MattermostNotifications.cshtml b/Ombi.UI/Views/Admin/MattermostNotifications.cshtml new file mode 100644 index 000000000..10d04e7c1 --- /dev/null +++ b/Ombi.UI/Views/Admin/MattermostNotifications.cshtml @@ -0,0 +1,119 @@ +@using Ombi.UI.Helpers +@Html.Partial("Shared/Partial/_Sidebar") + +
+
+
+ Mattermost Notifications + +
+
+ + @if (Model.Enabled) + { + + } + else + { + + } + +
+
+ +
+ + This is the full webhook url. + Mattermost > Settings > Add app or integration > Build > Make a Custom Integration > Incoming Webhooks > Add Incoming Webhook. You will then have a Webhook Url +
+ +
+
+ +
+ + You can override the default channel here +
+ +
+
+ +
+ + You can override the default username (Ombi) here +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml b/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml index e62947012..a4f609549 100644 --- a/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml +++ b/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml @@ -31,6 +31,7 @@ @Html.GetSidebarUrl(Context, "/admin/pushbulletnotification", "Pushbullet Notifications","fa fa-bell-o") @Html.GetSidebarUrl(Context, "/admin/pushovernotification", "Pushover Notifications", "fa fa-bell-o") @Html.GetSidebarUrl(Context, "/admin/slacknotification", "Slack Notifications", "fa fa-slack") + @Html.GetSidebarUrl(Context, "/admin/mattermostnotification", "Mattermost Notifications", "fa fa-bell-o") @Html.GetSidebarUrl(Context, "/admin/discordnotification", "Discord Notifications", "fa fa-bell-o") From 2f1060b665c0ffbde559158411bce7b380e18b86 Mon Sep 17 00:00:00 2001 From: anonaut Date: Tue, 14 Mar 2017 00:15:26 +0100 Subject: [PATCH 02/42] Added icon_url functionality to mattermost notification --- .../Notifications/MattermostNotificationBody.cs | 1 + .../SettingModels/MattermostNotificationSettings.cs | 1 + Ombi.Services/Notification/MattermostNotification.cs | 2 +- Ombi.UI/Views/Admin/MattermostNotifications.cshtml | 10 +++++++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Ombi.Api.Models/Notifications/MattermostNotificationBody.cs b/Ombi.Api.Models/Notifications/MattermostNotificationBody.cs index a179019cd..b804352e0 100644 --- a/Ombi.Api.Models/Notifications/MattermostNotificationBody.cs +++ b/Ombi.Api.Models/Notifications/MattermostNotificationBody.cs @@ -50,5 +50,6 @@ namespace Ombi.Api.Models.Notifications } public string channel { get; set; } public string text { get; set; } + public string icon_url { get; set; } } } \ No newline at end of file diff --git a/Ombi.Core/SettingModels/MattermostNotificationSettings.cs b/Ombi.Core/SettingModels/MattermostNotificationSettings.cs index 3ae1eeb8b..03ae5af3e 100644 --- a/Ombi.Core/SettingModels/MattermostNotificationSettings.cs +++ b/Ombi.Core/SettingModels/MattermostNotificationSettings.cs @@ -8,5 +8,6 @@ namespace Ombi.Core.SettingModels public string WebhookUrl { get; set; } public string Channel { get; set; } public string Username { get; set; } + public string IconUrl { get; set; } } } \ No newline at end of file diff --git a/Ombi.Services/Notification/MattermostNotification.cs b/Ombi.Services/Notification/MattermostNotification.cs index 9d8cdbaf9..708e8df34 100644 --- a/Ombi.Services/Notification/MattermostNotification.cs +++ b/Ombi.Services/Notification/MattermostNotification.cs @@ -125,7 +125,7 @@ namespace Ombi.Services.Notification { try { - var notification = new MattermostNotificationBody { username = config.Username, channel = config.Channel ?? string.Empty, text = message }; + var notification = new MattermostNotificationBody { username = config.Username, channel = config.Channel ?? string.Empty, icon_url = config.IconUrl ?? string.Empty, text = message }; var result = await Api.PushAsync(config.WebhookUrl, notification); if (!result.Equals("ok")) diff --git a/Ombi.UI/Views/Admin/MattermostNotifications.cshtml b/Ombi.UI/Views/Admin/MattermostNotifications.cshtml index 10d04e7c1..b48256319 100644 --- a/Ombi.UI/Views/Admin/MattermostNotifications.cshtml +++ b/Ombi.UI/Views/Admin/MattermostNotifications.cshtml @@ -24,7 +24,7 @@
This is the full webhook url. - Mattermost > Settings > Add app or integration > Build > Make a Custom Integration > Incoming Webhooks > Add Incoming Webhook. You will then have a Webhook Url + Mattermost > Integrations > Incoming Webhook > Add Incoming Webhook. You will then have a Webhook Url
@@ -46,6 +46,14 @@
+
+ + You can override the default icon here +
+ +
+
+
From 99c04e389fd4f99b782ea789df1b63a20eeca385 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 10:43:50 +0100 Subject: [PATCH 03/42] The start of a new world. --- Ombi/.gitignore | 16 ++ Ombi/Build/publish windows.bat | 4 + Ombi/Build/publish.bat | 7 + Ombi/Ombi.sln | 28 +++ Ombi/Ombi/.bowerrc | 3 + Ombi/Ombi/.gitignore | 17 ++ Ombi/Ombi/Controllers/HomeController.cs | 35 +++ Ombi/Ombi/Ombi.csproj | 32 +++ Ombi/Ombi/Program.cs | 24 ++ Ombi/Ombi/Properties/launchSettings.json | 22 ++ Ombi/Ombi/Startup.cs | 75 ++++++ Ombi/Ombi/Views/Home/Index.cshtml | 1 + Ombi/Ombi/Views/Shared/Error.cshtml | 14 ++ Ombi/Ombi/Views/Shared/_Layout.cshtml | 20 ++ Ombi/Ombi/Views/_ViewImports.cshtml | 2 + Ombi/Ombi/Views/_ViewStart.cshtml | 3 + Ombi/Ombi/app/app.component.html | 1 + Ombi/Ombi/app/app.component.ts | 10 + Ombi/Ombi/app/app.module.ts | 44 ++++ Ombi/Ombi/app/config.ts | 29 +++ Ombi/Ombi/app/errors/not-found.component.ts | 7 + Ombi/Ombi/app/main.ts | 13 + Ombi/Ombi/app/polyfills.ts | 14 ++ Ombi/Ombi/app/search/search.component.html | 1 + Ombi/Ombi/app/search/search.component.ts | 10 + Ombi/Ombi/appsettings.Development.json | 10 + Ombi/Ombi/appsettings.json | 8 + Ombi/Ombi/bower.json | 13 + Ombi/Ombi/bundleconfig.json | 24 ++ Ombi/Ombi/gulpfile.js | 252 ++++++++++++++++++++ Ombi/Ombi/package.json | 42 ++++ Ombi/Ombi/systemjs.config.ts | 20 ++ Ombi/Ombi/tsconfig.json | 20 ++ 33 files changed, 821 insertions(+) create mode 100644 Ombi/.gitignore create mode 100644 Ombi/Build/publish windows.bat create mode 100644 Ombi/Build/publish.bat create mode 100644 Ombi/Ombi.sln create mode 100644 Ombi/Ombi/.bowerrc create mode 100644 Ombi/Ombi/.gitignore create mode 100644 Ombi/Ombi/Controllers/HomeController.cs create mode 100644 Ombi/Ombi/Ombi.csproj create mode 100644 Ombi/Ombi/Program.cs create mode 100644 Ombi/Ombi/Properties/launchSettings.json create mode 100644 Ombi/Ombi/Startup.cs create mode 100644 Ombi/Ombi/Views/Home/Index.cshtml create mode 100644 Ombi/Ombi/Views/Shared/Error.cshtml create mode 100644 Ombi/Ombi/Views/Shared/_Layout.cshtml create mode 100644 Ombi/Ombi/Views/_ViewImports.cshtml create mode 100644 Ombi/Ombi/Views/_ViewStart.cshtml create mode 100644 Ombi/Ombi/app/app.component.html create mode 100644 Ombi/Ombi/app/app.component.ts create mode 100644 Ombi/Ombi/app/app.module.ts create mode 100644 Ombi/Ombi/app/config.ts create mode 100644 Ombi/Ombi/app/errors/not-found.component.ts create mode 100644 Ombi/Ombi/app/main.ts create mode 100644 Ombi/Ombi/app/polyfills.ts create mode 100644 Ombi/Ombi/app/search/search.component.html create mode 100644 Ombi/Ombi/app/search/search.component.ts create mode 100644 Ombi/Ombi/appsettings.Development.json create mode 100644 Ombi/Ombi/appsettings.json create mode 100644 Ombi/Ombi/bower.json create mode 100644 Ombi/Ombi/bundleconfig.json create mode 100644 Ombi/Ombi/gulpfile.js create mode 100644 Ombi/Ombi/package.json create mode 100644 Ombi/Ombi/systemjs.config.ts create mode 100644 Ombi/Ombi/tsconfig.json diff --git a/Ombi/.gitignore b/Ombi/.gitignore new file mode 100644 index 000000000..fb8c95056 --- /dev/null +++ b/Ombi/.gitignore @@ -0,0 +1,16 @@ +../app/**/*.js +../app/**/*.js.map +../wwwroot/** + +# dependencies +../node_modules +../bower_components + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log +/typings diff --git a/Ombi/Build/publish windows.bat b/Ombi/Build/publish windows.bat new file mode 100644 index 000000000..22260498f --- /dev/null +++ b/Ombi/Build/publish windows.bat @@ -0,0 +1,4 @@ +;https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/ +cd .. +dotnet restore +dotnet publish -c Release -r win10-x64 diff --git a/Ombi/Build/publish.bat b/Ombi/Build/publish.bat new file mode 100644 index 000000000..2d6b312a7 --- /dev/null +++ b/Ombi/Build/publish.bat @@ -0,0 +1,7 @@ +;https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/ +cd .. +dotnet restore +dotnet publish -c Release -r win10-x64 +dotnet publish -c Release -r osx.10.12-x64 +dotnet publish -c Release -r ubuntu.16.10-x64 +dotnet publish -c Release -r debian.8-x64 diff --git a/Ombi/Ombi.sln b/Ombi/Ombi.sln new file mode 100644 index 000000000..e46d08528 --- /dev/null +++ b/Ombi/Ombi.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9D30CCF8-A115-4EB7-A34D-07780D752789}" + ProjectSection(SolutionItems) = preProject + Build\publish windows.bat = Build\publish windows.bat + Build\publish.bat = Build\publish.bat + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Ombi/Ombi/.bowerrc b/Ombi/Ombi/.bowerrc new file mode 100644 index 000000000..69fad3580 --- /dev/null +++ b/Ombi/Ombi/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} diff --git a/Ombi/Ombi/.gitignore b/Ombi/Ombi/.gitignore new file mode 100644 index 000000000..71bffc9b8 --- /dev/null +++ b/Ombi/Ombi/.gitignore @@ -0,0 +1,17 @@ +/app/**/*.js +/app/**/*.js.map +/wwwroot/** + +# dependencies +/node_modules +/bower_components + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log +/typings +/systemjs.config.js* diff --git a/Ombi/Ombi/Controllers/HomeController.cs b/Ombi/Ombi/Controllers/HomeController.cs new file mode 100644 index 000000000..c03c9f475 --- /dev/null +++ b/Ombi/Ombi/Controllers/HomeController.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Ombi.Controllers +{ + public class HomeController : Controller + { + public IActionResult Index() + { + return View(); + } + + public IActionResult About() + { + ViewData["Message"] = "Your application description page."; + + return View(); + } + + public IActionResult Contact() + { + ViewData["Message"] = "Your contact page."; + + return View(); + } + + public IActionResult Error() + { + return View(); + } + } +} diff --git a/Ombi/Ombi/Ombi.csproj b/Ombi/Ombi/Ombi.csproj new file mode 100644 index 000000000..b1bcbb7c6 --- /dev/null +++ b/Ombi/Ombi/Ombi.csproj @@ -0,0 +1,32 @@ + + + + netcoreapp1.0 + win10-x64;osx.10.12-x64;ubuntu.16.10-x64;debian.8-x64; + + + + + + + + + + + + + + + + + + + + + + + + search.component.js + + + diff --git a/Ombi/Ombi/Program.cs b/Ombi/Ombi/Program.cs new file mode 100644 index 000000000..1949a296a --- /dev/null +++ b/Ombi/Ombi/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; + +namespace Ombi +{ + public class Program + { + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/Ombi/Ombi/Properties/launchSettings.json b/Ombi/Ombi/Properties/launchSettings.json new file mode 100644 index 000000000..8cea528a3 --- /dev/null +++ b/Ombi/Ombi/Properties/launchSettings.json @@ -0,0 +1,22 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:52038/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Ombi": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi/Startup.cs b/Ombi/Ombi/Startup.cs new file mode 100644 index 000000000..ccee5f545 --- /dev/null +++ b/Ombi/Ombi/Startup.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; + +namespace Ombi +{ + public class Startup + { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + // Add framework services. + services.AddMvc(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseBrowserLink(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + } + + app.UseStaticFiles(); + app.UseStaticFiles(new StaticFileOptions + { + FileProvider = new PhysicalFileProvider( + Path.Combine(Directory.GetCurrentDirectory(), @"app")), + RequestPath = new PathString("/app"), + }); + + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + + routes.MapRoute( + name: "spa-fallback", + template: "{*url}", + defaults: new { controller = "Home", action = "Index" }); + }); + } + } +} diff --git a/Ombi/Ombi/Views/Home/Index.cshtml b/Ombi/Ombi/Views/Home/Index.cshtml new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Ombi/Ombi/Views/Home/Index.cshtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Ombi/Ombi/Views/Shared/Error.cshtml b/Ombi/Ombi/Views/Shared/Error.cshtml new file mode 100644 index 000000000..e514139c4 --- /dev/null +++ b/Ombi/Ombi/Views/Shared/Error.cshtml @@ -0,0 +1,14 @@ +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

+ +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. +

diff --git a/Ombi/Ombi/Views/Shared/_Layout.cshtml b/Ombi/Ombi/Views/Shared/_Layout.cshtml new file mode 100644 index 000000000..0eaaf503f --- /dev/null +++ b/Ombi/Ombi/Views/Shared/_Layout.cshtml @@ -0,0 +1,20 @@ + + + + + + @ViewData["Title"] - Ombi + + + + + + + + + + + @RenderBody() + + + diff --git a/Ombi/Ombi/Views/_ViewImports.cshtml b/Ombi/Ombi/Views/_ViewImports.cshtml new file mode 100644 index 000000000..b60f8a386 --- /dev/null +++ b/Ombi/Ombi/Views/_ViewImports.cshtml @@ -0,0 +1,2 @@ +@using Ombi +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/Ombi/Ombi/Views/_ViewStart.cshtml b/Ombi/Ombi/Views/_ViewStart.cshtml new file mode 100644 index 000000000..a5f10045d --- /dev/null +++ b/Ombi/Ombi/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/Ombi/Ombi/app/app.component.html b/Ombi/Ombi/app/app.component.html new file mode 100644 index 000000000..87b55177c --- /dev/null +++ b/Ombi/Ombi/app/app.component.html @@ -0,0 +1 @@ + diff --git a/Ombi/Ombi/app/app.component.ts b/Ombi/Ombi/app/app.component.ts new file mode 100644 index 000000000..3b828746f --- /dev/null +++ b/Ombi/Ombi/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ombi', + moduleId: module.id, + templateUrl: './app.component.html' +}) +export class AppComponent { + +} \ No newline at end of file diff --git a/Ombi/Ombi/app/app.module.ts b/Ombi/Ombi/app/app.module.ts new file mode 100644 index 000000000..05807f52a --- /dev/null +++ b/Ombi/Ombi/app/app.module.ts @@ -0,0 +1,44 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { AppComponent } from './app.component'; + +import 'jquery.nanoscroller'; + +import { RouterModule, Routes } from '@angular/router'; +import { HttpModule } from '@angular/http'; + +import { SearchComponent } from './search/search.component'; +import { PageNotFoundComponent } from './errors/not-found.component'; + + +import { MenubarModule } from 'primeng/components/menubar/menubar'; +import { GrowlModule } from 'primeng/components/growl/growl'; + +const routes: Routes = [ + { path: '*', component: PageNotFoundComponent }, + { path: 'search', component: SearchComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(routes), + BrowserModule, + BrowserAnimationsModule, + HttpModule, + MenubarModule, + GrowlModule, + //ITAdminModule + ], + declarations: [ + AppComponent, + PageNotFoundComponent, + SearchComponent + ], + providers: [ + //MessageService, + //UtilService + ], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/Ombi/Ombi/app/config.ts b/Ombi/Ombi/app/config.ts new file mode 100644 index 000000000..a9ad55679 --- /dev/null +++ b/Ombi/Ombi/app/config.ts @@ -0,0 +1,29 @@ +// Config + +enum envs { + local, + test, + next, + live +} + +var envVar = "#{Environment}"; +var env = envs.local; +if (envs[envVar]) { + env = envs[envVar]; +} + +export var config = { + envs: envs, + env: env, + systemJS: { + bundle: { + [envs.local]: false, + [envs.test]: true, + [envs.next]: true, + [envs.live]: true + }[env] + } +} + +export default config; \ No newline at end of file diff --git a/Ombi/Ombi/app/errors/not-found.component.ts b/Ombi/Ombi/app/errors/not-found.component.ts new file mode 100644 index 000000000..29a78e9e0 --- /dev/null +++ b/Ombi/Ombi/app/errors/not-found.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + moduleId: module.id, + template: '

Page not found

' +}) +export class PageNotFoundComponent { } \ No newline at end of file diff --git a/Ombi/Ombi/app/main.ts b/Ombi/Ombi/app/main.ts new file mode 100644 index 000000000..774678cc2 --- /dev/null +++ b/Ombi/Ombi/app/main.ts @@ -0,0 +1,13 @@ +import './polyfills'; + +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app.module'; +import { config } from './config'; + +if (config.env !== config.envs.local) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule); \ No newline at end of file diff --git a/Ombi/Ombi/app/polyfills.ts b/Ombi/Ombi/app/polyfills.ts new file mode 100644 index 000000000..7dbacb023 --- /dev/null +++ b/Ombi/Ombi/app/polyfills.ts @@ -0,0 +1,14 @@ +// TypeScript transpiles our app to ES5 but some dependencies are written in ES6 so must polyfill +import 'core-js/es6/string'; +import 'core-js/es6/array'; +import 'core-js/es6/object'; + +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; + +import { config } from './config'; + +if (config.env === config.envs.local) { + Error['stackTraceLimit'] = Infinity; + require('zone.js/dist/long-stack-trace-zone'); +} \ No newline at end of file diff --git a/Ombi/Ombi/app/search/search.component.html b/Ombi/Ombi/app/search/search.component.html new file mode 100644 index 000000000..633c82a61 --- /dev/null +++ b/Ombi/Ombi/app/search/search.component.html @@ -0,0 +1 @@ +

Search

\ No newline at end of file diff --git a/Ombi/Ombi/app/search/search.component.ts b/Ombi/Ombi/app/search/search.component.ts new file mode 100644 index 000000000..d92fb760b --- /dev/null +++ b/Ombi/Ombi/app/search/search.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ombi', + moduleId: module.id, + templateUrl: './search.component.html' +}) +export class SearchComponent { + +} \ No newline at end of file diff --git a/Ombi/Ombi/appsettings.Development.json b/Ombi/Ombi/appsettings.Development.json new file mode 100644 index 000000000..fa8ce71a9 --- /dev/null +++ b/Ombi/Ombi/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/Ombi/Ombi/appsettings.json b/Ombi/Ombi/appsettings.json new file mode 100644 index 000000000..5fff67bac --- /dev/null +++ b/Ombi/Ombi/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Warning" + } + } +} diff --git a/Ombi/Ombi/bower.json b/Ombi/Ombi/bower.json new file mode 100644 index 000000000..66d9701f8 --- /dev/null +++ b/Ombi/Ombi/bower.json @@ -0,0 +1,13 @@ +{ + "name": "ombi", + "private": true, + "dependencies": { + "bootstrap": "3.3.7", + "jquery": "2.2.0", + "jquery-validation": "1.14.0", + "jquery-validation-unobtrusive": "3.2.6", + "PACE": "pace#^1.0.2", + "font-awesome": "^4.7.0" + } +} + \ No newline at end of file diff --git a/Ombi/Ombi/bundleconfig.json b/Ombi/Ombi/bundleconfig.json new file mode 100644 index 000000000..6d3f9a57a --- /dev/null +++ b/Ombi/Ombi/bundleconfig.json @@ -0,0 +1,24 @@ +// Configure bundling and minification for the project. +// More info at https://go.microsoft.com/fwlink/?LinkId=808241 +[ + { + "outputFileName": "wwwroot/css/site.min.css", + // An array of relative input file paths. Globbing patterns supported + "inputFiles": [ + "wwwroot/css/site.css" + ] + }, + { + "outputFileName": "wwwroot/js/site.min.js", + "inputFiles": [ + "wwwroot/js/site.js" + ], + // Optionally specify minification options + "minify": { + "enabled": true, + "renameLocals": true + }, + // Optionally generate .map file + "sourceMap": false + } +] diff --git a/Ombi/Ombi/gulpfile.js b/Ombi/Ombi/gulpfile.js new file mode 100644 index 000000000..1e12fb57e --- /dev/null +++ b/Ombi/Ombi/gulpfile.js @@ -0,0 +1,252 @@ +/// +'use strict'; +var gulp = require('gulp'); +var sass = require('gulp-sass'); +var changed = require('gulp-changed'); +var rename = require('gulp-rename'); +var uglify = require('gulp-uglify'); +var sourcemaps = require('gulp-sourcemaps'); +var path = require('path'); +var del = require('del'); +var merge = require('merge-stream'); +var gulpif = require('gulp-if'); +var runSequence = require('run-sequence'); +var cleancss = require('gulp-clean-css'); +var filter = require('gulp-filter'); +var systemJSBuilder = require('systemjs-builder'); +var run = require('gulp-run'); + +var paths = { + wwwroot: './wwwroot/', + npm: { // These will be resolved automatically and copied to output directory as its name, only works for pre-bundled modules e.g. angular + src: [ + '@angular/animations', + '@angular/animations/browser', + '@angular/core', + '@angular/common', + '@angular/compiler', + '@angular/platform-browser', + '@angular/platform-browser-dynamic', + '@angular/http', + '@angular/router', + '@angular/forms' + ], + dest: './lib' + }, + lib: { // These are simple single-file dependencies with optional rename, for more files or folders use modules + src: [ + { + file: './node_modules/@angular/platform-browser/bundles/platform-browser-animations.umd.js', + rename: '@angular/platform-browser/animations' + }, + { + file: './node_modules/systemjs/dist/system.src.js', + rename: 'system' + }, + { + file: './node_modules/systemjs/dist/system-polyfills.src.js', + rename: 'system-polyfills' + }, + './bower_components/jquery/dist/jquery.js', + './bower_components/PACE/pace.js', + './primeng/ripple.js', + './node_modules/nanoscroller/bin/javascripts/jquery.nanoscroller.js', + './systemjs.config.js' + ], + dest: './lib/' + }, + libcss: [ // Normal css files to be copied + { + src: [ + './bower_components/PACE/themes/purple/pace-theme-center-simple.css', + './node_modules/primeng/resources/primeng.css', + './node_modules/nanoscroller/bin/css/nanoscroller.css' + ], + dest: './css/lib/' + }, + { + src: './Styles/**/*.css', + dest: './css', + filter: '**/*.css' + } + ], + libfonts: [ // Library fonts + { + src: [ + './bower_components/font-awesome/fonts/*' + ], + dest: './fonts/lib/' + } + ], + modules: [ // This is for modules with multiple files that require each other, used when npm can't be used + { + name: 'zone.js', + src: ['./node_modules/zone.js/**/*.js'], + dest: './lib/zone.js/' + }, + { + name: 'rxjs', + src: ['./node_modules/rxjs/**/*.js', '!./node_modules/rxjs/src/**/*.js'], + dest: './lib/rxjs/' + }, + { + name: 'core-js', + src: ['./node_modules/core-js/**/*.js'], + dest: './lib/core-js/' + }, + { + name: 'primeng', + src: './node_modules/primeng/**/*.js', + dest: './lib/primeng/' + } + ], + sass: { // Simple sass->css compilation + src: ['./Styles/**/*.scss', '!./Styles/primeng/**'], + dest: './css/', + filter: '**/*.css' + }, + bundle: { // This is the config for the bundler, you shouldn't need to change this + root: './', + dest: './lib/bundle.js', + bundle: 'app/main.js', + } +} + +gulp.task('npm', function () { + var streams = [] + for (let module of paths.npm.src) { + let file = require.resolve(module); + streams.push( + gulp.src(file) + .pipe(gulpif(global.full, sourcemaps.init())) + .pipe(gulpif(global.full, uglify({ source_map: true }))) + .pipe(rename((path => { path.basename = module }))) + .pipe(gulpif(global.full, sourcemaps.write('../maps'))) + .pipe(gulp.dest(path.join(paths.wwwroot, paths.npm.dest))) + ); + } + return merge(streams); +}) + +gulp.task('lib', function () { + var streams = [] + for (let module of paths.lib.src) { + streams.push( + gulp.src(typeof module === "string" ? module : module.file) + .pipe(gulpif(global.full, sourcemaps.init())) + .pipe(gulpif(global.full, uglify({ source_map: true }))) + .pipe(rename(function (path) { + if (typeof module !== "string" && module.rename) { + path.basename = module.rename; + } + })) + .pipe(gulpif(global.full, sourcemaps.write('maps'))) + .pipe(gulp.dest(path.join(paths.wwwroot, paths.lib.dest))) + ); + } + return merge(streams); +}) + +gulp.task('libcss', function () { + var streams = [] + for (let module of paths.libcss) { + var f = filter("**/*.css", { restore: true }); + streams.push( + gulp.src(module.src) + .pipe(f) + .pipe(gulpif(global.full, sourcemaps.init())) + .pipe(gulpif(global.full, cleancss())) + .pipe(gulpif(global.full, sourcemaps.write(`${module.name ? '.' : ''}./maps/${module.name ? module.name : ''}`))) + .pipe(f.restore) + .pipe(gulp.dest(path.join(paths.wwwroot, module.dest))) + ); + } + return merge(streams); +}) + + +gulp.task('libfonts', function () { + var streams = [] + for (let module of paths.libfonts) { + streams.push( + gulp.src(module.src) + .pipe(gulp.dest(path.join(paths.wwwroot, module.dest))) + ); + } + return merge(streams); +}) + +gulp.task('modules', function () { + var streams = [] + for (let module of paths.modules) { + streams.push( + gulp.src(module.src) + .pipe(gulpif(global.full, sourcemaps.init())) + .pipe(gulpif(global.full, uglify({ source_map: true }))) + .pipe(gulpif(global.full, sourcemaps.write(`${module.name ? '.' : ''}./maps/${module.name ? module.name : ''}`))) + .pipe(gulp.dest(path.join(paths.wwwroot, module.dest))) + ); + } + return merge(streams); +}) + +gulp.task('sass', function () { + return gulp.src(paths.sass.src) + .pipe(changed(paths.sass.dest)) + .pipe(gulpif(global.full, sourcemaps.init())) + .pipe(sass({ outputStyle: global.full ? 'compressed' : 'nested' }).on('error', sass.logError)) + .pipe(gulpif(global.full, sourcemaps.write('maps'))) + .pipe(gulp.dest(path.join(paths.wwwroot, paths.sass.dest))) +}); + +gulp.task('bundle', function () { + var builder = new systemJSBuilder(paths.bundle.root); + builder.config({ + baseURL: paths.wwwroot, + packages: { + '.': { + defaultExtension: 'js' + } + }, + paths: { + '*': 'lib/*', + 'app/*': 'app/*' + } + }); + del.sync(path.join(paths.wwwroot, paths.bundle.dest), { force: true }); + return builder.bundle(paths.bundle.bundle, path.join(paths.wwwroot, paths.bundle.dest), { + sourceMaps: true + }) +}) + +gulp.task('clean', function () { + return del([ + ...paths.npm.src.map(x => path.join(paths.npm.dest, x + "**")), + paths.sass.dest + paths.sass.filter, + paths.lib.dest, + paths.bundle.dest, + ...paths.modules.map(m => m.dest), + ...paths.libcss.map(m => m.dest + (m.filter ? m.filter : '')), + ...paths.libfonts.map(m => m.dest) + ].map(x => path.join(paths.wwwroot, x)), { force: true }); +}) + +gulp.task('typescript', function () { + return run('tsc').exec(); +}); + +gulp.task('fullvar', () => { global.full = true }); +gulp.task('libs') +gulp.task('copy', ['lib', 'libcss', 'libfonts', 'npm', 'modules']); +gulp.task('compile', ['sass']); +gulp.task('build', callback => runSequence('copy', 'compile', callback)); +gulp.task('full', callback => runSequence('clean', 'build', callback)); + +// Use this in a build server environment to compile and bundle everything +gulp.task('publish', callback => runSequence('fullvar', 'full', 'typescript', 'bundle', callback)); + +// Auto compiles sass files on change, note that this doesn't seem to pick up new files at the moment +gulp.task('watch', function () { + gulp.watch(paths.sass.src, ['sass']); + gulp.watch('./Styles/**/*.css', ['libcss']); // legacy css +}); \ No newline at end of file diff --git a/Ombi/Ombi/package.json b/Ombi/Ombi/package.json new file mode 100644 index 000000000..6c8d0fb82 --- /dev/null +++ b/Ombi/Ombi/package.json @@ -0,0 +1,42 @@ +{ + "name": "ombi", + "version": "1.0.0", + "private": true, + "dependencies": { + "@angular/animations": "^4.0.0", + "@angular/common": "^4.0.0", + "@angular/compiler": "^4.0.0", + "@angular/compiler-cli": "^4.0.0", + "@angular/core": "^4.0.0", + "@angular/forms": "^4.0.0", + "@angular/http": "^4.0.0", + "@angular/platform-browser": "^4.0.0", + "@angular/platform-browser-dynamic": "^4.0.0", + "@angular/platform-server": "^4.0.0", + "@angular/router": "^4.0.0", + "@types/jquery": "^2.0.33", + "@types/systemjs": "^0.20.2", + "core-js": "^2.4.1", + "del": "^2.2.2", + "gulp": "~3.9.1", + "gulp-changed": "^1.3.0", + "gulp-clean-css": "^3.0.4", + "gulp-filter": "^5.0.0", + "gulp-if": "^2.0.2", + "gulp-rename": "^1.2.2", + "gulp-run": "^1.7.1", + "gulp-sass": "^2.3.2", + "gulp-sourcemaps": "^1.9.0", + "gulp-systemjs-builder": "^0.15.0", + "gulp-uglify": "^1.5.4", + "merge-stream": "^1.0.1", + "nanoscroller": "^0.8.7", + "primeng": "^2.0.5", + "run-sequence": "^1.2.2", + "rxjs": "^5.0.3", + "systemjs": "^0.19.41", + "systemjs-builder": "^0.15.34", + "typescript": "^2.2.1", + "zone.js": "^0.8.5" + } +} \ No newline at end of file diff --git a/Ombi/Ombi/systemjs.config.ts b/Ombi/Ombi/systemjs.config.ts new file mode 100644 index 000000000..b31bed9a4 --- /dev/null +++ b/Ombi/Ombi/systemjs.config.ts @@ -0,0 +1,20 @@ +System.import('/app/config.js').then((module: any) => { + var config = module.config.systemJS; + System.config({ + baseURL: '/lib', + packages: { + '.': { + defaultExtension: 'js' + } + }, + map: { app: '../app' } + }) + + if (config.bundle) { + System.import('bundle').then(() => { + System.import('/app/main'); + }) + } else { + System.import('/app/main') + } +}); \ No newline at end of file diff --git a/Ombi/Ombi/tsconfig.json b/Ombi/Ombi/tsconfig.json new file mode 100644 index 000000000..442f43235 --- /dev/null +++ b/Ombi/Ombi/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ "es5", "es2015" ], + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "noImplicitThis": true, + "noImplicitReturns": true, + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "alwaysStrict": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "skipLibCheck": true + }, + "compileOnSave": true +} \ No newline at end of file From 49e07e44d74f756c931e7f3a0f2c92e064d2fa5d Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 10:51:12 +0100 Subject: [PATCH 04/42] appveyor change --- appveyor.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2357e7eaa..96160bfb2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,15 +6,25 @@ assembly_info: assembly_version: '2.2.0' assembly_file_version: '{version}' assembly_informational_version: '2.2.0' + +project: Ombi/Ombi.sln before_build: +- cmd: dotnet restore +- cmd: npm install - cmd: appveyor-retry nuget restore build: verbosity: minimal after_build: - cmd: >- - 7z a Ombi.zip %APPVEYOR_BUILD_FOLDER%\Ombi.UI\bin\Release\ + 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish + 7z a OmbiUbuntu.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\ubuntu.16.10-x64\publish + 7z a OmbiOsx.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\osx.10.12-x64\publish + 7z a OmbiDebian.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\debian.8-x64\publish - appveyor PushArtifact Ombi.zip + appveyor PushArtifact OmbiWindows.zip + appveyor PushArtifact OmbiUbuntu.zip + appveyor PushArtifact OmbiOsx.zip + appveyor PushArtifact OmbiDebian.zip deploy: - provider: GitHub @@ -24,7 +34,3 @@ deploy: draft: true on: branch: master -- provider: Environment - name: Microserver - on: - branch: dev From 7825a5b9f1a7fc375b1bdc9ce01fb88d3974e4f9 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 10:52:13 +0100 Subject: [PATCH 05/42] cahnge 2 --- appveyor.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 96160bfb2..8451b2166 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,11 @@ project: Ombi/Ombi.sln before_build: - cmd: dotnet restore - cmd: npm install -- cmd: appveyor-retry nuget restore +- cmd: dotnet publish -c Release -r win10-x64 +- cmd: dotnet publish -c Release -r osx.10.12-x64 +- cmd: dotnet publish -c Release -r ubuntu.16.10-x64 +- cmd: dotnet publish -c Release -r debian.8-x64 + build: verbosity: minimal after_build: From 9144b2816f912977cfda2441bdbf782e3a1c9807 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 11:31:34 +0100 Subject: [PATCH 06/42] Fixed --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 8451b2166..d6fa48220 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ assembly_info: assembly_file_version: '{version}' assembly_informational_version: '2.2.0' -project: Ombi/Ombi.sln + before_build: - cmd: dotnet restore - cmd: npm install @@ -18,6 +18,7 @@ before_build: build: verbosity: minimal + project: Ombi/Ombi.sln after_build: - cmd: >- 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish From 3288276473f5663f50adb29a302d546c04d1d4ea Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 11:44:33 +0100 Subject: [PATCH 07/42] a --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index d6fa48220..20efa424c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,7 @@ assembly_info: before_build: +- cmd: cd ombi/ombi - cmd: dotnet restore - cmd: npm install - cmd: dotnet publish -c Release -r win10-x64 From be8383f82351bc33db9be497df5457e2a114d3cc Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 11:49:32 +0100 Subject: [PATCH 08/42] retry --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 20efa424c..83e4235ba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ assembly_info: before_build: - cmd: cd ombi/ombi - cmd: dotnet restore -- cmd: npm install +- cmd: appveyor-retry npm install - cmd: dotnet publish -c Release -r win10-x64 - cmd: dotnet publish -c Release -r osx.10.12-x64 - cmd: dotnet publish -c Release -r ubuntu.16.10-x64 From bc7362c4c539cdcde0878189c6b116ce40af2256 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 11:55:26 +0100 Subject: [PATCH 09/42] another --- appveyor.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 83e4235ba..292fdb21f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,18 +19,11 @@ before_build: build: verbosity: minimal - project: Ombi/Ombi.sln after_build: - cmd: >- 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish - 7z a OmbiUbuntu.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\ubuntu.16.10-x64\publish - 7z a OmbiOsx.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\osx.10.12-x64\publish - 7z a OmbiDebian.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\debian.8-x64\publish appveyor PushArtifact OmbiWindows.zip - appveyor PushArtifact OmbiUbuntu.zip - appveyor PushArtifact OmbiOsx.zip - appveyor PushArtifact OmbiDebian.zip deploy: - provider: GitHub From 0b43eab684354672233708254e4d2ab04cda8676 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 12:20:15 +0100 Subject: [PATCH 10/42] another --- appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 292fdb21f..053436a77 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,8 +17,6 @@ before_build: - cmd: dotnet publish -c Release -r ubuntu.16.10-x64 - cmd: dotnet publish -c Release -r debian.8-x64 -build: - verbosity: minimal after_build: - cmd: >- 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish From 4338b6783e668cf0333a40bd6db27065b3cf65cf Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 12:31:15 +0100 Subject: [PATCH 11/42] anbother --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 053436a77..0a5a017f9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,6 +17,9 @@ before_build: - cmd: dotnet publish -c Release -r ubuntu.16.10-x64 - cmd: dotnet publish -c Release -r debian.8-x64 +build: + verbosity: minimal + project: Ombi.sln after_build: - cmd: >- 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish From 6949a4128c60ef43941a91690f0b8688b49d74dc Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 12:37:32 +0100 Subject: [PATCH 12/42] again --- Ombi.sln | 131 --------------------------------------------------- appveyor.yml | 1 - 2 files changed, 132 deletions(-) delete mode 100644 Ombi.sln diff --git a/Ombi.sln b/Ombi.sln deleted file mode 100644 index 86b3aa0ff..000000000 --- a/Ombi.sln +++ /dev/null @@ -1,131 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.UI", "Ombi.UI\Ombi.UI.csproj", "{68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api", "Ombi.Api\Ombi.Api.csproj", "{8CB8D235-2674-442D-9C6A-35FCAEEB160D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Interfaces", "Ombi.Api.Interfaces\Ombi.Api.Interfaces.csproj", "{95834072-A675-415D-AA8F-877C91623810}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core", "Ombi.Core\Ombi.Core.csproj", "{DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Store", "Ombi.Store\Ombi.Store.csproj", "{92433867-2B7B-477B-A566-96C382427525}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F4BC839C-B8FF-48BE-B22E-536A0A0A81A5}" - ProjectSection(SolutionItems) = preProject - .travis.yml = .travis.yml - appveyor.yml = appveyor.yml - LICENSE = LICENSE - README.md = README.md - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Helpers", "Ombi.Helpers\Ombi.Helpers.csproj", "{1252336D-42A3-482A-804C-836E60173DFA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.UI.Tests", "Ombi.UI.Tests\Ombi.UI.Tests.csproj", "{A930E2CF-79E2-45F9-B06A-9A719A254CE4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core.Tests", "Ombi.Core.Tests\Ombi.Core.Tests.csproj", "{FCFECD5D-47F6-454D-8692-E27A921BE655}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Services", "Ombi.Services\Ombi.Services.csproj", "{566EFA49-68F8-4716-9693-A6B3F2624DEA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Models", "Ombi.Api.Models\Ombi.Api.Models.csproj", "{CB37A5F8-6DFC-4554-99D3-A42B502E4591}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Services.Tests", "Ombi.Services.Tests\Ombi.Services.Tests.csproj", "{EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Updater", "Ombi.Updater\Ombi.Updater.csproj", "{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Helpers.Tests", "Ombi.Helpers.Tests\Ombi.Helpers.Tests.csproj", "{0E6395D3-B074-49E8-898D-0EB99E507E0E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core.Migration", "Ombi.Core.Migration\Ombi.Core.Migration.csproj", "{8406EE57-D533-47C0-9302-C6B5F8C31E55}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Common", "Ombi.Common\Ombi.Common.csproj", "{BFD45569-90CF-47CA-B575-C7B0FF97F67B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Mono", "Ombi.Mono\Ombi.Mono.csproj", "{96C89180-1FB5-48B7-9D35-6EB5F11C9D95}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Windows", "Ombi.Windows\Ombi.Windows.csproj", "{FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platform", "Platform", "{3186D191-D5C6-46B1-86E0-3F3B65A12096}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Release|Any CPU.Build.0 = Release|Any CPU - {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Release|Any CPU.Build.0 = Release|Any CPU - {95834072-A675-415D-AA8F-877C91623810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95834072-A675-415D-AA8F-877C91623810}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95834072-A675-415D-AA8F-877C91623810}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95834072-A675-415D-AA8F-877C91623810}.Release|Any CPU.Build.0 = Release|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.Build.0 = Release|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.Build.0 = Release|Any CPU - {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.Build.0 = Release|Any CPU - {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.ActiveCfg = Release|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.Build.0 = Release|Any CPU - {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Release|Any CPU.Build.0 = Release|Any CPU - {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.Build.0 = Release|Any CPU - {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Release|Any CPU.Build.0 = Release|Any CPU - {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Release|Any CPU.Build.0 = Release|Any CPU - {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Debug|Any CPU.Build.0 = Debug|Any CPU - {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Release|Any CPU.ActiveCfg = Release|Any CPU - {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Release|Any CPU.Build.0 = Release|Any CPU - {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {96C89180-1FB5-48B7-9D35-6EB5F11C9D95} = {3186D191-D5C6-46B1-86E0-3F3B65A12096} - {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037} = {3186D191-D5C6-46B1-86E0-3F3B65A12096} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - RESX_PrefixTranslations = False - EndGlobalSection -EndGlobal diff --git a/appveyor.yml b/appveyor.yml index 0a5a017f9..292fdb21f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,7 +19,6 @@ before_build: build: verbosity: minimal - project: Ombi.sln after_build: - cmd: >- 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish From 41e91efb843fd6f41375634f1908eb49429a3ce7 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 12:48:01 +0100 Subject: [PATCH 13/42] more --- appveyor.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 292fdb21f..31666c90c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,21 +10,22 @@ assembly_info: before_build: - cmd: cd ombi/ombi -- cmd: dotnet restore -- cmd: appveyor-retry npm install -- cmd: dotnet publish -c Release -r win10-x64 -- cmd: dotnet publish -c Release -r osx.10.12-x64 -- cmd: dotnet publish -c Release -r ubuntu.16.10-x64 -- cmd: dotnet publish -c Release -r debian.8-x64 - -build: - verbosity: minimal +- appveyor-retry dotnet restore +- appveyor-retry npm install +build_script: +- dotnet build after_build: +- dotnet publish -c Release -r win10-x64 +- dotnet publish -c Release -r osx.10.12-x64 +- dotnet publish -c Release -r ubuntu.16.10-x64 +- dotnet publish -c Release -r debian.8-x64 - cmd: >- 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish appveyor PushArtifact OmbiWindows.zip - + +cache: +- '%USERPROFILE%\.nuget\packages' deploy: - provider: GitHub release: Ombi v$(appveyor_build_version) From 5b68c4c5e488cf9b45d9c8c8e4f4ea136f593135 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 12:52:30 +0100 Subject: [PATCH 14/42] try again --- appveyor.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 31666c90c..1966f7fca 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,9 +20,15 @@ after_build: - dotnet publish -c Release -r ubuntu.16.10-x64 - dotnet publish -c Release -r debian.8-x64 - cmd: >- - 7z a OmbiWidnows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish + 7z a Ombi_windows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish + 7z a Ombi_osx.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\osx.10.12-x64\publish + 7z a Ombi_ubuntu.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\ubuntu.16.10-x64\publish + 7z a Ombi_debian.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\debian.8-x64\publish - appveyor PushArtifact OmbiWindows.zip + appveyor PushArtifact Ombi_windows.zip + appveyor PushArtifact Ombi_osx.zip + appveyor PushArtifact Ombi_ubuntu.zip + appveyor PushArtifact Ombi_debian.zip cache: - '%USERPROFILE%\.nuget\packages' From 71c84eb3601945951af1660aee347177580f58eb Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 12:55:24 +0100 Subject: [PATCH 15/42] spacing --- appveyor.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 1966f7fca..fd3c8ec9a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,14 +21,29 @@ after_build: - dotnet publish -c Release -r debian.8-x64 - cmd: >- 7z a Ombi_windows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\win10-x64\publish + + 7z a Ombi_osx.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\osx.10.12-x64\publish + + 7z a Ombi_ubuntu.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\ubuntu.16.10-x64\publish + + 7z a Ombi_debian.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.0\debian.8-x64\publish + appveyor PushArtifact Ombi_windows.zip + + appveyor PushArtifact Ombi_osx.zip + + appveyor PushArtifact Ombi_ubuntu.zip + + appveyor PushArtifact Ombi_debian.zip + + cache: - '%USERPROFILE%\.nuget\packages' From e0250921a4cbe70bb95d2ee5df8eb4581dc821fa Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Tue, 4 Apr 2017 15:48:49 +0100 Subject: [PATCH 16/42] MOre changes --- Ombi.sln | 131 ++++ Ombi/Build/publish windows.bat | 2 + Ombi/Build/publish.bat | 2 + Ombi/Ombi/.bowerrc | 3 - Ombi/Ombi/Ombi.csproj | 26 +- Ombi/Ombi/Startup.cs | 16 +- Ombi/Ombi/Styles/Themes/original.scss | 2 + Ombi/Ombi/Styles/Themes/plex.scss | 237 +++++++ Ombi/Ombi/Styles/_imports.scss | 7 + Ombi/Ombi/Styles/base.scss | 690 +++++++++++++++++++++ Ombi/Ombi/Views/Shared/_Layout.cshtml | 18 +- Ombi/Ombi/app/app.component.html | 26 +- Ombi/Ombi/app/app.component.ts | 15 +- Ombi/Ombi/app/app.module.ts | 2 - Ombi/Ombi/app/config.ts | 8 +- Ombi/Ombi/app/search/search.component.html | 29 +- Ombi/Ombi/bower.json | 6 +- Ombi/Ombi/gulpfile.js | 43 +- Ombi/Ombi/package.json | 5 +- appveyor.yml | 1 + 20 files changed, 1215 insertions(+), 54 deletions(-) create mode 100644 Ombi.sln delete mode 100644 Ombi/Ombi/.bowerrc create mode 100644 Ombi/Ombi/Styles/Themes/original.scss create mode 100644 Ombi/Ombi/Styles/Themes/plex.scss create mode 100644 Ombi/Ombi/Styles/_imports.scss create mode 100644 Ombi/Ombi/Styles/base.scss diff --git a/Ombi.sln b/Ombi.sln new file mode 100644 index 000000000..86b3aa0ff --- /dev/null +++ b/Ombi.sln @@ -0,0 +1,131 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.UI", "Ombi.UI\Ombi.UI.csproj", "{68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api", "Ombi.Api\Ombi.Api.csproj", "{8CB8D235-2674-442D-9C6A-35FCAEEB160D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Interfaces", "Ombi.Api.Interfaces\Ombi.Api.Interfaces.csproj", "{95834072-A675-415D-AA8F-877C91623810}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core", "Ombi.Core\Ombi.Core.csproj", "{DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Store", "Ombi.Store\Ombi.Store.csproj", "{92433867-2B7B-477B-A566-96C382427525}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F4BC839C-B8FF-48BE-B22E-536A0A0A81A5}" + ProjectSection(SolutionItems) = preProject + .travis.yml = .travis.yml + appveyor.yml = appveyor.yml + LICENSE = LICENSE + README.md = README.md + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Helpers", "Ombi.Helpers\Ombi.Helpers.csproj", "{1252336D-42A3-482A-804C-836E60173DFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.UI.Tests", "Ombi.UI.Tests\Ombi.UI.Tests.csproj", "{A930E2CF-79E2-45F9-B06A-9A719A254CE4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core.Tests", "Ombi.Core.Tests\Ombi.Core.Tests.csproj", "{FCFECD5D-47F6-454D-8692-E27A921BE655}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Services", "Ombi.Services\Ombi.Services.csproj", "{566EFA49-68F8-4716-9693-A6B3F2624DEA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Models", "Ombi.Api.Models\Ombi.Api.Models.csproj", "{CB37A5F8-6DFC-4554-99D3-A42B502E4591}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Services.Tests", "Ombi.Services.Tests\Ombi.Services.Tests.csproj", "{EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Updater", "Ombi.Updater\Ombi.Updater.csproj", "{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Helpers.Tests", "Ombi.Helpers.Tests\Ombi.Helpers.Tests.csproj", "{0E6395D3-B074-49E8-898D-0EB99E507E0E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core.Migration", "Ombi.Core.Migration\Ombi.Core.Migration.csproj", "{8406EE57-D533-47C0-9302-C6B5F8C31E55}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Common", "Ombi.Common\Ombi.Common.csproj", "{BFD45569-90CF-47CA-B575-C7B0FF97F67B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Mono", "Ombi.Mono\Ombi.Mono.csproj", "{96C89180-1FB5-48B7-9D35-6EB5F11C9D95}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Windows", "Ombi.Windows\Ombi.Windows.csproj", "{FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platform", "Platform", "{3186D191-D5C6-46B1-86E0-3F3B65A12096}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Release|Any CPU.Build.0 = Release|Any CPU + {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Release|Any CPU.Build.0 = Release|Any CPU + {95834072-A675-415D-AA8F-877C91623810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95834072-A675-415D-AA8F-877C91623810}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95834072-A675-415D-AA8F-877C91623810}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95834072-A675-415D-AA8F-877C91623810}.Release|Any CPU.Build.0 = Release|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.Build.0 = Release|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.Build.0 = Release|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.Build.0 = Release|Any CPU + {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.ActiveCfg = Release|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.Build.0 = Release|Any CPU + {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Release|Any CPU.Build.0 = Release|Any CPU + {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.Build.0 = Release|Any CPU + {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8406EE57-D533-47C0-9302-C6B5F8C31E55}.Release|Any CPU.Build.0 = Release|Any CPU + {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFD45569-90CF-47CA-B575-C7B0FF97F67B}.Release|Any CPU.Build.0 = Release|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95}.Release|Any CPU.Build.0 = Release|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {96C89180-1FB5-48B7-9D35-6EB5F11C9D95} = {3186D191-D5C6-46B1-86E0-3F3B65A12096} + {FA5F2172-E82F-4D73-9C50-BEDC6A0A4037} = {3186D191-D5C6-46B1-86E0-3F3B65A12096} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + RESX_PrefixTranslations = False + EndGlobalSection +EndGlobal diff --git a/Ombi/Build/publish windows.bat b/Ombi/Build/publish windows.bat index 22260498f..e94f1864d 100644 --- a/Ombi/Build/publish windows.bat +++ b/Ombi/Build/publish windows.bat @@ -2,3 +2,5 @@ cd .. dotnet restore dotnet publish -c Release -r win10-x64 + +exit \ No newline at end of file diff --git a/Ombi/Build/publish.bat b/Ombi/Build/publish.bat index 2d6b312a7..48cc28c2a 100644 --- a/Ombi/Build/publish.bat +++ b/Ombi/Build/publish.bat @@ -5,3 +5,5 @@ dotnet publish -c Release -r win10-x64 dotnet publish -c Release -r osx.10.12-x64 dotnet publish -c Release -r ubuntu.16.10-x64 dotnet publish -c Release -r debian.8-x64 + +exit \ No newline at end of file diff --git a/Ombi/Ombi/.bowerrc b/Ombi/Ombi/.bowerrc deleted file mode 100644 index 69fad3580..000000000 --- a/Ombi/Ombi/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory": "bower_components" -} diff --git a/Ombi/Ombi/Ombi.csproj b/Ombi/Ombi/Ombi.csproj index b1bcbb7c6..c64595c28 100644 --- a/Ombi/Ombi/Ombi.csproj +++ b/Ombi/Ombi/Ombi.csproj @@ -1,32 +1,22 @@  - netcoreapp1.0 + netcoreapp1.1 win10-x64;osx.10.12-x64;ubuntu.16.10-x64;debian.8-x64; - - - - - + + + + + + - - - - - - - - - - - search.component.js - + diff --git a/Ombi/Ombi/Startup.cs b/Ombi/Ombi/Startup.cs index ccee5f545..66f46f4f9 100644 --- a/Ombi/Ombi/Startup.cs +++ b/Ombi/Ombi/Startup.cs @@ -51,7 +51,14 @@ namespace Ombi app.UseExceptionHandler("/Home/Error"); } - app.UseStaticFiles(); + var provider = new FileExtensionContentTypeProvider(); + provider.Mappings[".map"] = "application/octet-stream"; + + app.UseStaticFiles(new StaticFileOptions() + { + ContentTypeProvider = provider + }); + app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( @@ -65,10 +72,9 @@ namespace Ombi name: "default", template: "{controller=Home}/{action=Index}/{id?}"); - routes.MapRoute( - name: "spa-fallback", - template: "{*url}", - defaults: new { controller = "Home", action = "Index" }); + routes.MapSpaFallbackRoute( + name: "spa-fallback", + defaults: new { controller = "Home", action = "Index" }); }); } } diff --git a/Ombi/Ombi/Styles/Themes/original.scss b/Ombi/Ombi/Styles/Themes/original.scss new file mode 100644 index 000000000..46800d16a --- /dev/null +++ b/Ombi/Ombi/Styles/Themes/original.scss @@ -0,0 +1,2 @@ +body { +} diff --git a/Ombi/Ombi/Styles/Themes/plex.scss b/Ombi/Ombi/Styles/Themes/plex.scss new file mode 100644 index 000000000..8a5ffbe8b --- /dev/null +++ b/Ombi/Ombi/Styles/Themes/plex.scss @@ -0,0 +1,237 @@ +$primary-colour: #df691a; +$primary-colour-outline: #ff761b; +$bg-colour: #333333; +$bg-colour-disabled: #252424; +$i: +!important +; + +.form-control-custom { + background-color: $bg-colour $i; +} + +.form-control-custom-disabled { + background-color: $bg-colour-disabled $i; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background: $primary-colour; +} + +.scroll-top-wrapper { + background-color: $bg-colour; +} + +.scroll-top-wrapper:hover { + background-color: $primary-colour; +} + +body { + font-family: Open Sans Regular,Helvetica Neue,Helvetica,Arial,sans-serif; + color: #eee; + background-color: #1f1f1f; +} + +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #333; +} + +.table-hover > tbody > tr:hover { + background-color: #282828; +} + +fieldset { + padding: 15px; +} + +legend { + border-bottom: 1px solid #333333; +} + +.form-control { + color: #fefefe; + background-color: #333; +} + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + margin-left: -0px; +} + +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: -15px; +} + +.dropdown-menu { + background-color: #282828; +} + +.dropdown-menu .divider { + background-color: #333333; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #333; +} + +.input-group-addon { + background-color: #333333; +} + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: #df691a; +} + +.nav-tabs > li > a:hover { + border-color: #df691a #df691a transparent; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background-color: #df691a; + border: 1px solid #df691a; +} + +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #df691a; +} + +/*.navbar { + position: relative; + min-height: 40px; + margin-bottom: 21px; + z-index: 1000; + padding: 0px 3px; + font-size: 24px; + background-color: #000; + box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.2); +}*/ + +.navbar-default { + background-color: #0a0a0a; +} + +.navbar-default .navbar-brand { + color: #DF691A; +} + +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #F0ad4e; + background-color: #282828; +} + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + background-color: #282828; +} + +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: #df691a; + color: #fff; +} + +.pagination > li > a, +.pagination > li > span { + background-color: #282828; +} + +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + background-color: #333; +} + +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #fefefe; + background-color: #333333; +} + +.list-group-item { + background-color: #282828; +} + +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + background-color: #333333; +} + +.input-addon, +.input-group-addon { + color: #df691a; +} + +.modal-header, +.modal-footer { + background-color: #282828; +} + +.modal-content { + position: relative; + background-color: #282828; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: 0; +} + +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: 300; + color: #ebebeb; + line-height: 1; + vertical-align: middle; + white-space: nowrap; + text-align: center; + background-color: $bg-colour; + border-radius: 10px; +} + +.bootstrap-datetimepicker-widget.dropdown-menu { + background-color: $bg-colour; +} + +.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after { + border-bottom: 6px solid $bg-colour $i; +} + +#sidebar-wrapper { + background: $bg-colour-disabled; +} + +#cacherRunning { + background-color: $bg-colour; + text-align: center; + font-size: 15px; + padding: 3px 0; +} \ No newline at end of file diff --git a/Ombi/Ombi/Styles/_imports.scss b/Ombi/Ombi/Styles/_imports.scss new file mode 100644 index 000000000..a880f96e7 --- /dev/null +++ b/Ombi/Ombi/Styles/_imports.scss @@ -0,0 +1,7 @@ +@import "./lib/bootstrap.css"; +//@import "./lib/tether.css"; +@import "../node_modules/primeng/resources/themes/omega/theme.scss"; +@import "./lib/primeng.css"; + +$fa-font-path: "../fonts/lib"; +@import "../bower_components/font-awesome/scss/font-awesome.scss"; \ No newline at end of file diff --git a/Ombi/Ombi/Styles/base.scss b/Ombi/Ombi/Styles/base.scss new file mode 100644 index 000000000..c1c7c851a --- /dev/null +++ b/Ombi/Ombi/Styles/base.scss @@ -0,0 +1,690 @@ +@import './_imports.scss'; + +$form-color: #4e5d6c; +$form-color-lighter: #637689; +$primary-colour: #df691a; +$primary-colour-outline: #ff761b; +$info-colour: #5bc0de; +$warning-colour: #f0ad4e; +$danger-colour: #d9534f; +$success-colour: #5cb85c; +$i:!important; + +@media (min-width: 768px ) { + .row { + position: relative; + } + + .bottom-align-text { + position: absolute; + bottom: 0; + right: 0; + } + + .landing-block .media { + max-width: 450px; + } +} + +@media (max-width: 48em) { + .home { + padding-top: 1rem; + } +} + +@media (min-width: 48em) { + .home { + padding-top: 4rem; + } +} + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #fff; +} + +hr { + border: 1px dashed #777; +} + +.btn { + border-radius: .25rem $i; +} + +.btn-group-separated .btn, +.btn-group-separated .btn + .btn { + margin-left: 3px; +} + +.multiSelect { + background-color: $form-color; +} + +.form-control-custom { + background-color: $form-color $i; + color: white $i; + border-radius: 0; + box-shadow: 0 0 0 !important; +} + + +h1 { + font-size: 3.5rem $i; + font-weight: 600 $i; +} + +.request-title { + margin-top: 0 $i; + font-size: 1.9rem $i; +} + +p { + font-size: 1.1rem $i; +} + +label { + display: inline-block $i; + margin-bottom: .5rem $i; + font-size: 16px $i; +} +.small-label { + display: inline-block $i; + margin-bottom: .5rem $i; + font-size: 11px $i; +} + +.small-checkbox{ + min-height:0 $i; + +} + + +.round-checkbox { + border-radius:8px; +} + +.nav-tabs > li { + font-size: 13px; + line-height: 21px; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background: #4e5d6c; +} + +.nav-tabs > li > a > .fa { + padding: 3px 5px 3px 3px; +} + +.nav-tabs > li.nav-tab-right { + float: right; +} + +.nav-tabs > li.nav-tab-right a { + margin-right: 0; + margin-left: 2px; +} + +.nav-tabs > li.nav-tab-icononly .fa { + padding: 3px; +} + +.navbar .nav a .fa, +.dropdown-menu a .fa { + font-size: 130%; + top: 1px; + position: relative; + display: inline-block; + margin-right: 5px; +} + +.dropdown-menu a .fa { + top: 2px; +} + +.btn-danger-outline { + color: $danger-colour $i; + background-color: transparent; + background-image: none; + border-color: $danger-colour $i; +} + +.btn-danger-outline:focus, +.btn-danger-outline.focus, +.btn-danger-outline:active, +.btn-danger-outline.active, +.btn-danger-outline:hover, +.open > .btn-danger-outline.dropdown-toggle { + color: #fff $i; + background-color: $danger-colour $i; + border-color: $danger-colour $i; +} + + +.btn-primary-outline { + color: $primary-colour-outline $i; + background-color: transparent; + background-image: none; + border-color: $primary-colour-outline $i; +} + +.btn-primary-outline:focus, +.btn-primary-outline.focus, +.btn-primary-outline:active, +.btn-primary-outline.active, +.btn-primary-outline:hover, +.open > .btn-primary-outline.dropdown-toggle { + color: #fff $i; + background-color: $primary-colour $i; + border-color: $primary-colour $i; +} + +.btn-info-outline { + color: $info-colour $i; + background-color: transparent; + background-image: none; + border-color: $info-colour $i; +} + +.btn-info-outline:focus, +.btn-info-outline.focus, +.btn-info-outline:active, +.btn-info-outline.active, +.btn-info-outline:hover, +.open > .btn-info-outline.dropdown-toggle { + color: #fff $i; + background-color: $info-colour $i; + border-color: $info-colour $i; +} + +.btn-warning-outline { + color: $warning-colour $i; + background-color: transparent; + background-image: none; + border-color: $warning-colour $i; +} + +.btn-warning-outline:focus, +.btn-warning-outline.focus, +.btn-warning-outline:active, +.btn-warning-outline.active, +.btn-warning-outline:hover, +.open > .btn-warning-outline.dropdown-toggle { + color: #fff $i; + background-color: $warning-colour $i; + border-color: $warning-colour $i; +} + +.btn-success-outline { + color: $success-colour $i; + background-color: transparent; + background-image: none; + border-color: $success-colour $i; +} + +.btn-success-outline:focus, +.btn-success-outline.focus, +.btn-success-outline:active, +.btn-success-outline.active, +.btn-success-outline:hover, +.open > .btn-success-outline.dropdown-toggle { + color: #fff $i; + background-color: $success-colour $i; + border-color: $success-colour $i; +} + +#movieList .mix { + display: none; +} + +#tvList .mix { + display: none; +} + +$border-radius: 10px; + +.scroll-top-wrapper { + position: fixed; + opacity: 0; + visibility: hidden; + overflow: hidden; + text-align: center; + z-index: 99999999; + background-color: $form-color; + color: #eeeeee; + width: 50px; + height: 48px; + line-height: 48px; + right: 30px; + bottom: 30px; + padding-top: 2px; + border-top-left-radius: $border-radius; + border-top-right-radius: $border-radius; + border-bottom-right-radius: $border-radius; + border-bottom-left-radius: $border-radius; + -webkit-transition: all 0.5s ease-in-out; + -moz-transition: all 0.5s ease-in-out; + -ms-transition: all 0.5s ease-in-out; + -o-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} + +.scroll-top-wrapper:hover { + background-color: $form-color-lighter; +} + +.scroll-top-wrapper.show { + visibility: visible; + cursor: pointer; + opacity: 1.0; +} + +.scroll-top-wrapper i.fa { + line-height: inherit; +} + + +.no-search-results { + text-align: center; +} + +.no-search-results .no-search-results-icon { + font-size: 10em; + color: $form-color; +} + +.no-search-results .no-search-results-text { + margin: 20px 0; + color: #ccc; +} + +.form-control-search { + padding: 13px 105px 13px 16px; + height: 100%; +} + +.form-control-withbuttons { + padding-right: 105px; +} + +.input-group-addon .btn-group { + position: absolute; + right: 45px; + z-index: 3; + top: 10px; + box-shadow: 0 0 0; +} + +.input-group-addon .btn-group .btn { + border: 1px solid rgba(255,255,255,.7) !important; + padding: 3px 12px; + color: rgba(255,255,255,.7) !important; +} + +.btn-split .btn { + border-radius: 0 !important; +} + +.btn-split .btn:not(.dropdown-toggle) { + border-radius: .25rem 0 0 .25rem $i; +} + +.btn-split .btn.dropdown-toggle { + border-radius: 0 .25rem .25rem 0 $i; + padding: 12px 8px; +} + +#updateAvailable { + background-color: #df691a; + text-align: center; + font-size: 15px; + padding: 3px 0; +} + +#cacherRunning { + background-color: $form-color; + text-align: center; + font-size: 15px; + padding: 3px 0; +} + +.checkbox label { + display: inline-block; + cursor: pointer; + position: relative; + padding-left: 25px; + margin-right: 15px; + font-size: 13px; + margin-bottom: 10px; +} + +.checkbox label:before { + content: ""; + display: inline-block; + width: 18px; + height: 18px; + margin-right: 10px; + position: absolute; + left: 0; + bottom: 1px; + border: 2px solid #eee; + border-radius: 3px; +} + +.checkbox input[type=checkbox] { + display: none; +} + +.checkbox input[type=checkbox]:checked + label:before { + content: "\2713"; + font-size: 13px; + color: #fafafa; + text-align: center; + line-height: 13px; +} + +.small-checkbox label { + display: inline-block; + cursor: pointer; + position: relative; + padding-left: 25px; + margin-right: 15px; + font-size: 13px; + margin-bottom: 10px; +} + +.small-checkbox label:before { + content: ""; + display: inline-block; + width: 18px; + height: 18px; + margin-right: 10px; + position: absolute; + left: 0; + bottom: 1px; + border: 2px solid #eee; + border-radius: 8px; + min-height:0px $i; +} + +.small-checkbox input[type=checkbox] { + display: none; +} + +.small-checkbox input[type=checkbox]:checked + label:before { + content: "\2713"; + font-size: 13px; + color: #fafafa; + text-align: center; + line-height: 13px; +} + +.small-checkbox label { + min-height: 0 $i; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} + +.input-group-sm { + padding-top: 2px; + padding-bottom: 2px; +} + +.tab-pane .form-horizontal .form-group { + margin-right: 15px; + margin-left: 15px; +} + +.bootstrap-datetimepicker-widget.dropdown-menu { + background-color: $form-color; +} + +.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after { + border-bottom: 6px solid $form-color $i; +} + +.bootstrap-datetimepicker-widget table td.active, +.bootstrap-datetimepicker-widget table td.active:hover { + color: #fff $i; +} + +.landing-header { + display: block; + margin: 60px auto; +} + +.landing-block { + background: #2f2f2f $i; + padding: 5px; +} + +.landing-block .media { + margin: 30px auto; + max-width: 450px; +} + +.landing-block .media .media-left { + display: inline-block; + float: left; + width: 70px; +} + +.landing-block .media .media-left i.fa { + font-size: 3em; +} + +.landing-title { + font-weight: bold; +} + +.checkbox-custom { + margin-top: 0 $i; + margin-bottom: 0 $i; +} + +.tooltip_templates { + display: none; +} + +.shadow { + -moz-box-shadow: 3px 3px 5px 6px #191919; + -webkit-box-shadow: 3px 3px 5px 6px #191919; + box-shadow: 3px 3px 5px 6px #191919; +} +.img-circle { + border-radius: 50%; +} + +#wrapper { + padding-left: 0; + -webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; +} + +#wrapper.toggled { + padding-right: 250px; +} + +#sidebar-wrapper { + z-index: 1000; + position: fixed; + right: 250px; + width: 0; + height: 100%; + margin-right: -250px; + overflow-y: auto; + background: #4e5d6c; + padding-left:0; + -webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; +} + +#wrapper.toggled #sidebar-wrapper { + width: 500px; +} + +#page-content-wrapper { + width: 100%; + position: absolute; + padding: 15px; +} + +#wrapper.toggled #page-content-wrapper { + position: absolute; + margin-left: -250px; +} + +/* Sidebar Styles */ + +.sidebar-nav { + position: absolute; + top: 0; + width: 500px; + margin: 0; + padding-left: 0; + list-style: none; +} + +.sidebar-nav li { + text-indent: 20px; + line-height: 40px; +} + +.sidebar-nav li a { + display: block; + text-decoration: none; + color: #999999; +} + +.sidebar-nav li a:hover { + text-decoration: none; + color: #fff; + background: rgba(255,255,255,0.2); +} + +.sidebar-nav li a:active, +.sidebar-nav li a:focus { + text-decoration: none; +} + +.sidebar-nav > .sidebar-brand { + height: 65px; + font-size: 18px; + line-height: 60px; +} + +.sidebar-nav > .sidebar-brand a { + color: #999999; +} + +.sidebar-nav > .sidebar-brand a:hover { + color: #fff; + background: none; +} + +@media(min-width:768px) { + #wrapper { + padding-right: 250px; + } + + #wrapper.toggled { + padding-right: 0; + } + + #sidebar-wrapper { + width: 500px; + } + + #wrapper.toggled #sidebar-wrapper { + width: 0; + } + + #page-content-wrapper { + padding: 20px; + position: relative; + } + + #wrapper.toggled #page-content-wrapper { + position: relative; + margin-right: 0; + } +} + +#lightbox { + + background-color: grey; + filter:alpha(opacity=50); /* IE */ + opacity: 0.5; /* Safari, Opera */ + -moz-opacity:0.50; /* FireFox */ + top: 0px; + left: 0px; + z-index: 20; + height: 100%; + width: 100%; + background-repeat:no-repeat; + background-position:center; + position:absolute; +} + + +.list-group-item-dropdown { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #3e3e3e; + border: 1px solid transparent; +} + +.wizard-heading{ + text-align: center; +} +.wizard-img{ + width: 300px; + display: block $i; + margin: 0 auto $i; +} + +.pace { + -webkit-pointer-events: none; + pointer-events: none; + + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.pace-inactive { + display: none; +} + +.pace .pace-progress { + background: $primary-colour; + position: fixed; + z-index: 2000; + top: 0; + right: 100%; + width: 100%; + height: 5px; +} + +.navbar-brand { + float: left; + padding: 4.5px 15px; + font-size: 19px; + line-height: 21px; + height: 40px; +} + +.gravatar{ + border-radius:1em; +} diff --git a/Ombi/Ombi/Views/Shared/_Layout.cshtml b/Ombi/Ombi/Views/Shared/_Layout.cshtml index 0eaaf503f..1cc395747 100644 --- a/Ombi/Ombi/Views/Shared/_Layout.cshtml +++ b/Ombi/Ombi/Views/Shared/_Layout.cshtml @@ -1,15 +1,21 @@ - +@**@ @ViewData["Title"] - Ombi - - - - - + + + + + @**@ + + - - - - @**@ - -