mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-03-12 04:35:27 -07:00
work on issues and imporving the api.
Also added the GroupMe Api project so we can later add this as another notification agent
This commit is contained in:
parent
8de5057fd3
commit
189cfcaf05
src
Ombi.Api.GroupMe
Ombi.Api
Ombi.Core/Engine
Ombi.DependencyInjection
Ombi.Helpers
Ombi.TheMovieDbApi
Ombi.slnOmbi
48
src/Ombi.Api.GroupMe/GroupMeApi.cs
Normal file
48
src/Ombi.Api.GroupMe/GroupMeApi.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.GroupMe.Models;
|
||||
|
||||
namespace Ombi.Api.GroupMe
|
||||
{
|
||||
public class GroupMeApi : IGroupMeApi
|
||||
{
|
||||
public GroupMeApi(IApi api)
|
||||
{
|
||||
_api = api;
|
||||
}
|
||||
|
||||
private readonly IApi _api;
|
||||
private const string BaseUrl = "https://api.groupme.com/v3/";
|
||||
|
||||
|
||||
public async Task<GroupMeResponse<List<Groups>>> GetGroups(string token, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new Request($"groups", BaseUrl, HttpMethod.Get);
|
||||
request.AddQueryString("token", token);
|
||||
request.AddQueryString("omit", "memberships");
|
||||
|
||||
return await _api.Request<GroupMeResponse<List<Groups>>>(request, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<GroupMeResponse<SendResponse>> Send(string message, string token, int groupId)
|
||||
{
|
||||
var request = new Request($"groups/{groupId}/messages", BaseUrl, HttpMethod.Post);
|
||||
request.AddQueryString("token", token);
|
||||
|
||||
var body = new
|
||||
{
|
||||
message = new
|
||||
{
|
||||
source_guid = Guid.NewGuid(),
|
||||
text = message
|
||||
}
|
||||
};
|
||||
|
||||
request.AddJsonBody(body);
|
||||
return await _api.Request<GroupMeResponse<SendResponse>>(request);
|
||||
}
|
||||
}
|
||||
}
|
13
src/Ombi.Api.GroupMe/IGroupMeApi.cs
Normal file
13
src/Ombi.Api.GroupMe/IGroupMeApi.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.GroupMe.Models;
|
||||
|
||||
namespace Ombi.Api.GroupMe
|
||||
{
|
||||
public interface IGroupMeApi
|
||||
{
|
||||
Task<GroupMeResponse<List<Groups>>> GetGroups(string token, CancellationToken cancellationToken);
|
||||
Task<GroupMeResponse<SendResponse>> Send(string message, string token, int groupId);
|
||||
}
|
||||
}
|
61
src/Ombi.Api.GroupMe/Models/GroupMeResponse.cs
Normal file
61
src/Ombi.Api.GroupMe/Models/GroupMeResponse.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ombi.Api.GroupMe.Models
|
||||
{
|
||||
public class GroupMeResponse<T>
|
||||
{
|
||||
[JsonProperty(PropertyName = "response")]
|
||||
public T Response { get; set; }
|
||||
[JsonProperty(PropertyName = "meta")]
|
||||
public Meta Meta { get; set; }
|
||||
}
|
||||
public class Meta
|
||||
{
|
||||
public bool Successful
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (StatusCode)
|
||||
{
|
||||
case GroupMeStatusCode.OK:
|
||||
case GroupMeStatusCode.Created:
|
||||
case GroupMeStatusCode.NoContent:
|
||||
case GroupMeStatusCode.NotModified:
|
||||
return true;
|
||||
case GroupMeStatusCode.BadRequest:
|
||||
case GroupMeStatusCode.Unauthorized:
|
||||
case GroupMeStatusCode.Forbidden:
|
||||
case GroupMeStatusCode.NotFound:
|
||||
case GroupMeStatusCode.EnhanceYourCalm:
|
||||
case GroupMeStatusCode.InternalServerError:
|
||||
case GroupMeStatusCode.BadGateway:
|
||||
case GroupMeStatusCode.ServiceUnavailable:
|
||||
return false;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(GroupMeStatusCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GroupMeStatusCode StatusCode => (GroupMeStatusCode) code;
|
||||
public int code { get; set; }
|
||||
public string[] errors { get; set; }
|
||||
}
|
||||
|
||||
public enum GroupMeStatusCode
|
||||
{ OK = 200,
|
||||
Created = 201,
|
||||
NoContent = 204,
|
||||
NotModified = 304,
|
||||
BadRequest = 400,
|
||||
Unauthorized = 401,
|
||||
Forbidden = 403,
|
||||
NotFound = 404,
|
||||
EnhanceYourCalm = 420,
|
||||
InternalServerError = 500,
|
||||
BadGateway = 502,
|
||||
ServiceUnavailable = 503
|
||||
}
|
||||
|
||||
}
|
38
src/Ombi.Api.GroupMe/Models/Groups.cs
Normal file
38
src/Ombi.Api.GroupMe/Models/Groups.cs
Normal file
@ -0,0 +1,38 @@
|
||||
namespace Ombi.Api.GroupMe.Models
|
||||
{
|
||||
|
||||
public class Groups
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string group_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string phone_number { get; set; }
|
||||
public string type { get; set; }
|
||||
public string description { get; set; }
|
||||
public string image_url { get; set; }
|
||||
public string creator_user_id { get; set; }
|
||||
public int created_at { get; set; }
|
||||
public int updated_at { get; set; }
|
||||
public bool office_mode { get; set; }
|
||||
public string share_url { get; set; }
|
||||
public string share_qr_code_url { get; set; }
|
||||
public Messages messages { get; set; }
|
||||
public int max_members { get; set; }
|
||||
}
|
||||
|
||||
public class Messages
|
||||
{
|
||||
public int count { get; set; }
|
||||
public string last_message_id { get; set; }
|
||||
public int last_message_created_at { get; set; }
|
||||
public Preview preview { get; set; }
|
||||
}
|
||||
|
||||
public class Preview
|
||||
{
|
||||
public string nickname { get; set; }
|
||||
public string text { get; set; }
|
||||
public string image_url { get; set; }
|
||||
public object[] attachments { get; set; }
|
||||
}
|
||||
}
|
26
src/Ombi.Api.GroupMe/Models/SendMessageResponse.cs
Normal file
26
src/Ombi.Api.GroupMe/Models/SendMessageResponse.cs
Normal file
@ -0,0 +1,26 @@
|
||||
namespace Ombi.Api.GroupMe.Models
|
||||
{
|
||||
|
||||
public class SendResponse
|
||||
{
|
||||
public Message message { get; set; }
|
||||
}
|
||||
|
||||
public class Message
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string source_guid { get; set; }
|
||||
public int created_at { get; set; }
|
||||
public string user_id { get; set; }
|
||||
public string group_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string avatar_url { get; set; }
|
||||
public string text { get; set; }
|
||||
public bool system { get; set; }
|
||||
public object[] attachments { get; set; }
|
||||
public object[] favorited_by { get; set; }
|
||||
public string sender_type { get; set; }
|
||||
public string sender_id { get; set; }
|
||||
}
|
||||
|
||||
}
|
11
src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj
Normal file
11
src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj
Normal file
@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
@ -29,13 +30,13 @@ namespace Ombi.Api
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
|
||||
public async Task<T> Request<T>(Request request)
|
||||
public async Task<T> Request<T>(Request request, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri))
|
||||
{
|
||||
AddHeadersBody(request, httpRequestMessage);
|
||||
|
||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage);
|
||||
|
||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage, cancellationToken);
|
||||
|
||||
if (!httpResponseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
|
@ -1,11 +1,12 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Api
|
||||
{
|
||||
public interface IApi
|
||||
{
|
||||
Task Request(Request request);
|
||||
Task<T> Request<T>(Request request);
|
||||
Task<T> Request<T>(Request request, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<string> RequestContent(Request request);
|
||||
T DeserializeXml<T>(string receivedString);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Api
|
||||
@ -7,6 +8,7 @@ namespace Ombi.Api
|
||||
public interface IOmbiHttpClient
|
||||
{
|
||||
Task<HttpResponseMessage> SendAsync(HttpRequestMessage request);
|
||||
Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
|
||||
Task<string> GetStringAsync(Uri requestUri);
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Helpers;
|
||||
@ -61,6 +62,12 @@ namespace Ombi.Api
|
||||
return await _client.SendAsync(request);
|
||||
}
|
||||
|
||||
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
await Setup();
|
||||
return await _client.SendAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<string> GetStringAsync(Uri requestUri)
|
||||
{
|
||||
await Setup();
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Models.Search;
|
||||
@ -8,16 +9,16 @@ namespace Ombi.Core.Engine.Interfaces
|
||||
{
|
||||
public interface IMovieEngineV2
|
||||
{
|
||||
Task<MovieFullInfoViewModel> GetFullMovieInformation(int theMovieDbId, string langCode = null);
|
||||
Task<MovieFullInfoViewModel> GetFullMovieInformation(int theMovieDbId, CancellationToken cancellationToken, string langCode = null);
|
||||
Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId, string langCode);
|
||||
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
|
||||
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
|
||||
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
|
||||
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
|
||||
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies(int currentPosition, int amountToLoad);
|
||||
Task<MovieCollectionsViewModel> GetCollection(int collectionId, string langCode = null);
|
||||
Task<MovieCollectionsViewModel> GetCollection(int collectionId, CancellationToken cancellationToken, string langCode = null);
|
||||
Task<int> GetTvDbId(int theMovieDbId);
|
||||
Task<IEnumerable<SearchMovieViewModel>> PopularMovies(int currentlyLoaded, int toLoad);
|
||||
Task<IEnumerable<SearchMovieViewModel>> PopularMovies(int currentlyLoaded, int toLoad, CancellationToken cancellationToken);
|
||||
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies(int currentlyLoaded, int toLoad);
|
||||
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies(int currentlyLoaded, int toLoad);
|
||||
Task<ActorCredits> GetMoviesByActor(int actorId, string langCode);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
|
||||
@ -6,6 +7,6 @@ namespace Ombi.Core.Engine.V2
|
||||
{
|
||||
public interface IMultiSearchEngine
|
||||
{
|
||||
Task<List<MultiSearch>> MultiSearch(string searchTerm, string lang = "en");
|
||||
Task<List<MultiSearch>> MultiSearch(string searchTerm, CancellationToken cancellationToken, string lang = "en");
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Engine.V2
|
||||
@ -38,20 +39,20 @@ namespace Ombi.Core.Engine.V2
|
||||
private ILogger Logger { get; }
|
||||
|
||||
|
||||
public async Task<MovieFullInfoViewModel> GetFullMovieInformation(int theMovieDbId, string langCode = null)
|
||||
public async Task<MovieFullInfoViewModel> GetFullMovieInformation(int theMovieDbId, CancellationToken cancellationToken, string langCode = null)
|
||||
{
|
||||
langCode = await DefaultLanguageCode(langCode);
|
||||
var movieInfo = await Cache.GetOrAdd(nameof(GetFullMovieInformation) + theMovieDbId + langCode,
|
||||
async () => await MovieApi.GetFullMovieInfo(theMovieDbId, langCode), DateTime.Now.AddHours(12));
|
||||
async () => await MovieApi.GetFullMovieInfo(theMovieDbId, cancellationToken, langCode), DateTime.Now.AddHours(12), cancellationToken);
|
||||
|
||||
return await ProcessSingleMovie(movieInfo);
|
||||
}
|
||||
|
||||
public async Task<MovieCollectionsViewModel> GetCollection(int collectionId, string langCode = null)
|
||||
public async Task<MovieCollectionsViewModel> GetCollection(int collectionId, CancellationToken cancellationToken, string langCode = null)
|
||||
{
|
||||
langCode = await DefaultLanguageCode(langCode);
|
||||
var collections = await Cache.GetOrAdd(nameof(GetCollection) + collectionId + langCode,
|
||||
async () => await MovieApi.GetCollection(langCode, collectionId), DateTime.Now.AddDays(1));
|
||||
async () => await MovieApi.GetCollection(langCode, collectionId, cancellationToken), DateTime.Now.AddDays(1), cancellationToken);
|
||||
|
||||
var c = await ProcessCollection(collections);
|
||||
c.Collection = c.Collection.OrderBy(x => x.ReleaseDate).ToList();
|
||||
@ -107,7 +108,7 @@ namespace Ombi.Core.Engine.V2
|
||||
/// Gets popular movies by paging
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies(int currentlyLoaded, int toLoad)
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies(int currentlyLoaded, int toLoad, CancellationToken cancellationToken)
|
||||
{
|
||||
var langCode = await DefaultLanguageCode(null);
|
||||
|
||||
@ -117,7 +118,7 @@ namespace Ombi.Core.Engine.V2
|
||||
foreach (var pagesToLoad in pages)
|
||||
{
|
||||
var apiResult = await Cache.GetOrAdd(nameof(PopularMovies) + pagesToLoad.Page + langCode,
|
||||
async () => await MovieApi.PopularMovies(langCode, pagesToLoad.Page), DateTime.Now.AddHours(12));
|
||||
async () => await MovieApi.PopularMovies(langCode, pagesToLoad.Page, cancellationToken), DateTime.Now.AddHours(12), cancellationToken);
|
||||
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
|
||||
}
|
||||
return await TransformMovieResultsToResponse(results);
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
@ -27,9 +28,9 @@ namespace Ombi.Core.Engine.V2
|
||||
private readonly IMovieDbApi _movieDbApi;
|
||||
|
||||
|
||||
public async Task<List<MultiSearch>> MultiSearch(string searchTerm, string lang = "en")
|
||||
public async Task<List<MultiSearch>> MultiSearch(string searchTerm, CancellationToken cancellationToken, string lang = "en")
|
||||
{
|
||||
return (await _movieDbApi.MultiSearch(searchTerm, lang)).results;
|
||||
return (await _movieDbApi.MultiSearch(searchTerm, lang, cancellationToken)).results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ using Ombi.Api.DogNzb;
|
||||
using Ombi.Api.FanartTv;
|
||||
using Ombi.Api.Github;
|
||||
using Ombi.Api.Gotify;
|
||||
using Ombi.Api.GroupMe;
|
||||
using Ombi.Api.Lidarr;
|
||||
using Ombi.Api.Mattermost;
|
||||
using Ombi.Api.Notifications;
|
||||
@ -143,6 +144,7 @@ namespace Ombi.DependencyInjection
|
||||
services.AddTransient<IAppVeyorApi, AppVeyorApi>();
|
||||
services.AddTransient<IOneSignalApi, OneSignalApi>();
|
||||
services.AddTransient<ILidarrApi, LidarrApi>();
|
||||
services.AddTransient<IGroupMeApi, GroupMeApi>();
|
||||
}
|
||||
|
||||
public static void RegisterStore(this IServiceCollection services) {
|
||||
|
@ -21,6 +21,7 @@
|
||||
<ProjectReference Include="..\Ombi.Api.Emby\Ombi.Api.Emby.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.FanartTv\Ombi.Api.FanartTv.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Github\Ombi.Api.Github.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.GroupMe\Ombi.Api.GroupMe.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Notifications\Ombi.Api.Notifications.csproj" />
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Nito.AsyncEx;
|
||||
@ -16,7 +17,7 @@ namespace Ombi.Helpers
|
||||
_memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
|
||||
}
|
||||
|
||||
public async Task<T> GetOrAdd<T>(string cacheKey, Func<Task<T>> factory, DateTime absoluteExpiration = default(DateTime))
|
||||
public async Task<T> GetOrAdd<T>(string cacheKey, Func<Task<T>> factory, DateTime absoluteExpiration = default(DateTime), CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (absoluteExpiration == default(DateTime))
|
||||
{
|
||||
@ -33,6 +34,11 @@ namespace Ombi.Helpers
|
||||
return result;
|
||||
}
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
result = await factory();
|
||||
_memoryCache.Set(cacheKey, result, absoluteExpiration);
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Helpers
|
||||
{
|
||||
public interface ICacheService
|
||||
{
|
||||
Task<T> GetOrAdd<T>(string cacheKey, Func<Task<T>> factory, DateTime absoluteExpiration = default(DateTime));
|
||||
Task<T> GetOrAdd<T>(string cacheKey, Func<Task<T>> factory, DateTime absoluteExpiration = default(DateTime), CancellationToken cancellationToken = default(CancellationToken));
|
||||
T GetOrAdd<T>(string cacheKey, Func<T> factory, DateTime absoluteExpiration);
|
||||
void Remove(string key);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.TheMovieDbApi.Models;
|
||||
@ -10,7 +11,7 @@ namespace Ombi.Api.TheMovieDb
|
||||
Task<MovieResponseDto> GetMovieInformation(int movieId);
|
||||
Task<MovieResponseDto> GetMovieInformationWithExtraInfo(int movieId, string langCode = "en");
|
||||
Task<List<MovieSearchResult>> NowPlaying(string languageCode, int? page = null);
|
||||
Task<List<MovieSearchResult>> PopularMovies(string languageCode, int? page = null);
|
||||
Task<List<MovieSearchResult>> PopularMovies(string languageCode, int? page = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<List<MovieSearchResult>> SearchMovie(string searchTerm, int? year, string languageCode);
|
||||
Task<List<TvSearchResult>> SearchTv(string searchTerm);
|
||||
Task<List<MovieSearchResult>> TopRated(string languageCode, int? page = null);
|
||||
@ -21,9 +22,9 @@ namespace Ombi.Api.TheMovieDb
|
||||
Task<TvInfo> GetTVInfo(string themoviedbid);
|
||||
Task<TheMovieDbContainer<ActorResult>> SearchByActor(string searchTerm, string langCode);
|
||||
Task<ActorCredits> GetActorMovieCredits(int actorId, string langCode);
|
||||
Task<TheMovieDbContainer<MultiSearch>> MultiSearch(string searchTerm, string languageCode);
|
||||
Task<FullMovieInfo> GetFullMovieInfo(int movieId, string langCode);
|
||||
Task<TheMovieDbContainer<MultiSearch>> MultiSearch(string searchTerm, string languageCode, CancellationToken cancellationToken);
|
||||
Task<TheMovieDbContainer<DiscoverMovies>> DiscoverMovies(string langCode, int keywordId);
|
||||
Task<Collections> GetCollection(string langCode, int collectionId);
|
||||
Task<FullMovieInfo> GetFullMovieInfo(int movieId, CancellationToken cancellationToken, string langCode);
|
||||
Task<Collections> GetCollection(string langCode, int collectionId, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AutoMapper;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
@ -32,7 +33,7 @@ namespace Ombi.Api.TheMovieDb
|
||||
}
|
||||
|
||||
|
||||
public async Task<FullMovieInfo> GetFullMovieInfo(int movieId, string langCode)
|
||||
public async Task<FullMovieInfo> GetFullMovieInfo(int movieId, CancellationToken cancellationToken, string langCode)
|
||||
{
|
||||
var request = new Request($"movie/{movieId}", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
@ -40,7 +41,7 @@ namespace Ombi.Api.TheMovieDb
|
||||
request.FullUri = request.FullUri.AddQueryParameter("append_to_response", "videos,credits,similar,recommendations,release_dates,external_ids,keywords");
|
||||
AddRetry(request);
|
||||
|
||||
return await Api.Request<FullMovieInfo>(request);
|
||||
return await Api.Request<FullMovieInfo>(request, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<TheMovieDbContainer<DiscoverMovies>> DiscoverMovies(string langCode, int keywordId)
|
||||
@ -55,14 +56,14 @@ namespace Ombi.Api.TheMovieDb
|
||||
return await Api.Request<TheMovieDbContainer<DiscoverMovies>>(request);
|
||||
}
|
||||
|
||||
public async Task<Collections> GetCollection(string langCode, int collectionId)
|
||||
public async Task<Collections> GetCollection(string langCode, int collectionId, CancellationToken cancellationToken)
|
||||
{
|
||||
// https://developers.themoviedb.org/3/discover/movie-discover
|
||||
var request = new Request($"collection/{collectionId}", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("language", langCode);
|
||||
|
||||
return await Api.Request<Collections> (request);
|
||||
return await Api.Request<Collections>(request, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<FindResult> Find(string externalId, ExternalSource source)
|
||||
@ -156,7 +157,7 @@ namespace Ombi.Api.TheMovieDb
|
||||
return Mapper.Map<List<MovieSearchResult>>(result.results);
|
||||
}
|
||||
|
||||
public async Task<List<MovieSearchResult>> PopularMovies(string langageCode, int? page = null)
|
||||
public async Task<List<MovieSearchResult>> PopularMovies(string langageCode, int? page = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var request = new Request($"movie/popular", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
@ -166,7 +167,7 @@ namespace Ombi.Api.TheMovieDb
|
||||
request.FullUri = request.FullUri.AddQueryParameter("page", page.ToString());
|
||||
}
|
||||
AddRetry(request);
|
||||
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
|
||||
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request, cancellationToken);
|
||||
return Mapper.Map<List<MovieSearchResult>>(result.results);
|
||||
}
|
||||
|
||||
@ -222,13 +223,13 @@ namespace Ombi.Api.TheMovieDb
|
||||
return await Api.Request<TvInfo>(request);
|
||||
}
|
||||
|
||||
public async Task<TheMovieDbContainer<MultiSearch>> MultiSearch(string searchTerm, string languageCode)
|
||||
public async Task<TheMovieDbContainer<MultiSearch>> MultiSearch(string searchTerm, string languageCode, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new Request("search/multi", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("language", languageCode);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("query", searchTerm);
|
||||
var result = await Api.Request<TheMovieDbContainer<MultiSearch>>(request);
|
||||
var result = await Api.Request<TheMovieDbContainer<MultiSearch>>(request, cancellationToken);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
11
src/Ombi.sln
11
src/Ombi.sln
@ -102,9 +102,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Gotify", "Ombi.Api
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Settings.Tests", "Ombi.Settings.Tests\Ombi.Settings.Tests.csproj", "{F3969B69-3B07-4884-A7AB-0BAB8B84DF94}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Test.Common", "Ombi.Test.Common\Ombi.Test.Common.csproj", "{27111E7C-748E-4996-BD71-2117027C6460}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Test.Common", "Ombi.Test.Common\Ombi.Test.Common.csproj", "{27111E7C-748E-4996-BD71-2117027C6460}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Hubs", "Ombi.Hubs\Ombi.Hubs.csproj", "{67416CC5-13B2-44BB-98CE-39DA93D6F70E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Hubs", "Ombi.Hubs\Ombi.Hubs.csproj", "{67416CC5-13B2-44BB-98CE-39DA93D6F70E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.GroupMe", "Ombi.Api.GroupMe\Ombi.Api.GroupMe.csproj", "{9266403C-B04D-4C0F-AC39-82F12C781949}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -280,6 +282,10 @@ Global
|
||||
{67416CC5-13B2-44BB-98CE-39DA93D6F70E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{67416CC5-13B2-44BB-98CE-39DA93D6F70E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{67416CC5-13B2-44BB-98CE-39DA93D6F70E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9266403C-B04D-4C0F-AC39-82F12C781949}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9266403C-B04D-4C0F-AC39-82F12C781949}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9266403C-B04D-4C0F-AC39-82F12C781949}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9266403C-B04D-4C0F-AC39-82F12C781949}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -320,6 +326,7 @@ Global
|
||||
{105EA346-766E-45B8-928B-DE6991DCB7EB} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{F3969B69-3B07-4884-A7AB-0BAB8B84DF94} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
|
||||
{27111E7C-748E-4996-BD71-2117027C6460} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
|
||||
{9266403C-B04D-4C0F-AC39-82F12C781949} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
||||
|
20
src/Ombi/ClientApp/src/app/issues/components/index.ts
Normal file
20
src/Ombi/ClientApp/src/app/issues/components/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { AuthGuard } from "../../auth/auth.guard";
|
||||
import { IssuesListComponent } from "./issues-list/issues-list.component";
|
||||
import { Routes } from "@angular/router";
|
||||
|
||||
|
||||
|
||||
export const components: any[] = [
|
||||
IssuesListComponent,
|
||||
];
|
||||
|
||||
|
||||
export const entryComponents: any[] = [
|
||||
];
|
||||
|
||||
export const providers: any[] = [
|
||||
];
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: "", component: IssuesListComponent, canActivate: [AuthGuard] },
|
||||
];
|
@ -0,0 +1,28 @@
|
||||
<table mat-table
|
||||
[dataSource]="pendingIssues" multiTemplateDataRows
|
||||
class="mat-elevation-z8">
|
||||
<ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
|
||||
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
|
||||
<ng-container matColumnDef="expandedDetail">
|
||||
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplay.length">
|
||||
<div class="example-element-detail"
|
||||
[@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||
<div class="example-element-diagram">
|
||||
<div class="example-element-position"> {{element.requestId}} </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
|
||||
<tr mat-row *matRowDef="let element; columns: columnsToDisplay;"
|
||||
class="example-element-row"
|
||||
[class.example-expanded-row]="expandedElement === element"
|
||||
(click)="expandedElement = expandedElement === element ? null : element">
|
||||
</tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||
</table>
|
@ -0,0 +1,67 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
|
||||
import { IssuesService } from "../../../services";
|
||||
|
||||
import { IIssueCount, IIssues, IPagenator, IssueStatus } from "../../../interfaces";
|
||||
import { COLUMNS } from "./issues-list.constants";
|
||||
|
||||
@Component({
|
||||
templateUrl: "issues-list.component.html",
|
||||
})
|
||||
export class IssuesListComponent implements OnInit {
|
||||
|
||||
public columnsToDisplay = COLUMNS
|
||||
|
||||
public pendingIssues: IIssues[];
|
||||
public inProgressIssues: IIssues[];
|
||||
public resolvedIssues: IIssues[];
|
||||
|
||||
public count: IIssueCount;
|
||||
|
||||
private takeAmount = 10;
|
||||
private pendingSkip = 0;
|
||||
private inProgressSkip = 0;
|
||||
private resolvedSkip = 0;
|
||||
|
||||
constructor(private issueService: IssuesService) { }
|
||||
|
||||
public ngOnInit() {
|
||||
this.getPending();
|
||||
this.getInProg();
|
||||
this.getResolved();
|
||||
this.issueService.getIssuesCount().subscribe(x => this.count = x);
|
||||
}
|
||||
|
||||
public changePagePending(event: IPagenator) {
|
||||
this.pendingSkip = event.first;
|
||||
this.getPending();
|
||||
}
|
||||
|
||||
public changePageInProg(event: IPagenator) {
|
||||
this.inProgressSkip = event.first;
|
||||
this.getInProg();
|
||||
}
|
||||
|
||||
public changePageResolved(event: IPagenator) {
|
||||
this.resolvedSkip = event.first;
|
||||
this.getResolved();
|
||||
}
|
||||
|
||||
private getPending() {
|
||||
this.issueService.getIssuesPage(this.takeAmount, this.pendingSkip, IssueStatus.Pending).subscribe(x => {
|
||||
this.pendingIssues = x;
|
||||
});
|
||||
}
|
||||
|
||||
private getInProg() {
|
||||
this.issueService.getIssuesPage(this.takeAmount, this.inProgressSkip, IssueStatus.InProgress).subscribe(x => {
|
||||
this.inProgressIssues = x;
|
||||
});
|
||||
}
|
||||
|
||||
private getResolved() {
|
||||
this.issueService.getIssuesPage(this.takeAmount, this.resolvedSkip, IssueStatus.Resolved).subscribe(x => {
|
||||
this.resolvedIssues = x;
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
export const COLUMNS = [
|
||||
"title"
|
||||
]
|
@ -16,9 +16,12 @@ import { IssuesComponent } from "./issues.component";
|
||||
import { IssuesTableComponent } from "./issuestable.component";
|
||||
|
||||
import { PipeModule } from "../pipes/pipe.module";
|
||||
import { IssuesListComponent } from "./components/issues-list/issues-list.component";
|
||||
|
||||
import * as fromComponents from "./components";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "", component: IssuesComponent, canActivate: [AuthGuard] },
|
||||
{ path: "", component: IssuesListComponent, canActivate: [AuthGuard] },
|
||||
{ path: ":id", component: IssueDetailsComponent, canActivate: [AuthGuard] },
|
||||
];
|
||||
|
||||
@ -37,6 +40,7 @@ const routes: Routes = [
|
||||
IssuesComponent,
|
||||
IssueDetailsComponent,
|
||||
IssuesTableComponent,
|
||||
...fromComponents.components
|
||||
],
|
||||
exports: [
|
||||
RouterModule,
|
||||
|
@ -48,7 +48,7 @@ namespace Ombi.Controllers.V2
|
||||
[HttpGet("multi/{searchTerm}")]
|
||||
public async Task<List<MultiSearch>> MultiSearch(string searchTerm)
|
||||
{
|
||||
return await _multiSearchEngine.MultiSearch(searchTerm);
|
||||
return await _multiSearchEngine.MultiSearch(searchTerm, Request.HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -58,7 +58,7 @@ namespace Ombi.Controllers.V2
|
||||
[HttpGet("movie/{movieDbId}")]
|
||||
public async Task<MovieFullInfoViewModel> GetMovieInfo(int movieDbId)
|
||||
{
|
||||
return await _movieEngineV2.GetFullMovieInformation(movieDbId);
|
||||
return await _movieEngineV2.GetFullMovieInformation(movieDbId, Request.HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -69,7 +69,7 @@ namespace Ombi.Controllers.V2
|
||||
[HttpGet("movie/collection/{collectionId}")]
|
||||
public async Task<MovieCollectionsViewModel> GetMovieCollections(int collectionId)
|
||||
{
|
||||
return await _movieEngineV2.GetCollection(collectionId);
|
||||
return await _movieEngineV2.GetCollection(collectionId, Request.HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -133,7 +133,7 @@ namespace Ombi.Controllers.V2
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> Popular(int currentPosition, int amountToLoad)
|
||||
{
|
||||
return await _movieEngineV2.PopularMovies(currentPosition, amountToLoad);
|
||||
return await _movieEngineV2.PopularMovies(currentPosition, amountToLoad, Request.HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -38,6 +38,7 @@ namespace Ombi
|
||||
|
||||
//if (exception is NotFoundException) code = HttpStatusCode.NotFound;
|
||||
if (exception is UnauthorizedAccessException) code = HttpStatusCode.Unauthorized;
|
||||
if (exception is OperationCanceledException) code = HttpStatusCode.NoContent;
|
||||
string result;
|
||||
if (exception.InnerException != null)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user