From ae4d51de9bc1f93dedf2f985b68f3f7cfa5a1c85 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 31 May 2016 13:05:34 +0100 Subject: [PATCH] Started #273 --- PlexRequests.Core/CacheKeys.cs | 20 +- PlexRequests.Core/IIssueService.cs | 43 +++ .../JsonIssuesModelRequestService.cs | 115 ++++++ ...e.cs => JsonRequestModelRequestService.cs} | 350 +++++++++--------- PlexRequests.Core/Models/IssuesModel.cs | 58 +++ PlexRequests.Core/PlexRequests.Core.csproj | 5 +- PlexRequests.Store/Models/IssueBlobs.cs | 38 ++ PlexRequests.Store/PlexRequests.Store.csproj | 1 + PlexRequests.Store/SqlTables.sql | 11 +- PlexRequests.UI/Bootstrapper.cs | 13 +- PlexRequests.UI/Helpers/BaseUrlHelper.cs | 21 ++ PlexRequests.UI/Modules/IssuesModule.cs | 51 +++ PlexRequests.UI/PlexRequests.UI.csproj | 1 + PlexRequests.UI/Views/Shared/_Layout.cshtml | 30 +- 14 files changed, 562 insertions(+), 195 deletions(-) create mode 100644 PlexRequests.Core/IIssueService.cs create mode 100644 PlexRequests.Core/JsonIssuesModelRequestService.cs rename PlexRequests.Core/{JsonRequestService.cs => JsonRequestModelRequestService.cs} (95%) create mode 100644 PlexRequests.Core/Models/IssuesModel.cs create mode 100644 PlexRequests.Store/Models/IssueBlobs.cs create mode 100644 PlexRequests.UI/Modules/IssuesModule.cs diff --git a/PlexRequests.Core/CacheKeys.cs b/PlexRequests.Core/CacheKeys.cs index cd347b3c3..a2bbf2496 100644 --- a/PlexRequests.Core/CacheKeys.cs +++ b/PlexRequests.Core/CacheKeys.cs @@ -33,21 +33,21 @@ namespace PlexRequests.Core public const int SchedulerCaching = 60; } - public const string PlexLibaries = "PlexLibaries"; + public const string PlexLibaries = nameof(PlexLibaries); - public const string TvDbToken = "TheTvDbApiToken"; + public const string TvDbToken = nameof(TvDbToken); - public const string SonarrQualityProfiles = "SonarrQualityProfiles"; - public const string SonarrQueued = "SonarrQueued"; + public const string SonarrQualityProfiles = nameof(SonarrQualityProfiles); + public const string SonarrQueued = nameof(SonarrQueued); - public const string SickRageQualityProfiles = "SickRageQualityProfiles"; - public const string SickRageQueued = "SickRageQueued"; + public const string SickRageQualityProfiles = nameof(SickRageQualityProfiles); + public const string SickRageQueued = nameof(SickRageQueued); - public const string CouchPotatoQualityProfiles = "CouchPotatoQualityProfiles"; - public const string CouchPotatoQueued = "CouchPotatoQueued"; + public const string CouchPotatoQualityProfiles = nameof(CouchPotatoQualityProfiles); + public const string CouchPotatoQueued = nameof(CouchPotatoQueued); - public const string GetPlexRequestSettings = "GetPlexRequestSettings"; + public const string GetPlexRequestSettings = nameof(GetPlexRequestSettings); - public const string LastestProductVersion = "LatestProductVersion"; + public const string LastestProductVersion = nameof(LastestProductVersion); } } \ No newline at end of file diff --git a/PlexRequests.Core/IIssueService.cs b/PlexRequests.Core/IIssueService.cs new file mode 100644 index 000000000..dab00222e --- /dev/null +++ b/PlexRequests.Core/IIssueService.cs @@ -0,0 +1,43 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: IIssueService.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.Collections.Generic; +using System.Threading.Tasks; + +using PlexRequests.Core.Models; + +namespace PlexRequests.Core +{ + public interface IIssueService + { + Task AddIssueAsync(IssuesModel model); + Task UpdateIssueAsync(IssuesModel model); + Task DeleteIssueAsync(int id); + Task DeleteIssueAsync(IssuesModel model); + Task GetAsync(int id); + Task> GetAllAsync(); + } +} \ No newline at end of file diff --git a/PlexRequests.Core/JsonIssuesModelRequestService.cs b/PlexRequests.Core/JsonIssuesModelRequestService.cs new file mode 100644 index 000000000..dd6a8f9a7 --- /dev/null +++ b/PlexRequests.Core/JsonIssuesModelRequestService.cs @@ -0,0 +1,115 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: IssueJsonService.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.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Newtonsoft.Json; + +using PlexRequests.Core.Models; +using PlexRequests.Helpers; +using PlexRequests.Store.Models; +using PlexRequests.Store.Repository; + +namespace PlexRequests.Core +{ + public class IssueJsonService : IIssueService + { + public IssueJsonService(IRepository repo) + { + Repo = repo; + } + private IRepository Repo { get; } + public async Task AddIssueAsync(IssuesModel model) + { + var entity = new IssueBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), RequestId = model.RequestId }; + var id = await Repo.InsertAsync(entity); + + model.Id = id; + + entity = new IssueBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), RequestId = model.RequestId, Id = id }; + var result = await Repo.UpdateAsync(entity); + + return result ? id : -1; + } + + public async Task UpdateIssueAsync(IssuesModel model) + { + var entity = new IssueBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), RequestId = model.RequestId, Id = model.Id }; + return await Repo.UpdateAsync(entity); + } + + public async Task DeleteIssueAsync(int id) + { + var entity = await Repo.GetAsync(id); + + await Repo.DeleteAsync(entity); + } + + public async Task DeleteIssueAsync(IssuesModel model) + { + var entity = new IssueBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), RequestId = model.RequestId, Id = model.Id }; + + await Repo.DeleteAsync(entity); + } + + /// + /// Gets the Issues, if there is no issue in the DB we return a new . + /// + /// The identifier. + /// + public async Task GetAsync(int id) + { + var blob = await Repo.GetAsync(id); + + if (blob == null) + { + return new IssuesModel(); + } + var model = ByteConverterHelper.ReturnObject(blob.Content); + return model; + } + + /// + /// Gets all the Issues, if there is no issue in the DB we return a new IEnumerable<IssuesModel>. + /// + /// + public async Task> GetAllAsync() + { + var blobs = await Repo.GetAllAsync(); + + if (blobs == null) + { + return new List(); + } + return blobs.Select(b => Encoding.UTF8.GetString(b.Content)) + .Select(JsonConvert.DeserializeObject) + .ToList(); + } + } +} \ No newline at end of file diff --git a/PlexRequests.Core/JsonRequestService.cs b/PlexRequests.Core/JsonRequestModelRequestService.cs similarity index 95% rename from PlexRequests.Core/JsonRequestService.cs rename to PlexRequests.Core/JsonRequestModelRequestService.cs index d44069271..a8d279063 100644 --- a/PlexRequests.Core/JsonRequestService.cs +++ b/PlexRequests.Core/JsonRequestModelRequestService.cs @@ -1,176 +1,176 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2016 Jamie Rees -// File: JsonRequestService.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.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Newtonsoft.Json; - -using PlexRequests.Helpers; -using PlexRequests.Store; -using PlexRequests.Store.Models; -using PlexRequests.Store.Repository; - -namespace PlexRequests.Core -{ - public class JsonRequestService : IRequestService - { - public JsonRequestService(IRequestRepository repo) - { - Repo = repo; - } - private IRequestRepository Repo { get; } - public long AddRequest(RequestedModel model) - { - var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId }; - var id = Repo.Insert(entity); - - model.Id = (int)id; - - entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = (int)id, MusicId = model.MusicBrainzId }; - var result = Repo.Update(entity); - - return result ? id : -1; - } - - public async Task AddRequestAsync(RequestedModel model) - { - var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId }; - var id = await Repo.InsertAsync(entity); - - model.Id = id; - - entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = id, MusicId = model.MusicBrainzId }; - var result = await Repo.UpdateAsync(entity); - - return result ? id : -1; - } - - public RequestedModel CheckRequest(int providerId) - { - var blobs = Repo.GetAll(); - var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId); - return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; - } - - public async Task CheckRequestAsync(int providerId) - { - var blobs = await Repo.GetAllAsync(); - var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId); - return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; - } - - public RequestedModel CheckRequest(string musicId) - { - var blobs = Repo.GetAll(); - var blob = blobs.FirstOrDefault(x => x.MusicId == musicId); - return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; - } - - public async Task CheckRequestAsync(string musicId) - { - var blobs = await Repo.GetAllAsync(); - var blob = blobs.FirstOrDefault(x => x.MusicId == musicId); - return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; - } - - public void DeleteRequest(RequestedModel request) - { - var blob = Repo.Get(request.Id); - Repo.Delete(blob); - } - - public async Task DeleteRequestAsync(RequestedModel request) - { - var blob = await Repo.GetAsync(request.Id); - await Repo.DeleteAsync(blob); - } - - public bool UpdateRequest(RequestedModel model) - { - var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id }; - return Repo.Update(entity); - } - - public async Task UpdateRequestAsync(RequestedModel model) - { - var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id }; - return await Repo.UpdateAsync(entity); - } - - public RequestedModel Get(int id) - { - var blob = Repo.Get(id); - if (blob == null) - { - return new RequestedModel(); - } - var model = ByteConverterHelper.ReturnObject(blob.Content); - return model; - } - - public async Task GetAsync(int id) - { - var blob = await Repo.GetAsync(id); - if (blob == null) - { - return new RequestedModel(); - } - var model = ByteConverterHelper.ReturnObject(blob.Content); - return model; - } - - public IEnumerable GetAll() - { - var blobs = Repo.GetAll(); - return blobs.Select(b => Encoding.UTF8.GetString(b.Content)) - .Select(JsonConvert.DeserializeObject) - .ToList(); - } - - public async Task> GetAllAsync() - { - var blobs = await Repo.GetAllAsync(); - return blobs.Select(b => Encoding.UTF8.GetString(b.Content)) - .Select(JsonConvert.DeserializeObject) - .ToList(); - } - - public bool BatchUpdate(List model) - { - var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList(); - return Repo.UpdateAll(entities); - } - - public bool BatchDelete(List model) - { - var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList(); - return Repo.DeleteAll(entities); - } - } +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: JsonRequestModelRequestService.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.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Newtonsoft.Json; + +using PlexRequests.Helpers; +using PlexRequests.Store; +using PlexRequests.Store.Models; +using PlexRequests.Store.Repository; + +namespace PlexRequests.Core +{ + public class JsonRequestModelRequestService : IRequestService + { + public JsonRequestModelRequestService(IRequestRepository repo) + { + Repo = repo; + } + private IRequestRepository Repo { get; } + public long AddRequest(RequestedModel model) + { + var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId }; + var id = Repo.Insert(entity); + + model.Id = (int)id; + + entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = (int)id, MusicId = model.MusicBrainzId }; + var result = Repo.Update(entity); + + return result ? id : -1; + } + + public async Task AddRequestAsync(RequestedModel model) + { + var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId }; + var id = await Repo.InsertAsync(entity); + + model.Id = id; + + entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = id, MusicId = model.MusicBrainzId }; + var result = await Repo.UpdateAsync(entity); + + return result ? id : -1; + } + + public RequestedModel CheckRequest(int providerId) + { + var blobs = Repo.GetAll(); + var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId); + return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; + } + + public async Task CheckRequestAsync(int providerId) + { + var blobs = await Repo.GetAllAsync(); + var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId); + return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; + } + + public RequestedModel CheckRequest(string musicId) + { + var blobs = Repo.GetAll(); + var blob = blobs.FirstOrDefault(x => x.MusicId == musicId); + return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; + } + + public async Task CheckRequestAsync(string musicId) + { + var blobs = await Repo.GetAllAsync(); + var blob = blobs.FirstOrDefault(x => x.MusicId == musicId); + return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; + } + + public void DeleteRequest(RequestedModel request) + { + var blob = Repo.Get(request.Id); + Repo.Delete(blob); + } + + public async Task DeleteRequestAsync(RequestedModel request) + { + var blob = await Repo.GetAsync(request.Id); + await Repo.DeleteAsync(blob); + } + + public bool UpdateRequest(RequestedModel model) + { + var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id }; + return Repo.Update(entity); + } + + public async Task UpdateRequestAsync(RequestedModel model) + { + var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id }; + return await Repo.UpdateAsync(entity); + } + + public RequestedModel Get(int id) + { + var blob = Repo.Get(id); + if (blob == null) + { + return new RequestedModel(); + } + var model = ByteConverterHelper.ReturnObject(blob.Content); + return model; + } + + public async Task GetAsync(int id) + { + var blob = await Repo.GetAsync(id); + if (blob == null) + { + return new RequestedModel(); + } + var model = ByteConverterHelper.ReturnObject(blob.Content); + return model; + } + + public IEnumerable GetAll() + { + var blobs = Repo.GetAll(); + return blobs.Select(b => Encoding.UTF8.GetString(b.Content)) + .Select(JsonConvert.DeserializeObject) + .ToList(); + } + + public async Task> GetAllAsync() + { + var blobs = await Repo.GetAllAsync(); + return blobs.Select(b => Encoding.UTF8.GetString(b.Content)) + .Select(JsonConvert.DeserializeObject) + .ToList(); + } + + public bool BatchUpdate(List model) + { + var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList(); + return Repo.UpdateAll(entities); + } + + public bool BatchDelete(List model) + { + var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList(); + return Repo.DeleteAll(entities); + } + } } \ No newline at end of file diff --git a/PlexRequests.Core/Models/IssuesModel.cs b/PlexRequests.Core/Models/IssuesModel.cs new file mode 100644 index 000000000..0a7a537e8 --- /dev/null +++ b/PlexRequests.Core/Models/IssuesModel.cs @@ -0,0 +1,58 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: IssuesModel.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.Collections.Generic; + +using PlexRequests.Store; + +namespace PlexRequests.Core.Models +{ + public class IssuesModel : Entity + { + public string Title { get; set; } + public string PosterUrl1 { get; set; } + public int RequestId { get; set; } + public List Issues { get; set; } + public bool Deleted { get; set; } + public RequestType Type { get; set; } + } + + public class IssueModel + { + public string UserNote { get; set; } + public string UserReported { get; set; } + public IssueState Issue { get; set; } + public string AdminNote { get; set; } + public IssueStatus IssueStatus { get; set; } + } + + public enum IssueStatus + { + PendingIssue, + InProgressIssue, + ResolvedIssue + } +} \ No newline at end of file diff --git a/PlexRequests.Core/PlexRequests.Core.csproj b/PlexRequests.Core/PlexRequests.Core.csproj index 0b454381e..62a2af642 100644 --- a/PlexRequests.Core/PlexRequests.Core.csproj +++ b/PlexRequests.Core/PlexRequests.Core.csproj @@ -66,9 +66,12 @@ + - + + + diff --git a/PlexRequests.Store/Models/IssueBlobs.cs b/PlexRequests.Store/Models/IssueBlobs.cs new file mode 100644 index 000000000..5dfa99914 --- /dev/null +++ b/PlexRequests.Store/Models/IssueBlobs.cs @@ -0,0 +1,38 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: RequestBlobs.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 Dapper.Contrib.Extensions; + +namespace PlexRequests.Store.Models +{ + [Table("IssueBlobs")] + public class IssueBlobs : Entity + { + public int RequestId { get; set; } + public byte[] Content { get; set; } + public RequestType Type { get; set; } + } +} \ No newline at end of file diff --git a/PlexRequests.Store/PlexRequests.Store.csproj b/PlexRequests.Store/PlexRequests.Store.csproj index c5dd29053..6742f3e1c 100644 --- a/PlexRequests.Store/PlexRequests.Store.csproj +++ b/PlexRequests.Store/PlexRequests.Store.csproj @@ -62,6 +62,7 @@ + diff --git a/PlexRequests.Store/SqlTables.sql b/PlexRequests.Store/SqlTables.sql index 74d5f2c13..6e89f589c 100644 --- a/PlexRequests.Store/SqlTables.sql +++ b/PlexRequests.Store/SqlTables.sql @@ -72,4 +72,13 @@ CREATE TABLE IF NOT EXISTS UsersToNotify Id INTEGER PRIMARY KEY AUTOINCREMENT, Username varchar(100) NOT NULL ); -CREATE UNIQUE INDEX IF NOT EXISTS UsersToNotify_Id ON UsersToNotify (Id); \ No newline at end of file +CREATE UNIQUE INDEX IF NOT EXISTS UsersToNotify_Id ON UsersToNotify (Id); + +CREATE TABLE IF NOT EXISTS IssueBlobs +( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + RequestId INTEGER, + Type INTEGER NOT NULL, + Content BLOB NOT NULL +); +CREATE UNIQUE INDEX IF NOT EXISTS IssueBlobs_Id ON IssueBlobs (Id); \ No newline at end of file diff --git a/PlexRequests.UI/Bootstrapper.cs b/PlexRequests.UI/Bootstrapper.cs index 4eef3be38..105dda195 100644 --- a/PlexRequests.UI/Bootstrapper.cs +++ b/PlexRequests.UI/Bootstrapper.cs @@ -68,9 +68,6 @@ namespace PlexRequests.UI protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context) { - - container.Register().AsSingleton(); - // Settings container.Register, SettingsServiceV2>(); container.Register, SettingsServiceV2>(); @@ -89,7 +86,9 @@ namespace PlexRequests.UI container.Register, GenericRepository>(); container.Register, GenericRepository>(); container.Register, GenericRepository>(); - container.Register(); + container.Register, GenericRepository>(); + container.Register(); + container.Register(); container.Register(); container.Register(); @@ -100,7 +99,7 @@ namespace PlexRequests.UI container.Register(); container.Register(); - // Api's + // Api container.Register(); container.Register(); container.Register(); @@ -111,7 +110,7 @@ namespace PlexRequests.UI container.Register(); container.Register(); - // NotificationService + // Notification Service container.Register().AsSingleton(); JsonSettings.MaxJsonLength = int.MaxValue; @@ -125,6 +124,7 @@ namespace PlexRequests.UI protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines) { + container.Register().AsSingleton(); container.Register(new DbConfiguration(new SqliteFactory())); container.Register, UserRepository>(); container.Register(); @@ -132,7 +132,6 @@ namespace PlexRequests.UI CookieBasedSessions.Enable(pipelines, CryptographyConfiguration.Default); - StaticConfiguration.DisableErrorTraces = false; base.ApplicationStartup(container, pipelines); diff --git a/PlexRequests.UI/Helpers/BaseUrlHelper.cs b/PlexRequests.UI/Helpers/BaseUrlHelper.cs index f186054b9..331cf5e31 100644 --- a/PlexRequests.UI/Helpers/BaseUrlHelper.cs +++ b/PlexRequests.UI/Helpers/BaseUrlHelper.cs @@ -154,6 +154,27 @@ namespace PlexRequests.UI.Helpers returnString = $"
  • {title}
  • "; } + return helper.Raw(returnString); + } + + public static IHtmlString GetNavbarUrl(this HtmlHelpers helper, NancyContext context, string url, string title, string fontIcon, string extraHtml) + { + var returnString = string.Empty; + var content = GetLinkUrl(GetBaseUrl()); + if (!string.IsNullOrEmpty(content)) + { + url = $"/{content}{url}"; + } + + if (context.Request.Path == url) + { + returnString = $"
  • {title} {extraHtml}
  • "; + } + else + { + returnString = $"
  • {title} {extraHtml}
  • "; + } + return helper.Raw(returnString); } diff --git a/PlexRequests.UI/Modules/IssuesModule.cs b/PlexRequests.UI/Modules/IssuesModule.cs new file mode 100644 index 000000000..7b81494c0 --- /dev/null +++ b/PlexRequests.UI/Modules/IssuesModule.cs @@ -0,0 +1,51 @@ +using System.Linq; +using System.Threading.Tasks; + +using Nancy; +using Nancy.Responses.Negotiation; + +using PlexRequests.Core; +using PlexRequests.Core.SettingModels; + +namespace PlexRequests.UI.Modules +{ + public class IssuesModule : BaseAuthModule + { + public IssuesModule(ISettingsService pr, IIssueService issueService) : base("issues", pr) + { + IssuesService = issueService; + + Get["/"] = x => Index(); + + Get["/issuecount", true] = async (x, ct) => await IssueCount(); + + Get["/details/{id}", true] = async (x, ct) => await Details(x.id); + } + + private IIssueService IssuesService { get; } + + public Negotiator Index() + { + return View["Index"]; + } + + public async Task IssueCount() + { + var issues = await IssuesService.GetAllAsync(); + var count = issues.Count(x => x.Deleted == false); + + return Response.AsJson(count); + } + + public async Task Details(int id) + { + var issue = await IssuesService.GetAsync(id); + + return issue == null + ? Index() + : View["Details", issue]; + } + + + } +} diff --git a/PlexRequests.UI/PlexRequests.UI.csproj b/PlexRequests.UI/PlexRequests.UI.csproj index 2e226b54f..5e0f356b2 100644 --- a/PlexRequests.UI/PlexRequests.UI.csproj +++ b/PlexRequests.UI/PlexRequests.UI.csproj @@ -190,6 +190,7 @@ + diff --git a/PlexRequests.UI/Views/Shared/_Layout.cshtml b/PlexRequests.UI/Views/Shared/_Layout.cshtml index 78b66cd9f..09b0f7156 100644 --- a/PlexRequests.UI/Views/Shared/_Layout.cshtml +++ b/PlexRequests.UI/Views/Shared/_Layout.cshtml @@ -39,6 +39,8 @@