mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 21:03:17 -07:00
commit
f4e75f20ac
64 changed files with 1812 additions and 8322 deletions
|
@ -26,6 +26,8 @@
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
|
|
||||||
namespace PlexRequests.Core
|
namespace PlexRequests.Core
|
||||||
|
@ -33,13 +35,21 @@ namespace PlexRequests.Core
|
||||||
public interface IRequestService
|
public interface IRequestService
|
||||||
{
|
{
|
||||||
long AddRequest(RequestedModel model);
|
long AddRequest(RequestedModel model);
|
||||||
|
Task<int> AddRequestAsync(RequestedModel model);
|
||||||
RequestedModel CheckRequest(int providerId);
|
RequestedModel CheckRequest(int providerId);
|
||||||
|
Task<RequestedModel> CheckRequestAsync(int providerId);
|
||||||
RequestedModel CheckRequest(string musicId);
|
RequestedModel CheckRequest(string musicId);
|
||||||
|
Task<RequestedModel> CheckRequestAsync(string musicId);
|
||||||
|
|
||||||
void DeleteRequest(RequestedModel request);
|
void DeleteRequest(RequestedModel request);
|
||||||
|
Task DeleteRequestAsync(RequestedModel request);
|
||||||
bool UpdateRequest(RequestedModel model);
|
bool UpdateRequest(RequestedModel model);
|
||||||
|
Task<bool> UpdateRequestAsync(RequestedModel model);
|
||||||
RequestedModel Get(int id);
|
RequestedModel Get(int id);
|
||||||
|
Task<RequestedModel> GetAsync(int id);
|
||||||
IEnumerable<RequestedModel> GetAll();
|
IEnumerable<RequestedModel> GetAll();
|
||||||
|
Task<IEnumerable<RequestedModel>> GetAllAsync();
|
||||||
bool BatchUpdate(List<RequestedModel> model);
|
bool BatchUpdate(List<RequestedModel> model);
|
||||||
|
bool BatchDelete(List<RequestedModel> model);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,12 +24,18 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PlexRequests.Core
|
namespace PlexRequests.Core
|
||||||
{
|
{
|
||||||
public interface ISettingsService<T>
|
public interface ISettingsService<T>
|
||||||
{
|
{
|
||||||
T GetSettings();
|
T GetSettings();
|
||||||
|
Task<T> GetSettingsAsync();
|
||||||
bool SaveSettings(T model);
|
bool SaveSettings(T model);
|
||||||
|
Task<bool> SaveSettingsAsync(T model);
|
||||||
bool Delete(T model);
|
bool Delete(T model);
|
||||||
|
Task<bool> DeleteAsync(T model);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,6 +27,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
@ -57,6 +58,19 @@ namespace PlexRequests.Core
|
||||||
return result ? id : -1;
|
return result ? id : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> 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)
|
public RequestedModel CheckRequest(int providerId)
|
||||||
{
|
{
|
||||||
var blobs = Repo.GetAll();
|
var blobs = Repo.GetAll();
|
||||||
|
@ -64,6 +78,13 @@ namespace PlexRequests.Core
|
||||||
return blob != null ? ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content) : null;
|
return blob != null ? ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<RequestedModel> CheckRequestAsync(int providerId)
|
||||||
|
{
|
||||||
|
var blobs = await Repo.GetAllAsync();
|
||||||
|
var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId);
|
||||||
|
return blob != null ? ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public RequestedModel CheckRequest(string musicId)
|
public RequestedModel CheckRequest(string musicId)
|
||||||
{
|
{
|
||||||
var blobs = Repo.GetAll();
|
var blobs = Repo.GetAll();
|
||||||
|
@ -71,18 +92,37 @@ namespace PlexRequests.Core
|
||||||
return blob != null ? ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content) : null;
|
return blob != null ? ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<RequestedModel> CheckRequestAsync(string musicId)
|
||||||
|
{
|
||||||
|
var blobs = await Repo.GetAllAsync();
|
||||||
|
var blob = blobs.FirstOrDefault(x => x.MusicId == musicId);
|
||||||
|
return blob != null ? ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public void DeleteRequest(RequestedModel request)
|
public void DeleteRequest(RequestedModel request)
|
||||||
{
|
{
|
||||||
var blob = Repo.Get(request.Id);
|
var blob = Repo.Get(request.Id);
|
||||||
Repo.Delete(blob);
|
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)
|
public bool UpdateRequest(RequestedModel model)
|
||||||
{
|
{
|
||||||
var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id };
|
var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id };
|
||||||
return Repo.Update(entity);
|
return Repo.Update(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> 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)
|
public RequestedModel Get(int id)
|
||||||
{
|
{
|
||||||
var blob = Repo.Get(id);
|
var blob = Repo.Get(id);
|
||||||
|
@ -94,6 +134,17 @@ namespace PlexRequests.Core
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<RequestedModel> GetAsync(int id)
|
||||||
|
{
|
||||||
|
var blob = await Repo.GetAsync(id);
|
||||||
|
if (blob == null)
|
||||||
|
{
|
||||||
|
return new RequestedModel();
|
||||||
|
}
|
||||||
|
var model = ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<RequestedModel> GetAll()
|
public IEnumerable<RequestedModel> GetAll()
|
||||||
{
|
{
|
||||||
var blobs = Repo.GetAll();
|
var blobs = Repo.GetAll();
|
||||||
|
@ -102,10 +153,24 @@ namespace PlexRequests.Core
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<RequestedModel>> GetAllAsync()
|
||||||
|
{
|
||||||
|
var blobs = await Repo.GetAllAsync();
|
||||||
|
return blobs.Select(b => Encoding.UTF8.GetString(b.Content))
|
||||||
|
.Select(JsonConvert.DeserializeObject<RequestedModel>)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public bool BatchUpdate(List<RequestedModel> model)
|
public bool BatchUpdate(List<RequestedModel> model)
|
||||||
{
|
{
|
||||||
var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList();
|
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);
|
return Repo.UpdateAll(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool BatchDelete(List<RequestedModel> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,6 +24,8 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
|
@ -62,6 +64,21 @@ namespace PlexRequests.Core
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<T> GetSettingsAsync()
|
||||||
|
{
|
||||||
|
var result = await Repo.GetAsync(EntityName);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
result.Content = DecryptSettings(result);
|
||||||
|
var obj = string.IsNullOrEmpty(result.Content) ? null : JsonConvert.DeserializeObject<T>(result.Content, SerializerSettings.Settings);
|
||||||
|
|
||||||
|
var model = obj;
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
public bool SaveSettings(T model)
|
public bool SaveSettings(T model)
|
||||||
{
|
{
|
||||||
var entity = Repo.Get(EntityName);
|
var entity = Repo.Get(EntityName);
|
||||||
|
@ -88,6 +105,31 @@ namespace PlexRequests.Core
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> SaveSettingsAsync(T model)
|
||||||
|
{
|
||||||
|
var entity = await Repo.GetAsync(EntityName);
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
var newEntity = model;
|
||||||
|
|
||||||
|
var settings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(newEntity, SerializerSettings.Settings) };
|
||||||
|
settings.Content = EncryptSettings(settings);
|
||||||
|
var insertResult = await Repo.InsertAsync(settings);
|
||||||
|
|
||||||
|
return insertResult != int.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var modified = model;
|
||||||
|
modified.Id = entity.Id;
|
||||||
|
|
||||||
|
var globalSettings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(modified, SerializerSettings.Settings), Id = entity.Id };
|
||||||
|
globalSettings.Content = EncryptSettings(globalSettings);
|
||||||
|
var result = await Repo.UpdateAsync(globalSettings);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Delete(T model)
|
public bool Delete(T model)
|
||||||
{
|
{
|
||||||
var entity = Repo.Get(EntityName);
|
var entity = Repo.Get(EntityName);
|
||||||
|
@ -100,6 +142,17 @@ namespace PlexRequests.Core
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteAsync(T model)
|
||||||
|
{
|
||||||
|
var entity = Repo.Get(EntityName);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
return await Repo.DeleteAsync(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private string EncryptSettings(GlobalSettings settings)
|
private string EncryptSettings(GlobalSettings settings)
|
||||||
{
|
{
|
||||||
return StringCipher.Encrypt(settings.Content, settings.SettingsName);
|
return StringCipher.Encrypt(settings.Content, settings.SettingsName);
|
||||||
|
|
|
@ -61,6 +61,10 @@ namespace PlexRequests.Core
|
||||||
{
|
{
|
||||||
MigrateToVersion1700();
|
MigrateToVersion1700();
|
||||||
}
|
}
|
||||||
|
if (version > 1800 && version <= 1899)
|
||||||
|
{
|
||||||
|
MigrateToVersion1800();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Db.DbConnection().ConnectionString;
|
return Db.DbConnection().ConnectionString;
|
||||||
|
@ -73,7 +77,7 @@ namespace PlexRequests.Core
|
||||||
{
|
{
|
||||||
var productVersion = AssemblyHelper.GetProductVersion();
|
var productVersion = AssemblyHelper.GetProductVersion();
|
||||||
var trimStatus = new Regex("[^0-9]", RegexOptions.Compiled).Replace(productVersion, string.Empty).PadRight(4, '0');
|
var trimStatus = new Regex("[^0-9]", RegexOptions.Compiled).Replace(productVersion, string.Empty).PadRight(4, '0');
|
||||||
var version = int.Parse(trimStatus);
|
var version = int.Parse(trimStatus);
|
||||||
|
|
||||||
var connection = Db.DbConnection();
|
var connection = Db.DbConnection();
|
||||||
var schema = connection.GetSchemaVersion();
|
var schema = connection.GetSchemaVersion();
|
||||||
|
@ -173,5 +177,50 @@ namespace PlexRequests.Core
|
||||||
TableCreation.DropTable(Db.DbConnection(), "User");
|
TableCreation.DropTable(Db.DbConnection(), "User");
|
||||||
TableCreation.DropTable(Db.DbConnection(), "Log");
|
TableCreation.DropTable(Db.DbConnection(), "Log");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Migrates to version 1.8.
|
||||||
|
/// <para>This includes updating the admin account to have all roles.</para>
|
||||||
|
/// <para>Set the log level to info</para>
|
||||||
|
/// </summary>
|
||||||
|
private void MigrateToVersion1800()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userMapper = new UserMapper(new UserRepository<UsersModel>(Db, new MemoryCacheProvider()));
|
||||||
|
var users = userMapper.GetUsers();
|
||||||
|
|
||||||
|
foreach (var u in users)
|
||||||
|
{
|
||||||
|
var claims = new[] { UserClaims.User, UserClaims.Admin, UserClaims.PowerUser };
|
||||||
|
u.Claims = ByteConverterHelper.ReturnBytes(claims);
|
||||||
|
|
||||||
|
userMapper.EditUser(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settingsService = new SettingsServiceV2<LogSettings>(new SettingsJsonRepository(Db, new MemoryCacheProvider()));
|
||||||
|
var logSettings = settingsService.GetSettings();
|
||||||
|
logSettings.Level = LogLevel.Info.Ordinal;
|
||||||
|
settingsService.SaveSettings(logSettings);
|
||||||
|
|
||||||
|
LoggingHelper.ReconfigureLogLevel(LogLevel.FromOrdinal(logSettings.Level));
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,16 @@ namespace PlexRequests.Core
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UsersModel EditUser(UsersModel user)
|
||||||
|
{
|
||||||
|
var existingUser = Repo.Get(user.UserGuid);
|
||||||
|
|
||||||
|
user.Id = existingUser.Id;
|
||||||
|
user.UserGuid = existingUser.UserGuid;
|
||||||
|
Repo.Update(user);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
public bool DoUsersExist()
|
public bool DoUsersExist()
|
||||||
{
|
{
|
||||||
var users = Repo.GetAll();
|
var users = Repo.GetAll();
|
||||||
|
@ -88,7 +98,7 @@ namespace PlexRequests.Core
|
||||||
return users.Any();
|
return users.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid? CreateUser(string username, string password, string[] claims = default(string[]))
|
private Guid? CreateUser(string username, string password, string[] claims = default(string[]))
|
||||||
{
|
{
|
||||||
var salt = PasswordHasher.GenerateSalt();
|
var salt = PasswordHasher.GenerateSalt();
|
||||||
|
|
||||||
|
@ -108,6 +118,21 @@ namespace PlexRequests.Core
|
||||||
return new Guid(userRecord.UserGuid);
|
return new Guid(userRecord.UserGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Guid? CreateAdmin(string username, string password)
|
||||||
|
{
|
||||||
|
return CreateUser(username, password, new[] { UserClaims.User, UserClaims.PowerUser, UserClaims.Admin });
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid? CreatePowerUser(string username, string password)
|
||||||
|
{
|
||||||
|
return CreateUser(username, password, new[] { UserClaims.User, UserClaims.PowerUser });
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid? CreateRegularUser(string username, string password)
|
||||||
|
{
|
||||||
|
return CreateUser(username, password, new[] { UserClaims.User });
|
||||||
|
}
|
||||||
|
|
||||||
public bool UpdatePassword(string username, string oldPassword, string newPassword)
|
public bool UpdatePassword(string username, string oldPassword, string newPassword)
|
||||||
{
|
{
|
||||||
var users = Repo.GetAll();
|
var users = Repo.GetAll();
|
||||||
|
@ -134,15 +159,25 @@ namespace PlexRequests.Core
|
||||||
{
|
{
|
||||||
return Repo.GetAll();
|
return Repo.GetAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UsersModel GetUser(Guid userId)
|
||||||
|
{
|
||||||
|
var user = Repo.Get(userId.ToString());
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ICustomUserMapper
|
public interface ICustomUserMapper
|
||||||
{
|
{
|
||||||
IEnumerable<UsersModel> GetUsers();
|
IEnumerable<UsersModel> GetUsers();
|
||||||
Guid? CreateUser(string username, string password, string[] claims = default(string[]));
|
UsersModel GetUser(Guid userId);
|
||||||
|
UsersModel EditUser(UsersModel user);
|
||||||
bool DoUsersExist();
|
bool DoUsersExist();
|
||||||
Guid? ValidateUser(string username, string password);
|
Guid? ValidateUser(string username, string password);
|
||||||
bool UpdatePassword(string username, string oldPassword, string newPassword);
|
bool UpdatePassword(string username, string oldPassword, string newPassword);
|
||||||
|
Guid? CreateAdmin(string username, string password);
|
||||||
|
Guid? CreatePowerUser(string username, string password);
|
||||||
|
Guid? CreateRegularUser(string username, string password);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Helpers.Tests</RootNamespace>
|
<RootNamespace>PlexRequests.Helpers.Tests</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Helpers.Tests</AssemblyName>
|
<AssemblyName>PlexRequests.Helpers.Tests</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||||
<IsCodedUITest>False</IsCodedUITest>
|
<IsCodedUITest>False</IsCodedUITest>
|
||||||
<TestProjectType>UnitTest</TestProjectType>
|
<TestProjectType>UnitTest</TestProjectType>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq.Expressions;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace PlexRequests.Helpers.Tests
|
namespace PlexRequests.Helpers.Tests
|
||||||
|
@ -35,11 +36,9 @@ namespace PlexRequests.Helpers.Tests
|
||||||
public class UriHelperTests
|
public class UriHelperTests
|
||||||
{
|
{
|
||||||
[TestCaseSource(nameof(UriData))]
|
[TestCaseSource(nameof(UriData))]
|
||||||
public void CreateUri1(string uri, Uri expected)
|
public Uri CreateUri1(string uri)
|
||||||
{
|
{
|
||||||
var result = uri.ReturnUri();
|
return uri.ReturnUri();
|
||||||
|
|
||||||
Assert.That(result, Is.EqualTo(expected));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -52,54 +51,58 @@ namespace PlexRequests.Helpers.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCaseSource(nameof(UriDataWithPort))]
|
[TestCaseSource(nameof(UriDataWithPort))]
|
||||||
public void CreateUri2(string uri, int port, Uri expected)
|
public Uri CreateUri2(string uri, int port)
|
||||||
{
|
{
|
||||||
var result = uri.ReturnUri(port);
|
return uri.ReturnUri(port);
|
||||||
|
|
||||||
Assert.That(result, Is.EqualTo(expected));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCaseSource(nameof(UriDataWithSubDir))]
|
[TestCaseSource(nameof(UriDataWithSubDir))]
|
||||||
public void CreateUriWithSubDir(string uri, int port, bool ssl, string subDir, Uri expected)
|
public Uri CreateUriWithSubDir(string uri, int port, bool ssl, string subDir)
|
||||||
{
|
{
|
||||||
var result = uri.ReturnUriWithSubDir(port, ssl, subDir);
|
return uri.ReturnUriWithSubDir(port, ssl, subDir);
|
||||||
|
|
||||||
Assert.That(result, Is.EqualTo(expected));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly object[] UriData =
|
private static IEnumerable<TestCaseData> UriData
|
||||||
{
|
{
|
||||||
new object[] { "google.com", new Uri("http://google.com/"), },
|
get
|
||||||
new object[] { "http://google.com", new Uri("http://google.com/"), },
|
{
|
||||||
new object[] { "https://google.com", new Uri("https://google.com/"), },
|
yield return new TestCaseData("google.com").Returns(new Uri("http://google.com/"));
|
||||||
new object[] { "192.168.1.1", new Uri("http://192.168.1.1")},
|
yield return new TestCaseData("http://google.com").Returns(new Uri("http://google.com/"));
|
||||||
new object[] { "0.0.0.0:5533", new Uri("http://0.0.0.0:5533")},
|
yield return new TestCaseData("https://google.com").Returns(new Uri("https://google.com/"));
|
||||||
new object[] {"www.google.com", new Uri("http://www.google.com/")},
|
yield return new TestCaseData("192.168.1.1").Returns(new Uri("http://192.168.1.1"));
|
||||||
new object[] {"http://www.google.com/", new Uri("http://www.google.com/") },
|
yield return new TestCaseData("0.0.0.0:5533").Returns(new Uri("http://0.0.0.0:5533"));
|
||||||
new object[] {"https://www.google.com", new Uri("https://www.google.com/") },
|
yield return new TestCaseData("www.google.com").Returns(new Uri("http://www.google.com/"));
|
||||||
new object[] {"www.google.com:443", new Uri("http://www.google.com:443/") },
|
yield return new TestCaseData("http://www.google.com/").Returns(new Uri("http://www.google.com/"));
|
||||||
new object[] {"https://www.google.com:443", new Uri("https://www.google.com:443/") },
|
yield return new TestCaseData("https://www.google.com").Returns(new Uri("https://www.google.com/"));
|
||||||
new object[] {"http://www.google.com:443/id=2", new Uri("http://www.google.com:443/id=2") },
|
yield return new TestCaseData("www.google.com:443").Returns(new Uri("http://www.google.com:443/"));
|
||||||
new object[] {"www.google.com:4438/id=22", new Uri("http://www.google.com:4438/id=22") }
|
yield return new TestCaseData("https://www.google.com:443").Returns(new Uri("https://www.google.com/"));
|
||||||
};
|
yield return new TestCaseData("http://www.google.com:443/id=2").Returns(new Uri("http://www.google.com:443/id=2"));
|
||||||
|
yield return new TestCaseData("www.google.com:4438/id=22").Returns(new Uri("http://www.google.com:4438/id=22"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static readonly object[] UriDataWithPort =
|
private static IEnumerable<TestCaseData> UriDataWithPort
|
||||||
{
|
{
|
||||||
new object[] {"www.google.com", 80, new Uri("http://www.google.com:80/"), },
|
get
|
||||||
new object[] {"www.google.com", 443, new Uri("http://www.google.com:443/") },
|
{
|
||||||
new object[] {"http://www.google.com", 443, new Uri("http://www.google.com:443/") },
|
yield return new TestCaseData("www.google.com", 80).Returns(new Uri("http://www.google.com:80/"));
|
||||||
new object[] {"https://www.google.com", 443, new Uri("https://www.google.com:443/") },
|
yield return new TestCaseData("www.google.com", 443).Returns(new Uri("http://www.google.com:443/"));
|
||||||
new object[] {"http://www.google.com/id=2", 443, new Uri("http://www.google.com:443/id=2") },
|
yield return new TestCaseData("http://www.google.com", 443).Returns(new Uri("http://www.google.com:443/"));
|
||||||
new object[] {"http://www.google.com/id=2", 443, new Uri("http://www.google.com:443/id=2") },
|
yield return new TestCaseData("https://www.google.com", 443).Returns(new Uri("https://www.google.com:443/"));
|
||||||
new object[] {"https://www.google.com/id=2", 443, new Uri("https://www.google.com:443/id=2") },
|
yield return new TestCaseData("http://www.google.com/id=2", 443).Returns(new Uri("http://www.google.com:443/id=2"));
|
||||||
};
|
yield return new TestCaseData("https://www.google.com/id=2", 443).Returns(new Uri("https://www.google.com:443/id=2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static readonly object[] UriDataWithSubDir =
|
private static IEnumerable<TestCaseData> UriDataWithSubDir
|
||||||
{
|
{
|
||||||
new object[] {"www.google.com", 80, false,"test", new Uri("http://www.google.com:80/test"), },
|
get
|
||||||
new object[] {"www.google.com", 443, false,"test", new Uri("http://www.google.com:443/test") },
|
{
|
||||||
new object[] {"http://www.google.com", 443, true,"test", new Uri("https://www.google.com:443/test") },
|
yield return new TestCaseData("www.google.com", 80, false, "test").Returns(new Uri("http://www.google.com:80/test"));
|
||||||
new object[] {"https://www.google.com", 443,true,"test", new Uri("https://www.google.com:443/test") },
|
yield return new TestCaseData("www.google.com", 443, false, "test").Returns(new Uri("http://www.google.com:443/test"));
|
||||||
};
|
yield return new TestCaseData("http://www.google.com", 443, true, "test").Returns(new Uri("https://www.google.com:443/test"));
|
||||||
|
yield return new TestCaseData("https://www.google.com", 443, true, "test").Returns(new Uri("https://www.google.com:443/test"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0"/>
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0"/>
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
</configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PlexRequests.Helpers
|
namespace PlexRequests.Helpers
|
||||||
{
|
{
|
||||||
|
@ -40,6 +41,7 @@ namespace PlexRequests.Helpers
|
||||||
/// <param name="cacheTime">The amount of time we want to cache the object</param>
|
/// <param name="cacheTime">The amount of time we want to cache the object</param>
|
||||||
/// <returns><see cref="T"/></returns>
|
/// <returns><see cref="T"/></returns>
|
||||||
T GetOrSet<T>(string key, Func<T> itemCallback, int cacheTime = 20) where T : class;
|
T GetOrSet<T>(string key, Func<T> itemCallback, int cacheTime = 20) where T : class;
|
||||||
|
Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> itemCallback, int cacheTime = 20) where T : class;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the specified item from the cache.
|
/// Gets the specified item from the cache.
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Caching;
|
using System.Runtime.Caching;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PlexRequests.Helpers
|
namespace PlexRequests.Helpers
|
||||||
{
|
{
|
||||||
|
@ -65,6 +66,23 @@ namespace PlexRequests.Helpers
|
||||||
return item.CloneJson();
|
return item.CloneJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> itemCallback, int cacheTime = 20) where T : class
|
||||||
|
{
|
||||||
|
var item = Get<T>(key);
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
item = await itemCallback();
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
Set(key, item, cacheTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a copy, not the stored cache reference
|
||||||
|
// The cached object will not change
|
||||||
|
return item.CloneJson();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the specified item from the cache.
|
/// Gets the specified item from the cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace PlexRequests.Services.Jobs
|
||||||
public int[] QueuedIds()
|
public int[] QueuedIds()
|
||||||
{
|
{
|
||||||
var movies = Cache.Get<CouchPotatoMovies>(CacheKeys.CouchPotatoQueued);
|
var movies = Cache.Get<CouchPotatoMovies>(CacheKeys.CouchPotatoQueued);
|
||||||
return movies?.movies.Select(x => x.info.tmdb_id).ToArray() ?? new int[] { };
|
return movies?.movies?.Select(x => x.info.tmdb_id).ToArray() ?? new int[] { };
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(IJobExecutionContext context)
|
public void Execute(IJobExecutionContext context)
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
namespace PlexRequests.Services
|
namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
public static class JobNames
|
public static class JobNames
|
||||||
{
|
{
|
||||||
|
@ -33,5 +33,6 @@ namespace PlexRequests.Services
|
||||||
public const string SonarrCacher = "Sonarr Cacher";
|
public const string SonarrCacher = "Sonarr Cacher";
|
||||||
public const string SrCacher = "SickRage Cacher";
|
public const string SrCacher = "SickRage Cacher";
|
||||||
public const string PlexChecker = "Plex Availability Cacher";
|
public const string PlexChecker = "Plex Availability Cacher";
|
||||||
|
public const string StoreCleanup = "Database Cleanup";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -326,33 +326,36 @@ namespace PlexRequests.Services.Jobs
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var plexUser = PlexApi.GetUsers(apiKey);
|
var plexUser = PlexApi.GetUsers(apiKey);
|
||||||
if (plexUser?.User == null || plexUser.User.Length == 0)
|
var userAccount = PlexApi.GetAccount(apiKey);
|
||||||
{
|
|
||||||
return;
|
var adminUsername = userAccount.Username ?? string.Empty;
|
||||||
}
|
|
||||||
|
|
||||||
var users = UserNotifyRepo.GetAll().ToList();
|
var users = UserNotifyRepo.GetAll().ToList();
|
||||||
|
Log.Debug("Notifying Users Count {0}", users.Count);
|
||||||
foreach (var model in modelChanged)
|
foreach (var model in modelChanged)
|
||||||
{
|
{
|
||||||
var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers);
|
var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers);
|
||||||
|
Log.Debug("Selected Users {0}", selectedUsers.DumpJson());
|
||||||
foreach (var user in selectedUsers)
|
foreach (var user in selectedUsers)
|
||||||
{
|
{
|
||||||
|
Log.Info("Notifying user {0}", user);
|
||||||
|
if (user == adminUsername)
|
||||||
|
{
|
||||||
|
Log.Info("This user is the Plex server owner");
|
||||||
|
PublishUserNotification(userAccount.Username, userAccount.Email, model.Title);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var email = plexUser.User.FirstOrDefault(x => x.Username == user);
|
var email = plexUser.User.FirstOrDefault(x => x.Username == user);
|
||||||
if (email == null)
|
if (email == null)
|
||||||
{
|
{
|
||||||
|
Log.Info("There is no email address for this Plex user, cannot send notification");
|
||||||
// We do not have a plex user that requested this!
|
// We do not have a plex user that requested this!
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var notificationModel = new NotificationModel
|
|
||||||
{
|
|
||||||
User = email.Username,
|
|
||||||
UserEmail = email.Email,
|
|
||||||
NotificationType = NotificationType.RequestAvailable,
|
|
||||||
Title = model.Title
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send the notification to the user.
|
Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Username, email.Email, model.Title);
|
||||||
Notification.Publish(notificationModel);
|
PublishUserNotification(email.Username, email.Email, model.Title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,6 +365,20 @@ namespace PlexRequests.Services.Jobs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PublishUserNotification(string username, string email, string title)
|
||||||
|
{
|
||||||
|
var notificationModel = new NotificationModel
|
||||||
|
{
|
||||||
|
User = username,
|
||||||
|
UserEmail = email,
|
||||||
|
NotificationType = NotificationType.RequestAvailable,
|
||||||
|
Title = title
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send the notification to the user.
|
||||||
|
Notification.Publish(notificationModel);
|
||||||
|
}
|
||||||
|
|
||||||
public void Execute(IJobExecutionContext context)
|
public void Execute(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
CheckAndUpdateAll();
|
CheckAndUpdateAll();
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace PlexRequests.Services.Jobs
|
||||||
public int[] QueuedIds()
|
public int[] QueuedIds()
|
||||||
{
|
{
|
||||||
var tv = Cache.Get<SickrageShows>(CacheKeys.SickRageQueued);
|
var tv = Cache.Get<SickrageShows>(CacheKeys.SickRageQueued);
|
||||||
return tv?.data.Values.Select(x => x.tvdbid).ToArray() ?? new int[] { };
|
return tv?.data?.Values.Select(x => x.tvdbid).ToArray() ?? new int[] { };
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(IJobExecutionContext context)
|
public void Execute(IJobExecutionContext context)
|
||||||
|
|
|
@ -26,15 +26,11 @@
|
||||||
#endregion
|
#endregion
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
using PlexRequests.Services.Interfaces;
|
using PlexRequests.Services.Interfaces;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
using PlexRequests.Store.Models;
|
|
||||||
using PlexRequests.Store.Repository;
|
|
||||||
|
|
||||||
using Quartz;
|
using Quartz;
|
||||||
|
|
||||||
|
@ -57,7 +53,7 @@ namespace PlexRequests.Services.Jobs
|
||||||
public void Execute(IJobExecutionContext context)
|
public void Execute(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
TakeBackup();
|
TakeBackup();
|
||||||
Cleanup ();
|
Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TakeBackup()
|
private void TakeBackup()
|
||||||
|
@ -81,11 +77,11 @@ namespace PlexRequests.Services.Jobs
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(DoWeNeedToBackup(backupDir.FullName))
|
if (DoWeNeedToBackup(backupDir.FullName))
|
||||||
{
|
{
|
||||||
File.Copy(dbPath, Path.Combine(backupDir.FullName, $"PlexRequests.sqlite_{DateTime.Now.ToString("yyyy-MM-dd hh.mm.ss")}.bak"));
|
File.Copy(dbPath, Path.Combine(backupDir.FullName, $"PlexRequests.sqlite_{DateTime.Now.ToString("yyyy-MM-dd hh.mm.ss")}.bak"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Warn(e);
|
Log.Warn(e);
|
||||||
|
@ -98,53 +94,58 @@ namespace PlexRequests.Services.Jobs
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Cleanup()
|
private void Cleanup()
|
||||||
{
|
{
|
||||||
Log.Trace("Starting DB Cleanup");
|
Log.Trace("Starting DB Cleanup");
|
||||||
var dbPath = Sql.CurrentPath;
|
var dbPath = Sql.CurrentPath;
|
||||||
var dir = Path.GetDirectoryName(dbPath);
|
var dir = Path.GetDirectoryName(dbPath);
|
||||||
if (dir == null)
|
if (dir == null)
|
||||||
{
|
{
|
||||||
Log.Warn("We couldn't find the DB path. We cannot backup.");
|
Log.Warn("We couldn't find the DB path. We cannot backup.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var backupDir = Directory.CreateDirectory(Path.Combine(dir, "Backup"));
|
var backupDir = Directory.CreateDirectory(Path.Combine(dir, "Backup"));
|
||||||
|
|
||||||
var files = backupDir.GetFiles();
|
var files = backupDir.GetFiles();
|
||||||
|
|
||||||
foreach (var file in files) {
|
foreach (var file in files)
|
||||||
var dt = ParseName(file.Name);
|
{
|
||||||
if(dt < DateTime.Now.AddDays(-7)){
|
var dt = ParseName(file.Name);
|
||||||
try {
|
if (dt < DateTime.Now.AddDays(-7))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
File.Delete(file.FullName);
|
File.Delete(file.FullName);
|
||||||
} catch (Exception ex) {
|
}
|
||||||
Log.Error(ex);
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
}
|
Log.Error(ex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DoWeNeedToBackup(string backupPath)
|
private bool DoWeNeedToBackup(string backupPath)
|
||||||
{
|
{
|
||||||
var files = Directory.GetFiles(backupPath);
|
var files = Directory.GetFiles(backupPath);
|
||||||
//TODO Get the latest file and if it's within an hour of DateTime.Now then don't bother backing up.
|
//TODO Get the latest file and if it's within an hour of DateTime.Now then don't bother backing up.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateTime ParseName(string fileName)
|
private DateTime ParseName(string fileName)
|
||||||
{
|
{
|
||||||
var names = fileName.Split(new []{'_','.',' '}, StringSplitOptions.RemoveEmptyEntries);
|
var names = fileName.Split(new[] { '_', '.', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
if(names.Count() > 1)
|
if (names.Length > 1)
|
||||||
{
|
{
|
||||||
DateTime parsed;
|
DateTime parsed;
|
||||||
//DateTime.TryParseExcat(names[1], "yyyy-MM-dd hh.mm.ss",CultureInfo.CurrentUICulture, DateTimeStyles.None, out parsed);
|
//DateTime.TryParseExcat(names[1], "yyyy-MM-dd hh.mm.ss",CultureInfo.CurrentUICulture, DateTimeStyles.None, out parsed);
|
||||||
DateTime.TryParse(names[2], out parsed);
|
DateTime.TryParse(names[2], out parsed);
|
||||||
return parsed;
|
return parsed;
|
||||||
|
|
||||||
}
|
}
|
||||||
return DateTime.MinValue;
|
return DateTime.MinValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
82
PlexRequests.Services/Jobs/StoreCleanup.cs
Normal file
82
PlexRequests.Services/Jobs/StoreCleanup.cs
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: StoreCleanup.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.Linq;
|
||||||
|
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
using PlexRequests.Services.Interfaces;
|
||||||
|
using PlexRequests.Store.Models;
|
||||||
|
using PlexRequests.Store.Repository;
|
||||||
|
|
||||||
|
using Quartz;
|
||||||
|
|
||||||
|
namespace PlexRequests.Services.Jobs
|
||||||
|
{
|
||||||
|
public class StoreCleanup : IJob
|
||||||
|
{
|
||||||
|
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public StoreCleanup(IRepository<LogEntity> repo, IJobRecord rec)
|
||||||
|
{
|
||||||
|
Repo = repo;
|
||||||
|
JobRecord = rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IJobRecord JobRecord { get; }
|
||||||
|
|
||||||
|
private IRepository<LogEntity> Repo { get; }
|
||||||
|
|
||||||
|
private void Cleanup()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var items = Repo.GetAll();
|
||||||
|
var orderedItems = items.Where(x => x.Date < DateTime.Now.AddDays(-7));
|
||||||
|
|
||||||
|
foreach (var o in orderedItems)
|
||||||
|
{
|
||||||
|
Repo.Delete(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
JobRecord.Record(JobNames.StoreCleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(IJobExecutionContext context)
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,7 +62,10 @@ namespace PlexRequests.Services.Notification
|
||||||
|
|
||||||
var emailSettings = (EmailNotificationSettings)settings;
|
var emailSettings = (EmailNotificationSettings)settings;
|
||||||
|
|
||||||
if (!ValidateConfiguration(emailSettings)) return;
|
if (!ValidateConfiguration(emailSettings))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (model.NotificationType)
|
switch (model.NotificationType)
|
||||||
{
|
{
|
||||||
|
@ -96,15 +99,19 @@ namespace PlexRequests.Services.Notification
|
||||||
|
|
||||||
private bool ValidateConfiguration(EmailNotificationSettings settings)
|
private bool ValidateConfiguration(EmailNotificationSettings settings)
|
||||||
{
|
{
|
||||||
if (!settings.Enabled)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString()))
|
if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!settings.EnableUserEmailNotifications)
|
||||||
|
{
|
||||||
|
if (!settings.Enabled)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace PlexRequests.Services.Notification
|
||||||
Observers.TryRemove(notification.NotificationName, out notification);
|
Observers.TryRemove(notification.NotificationName, out notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task NotifyAsync(INotification notification, NotificationModel model)
|
private async Task NotifyAsync(INotification notification, NotificationModel model)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -89,7 +89,7 @@ namespace PlexRequests.Services.Notification
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task NotifyAsync(INotification notification, NotificationModel model, Settings settings)
|
private async Task NotifyAsync(INotification notification, NotificationModel model, Settings settings)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
<Compile Include="Jobs\JobRecord.cs" />
|
<Compile Include="Jobs\JobRecord.cs" />
|
||||||
<Compile Include="Jobs\JobNames.cs" />
|
<Compile Include="Jobs\JobNames.cs" />
|
||||||
<Compile Include="Jobs\StoreBackup.cs" />
|
<Compile Include="Jobs\StoreBackup.cs" />
|
||||||
|
<Compile Include="Jobs\StoreCleanup.cs" />
|
||||||
<Compile Include="Jobs\CouchPotatoCacher.cs" />
|
<Compile Include="Jobs\CouchPotatoCacher.cs" />
|
||||||
<Compile Include="Jobs\PlexAvailabilityChecker.cs" />
|
<Compile Include="Jobs\PlexAvailabilityChecker.cs" />
|
||||||
<Compile Include="Jobs\SickRageCacher.cs" />
|
<Compile Include="Jobs\SickRageCacher.cs" />
|
||||||
|
|
|
@ -31,11 +31,20 @@
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="Dapper, Version=1.50.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Dapper.1.50.0-beta8\lib\net45\Dapper.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Dapper.Contrib, Version=1.50.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Dapper.Contrib.1.50.0-beta8\lib\net45\Dapper.Contrib.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Mono.Data.Sqlite">
|
<Reference Include="Mono.Data.Sqlite">
|
||||||
<HintPath>..\Assemblies\Mono.Data.Sqlite.dll</HintPath>
|
<HintPath>..\Assemblies\Mono.Data.Sqlite.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Data.Linq" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
@ -43,12 +52,6 @@
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="Dapper, Version=1.40.0.0, Culture=neutral, PublicKeyToken=null">
|
|
||||||
<HintPath>..\packages\Dapper.1.42\lib\net45\Dapper.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Dapper.Contrib, Version=1.40.0.0, Culture=neutral, PublicKeyToken=null">
|
|
||||||
<HintPath>..\packages\Dapper.Contrib.1.43\lib\net45\Dapper.Contrib.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
|
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
|
||||||
<HintPath>..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
@ -61,6 +64,7 @@
|
||||||
<Compile Include="Entity.cs" />
|
<Compile Include="Entity.cs" />
|
||||||
<Compile Include="Models\ScheduledJobs.cs" />
|
<Compile Include="Models\ScheduledJobs.cs" />
|
||||||
<Compile Include="Models\UsersToNotify.cs" />
|
<Compile Include="Models\UsersToNotify.cs" />
|
||||||
|
<Compile Include="Repository\BaseGenericRepository.cs" />
|
||||||
<Compile Include="Repository\IRequestRepository.cs" />
|
<Compile Include="Repository\IRequestRepository.cs" />
|
||||||
<Compile Include="Repository\ISettingsRepository.cs" />
|
<Compile Include="Repository\ISettingsRepository.cs" />
|
||||||
<Compile Include="ISqliteConfiguration.cs" />
|
<Compile Include="ISqliteConfiguration.cs" />
|
||||||
|
|
179
PlexRequests.Store/Repository/BaseGenericRepository.cs
Normal file
179
PlexRequests.Store/Repository/BaseGenericRepository.cs
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: BaseGenericRepository.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.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Dapper.Contrib.Extensions;
|
||||||
|
using NLog;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
|
namespace PlexRequests.Store.Repository
|
||||||
|
{
|
||||||
|
public abstract class BaseGenericRepository<T> where T : class
|
||||||
|
{
|
||||||
|
protected BaseGenericRepository(ISqliteConfiguration config, ICacheProvider cache)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
Cache = cache;
|
||||||
|
}
|
||||||
|
protected ICacheProvider Cache { get; }
|
||||||
|
protected ISqliteConfiguration Config { get; }
|
||||||
|
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
public abstract T Get(string id);
|
||||||
|
public abstract Task<T> GetAsync(int id);
|
||||||
|
public abstract T Get(int id);
|
||||||
|
public abstract Task<T> GetAsync(string id);
|
||||||
|
|
||||||
|
public long Insert(T entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var cnn = Config.DbConnection())
|
||||||
|
{
|
||||||
|
cnn.Open();
|
||||||
|
return cnn.Insert(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Delete(T entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
db.Delete(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync(T entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
await db.DeleteAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Update(T entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
Log.Trace("Updating entity");
|
||||||
|
Log.Trace(entity.DumpJson());
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
return db.Update(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAsync(T entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
Log.Trace("Updating entity");
|
||||||
|
Log.Trace(entity.DumpJson());
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
return await db.UpdateAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UpdateAll(IEnumerable<T> entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
Log.Trace("Updating all entities");
|
||||||
|
var result = new HashSet<bool>();
|
||||||
|
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
foreach (var e in entity)
|
||||||
|
{
|
||||||
|
result.Add(db.Update(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.All(x => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAllAsync(IEnumerable<T> entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
Log.Trace("Updating all entities");
|
||||||
|
var result = new HashSet<bool>();
|
||||||
|
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
foreach (var e in entity)
|
||||||
|
{
|
||||||
|
result.Add(await db.UpdateAsync(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.All(x => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertAsync(T entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var cnn = Config.DbConnection())
|
||||||
|
{
|
||||||
|
cnn.Open();
|
||||||
|
return await cnn.InsertAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetCache()
|
||||||
|
{
|
||||||
|
Cache.Remove("Get");
|
||||||
|
Cache.Remove("GetAll");
|
||||||
|
}
|
||||||
|
public IEnumerable<T> GetAll()
|
||||||
|
{
|
||||||
|
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
var result = db.GetAll<T>();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public async Task<IEnumerable<T>> GetAllAsync()
|
||||||
|
{
|
||||||
|
|
||||||
|
using (var db = Config.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
var result = await db.GetAllAsync<T>();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
#region Copyright
|
#region Copyright
|
||||||
|
|
||||||
// /************************************************************************
|
// /************************************************************************
|
||||||
// Copyright (c) 2016 Jamie Rees
|
// Copyright (c) 2016 Jamie Rees
|
||||||
// File: GenericRepository.cs
|
// File: GenericRepository.cs
|
||||||
|
@ -23,59 +24,38 @@
|
||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Dapper.Contrib.Extensions;
|
using Dapper.Contrib.Extensions;
|
||||||
|
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
namespace PlexRequests.Store.Repository
|
namespace PlexRequests.Store.Repository
|
||||||
{
|
{
|
||||||
public class GenericRepository<T> : IRepository<T> where T : Entity
|
public class GenericRepository<T> : BaseGenericRepository<T>, IRepository<T> where T : Entity
|
||||||
{
|
{
|
||||||
private ICacheProvider Cache { get; }
|
|
||||||
public GenericRepository(ISqliteConfiguration config, ICacheProvider cache)
|
public GenericRepository(ISqliteConfiguration config, ICacheProvider cache) : base(config, cache)
|
||||||
{
|
{
|
||||||
Config = config;
|
|
||||||
Cache = cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
|
||||||
|
|
||||||
private ISqliteConfiguration Config { get; }
|
|
||||||
public long Insert(T entity)
|
|
||||||
{
|
|
||||||
ResetCache();
|
|
||||||
using (var cnn = Config.DbConnection())
|
|
||||||
{
|
|
||||||
cnn.Open();
|
|
||||||
return cnn.Insert(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<T> GetAll()
|
|
||||||
{
|
|
||||||
|
|
||||||
using (var db = Config.DbConnection())
|
|
||||||
{
|
|
||||||
db.Open();
|
|
||||||
var result = db.GetAll<T>();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get(string id)
|
public override T Get(string id)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("Get(string) is not supported. Use Get(int)");
|
throw new NotSupportedException("Get(string) is not supported. Use Get(int)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get(int id)
|
public override Task<T> GetAsync(string id)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("GetAsync(string) is not supported. Use GetAsync(int)");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override T Get(int id)
|
||||||
{
|
{
|
||||||
var key = "Get" + id;
|
var key = "Get" + id;
|
||||||
var item = Cache.GetOrSet(
|
var item = Cache.GetOrSet(
|
||||||
|
@ -91,49 +71,22 @@ namespace PlexRequests.Store.Repository
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(T entity)
|
public override async Task<T> GetAsync(int id)
|
||||||
{
|
{
|
||||||
ResetCache();
|
var key = "Get" + id;
|
||||||
using (var db = Config.DbConnection())
|
var item = await Cache.GetOrSetAsync(
|
||||||
{
|
key,
|
||||||
db.Open();
|
async () =>
|
||||||
db.Delete(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Update(T entity)
|
|
||||||
{
|
|
||||||
ResetCache();
|
|
||||||
Log.Trace("Updating entity");
|
|
||||||
Log.Trace(entity.DumpJson());
|
|
||||||
using (var db = Config.DbConnection())
|
|
||||||
{
|
|
||||||
db.Open();
|
|
||||||
return db.Update(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateAll(IEnumerable<T> entity)
|
|
||||||
{
|
|
||||||
ResetCache();
|
|
||||||
Log.Trace("Updating all entities");
|
|
||||||
var result = new HashSet<bool>();
|
|
||||||
|
|
||||||
using (var db = Config.DbConnection())
|
|
||||||
{
|
|
||||||
db.Open();
|
|
||||||
foreach (var e in entity)
|
|
||||||
{
|
{
|
||||||
result.Add(db.Update(e));
|
using (var db = Config.DbConnection())
|
||||||
}
|
{
|
||||||
}
|
db.Open();
|
||||||
return result.All(x => true);
|
return await db.GetAsync<T>(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetCache()
|
|
||||||
{
|
|
||||||
Cache.Remove("Get");
|
|
||||||
Cache.Remove("GetAll");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PlexRequests.Store.Repository
|
namespace PlexRequests.Store.Repository
|
||||||
{
|
{
|
||||||
|
@ -35,12 +36,15 @@ namespace PlexRequests.Store.Repository
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
long Insert(T entity);
|
long Insert(T entity);
|
||||||
|
Task<int> InsertAsync(T entity);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all.
|
/// Gets all.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<T> GetAll();
|
IEnumerable<T> GetAll();
|
||||||
|
Task<IEnumerable<T>> GetAllAsync();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the specified identifier.
|
/// Gets the specified identifier.
|
||||||
|
@ -48,12 +52,15 @@ namespace PlexRequests.Store.Repository
|
||||||
/// <param name="id">The identifier.</param>
|
/// <param name="id">The identifier.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
T Get(string id);
|
T Get(string id);
|
||||||
|
Task<T> GetAsync(string id);
|
||||||
T Get(int id);
|
T Get(int id);
|
||||||
|
Task<T> GetAsync(int id);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified entity.
|
/// Deletes the specified entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
void Delete(T entity);
|
void Delete(T entity);
|
||||||
|
Task DeleteAsync(T entity);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the specified entity.
|
/// Updates the specified entity.
|
||||||
|
@ -61,6 +68,7 @@ namespace PlexRequests.Store.Repository
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool Update(T entity);
|
bool Update(T entity);
|
||||||
|
Task<bool> UpdateAsync(T entity);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates all.
|
/// Updates all.
|
||||||
|
@ -68,5 +76,6 @@ namespace PlexRequests.Store.Repository
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool UpdateAll(IEnumerable<T> entity);
|
bool UpdateAll(IEnumerable<T> entity);
|
||||||
|
Task<bool> UpdateAllAsync(IEnumerable<T> entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using PlexRequests.Store.Models;
|
using PlexRequests.Store.Models;
|
||||||
|
|
||||||
|
@ -38,13 +39,18 @@ namespace PlexRequests.Store.Repository
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
long Insert(RequestBlobs entity);
|
long Insert(RequestBlobs entity);
|
||||||
|
|
||||||
|
Task<int> InsertAsync(RequestBlobs entity);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all.
|
/// Gets all.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<RequestBlobs> GetAll();
|
IEnumerable<RequestBlobs> GetAll();
|
||||||
|
|
||||||
|
Task<IEnumerable<RequestBlobs>> GetAllAsync();
|
||||||
|
|
||||||
RequestBlobs Get(int id);
|
RequestBlobs Get(int id);
|
||||||
|
Task<RequestBlobs> GetAsync(int id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified entity.
|
/// Deletes the specified entity.
|
||||||
|
@ -52,6 +58,10 @@ namespace PlexRequests.Store.Repository
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool Delete(RequestBlobs entity);
|
bool Delete(RequestBlobs entity);
|
||||||
|
Task<bool> DeleteAsync(RequestBlobs entity);
|
||||||
|
|
||||||
|
bool DeleteAll(IEnumerable<RequestBlobs> entity);
|
||||||
|
Task<bool> DeleteAllAsync(IEnumerable<RequestBlobs> entity);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the specified entity.
|
/// Updates the specified entity.
|
||||||
|
@ -59,7 +69,9 @@ namespace PlexRequests.Store.Repository
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool Update(RequestBlobs entity);
|
bool Update(RequestBlobs entity);
|
||||||
|
Task<bool> UpdateAsync(RequestBlobs entity);
|
||||||
|
|
||||||
bool UpdateAll(IEnumerable<RequestBlobs> entity);
|
bool UpdateAll(IEnumerable<RequestBlobs> entity);
|
||||||
|
Task<bool> UpdateAllAsync(IEnumerable<RequestBlobs> entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using PlexRequests.Store.Models;
|
using PlexRequests.Store.Models;
|
||||||
|
|
||||||
namespace PlexRequests.Store.Repository
|
namespace PlexRequests.Store.Repository
|
||||||
|
@ -37,12 +37,14 @@ namespace PlexRequests.Store.Repository
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
long Insert(GlobalSettings entity);
|
long Insert(GlobalSettings entity);
|
||||||
|
Task<int> InsertAsync(GlobalSettings entity);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all.
|
/// Gets all.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<GlobalSettings> GetAll();
|
IEnumerable<GlobalSettings> GetAll();
|
||||||
|
Task<IEnumerable<GlobalSettings>> GetAllAsync();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the specified identifier.
|
/// Gets the specified identifier.
|
||||||
|
@ -50,12 +52,14 @@ namespace PlexRequests.Store.Repository
|
||||||
/// <param name="settingsName">Name of the settings.</param>
|
/// <param name="settingsName">Name of the settings.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
GlobalSettings Get(string settingsName);
|
GlobalSettings Get(string settingsName);
|
||||||
|
Task<GlobalSettings> GetAsync(string settingsName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified entity.
|
/// Deletes the specified entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
Task<bool> DeleteAsync(GlobalSettings entity);
|
||||||
bool Delete(GlobalSettings entity);
|
bool Delete(GlobalSettings entity);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -63,6 +67,7 @@ namespace PlexRequests.Store.Repository
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The entity.</param>
|
/// <param name="entity">The entity.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
Task<bool> UpdateAsync(GlobalSettings entity);
|
||||||
bool Update(GlobalSettings entity);
|
bool Update(GlobalSettings entity);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#endregion
|
#endregion
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Dapper.Contrib.Extensions;
|
using Dapper.Contrib.Extensions;
|
||||||
|
|
||||||
|
@ -56,6 +57,16 @@ namespace PlexRequests.Store.Repository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertAsync(RequestBlobs entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
var id = await con.InsertAsync(entity);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<RequestBlobs> GetAll()
|
public IEnumerable<RequestBlobs> GetAll()
|
||||||
{
|
{
|
||||||
var key = "GetAll";
|
var key = "GetAll";
|
||||||
|
@ -70,6 +81,20 @@ namespace PlexRequests.Store.Repository
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<RequestBlobs>> GetAllAsync()
|
||||||
|
{
|
||||||
|
var key = "GetAll";
|
||||||
|
var item = await Cache.GetOrSetAsync(key, async() =>
|
||||||
|
{
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
var page = await con.GetAllAsync<RequestBlobs>();
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
}, 5);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
public RequestBlobs Get(int id)
|
public RequestBlobs Get(int id)
|
||||||
{
|
{
|
||||||
var key = "Get" + id;
|
var key = "Get" + id;
|
||||||
|
@ -84,6 +109,20 @@ namespace PlexRequests.Store.Repository
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<RequestBlobs> GetAsync(int id)
|
||||||
|
{
|
||||||
|
var key = "Get" + id;
|
||||||
|
var item = await Cache.GetOrSetAsync(key, async () =>
|
||||||
|
{
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
var page = await con.GetAsync<RequestBlobs>(id);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
}, 5);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Delete(RequestBlobs entity)
|
public bool Delete(RequestBlobs entity)
|
||||||
{
|
{
|
||||||
ResetCache();
|
ResetCache();
|
||||||
|
@ -93,6 +132,30 @@ namespace PlexRequests.Store.Repository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteAsync(RequestBlobs entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
return await con.DeleteAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteAllAsync(IEnumerable<RequestBlobs> entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
var result = new HashSet<bool>();
|
||||||
|
using (var db = Db.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
foreach (var e in entity)
|
||||||
|
{
|
||||||
|
result.Add(await db.DeleteAsync(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.All(x => true);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Update(RequestBlobs entity)
|
public bool Update(RequestBlobs entity)
|
||||||
{
|
{
|
||||||
ResetCache();
|
ResetCache();
|
||||||
|
@ -102,6 +165,15 @@ namespace PlexRequests.Store.Repository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAsync(RequestBlobs entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
return await con.UpdateAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ResetCache()
|
private void ResetCache()
|
||||||
{
|
{
|
||||||
Cache.Remove("Get");
|
Cache.Remove("Get");
|
||||||
|
@ -122,5 +194,35 @@ namespace PlexRequests.Store.Repository
|
||||||
}
|
}
|
||||||
return result.All(x => true);
|
return result.All(x => true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAllAsync(IEnumerable<RequestBlobs> entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
var result = new HashSet<bool>();
|
||||||
|
using (var db = Db.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
foreach (var e in entity)
|
||||||
|
{
|
||||||
|
result.Add(await db.UpdateAsync(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.All(x => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DeleteAll(IEnumerable<RequestBlobs> entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
var result = new HashSet<bool>();
|
||||||
|
using (var db = Db.DbConnection())
|
||||||
|
{
|
||||||
|
db.Open();
|
||||||
|
foreach (var e in entity)
|
||||||
|
{
|
||||||
|
result.Add(db.Delete(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.All(x => true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#endregion
|
#endregion
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Dapper.Contrib.Extensions;
|
using Dapper.Contrib.Extensions;
|
||||||
|
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
|
@ -57,6 +57,15 @@ namespace PlexRequests.Store.Repository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertAsync(GlobalSettings entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
return await con.InsertAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<GlobalSettings> GetAll()
|
public IEnumerable<GlobalSettings> GetAll()
|
||||||
{
|
{
|
||||||
var key = TypeName + "GetAll";
|
var key = TypeName + "GetAll";
|
||||||
|
@ -71,6 +80,20 @@ namespace PlexRequests.Store.Repository
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<GlobalSettings>> GetAllAsync()
|
||||||
|
{
|
||||||
|
var key = TypeName + "GetAll";
|
||||||
|
var item = await Cache.GetOrSetAsync(key, async() =>
|
||||||
|
{
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
var page = await con.GetAllAsync<GlobalSettings>();
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
}, 5);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
public GlobalSettings Get(string pageName)
|
public GlobalSettings Get(string pageName)
|
||||||
{
|
{
|
||||||
var key = pageName + "Get";
|
var key = pageName + "Get";
|
||||||
|
@ -85,6 +108,38 @@ namespace PlexRequests.Store.Repository
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<GlobalSettings> GetAsync(string settingsName)
|
||||||
|
{
|
||||||
|
var key = settingsName + "Get";
|
||||||
|
var item = await Cache.GetOrSetAsync(key, async() =>
|
||||||
|
{
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
var page = await con.GetAllAsync<GlobalSettings>();
|
||||||
|
return page.SingleOrDefault(x => x.SettingsName == settingsName);
|
||||||
|
}
|
||||||
|
}, 5);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteAsync(GlobalSettings entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
return await con.DeleteAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAsync(GlobalSettings entity)
|
||||||
|
{
|
||||||
|
ResetCache();
|
||||||
|
using (var con = Db.DbConnection())
|
||||||
|
{
|
||||||
|
return await con.UpdateAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool Delete(GlobalSettings entity)
|
public bool Delete(GlobalSettings entity)
|
||||||
{
|
{
|
||||||
ResetCache();
|
ResetCache();
|
||||||
|
|
|
@ -27,41 +27,31 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Dapper.Contrib.Extensions;
|
using Dapper.Contrib.Extensions;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
using PlexRequests.Store.Repository;
|
using PlexRequests.Store.Repository;
|
||||||
|
|
||||||
namespace PlexRequests.Store
|
namespace PlexRequests.Store
|
||||||
{
|
{
|
||||||
public class UserRepository<T> : IRepository<T> where T : UserEntity
|
public class UserRepository<T> : BaseGenericRepository<T>, IRepository<T> where T : UserEntity
|
||||||
{
|
{
|
||||||
public UserRepository(ISqliteConfiguration config)
|
public UserRepository(ISqliteConfiguration config, ICacheProvider cache) : base(config, cache)
|
||||||
{
|
{
|
||||||
Config = config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISqliteConfiguration Config { get; }
|
public override T Get(int id)
|
||||||
public long Insert(T entity)
|
|
||||||
{
|
{
|
||||||
using (var cnn = Config.DbConnection())
|
throw new NotSupportedException("Get(int) is not supported. Use Get(string)");
|
||||||
{
|
|
||||||
cnn.Open();
|
|
||||||
return cnn.Insert(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<T> GetAll()
|
public override Task<T> GetAsync(int id)
|
||||||
{
|
{
|
||||||
using (var db = Config.DbConnection())
|
throw new NotSupportedException("GetAsync(int) is not supported. Use GetAsync(string)");
|
||||||
{
|
|
||||||
db.Open();
|
|
||||||
var result = db.GetAll<T>();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get(string id)
|
public override T Get(string id)
|
||||||
{
|
{
|
||||||
using (var db = Config.DbConnection())
|
using (var db = Config.DbConnection())
|
||||||
{
|
{
|
||||||
|
@ -72,33 +62,18 @@ namespace PlexRequests.Store
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get(int id)
|
public override async Task<T> GetAsync(string id)
|
||||||
{
|
|
||||||
throw new NotSupportedException("Get(int) is not supported. Use Get(string)");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Delete(T entity)
|
|
||||||
{
|
{
|
||||||
using (var db = Config.DbConnection())
|
using (var db = Config.DbConnection())
|
||||||
{
|
{
|
||||||
db.Open();
|
db.Open();
|
||||||
db.Delete(entity);
|
var result = await db.GetAllAsync<T>();
|
||||||
|
var selected = result.FirstOrDefault(x => x.UserGuid == id);
|
||||||
|
return selected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Update(T entity)
|
|
||||||
{
|
|
||||||
using (var db = Config.DbConnection())
|
|
||||||
{
|
|
||||||
db.Open();
|
|
||||||
return db.Update(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateAll(IEnumerable<T> entity)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Dapper" version="1.42" targetFramework="net45" />
|
<package id="Dapper" version="1.50.0-beta8" targetFramework="net45" />
|
||||||
<package id="Dapper.Contrib" version="1.43" targetFramework="net45" />
|
<package id="Dapper.Contrib" version="1.50.0-beta8" targetFramework="net45" />
|
||||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net45" />
|
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net45" />
|
||||||
<package id="NLog" version="4.2.3" targetFramework="net45" />
|
<package id="NLog" version="4.2.3" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
@ -1,295 +0,0 @@
|
||||||
@media (min-width: 768px) {
|
|
||||||
.row {
|
|
||||||
position: relative; }
|
|
||||||
.bottom-align-text {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0; } }
|
|
||||||
|
|
||||||
@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-color: #777; }
|
|
||||||
|
|
||||||
body.update-available {
|
|
||||||
margin-top: 80px; }
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
border-radius: 0.25rem !important; }
|
|
||||||
|
|
||||||
.multiSelect {
|
|
||||||
background-color: #4e5d6c; }
|
|
||||||
|
|
||||||
.form-control-custom {
|
|
||||||
background-color: #333333 !important;
|
|
||||||
color: white !important;
|
|
||||||
border-radius: 0;
|
|
||||||
box-shadow: 0 0 0 !important; }
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 3.5rem !important;
|
|
||||||
font-weight: 600 !important; }
|
|
||||||
|
|
||||||
.request-title {
|
|
||||||
margin-top: 0 !important;
|
|
||||||
font-size: 1.9rem !important; }
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 1.1rem !important; }
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: inline-block !important;
|
|
||||||
margin-bottom: 0.5rem !important;
|
|
||||||
font-size: 16px !important; }
|
|
||||||
|
|
||||||
.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: #df691a; }
|
|
||||||
|
|
||||||
.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: #d9534f !important;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: #d9534f !important; }
|
|
||||||
|
|
||||||
.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 !important;
|
|
||||||
background-color: #d9534f !important;
|
|
||||||
border-color: #d9534f !important; }
|
|
||||||
|
|
||||||
.btn-primary-outline {
|
|
||||||
color: #ff761b !important;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: #ff761b !important; }
|
|
||||||
|
|
||||||
.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 !important;
|
|
||||||
background-color: #df691a !important;
|
|
||||||
border-color: #df691a !important; }
|
|
||||||
|
|
||||||
.btn-info-outline {
|
|
||||||
color: #5bc0de !important;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: #5bc0de !important; }
|
|
||||||
|
|
||||||
.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 !important;
|
|
||||||
background-color: #5bc0de !important;
|
|
||||||
border-color: #5bc0de !important; }
|
|
||||||
|
|
||||||
.btn-warning-outline {
|
|
||||||
color: #f0ad4e !important;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: #f0ad4e !important; }
|
|
||||||
|
|
||||||
.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 !important;
|
|
||||||
background-color: #f0ad4e !important;
|
|
||||||
border-color: #f0ad4e !important; }
|
|
||||||
|
|
||||||
.btn-success-outline {
|
|
||||||
color: #5cb85c !important;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: #5cb85c !important; }
|
|
||||||
|
|
||||||
.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 !important;
|
|
||||||
background-color: #5cb85c !important;
|
|
||||||
border-color: #5cb85c !important; }
|
|
||||||
|
|
||||||
#movieList .mix {
|
|
||||||
display: none; }
|
|
||||||
|
|
||||||
#tvList .mix {
|
|
||||||
display: none; }
|
|
||||||
|
|
||||||
.scroll-top-wrapper {
|
|
||||||
position: fixed;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
z-index: 99999999;
|
|
||||||
background-color: #333333;
|
|
||||||
color: #eeeeee;
|
|
||||||
width: 50px;
|
|
||||||
height: 48px;
|
|
||||||
line-height: 48px;
|
|
||||||
right: 30px;
|
|
||||||
bottom: 30px;
|
|
||||||
padding-top: 2px;
|
|
||||||
border-top-left-radius: 10px;
|
|
||||||
border-top-right-radius: 10px;
|
|
||||||
border-bottom-right-radius: 10px;
|
|
||||||
border-bottom-left-radius: 10px;
|
|
||||||
-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: #df691a; }
|
|
||||||
|
|
||||||
.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: #4e5d6c; }
|
|
||||||
|
|
||||||
.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, 0.7) !important;
|
|
||||||
padding: 3px 12px;
|
|
||||||
color: rgba(255, 255, 255, 0.7) !important; }
|
|
||||||
|
|
||||||
.btn-split .btn {
|
|
||||||
border-radius: 0 !important; }
|
|
||||||
|
|
||||||
.btn-split .btn:not(.dropdown-toggle) {
|
|
||||||
border-radius: 0.25rem 0 0 0.25rem !important; }
|
|
||||||
|
|
||||||
.btn-split .btn.dropdown-toggle {
|
|
||||||
border-radius: 0 0.25rem 0.25rem 0 !important;
|
|
||||||
padding: 12px 8px; }
|
|
||||||
|
|
||||||
#updateAvailable {
|
|
||||||
background-color: #df691a;
|
|
||||||
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; }
|
|
||||||
|
|
||||||
.input-group-sm {
|
|
||||||
padding-top: 2px;
|
|
||||||
padding-bottom: 2px; }
|
|
||||||
|
|
||||||
.tab-pane .form-horizontal .form-group {
|
|
||||||
margin-right: 15px;
|
|
||||||
margin-left: 15px; }
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,365 +0,0 @@
|
||||||
$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;
|
|
||||||
$bg-colour: #333333;
|
|
||||||
$i:
|
|
||||||
!important;
|
|
||||||
|
|
||||||
@media (min-width: 768px ) {
|
|
||||||
.row {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-align-text {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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-color: #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.update-available {
|
|
||||||
margin-top: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
border-radius: .25rem $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.multiSelect {
|
|
||||||
background-color: $form-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control-custom {
|
|
||||||
background-color: $bg-colour $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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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: $primary-colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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: $bg-colour;
|
|
||||||
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: $primary-colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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; }
|
|
||||||
|
|
||||||
.input-group-sm{
|
|
||||||
padding-top: 2px;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-pane .form-horizontal .form-group {
|
|
||||||
margin-right: 15px;
|
|
||||||
margin-left: 15px; }
|
|
1
PlexRequests.UI/Content/Themes/original.css
Normal file
1
PlexRequests.UI/Content/Themes/original.css
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
1
PlexRequests.UI/Content/Themes/original.min.css
vendored
Normal file
1
PlexRequests.UI/Content/Themes/original.min.css
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
2
PlexRequests.UI/Content/Themes/original.scss
Normal file
2
PlexRequests.UI/Content/Themes/original.scss
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
body {
|
||||||
|
}
|
158
PlexRequests.UI/Content/Themes/plex.css
Normal file
158
PlexRequests.UI/Content/Themes/plex.css
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
.form-control-custom {
|
||||||
|
background-color: #333333 !important; }
|
||||||
|
|
||||||
|
.nav-tabs > li.active > a,
|
||||||
|
.nav-tabs > li.active > a:hover,
|
||||||
|
.nav-tabs > li.active > a:focus {
|
||||||
|
background: #df691a; }
|
||||||
|
|
||||||
|
scroll-top-wrapper {
|
||||||
|
background-color: #333333; }
|
||||||
|
|
||||||
|
.scroll-top-wrapper:hover {
|
||||||
|
background-color: #df691a; }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
|
1
PlexRequests.UI/Content/Themes/plex.min.css
vendored
Normal file
1
PlexRequests.UI/Content/Themes/plex.min.css
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.form-control-custom{background-color:#333 !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#df691a;}scroll-top-wrapper{background-color:#333;}.scroll-top-wrapper:hover{background-color:#df691a;}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 #333;}.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:-0;}.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:#333;}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#333;}.input-group-addon{background-color:#333;}.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-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:#333;}.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:#333;}.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,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:0;}
|
196
PlexRequests.UI/Content/Themes/plex.scss
Normal file
196
PlexRequests.UI/Content/Themes/plex.scss
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
$primary-colour: #df691a;
|
||||||
|
$primary-colour-outline: #ff761b;
|
||||||
|
$bg-colour: #333333;
|
||||||
|
$i: !important;
|
||||||
|
|
||||||
|
.form-control-custom {
|
||||||
|
background-color: $bg-colour $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;
|
||||||
|
}
|
|
@ -20,11 +20,15 @@
|
||||||
color: #fff; }
|
color: #fff; }
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
border-color: #777; }
|
border: 1px dashed #777; }
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
border-radius: 0.25rem !important; }
|
border-radius: 0.25rem !important; }
|
||||||
|
|
||||||
|
.btn-group-separated .btn,
|
||||||
|
.btn-group-separated .btn + .btn {
|
||||||
|
margin-left: 3px; }
|
||||||
|
|
||||||
.multiSelect {
|
.multiSelect {
|
||||||
background-color: #4e5d6c; }
|
background-color: #4e5d6c; }
|
||||||
|
|
1
PlexRequests.UI/Content/base.min.css
vendored
Normal file
1
PlexRequests.UI/Content/base.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -6,8 +6,7 @@ $info-colour: #5bc0de;
|
||||||
$warning-colour: #f0ad4e;
|
$warning-colour: #f0ad4e;
|
||||||
$danger-colour: #d9534f;
|
$danger-colour: #d9534f;
|
||||||
$success-colour: #5cb85c;
|
$success-colour: #5cb85c;
|
||||||
$i:
|
$i: !important;
|
||||||
!important;
|
|
||||||
|
|
||||||
@media (min-width: 768px ) {
|
@media (min-width: 768px ) {
|
||||||
.row {
|
.row {
|
||||||
|
@ -40,13 +39,18 @@ $i:
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
border-color: #777;
|
border: 1px dashed #777;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
border-radius: .25rem $i;
|
border-radius: .25rem $i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-group-separated .btn,
|
||||||
|
.btn-group-separated .btn + .btn {
|
||||||
|
margin-left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.multiSelect {
|
.multiSelect {
|
||||||
background-color: $form-color;
|
background-color: $form-color;
|
||||||
}
|
}
|
|
@ -12,6 +12,8 @@ var albumTemplate = Handlebars.compile(albumSource);
|
||||||
var movieTimer = 0;
|
var movieTimer = 0;
|
||||||
var tvimer = 0;
|
var tvimer = 0;
|
||||||
var base = $('#baseUrl').text();
|
var base = $('#baseUrl').text();
|
||||||
|
var tvLoaded = false;
|
||||||
|
var albumLoaded = false;
|
||||||
|
|
||||||
var mixItUpDefault = {
|
var mixItUpDefault = {
|
||||||
animation: { enable: true },
|
animation: { enable: true },
|
||||||
|
@ -40,9 +42,14 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
var $tvl = $('#tvList');
|
var $tvl = $('#tvList');
|
||||||
var $musicL = $('#musicList');
|
var $musicL = $('#musicList');
|
||||||
|
|
||||||
$('.approve-category').hide();
|
$('.approve-category,.delete-category').hide();
|
||||||
if (target === "#TvShowTab") {
|
if (target === "#TvShowTab") {
|
||||||
$('#approveTVShows').show();
|
if (!tvLoaded) {
|
||||||
|
tvLoaded = true;
|
||||||
|
tvLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#approveTVShows,#deleteTVShows').show();
|
||||||
if ($ml.mixItUp('isLoaded')) {
|
if ($ml.mixItUp('isLoaded')) {
|
||||||
activeState = $ml.mixItUp('getState');
|
activeState = $ml.mixItUp('getState');
|
||||||
$ml.mixItUp('destroy');
|
$ml.mixItUp('destroy');
|
||||||
|
@ -51,11 +58,11 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
activeState = $musicL.mixItUp('getState');
|
activeState = $musicL.mixItUp('getState');
|
||||||
$musicL.mixItUp('destroy');
|
$musicL.mixItUp('destroy');
|
||||||
}
|
}
|
||||||
if ($tvl.mixItUp('isLoaded')) $tvl.mixItUp('destroy');
|
//if ($tvl.mixItUp('isLoaded')) $tvl.mixItUp('destroy');
|
||||||
$tvl.mixItUp(mixItUpConfig(activeState)); // init or reinit
|
//$tvl.mixItUp(mixItUpConfig(activeState)); // init or reinit
|
||||||
}
|
}
|
||||||
if (target === "#MoviesTab") {
|
if (target === "#MoviesTab") {
|
||||||
$('#approveMovies').show();
|
$('#approveMovies,#deleteMovies').show();
|
||||||
if ($tvl.mixItUp('isLoaded')) {
|
if ($tvl.mixItUp('isLoaded')) {
|
||||||
activeState = $tvl.mixItUp('getState');
|
activeState = $tvl.mixItUp('getState');
|
||||||
$tvl.mixItUp('destroy');
|
$tvl.mixItUp('destroy');
|
||||||
|
@ -69,7 +76,11 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target === "#MusicTab") {
|
if (target === "#MusicTab") {
|
||||||
$('#approveMusic').show();
|
if (!albumLoaded) {
|
||||||
|
albumLoaded = true;
|
||||||
|
albumLoad();
|
||||||
|
}
|
||||||
|
$('#approveMusic,#deleteMusic').show();
|
||||||
if ($tvl.mixItUp('isLoaded')) {
|
if ($tvl.mixItUp('isLoaded')) {
|
||||||
activeState = $tvl.mixItUp('getState');
|
activeState = $tvl.mixItUp('getState');
|
||||||
$tvl.mixItUp('destroy');
|
$tvl.mixItUp('destroy');
|
||||||
|
@ -124,7 +135,7 @@ $('#approveTVShows').click(function (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingButton(buttonId, "success");
|
loadingButton(buttonId, "warning");
|
||||||
var url = createBaseUrl(base, '/approval/approvealltvshows');
|
var url = createBaseUrl(base, '/approval/approvealltvshows');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'post',
|
type: 'post',
|
||||||
|
@ -140,6 +151,72 @@ $('#approveTVShows').click(function (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
generateNotify("Something went wrong!", "danger");
|
generateNotify("Something went wrong!", "danger");
|
||||||
},
|
},
|
||||||
|
complete: function (e) {
|
||||||
|
finishLoading(buttonId, "warning", origHtml);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#deleteMovies').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!confirm("Are you sure you want to delete all TV show requests?")) return;
|
||||||
|
|
||||||
|
var buttonId = e.target.id;
|
||||||
|
var origHtml = $(this).html();
|
||||||
|
|
||||||
|
if ($('#' + buttonId).text() === " Loading...") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingButton(buttonId, "warning");
|
||||||
|
|
||||||
|
var url = createBaseUrl(base, '/approval/deleteallmovies');
|
||||||
|
$.ajax({
|
||||||
|
type: 'post',
|
||||||
|
url: url,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (response) {
|
||||||
|
if (checkJsonResponse(response)) {
|
||||||
|
generateNotify("Success! All Movie requests deleted!", "success");
|
||||||
|
movieLoad();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (e) {
|
||||||
|
console.log(e);
|
||||||
|
generateNotify("Something went wrong!", "danger");
|
||||||
|
},
|
||||||
|
complete: function (e) {
|
||||||
|
finishLoading(buttonId, "warning", origHtml);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$('#deleteTVShows').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!confirm("Are you sure you want to delete all TV show requests?")) return;
|
||||||
|
|
||||||
|
var buttonId = e.target.id;
|
||||||
|
var origHtml = $(this).html();
|
||||||
|
|
||||||
|
if ($('#' + buttonId).text() === " Loading...") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingButton(buttonId, "warning");
|
||||||
|
var url = createBaseUrl(base, '/approval/deletealltvshows');
|
||||||
|
$.ajax({
|
||||||
|
type: 'post',
|
||||||
|
url: url,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (response) {
|
||||||
|
if (checkJsonResponse(response)) {
|
||||||
|
generateNotify("Success! All TV Show requests deleted!", "success");
|
||||||
|
tvLoad();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (e) {
|
||||||
|
console.log(e);
|
||||||
|
generateNotify("Something went wrong!", "danger");
|
||||||
|
},
|
||||||
complete: function (e) {
|
complete: function (e) {
|
||||||
finishLoading(buttonId, "success", origHtml);
|
finishLoading(buttonId, "success", origHtml);
|
||||||
}
|
}
|
||||||
|
@ -448,10 +525,10 @@ function mixItUpConfig(activeState) {
|
||||||
return conf;
|
return conf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var position = 0;
|
||||||
function initLoad() {
|
function initLoad() {
|
||||||
movieLoad();
|
movieLoad();
|
||||||
tvLoad();
|
|
||||||
albumLoad();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function movieLoad() {
|
function movieLoad() {
|
||||||
|
|
|
@ -57,12 +57,15 @@ namespace PlexRequests.UI.Helpers
|
||||||
{
|
{
|
||||||
settings.ThemeName = Themes.PlexTheme;
|
settings.ThemeName = Themes.PlexTheme;
|
||||||
}
|
}
|
||||||
|
if (settings.ThemeName == "PlexBootstrap.css") settings.ThemeName = Themes.PlexTheme;
|
||||||
|
if (settings.ThemeName == "OriginalBootstrap.css") settings.ThemeName = Themes.OriginalTheme;
|
||||||
|
|
||||||
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/Themes/{settings.ThemeName}\" type=\"text/css\"/>");
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/bootstrap.css\" type=\"text/css\"/>");
|
||||||
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/Themes/{settings.ThemeName.Replace(".css",string.Empty)}Custom.min.css\" type=\"text/css\" />");
|
|
||||||
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/font-awesome.css\" type=\"text/css\"/>");
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/font-awesome.css\" type=\"text/css\"/>");
|
||||||
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/pace.min.css\" type=\"text/css\"/>");
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/pace.min.css\" type=\"text/css\"/>");
|
||||||
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/awesome-bootstrap-checkbox.css\" type=\"text/css\"/>");
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/awesome-bootstrap-checkbox.css\" type=\"text/css\"/>");
|
||||||
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/base.css\" type=\"text/css\"/>");
|
||||||
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/Themes/{settings.ThemeName}\" type=\"text/css\"/>");
|
||||||
|
|
||||||
sb.AppendLine($"<script src=\"{content}/Content/jquery-2.2.1.min.js\"></script>");
|
sb.AppendLine($"<script src=\"{content}/Content/jquery-2.2.1.min.js\"></script>");
|
||||||
sb.AppendLine($"<script src=\"{content}/Content/handlebars.min.js\"></script>");
|
sb.AppendLine($"<script src=\"{content}/Content/handlebars.min.js\"></script>");
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace PlexRequests.UI.Helpers
|
||||||
{
|
{
|
||||||
public static class Themes
|
public static class Themes
|
||||||
{
|
{
|
||||||
public const string OriginalTheme = "OriginalBootstrap.css";
|
public const string OriginalTheme = "original.css";
|
||||||
public const string PlexTheme = "PlexBootstrap.css";
|
public const string PlexTheme = "plex.css";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -56,13 +56,15 @@ namespace PlexRequests.UI.Jobs
|
||||||
var sickrage = JobBuilder.Create<SickRageCacher>().WithIdentity("SickRageCacher", "Cache").Build();
|
var sickrage = JobBuilder.Create<SickRageCacher>().WithIdentity("SickRageCacher", "Cache").Build();
|
||||||
var sonarr = JobBuilder.Create<SonarrCacher>().WithIdentity("SonarrCacher", "Cache").Build();
|
var sonarr = JobBuilder.Create<SonarrCacher>().WithIdentity("SonarrCacher", "Cache").Build();
|
||||||
var cp = JobBuilder.Create<CouchPotatoCacher>().WithIdentity("CouchPotatoCacher", "Cache").Build();
|
var cp = JobBuilder.Create<CouchPotatoCacher>().WithIdentity("CouchPotatoCacher", "Cache").Build();
|
||||||
var store = JobBuilder.Create<StoreBackup>().WithIdentity("StoreBackup", "Backup").Build();
|
var store = JobBuilder.Create<StoreBackup>().WithIdentity("StoreBackup", "Database").Build();
|
||||||
|
var storeClean = JobBuilder.Create<StoreCleanup>().WithIdentity("StoreCleanup", "Database").Build();
|
||||||
|
|
||||||
jobs.Add(plex);
|
jobs.Add(plex);
|
||||||
jobs.Add(sickrage);
|
jobs.Add(sickrage);
|
||||||
jobs.Add(sonarr);
|
jobs.Add(sonarr);
|
||||||
jobs.Add(cp);
|
jobs.Add(cp);
|
||||||
jobs.Add(store);
|
jobs.Add(store);
|
||||||
|
jobs.Add(storeClean);
|
||||||
|
|
||||||
return jobs;
|
return jobs;
|
||||||
}
|
}
|
||||||
|
@ -129,17 +131,25 @@ namespace PlexRequests.UI.Jobs
|
||||||
|
|
||||||
var storeBackup =
|
var storeBackup =
|
||||||
TriggerBuilder.Create()
|
TriggerBuilder.Create()
|
||||||
.WithIdentity("StoreBackup", "Backup")
|
.WithIdentity("StoreBackup", "Database")
|
||||||
.StartNow()
|
.StartNow()
|
||||||
.WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever())
|
.WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
var storeCleanup =
|
||||||
|
TriggerBuilder.Create()
|
||||||
|
.WithIdentity("StoreCleanup", "Database")
|
||||||
|
.StartNow()
|
||||||
|
.WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
triggers.Add(plexAvailabilityChecker);
|
triggers.Add(plexAvailabilityChecker);
|
||||||
triggers.Add(srCacher);
|
triggers.Add(srCacher);
|
||||||
triggers.Add(sonarrCacher);
|
triggers.Add(sonarrCacher);
|
||||||
triggers.Add(cpCacher);
|
triggers.Add(cpCacher);
|
||||||
triggers.Add(storeBackup);
|
triggers.Add(storeBackup);
|
||||||
|
triggers.Add(storeCleanup);
|
||||||
|
|
||||||
return triggers;
|
return triggers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,7 +481,6 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
return Response.AsJson(valid.SendJsonError());
|
return Response.AsJson(valid.SendJsonError());
|
||||||
}
|
}
|
||||||
Log.Trace(settings.DumpJson());
|
|
||||||
|
|
||||||
var result = EmailService.SaveSettings(settings);
|
var result = EmailService.SaveSettings(settings);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace PlexRequests.UI.Modules
|
||||||
ISettingsService<SonarrSettings> sonarrSettings, ISickRageApi srApi, ISettingsService<SickRageSettings> srSettings,
|
ISettingsService<SonarrSettings> sonarrSettings, ISickRageApi srApi, ISettingsService<SickRageSettings> srSettings,
|
||||||
ISettingsService<HeadphonesSettings> hpSettings, IHeadphonesApi hpApi, ISettingsService<PlexRequestSettings> pr) : base("approval", pr)
|
ISettingsService<HeadphonesSettings> hpSettings, IHeadphonesApi hpApi, ISettingsService<PlexRequestSettings> pr) : base("approval", pr)
|
||||||
{
|
{
|
||||||
this.RequiresClaims(UserClaims.Admin);
|
this.RequiresClaims(UserClaims.Admin);
|
||||||
|
|
||||||
Service = service;
|
Service = service;
|
||||||
CpService = cpService;
|
CpService = cpService;
|
||||||
|
@ -66,6 +66,8 @@ namespace PlexRequests.UI.Modules
|
||||||
Post["/approveall"] = x => ApproveAll();
|
Post["/approveall"] = x => ApproveAll();
|
||||||
Post["/approveallmovies"] = x => ApproveAllMovies();
|
Post["/approveallmovies"] = x => ApproveAllMovies();
|
||||||
Post["/approvealltvshows"] = x => ApproveAllTVShows();
|
Post["/approvealltvshows"] = x => ApproveAllTVShows();
|
||||||
|
Post["/deleteallmovies"] = x => DeleteAllMovies();
|
||||||
|
Post["/deletealltvshows"] = x => DeleteAllTVShows();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRequestService Service { get; }
|
private IRequestService Service { get; }
|
||||||
|
@ -130,7 +132,7 @@ namespace PlexRequests.UI.Modules
|
||||||
Log.Trace("Approval result: {0}", requestResult);
|
Log.Trace("Approval result: {0}", requestResult);
|
||||||
if (requestResult)
|
if (requestResult)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel {Result = true});
|
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
Response.AsJson(new JsonResponseModel
|
Response.AsJson(new JsonResponseModel
|
||||||
|
@ -156,11 +158,9 @@ namespace PlexRequests.UI.Modules
|
||||||
request.Approved = true;
|
request.Approved = true;
|
||||||
var requestResult = Service.UpdateRequest(request);
|
var requestResult = Service.UpdateRequest(request);
|
||||||
Log.Trace("Approval result: {0}", requestResult);
|
Log.Trace("Approval result: {0}", requestResult);
|
||||||
if (requestResult)
|
return Response.AsJson(requestResult
|
||||||
{
|
? new JsonResponseModel { Result = true }
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
: new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" });
|
||||||
}
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" });
|
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel
|
return Response.AsJson(new JsonResponseModel
|
||||||
{
|
{
|
||||||
|
@ -168,17 +168,19 @@ namespace PlexRequests.UI.Modules
|
||||||
Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Could not add the series to SickRage"
|
Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Could not add the series to SickRage"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel
|
|
||||||
{
|
|
||||||
Result = false,
|
request.Approved = true;
|
||||||
Message = "SickRage or Sonarr are not set up!"
|
var res = Service.UpdateRequest(request);
|
||||||
});
|
return Response.AsJson(res
|
||||||
|
? new JsonResponseModel { Result = true, Message = "This has been approved, but It has not been sent to Sonarr/SickRage because it has not been configured" }
|
||||||
|
: new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response RequestMovieAndUpdateStatus(RequestedModel request, string qualityId)
|
private Response RequestMovieAndUpdateStatus(RequestedModel request, string qualityId)
|
||||||
{
|
{
|
||||||
var cpSettings = CpService.GetSettings();
|
var cpSettings = CpService.GetSettings();
|
||||||
var cp = new CouchPotatoApi();
|
|
||||||
Log.Info("Adding movie to CouchPotato : {0}", request.Title);
|
Log.Info("Adding movie to CouchPotato : {0}", request.Title);
|
||||||
if (!cpSettings.Enabled)
|
if (!cpSettings.Enabled)
|
||||||
{
|
{
|
||||||
|
@ -197,7 +199,7 @@ namespace PlexRequests.UI.Modules
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = cp.AddMovie(request.ImdbId, cpSettings.ApiKey, request.Title, cpSettings.FullUri, string.IsNullOrEmpty(qualityId) ? cpSettings.ProfileId : qualityId);
|
var result = CpApi.AddMovie(request.ImdbId, cpSettings.ApiKey, request.Title, cpSettings.FullUri, string.IsNullOrEmpty(qualityId) ? cpSettings.ProfileId : qualityId);
|
||||||
Log.Trace("Adding movie to CP result {0}", result);
|
Log.Trace("Adding movie to CP result {0}", result);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
@ -250,7 +252,7 @@ namespace PlexRequests.UI.Modules
|
||||||
var result = sender.AddAlbum(request);
|
var result = sender.AddAlbum(request);
|
||||||
|
|
||||||
|
|
||||||
return Response.AsJson( new JsonResponseModel { Result = true, Message = "We have sent the approval to Headphones for processing, This can take a few minutes."} );
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = "We have sent the approval to Headphones for processing, This can take a few minutes." });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response ApproveAllMovies()
|
private Response ApproveAllMovies()
|
||||||
|
@ -274,6 +276,27 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response DeleteAllMovies()
|
||||||
|
{
|
||||||
|
|
||||||
|
var requests = Service.GetAll().Where(x => x.Type == RequestType.Movie);
|
||||||
|
var requestedModels = requests as RequestedModel[] ?? requests.ToArray();
|
||||||
|
if (!requestedModels.Any())
|
||||||
|
{
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "There are no movie requests to delete. Please refresh." });
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DeleteRequests(requestedModels);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Fatal(e);
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Response ApproveAllTVShows()
|
private Response ApproveAllTVShows()
|
||||||
{
|
{
|
||||||
var requests = Service.GetAll().Where(x => x.CanApprove && x.Type == RequestType.TvShow);
|
var requests = Service.GetAll().Where(x => x.CanApprove && x.Type == RequestType.TvShow);
|
||||||
|
@ -294,6 +317,27 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response DeleteAllTVShows()
|
||||||
|
{
|
||||||
|
|
||||||
|
var requests = Service.GetAll().Where(x => x.Type == RequestType.TvShow);
|
||||||
|
var requestedModels = requests as RequestedModel[] ?? requests.ToArray();
|
||||||
|
if (!requestedModels.Any())
|
||||||
|
{
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "There are no tv show requests to delete. Please refresh." });
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DeleteRequests(requestedModels);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Fatal(e);
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Approves all.
|
/// Approves all.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -319,6 +363,22 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response DeleteRequests(RequestedModel[] requestedModels)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = Service.BatchDelete(requestedModels.ToList());
|
||||||
|
return Response.AsJson(result
|
||||||
|
? new JsonResponseModel { Result = true }
|
||||||
|
: new JsonResponseModel { Result = false, Message = "We could not delete all of the requests. Please try again or check the logs." });
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Fatal(e);
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Response UpdateRequests(RequestedModel[] requestedModels)
|
private Response UpdateRequests(RequestedModel[] requestedModels)
|
||||||
{
|
{
|
||||||
var cpSettings = CpService.GetSettings();
|
var cpSettings = CpService.GetSettings();
|
||||||
|
@ -327,15 +387,23 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
if (r.Type == RequestType.Movie)
|
if (r.Type == RequestType.Movie)
|
||||||
{
|
{
|
||||||
var res = SendMovie(cpSettings, r, CpApi);
|
if (cpSettings.Enabled)
|
||||||
if (res)
|
|
||||||
{
|
{
|
||||||
r.Approved = true;
|
var res = SendMovie(cpSettings, r, CpApi);
|
||||||
updatedRequests.Add(r);
|
if (res)
|
||||||
|
{
|
||||||
|
r.Approved = true;
|
||||||
|
updatedRequests.Add(r);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("Could not approve and send the movie {0} to couch potato!", r.Title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error("Could not approve and send the movie {0} to couch potato!", r.Title);
|
r.Approved = true;
|
||||||
|
updatedRequests.Add(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r.Type == RequestType.TvShow)
|
if (r.Type == RequestType.TvShow)
|
||||||
|
@ -358,7 +426,7 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sonarr.Enabled)
|
else if (sonarr.Enabled)
|
||||||
{
|
{
|
||||||
var res = sender.SendToSonarr(sonarr, r);
|
var res = sender.SendToSonarr(sonarr, r);
|
||||||
if (!string.IsNullOrEmpty(res?.title))
|
if (!string.IsNullOrEmpty(res?.title))
|
||||||
|
@ -372,11 +440,15 @@ namespace PlexRequests.UI.Modules
|
||||||
res?.ErrorMessages.ForEach(x => Log.Error("Error messages: {0}", x));
|
res?.ErrorMessages.ForEach(x => Log.Error("Error messages: {0}", x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r.Approved = true;
|
||||||
|
updatedRequests.Add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var result = Service.BatchUpdate(updatedRequests);
|
var result = Service.BatchUpdate(updatedRequests);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new JsonResponseModel { Result = true }
|
? new JsonResponseModel { Result = true }
|
||||||
|
|
|
@ -35,6 +35,7 @@ using Nancy.Security;
|
||||||
|
|
||||||
using PlexRequests.Core;
|
using PlexRequests.Core;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.UI.Models;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
|
@ -103,7 +104,7 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
return Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/register?error=true" : "~/register?error=true");
|
return Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/register?error=true" : "~/register?error=true");
|
||||||
}
|
}
|
||||||
var userId = UserMapper.CreateUser(username, Request.Form.Password, new[] { "Admin" });
|
var userId = UserMapper.CreateAdmin(username, Request.Form.Password);
|
||||||
Session[SessionKeys.UsernameKey] = username;
|
Session[SessionKeys.UsernameKey] = username;
|
||||||
return this.LoginAndRedirect((Guid)userId);
|
return this.LoginAndRedirect((Guid)userId);
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,17 +74,17 @@ namespace PlexRequests.UI.Modules
|
||||||
Cache = cache;
|
Cache = cache;
|
||||||
|
|
||||||
Get["/"] = _ => LoadRequests();
|
Get["/"] = _ => LoadRequests();
|
||||||
Get["/movies"] = _ => GetMovies();
|
Get["/movies", true] = async (x, ct) => await GetMovies();
|
||||||
Get["/tvshows"] = _ => GetTvShows();
|
Get["/tvshows", true] = async (c, ct) => await GetTvShows();
|
||||||
Get["/albums"] = _ => GetAlbumRequests();
|
Get["/albums", true] = async (x,ct) => await GetAlbumRequests();
|
||||||
Post["/delete"] = _ => DeleteRequest((int)Request.Form.id);
|
Post["/delete", true] = async (x, ct) => await DeleteRequest((int)Request.Form.id);
|
||||||
Post["/reportissue"] = _ => ReportIssue((int)Request.Form.requestId, (IssueState)(int)Request.Form.issue, null);
|
Post["/reportissue", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, (IssueState)(int)Request.Form.issue, null);
|
||||||
Post["/reportissuecomment"] = _ => ReportIssue((int)Request.Form.requestId, IssueState.Other, (string)Request.Form.commentArea);
|
Post["/reportissuecomment", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, IssueState.Other, (string)Request.Form.commentArea);
|
||||||
|
|
||||||
Post["/clearissues"] = _ => ClearIssue((int)Request.Form.Id);
|
Post["/clearissues", true] = async (x, ct) => await ClearIssue((int)Request.Form.Id);
|
||||||
|
|
||||||
Post["/changeavailability"] = _ => ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available);
|
Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available);
|
||||||
Post["/addnote"] = _ => AddNote((int)Request.Form.requestId, (string)Request.Form.noteArea);
|
Post["/addnote", true] = async (x, ct) => await AddNote((int)Request.Form.requestId, (string)Request.Form.noteArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRequestService Service { get; }
|
private IRequestService Service { get; }
|
||||||
|
@ -105,122 +105,94 @@ namespace PlexRequests.UI.Modules
|
||||||
return View["Index", settings];
|
return View["Index", settings];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response GetMovies() // TODO: async await the API calls
|
private async Task<Response> GetMovies()
|
||||||
{
|
{
|
||||||
var settings = PrSettings.GetSettings();
|
var settings = PrSettings.GetSettings();
|
||||||
|
|
||||||
List<Task> taskList = new List<Task>();
|
var allRequests = await Service.GetAllAsync();
|
||||||
|
allRequests = allRequests.Where(x => x.Type == RequestType.Movie);
|
||||||
|
|
||||||
List<RequestedModel> dbMovies = new List<RequestedModel>();
|
var dbMovies = allRequests.ToList();
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
|
||||||
|
if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin)
|
||||||
{
|
{
|
||||||
return Service.GetAll().Where(x => x.Type == RequestType.Movie);
|
dbMovies = dbMovies.Where(x => x.UserHasRequested(Username)).ToList();
|
||||||
|
}
|
||||||
}).ContinueWith((t) =>
|
|
||||||
{
|
|
||||||
dbMovies = t.Result.ToList();
|
|
||||||
|
|
||||||
if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin)
|
|
||||||
{
|
|
||||||
dbMovies = dbMovies.Where(x => x.UserHasRequested(Username)).ToList();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
List<QualityModel> qualities = new List<QualityModel>();
|
List<QualityModel> qualities = new List<QualityModel>();
|
||||||
|
|
||||||
if (IsAdmin)
|
if (IsAdmin)
|
||||||
{
|
{
|
||||||
var cpSettings = CpSettings.GetSettings();
|
var cpSettings = CpSettings.GetSettings();
|
||||||
if (cpSettings.Enabled)
|
if (cpSettings.Enabled)
|
||||||
{
|
{
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
|
||||||
|
var result = await Cache.GetOrSetAsync(CacheKeys.CouchPotatoQualityProfiles, async () =>
|
||||||
{
|
{
|
||||||
return Cache.GetOrSet(CacheKeys.CouchPotatoQualityProfiles, () =>
|
return await Task.Run(() => CpApi.GetProfiles(cpSettings.FullUri, cpSettings.ApiKey)).ConfigureAwait(false);
|
||||||
{
|
});
|
||||||
return CpApi.GetProfiles(cpSettings.FullUri, cpSettings.ApiKey); // TODO: cache this!
|
|
||||||
});
|
qualities = result.list.Select(x => new QualityModel() { Id = x._id, Name = x.label }).ToList();
|
||||||
}).ContinueWith((t) =>
|
|
||||||
{
|
|
||||||
qualities = t.Result.list.Select(x => new QualityModel() { Id = x._id, Name = x.label }).ToList();
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.WaitAll(taskList.ToArray());
|
var viewModel = dbMovies.Select(movie => new RequestViewModel
|
||||||
|
|
||||||
var viewModel = dbMovies.Select(movie =>
|
|
||||||
{
|
{
|
||||||
return new RequestViewModel
|
ProviderId = movie.ProviderId,
|
||||||
{
|
Type = movie.Type,
|
||||||
ProviderId = movie.ProviderId,
|
Status = movie.Status,
|
||||||
Type = movie.Type,
|
ImdbId = movie.ImdbId,
|
||||||
Status = movie.Status,
|
Id = movie.Id,
|
||||||
ImdbId = movie.ImdbId,
|
PosterPath = movie.PosterPath,
|
||||||
Id = movie.Id,
|
ReleaseDate = movie.ReleaseDate,
|
||||||
PosterPath = movie.PosterPath,
|
ReleaseDateTicks = movie.ReleaseDate.Ticks,
|
||||||
ReleaseDate = movie.ReleaseDate,
|
RequestedDate = movie.RequestedDate,
|
||||||
ReleaseDateTicks = movie.ReleaseDate.Ticks,
|
Released = DateTime.Now > movie.ReleaseDate,
|
||||||
RequestedDate = movie.RequestedDate,
|
RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(movie.RequestedDate, DateTimeOffset).Ticks,
|
||||||
Released = DateTime.Now > movie.ReleaseDate,
|
Approved = movie.Available || movie.Approved,
|
||||||
RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(movie.RequestedDate, DateTimeOffset).Ticks,
|
Title = movie.Title,
|
||||||
Approved = movie.Available || movie.Approved,
|
Overview = movie.Overview,
|
||||||
Title = movie.Title,
|
RequestedUsers = IsAdmin ? movie.AllUsers.ToArray() : new string[] { },
|
||||||
Overview = movie.Overview,
|
ReleaseYear = movie.ReleaseDate.Year.ToString(),
|
||||||
RequestedUsers = IsAdmin ? movie.AllUsers.ToArray() : new string[] { },
|
Available = movie.Available,
|
||||||
ReleaseYear = movie.ReleaseDate.Year.ToString(),
|
Admin = IsAdmin,
|
||||||
Available = movie.Available,
|
Issues = movie.Issues.ToString().CamelCaseToWords(),
|
||||||
Admin = IsAdmin,
|
OtherMessage = movie.OtherMessage,
|
||||||
Issues = movie.Issues.ToString().CamelCaseToWords(),
|
AdminNotes = movie.AdminNote,
|
||||||
OtherMessage = movie.OtherMessage,
|
Qualities = qualities.ToArray()
|
||||||
AdminNotes = movie.AdminNote,
|
|
||||||
Qualities = qualities.ToArray()
|
|
||||||
};
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
return Response.AsJson(viewModel);
|
return Response.AsJson(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response GetTvShows() // TODO: async await the API calls
|
private async Task<Response> GetTvShows()
|
||||||
{
|
{
|
||||||
var settings = PrSettings.GetSettings();
|
var settings = PrSettings.GetSettings();
|
||||||
|
|
||||||
List<Task> taskList = new List<Task>();
|
var requests = await Service.GetAllAsync();
|
||||||
|
requests = requests.Where(x => x.Type == RequestType.TvShow);
|
||||||
|
|
||||||
List<RequestedModel> dbTv = new List<RequestedModel>();
|
var dbTv = requests;
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
|
||||||
|
if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin)
|
||||||
{
|
{
|
||||||
return Service.GetAll().Where(x => x.Type == RequestType.TvShow);
|
dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
}).ContinueWith((t) =>
|
IEnumerable<QualityModel> qualities = new List<QualityModel>();
|
||||||
{
|
|
||||||
dbTv = t.Result.ToList();
|
|
||||||
|
|
||||||
if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin)
|
|
||||||
{
|
|
||||||
dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
List<QualityModel> qualities = new List<QualityModel>();
|
|
||||||
if (IsAdmin)
|
if (IsAdmin)
|
||||||
{
|
{
|
||||||
var sonarrSettings = SonarrSettings.GetSettings();
|
var sonarrSettings = SonarrSettings.GetSettings();
|
||||||
if (sonarrSettings.Enabled)
|
if (sonarrSettings.Enabled)
|
||||||
{
|
{
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
var result = Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async () =>
|
||||||
{
|
{
|
||||||
return Cache.GetOrSet(CacheKeys.SonarrQualityProfiles, () =>
|
return await Task.Run(() => SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri));
|
||||||
{
|
|
||||||
return SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri); // TODO: cache this!
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}).ContinueWith((t) =>
|
qualities = result.Result.Select(x => new QualityModel() { Id = x.id.ToString(), Name = x.name }).ToList();
|
||||||
{
|
|
||||||
qualities = t.Result.Select(x => new QualityModel() { Id = x.id.ToString(), Name = x.name }).ToList();
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
var sickRageSettings = SickRageSettings.GetSettings();
|
var sickRageSettings = SickRageSettings.GetSettings();
|
||||||
if (sickRageSettings.Enabled)
|
if (sickRageSettings.Enabled)
|
||||||
{
|
{
|
||||||
|
@ -229,8 +201,6 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.WaitAll(taskList.ToArray());
|
|
||||||
|
|
||||||
var viewModel = dbTv.Select(tv =>
|
var viewModel = dbTv.Select(tv =>
|
||||||
{
|
{
|
||||||
return new RequestViewModel
|
return new RequestViewModel
|
||||||
|
@ -264,10 +234,11 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(viewModel);
|
return Response.AsJson(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response GetAlbumRequests()
|
private async Task<Response> GetAlbumRequests()
|
||||||
{
|
{
|
||||||
var settings = PrSettings.GetSettings();
|
var settings = PrSettings.GetSettings();
|
||||||
var dbAlbum = Service.GetAll().Where(x => x.Type == RequestType.Album);
|
var dbAlbum = await Service.GetAllAsync();
|
||||||
|
dbAlbum = dbAlbum.Where(x => x.Type == RequestType.Album);
|
||||||
if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin)
|
if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin)
|
||||||
{
|
{
|
||||||
dbAlbum = dbAlbum.Where(x => x.UserHasRequested(Username));
|
dbAlbum = dbAlbum.Where(x => x.UserHasRequested(Username));
|
||||||
|
@ -308,12 +279,12 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(viewModel);
|
return Response.AsJson(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response DeleteRequest(int requestid)
|
private async Task<Response> DeleteRequest(int requestid)
|
||||||
{
|
{
|
||||||
this.RequiresClaims (UserClaims.Admin);
|
this.RequiresClaims(UserClaims.Admin);
|
||||||
|
|
||||||
var currentEntity = Service.Get(requestid);
|
var currentEntity = await Service.GetAsync(requestid);
|
||||||
Service.DeleteRequest(currentEntity);
|
await Service.DeleteRequestAsync(currentEntity);
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,9 +296,9 @@ namespace PlexRequests.UI.Modules
|
||||||
/// <param name="issue">The issue.</param>
|
/// <param name="issue">The issue.</param>
|
||||||
/// <param name="comment">The comment.</param>
|
/// <param name="comment">The comment.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private Response ReportIssue(int requestId, IssueState issue, string comment)
|
private async Task<Response> ReportIssue(int requestId, IssueState issue, string comment)
|
||||||
{
|
{
|
||||||
var originalRequest = Service.Get(requestId);
|
var originalRequest = await Service.GetAsync(requestId);
|
||||||
if (originalRequest == null)
|
if (originalRequest == null)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" });
|
||||||
|
@ -338,7 +309,7 @@ namespace PlexRequests.UI.Modules
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
|
|
||||||
|
|
||||||
var result = Service.UpdateRequest(originalRequest);
|
var result = await Service.UpdateRequestAsync(originalRequest);
|
||||||
|
|
||||||
var model = new NotificationModel
|
var model = new NotificationModel
|
||||||
{
|
{
|
||||||
|
@ -348,18 +319,18 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
Body = issue == IssueState.Other ? comment : issue.ToString().CamelCaseToWords()
|
Body = issue == IssueState.Other ? comment : issue.ToString().CamelCaseToWords()
|
||||||
};
|
};
|
||||||
NotificationService.Publish(model);
|
await NotificationService.Publish(model);
|
||||||
|
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new JsonResponseModel { Result = true }
|
? new JsonResponseModel { Result = true }
|
||||||
: new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" });
|
: new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response ClearIssue(int requestId)
|
private async Task<Response> ClearIssue(int requestId)
|
||||||
{
|
{
|
||||||
this.RequiresClaims ( UserClaims.Admin);
|
this.RequiresClaims(UserClaims.Admin);
|
||||||
|
|
||||||
var originalRequest = Service.Get(requestId);
|
var originalRequest = await Service.GetAsync(requestId);
|
||||||
if (originalRequest == null)
|
if (originalRequest == null)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to clear it!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to clear it!" });
|
||||||
|
@ -367,16 +338,16 @@ namespace PlexRequests.UI.Modules
|
||||||
originalRequest.Issues = IssueState.None;
|
originalRequest.Issues = IssueState.None;
|
||||||
originalRequest.OtherMessage = string.Empty;
|
originalRequest.OtherMessage = string.Empty;
|
||||||
|
|
||||||
var result = Service.UpdateRequest(originalRequest);
|
var result = await Service.UpdateRequestAsync(originalRequest);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new JsonResponseModel { Result = true }
|
? new JsonResponseModel { Result = true }
|
||||||
: new JsonResponseModel { Result = false, Message = "Could not clear issue, please try again or check the logs" });
|
: new JsonResponseModel { Result = false, Message = "Could not clear issue, please try again or check the logs" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response ChangeRequestAvailability(int requestId, bool available)
|
private async Task<Response> ChangeRequestAvailability(int requestId, bool available)
|
||||||
{
|
{
|
||||||
this.RequiresClaims (UserClaims.Admin);
|
this.RequiresClaims(UserClaims.Admin);
|
||||||
var originalRequest = Service.Get(requestId);
|
var originalRequest = await Service.GetAsync(requestId);
|
||||||
if (originalRequest == null)
|
if (originalRequest == null)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to change the availability!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to change the availability!" });
|
||||||
|
@ -384,16 +355,16 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
originalRequest.Available = available;
|
originalRequest.Available = available;
|
||||||
|
|
||||||
var result = Service.UpdateRequest(originalRequest);
|
var result = await Service.UpdateRequestAsync(originalRequest);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new { Result = true, Available = available, Message = string.Empty }
|
? new { Result = true, Available = available, Message = string.Empty }
|
||||||
: new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" });
|
: new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response AddNote(int requestId, string noteArea)
|
private async Task<Response> AddNote(int requestId, string noteArea)
|
||||||
{
|
{
|
||||||
this.RequiresClaims (UserClaims.Admin);
|
this.RequiresClaims(UserClaims.Admin);
|
||||||
var originalRequest = Service.Get(requestId);
|
var originalRequest = await Service.GetAsync(requestId);
|
||||||
if (originalRequest == null)
|
if (originalRequest == null)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to add a note!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to add a note!" });
|
||||||
|
@ -401,7 +372,7 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
originalRequest.AdminNote = noteArea;
|
originalRequest.AdminNote = noteArea;
|
||||||
|
|
||||||
var result = Service.UpdateRequest(originalRequest);
|
var result = await Service.UpdateRequestAsync(originalRequest);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new JsonResponseModel { Result = true }
|
? new JsonResponseModel { Result = true }
|
||||||
: new JsonResponseModel { Result = false, Message = "Could not update the notes, please try again or check the logs" });
|
: new JsonResponseModel { Result = false, Message = "Could not update the notes, please try again or check the logs" });
|
||||||
|
|
|
@ -47,7 +47,7 @@ using PlexRequests.Store;
|
||||||
using PlexRequests.UI.Helpers;
|
using PlexRequests.UI.Helpers;
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.UI.Models;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
|
||||||
using Nancy.Extensions;
|
using Nancy.Extensions;
|
||||||
using PlexRequests.Api.Models.Tv;
|
using PlexRequests.Api.Models.Tv;
|
||||||
using PlexRequests.Store.Models;
|
using PlexRequests.Store.Models;
|
||||||
|
@ -92,22 +92,22 @@ namespace PlexRequests.UI.Modules
|
||||||
EmailNotificationSettings = email;
|
EmailNotificationSettings = email;
|
||||||
|
|
||||||
|
|
||||||
Get["/"] = parameters => RequestLoad();
|
Get["/", true] = async (x, ct) => await RequestLoad();
|
||||||
|
|
||||||
Get["movie/{searchTerm}"] = parameters => SearchMovie((string)parameters.searchTerm);
|
Get["movie/{searchTerm}", true] = async (x, ct) => await SearchMovie((string)x.searchTerm);
|
||||||
Get["tv/{searchTerm}"] = parameters => SearchTvShow((string)parameters.searchTerm);
|
Get["tv/{searchTerm}", true] = async (x, ct) => await SearchTvShow((string)x.searchTerm);
|
||||||
Get["music/{searchTerm}"] = parameters => SearchMusic((string)parameters.searchTerm);
|
Get["music/{searchTerm}", true] = async (x, ct) => await SearchMusic((string)x.searchTerm);
|
||||||
Get["music/coverArt/{id}"] = p => GetMusicBrainzCoverArt((string)p.id);
|
Get["music/coverArt/{id}"] = p => GetMusicBrainzCoverArt((string)p.id);
|
||||||
|
|
||||||
Get["movie/upcoming"] = parameters => UpcomingMovies();
|
Get["movie/upcoming", true] = async (x, ct) => await UpcomingMovies();
|
||||||
Get["movie/playing"] = parameters => CurrentlyPlayingMovies();
|
Get["movie/playing", true] = async (x, ct) => await CurrentlyPlayingMovies();
|
||||||
|
|
||||||
Post["request/movie"] = parameters => RequestMovie((int)Request.Form.movieId);
|
Post["request/movie", true] = async (x, ct) => await RequestMovie((int)Request.Form.movieId);
|
||||||
Post["request/tv"] = parameters => RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons);
|
Post["request/tv", true] = async (x, ct) => await RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons);
|
||||||
Post["request/album"] = parameters => RequestAlbum((string)Request.Form.albumId);
|
Post["request/album", true] = async (x, ct) => await RequestAlbum((string)Request.Form.albumId);
|
||||||
|
|
||||||
Post["/notifyuser"] = x => NotifyUser((bool)Request.Form.notify);
|
Post["/notifyuser", true] = async (x, ct) => await NotifyUser((bool)Request.Form.notify);
|
||||||
Get["/notifyuser"] = x => GetUserNotificationSettings();
|
Get["/notifyuser", true] = async (x, ct) => await GetUserNotificationSettings();
|
||||||
|
|
||||||
Get["/seasons"] = x => GetSeasons();
|
Get["/seasons"] = x => GetSeasons();
|
||||||
}
|
}
|
||||||
|
@ -136,87 +136,86 @@ namespace PlexRequests.UI.Modules
|
||||||
private IRepository<UsersToNotify> UsersToNotifyRepo { get; }
|
private IRepository<UsersToNotify> UsersToNotifyRepo { get; }
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private Negotiator RequestLoad()
|
private async Task<Negotiator> RequestLoad()
|
||||||
{
|
{
|
||||||
var settings = PrService.GetSettings();
|
var settings = await PrService.GetSettingsAsync();
|
||||||
|
|
||||||
Log.Trace("Loading Index");
|
Log.Trace("Loading Index");
|
||||||
return View["Search/Index", settings];
|
return View["Search/Index", settings];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response UpcomingMovies()
|
private async Task<Response> UpcomingMovies()
|
||||||
{
|
{
|
||||||
Log.Trace("Loading upcoming movies");
|
Log.Trace("Loading upcoming movies");
|
||||||
return ProcessMovies(MovieSearchType.Upcoming, string.Empty);
|
return await ProcessMovies(MovieSearchType.Upcoming, string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response CurrentlyPlayingMovies()
|
private async Task<Response> CurrentlyPlayingMovies()
|
||||||
{
|
{
|
||||||
Log.Trace("Loading currently playing movies");
|
Log.Trace("Loading currently playing movies");
|
||||||
return ProcessMovies(MovieSearchType.CurrentlyPlaying, string.Empty);
|
return await ProcessMovies(MovieSearchType.CurrentlyPlaying, string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response SearchMovie(string searchTerm)
|
private async Task<Response> SearchMovie(string searchTerm)
|
||||||
{
|
{
|
||||||
Log.Trace("Searching for Movie {0}", searchTerm);
|
Log.Trace("Searching for Movie {0}", searchTerm);
|
||||||
return ProcessMovies(MovieSearchType.Search, searchTerm);
|
return await ProcessMovies(MovieSearchType.Search, searchTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response ProcessMovies(MovieSearchType searchType, string searchTerm)
|
private async Task<Response> ProcessMovies(MovieSearchType searchType, string searchTerm)
|
||||||
{
|
{
|
||||||
var taskList = new List<Task>();
|
|
||||||
|
|
||||||
var apiMovies = new List<MovieResult>();
|
var apiMovies = new List<MovieResult>();
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
await Task.Factory.StartNew(
|
||||||
{
|
() =>
|
||||||
switch (searchType)
|
|
||||||
{
|
{
|
||||||
case MovieSearchType.Search:
|
switch (searchType)
|
||||||
return MovieApi.SearchMovie(searchTerm).Result.Select(x => new MovieResult()
|
{
|
||||||
{
|
case MovieSearchType.Search:
|
||||||
Adult = x.Adult,
|
return
|
||||||
BackdropPath = x.BackdropPath,
|
MovieApi.SearchMovie(searchTerm)
|
||||||
GenreIds = x.GenreIds,
|
.Result.Select(
|
||||||
Id = x.Id,
|
x =>
|
||||||
OriginalLanguage = x.OriginalLanguage,
|
new MovieResult()
|
||||||
OriginalTitle = x.OriginalTitle,
|
{
|
||||||
Overview = x.Overview,
|
Adult = x.Adult,
|
||||||
Popularity = x.Popularity,
|
BackdropPath = x.BackdropPath,
|
||||||
PosterPath = x.PosterPath,
|
GenreIds = x.GenreIds,
|
||||||
ReleaseDate = x.ReleaseDate,
|
Id = x.Id,
|
||||||
Title = x.Title,
|
OriginalLanguage = x.OriginalLanguage,
|
||||||
Video = x.Video,
|
OriginalTitle = x.OriginalTitle,
|
||||||
VoteAverage = x.VoteAverage,
|
Overview = x.Overview,
|
||||||
VoteCount = x.VoteCount
|
Popularity = x.Popularity,
|
||||||
}).ToList();
|
PosterPath = x.PosterPath,
|
||||||
case MovieSearchType.CurrentlyPlaying:
|
ReleaseDate = x.ReleaseDate,
|
||||||
return MovieApi.GetCurrentPlayingMovies().Result.ToList();
|
Title = x.Title,
|
||||||
case MovieSearchType.Upcoming:
|
Video = x.Video,
|
||||||
return MovieApi.GetUpcomingMovies().Result.ToList();
|
VoteAverage = x.VoteAverage,
|
||||||
default:
|
VoteCount = x.VoteCount
|
||||||
return new List<MovieResult>();
|
})
|
||||||
}
|
.ToList();
|
||||||
}).ContinueWith((t) =>
|
case MovieSearchType.CurrentlyPlaying:
|
||||||
{
|
return MovieApi.GetCurrentPlayingMovies().Result.ToList();
|
||||||
apiMovies = t.Result;
|
case MovieSearchType.Upcoming:
|
||||||
}));
|
return MovieApi.GetUpcomingMovies().Result.ToList();
|
||||||
|
default:
|
||||||
|
return new List<MovieResult>();
|
||||||
|
}
|
||||||
|
}).ContinueWith(
|
||||||
|
(t) =>
|
||||||
|
{
|
||||||
|
apiMovies = t.Result;
|
||||||
|
});
|
||||||
|
|
||||||
Dictionary<int, RequestedModel> dbMovies = new Dictionary<int, RequestedModel>();
|
var allResults = await RequestService.GetAllAsync();
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
allResults = allResults.Where(x => x.Type == RequestType.Movie);
|
||||||
{
|
|
||||||
return RequestService.GetAll().Where(x => x.Type == RequestType.Movie);
|
|
||||||
|
|
||||||
}).ContinueWith((t) =>
|
var distinctResults = allResults.DistinctBy(x => x.ProviderId);
|
||||||
{
|
var dbMovies = distinctResults.ToDictionary(x => x.ProviderId);
|
||||||
var distinctResults = t.Result.DistinctBy(x => x.ProviderId);
|
|
||||||
dbMovies = distinctResults.ToDictionary(x => x.ProviderId);
|
|
||||||
}));
|
|
||||||
|
|
||||||
Task.WaitAll(taskList.ToArray());
|
|
||||||
|
|
||||||
var cpCached = CpCacher.QueuedIds();
|
var cpCached = CpCacher.QueuedIds();
|
||||||
var plexMovies = Checker.GetPlexMovies();
|
var plexMovies = Checker.GetPlexMovies();
|
||||||
var settings = PrService.GetSettings();
|
var settings = await PrService.GetSettingsAsync();
|
||||||
var viewMovies = new List<SearchMovieViewModel>();
|
var viewMovies = new List<SearchMovieViewModel>();
|
||||||
foreach (MovieResult movie in apiMovies)
|
foreach (MovieResult movie in apiMovies)
|
||||||
{
|
{
|
||||||
|
@ -272,33 +271,20 @@ namespace PlexRequests.UI.Modules
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response SearchTvShow(string searchTerm)
|
private async Task<Response> SearchTvShow(string searchTerm)
|
||||||
{
|
{
|
||||||
Log.Trace("Searching for TV Show {0}", searchTerm);
|
Log.Trace("Searching for TV Show {0}", searchTerm);
|
||||||
|
|
||||||
var taskList = new List<Task>();
|
|
||||||
|
|
||||||
var apiTv = new List<TvMazeSearch>();
|
var apiTv = new List<TvMazeSearch>();
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
await Task.Factory.StartNew(() => new TvMazeApi().Search(searchTerm)).ContinueWith((t) =>
|
||||||
{
|
|
||||||
return new TvMazeApi().Search(searchTerm);
|
|
||||||
|
|
||||||
}).ContinueWith((t) =>
|
|
||||||
{
|
{
|
||||||
apiTv = t.Result;
|
apiTv = t.Result;
|
||||||
}));
|
});
|
||||||
|
|
||||||
var dbTv = new Dictionary<int, RequestedModel>();
|
var allResults = await RequestService.GetAllAsync();
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
allResults = allResults.Where(x => x.Type == RequestType.TvShow);
|
||||||
{
|
|
||||||
return RequestService.GetAll().Where(x => x.Type == RequestType.TvShow);
|
|
||||||
|
|
||||||
}).ContinueWith((t) =>
|
var dbTv = allResults.ToDictionary(x => x.ProviderId);
|
||||||
{
|
|
||||||
dbTv = t.Result.ToDictionary(x => x.ProviderId);
|
|
||||||
}));
|
|
||||||
|
|
||||||
Task.WaitAll(taskList.ToArray());
|
|
||||||
|
|
||||||
if (!apiTv.Any())
|
if (!apiTv.Any())
|
||||||
{
|
{
|
||||||
|
@ -361,31 +347,18 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(viewTv);
|
return Response.AsJson(viewTv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response SearchMusic(string searchTerm)
|
private async Task<Response> SearchMusic(string searchTerm)
|
||||||
{
|
{
|
||||||
var taskList = new List<Task>();
|
|
||||||
|
|
||||||
var apiAlbums = new List<Release>();
|
var apiAlbums = new List<Release>();
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
await Task.Run(() => MusicBrainzApi.SearchAlbum(searchTerm)).ContinueWith((t) =>
|
||||||
{
|
|
||||||
return MusicBrainzApi.SearchAlbum(searchTerm);
|
|
||||||
|
|
||||||
}).ContinueWith((t) =>
|
|
||||||
{
|
{
|
||||||
apiAlbums = t.Result.releases ?? new List<Release>();
|
apiAlbums = t.Result.releases ?? new List<Release>();
|
||||||
}));
|
});
|
||||||
|
|
||||||
var dbAlbum = new Dictionary<string, RequestedModel>();
|
var allResults = await RequestService.GetAllAsync();
|
||||||
taskList.Add(Task.Factory.StartNew(() =>
|
allResults = allResults.Where(x => x.Type == RequestType.Album);
|
||||||
{
|
|
||||||
return RequestService.GetAll().Where(x => x.Type == RequestType.Album);
|
|
||||||
|
|
||||||
}).ContinueWith((t) =>
|
var dbAlbum = allResults.ToDictionary(x => x.MusicBrainzId);
|
||||||
{
|
|
||||||
dbAlbum = t.Result.ToDictionary(x => x.MusicBrainzId);
|
|
||||||
}));
|
|
||||||
|
|
||||||
Task.WaitAll(taskList.ToArray());
|
|
||||||
|
|
||||||
var plexAlbums = Checker.GetPlexAlbums();
|
var plexAlbums = Checker.GetPlexAlbums();
|
||||||
|
|
||||||
|
@ -407,7 +380,7 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime release;
|
DateTime release;
|
||||||
DateTimeHelper.CustomParse(a.ReleaseEvents?.FirstOrDefault()?.date, out release);
|
DateTimeHelper.CustomParse(a.ReleaseEvents?.FirstOrDefault()?.date, out release);
|
||||||
var artist = a.ArtistCredit?.FirstOrDefault()?.artist;
|
var artist = a.ArtistCredit?.FirstOrDefault()?.artist;
|
||||||
if (Checker.IsAlbumAvailable(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist.name))
|
if (Checker.IsAlbumAvailable(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist?.name))
|
||||||
{
|
{
|
||||||
viewA.Available = true;
|
viewA.Available = true;
|
||||||
}
|
}
|
||||||
|
@ -425,27 +398,26 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(viewAlbum);
|
return Response.AsJson(viewAlbum);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response RequestMovie(int movieId)
|
private async Task<Response> RequestMovie(int movieId)
|
||||||
{
|
{
|
||||||
var movieApi = new TheMovieDbApi();
|
var movieApi = new TheMovieDbApi();
|
||||||
var movieInfo = movieApi.GetMovieInformation(movieId).Result;
|
var movieInfo = movieApi.GetMovieInformation(movieId).Result;
|
||||||
var fullMovieName = $"{movieInfo.Title}{(movieInfo.ReleaseDate.HasValue ? $" ({movieInfo.ReleaseDate.Value.Year})" : string.Empty)}";
|
var fullMovieName = $"{movieInfo.Title}{(movieInfo.ReleaseDate.HasValue ? $" ({movieInfo.ReleaseDate.Value.Year})" : string.Empty)}";
|
||||||
Log.Trace("Getting movie info from TheMovieDb");
|
Log.Trace("Getting movie info from TheMovieDb");
|
||||||
Log.Trace(movieInfo.DumpJson);
|
|
||||||
//#if !DEBUG
|
//#if !DEBUG
|
||||||
|
|
||||||
var settings = PrService.GetSettings();
|
var settings = await PrService.GetSettingsAsync();
|
||||||
|
|
||||||
// check if the movie has already been requested
|
// check if the movie has already been requested
|
||||||
Log.Info("Requesting movie with id {0}", movieId);
|
Log.Info("Requesting movie with id {0}", movieId);
|
||||||
var existingRequest = RequestService.CheckRequest(movieId);
|
var existingRequest = await RequestService.CheckRequestAsync(movieId);
|
||||||
if (existingRequest != null)
|
if (existingRequest != null)
|
||||||
{
|
{
|
||||||
// check if the current user is already marked as a requester for this movie, if not, add them
|
// check if the current user is already marked as a requester for this movie, if not, add them
|
||||||
if (!existingRequest.UserHasRequested(Username))
|
if (!existingRequest.UserHasRequested(Username))
|
||||||
{
|
{
|
||||||
existingRequest.RequestedUsers.Add(Username);
|
existingRequest.RequestedUsers.Add(Username);
|
||||||
RequestService.UpdateRequest(existingRequest);
|
await RequestService.UpdateRequestAsync(existingRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullMovieName} was successfully added!" : $"{fullMovieName} has already been requested!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullMovieName} was successfully added!" : $"{fullMovieName} has already been requested!" });
|
||||||
|
@ -461,8 +433,9 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullMovieName} is already in Plex!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullMovieName} is already in Plex!" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ApplicationSettingsException)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
Log.Error(e);
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"We could not check if {fullMovieName} is in Plex, are you sure it's correctly setup?" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"We could not check if {fullMovieName} is in Plex, are you sure it's correctly setup?" });
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
@ -473,7 +446,7 @@ namespace PlexRequests.UI.Modules
|
||||||
Type = RequestType.Movie,
|
Type = RequestType.Movie,
|
||||||
Overview = movieInfo.Overview,
|
Overview = movieInfo.Overview,
|
||||||
ImdbId = movieInfo.ImdbId,
|
ImdbId = movieInfo.ImdbId,
|
||||||
PosterPath = "http://image.tmdb.org/t/p/w150/" + movieInfo.PosterPath,
|
PosterPath = "https://image.tmdb.org/t/p/w150/" + movieInfo.PosterPath,
|
||||||
Title = movieInfo.Title,
|
Title = movieInfo.Title,
|
||||||
ReleaseDate = movieInfo.ReleaseDate ?? DateTime.MinValue,
|
ReleaseDate = movieInfo.ReleaseDate ?? DateTime.MinValue,
|
||||||
Status = movieInfo.Status,
|
Status = movieInfo.Status,
|
||||||
|
@ -484,13 +457,10 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Log.Trace(settings.DumpJson());
|
|
||||||
if (ShouldAutoApprove(RequestType.Movie, settings))
|
if (ShouldAutoApprove(RequestType.Movie, settings))
|
||||||
{
|
{
|
||||||
var cpSettings = CpService.GetSettings();
|
var cpSettings = await CpService.GetSettingsAsync();
|
||||||
|
|
||||||
Log.Trace("Settings: ");
|
|
||||||
Log.Trace(cpSettings.DumpJson);
|
|
||||||
if (cpSettings.Enabled)
|
if (cpSettings.Enabled)
|
||||||
{
|
{
|
||||||
Log.Info("Adding movie to CP (No approval required)");
|
Log.Info("Adding movie to CP (No approval required)");
|
||||||
|
@ -501,8 +471,7 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
model.Approved = true;
|
model.Approved = true;
|
||||||
Log.Info("Adding movie to database (No approval required)");
|
Log.Info("Adding movie to database (No approval required)");
|
||||||
RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
|
|
||||||
|
|
||||||
if (ShouldSendNotification())
|
if (ShouldSendNotification())
|
||||||
{
|
{
|
||||||
|
@ -513,7 +482,7 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
NotificationType = NotificationType.NewRequest
|
NotificationType = NotificationType.NewRequest
|
||||||
};
|
};
|
||||||
NotificationService.Publish(notificationModel);
|
await NotificationService.Publish(notificationModel);
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" });
|
||||||
}
|
}
|
||||||
|
@ -529,7 +498,7 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
model.Approved = true;
|
model.Approved = true;
|
||||||
Log.Info("Adding movie to database (No approval required)");
|
Log.Info("Adding movie to database (No approval required)");
|
||||||
RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
|
|
||||||
if (ShouldSendNotification())
|
if (ShouldSendNotification())
|
||||||
{
|
{
|
||||||
|
@ -540,7 +509,7 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
NotificationType = NotificationType.NewRequest
|
NotificationType = NotificationType.NewRequest
|
||||||
};
|
};
|
||||||
NotificationService.Publish(notificationModel);
|
await NotificationService.Publish(notificationModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" });
|
||||||
|
@ -550,10 +519,10 @@ namespace PlexRequests.UI.Modules
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.Info("Adding movie to database");
|
Log.Info("Adding movie to database");
|
||||||
var id = RequestService.AddRequest(model);
|
var id = await RequestService.AddRequestAsync(model);
|
||||||
|
|
||||||
var notificationModel = new NotificationModel { Title = model.Title, User = Username, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest };
|
var notificationModel = new NotificationModel { Title = model.Title, User = Username, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest };
|
||||||
NotificationService.Publish(notificationModel);
|
await NotificationService.Publish(notificationModel);
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" });
|
||||||
}
|
}
|
||||||
|
@ -570,9 +539,8 @@ namespace PlexRequests.UI.Modules
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="showId">The show identifier.</param>
|
/// <param name="showId">The show identifier.</param>
|
||||||
/// <param name="seasons">The seasons.</param>
|
/// <param name="seasons">The seasons.</param>
|
||||||
/// <param name="notify">if set to <c>true</c> [notify].</param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private Response RequestTvShow(int showId, string seasons)
|
private async Task<Response> RequestTvShow(int showId, string seasons)
|
||||||
{
|
{
|
||||||
var tvApi = new TvMazeApi();
|
var tvApi = new TvMazeApi();
|
||||||
|
|
||||||
|
@ -582,18 +550,18 @@ namespace PlexRequests.UI.Modules
|
||||||
string fullShowName = $"{showInfo.name} ({firstAir.Year})";
|
string fullShowName = $"{showInfo.name} ({firstAir.Year})";
|
||||||
//#if !DEBUG
|
//#if !DEBUG
|
||||||
|
|
||||||
var settings = PrService.GetSettings();
|
var settings = await PrService.GetSettingsAsync();
|
||||||
|
|
||||||
// check if the show has already been requested
|
// check if the show has already been requested
|
||||||
Log.Info("Requesting tv show with id {0}", showId);
|
Log.Info("Requesting tv show with id {0}", showId);
|
||||||
var existingRequest = RequestService.CheckRequest(showId);
|
var existingRequest = await RequestService.CheckRequestAsync(showId);
|
||||||
if (existingRequest != null)
|
if (existingRequest != null)
|
||||||
{
|
{
|
||||||
// check if the current user is already marked as a requester for this show, if not, add them
|
// check if the current user is already marked as a requester for this show, if not, add them
|
||||||
if (!existingRequest.UserHasRequested(Username))
|
if (!existingRequest.UserHasRequested(Username))
|
||||||
{
|
{
|
||||||
existingRequest.RequestedUsers.Add(Username);
|
existingRequest.RequestedUsers.Add(Username);
|
||||||
RequestService.UpdateRequest(existingRequest);
|
await RequestService.UpdateRequestAsync(existingRequest);
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullShowName} was successfully added!" : $"{fullShowName} has already been requested!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullShowName} was successfully added!" : $"{fullShowName} has already been requested!" });
|
||||||
}
|
}
|
||||||
|
@ -606,7 +574,7 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} is already in Plex!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} is already in Plex!" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ApplicationSettingsException)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"We could not check if {fullShowName} is in Plex, are you sure it's correctly setup?" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"We could not check if {fullShowName} is in Plex, are you sure it's correctly setup?" });
|
||||||
}
|
}
|
||||||
|
@ -627,7 +595,7 @@ namespace PlexRequests.UI.Modules
|
||||||
RequestedUsers = new List<string> { Username },
|
RequestedUsers = new List<string> { Username },
|
||||||
Issues = IssueState.None,
|
Issues = IssueState.None,
|
||||||
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
||||||
SeasonCount = showInfo.seasonCount
|
SeasonCount = showInfo.seasonCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
var seasonsList = new List<int>();
|
var seasonsList = new List<int>();
|
||||||
|
@ -645,6 +613,7 @@ namespace PlexRequests.UI.Modules
|
||||||
model.SeasonsRequested = "All";
|
model.SeasonsRequested = "All";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
model.SeasonsRequested = seasons;
|
||||||
var split = seasons.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
var split = seasons.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
var seasonsCount = new int[split.Length];
|
var seasonsCount = new int[split.Length];
|
||||||
for (var i = 0; i < split.Length; i++)
|
for (var i = 0; i < split.Length; i++)
|
||||||
|
@ -661,16 +630,16 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
if (ShouldAutoApprove(RequestType.TvShow, settings))
|
if (ShouldAutoApprove(RequestType.TvShow, settings))
|
||||||
{
|
{
|
||||||
var sonarrSettings = SonarrService.GetSettings();
|
var sonarrSettings = await SonarrService.GetSettingsAsync();
|
||||||
var sender = new TvSender(SonarrApi, SickrageApi);
|
var sender = new TvSender(SonarrApi, SickrageApi);
|
||||||
if (sonarrSettings.Enabled)
|
if (sonarrSettings.Enabled)
|
||||||
{
|
{
|
||||||
var result = sender.SendToSonarr(sonarrSettings, model);
|
var result = sender.SendToSonarr(sonarrSettings, model);
|
||||||
if (result != null && !string.IsNullOrEmpty(result.title))
|
if (!string.IsNullOrEmpty(result?.title))
|
||||||
{
|
{
|
||||||
model.Approved = true;
|
model.Approved = true;
|
||||||
Log.Debug("Adding tv to database requests (No approval required & Sonarr)");
|
Log.Debug("Adding tv to database requests (No approval required & Sonarr)");
|
||||||
RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
|
|
||||||
if (ShouldSendNotification())
|
if (ShouldSendNotification())
|
||||||
{
|
{
|
||||||
|
@ -681,7 +650,7 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
NotificationType = NotificationType.NewRequest
|
NotificationType = NotificationType.NewRequest
|
||||||
};
|
};
|
||||||
NotificationService.Publish(notify1);
|
await NotificationService.Publish(notify1);
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
||||||
}
|
}
|
||||||
|
@ -699,7 +668,7 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
model.Approved = true;
|
model.Approved = true;
|
||||||
Log.Debug("Adding tv to database requests (No approval required & SickRage)");
|
Log.Debug("Adding tv to database requests (No approval required & SickRage)");
|
||||||
RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
if (ShouldSendNotification())
|
if (ShouldSendNotification())
|
||||||
{
|
{
|
||||||
var notify2 = new NotificationModel
|
var notify2 = new NotificationModel
|
||||||
|
@ -709,7 +678,7 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
NotificationType = NotificationType.NewRequest
|
NotificationType = NotificationType.NewRequest
|
||||||
};
|
};
|
||||||
NotificationService.Publish(notify2);
|
await NotificationService.Publish(notify2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
||||||
|
@ -717,14 +686,33 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Something went wrong adding the movie to SickRage! Please check your settings." });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Something went wrong adding the movie to SickRage! Please check your settings." });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!srSettings.Enabled && !sonarrSettings.Enabled)
|
||||||
|
{
|
||||||
|
model.Approved = true;
|
||||||
|
Log.Debug("Adding tv to database requests (No approval required) and Sonarr/Sickrage not setup");
|
||||||
|
await RequestService.AddRequestAsync(model);
|
||||||
|
if (ShouldSendNotification())
|
||||||
|
{
|
||||||
|
var notify2 = new NotificationModel
|
||||||
|
{
|
||||||
|
Title = model.Title,
|
||||||
|
User = Username,
|
||||||
|
DateTime = DateTime.Now,
|
||||||
|
NotificationType = NotificationType.NewRequest
|
||||||
|
};
|
||||||
|
await NotificationService.Publish(notify2);
|
||||||
|
}
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
||||||
|
}
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "The request of TV Shows is not correctly set up. Please contact your admin." });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "The request of TV Shows is not correctly set up. Please contact your admin." });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
|
|
||||||
var notificationModel = new NotificationModel { Title = model.Title, User = Username, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest };
|
var notificationModel = new NotificationModel { Title = model.Title, User = Username, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest };
|
||||||
NotificationService.Publish(notificationModel);
|
await NotificationService.Publish(notificationModel);
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
||||||
}
|
}
|
||||||
|
@ -735,7 +723,8 @@ namespace PlexRequests.UI.Modules
|
||||||
var claims = Context.CurrentUser?.Claims;
|
var claims = Context.CurrentUser?.Claims;
|
||||||
if (claims != null)
|
if (claims != null)
|
||||||
{
|
{
|
||||||
if (claims.Contains(UserClaims.Admin) || claims.Contains(UserClaims.PowerUser))
|
var enumerable = claims as string[] ?? claims.ToArray();
|
||||||
|
if (enumerable.Contains(UserClaims.Admin) || enumerable.Contains(UserClaims.PowerUser))
|
||||||
{
|
{
|
||||||
sendNotification = false; // Don't bother sending a notification if the user is an admin
|
sendNotification = false; // Don't bother sending a notification if the user is an admin
|
||||||
}
|
}
|
||||||
|
@ -744,10 +733,10 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Response RequestAlbum(string releaseId)
|
private async Task<Response> RequestAlbum(string releaseId)
|
||||||
{
|
{
|
||||||
var settings = PrService.GetSettings();
|
var settings = await PrService.GetSettingsAsync();
|
||||||
var existingRequest = RequestService.CheckRequest(releaseId);
|
var existingRequest = await RequestService.CheckRequestAsync(releaseId);
|
||||||
Log.Debug("Checking for an existing request");
|
Log.Debug("Checking for an existing request");
|
||||||
|
|
||||||
if (existingRequest != null)
|
if (existingRequest != null)
|
||||||
|
@ -758,12 +747,11 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
Log.Debug("Not in the requested list so adding them and updating the request. User: {0}", Username);
|
Log.Debug("Not in the requested list so adding them and updating the request. User: {0}", Username);
|
||||||
existingRequest.RequestedUsers.Add(Username);
|
existingRequest.RequestedUsers.Add(Username);
|
||||||
RequestService.UpdateRequest(existingRequest);
|
await RequestService.UpdateRequestAsync(existingRequest);
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{existingRequest.Title} was successfully added!" : $"{existingRequest.Title} has already been requested!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{existingRequest.Title} was successfully added!" : $"{existingRequest.Title} has already been requested!" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Log.Debug("This is a new request");
|
Log.Debug("This is a new request");
|
||||||
|
|
||||||
var albumInfo = MusicBrainzApi.GetAlbum(releaseId);
|
var albumInfo = MusicBrainzApi.GetAlbum(releaseId);
|
||||||
|
@ -823,7 +811,7 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
if (!hpSettings.Enabled)
|
if (!hpSettings.Enabled)
|
||||||
{
|
{
|
||||||
RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
return
|
return
|
||||||
Response.AsJson(new JsonResponseModel
|
Response.AsJson(new JsonResponseModel
|
||||||
{
|
{
|
||||||
|
@ -833,9 +821,9 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService);
|
var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService);
|
||||||
sender.AddAlbum(model).Wait();
|
await sender.AddAlbum(model);
|
||||||
model.Approved = true;
|
model.Approved = true;
|
||||||
RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
|
|
||||||
if (ShouldSendNotification())
|
if (ShouldSendNotification())
|
||||||
{
|
{
|
||||||
|
@ -846,7 +834,7 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
NotificationType = NotificationType.NewRequest
|
NotificationType = NotificationType.NewRequest
|
||||||
};
|
};
|
||||||
NotificationService.Publish(notify2);
|
await NotificationService.Publish(notify2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -866,9 +854,9 @@ namespace PlexRequests.UI.Modules
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
NotificationType = NotificationType.NewRequest
|
NotificationType = NotificationType.NewRequest
|
||||||
};
|
};
|
||||||
NotificationService.Publish(notify2);
|
await NotificationService.Publish(notify2);
|
||||||
}
|
}
|
||||||
var result = RequestService.AddRequest(model);
|
await RequestService.AddRequestAsync(model);
|
||||||
return Response.AsJson(new JsonResponseModel
|
return Response.AsJson(new JsonResponseModel
|
||||||
{
|
{
|
||||||
Result = true,
|
Result = true,
|
||||||
|
@ -909,20 +897,22 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response NotifyUser(bool notify)
|
private async Task<Response> NotifyUser(bool notify)
|
||||||
{
|
{
|
||||||
var auth = Auth.GetSettings().UserAuthentication;
|
var authSettings = await Auth.GetSettingsAsync();
|
||||||
var email = EmailNotificationSettings.GetSettings().EnableUserEmailNotifications;
|
var auth = authSettings.UserAuthentication;
|
||||||
|
var emailSettings = await EmailNotificationSettings.GetSettingsAsync();
|
||||||
|
var email = emailSettings.EnableUserEmailNotifications;
|
||||||
if (!auth)
|
if (!auth)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sorry, but this functionality is currently only for users with Plex accounts"});
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sorry, but this functionality is currently only for users with Plex accounts" });
|
||||||
}
|
}
|
||||||
if (!email)
|
if (!email)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sorry, but your administrator has not yet enabled this functionality." });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sorry, but your administrator has not yet enabled this functionality." });
|
||||||
}
|
}
|
||||||
var username = Username;
|
var username = Username;
|
||||||
var originalList = UsersToNotifyRepo.GetAll();
|
var originalList = await UsersToNotifyRepo.GetAllAsync();
|
||||||
if (!notify)
|
if (!notify)
|
||||||
{
|
{
|
||||||
if (originalList == null)
|
if (originalList == null)
|
||||||
|
@ -932,7 +922,7 @@ namespace PlexRequests.UI.Modules
|
||||||
var userToRemove = originalList.FirstOrDefault(x => x.Username == username);
|
var userToRemove = originalList.FirstOrDefault(x => x.Username == username);
|
||||||
if (userToRemove != null)
|
if (userToRemove != null)
|
||||||
{
|
{
|
||||||
UsersToNotifyRepo.Delete(userToRemove);
|
await UsersToNotifyRepo.DeleteAsync(userToRemove);
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||||
}
|
}
|
||||||
|
@ -941,7 +931,7 @@ namespace PlexRequests.UI.Modules
|
||||||
if (originalList == null)
|
if (originalList == null)
|
||||||
{
|
{
|
||||||
var userModel = new UsersToNotify { Username = username };
|
var userModel = new UsersToNotify { Username = username };
|
||||||
var insertResult = UsersToNotifyRepo.Insert(userModel);
|
var insertResult = await UsersToNotifyRepo.InsertAsync(userModel);
|
||||||
return Response.AsJson(insertResult != -1 ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not save, please try again" });
|
return Response.AsJson(insertResult != -1 ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not save, please try again" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,15 +943,16 @@ namespace PlexRequests.UI.Modules
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var userModel = new UsersToNotify { Username = username };
|
var userModel = new UsersToNotify { Username = username };
|
||||||
var insertResult = UsersToNotifyRepo.Insert(userModel);
|
var insertResult = await UsersToNotifyRepo.InsertAsync(userModel);
|
||||||
return Response.AsJson(insertResult != -1 ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not save, please try again" });
|
return Response.AsJson(insertResult != -1 ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not save, please try again" });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
private Response GetUserNotificationSettings()
|
private async Task<Response> GetUserNotificationSettings()
|
||||||
{
|
{
|
||||||
var retval = UsersToNotifyRepo.GetAll().FirstOrDefault(x => x.Username == Username);
|
var all = await UsersToNotifyRepo.GetAllAsync();
|
||||||
return Response.AsJson(retval != null);
|
var retVal = all.FirstOrDefault(x => x.Username == Username);
|
||||||
|
return Response.AsJson(retVal != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response GetSeasons()
|
private Response GetSeasons()
|
||||||
|
|
|
@ -46,24 +46,24 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(users);
|
return Response.AsJson(users);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response CreateUser(string username, string password, string claims)
|
//private Response CreateUser(string username, string password, string claims)
|
||||||
{
|
//{
|
||||||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
// if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||||
{
|
// {
|
||||||
return Response.AsJson(new JsonResponseModel
|
// return Response.AsJson(new JsonResponseModel
|
||||||
{
|
// {
|
||||||
Result = true,
|
// Result = true,
|
||||||
Message = "Please enter in a valid Username and Password"
|
// Message = "Please enter in a valid Username and Password"
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
var user = UserMapper.CreateUser(username, password, new string[] {claims});
|
// var user = UserMapper.CreateUser(username, password, new string[] {claims});
|
||||||
if (user.HasValue)
|
// if (user.HasValue)
|
||||||
{
|
// {
|
||||||
return Response.AsJson(new JsonResponseModel {Result = true});
|
// return Response.AsJson(new JsonResponseModel {Result = true});
|
||||||
}
|
// }
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel {Result = false, Message = "Could not save user"});
|
// return Response.AsJson(new JsonResponseModel {Result = false, Message = "Could not save user"});
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,15 @@
|
||||||
<Content Include="Content\bootstrap-notify.min.js">
|
<Content Include="Content\bootstrap-notify.min.js">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Themes\OriginalBootstrap.css">
|
<Content Include="Content\base.css">
|
||||||
|
<DependentUpon>base.scss</DependentUpon>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Content\base.min.css">
|
||||||
|
<DependentUpon>base.css</DependentUpon>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Content\bootstrap.css">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Compile Include="Models\JsonResponseModel.cs" />
|
<Compile Include="Models\JsonResponseModel.cs" />
|
||||||
|
@ -286,22 +294,21 @@
|
||||||
<Content Include="Content\swagger\underscore-min.js">
|
<Content Include="Content\swagger\underscore-min.js">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Themes\OriginalBootstrapCustom.css">
|
<Content Include="Content\Themes\original.css">
|
||||||
<DependentUpon>OriginalBootstrapCustom.scss</DependentUpon>
|
<DependentUpon>original.scss</DependentUpon>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Themes\OriginalBootstrapCustom.min.css">
|
<Content Include="Content\Themes\original.min.css">
|
||||||
<DependentUpon>OriginalBootstrapCustom.css</DependentUpon>
|
<DependentUpon>original.css</DependentUpon>
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Themes\PlexBootstrap.css">
|
<Content Include="Content\Themes\plex.css">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<DependentUpon>plex.scss</DependentUpon>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Themes\PlexBootstrapCustom.css">
|
<Content Include="Content\Themes\plex.min.css">
|
||||||
<DependentUpon>PlexBootstrapCustom.scss</DependentUpon>
|
<DependentUpon>plex.css</DependentUpon>
|
||||||
</Content>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<Content Include="Content\Themes\PlexBootstrapCustom.min.css">
|
|
||||||
<DependentUpon>PlexBootstrapCustom.css</DependentUpon>
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Views\ApiDocs\index.html">
|
<Content Include="Views\ApiDocs\index.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
@ -387,8 +394,9 @@
|
||||||
<None Include="Content\awesome-bootstrap-checkbox.scss">
|
<None Include="Content\awesome-bootstrap-checkbox.scss">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="Content\Themes\PlexBootstrapCustom.scss" />
|
<None Include="Content\base.scss" />
|
||||||
<None Include="Content\Themes\OriginalBootstrapCustom.scss" />
|
<None Include="Content\Themes\original.scss" />
|
||||||
|
<None Include="Content\Themes\plex.scss" />
|
||||||
<Content Include="Content\pace.min.js">
|
<Content Include="Content\pace.min.js">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
<p class="form-group">Current users that are allowed to authenticate: </p>
|
<p class="form-group">Current users that are allowed to authenticate: </p>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<select id="users" multiple="" class="form-control-custom "></select>
|
<select id="users" multiple="" class="form-control-custom" style="height: 180px;"></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@
|
||||||
$('#users').append("<option>Error!</option>");
|
$('#users').append("<option>Error!</option>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (response.users.length > 1) {
|
if (response.users.length > 0) {
|
||||||
$(response.users).each(function () {
|
$(response.users).each(function () {
|
||||||
$('#users').append("<option>" + this + "</option>");
|
$('#users').append("<option>" + this + "</option>");
|
||||||
});
|
});
|
||||||
|
|
|
@ -54,10 +54,10 @@
|
||||||
var dots = new Array(count % 10).join('.');
|
var dots = new Array(count % 10).join('.');
|
||||||
document.getElementById('autoUpdate').innerHTML = "Updating" + dots;
|
document.getElementById('autoUpdate').innerHTML = "Updating" + dots;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
var url = createBaseUrl(base, "autoupdate");
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "Post",
|
type: "Post",
|
||||||
url: url,
|
url: "autoupdate",
|
||||||
data: { url: "@Model.DownloadUri" },
|
data: { url: "@Model.DownloadUri" },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
error: function () {
|
error: function () {
|
||||||
|
|
|
@ -35,19 +35,22 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group btn-group-separated">
|
||||||
@if (Context.CurrentUser.IsAuthenticated()) //TODO replace with IsAdmin
|
@if (Context.CurrentUser.IsAuthenticated()) //TODO replace with IsAdmin
|
||||||
{
|
{
|
||||||
@if (Model.SearchForMovies)
|
@if (Model.SearchForMovies)
|
||||||
{
|
{
|
||||||
|
<button id="deleteMovies" class="btn btn-warning-outline delete-category" type="submit"><i class="fa fa-trash"></i> Delete Movies</button>
|
||||||
<button id="approveMovies" class="btn btn-success-outline approve-category" type="submit"><i class="fa fa-plus"></i> Approve Movies</button>
|
<button id="approveMovies" class="btn btn-success-outline approve-category" type="submit"><i class="fa fa-plus"></i> Approve Movies</button>
|
||||||
}
|
}
|
||||||
@if (Model.SearchForTvShows)
|
@if (Model.SearchForTvShows)
|
||||||
{
|
{
|
||||||
|
<button id="deleteTVShows" class="btn btn-warning-outline delete-category" type="submit" style="display: none;"><i class="fa fa-trash"></i> Delete TV Shows</button>
|
||||||
<button id="approveTVShows" class="btn btn-success-outline approve-category" type="submit" style="display: none;"><i class="fa fa-plus"></i> Approve TV Shows</button>
|
<button id="approveTVShows" class="btn btn-success-outline approve-category" type="submit" style="display: none;"><i class="fa fa-plus"></i> Approve TV Shows</button>
|
||||||
}
|
}
|
||||||
@if (Model.SearchForMusic)
|
@if (Model.SearchForMusic)
|
||||||
{
|
{
|
||||||
|
<button id="deleteMusics" class="btn btn-warning-outline delete-category" type="submit" style="display: none;"><i class="fa fa-trash"></i> Delete Music</button>
|
||||||
<button id="approveMusic" class="btn btn-success-outline approve-category" type="submit" style="display: none;"><i class="fa fa-plus"></i> Approve Music</button>
|
<button id="approveMusic" class="btn btn-success-outline approve-category" type="submit" style="display: none;"><i class="fa fa-plus"></i> Approve Music</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +135,7 @@
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
{{#if_eq type "movie"}}
|
{{#if_eq type "movie"}}
|
||||||
{{#if posterPath}}
|
{{#if posterPath}}
|
||||||
<img class="img-responsive" src="http://image.tmdb.org/t/p/w150/{{posterPath}}" alt="poster">
|
<img class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{posterPath}}" alt="poster">
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
{{#if_eq type "tv"}}
|
{{#if_eq type "tv"}}
|
||||||
|
@ -169,7 +172,7 @@
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
</div>
|
</div>
|
||||||
{{#if_eq type "tv"}}
|
{{#if_eq type "tv"}}
|
||||||
<div>Series Requested: {{seriesRequested}}</div>
|
<div>Seasons Requested: {{seriesRequested}}</div>
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
{{#if requestedUsers}}
|
{{#if requestedUsers}}
|
||||||
<div>Requested By: {{requestedUsers}}</div>
|
<div>Requested By: {{requestedUsers}}</div>
|
||||||
|
|
|
@ -144,7 +144,7 @@
|
||||||
|
|
||||||
{{#if_eq type "movie"}}
|
{{#if_eq type "movie"}}
|
||||||
{{#if posterPath}}
|
{{#if posterPath}}
|
||||||
<img class="img-responsive" src="http://image.tmdb.org/t/p/w150/{{posterPath}}" alt="poster">
|
<img class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{posterPath}}" alt="poster">
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
{{#if_eq type "tv"}}
|
{{#if_eq type "tv"}}
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
[
|
[
|
||||||
{
|
|
||||||
"outputFile": "Content/custom.css",
|
|
||||||
"inputFile": "Content/custom.scss"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"outputFile": "Content/pace.css",
|
"outputFile": "Content/pace.css",
|
||||||
"inputFile": "Content/pace.scss"
|
"inputFile": "Content/pace.scss"
|
||||||
|
@ -18,5 +14,17 @@
|
||||||
{
|
{
|
||||||
"outputFile": "Content/Themes/PlexBootstrapCustom.css",
|
"outputFile": "Content/Themes/PlexBootstrapCustom.css",
|
||||||
"inputFile": "Content/Themes/PlexBootstrapCustom.scss"
|
"inputFile": "Content/Themes/PlexBootstrapCustom.scss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"outputFile": "Content/base.css",
|
||||||
|
"inputFile": "Content/base.scss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"outputFile": "Content/Themes/plex.css",
|
||||||
|
"inputFile": "Content/Themes/plex.scss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"outputFile": "Content/Themes/original.css",
|
||||||
|
"inputFile": "Content/Themes/original.scss"
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.25123.0
|
VisualStudioVersion = 14.0.25123.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.UI", "PlexRequests.UI\PlexRequests.UI.csproj", "{68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.UI", "PlexRequests.UI\PlexRequests.UI.csproj", "{68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}"
|
||||||
|
@ -35,20 +35,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.Services.Tests
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.Updater", "PlexRequests.Updater\PlexRequests.Updater.csproj", "{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.Updater", "PlexRequests.Updater\PlexRequests.Updater.csproj", "{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.Helpers.Tests", "PlexRequests.Helpers.Tests\PlexRequests.Helpers.Tests.csproj", "{0E6395D3-B074-49E8-898D-0EB99E507E0E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{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
|
|
||||||
{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
|
|
||||||
{68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{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}.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.ActiveCfg = Release|Any CPU
|
||||||
|
@ -57,26 +51,38 @@ Global
|
||||||
{8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8CB8D235-2674-442D-9C6A-35FCAEEB160D}.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
|
|
||||||
{95834072-A675-415D-AA8F-877C91623810}.Debug|Any CPU.ActiveCfg = Debug|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}.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.ActiveCfg = Release|Any CPU
|
||||||
{95834072-A675-415D-AA8F-877C91623810}.Release|Any CPU.Build.0 = Release|Any CPU
|
{95834072-A675-415D-AA8F-877C91623810}.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
|
|
||||||
{A930E2CF-79E2-45F9-B06A-9A719A254CE4}.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
|
|
||||||
{DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.ActiveCfg = Debug|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}.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.ActiveCfg = Release|Any CPU
|
||||||
{DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.Build.0 = 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
|
||||||
|
{A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Release|Any CPU.Build.0 = 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
|
||||||
|
{FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU
|
||||||
{EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Debug|Any CPU.Build.0 = 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
|
{EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
@ -85,12 +91,10 @@ Global
|
||||||
{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{0E6395D3-B074-49E8-898D-0EB99E507E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.Build.0 = Release|Any CPU
|
{0E6395D3-B074-49E8-898D-0EB99E507E0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -3,9 +3,9 @@ configuration: Release
|
||||||
assembly_info:
|
assembly_info:
|
||||||
patch: true
|
patch: true
|
||||||
file: '**\AssemblyInfo.*'
|
file: '**\AssemblyInfo.*'
|
||||||
assembly_version: '1.7.4'
|
assembly_version: '1.7.5'
|
||||||
assembly_file_version: '{version}'
|
assembly_file_version: '{version}'
|
||||||
assembly_informational_version: '1.7.4'
|
assembly_informational_version: '1.7.5'
|
||||||
before_build:
|
before_build:
|
||||||
- cmd: appveyor-retry nuget restore
|
- cmd: appveyor-retry nuget restore
|
||||||
build:
|
build:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue