Merge pull request #1204 from tidusjar/dev

Dev
pull/1225/head
Jamie 8 years ago committed by GitHub
commit 83ee6427d8

@ -8,7 +8,7 @@ namespace Ombi.Api.Interfaces
public interface IRadarrApi
{
RadarrAddMovie AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath, string apiKey, Uri baseUrl, bool searchNow = false);
List<RadarrMovieResponse> GetMovies(string apiKey, Uri baseUrl);
RadarrMovieContainer GetMovies(string apiKey, Uri baseUrl);
List<SonarrProfile> GetProfiles(string apiKey, Uri baseUrl);
SystemStatus SystemStatus(string apiKey, Uri baseUrl);
List<SonarrRootFolder> GetRootFolders(string apiKey, Uri baseUrl);

@ -112,6 +112,7 @@
<Compile Include="Radarr\RadarrAddMovie.cs" />
<Compile Include="Radarr\RadarrAddOptions.cs" />
<Compile Include="Radarr\RadarrError.cs" />
<Compile Include="Radarr\RadarrMovieContainer.cs" />
<Compile Include="Radarr\RadarrMovieResponse.cs" />
<Compile Include="SickRage\SickRageBase.cs" />
<Compile Include="SickRage\SickrageShows.cs" />

@ -0,0 +1,41 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: RadarrMovieContainer.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System.Collections.Generic;
namespace Ombi.Api.Models.Radarr
{
public class RadarrMovieContainer
{
public int page { get; set; }
public int pageSize { get; set; }
public string sortKey { get; set; }
public string sortDirection { get; set; }
public int totalRecords { get; set; }
public List<RadarrMovieResponse> records { get; set; }
}
}

@ -15,7 +15,7 @@ namespace Ombi.Api.Models.Tv
public string language { get; set; }
public List<string> genres { get; set; }
public string status { get; set; }
public int runtime { get; set; }
public double runtime { get; set; }
public string premiered { get; set; }
public Schedule schedule { get; set; }
public Rating rating { get; set; }

@ -152,7 +152,7 @@ namespace Ombi.Api
}
public List<RadarrMovieResponse> GetMovies(string apiKey, Uri baseUrl)
public RadarrMovieContainer GetMovies(string apiKey, Uri baseUrl)
{
var request = new RestRequest { Resource = "/api/movie", Method = Method.GET };
request.AddHeader("X-Api-Key", apiKey);
@ -165,7 +165,7 @@ namespace Ombi.Api
var obj = policy.Execute(() => Api.Execute(request, baseUrl));
return JsonConvert.DeserializeObject<List<RadarrMovieResponse>>(obj.Content);
return JsonConvert.DeserializeObject<RadarrMovieContainer>(obj.Content);
}
}
}

@ -8,5 +8,6 @@ namespace Ombi.Core.Users
IEnumerable<UserHelperModel> GetUsers();
IEnumerable<UserHelperModel> GetUsersWithPermission(Permissions permission);
IEnumerable<UserHelperModel> GetUsersWithFeature(Features feature);
UserHelperModel GetUser(string username);
}
}

@ -51,6 +51,49 @@ namespace Ombi.Core.Users
private ISecurityExtensions Security { get; }
private IExternalUserRepository<EmbyUsers> EmbyUserRepository { get; }
public UserHelperModel GetUser(string username)
{
var localUsers = LocalUserRepository.GetUserByUsername(username);
if (localUsers != null)
{
var props = ByteConverterHelper.ReturnObject<UserProperties>(localUsers.UserProperties);
return new UserHelperModel
{
Type = UserType.LocalUser,
Username = localUsers.UserName,
UserAlias = props.UserAlias,
EmailAddress = props.EmailAddress,
Permissions = (Permissions) localUsers.Permissions
};
}
var plexUsers = PlexUserRepository.GetUserByUsername(username);
if (plexUsers != null)
{
return new UserHelperModel
{
Type = UserType.PlexUser,
Username = plexUsers.Username,
UserAlias = plexUsers.UserAlias,
EmailAddress = plexUsers.EmailAddress,
Permissions = (Permissions)plexUsers.Permissions
};
}
var embyUsers = EmbyUserRepository.GetUserByUsername(username);
if (embyUsers != null)
{
return new UserHelperModel
{
Type = UserType.EmbyUser,
Username = embyUsers.Username,
UserAlias = embyUsers.UserAlias,
EmailAddress = embyUsers.EmailAddress,
Permissions = (Permissions)embyUsers.Permissions
};
}
return null;
}
public IEnumerable<UserHelperModel> GetUsers()
{

@ -35,6 +35,10 @@ namespace Ombi.Helpers
{
public static string CalcuateMd5Hash(string input)
{
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}
using (var md5 = MD5.Create())
{
var inputBytes = Encoding.UTF8.GetBytes(input);

@ -264,7 +264,7 @@ namespace Ombi.Services.Jobs
return media;
});
if (item == null)
if (item == null && !string.IsNullOrEmpty(m.ItemId))
{
// Doesn't exist, insert it
PlexContent.Insert(new PlexContent
@ -305,7 +305,7 @@ namespace Ombi.Services.Jobs
return media;
});
if (item == null)
if (item == null && !string.IsNullOrEmpty(t.ItemId))
{
PlexContent.Insert(new PlexContent
{

@ -67,12 +67,16 @@ namespace Ombi.Services.Jobs
if (movies != null)
{
var movieIds = new List<int>();
foreach (var m in movies)
foreach (var m in movies.records)
{
if (m.tmdbId > 0)
{
movieIds.Add(m.tmdbId);
}
else
{
Log.Error("TMDBId is not > 0 for movie {0}", m.title);
}
}
//var movieIds = movies.Select(x => x.tmdbId).ToList();
Cache.Set(CacheKeys.RadarrMovies, movieIds, CacheKeys.TimeFrameMinutes.SchedulerCaching);

@ -544,3 +544,13 @@ label {
width: 100%;
height: 5px; }
.navbar-brand {
float: left;
padding: 4.5px 15px;
font-size: 19px;
line-height: 21px;
height: 40px; }
.gravatar {
border-radius: 1em; }

File diff suppressed because one or more lines are too long

@ -673,4 +673,16 @@ $border-radius: 10px;
right: 100%;
width: 100%;
height: 5px;
}
}
.navbar-brand {
float: left;
padding: 4.5px 15px;
font-size: 19px;
line-height: 21px;
height: 40px;
}
.gravatar{
border-radius:1em;
}

@ -29,10 +29,12 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using Nancy;
using Nancy.Responses;
using NLog;
using Ombi.Core;
using Ombi.Core.SettingModels;
using Ombi.Core.StatusChecker;
using Ombi.Core.Users;
using Ombi.Helpers;
using Ombi.Services.Interfaces;
using Ombi.Services.Jobs;
@ -43,14 +45,16 @@ namespace Ombi.UI.Modules
{
public class LayoutModule : BaseAuthModule
{
public LayoutModule(ICacheProvider provider, ISettingsService<PlexRequestSettings> pr, ISettingsService<SystemSettings> settings, IJobRecord rec, ISecurityExtensions security) : base("layout", pr, security)
public LayoutModule(ICacheProvider provider, ISettingsService<PlexRequestSettings> pr, ISettingsService<SystemSettings> settings, IJobRecord rec, ISecurityExtensions security, IUserHelper helper) : base("layout", pr, security)
{
Cache = provider;
SystemSettings = settings;
Job = rec;
UserHelper = helper;
Get["/", true] = async (x,ct) => await CheckLatestVersion();
Get["/cacher", true] = async (x,ct) => await CacherRunning();
Get["/gravatar"] = x => GetGravatarImage();
}
private ICacheProvider Cache { get; }
@ -58,6 +62,7 @@ namespace Ombi.UI.Modules
private static Logger Log = LogManager.GetCurrentClassLogger();
private ISettingsService<SystemSettings> SystemSettings { get; }
private IJobRecord Job { get; }
private IUserHelper UserHelper { get; }
private async Task<Response> CheckLatestVersion()
{
@ -116,5 +121,31 @@ namespace Ombi.UI.Modules
return Response.AsJson(new { CurrentlyRunning = false, IsAdmin });
}
}
private Response GetGravatarImage()
{
if (LoggedIn)
{
var user = UserHelper.GetUser(Username);
var hashed = StringHasher.CalcuateMd5Hash(user.EmailAddress);
if (string.IsNullOrEmpty(hashed))
{
return Response.AsJson(new JsonResponseModel
{
Result = false
});
}
return
Response.AsJson(new JsonResponseModel
{
Result = true,
Message = $"https://www.gravatar.com/avatar/{hashed}"
});
}
else
{
return Response.AsJson(new JsonResponseModel {Result = false});
}
}
}
}

@ -33,6 +33,7 @@ using Nancy;
using Nancy.Responses.Negotiation;
using NLog;
using Ombi.Api.Interfaces;
using Ombi.Api.Models.Sonarr;
using Ombi.Core;
using Ombi.Core.Models;
using Ombi.Core.SettingModels;
@ -104,7 +105,8 @@ namespace Ombi.UI.Modules
Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available);
Post["/changeRootFolder", true] = async (x, ct) => await ChangeRootFolder((int) Request.Form.requestId, (int) Request.Form.rootFolderId);
Post["/changeRootFoldertv", true] = async (x, ct) => await ChangeRootFolder(RequestType.TvShow, (int)Request.Form.requestId, (int)Request.Form.rootFolderId);
Post["/changeRootFoldermovie", true] = async (x, ct) => await ChangeRootFolder(RequestType.Movie, (int)Request.Form.requestId, (int)Request.Form.rootFolderId);
Get["/UpdateFilters", true] = async (x, ct) => await GetFilterAndSortSettings();
}
@ -171,7 +173,7 @@ namespace Ombi.UI.Modules
if (result != null)
{
qualities =
result.list.Select(x => new QualityModel {Id = x._id, Name = x.label}).ToList();
result.list.Select(x => new QualityModel { Id = x._id, Name = x.label }).ToList();
}
}
catch (Exception e)
@ -188,7 +190,7 @@ namespace Ombi.UI.Modules
rootFolders =
rootFoldersResult.Select(
x => new RootFolderModel {Id = x.id.ToString(), Path = x.path, FreeSpace = x.freespace})
x => new RootFolderModel { Id = x.id.ToString(), Path = x.path, FreeSpace = x.freespace })
.ToList();
var result = await Cache.GetOrSetAsync(CacheKeys.RadarrQualityProfiles, async () =>
@ -204,7 +206,7 @@ namespace Ombi.UI.Modules
}
}
var canManageRequest = Security.HasAnyPermissions(User, Permissions.Administrator, Permissions.ManageRequests);
var viewModel = dbMovies.Select(movie => new RequestViewModel
{
@ -265,14 +267,14 @@ namespace Ombi.UI.Modules
});
qualities = result.Select(x => new QualityModel { Id = x.id.ToString(), Name = x.name }).ToList();
var rootFoldersResult =await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () =>
{
return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri));
});
rootFolders = rootFoldersResult.Select(x => new RootFolderModel { Id = x.id.ToString(), Path = x.path, FreeSpace = x.freespace}).ToList();
}
var rootFoldersResult = await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () =>
{
return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri));
});
rootFolders = rootFoldersResult.Select(x => new RootFolderModel { Id = x.id.ToString(), Path = x.path, FreeSpace = x.freespace }).ToList();
}
else
{
var sickRageSettings = await SickRageSettings.GetSettingsAsync();
@ -318,7 +320,7 @@ namespace Ombi.UI.Modules
TvSeriesRequestType = tv.SeasonsRequested,
Qualities = qualities.ToArray(),
Episodes = tv.Episodes.ToArray(),
RootFolders = rootFolders.ToArray(),
RootFolders = rootFolders.ToArray(),
HasRootFolders = rootFolders.Any(),
CurrentRootPath = sonarrSettings.Enabled ? GetRootPath(tv.RootFolderSelected, sonarrSettings).Result : null
}).ToList();
@ -555,11 +557,21 @@ namespace Ombi.UI.Modules
return Response.AsJson(vm);
}
private async Task<Response> ChangeRootFolder(int id, int rootFolderId)
private async Task<Response> ChangeRootFolder(RequestType type, int id, int rootFolderId)
{
// Get all root folders
var settings = await SonarrSettings.GetSettingsAsync();
var rootFolders = SonarrApi.GetRootFolders(settings.ApiKey, settings.FullUri);
var rootFolders = new List<SonarrRootFolder>();
if (type == RequestType.TvShow)
{
// Get all root folders
var settings = await SonarrSettings.GetSettingsAsync();
rootFolders = SonarrApi.GetRootFolders(settings.ApiKey, settings.FullUri);
}
else
{
var settings = await Radarr.GetSettingsAsync();
rootFolders = RadarrApi.GetRootFolders(settings.ApiKey, settings.FullUri);
}
// Get Request
var allRequests = await Service.GetAllAsync();
@ -567,7 +579,7 @@ namespace Ombi.UI.Modules
if (request == null)
{
return Response.AsJson(new JsonResponseModel {Result = false});
return Response.AsJson(new JsonResponseModel { Result = false });
}
foreach (var folder in rootFolders)
@ -581,7 +593,7 @@ namespace Ombi.UI.Modules
await Service.UpdateRequestAsync(request);
return Response.AsJson(new JsonResponseModel {Result = true});
}
}
return Response.AsJson(new JsonResponseModel { Result = true });
}
}
}

