diff --git a/Ombi.Core/SettingModels/CustomizationSettings.cs b/Ombi.Core/SettingModels/CustomizationSettings.cs index 6225861ad..2fa664f35 100644 --- a/Ombi.Core/SettingModels/CustomizationSettings.cs +++ b/Ombi.Core/SettingModels/CustomizationSettings.cs @@ -35,5 +35,23 @@ namespace Ombi.Core.SettingModels /// The CSS name of the theme we want /// public string ThemeName { get; set; } + + /// + /// Admin Only. + /// + /// + /// The default filter. + /// + public int DefaultFilter { get; set; } + /// + /// Admin only. + /// + /// + /// The default sort. + /// + public int DefaultSort { get; set; } + + public int DefaultLang { get; set; } + } } \ No newline at end of file diff --git a/Ombi.Helpers/EnumHelper.cs b/Ombi.Helpers/EnumHelper.cs index 316de8ec7..db1ced9da 100644 --- a/Ombi.Helpers/EnumHelper.cs +++ b/Ombi.Helpers/EnumHelper.cs @@ -82,6 +82,19 @@ namespace Ombi.Helpers if (descriptionAttributes == null) return string.Empty; return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Name : value.ToString(); } + public static string GetDisplayDescription(T value) + { + var fieldInfo = value.GetType().GetField(value.ToString()); + + var descriptionAttributes = fieldInfo.GetCustomAttributes( + typeof(DisplayAttribute), false) as DisplayAttribute[]; + + if (descriptionAttributes[0].ResourceType != null) + return LookupResource(descriptionAttributes[0].ResourceType, descriptionAttributes[0].Description); + + if (descriptionAttributes == null) return string.Empty; + return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Description : value.ToString(); + } public static T GetValueFromName(string name) { diff --git a/Ombi.UI/Content/requests.js b/Ombi.UI/Content/requests.js index 7af2631ed..7928f39aa 100644 --- a/Ombi.UI/Content/requests.js +++ b/Ombi.UI/Content/requests.js @@ -16,40 +16,50 @@ var base = $('#baseUrl').text(); var tvLoaded = false; var albumLoaded = false; -var isAdmin = $('#isAdmin').text(); -var defaultFiler = isAdmin == 'True' ? '.approved-fase' : 'all'; +var isAdmin = $('#isAdmin').text() === "True"; + +var adminFilter = $('#adminFilter').text(); +var adminFilterText = $('#adminFilterText').text(); +var adminSort = $('#adminSort').text(); +var adminSortText = $('#adminSortText').text(); + +var defaultFilterText = $('#defaultFilterText').text(); +var defaultSortText = $('#defaultSortText').text(); + + +$("#filterText").text(isAdmin ? adminFilterText : defaultFilterText); +$("#sortText").text(isAdmin ? adminSortText : defaultSortText); + +// Loop through all the filters to set the correct one to checked +selectCheckboxes('.filter', isAdmin ? adminFilterText : defaultFilterText); +selectCheckboxes('.sort', isAdmin ? adminSortText : defaultSortText); + + +function selectCheckboxes(className, text) { + $(className).each(function (i, obj) { + + var $element = $(obj.children[0]); + if (obj.text === " " + text) { + $element.removeClass('fa-square-o').addClass('fa-check-square'); + } else { + if ($element.hasClass('fa-check-square')) { + $element.removeClass('fa-check-square').addClass('fa-square-o'); + } + } + }); +} var mixItUpDefault = { animation: { enable: true }, load: { - filter: defaultFiler, - sort: 'requestorder:desc' + filter: isAdmin ? adminFilter : 'all', + sort: isAdmin ? adminSort : 'requestorder:desc' }, layout: { display: 'block' }, callbacks: { onMixStart: function (state, futureState) { - //futureState.activeSort // sort - //futureState.activeFilter // next filter - - // The below is TODO for saving the users filter and sort order - //var url = createBaseUrl(base, '/requests/UpdateFilters'); - //$.ajax({ - // type: 'post', - // url: url, - // data: {sort:futureState.activeSort, filter:futureState.activeFilte}, - // dataType: "json", - // success: function (response) { - // console.log("saved filter and sort order"); - // }, - // error: function (e) { - // console.log(e); - // generateNotify("Something went wrong saving your filter!", "danger"); - // } - //}); - - $('.mix', this).removeAttr('data-bound').removeData('bound'); // fix for animation issues in other tabs } } @@ -295,6 +305,9 @@ $('.sort', '.dropdown-menu').click(function (e) { var $this = $(this); $('.fa-check-square', $this.parents('.dropdown-menu:first')).removeClass('fa-check-square').addClass('fa-square-o'); $this.children('.fa').first().removeClass('fa-square-o').addClass('fa-check-square'); + $("#sortText").fadeOut(function () { + $(this).text($this.text().trim()); + }).fadeIn(); }); diff --git a/Ombi.UI/Models/Admin/CustomizationViewModel.cs b/Ombi.UI/Models/Admin/CustomizationViewModel.cs new file mode 100644 index 000000000..568182a10 --- /dev/null +++ b/Ombi.UI/Models/Admin/CustomizationViewModel.cs @@ -0,0 +1,97 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: CustomizationViewModel.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.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using Ombi.Core.SettingModels; +using Ombi.UI.Models.UI; + +namespace Ombi.UI.Models.Admin +{ + public class CustomizationViewModel + { + public CustomizationSettings Settings { get; set; } + public List> LanguageDropdown { get; } = new List>(); + public List> FilterOptions { get; } = new List>(); + public List> SortOptions { get; set; } = new List>(); + } + + public enum FilterOptions + { + [Display(Name = "all", Description = "All")] + All, + [Display(Name = ".approved-true", Description = "Approved")] + Approved, + [Display(Name = ".approved-false", Description = "Not Approved")] + NotApproved, + [Display(Name = ".available-true", Description = "Available")] + Available, + [Display(Name = ".available-false", Description = "Not Available")] + NotAvailable, + [Display(Name = ".released-true", Description = "Released")] + Released, + [Display(Name = ".released-false", Description = "Not Released")] + NotReleased + } + + public enum SortOptions + { + [Display(Name = "requestorder:desc", Description = "Latest Requests")] + LatestRequests, + [Display(Name = "requestorder:asc", Description = "Oldest Requests")] + OldestRequests, + [Display(Name = "releaseorder:desc", Description = "Latest Releases")] + LatestRelease, + [Display(Name = "releaseorder:asc", Description = "Oldest Releases")] + OldestRelease + } + + public enum Languages + { + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_English")] + en, + + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_French")] + fr, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Dutch")] + nl, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Spanish")] + es, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_German")] + de, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Danish")] + da, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Portuguese")] + pt, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Swedish")] + sv, + [Display(ResourceType = typeof(Resources.UI), Name = "Layout_Italian")] + it + } +} \ No newline at end of file diff --git a/Ombi.UI/Models/Requests/RequestsIndexViewModel.cs b/Ombi.UI/Models/Requests/RequestsIndexViewModel.cs new file mode 100644 index 000000000..b95b96273 --- /dev/null +++ b/Ombi.UI/Models/Requests/RequestsIndexViewModel.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: RequestsIndexViewModel.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 Ombi.Core.SettingModels; + +namespace Ombi.UI.Models.Requests +{ + public class RequestsIndexViewModel + { + public PlexRequestSettings PlexRequestSettings { get; set; } + public CustomizationSettings CustomizationSettings { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.UI/Models/UI/Dropdown.cs b/Ombi.UI/Models/UI/Dropdown.cs new file mode 100644 index 000000000..834a7cf61 --- /dev/null +++ b/Ombi.UI/Models/UI/Dropdown.cs @@ -0,0 +1,35 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: Dropdown.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 +namespace Ombi.UI.Models.UI +{ + public class Dropdown + { + public bool Selected { get; set; } + public string Name { get; set; } + public T Value { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.UI/Modules/Admin/CustomizationModule.cs b/Ombi.UI/Modules/Admin/CustomizationModule.cs index a368e66f4..d34e41ee2 100644 --- a/Ombi.UI/Modules/Admin/CustomizationModule.cs +++ b/Ombi.UI/Modules/Admin/CustomizationModule.cs @@ -1,4 +1,5 @@ #region Copyright + // /************************************************************************ // Copyright (c) 2016 Jamie Rees // File: CustomizationModule.cs @@ -23,43 +24,94 @@ // 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.Collections.Generic; using System.Threading.Tasks; using Nancy; using Nancy.ModelBinding; using Nancy.Responses.Negotiation; using Ombi.Core; using Ombi.Core.SettingModels; +using Ombi.Helpers; using Ombi.Helpers.Permissions; using Ombi.UI.Models; +using Ombi.UI.Models.Admin; +using Ombi.UI.Models.UI; +using TMDbLib.Utilities; using ISecurityExtensions = Ombi.Core.ISecurityExtensions; namespace Ombi.UI.Modules.Admin { public class CustomizationModule : BaseModule { - public CustomizationModule(ISettingsService settingsService, ISettingsService cust, ISecurityExtensions security) : base("admin", settingsService, security) + public CustomizationModule(ISettingsService settingsService, + ISettingsService cust, ISecurityExtensions security) + : base("admin", settingsService, security) { Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx); Settings = cust; - Get["/customization", true] = async (x,ct) => await Index(); - Post["/customization", true] = async (x,ct) => await Save(); + Get["/customization", true] = async (x, ct) => await Index(); + Post["/customization", true] = async (x, ct) => await Save(); } - + private ISettingsService Settings { get; } private async Task Index() { var model = await Settings.GetSettingsAsync(); - return View["customization", model]; + var viewModel = new CustomizationViewModel + { + Settings = model, + SortOptions = new List>() + }; + + + + + foreach (var value in EnumHelper.GetValues(SortOptions.LatestRelease)) + { + viewModel.SortOptions.Add(new Dropdown + { + Value = value, + Name = EnumHelper.GetDisplayDescription(value), + Selected = model.DefaultSort == (int) value + }); + } + + foreach (var value in EnumHelper.GetValues(FilterOptions.Available)) + { + viewModel.FilterOptions.Add(new Dropdown + { + Value = value, + Name = EnumHelper.GetDisplayDescription(value), + Selected = model.DefaultFilter == (int) value + }); + } + + foreach (var value in EnumHelper.GetValues(Languages.en)) + { + viewModel.LanguageDropdown.Add(new Dropdown + { + Value = value, + Name = EnumHelper.GetDisplayValue(value), + Selected = model.DefaultLang == (int) value + }); + } + + return View["customization", viewModel]; } private async Task Save() { + try + { + var model = this.Bind(); var result = await Settings.SaveSettingsAsync(model); @@ -67,6 +119,12 @@ namespace Ombi.UI.Modules.Admin return Response.AsJson(result ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "We could not save to the database, please try again" }); + } + catch (Exception e) + { + + throw; + } } } } \ No newline at end of file diff --git a/Ombi.UI/Modules/RequestsModule.cs b/Ombi.UI/Modules/RequestsModule.cs index e304120e5..f0c0934ac 100644 --- a/Ombi.UI/Modules/RequestsModule.cs +++ b/Ombi.UI/Modules/RequestsModule.cs @@ -43,6 +43,8 @@ using Ombi.Services.Interfaces; using Ombi.Services.Notification; using Ombi.Store; using Ombi.UI.Models; +using Ombi.UI.Models.Admin; +using Ombi.UI.Models.Requests; using Action = Ombi.Helpers.Analytics.Action; using ISecurityExtensions = Ombi.Core.ISecurityExtensions; @@ -64,7 +66,8 @@ namespace Ombi.UI.Modules ICacheProvider cache, IAnalytics an, INotificationEngine engine, - ISecurityExtensions security) : base("requests", prSettings, security) + ISecurityExtensions security, + ISettingsService customSettings) : base("requests", prSettings, security) { Service = service; PrSettings = prSettings; @@ -79,6 +82,7 @@ namespace Ombi.UI.Modules Cache = cache; Analytics = an; NotificationEngine = engine; + CustomizationSettings = customSettings; Get["/", true] = async (x, ct) => await LoadRequests(); Get["/movies", true] = async (x, ct) => await GetMovies(); @@ -92,7 +96,7 @@ namespace Ombi.UI.Modules Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available); - Post["/UpdateFilters", true] = async (x, ct) => await UpdateFilters(); + Get["/UpdateFilters", true] = async (x, ct) => await GetFilterAndSortSettings(); } private static Logger Log = LogManager.GetCurrentClassLogger(); @@ -104,6 +108,7 @@ namespace Ombi.UI.Modules private ISettingsService SonarrSettings { get; } private ISettingsService SickRageSettings { get; } private ISettingsService CpSettings { get; } + private ISettingsService CustomizationSettings { get; } private ISonarrApi SonarrApi { get; } private ISickRageApi SickRageApi { get; } private ICouchPotatoApi CpApi { get; } @@ -113,7 +118,9 @@ namespace Ombi.UI.Modules private async Task LoadRequests() { var settings = await PrSettings.GetSettingsAsync(); - return View["Index", settings]; + var custom = await CustomizationSettings.GetSettingsAsync(); + + return View["Index", new RequestsIndexViewModel { CustomizationSettings = custom, PlexRequestSettings = settings }]; } private async Task GetMovies() @@ -223,7 +230,7 @@ namespace Ombi.UI.Modules } catch (Exception e) { - Log.Info(e); + Log.Info(e); } } @@ -312,7 +319,7 @@ namespace Ombi.UI.Modules return Response.AsJson(new JsonResponseModel { Result = true }); } - + Analytics.TrackEventAsync(Category.Requests, Action.Delete, "Delete Request", Username, CookieHelper.GetAnalyticClientId(Cookies)); var currentEntity = await Service.GetAsync(requestid); @@ -408,11 +415,20 @@ namespace Ombi.UI.Modules : new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" }); } - private async Task UpdateFilters() + private async Task GetFilterAndSortSettings() { + var s = await CustomizationSettings.GetSettingsAsync(); + var sortVal = EnumHelper.GetDisplayValue((SortOptions)s.DefaultSort); + var filterVal = EnumHelper.GetDisplayValue((FilterOptions)s.DefaultFilter); - return Response.AsJson(""); + var vm = new + { + DefaultSort = sortVal, + DefaultFilter = filterVal + }; + + return Response.AsJson(vm); } } } diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj index 74904233c..38a6bdf40 100644 --- a/Ombi.UI/Ombi.UI.csproj +++ b/Ombi.UI/Ombi.UI.csproj @@ -118,6 +118,7 @@ True + @@ -233,6 +234,7 @@ + @@ -243,10 +245,12 @@ + + diff --git a/Ombi.UI/Views/Customization/Customization.cshtml b/Ombi.UI/Views/Customization/Customization.cshtml index 112fb6e44..ff2e7a296 100644 --- a/Ombi.UI/Views/Customization/Customization.cshtml +++ b/Ombi.UI/Views/Customization/Customization.cshtml @@ -1,14 +1,14 @@ @using Ombi.UI.Helpers -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @Html.Partial("Shared/Partial/_Sidebar") @{ var plexTheme = string.Empty; var originalTheme = string.Empty; - if (!string.IsNullOrEmpty(Model.ThemeName)) + if (!string.IsNullOrEmpty(Model.Settings.ThemeName)) { - plexTheme = Model.ThemeName.Equals(Themes.PlexTheme) ? "selected=\"selected\"" : string.Empty; - originalTheme = Model.ThemeName.Equals(Themes.OriginalTheme) ? "selected=\"selected\"" : string.Empty; + plexTheme = Model.Settings.ThemeName.Equals(Themes.PlexTheme) ? "selected=\"selected\"" : string.Empty; + originalTheme = Model.Settings.ThemeName.Equals(Themes.OriginalTheme) ? "selected=\"selected\"" : string.Empty; } else { @@ -26,7 +26,7 @@
- +
@@ -39,6 +39,69 @@ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
@@ -60,10 +123,17 @@ e.preventDefault(); var theme = $("#themes option:selected").val(); + var lang = $('#langSelect option:selected').val(); + var sort = $('#sortSelect option:selected').val(); + var filter = $('#filterSelect option:selected').val(); var $form = $("#mainForm"); var data = $form.serialize(); - data = data + "&themeName=" + theme; + data = data + + "&themeName=" + theme + + "&DefaultLang=" + lang + + "&DefaultSort=" + sort + + "&DefaultFilter=" + filter; $.ajax({ type: $form.prop("method"), diff --git a/Ombi.UI/Views/Requests/Index.cshtml b/Ombi.UI/Views/Requests/Index.cshtml index 9134aff07..0447e25fa 100644 --- a/Ombi.UI/Views/Requests/Index.cshtml +++ b/Ombi.UI/Views/Requests/Index.cshtml @@ -1,8 +1,12 @@ @using Nancy.Security @using Nancy.Security +@using Ombi.Helpers @using Ombi.Helpers.Permissions @using Ombi.UI.Helpers +@using Ombi.UI.Models.Admin @using Ombi.UI.Resources + +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @{ var baseUrl = Html.GetBaseUrl(); var formAction = string.Empty; @@ -11,29 +15,42 @@ { formAction = "/" + baseUrl.ToHtmlString(); } + + var sortText = EnumHelper.GetDisplayDescription((SortOptions) Model.CustomizationSettings.DefaultSort); + var filterText = EnumHelper.GetDisplayDescription((FilterOptions) Model.CustomizationSettings.DefaultFilter); + var defaultFilter = EnumHelper.GetDisplayValue((FilterOptions) Model.CustomizationSettings.DefaultFilter); + var defaultSort = EnumHelper.GetDisplayValue((SortOptions) Model.CustomizationSettings.DefaultSort); + }
- + + + + + + + +

@UI.Requests_Title

@UI.Requests_Paragraph

-
+
-
+
@@ -43,53 +60,33 @@
@if (isAdmin) { - @if (Model.SearchForMovies) - { - - - } - @if (Model.SearchForTvShows) - { - - - } - @if (Model.SearchForMusic) - { - - - } + @if (Model.PlexRequestSettings.SearchForMovies) + { + + + } + @if (Model.PlexRequestSettings.SearchForTvShows) + { + + + } + @if (Model.PlexRequestSettings.SearchForMusic) + { + + + } }
- @if (Model.SearchForMovies) + @if (Model.PlexRequestSettings.SearchForMovies) {
-
-
+
+
} - @if (Model.SearchForTvShows) + @if (Model.PlexRequestSettings.SearchForTvShows) {
-
-
+
+
} - @if (Model.SearchForMusic) + @if (Model.PlexRequestSettings.SearchForMusic) {
-
-
+
+
@@ -202,12 +199,12 @@ {{status}} {{#if denied}}
- Denied: + Denied: {{#if deniedReason}} {{/if}}
- + {{/if}} {{#if_eq releaseDate "01/01/0001 00:00:00"}}
@UI.Requests_ReleaseDate: {{releaseDate}}
@@ -234,7 +231,7 @@ {{/if_eq}}
- + {{#if_eq type "tv"}} {{#if episodes}} Episodes: @@ -284,7 +281,7 @@
- diff --git a/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml b/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml index 9d3e24893..f801cc9a4 100644 --- a/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml +++ b/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml @@ -1,4 +1,4 @@ -ab@using Nancy.Security +@using Nancy.Security @using Nancy.Session @using Nancy; @using Ombi.Helpers diff --git a/README.md b/README.md index 7d5863d88..776438511 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,11 @@ ____ Here some of the features Ombi has: * All your users to Request Movies, TV Shows (Whole series, whole seaons or even single episodes!) and Albums * Easily manage your requests + * User mangement system (supports plex.tv accounts and local accounts) [NEW] * Sending newsletters [NEW] * Fault Queue for requests (Buffer requests if Sonar/Couchpotato/SickRage is offline) [NEW] + * Allow your users to report issues and manage them seperatly * A landing page that will give you the availability of your Plex server and also add custom notification text to inform your users of downtime. * Allow your users to get notifications! @@ -70,16 +72,13 @@ Looking for a Docker Image? Well [rogueosb](https://github.com/rogueosb/) has cr We are looking for any contributions to the project! Just pick up a task, if you have any questions ask and i'll get straight on it! -Please feel free to submit a pull request! +Please feed free to submit a pull request! # Donation If you feel like donating you can [here!](https://paypal.me/PlexRequestsNet) ### A massive thanks to everyone for all their help! - -## [Feathub](http://feathub.com/tidusjar/Ombi) -[![Feature Requests](http://feathub.com/tidusjar/Ombi?format=svg)](http://feathub.com/tidusjar/Ombi) - ## Stats -[![Throughput Graph](https://graphs.waffle.io/tidusjar/Ombi/throughput.svg)](https://waffle.io/tidusjar/Ombi/metrics/throughput) +[![Throughput Graph](https://graphs.waffle.io/tidusjar/PlexRequests.Net/throughput.svg)](https://waffle.io/tidusjar/PlexRequests.Net/metrics/throughput) +