diff --git a/Ombi/Build/publish windows.bat b/Ombi/Build/publish windows.bat
index e94f1864d..f984ee1ba 100644
--- a/Ombi/Build/publish windows.bat
+++ b/Ombi/Build/publish windows.bat
@@ -1,6 +1,6 @@
;https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/
cd ..
dotnet restore
-dotnet publish -c Release -r win10-x64
+dotnet publish -c Release /p:AppRuntimeIdentifier=win10-x64
exit
\ No newline at end of file
diff --git a/Ombi/Ombi.Api/Ombi.Api.csproj b/Ombi/Ombi.Api/Ombi.Api.csproj
index 498e443c1..80457725a 100644
--- a/Ombi/Ombi.Api/Ombi.Api.csproj
+++ b/Ombi/Ombi.Api/Ombi.Api.csproj
@@ -2,6 +2,7 @@
netstandard1.4
+
diff --git a/Ombi/Ombi.Core/IMovieEngine.cs b/Ombi/Ombi.Core/Engine/Interfaces/IMovieEngine.cs
similarity index 100%
rename from Ombi/Ombi.Core/IMovieEngine.cs
rename to Ombi/Ombi.Core/Engine/Interfaces/IMovieEngine.cs
diff --git a/Ombi/Ombi.Core/Engine/Interfaces/IRequestEngine.cs b/Ombi/Ombi.Core/Engine/Interfaces/IRequestEngine.cs
new file mode 100644
index 000000000..f23604468
--- /dev/null
+++ b/Ombi/Ombi.Core/Engine/Interfaces/IRequestEngine.cs
@@ -0,0 +1,12 @@
+using System.Threading.Tasks;
+using Ombi.Core.Models.Search;
+using Ombi.Store.Entities;
+
+namespace Ombi.Core.Engine
+{
+ public interface IRequestEngine
+ {
+ Task RequestMovie(SearchMovieViewModel model);
+ bool ShouldAutoApprove(RequestType requestType);
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Core/MovieEngine.cs b/Ombi/Ombi.Core/Engine/MovieEngine.cs
similarity index 80%
rename from Ombi/Ombi.Core/MovieEngine.cs
rename to Ombi/Ombi.Core/Engine/MovieEngine.cs
index b0e1d52ec..219f65d11 100644
--- a/Ombi/Ombi.Core/MovieEngine.cs
+++ b/Ombi/Ombi.Core/Engine/MovieEngine.cs
@@ -1,14 +1,24 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
+using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
+using Ombi.Core.Requests.Models;
+using Ombi.Helpers;
+using Ombi.Store.Entities;
using Ombi.TheMovieDbApi.Models;
-namespace Ombi.Core
+namespace Ombi.Core.Engine
{
public class MovieEngine : IMovieEngine
{
+ public MovieEngine(IRequestService service)
+ {
+ RequestService = service;
+ }
+ private IRequestService RequestService { get; }
public async Task> ProcessMovieSearch(string search)
{
var api = new TheMovieDbApi.TheMovieDbApi();
@@ -67,8 +77,8 @@ namespace Ombi.Core
{
await Task.Yield();
var viewMovies = new List();
- var counter = 0;
- //Dictionary dbMovies = await RequestedMovies();
+ //var counter = 0;
+ Dictionary dbMovies = await RequestedMovies();
foreach (var movie in movies)
{
var viewMovie = new SearchMovieViewModel
@@ -138,14 +148,14 @@ namespace Ombi.Core
// viewMovie.Available = true;
// }
// }
- // if (dbMovies.ContainsKey(movie.Id) && canSee) // compare to the requests db
- // {
- // var dbm = dbMovies[movie.Id];
+ if (dbMovies.ContainsKey(movie.id) /*&& canSee*/) // compare to the requests db
+ {
+ var dbm = dbMovies[movie.id];
- // viewMovie.Requested = true;
- // viewMovie.Approved = dbm.Approved;
- // viewMovie.Available = dbm.Available;
- // }
+ viewMovie.Requested = true;
+ viewMovie.Approved = dbm.Approved;
+ viewMovie.Available = dbm.Available;
+ }
// else if (canSee)
// {
// bool exists = IsMovieInCache(movie, viewMovie.ImdbId);
@@ -159,5 +169,23 @@ namespace Ombi.Core
}
return viewMovies;
}
+
+
+ private long _dbMovieCacheTime = 0;
+ private Dictionary _dbMovies;
+ private async Task> RequestedMovies()
+ {
+ long now = DateTime.Now.Ticks;
+ if (_dbMovies == null || (now - _dbMovieCacheTime) > 10000)
+ {
+ var allResults = await RequestService.GetAllAsync();
+ allResults = allResults.Where(x => x.Type == RequestType.Movie);
+
+ var distinctResults = allResults.DistinctBy(x => x.ProviderId);
+ _dbMovies = distinctResults.ToDictionary(x => x.ProviderId);
+ _dbMovieCacheTime = now;
+ }
+ return _dbMovies;
+ }
}
}
diff --git a/Ombi/Ombi.Core/Engine/RequestEngine.cs b/Ombi/Ombi.Core/Engine/RequestEngine.cs
new file mode 100644
index 000000000..eeaecfa86
--- /dev/null
+++ b/Ombi/Ombi.Core/Engine/RequestEngine.cs
@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Ombi.Core.Models.Requests;
+using Ombi.Core.Models.Search;
+using Ombi.Core.Requests.Models;
+using Ombi.Store.Entities;
+using Ombi.TheMovieDbApi;
+
+namespace Ombi.Core.Engine
+{
+ public class RequestEngine : IRequestEngine
+ {
+ public RequestEngine(IMovieDbApi movieApi, IRequestService requestService)
+ {
+ MovieApi = movieApi;
+ RequestService = requestService;
+ }
+ private IMovieDbApi MovieApi { get; }
+ private IRequestService RequestService { get; }
+ public async Task RequestMovie(SearchMovieViewModel model)
+ {
+ var movieInfo = await MovieApi.GetMovieInformation(model.Id);
+ if (movieInfo == null)
+ {
+ return new RequestEngineResult
+ {
+ RequestAdded = false,
+ Message = "There was an issue adding this movie!"
+ };
+ //Response.AsJson(new JsonResponseModel
+ //{
+ // Result = false,
+ // Message = "There was an issue adding this movie!"
+ //});
+ }
+ var fullMovieName =
+ $"{movieInfo.title}{(!string.IsNullOrEmpty(movieInfo.release_date) ? $" ({DateTime.Parse(movieInfo.release_date).Year})" : string.Empty)}";
+
+ var existingRequest = await RequestService.CheckRequestAsync(model.Id);
+ if (existingRequest != null)
+ {
+ // check if the current user is already marked as a requester for this movie, if not, add them
+ //if (!existingRequest.UserHasRequested(Username))
+ //{
+ // existingRequest.RequestedUsers.Add(Username);
+ // await RequestService.UpdateRequestAsync(existingRequest);
+ //}
+
+ return new RequestEngineResult
+ {
+ RequestAdded = true,
+
+ };
+ //Response.AsJson(new JsonResponseModel
+ //{
+ // Result = true,
+ // Message =
+ // Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests)
+ // ? $"{fullMovieName} {Ombi.UI.Resources.UI.Search_SuccessfullyAdded}"
+ // : $"{fullMovieName} {Resources.UI.Search_AlreadyRequested}"
+ //});
+ }
+
+
+ // TODO
+ //try
+ //{
+
+ // var content = PlexContentRepository.GetAll();
+ // var movies = PlexChecker.GetPlexMovies(content);
+ // if (PlexChecker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString()))
+ // {
+ // return
+ // Response.AsJson(new JsonResponseModel
+ // {
+ // Result = false,
+ // Message = $"{fullMovieName} is already in Plex!"
+ // });
+ // }
+ //}
+ //catch (Exception e)
+ //{
+ // Log.Error(e);
+ // return
+ // Response.AsJson(new JsonResponseModel
+ // {
+ // Result = false,
+ // Message = string.Format(Resources.UI.Search_CouldNotCheckPlex, fullMovieName, GetMediaServerName())
+ // });
+ //}
+
+ var requestModel = new RequestModel
+ {
+ ProviderId = movieInfo.id,
+ Type = RequestType.Movie,
+ Overview = movieInfo.overview,
+ ImdbId = movieInfo.imdb_id,
+ PosterPath = movieInfo.poster_path,
+ Title = movieInfo.title,
+ ReleaseDate = !string.IsNullOrEmpty(movieInfo.release_date) ? DateTime.Parse(movieInfo.release_date) : DateTime.MinValue,
+ Status = movieInfo.status,
+ RequestedDate = DateTime.UtcNow,
+ Approved = false,
+ //RequestedUsers = new List { Username },
+ Issues = IssueState.None,
+ };
+
+ try
+ {
+ if (ShouldAutoApprove(RequestType.Movie))
+ {
+ // model.Approved = true;
+
+ // var result = await MovieSender.Send(model);
+ // if (result.Result)
+ // {
+ // return await AddRequest(model, settings,
+ // $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
+ // }
+ // if (result.Error)
+
+ // {
+ // return
+ // Response.AsJson(new JsonResponseModel
+ // {
+ // Message = "Could not add movie, please contact your administrator",
+ // Result = false
+ // });
+ // }
+ // if (!result.MovieSendingEnabled)
+ // {
+
+ // return await AddRequest(model, settings, $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
+ // }
+
+ // return Response.AsJson(new JsonResponseModel
+ // {
+ // Result = false,
+ // Message = Resources.UI.Search_CouchPotatoError
+ // });
+ }
+
+
+ return await AddRequest(requestModel, /*settings,*/
+ $"{fullMovieName} has been successfully added!");
+
+ }
+ catch (Exception e)
+ {
+ //Log.Fatal(e);
+ //await FaultQueue.QueueItemAsync(model, movieInfo.Id.ToString(), RequestType.Movie, FaultType.RequestFault, e.Message);
+
+ //await NotificationService.Publish(new NotificationModel
+ //{
+ // DateTime = DateTime.Now,
+ // User = Username,
+ // RequestType = RequestType.Movie,
+ // Title = model.Title,
+ // NotificationType = NotificationType.ItemAddedToFaultQueue
+ //});
+
+ //return Response.AsJson(new JsonResponseModel
+ //{
+ // Result = true,
+ // Message = $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}"
+ //});
+ }
+
+ return null;
+ }
+
+ public bool ShouldAutoApprove(RequestType requestType)
+ {
+ //var admin = Security.HasPermissions(Context.CurrentUser, Permissions.Administrator);
+ //// if the user is an admin, they go ahead and allow auto-approval
+ //if (admin) return true;
+
+ //// check by request type if the category requires approval or not
+ //switch (requestType)
+ //{
+ // case RequestType.Movie:
+ // return Security.HasPermissions(User, Permissions.AutoApproveMovie);
+ // case RequestType.TvShow:
+ // return Security.HasPermissions(User, Permissions.AutoApproveTv);
+ // case RequestType.Album:
+ // return Security.HasPermissions(User, Permissions.AutoApproveAlbum);
+ // default:
+ // return false;
+ return false;
+ }
+
+ private async Task AddRequest(RequestModel model, /*PlexRequestSettings settings,*/ string message)
+ {
+ await RequestService.AddRequestAsync(model);
+
+ //if (ShouldSendNotification(model.Type, settings))
+ //{
+ // var notificationModel = new NotificationModel
+ // {
+ // Title = model.Title,
+ // User = Username,
+ // DateTime = DateTime.Now,
+ // NotificationType = NotificationType.NewRequest,
+ // RequestType = model.Type,
+ // ImgSrc = model.Type == RequestType.Movie ? $"https://image.tmdb.org/t/p/w300/{model.PosterPath}" : model.PosterPath
+ // };
+ // await NotificationService.Publish(notificationModel);
+ //}
+
+ //var limit = await RequestLimitRepo.GetAllAsync();
+ //var usersLimit = limit.FirstOrDefault(x => x.Username == Username && x.RequestType == model.Type);
+ //if (usersLimit == null)
+ //{
+ // await RequestLimitRepo.InsertAsync(new RequestLimit
+ // {
+ // Username = Username,
+ // RequestType = model.Type,
+ // FirstRequestDate = DateTime.UtcNow,
+ // RequestCount = 1
+ // });
+ //}
+ //else
+ //{
+ // usersLimit.RequestCount++;
+ // await RequestLimitRepo.UpdateAsync(usersLimit);
+ //}
+
+ return new RequestEngineResult{RequestAdded = true};
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Core/Engine/RequestEngineResult.cs b/Ombi/Ombi.Core/Engine/RequestEngineResult.cs
new file mode 100644
index 000000000..f2f2329a7
--- /dev/null
+++ b/Ombi/Ombi.Core/Engine/RequestEngineResult.cs
@@ -0,0 +1,8 @@
+namespace Ombi.Core.Engine
+{
+ public class RequestEngineResult
+ {
+ public bool RequestAdded { get; set; }
+ public string Message { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Core/Models/Requests/IRequestService.cs b/Ombi/Ombi.Core/Models/Requests/IRequestService.cs
new file mode 100644
index 000000000..1cc56dea8
--- /dev/null
+++ b/Ombi/Ombi.Core/Models/Requests/IRequestService.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Ombi.Core.Models.Requests;
+using Ombi.Store.Entities;
+
+namespace Ombi.Core.Requests.Models
+{
+ public interface IRequestService
+ {
+ int AddRequest(RequestModel model);
+ Task AddRequestAsync(RequestModel model);
+ void BatchDelete(IEnumerable model);
+ void BatchUpdate(IEnumerable model);
+ RequestModel CheckRequest(int providerId);
+ RequestModel CheckRequest(string musicId);
+ Task CheckRequestAsync(int providerId);
+ Task CheckRequestAsync(string musicId);
+ void DeleteRequest(RequestModel request);
+ Task DeleteRequestAsync(RequestModel request);
+ RequestModel Get(int id);
+ IEnumerable GetAll();
+ Task> GetAllAsync();
+ Task GetAsync(int id);
+ RequestBlobs UpdateRequest(RequestModel model);
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Core/Models/Requests/JsonRequestService.cs b/Ombi/Ombi.Core/Models/Requests/JsonRequestService.cs
new file mode 100644
index 000000000..f5418e74a
--- /dev/null
+++ b/Ombi/Ombi.Core/Models/Requests/JsonRequestService.cs
@@ -0,0 +1,174 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Ombi.Core.Requests.Models;
+using Ombi.Helpers;
+using Ombi.Store.Entities;
+using Ombi.Store.Repository;
+
+namespace Ombi.Core.Models.Requests
+{
+ public class JsonRequestService : IRequestService
+ {
+ public JsonRequestService(IRequestRepository repo)
+ {
+ Repo = repo;
+ }
+ private IRequestRepository Repo { get; }
+ public int AddRequest(RequestModel model)
+ {
+ var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId };
+ var id = Repo.Insert(entity);
+
+ return id.Id;
+ }
+
+ public async Task AddRequestAsync(RequestModel model)
+ {
+ var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId };
+ var id = await Repo.InsertAsync(entity).ConfigureAwait(false);
+
+ return id.Id;
+ }
+
+ public RequestModel CheckRequest(int providerId)
+ {
+ var blobs = Repo.GetAll();
+ var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId); if (blob == null)
+ {
+ return null;
+ }
+ var model = ByteConverterHelper.ReturnObject(blob.Content);
+ model.Id = blob.Id;
+ return model;
+ }
+
+ public async Task CheckRequestAsync(int providerId)
+ {
+ var blobs = await Repo.GetAllAsync().ConfigureAwait(false);
+ var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId); if (blob == null)
+ {
+ return null;
+ }
+ var model = ByteConverterHelper.ReturnObject(blob.Content);
+ model.Id = blob.Id;
+ return model;
+ }
+
+ public RequestModel CheckRequest(string musicId)
+ {
+ var blobs = Repo.GetAll();
+ var blob = blobs.FirstOrDefault(x => x.MusicId == musicId); if (blob == null)
+ {
+ return null;
+ }
+ var model = ByteConverterHelper.ReturnObject(blob.Content);
+ model.Id = blob.Id;
+ return model;
+ }
+
+ public async Task CheckRequestAsync(string musicId)
+ {
+ var blobs = await Repo.GetAllAsync().ConfigureAwait(false);
+ var blob = blobs.FirstOrDefault(x => x.MusicId == musicId);
+
+ if (blob == null)
+ {
+ return null;
+ }
+ var model = ByteConverterHelper.ReturnObject(blob.Content);
+ model.Id = blob.Id;
+ return model;
+ }
+
+ public void DeleteRequest(RequestModel request)
+ {
+ var blob = Repo.Get(request.Id);
+ Repo.Delete(blob);
+ }
+
+ public async Task DeleteRequestAsync(RequestModel request)
+ {
+ var blob = await Repo.GetAsync(request.Id).ConfigureAwait(false);
+ Repo.Delete(blob);
+ }
+
+ public RequestBlobs UpdateRequest(RequestModel model)
+ {
+ var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id };
+ return Repo.Update(entity);
+ }
+
+ public RequestModel Get(int id)
+ {
+ var blob = Repo.Get(id);
+ if (blob == null)
+ {
+ return new RequestModel();
+ }
+ var model = ByteConverterHelper.ReturnObject(blob.Content);
+ model.Id = blob.Id; // They should always be the same, but for somereason a user didn't have it in the db https://github.com/tidusjar/Ombi/issues/862#issuecomment-269743847
+ return model;
+ }
+
+ public async Task GetAsync(int id)
+ {
+ var blob = await Repo.GetAsync(id).ConfigureAwait(false);
+ if (blob == null)
+ {
+ return new RequestModel();
+ }
+ var model = ByteConverterHelper.ReturnObject(blob.Content);
+ model.Id = blob.Id;
+ return model;
+ }
+
+ public IEnumerable GetAll()
+ {
+ var blobs = Repo.GetAll().ToList();
+ var retVal = new List();
+
+ foreach (var b in blobs)
+ {
+ if (b == null)
+ {
+ continue;
+ }
+ var model = ByteConverterHelper.ReturnObject(b.Content);
+ model.Id = b.Id;
+ retVal.Add(model);
+ }
+ return retVal;
+ }
+
+ public async Task> GetAllAsync()
+ {
+ var blobs = await Repo.GetAllAsync().ConfigureAwait(false);
+ var retVal = new List();
+
+ foreach (var b in blobs)
+ {
+ if (b == null)
+ {
+ continue;
+ }
+ var model = ByteConverterHelper.ReturnObject(b.Content);
+ model.Id = b.Id;
+ retVal.Add(model);
+ }
+ return retVal;
+ }
+
+ public void BatchUpdate(IEnumerable model)
+ {
+ var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList();
+ Repo.UpdateAll(entities);
+ }
+
+ public void BatchDelete(IEnumerable model)
+ {
+ var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList();
+ Repo.DeleteAll(entities);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Core/Models/Requests/RequestModel.cs b/Ombi/Ombi.Core/Models/Requests/RequestModel.cs
new file mode 100644
index 000000000..1eb9442e6
--- /dev/null
+++ b/Ombi/Ombi.Core/Models/Requests/RequestModel.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
+using Ombi.Store.Entities;
+
+namespace Ombi.Core.Models.Requests
+{
+ public class RequestModel : Entity
+ {
+ public RequestModel()
+ {
+ RequestedUsers = new List();
+ Episodes = new List();
+ }
+
+ public int ProviderId { get; set; }
+ public string ImdbId { get; set; }
+ public string TvDbId { get; set; }
+ public string Overview { get; set; }
+ public string Title { get; set; }
+ public string PosterPath { get; set; }
+ public DateTime ReleaseDate { get; set; }
+ public RequestType Type { get; set; }
+ public string Status { get; set; }
+ public bool Approved { get; set; }
+
+ public DateTime RequestedDate { get; set; }
+ public bool Available { get; set; }
+ public IssueState Issues { get; set; }
+ public string OtherMessage { get; set; }
+ public string AdminNote { get; set; }
+ public int[] SeasonList { get; set; }
+ public int SeasonCount { get; set; }
+ public string SeasonsRequested { get; set; }
+ public string MusicBrainzId { get; set; }
+ public List RequestedUsers { get; set; }
+ public string ArtistName { get; set; }
+ public string ArtistId { get; set; }
+ public int IssueId { get; set; }
+ public List Episodes { get; set; }
+ public bool Denied { get; set; }
+ public string DeniedReason { get; set; }
+ ///
+ /// For TV Shows with a custom root folder
+ ///
+ ///
+ /// The root folder selected.
+ ///
+ public int RootFolderSelected { get; set; }
+
+ [JsonIgnore]
+ public List AllUsers
+ {
+ get
+ {
+ var u = new List();
+ if (RequestedUsers != null && RequestedUsers.Any())
+ {
+ u.AddRange(RequestedUsers);
+ }
+ return u;
+ }
+ }
+
+ [JsonIgnore]
+ public bool CanApprove => !Approved && !Available;
+
+ public string ReleaseId { get; set; }
+
+ public bool UserHasRequested(string username)
+ {
+ return AllUsers.Any(x => x.Equals(username, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+
+
+
+ public static class RequestTypeDisplay
+ {
+ public static string GetString(this RequestType type)
+ {
+ switch (type)
+ {
+ case RequestType.Movie:
+ return "Movie";
+ case RequestType.TvShow:
+ return "TV Show";
+ case RequestType.Album:
+ return "Album";
+ default:
+ return string.Empty;
+ }
+ }
+ }
+
+ public enum IssueState
+ {
+ None = 99,
+ WrongAudio = 0,
+ NoSubtitles = 1,
+ WrongContent = 2,
+ PlaybackIssues = 3,
+ Other = 4, // Provide a message
+ }
+
+ public class EpisodesModel : IEquatable
+ {
+ public int SeasonNumber { get; set; }
+ public int EpisodeNumber { get; set; }
+ public bool Equals(EpisodesModel other)
+ {
+ // Check whether the compared object is null.
+ if (ReferenceEquals(other, null)) return false;
+
+ //Check whether the compared object references the same data.
+ if (ReferenceEquals(this, other)) return true;
+
+ //Check whether the properties are equal.
+ return SeasonNumber.Equals(other.SeasonNumber) && EpisodeNumber.Equals(other.EpisodeNumber);
+ }
+
+ public override int GetHashCode()
+ {
+ var hashSeason = SeasonNumber.GetHashCode();
+ var hashEp = EpisodeNumber.GetHashCode();
+
+ //Calculate the hash code.
+ return hashSeason + hashEp;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Core/Ombi.Core.csproj b/Ombi/Ombi.Core/Ombi.Core.csproj
index 714b40cd8..078f56b95 100644
--- a/Ombi/Ombi.Core/Ombi.Core.csproj
+++ b/Ombi/Ombi.Core/Ombi.Core.csproj
@@ -2,9 +2,18 @@
netstandard1.4
+
+
+
+
+
+
+
+
+
diff --git a/Ombi/Ombi.Helpers/ByteConverterHelper.cs b/Ombi/Ombi.Helpers/ByteConverterHelper.cs
new file mode 100644
index 000000000..07db8fd7d
--- /dev/null
+++ b/Ombi/Ombi.Helpers/ByteConverterHelper.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Text;
+using Newtonsoft.Json;
+
+namespace Ombi.Helpers
+{
+ public class ByteConverterHelper
+ {
+ public static byte[] ReturnBytes(object obj)
+ {
+ var json = JsonConvert.SerializeObject(obj);
+ var bytes = Encoding.UTF8.GetBytes(json);
+
+ return bytes;
+ }
+
+ public static T ReturnObject(byte[] bytes)
+ {
+ var json = Encoding.UTF8.GetString(bytes);
+ var model = JsonConvert.DeserializeObject(json);
+ return model;
+ }
+ public static string ReturnFromBytes(byte[] bytes)
+ {
+ return Encoding.UTF8.GetString(bytes);
+ }
+ }
+}
diff --git a/Ombi/Ombi.Helpers/LinqHelpers.cs b/Ombi/Ombi.Helpers/LinqHelpers.cs
new file mode 100644
index 000000000..279d161b7
--- /dev/null
+++ b/Ombi/Ombi.Helpers/LinqHelpers.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+
+namespace Ombi.Helpers
+{
+ public static class LinqHelpers
+ {
+ public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector)
+ {
+ HashSet knownKeys = new HashSet();
+ foreach (TSource source1 in source)
+ {
+ if (knownKeys.Add(keySelector(source1)))
+ yield return source1;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Helpers/Ombi.Helpers.csproj b/Ombi/Ombi.Helpers/Ombi.Helpers.csproj
new file mode 100644
index 000000000..498e443c1
--- /dev/null
+++ b/Ombi/Ombi.Helpers/Ombi.Helpers.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netstandard1.4
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Ombi/Ombi.Store/Context/IOmbiContext.cs b/Ombi/Ombi.Store/Context/IOmbiContext.cs
new file mode 100644
index 000000000..c9dff7bca
--- /dev/null
+++ b/Ombi/Ombi.Store/Context/IOmbiContext.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Ombi.Store.Entities;
+
+namespace Ombi.Store.Context
+{
+ public interface IOmbiContext : IDisposable
+ {
+ int SaveChanges();
+ Task SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));
+ DbSet Requests { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Store/Context/OmbiContext.cs b/Ombi/Ombi.Store/Context/OmbiContext.cs
new file mode 100644
index 000000000..ec8903d3a
--- /dev/null
+++ b/Ombi/Ombi.Store/Context/OmbiContext.cs
@@ -0,0 +1,25 @@
+using Microsoft.EntityFrameworkCore;
+using Ombi.Store.Entities;
+
+namespace Ombi.Store.Context
+{
+ public class OmbiContext : DbContext, IOmbiContext
+ {
+ private static bool _created = false;
+ public OmbiContext()
+ {
+ if(!_created)
+ {
+ _created = true;
+ //Database.EnsureDeleted();
+ Database.EnsureCreated();
+ }
+ }
+ public DbSet Requests { get; set; }
+
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+ optionsBuilder.UseSqlite("Data Source=Ombi.db");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Store/Entities/Entity.cs b/Ombi/Ombi.Store/Entities/Entity.cs
new file mode 100644
index 000000000..8e1cd2887
--- /dev/null
+++ b/Ombi/Ombi.Store/Entities/Entity.cs
@@ -0,0 +1,10 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Ombi.Store.Entities
+{
+ public abstract class Entity
+ {
+ [Key]
+ public int Id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Store/Entities/RequestBlobs.cs b/Ombi/Ombi.Store/Entities/RequestBlobs.cs
new file mode 100644
index 000000000..16ecff989
--- /dev/null
+++ b/Ombi/Ombi.Store/Entities/RequestBlobs.cs
@@ -0,0 +1,20 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Ombi.Store.Entities
+{
+ [Table("RequestBlobs")]
+ public class RequestBlobs : Entity
+ {
+ public int ProviderId { get; set; }
+ public byte[] Content { get; set; }
+ public RequestType Type { get; set; }
+ public string MusicId { get; set; }
+
+ }
+ public enum RequestType
+ {
+ Movie,
+ TvShow,
+ Album
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Store/Ombi.Store.csproj b/Ombi/Ombi.Store/Ombi.Store.csproj
new file mode 100644
index 000000000..7d9da619e
--- /dev/null
+++ b/Ombi/Ombi.Store/Ombi.Store.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard1.4
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Ombi/Ombi.Store/Repository/IRequestRepository.cs b/Ombi/Ombi.Store/Repository/IRequestRepository.cs
new file mode 100644
index 000000000..4e1ac2798
--- /dev/null
+++ b/Ombi/Ombi.Store/Repository/IRequestRepository.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Ombi.Store.Entities;
+
+namespace Ombi.Store.Repository
+{
+ public interface IRequestRepository
+ {
+ void Delete(RequestBlobs entity);
+ void DeleteAll(IEnumerable entity);
+ RequestBlobs Get(int id);
+ IEnumerable GetAll();
+ Task> GetAllAsync();
+ Task GetAsync(int id);
+ RequestBlobs Insert(RequestBlobs entity);
+ Task InsertAsync(RequestBlobs entity);
+ RequestBlobs Update(RequestBlobs entity);
+ void UpdateAll(IEnumerable entity);
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.Store/Repository/RequestJsonRepository.cs b/Ombi/Ombi.Store/Repository/RequestJsonRepository.cs
new file mode 100644
index 000000000..f16b96d51
--- /dev/null
+++ b/Ombi/Ombi.Store/Repository/RequestJsonRepository.cs
@@ -0,0 +1,126 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Ombi.Store.Context;
+using Ombi.Store.Entities;
+
+namespace Ombi.Store.Repository
+{
+ public class RequestJsonRepository : IRequestRepository
+ {
+ //private ICacheProvider Cache { get; }
+
+ public RequestJsonRepository(IOmbiContext ctx)
+ {
+ Db = ctx;
+ }
+
+ private IOmbiContext Db { get; }
+
+ public RequestBlobs Insert(RequestBlobs entity)
+ {
+
+ var id = Db.Requests.Add(entity);
+ Db.SaveChanges();
+ return id.Entity;
+
+ }
+
+ public async Task InsertAsync(RequestBlobs entity)
+ {
+
+ var id = await Db.Requests.AddAsync(entity).ConfigureAwait(false);
+ await Db.SaveChangesAsync();
+ return id.Entity;
+
+ }
+
+ public IEnumerable GetAll()
+ {
+ //var key = "GetAll";
+ //var item = Cache.GetOrSet(key, () =>
+ //{
+
+ var page = Db.Requests.ToList();
+ return page;
+
+ //}, 5);
+ //return item;
+ }
+
+ public async Task> GetAllAsync()
+ {
+ //var key = "GetAll";
+ //var item = await Cache.GetOrSetAsync(key, async () =>
+ //{
+
+ var page = await Db.Requests.ToListAsync().ConfigureAwait(false);
+ return page;
+
+ //}, 5);
+ //return item;
+ }
+
+ public RequestBlobs Get(int id)
+ {
+ //var key = "Get" + id;
+ //var item = Cache.GetOrSet(key, () =>
+ //{
+
+ var page = Db.Requests.Find(id);
+ return page;
+
+ //}, 5);
+ //return item;
+ }
+
+ public async Task GetAsync(int id)
+ {
+ //var key = "Get" + id;
+ //var item = await Cache.GetOrSetAsync(key, async () =>
+ //{
+
+ var page = await Db.Requests.FindAsync(id).ConfigureAwait(false);
+ return page;
+
+ //}, 5);
+ //return item;
+ }
+
+ public void Delete(RequestBlobs entity)
+ {
+ //ResetCache();
+
+ Db.Requests.Remove(entity);
+ Db.SaveChanges();
+
+ }
+
+ public RequestBlobs Update(RequestBlobs entity)
+ {
+
+ return Db.Requests.Update(entity).Entity;
+ Db.SaveChanges();
+
+ }
+
+ public void UpdateAll(IEnumerable entity)
+ {
+
+ Db.Requests.UpdateRange(entity);
+ Db.SaveChanges();
+
+ }
+
+
+
+ public void DeleteAll(IEnumerable entity)
+ {
+
+ Db.Requests.RemoveRange(entity);
+ Db.SaveChanges();
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi/Ombi.TheMovieDbApi/IMovieDbApi.cs b/Ombi/Ombi.TheMovieDbApi/IMovieDbApi.cs
index 3be66d0c1..219bc5a41 100644
--- a/Ombi/Ombi.TheMovieDbApi/IMovieDbApi.cs
+++ b/Ombi/Ombi.TheMovieDbApi/IMovieDbApi.cs
@@ -1,33 +1,16 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2017 Jamie Rees
-// File: IMovieDbApi.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.Threading.Tasks;
+using Ombi.Api;
+using Ombi.TheMovieDbApi.Models;
+
namespace Ombi.TheMovieDbApi
{
public interface IMovieDbApi
{
-
+ Task GetMovieInformation(int movieId);
+ Task> NowPlaying();
+ Task> PopularMovies();
+ Task> SearchMovie(string searchTerm);
+ Task> TopRated();
+ Task> Upcoming();
}
}
\ No newline at end of file
diff --git a/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj b/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj
index 3197c51cf..16516740e 100644
--- a/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj
+++ b/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj
@@ -2,6 +2,7 @@
netstandard1.4
+
diff --git a/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs
index d8e4e5709..dc68c5f52 100644
--- a/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs
+++ b/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs
@@ -6,7 +6,7 @@ using Ombi.TheMovieDbApi.Models;
namespace Ombi.TheMovieDbApi
{
- public class TheMovieDbApi
+ public class TheMovieDbApi : IMovieDbApi
{
public TheMovieDbApi()
{
@@ -19,7 +19,7 @@ namespace Ombi.TheMovieDbApi
public async Task GetMovieInformation(int movieId)
{
var url = BaseUri.ChangePath("movie/{0}", movieId.ToString());
- AddHeaders(url);
+ url = AddHeaders(url);
return await Api.Get(url);
}
diff --git a/Ombi/Ombi.sln b/Ombi/Ombi.sln
index d4488bfca..8857dcc07 100644
--- a/Ombi/Ombi.sln
+++ b/Ombi/Ombi.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26228.9
+VisualStudioVersion = 15.0.26228.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
EndProject
@@ -20,6 +20,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.TheMovieDbApi", "Ombi.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api", "Ombi.Api\Ombi.Api.csproj", "{EA31F915-31F9-4318-B521-1500CDF40DDF}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Helpers", "Ombi.Helpers\Ombi.Helpers.csproj", "{C182B435-1FAB-49C5-9BF9-F7F5C6EF3C94}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Store", "Ombi.Store\Ombi.Store.csproj", "{68086581-1EFD-4390-8100-47F87D1CB628}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -42,6 +46,14 @@ Global
{EA31F915-31F9-4318-B521-1500CDF40DDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EA31F915-31F9-4318-B521-1500CDF40DDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EA31F915-31F9-4318-B521-1500CDF40DDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C182B435-1FAB-49C5-9BF9-F7F5C6EF3C94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C182B435-1FAB-49C5-9BF9-F7F5C6EF3C94}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C182B435-1FAB-49C5-9BF9-F7F5C6EF3C94}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C182B435-1FAB-49C5-9BF9-F7F5C6EF3C94}.Release|Any CPU.Build.0 = Release|Any CPU
+ {68086581-1EFD-4390-8100-47F87D1CB628}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {68086581-1EFD-4390-8100-47F87D1CB628}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {68086581-1EFD-4390-8100-47F87D1CB628}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {68086581-1EFD-4390-8100-47F87D1CB628}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Ombi/Ombi/Controllers/RequestController.cs b/Ombi/Ombi/Controllers/RequestController.cs
new file mode 100644
index 000000000..34e4465d2
--- /dev/null
+++ b/Ombi/Ombi/Controllers/RequestController.cs
@@ -0,0 +1,23 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Ombi.Core.Engine;
+using Ombi.Core.Models.Search;
+
+namespace Ombi.Controllers
+{
+ public class RequestController : BaseApiController
+ {
+ public RequestController(IRequestEngine engine)
+ {
+ RequestEngine = engine;
+ }
+
+ private IRequestEngine RequestEngine { get; }
+
+ [HttpPost("movie")]
+ public async Task SearchMovie([FromBody]SearchMovieViewModel movie)
+ {
+ return await RequestEngine.RequestMovie(movie);
+ }
+ }
+}
diff --git a/Ombi/Ombi/Ombi.csproj b/Ombi/Ombi/Ombi.csproj
index 6dd5183f2..bfb0278da 100644
--- a/Ombi/Ombi/Ombi.csproj
+++ b/Ombi/Ombi/Ombi.csproj
@@ -12,6 +12,8 @@
+
+
diff --git a/Ombi/Ombi/Startup.cs b/Ombi/Ombi/Startup.cs
index a4ed7be34..7fb5c4e52 100644
--- a/Ombi/Ombi/Startup.cs
+++ b/Ombi/Ombi/Startup.cs
@@ -7,11 +7,18 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Ombi.Core;
+using Ombi.Core.Engine;
+using Ombi.Core.Models.Requests;
+using Ombi.Core.Requests.Models;
+using Ombi.Store.Context;
+using Ombi.Store.Repository;
+using Ombi.TheMovieDbApi;
namespace Ombi
{
@@ -25,6 +32,13 @@ namespace Ombi
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
+
+ using (var ctx = new OmbiContext())
+ {
+ ctx.Database.EnsureCreated();
+ ctx.Database.Migrate();
+ }
+
}
public IConfigurationRoot Configuration { get; }
@@ -34,7 +48,13 @@ namespace Ombi
{
// Add framework services.
services.AddMvc();
+ services.AddEntityFrameworkSqlite().AddDbContext();
services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
diff --git a/Ombi/Ombi/app/app.module.ts b/Ombi/Ombi/app/app.module.ts
index 8741b8fb9..2bc3967a6 100644
--- a/Ombi/Ombi/app/app.module.ts
+++ b/Ombi/Ombi/app/app.module.ts
@@ -13,6 +13,7 @@ import { PageNotFoundComponent } from './errors/not-found.component';
// Services
import { SearchService } from './services/search.service';
+import { RequestService } from './services/request.service';
import { ButtonModule } from 'primeng/primeng';
import { MenubarModule } from 'primeng/components/menubar/menubar';
@@ -40,7 +41,8 @@ const routes: Routes = [
SearchComponent
],
providers: [
- SearchService
+ SearchService,
+ RequestService
],
bootstrap: [AppComponent]
})
diff --git a/Ombi/Ombi/app/interfaces/IRequestEngineResult.ts b/Ombi/Ombi/app/interfaces/IRequestEngineResult.ts
new file mode 100644
index 000000000..b29f3509d
--- /dev/null
+++ b/Ombi/Ombi/app/interfaces/IRequestEngineResult.ts
@@ -0,0 +1,4 @@
+export interface IRequestEngineResult {
+ requestAdded: boolean,
+ message: string
+}
\ No newline at end of file
diff --git a/Ombi/Ombi/app/search/interfaces/ISearchMovieResult.ts b/Ombi/Ombi/app/interfaces/ISearchMovieResult.ts
similarity index 100%
rename from Ombi/Ombi/app/search/interfaces/ISearchMovieResult.ts
rename to Ombi/Ombi/app/interfaces/ISearchMovieResult.ts
diff --git a/Ombi/Ombi/app/search/search.component.ts b/Ombi/Ombi/app/search/search.component.ts
index ccee48c79..c7152dcea 100644
--- a/Ombi/Ombi/app/search/search.component.ts
+++ b/Ombi/Ombi/app/search/search.component.ts
@@ -5,22 +5,25 @@ import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import { SearchService } from '../services/search.service';
+import { RequestService } from '../services/request.service';
-import { ISearchMovieResult } from './interfaces/ISearchMovieResult';
+import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
+import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
@Component({
selector: 'ombi',
moduleId: module.id,
templateUrl: './search.component.html',
- providers: [SearchService]
+ providers: [SearchService, RequestService]
})
export class SearchComponent implements OnInit {
searchText: string;
searchChanged: Subject = new Subject();
movieResults: ISearchMovieResult[];
+ result: IRequestEngineResult;
- constructor(private searchService: SearchService) {
+ constructor(private searchService: SearchService, private requestService: RequestService) {
this.searchChanged
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
.distinctUntilChanged() // only emit if value is different from previous value
@@ -37,6 +40,10 @@ export class SearchComponent implements OnInit {
ngOnInit(): void {
this.searchText = "";
this.movieResults = [];
+ this.result = {
+ message: "",
+ requestAdded:false
+ }
}
search(text: any) {
@@ -44,7 +51,7 @@ export class SearchComponent implements OnInit {
}
request(searchResult: ISearchMovieResult) {
- console.log(searchResult);
+ this.requestService.requestMovie(searchResult).subscribe(x => this.result = x);
}
popularMovies() {
diff --git a/Ombi/Ombi/app/services/request.service.ts b/Ombi/Ombi/app/services/request.service.ts
new file mode 100644
index 000000000..4af6c70b7
--- /dev/null
+++ b/Ombi/Ombi/app/services/request.service.ts
@@ -0,0 +1,18 @@
+import { Injectable } from '@angular/core';
+import { Http } from '@angular/http';
+import { Observable } from 'rxjs/Rx';
+
+import { ServiceHelpers } from './service.helpers';
+import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
+import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
+
+@Injectable()
+export class RequestService {
+ constructor(private http: Http) {
+ }
+
+ requestMovie(movie: ISearchMovieResult): Observable {
+ return this.http.post('/api/Request/Movie/', JSON.stringify(movie), ServiceHelpers.RequestOptions).map(ServiceHelpers.extractData);
+ }
+
+}
\ No newline at end of file
diff --git a/Ombi/Ombi/app/services/search.service.ts b/Ombi/Ombi/app/services/search.service.ts
index 6e401abe7..f684fa235 100644
--- a/Ombi/Ombi/app/services/search.service.ts
+++ b/Ombi/Ombi/app/services/search.service.ts
@@ -3,7 +3,7 @@ import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { ServiceHelpers } from './service.helpers';
-import { ISearchMovieResult } from '../search/interfaces/ISearchMovieResult';
+import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
@Injectable()
export class SearchService {
diff --git a/appveyor.yml b/appveyor.yml
index 6c0f2e7eb..46f31155b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -21,10 +21,10 @@ before_build:
build_script:
- dotnet build
after_build:
-- dotnet publish -c Release -r win10-x64
-- dotnet publish -c Release -r osx.10.12-x64
-- dotnet publish -c Release -r ubuntu.16.10-x64
-- dotnet publish -c Release -r debian.8-x64
+- dotnet publish -c Release /p:AppRuntimeIdentifier=win10-x64
+- dotnet publish -c Release /p:AppRuntimeIdentifier=osx.10.12-x64
+- dotnet publish -c Release /p:AppRuntimeIdentifier=ubuntu.16.10-x64
+- dotnet publish -c Release /p:AppRuntimeIdentifier=debian.8-x64
- cmd: >-
7z a Ombi_windows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.1\win10-x64\publish