@ -266,13 +266,13 @@
<Compile Include="Modules\Admin\UserManagementSettingsModule.cs" />
<Compile Include="Modules\Admin\FaultQueueModule.cs" />
<Compile Include="Modules\Admin\SystemStatusModule.cs" />
<Compile Include="Modules\ApiDocsModule.cs" />
<Compile Include="Modules\ApiSettingsMetadataModule.cs" />
<Compile Include="Modules\ApiUserMetadataModule.cs" />
<Compile Include="Modules\ApiRequestMetadataModule.cs" />
<Compile Include="Modules\ApiSettingsModule.cs" />
<Compile Include="Modules\ApiUserModule.cs" />
<Compile Include="Modules\BaseApiModule.cs" />
<Compile Include="Modules\Api\ApiDocsModule.cs" />
<Compile Include="Modules\Api\ApiSettingsMetadataModule.cs" />
<Compile Include="Modules\Api\ApiUserMetadataModule.cs" />
<Compile Include="Modules\Api\ApiRequestMetadataModule.cs" />
<Compile Include="Modules\Api\ApiSettingsModule.cs" />
<Compile Include="Modules\Api\ApiUserModule.cs" />
<Compile Include="Modules\Api\BaseApiModule.cs" />
<Compile Include="Modules\BaseModule.cs" />
<Compile Include="Modules\BetaModule.cs" />
<Compile Include="Modules\CultureModule.cs" />
@ -641,7 +641,7 @@
<Content Include="Views\UserManagement\Index.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Compile Include="Modules\ApiRequestModule.cs" />
<Compile Include="Modules\Api\ApiRequestModule.cs" />
<Compile Include="Models\ApiModel.cs" />
<Compile Include="Models\UserManagement\UserManagementUsersViewModel.cs" />
</ItemGroup>

@ -281,7 +281,7 @@
</form>
<form method="POST" action="@formAction/requests/changeRootFolder" id="changeFolder{{requestId}}">
<form method="POST" action="@formAction/requests/changeRootFolder{{#if_eq type "tv"}}tv{{else}}movie{{/if_eq}}" id="changeFolder{{requestId}}">
<input name="requestId" type="text" value="{{requestId}}" hidden="hidden" />
{{#if_eq hasRootFolders true}}
<div class="btn-group btn-split">

@ -26,6 +26,23 @@
console.log(e);
}
});
var gravatarUrl = createBaseUrl(base, 'layout/gravatar');
$.ajax({
url: gravatarUrl,
success: function (result) {
if (result.result) {
$('#gravatarImg').html("<img src=\"" + result.message + "\" class=\"gravatar\" width=\"30\" height=\"30\" alt=\"\">");
}
},
error: function (xhr, status, error) {
console.log("error " + error);
}
});
// End Check for update
checkCacheInProgress();

@ -52,6 +52,9 @@
<li id="customDonate" style="display: none"><a id="customDonateHref" href="https://www.paypal.me/PlexRequestsNet" target="_blank"><i class="fa fa-heart" style="color: yellow;"></i> <span id="donationText">@UI.Custom_Donation_Default</span></a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<a id="gravatarImg" class="navbar-brand" href="#">
</a>
@if (Html.IsAdmin())
{
<li><a>@UI.Layout_Welcome @Context.CurrentUser.UserName</a></li>
@ -101,19 +104,19 @@
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-language" aria-hidden="true"><span class="caret"></span></i></a>
<ul class="dropdown-menu" role="menu">
<li><a href="@url/culture?l=en&u=@Context.Request.Path">@UI.Layout_English</a></li>
<li><a href="@url/culture?l=fr&u=@Context.Request.Path">@UI.Layout_French</a></li>
<li><a href="@url/culture?l=nl&u=@Context.Request.Path">@UI.Layout_Dutch</a></li>
<li><a href="@url/culture?l=es&u=@Context.Request.Path">@UI.Layout_Spanish</a></li>
<li><a href="@url/culture?l=de&u=@Context.Request.Path">@UI.Layout_German</a></li>
<li><a href="@url/culture?l=da&u=@Context.Request.Path">@UI.Layout_Danish</a></li>
<li><a href="@url/culture?l=pt&u=@Context.Request.Path">@UI.Layout_Portuguese</a></li>
<li><a href="@url/culture?l=sv&u=@Context.Request.Path">@UI.Layout_Swedish</a></li>
<li><a href="@url/culture?l=it&u=@Context.Request.Path">@UI.Layout_Italian</a></li>
</ul>
<li />
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-language" aria-hidden="true"><span class="caret"></span></i></a>
<ul class="dropdown-menu" role="menu">
<li><a href="@url/culture?l=en&u=@Context.Request.Path">@UI.Layout_English</a></li>
<li><a href="@url/culture?l=fr&u=@Context.Request.Path">@UI.Layout_French</a></li>
<li><a href="@url/culture?l=nl&u=@Context.Request.Path">@UI.Layout_Dutch</a></li>
<li><a href="@url/culture?l=es&u=@Context.Request.Path">@UI.Layout_Spanish</a></li>
<li><a href="@url/culture?l=de&u=@Context.Request.Path">@UI.Layout_German</a></li>
<li><a href="@url/culture?l=da&u=@Context.Request.Path">@UI.Layout_Danish</a></li>
<li><a href="@url/culture?l=pt&u=@Context.Request.Path">@UI.Layout_Portuguese</a></li>
<li><a href="@url/culture?l=sv&u=@Context.Request.Path">@UI.Layout_Swedish</a></li>
<li><a href="@url/culture?l=it&u=@Context.Request.Path">@UI.Layout_Italian</a></li>
</ul>
<li/>
</ul>
</div>
</div>
@ -129,7 +132,7 @@
var donationText = $("#donationText");
donateLink.attr("href", result.url);
if (result.message) {
donationText.text(result.message);
donationText.text(result.message);
}
}
},
@ -138,6 +141,8 @@
$("#customDonate").hide();
}
});
</script>
<div id="updateAvailable" hidden="hidden"></div>

Loading…
Cancel
Save