mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 12:59:39 -07:00
Revert "Merge branch 'DotNetCore' into dev"
This reverts commit90827aa7f9
, reversing changes made to205f72a83d
.
This commit is contained in:
parent
ab67ff692c
commit
2e5e113743
93 changed files with 12 additions and 11559 deletions
16
Ombi/.gitignore
vendored
16
Ombi/.gitignore
vendored
|
@ -1,16 +0,0 @@
|
||||||
../app/**/*.js
|
|
||||||
../app/**/*.js.map
|
|
||||||
../wwwroot/**
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
../node_modules
|
|
||||||
../bower_components
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/.sass-cache
|
|
||||||
/connect.lock
|
|
||||||
/coverage/*
|
|
||||||
/libpeerconnection.log
|
|
||||||
npm-debug.log
|
|
||||||
testem.log
|
|
||||||
/typings
|
|
|
@ -1,6 +0,0 @@
|
||||||
;https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/
|
|
||||||
cd ..
|
|
||||||
dotnet restore
|
|
||||||
dotnet publish -c Release /p:AppRuntimeIdentifier=win10-x64
|
|
||||||
|
|
||||||
exit
|
|
|
@ -1,9 +0,0 @@
|
||||||
;https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/
|
|
||||||
cd ..
|
|
||||||
dotnet restore
|
|
||||||
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
|
|
||||||
|
|
||||||
exit
|
|
|
@ -1,29 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Ombi.Api
|
|
||||||
{
|
|
||||||
public class Api
|
|
||||||
{
|
|
||||||
public static JsonSerializerSettings Settings = new JsonSerializerSettings
|
|
||||||
{
|
|
||||||
NullValueHandling = NullValueHandling.Ignore
|
|
||||||
};
|
|
||||||
public async Task<T> Get<T>(Uri uri)
|
|
||||||
{
|
|
||||||
var h = new HttpClient();
|
|
||||||
var response = await h.GetAsync(uri);
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
// Logging
|
|
||||||
}
|
|
||||||
var receiveString = await response.Content.ReadAsStringAsync();
|
|
||||||
return JsonConvert.DeserializeObject<T>(receiveString, Settings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
#region Copyright
|
|
||||||
// /************************************************************************
|
|
||||||
// Copyright (c) 2017 Jamie Rees
|
|
||||||
// File: ApiHelper.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;
|
|
||||||
|
|
||||||
namespace Ombi.Api
|
|
||||||
{
|
|
||||||
public static class ApiHelper
|
|
||||||
{
|
|
||||||
public static Uri ChangePath(this Uri uri, string path, params string[] args)
|
|
||||||
{
|
|
||||||
var builder = new UriBuilder(uri);
|
|
||||||
|
|
||||||
if (args != null && args.Length > 0)
|
|
||||||
{
|
|
||||||
builder.Path = builder.Path + string.Format(path, args);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builder.Path += path;
|
|
||||||
}
|
|
||||||
return builder.Uri;
|
|
||||||
}
|
|
||||||
public static Uri ChangePath(this Uri uri, string path)
|
|
||||||
{
|
|
||||||
return ChangePath(uri, path, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri AddQueryParameter(this Uri uri, string parameter, string value)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(parameter) || string.IsNullOrEmpty(value)) return uri;
|
|
||||||
var builder = new UriBuilder(uri);
|
|
||||||
var startingTag = string.Empty;
|
|
||||||
var hasQuery = false;
|
|
||||||
if (string.IsNullOrEmpty(builder.Query))
|
|
||||||
{
|
|
||||||
startingTag = "?";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hasQuery = true;
|
|
||||||
startingTag = builder.Query.Contains("?") ? "&" : "?";
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Query = hasQuery
|
|
||||||
? $"{builder.Query}{startingTag}{parameter}={value}"
|
|
||||||
: $"{startingTag}{parameter}={value}";
|
|
||||||
return builder.Uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard1.4</TargetFramework>
|
|
||||||
<!--<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>-->
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,15 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Ombi.Core.Models.Search;
|
|
||||||
|
|
||||||
namespace Ombi.Core
|
|
||||||
{
|
|
||||||
public interface IMovieEngine
|
|
||||||
{
|
|
||||||
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
|
|
||||||
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
|
|
||||||
Task<IEnumerable<SearchMovieViewModel>> ProcessMovieSearch(string search);
|
|
||||||
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
|
|
||||||
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Ombi.Core.Models.Search;
|
|
||||||
using Ombi.Store.Entities;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Engine
|
|
||||||
{
|
|
||||||
public interface IRequestEngine
|
|
||||||
{
|
|
||||||
Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model);
|
|
||||||
bool ShouldAutoApprove(RequestType requestType);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,191 +0,0 @@
|
||||||
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.Engine
|
|
||||||
{
|
|
||||||
public class MovieEngine : IMovieEngine
|
|
||||||
{
|
|
||||||
|
|
||||||
public MovieEngine(IRequestService service)
|
|
||||||
{
|
|
||||||
RequestService = service;
|
|
||||||
}
|
|
||||||
private IRequestService RequestService { get; }
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> ProcessMovieSearch(string search)
|
|
||||||
{
|
|
||||||
var api = new TheMovieDbApi.TheMovieDbApi();
|
|
||||||
var result = await api.SearchMovie(search);
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
return await TransformMovieResultsToResponse(result.results);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies()
|
|
||||||
{
|
|
||||||
var api = new TheMovieDbApi.TheMovieDbApi();
|
|
||||||
var result = await api.PopularMovies();
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
return await TransformMovieResultsToResponse(result.results);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
|
|
||||||
{
|
|
||||||
var api = new TheMovieDbApi.TheMovieDbApi();
|
|
||||||
var result = await api.TopRated();
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
return await TransformMovieResultsToResponse(result.results);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
|
|
||||||
{
|
|
||||||
var api = new TheMovieDbApi.TheMovieDbApi();
|
|
||||||
var result = await api.Upcoming();
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
return await TransformMovieResultsToResponse(result.results);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
|
|
||||||
{
|
|
||||||
var api = new TheMovieDbApi.TheMovieDbApi();
|
|
||||||
var result = await api.NowPlaying();
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
return await TransformMovieResultsToResponse(result.results);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task<List<SearchMovieViewModel>> TransformMovieResultsToResponse(IEnumerable<SearchResult> movies)
|
|
||||||
{
|
|
||||||
await Task.Yield();
|
|
||||||
var viewMovies = new List<SearchMovieViewModel>();
|
|
||||||
//var counter = 0;
|
|
||||||
Dictionary<int, RequestModel> dbMovies = await RequestedMovies();
|
|
||||||
foreach (var movie in movies)
|
|
||||||
{
|
|
||||||
var viewMovie = new SearchMovieViewModel
|
|
||||||
{
|
|
||||||
Adult = movie.adult,
|
|
||||||
BackdropPath = movie.backdrop_path,
|
|
||||||
Id = movie.id,
|
|
||||||
OriginalLanguage = movie.original_language,
|
|
||||||
OriginalTitle = movie.original_title,
|
|
||||||
Overview = movie.overview,
|
|
||||||
Popularity = movie.popularity,
|
|
||||||
PosterPath = movie.poster_path,
|
|
||||||
ReleaseDate = string.IsNullOrEmpty(movie.release_date) ? DateTime.MinValue : DateTime.Parse(movie.release_date),
|
|
||||||
Title = movie.title,
|
|
||||||
Video = movie.video,
|
|
||||||
VoteAverage = movie.vote_average,
|
|
||||||
VoteCount = movie.vote_count
|
|
||||||
};
|
|
||||||
viewMovies.Add(viewMovie);
|
|
||||||
|
|
||||||
//if (counter <= 5) // Let's only do it for the first 5 items
|
|
||||||
//{
|
|
||||||
// var movieInfo = MovieApi.GetMovieInformationWithVideos(movie.Id);
|
|
||||||
|
|
||||||
// // TODO needs to be careful about this, it's adding extra time to search...
|
|
||||||
// // https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
|
|
||||||
// viewMovie.ImdbId = movieInfo?.imdb_id;
|
|
||||||
// viewMovie.Homepage = movieInfo?.homepage;
|
|
||||||
// var videoId = movieInfo?.video ?? false
|
|
||||||
// ? movieInfo?.videos?.results?.FirstOrDefault()?.key
|
|
||||||
// : string.Empty;
|
|
||||||
|
|
||||||
// viewMovie.Trailer = string.IsNullOrEmpty(videoId)
|
|
||||||
// ? string.Empty
|
|
||||||
// : $"https://www.youtube.com/watch?v={videoId}";
|
|
||||||
|
|
||||||
// counter++;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// var canSee = CanUserSeeThisRequest(viewMovie.Id, Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests), dbMovies);
|
|
||||||
|
|
||||||
// var plexSettings = await PlexService.GetSettingsAsync();
|
|
||||||
// var embySettings = await EmbySettings.GetSettingsAsync();
|
|
||||||
// if (plexSettings.Enable)
|
|
||||||
// {
|
|
||||||
// var content = PlexContentRepository.GetAll();
|
|
||||||
// var plexMovies = PlexChecker.GetPlexMovies(content);
|
|
||||||
|
|
||||||
// var plexMovie = PlexChecker.GetMovie(plexMovies.ToArray(), movie.Title,
|
|
||||||
// movie.ReleaseDate?.Year.ToString(),
|
|
||||||
// viewMovie.ImdbId);
|
|
||||||
// if (plexMovie != null)
|
|
||||||
// {
|
|
||||||
// viewMovie.Available = true;
|
|
||||||
// viewMovie.PlexUrl = plexMovie.Url;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (embySettings.Enable)
|
|
||||||
// {
|
|
||||||
// var embyContent = EmbyContentRepository.GetAll();
|
|
||||||
// var embyMovies = EmbyChecker.GetEmbyMovies(embyContent);
|
|
||||||
|
|
||||||
// var embyMovie = EmbyChecker.GetMovie(embyMovies.ToArray(), movie.Title,
|
|
||||||
// movie.ReleaseDate?.Year.ToString(), viewMovie.ImdbId);
|
|
||||||
// if (embyMovie != null)
|
|
||||||
// {
|
|
||||||
// viewMovie.Available = true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
// else if (canSee)
|
|
||||||
// {
|
|
||||||
// bool exists = IsMovieInCache(movie, viewMovie.ImdbId);
|
|
||||||
// viewMovie.Approved = exists;
|
|
||||||
// viewMovie.Requested = exists;
|
|
||||||
// }
|
|
||||||
// viewMovies.Add(viewMovie);
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return viewMovies;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private long _dbMovieCacheTime = 0;
|
|
||||||
private Dictionary<int, RequestModel> _dbMovies;
|
|
||||||
private async Task<Dictionary<int, RequestModel>> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,232 +0,0 @@
|
||||||
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<RequestEngineResult> 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<string> { 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<RequestEngineResult> 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};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace Ombi.Core.Engine
|
|
||||||
{
|
|
||||||
public class RequestEngineResult
|
|
||||||
{
|
|
||||||
public bool RequestAdded { get; set; }
|
|
||||||
public string Message { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
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<int> AddRequestAsync(RequestModel model);
|
|
||||||
void BatchDelete(IEnumerable<RequestModel> model);
|
|
||||||
void BatchUpdate(IEnumerable<RequestModel> model);
|
|
||||||
RequestModel CheckRequest(int providerId);
|
|
||||||
RequestModel CheckRequest(string musicId);
|
|
||||||
Task<RequestModel> CheckRequestAsync(int providerId);
|
|
||||||
Task<RequestModel> CheckRequestAsync(string musicId);
|
|
||||||
void DeleteRequest(RequestModel request);
|
|
||||||
Task DeleteRequestAsync(RequestModel request);
|
|
||||||
RequestModel Get(int id);
|
|
||||||
IEnumerable<RequestModel> GetAll();
|
|
||||||
Task<IEnumerable<RequestModel>> GetAllAsync();
|
|
||||||
Task<RequestModel> GetAsync(int id);
|
|
||||||
RequestBlobs UpdateRequest(RequestModel model);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,174 +0,0 @@
|
||||||
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<int> 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<RequestModel>(blob.Content);
|
|
||||||
model.Id = blob.Id;
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<RequestModel> 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<RequestModel>(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<RequestModel>(blob.Content);
|
|
||||||
model.Id = blob.Id;
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<RequestModel> 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<RequestModel>(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<RequestModel>(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<RequestModel> GetAsync(int id)
|
|
||||||
{
|
|
||||||
var blob = await Repo.GetAsync(id).ConfigureAwait(false);
|
|
||||||
if (blob == null)
|
|
||||||
{
|
|
||||||
return new RequestModel();
|
|
||||||
}
|
|
||||||
var model = ByteConverterHelper.ReturnObject<RequestModel>(blob.Content);
|
|
||||||
model.Id = blob.Id;
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<RequestModel> GetAll()
|
|
||||||
{
|
|
||||||
var blobs = Repo.GetAll().ToList();
|
|
||||||
var retVal = new List<RequestModel>();
|
|
||||||
|
|
||||||
foreach (var b in blobs)
|
|
||||||
{
|
|
||||||
if (b == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var model = ByteConverterHelper.ReturnObject<RequestModel>(b.Content);
|
|
||||||
model.Id = b.Id;
|
|
||||||
retVal.Add(model);
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<RequestModel>> GetAllAsync()
|
|
||||||
{
|
|
||||||
var blobs = await Repo.GetAllAsync().ConfigureAwait(false);
|
|
||||||
var retVal = new List<RequestModel>();
|
|
||||||
|
|
||||||
foreach (var b in blobs)
|
|
||||||
{
|
|
||||||
if (b == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var model = ByteConverterHelper.ReturnObject<RequestModel>(b.Content);
|
|
||||||
model.Id = b.Id;
|
|
||||||
retVal.Add(model);
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BatchUpdate(IEnumerable<RequestModel> 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<RequestModel> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
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<string>();
|
|
||||||
Episodes = new List<EpisodesModel>();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<string> RequestedUsers { get; set; }
|
|
||||||
public string ArtistName { get; set; }
|
|
||||||
public string ArtistId { get; set; }
|
|
||||||
public int IssueId { get; set; }
|
|
||||||
public List<EpisodesModel> Episodes { get; set; }
|
|
||||||
public bool Denied { get; set; }
|
|
||||||
public string DeniedReason { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// For TV Shows with a custom root folder
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The root folder selected.
|
|
||||||
/// </value>
|
|
||||||
public int RootFolderSelected { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public List<string> AllUsers
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var u = new List<string>();
|
|
||||||
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<EpisodesModel>
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
#region Copyright
|
|
||||||
// /************************************************************************
|
|
||||||
// Copyright (c) 2017 Jamie Rees
|
|
||||||
// File: SearchMovieViewModel.cs
|
|
||||||
// Created By: Jamie Rees
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
// a copy of this software and associated documentation files (the
|
|
||||||
// "Software"), to deal in the Software without restriction, including
|
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
// permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
// the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be
|
|
||||||
// included in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
// ************************************************************************/
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Models.Search
|
|
||||||
{
|
|
||||||
public class SearchMovieViewModel : SearchViewModel
|
|
||||||
{
|
|
||||||
public bool Adult { get; set; }
|
|
||||||
public string BackdropPath { get; set; }
|
|
||||||
public List<int> GenreIds { get; set; }
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string OriginalLanguage { get; set; }
|
|
||||||
public string OriginalTitle { get; set; }
|
|
||||||
public string Overview { get; set; }
|
|
||||||
public double Popularity { get; set; }
|
|
||||||
public string PosterPath { get; set; }
|
|
||||||
public DateTime? ReleaseDate { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public bool Video { get; set; }
|
|
||||||
public double VoteAverage { get; set; }
|
|
||||||
public int VoteCount { get; set; }
|
|
||||||
public bool AlreadyInCp { get; set; }
|
|
||||||
public string Trailer { get; set; }
|
|
||||||
public string Homepage { get; set; }
|
|
||||||
public string ImdbId { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
#region Copyright
|
|
||||||
// /************************************************************************
|
|
||||||
// Copyright (c) 2017 Jamie Rees
|
|
||||||
// File: SearchViewModel.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
|
|
||||||
namespace Ombi.Core.Models.Search
|
|
||||||
{
|
|
||||||
public class SearchViewModel
|
|
||||||
{
|
|
||||||
public bool Approved { get; set; }
|
|
||||||
public bool Requested { get; set; }
|
|
||||||
public bool Available { get; set; }
|
|
||||||
public string PlexUrl { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard1.4</TargetFramework>
|
|
||||||
<!--<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>-->
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
|
||||||
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />
|
|
||||||
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.TheMovieDbApi.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,14 +0,0 @@
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Settings
|
|
||||||
{
|
|
||||||
public interface ISettingsService<T>
|
|
||||||
{
|
|
||||||
T GetSettings();
|
|
||||||
Task<T> GetSettingsAsync();
|
|
||||||
bool SaveSettings(T model);
|
|
||||||
Task<bool> SaveSettingsAsync(T model);
|
|
||||||
bool Delete(T model);
|
|
||||||
Task<bool> DeleteAsync(T model);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
namespace Ombi.Core.Settings.Models
|
|
||||||
{
|
|
||||||
public class Settings
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Ombi.Helpers;
|
|
||||||
using Ombi.Store.Entities;
|
|
||||||
using Ombi.Store.Repository;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Settings
|
|
||||||
{
|
|
||||||
public class SettingsServiceV2<T> : ISettingsService<T>
|
|
||||||
where T : Models.Settings, new()
|
|
||||||
{
|
|
||||||
|
|
||||||
public SettingsServiceV2(ISettingsRepository repo)
|
|
||||||
{
|
|
||||||
Repo = repo;
|
|
||||||
EntityName = typeof(T).Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ISettingsRepository Repo { get; }
|
|
||||||
private string EntityName { get; }
|
|
||||||
|
|
||||||
public T GetSettings()
|
|
||||||
{
|
|
||||||
var result = Repo.Get(EntityName);
|
|
||||||
if (result == null)
|
|
||||||
{
|
|
||||||
return new T();
|
|
||||||
}
|
|
||||||
result.Content = DecryptSettings(result);
|
|
||||||
var obj = string.IsNullOrEmpty(result.Content) ? null : JsonConvert.DeserializeObject<T>(result.Content, SerializerSettings.Settings);
|
|
||||||
|
|
||||||
var model = obj;
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<T> GetSettingsAsync()
|
|
||||||
{
|
|
||||||
var result = await Repo.GetAsync(EntityName).ConfigureAwait(false);
|
|
||||||
if (result == null)
|
|
||||||
{
|
|
||||||
return new T();
|
|
||||||
}
|
|
||||||
result.Content = DecryptSettings(result);
|
|
||||||
return string.IsNullOrEmpty(result.Content) ? null : JsonConvert.DeserializeObject<T>(result.Content, SerializerSettings.Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SaveSettings(T model)
|
|
||||||
{
|
|
||||||
var entity = Repo.Get(EntityName);
|
|
||||||
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
var newEntity = model;
|
|
||||||
|
|
||||||
var settings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(newEntity, SerializerSettings.Settings) };
|
|
||||||
settings.Content = EncryptSettings(settings);
|
|
||||||
var insertResult = Repo.Insert(settings);
|
|
||||||
|
|
||||||
return insertResult != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var modified = model;
|
|
||||||
modified.Id = entity.Id;
|
|
||||||
|
|
||||||
var globalSettings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(modified, SerializerSettings.Settings), Id = entity.Id };
|
|
||||||
globalSettings.Content = EncryptSettings(globalSettings);
|
|
||||||
Repo.Update(globalSettings);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> SaveSettingsAsync(T model)
|
|
||||||
{
|
|
||||||
var entity = await Repo.GetAsync(EntityName);
|
|
||||||
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
var newEntity = model;
|
|
||||||
|
|
||||||
var settings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(newEntity, SerializerSettings.Settings) };
|
|
||||||
settings.Content = EncryptSettings(settings);
|
|
||||||
var insertResult = await Repo.InsertAsync(settings).ConfigureAwait(false);
|
|
||||||
|
|
||||||
return insertResult != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var modified = model;
|
|
||||||
modified.Id = entity.Id;
|
|
||||||
|
|
||||||
var globalSettings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(modified, SerializerSettings.Settings), Id = entity.Id };
|
|
||||||
globalSettings.Content = EncryptSettings(globalSettings);
|
|
||||||
await Repo.UpdateAsync(globalSettings).ConfigureAwait(false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Delete(T model)
|
|
||||||
{
|
|
||||||
var entity = Repo.Get(EntityName);
|
|
||||||
if (entity != null)
|
|
||||||
{
|
|
||||||
Repo.Delete(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteAsync(T model)
|
|
||||||
{
|
|
||||||
var entity = Repo.Get(EntityName);
|
|
||||||
if (entity != null)
|
|
||||||
{
|
|
||||||
await Repo.DeleteAsync(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EncryptSettings(GlobalSettings settings)
|
|
||||||
{
|
|
||||||
return StringCipher.Encrypt(settings.Content, settings.SettingsName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string DecryptSettings(GlobalSettings settings)
|
|
||||||
{
|
|
||||||
return StringCipher.Decrypt(settings.Content, settings.SettingsName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Ombi.Core;
|
|
||||||
using Ombi.Core.Engine;
|
|
||||||
using Ombi.Core.Models.Requests;
|
|
||||||
using Ombi.Core.Requests.Models;
|
|
||||||
using Ombi.Core.Settings;
|
|
||||||
using Ombi.Store.Context;
|
|
||||||
using Ombi.Store.Repository;
|
|
||||||
using Ombi.TheMovieDbApi;
|
|
||||||
|
|
||||||
namespace Ombi.DependencyInjection
|
|
||||||
{
|
|
||||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
|
||||||
public static class IocExtensions
|
|
||||||
{
|
|
||||||
public static IServiceCollection RegisterDependencies(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.RegisterEngines();
|
|
||||||
services.RegisterApi();
|
|
||||||
services.RegisterServices();
|
|
||||||
services.RegisterStore();
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection RegisterEngines(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddTransient<IMovieEngine, MovieEngine>();
|
|
||||||
services.AddTransient<IRequestEngine, RequestEngine>();
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection RegisterApi(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddTransient<IMovieDbApi, TheMovieDbApi.TheMovieDbApi>();
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection RegisterStore(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddEntityFrameworkSqlite().AddDbContext<OmbiContext>();
|
|
||||||
|
|
||||||
services.AddTransient<IOmbiContext, OmbiContext>();
|
|
||||||
services.AddTransient<IRequestRepository, RequestJsonRepository>();
|
|
||||||
services.AddTransient<ISettingsRepository, SettingsJsonRepository>();
|
|
||||||
services.AddTransient(typeof(ISettingsService<>), typeof(SettingsServiceV2<>));
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
public static IServiceCollection RegisterServices(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddTransient<IRequestService, JsonRequestService>();
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard1.4</TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
|
|
||||||
<HintPath>..\..\..\..\..\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,28 +0,0 @@
|
||||||
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<T>(byte[] bytes)
|
|
||||||
{
|
|
||||||
var json = Encoding.UTF8.GetString(bytes);
|
|
||||||
var model = JsonConvert.DeserializeObject<T>(json);
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
public static string ReturnFromBytes(byte[] bytes)
|
|
||||||
{
|
|
||||||
return Encoding.UTF8.GetString(bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ombi.Helpers
|
|
||||||
{
|
|
||||||
public static class LinqHelpers
|
|
||||||
{
|
|
||||||
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
|
||||||
{
|
|
||||||
HashSet<TKey> knownKeys = new HashSet<TKey>();
|
|
||||||
foreach (TSource source1 in source)
|
|
||||||
{
|
|
||||||
if (knownKeys.Add(keySelector(source1)))
|
|
||||||
yield return source1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard1.4</TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,15 +0,0 @@
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Ombi.Helpers
|
|
||||||
{
|
|
||||||
public static class SerializerSettings
|
|
||||||
{
|
|
||||||
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
|
|
||||||
{
|
|
||||||
Formatting = Formatting.None,
|
|
||||||
//TypeNameHandling = TypeNameHandling.Objects,
|
|
||||||
//TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
|
|
||||||
NullValueHandling = NullValueHandling.Ignore
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,120 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Ombi.Helpers
|
|
||||||
{
|
|
||||||
public class StringCipher
|
|
||||||
{
|
|
||||||
// This constant determines the number of iterations for the password bytes generation function.
|
|
||||||
private const int DerivationIterations = 1000;
|
|
||||||
// This constant is used to determine the keysize of the encryption algorithm in bits.
|
|
||||||
// We divide this by 8 within the code below to get the equivalent number of bytes.
|
|
||||||
private const int Keysize = 256;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Decrypts the specified cipher text.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cipherText">The cipher text.</param>
|
|
||||||
/// <param name="passPhrase">The pass phrase.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string Decrypt(string cipherText, string passPhrase)
|
|
||||||
{
|
|
||||||
// Get the complete stream of bytes that represent:
|
|
||||||
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
|
|
||||||
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
|
|
||||||
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
|
|
||||||
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
|
|
||||||
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
|
|
||||||
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
|
|
||||||
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
|
|
||||||
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
|
|
||||||
|
|
||||||
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
|
|
||||||
{
|
|
||||||
var keyBytes = password.GetBytes(Keysize / 8);
|
|
||||||
var aes = Aes.Create();
|
|
||||||
using (var symmetricKey = new RijndaelManaged())
|
|
||||||
{
|
|
||||||
symmetricKey.BlockSize = 256;
|
|
||||||
symmetricKey.Mode = CipherMode.CBC;
|
|
||||||
symmetricKey.Padding = PaddingMode.PKCS7;
|
|
||||||
using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
|
|
||||||
{
|
|
||||||
using (var memoryStream = new MemoryStream(cipherTextBytes))
|
|
||||||
{
|
|
||||||
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
|
|
||||||
{
|
|
||||||
var plainTextBytes = new byte[cipherTextBytes.Length];
|
|
||||||
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
|
|
||||||
memoryStream.Close();
|
|
||||||
cryptoStream.Close();
|
|
||||||
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Encrypts the specified plain text.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="plainText">The plain text.</param>
|
|
||||||
/// <param name="passPhrase">The pass phrase.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string Encrypt(string plainText, string passPhrase)
|
|
||||||
{
|
|
||||||
// Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
|
|
||||||
// so that the same Salt and IV values can be used when decrypting.
|
|
||||||
var saltStringBytes = Generate256BitsOfRandomEntropy();
|
|
||||||
var ivStringBytes = Generate256BitsOfRandomEntropy();
|
|
||||||
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
|
||||||
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
|
|
||||||
{
|
|
||||||
var keyBytes = password.GetBytes(Keysize / 8);
|
|
||||||
using (var symmetricKey = new RijndaelManaged())
|
|
||||||
{
|
|
||||||
symmetricKey.BlockSize = 256;
|
|
||||||
symmetricKey.Mode = CipherMode.CBC;
|
|
||||||
symmetricKey.Padding = PaddingMode.PKCS7;
|
|
||||||
using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
|
|
||||||
{
|
|
||||||
using (var memoryStream = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
|
|
||||||
{
|
|
||||||
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
|
|
||||||
cryptoStream.FlushFinalBlock();
|
|
||||||
// Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
|
|
||||||
var cipherTextBytes = saltStringBytes;
|
|
||||||
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
|
|
||||||
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
|
|
||||||
memoryStream.Close();
|
|
||||||
cryptoStream.Close();
|
|
||||||
return Convert.ToBase64String(cipherTextBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generate256s the bits of random entropy.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static byte[] Generate256BitsOfRandomEntropy()
|
|
||||||
{
|
|
||||||
var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
|
|
||||||
using (var rngCsp = new RNGCryptoServiceProvider())
|
|
||||||
{
|
|
||||||
// Fill the array with cryptographically secure random bytes.
|
|
||||||
rngCsp.GetBytes(randomBytes);
|
|
||||||
}
|
|
||||||
return randomBytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
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<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));
|
|
||||||
DbSet<RequestBlobs> Requests { get; set; }
|
|
||||||
DbSet<GlobalSettings> Settings { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Ombi.Store.Entities;
|
|
||||||
|
|
||||||
namespace Ombi.Store.Context
|
|
||||||
{
|
|
||||||
public class OmbiContext : DbContext, IOmbiContext
|
|
||||||
{
|
|
||||||
private static bool _created;
|
|
||||||
public OmbiContext()
|
|
||||||
{
|
|
||||||
if (_created) return;
|
|
||||||
|
|
||||||
_created = true;
|
|
||||||
Database.EnsureCreated();
|
|
||||||
Database.Migrate();
|
|
||||||
}
|
|
||||||
public DbSet<RequestBlobs> Requests { get; set; }
|
|
||||||
public DbSet<GlobalSettings> Settings { get; set; }
|
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
||||||
{
|
|
||||||
optionsBuilder.UseSqlite("Data Source=Ombi.db");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Ombi.Store.Entities
|
|
||||||
{
|
|
||||||
public abstract class Entity
|
|
||||||
{
|
|
||||||
[Key]
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Ombi.Store.Entities
|
|
||||||
{
|
|
||||||
[Table("GlobalSettings")]
|
|
||||||
public class GlobalSettings : Entity
|
|
||||||
{
|
|
||||||
public string Content { get; set; }
|
|
||||||
public string SettingsName { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard1.4</TargetFramework>
|
|
||||||
<!--<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>-->
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -1,20 +0,0 @@
|
||||||
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<RequestBlobs> entity);
|
|
||||||
RequestBlobs Get(int id);
|
|
||||||
IEnumerable<RequestBlobs> GetAll();
|
|
||||||
Task<IEnumerable<RequestBlobs>> GetAllAsync();
|
|
||||||
Task<RequestBlobs> GetAsync(int id);
|
|
||||||
RequestBlobs Insert(RequestBlobs entity);
|
|
||||||
Task<RequestBlobs> InsertAsync(RequestBlobs entity);
|
|
||||||
RequestBlobs Update(RequestBlobs entity);
|
|
||||||
void UpdateAll(IEnumerable<RequestBlobs> entity);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Ombi.Store.Entities;
|
|
||||||
|
|
||||||
namespace Ombi.Store.Repository
|
|
||||||
{
|
|
||||||
public interface ISettingsRepository
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Inserts the specified entity.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">The entity.</param>
|
|
||||||
GlobalSettings Insert(GlobalSettings entity);
|
|
||||||
Task<GlobalSettings> InsertAsync(GlobalSettings entity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets all.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
IEnumerable<GlobalSettings> GetAll();
|
|
||||||
Task<IEnumerable<GlobalSettings>> GetAllAsync();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the specified identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="settingsName">Name of the settings.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
GlobalSettings Get(string settingsName);
|
|
||||||
Task<GlobalSettings> GetAsync(string settingsName);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the specified entity.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">The entity.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task DeleteAsync(GlobalSettings entity);
|
|
||||||
void Delete(GlobalSettings entity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the specified entity.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">The entity.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task UpdateAsync(GlobalSettings entity);
|
|
||||||
void Update(GlobalSettings entity);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
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<RequestBlobs> InsertAsync(RequestBlobs entity)
|
|
||||||
{
|
|
||||||
|
|
||||||
var id = await Db.Requests.AddAsync(entity).ConfigureAwait(false);
|
|
||||||
await Db.SaveChangesAsync();
|
|
||||||
return id.Entity;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<RequestBlobs> GetAll()
|
|
||||||
{
|
|
||||||
//var key = "GetAll";
|
|
||||||
//var item = Cache.GetOrSet(key, () =>
|
|
||||||
//{
|
|
||||||
|
|
||||||
var page = Db.Requests.ToList();
|
|
||||||
return page;
|
|
||||||
|
|
||||||
//}, 5);
|
|
||||||
//return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<RequestBlobs>> 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<RequestBlobs> 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<RequestBlobs> entity)
|
|
||||||
{
|
|
||||||
|
|
||||||
Db.Requests.UpdateRange(entity);
|
|
||||||
Db.SaveChanges();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void DeleteAll(IEnumerable<RequestBlobs> entity)
|
|
||||||
{
|
|
||||||
|
|
||||||
Db.Requests.RemoveRange(entity);
|
|
||||||
Db.SaveChanges();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
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 SettingsJsonRepository : ISettingsRepository
|
|
||||||
{
|
|
||||||
public SettingsJsonRepository(IOmbiContext ctx)
|
|
||||||
{
|
|
||||||
Db = ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IOmbiContext Db { get; }
|
|
||||||
|
|
||||||
public GlobalSettings Insert(GlobalSettings entity)
|
|
||||||
{
|
|
||||||
|
|
||||||
var settings = Db.Settings.Add(entity);
|
|
||||||
Db.SaveChanges();
|
|
||||||
return settings.Entity;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<GlobalSettings> InsertAsync(GlobalSettings entity)
|
|
||||||
{
|
|
||||||
|
|
||||||
var settings = await Db.Settings.AddAsync(entity).ConfigureAwait(false);
|
|
||||||
await Db.SaveChangesAsync().ConfigureAwait(false);
|
|
||||||
return settings.Entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<GlobalSettings> GetAll()
|
|
||||||
{
|
|
||||||
|
|
||||||
var page = Db.Settings.ToList();
|
|
||||||
return page;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<GlobalSettings>> GetAllAsync()
|
|
||||||
{
|
|
||||||
var page = await Db.Settings.ToListAsync();
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GlobalSettings Get(string pageName)
|
|
||||||
{
|
|
||||||
return Db.Settings.FirstOrDefault(x => x.SettingsName == pageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<GlobalSettings> GetAsync(string settingsName)
|
|
||||||
{
|
|
||||||
return await Db.Settings.FirstOrDefaultAsync(x => x.SettingsName == settingsName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteAsync(GlobalSettings entity)
|
|
||||||
{
|
|
||||||
Db.Settings.Remove(entity);
|
|
||||||
await Db.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateAsync(GlobalSettings entity)
|
|
||||||
{
|
|
||||||
Db.Settings.Update(entity);
|
|
||||||
await Db.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Delete(GlobalSettings entity)
|
|
||||||
{
|
|
||||||
Db.Settings.Remove(entity);
|
|
||||||
Db.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(GlobalSettings entity)
|
|
||||||
{
|
|
||||||
Db.Settings.Update(entity);
|
|
||||||
Db.SaveChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Ombi.Api;
|
|
||||||
using Ombi.TheMovieDbApi.Models;
|
|
||||||
|
|
||||||
namespace Ombi.TheMovieDbApi
|
|
||||||
{
|
|
||||||
public interface IMovieDbApi
|
|
||||||
{
|
|
||||||
Task<MovieResponse> GetMovieInformation(int movieId);
|
|
||||||
Task<TheMovieDbContainer<SearchResult>> NowPlaying();
|
|
||||||
Task<TheMovieDbContainer<SearchResult>> PopularMovies();
|
|
||||||
Task<TheMovieDbContainer<SearchResult>> SearchMovie(string searchTerm);
|
|
||||||
Task<TheMovieDbContainer<SearchResult>> TopRated();
|
|
||||||
Task<TheMovieDbContainer<SearchResult>> Upcoming();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
namespace Ombi.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
public class BelongsToCollection
|
|
||||||
{
|
|
||||||
public int id { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
public string poster_path { get; set; }
|
|
||||||
public string backdrop_path { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace Ombi.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
public class Genre
|
|
||||||
{
|
|
||||||
public int id { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
#region Copyright
|
|
||||||
// /************************************************************************
|
|
||||||
// Copyright (c) 2017 Jamie Rees
|
|
||||||
// File: MovieResponse.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
|
|
||||||
namespace Ombi.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
|
|
||||||
public class MovieResponse
|
|
||||||
{
|
|
||||||
public bool adult { get; set; }
|
|
||||||
public string backdrop_path { get; set; }
|
|
||||||
public BelongsToCollection belongs_to_collection { get; set; }
|
|
||||||
public int budget { get; set; }
|
|
||||||
public Genre[] genres { get; set; }
|
|
||||||
public string homepage { get; set; }
|
|
||||||
public int id { get; set; }
|
|
||||||
public string imdb_id { get; set; }
|
|
||||||
public string original_language { get; set; }
|
|
||||||
public string original_title { get; set; }
|
|
||||||
public string overview { get; set; }
|
|
||||||
public float popularity { get; set; }
|
|
||||||
public string poster_path { get; set; }
|
|
||||||
public ProductionCompanies[] production_companies { get; set; }
|
|
||||||
public ProductionCountries[] production_countries { get; set; }
|
|
||||||
public string release_date { get; set; }
|
|
||||||
public int revenue { get; set; }
|
|
||||||
public int runtime { get; set; }
|
|
||||||
public SpokenLanguages[] spoken_languages { get; set; }
|
|
||||||
public string status { get; set; }
|
|
||||||
public string tagline { get; set; }
|
|
||||||
public string title { get; set; }
|
|
||||||
public bool video { get; set; }
|
|
||||||
public float vote_average { get; set; }
|
|
||||||
public int vote_count { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace Ombi.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
public class ProductionCompanies
|
|
||||||
{
|
|
||||||
public string name { get; set; }
|
|
||||||
public int id { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace Ombi.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
public class ProductionCountries
|
|
||||||
{
|
|
||||||
public string iso_3166_1 { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
#region Copyright
|
|
||||||
// /************************************************************************
|
|
||||||
// Copyright (c) 2017 Jamie Rees
|
|
||||||
// File: SearchResult.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
|
|
||||||
namespace Ombi.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
public class SearchResult
|
|
||||||
{
|
|
||||||
public string poster_path { get; set; }
|
|
||||||
public bool adult { get; set; }
|
|
||||||
public string overview { get; set; }
|
|
||||||
public string release_date { get; set; }
|
|
||||||
public int?[] genre_ids { get; set; }
|
|
||||||
public int id { get; set; }
|
|
||||||
public string original_title { get; set; }
|
|
||||||
public string original_language { get; set; }
|
|
||||||
public string title { get; set; }
|
|
||||||
public string backdrop_path { get; set; }
|
|
||||||
public float popularity { get; set; }
|
|
||||||
public int vote_count { get; set; }
|
|
||||||
public bool video { get; set; }
|
|
||||||
public float vote_average { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace Ombi.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
public class SpokenLanguages
|
|
||||||
{
|
|
||||||
public string iso_639_1 { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#region Copyright
|
|
||||||
// /************************************************************************
|
|
||||||
// Copyright (c) 2017 Jamie Rees
|
|
||||||
// File: TheMovieDbContainer.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.TheMovieDbApi.Models
|
|
||||||
{
|
|
||||||
public class TheMovieDbContainer<T>
|
|
||||||
{
|
|
||||||
public int page { get; set; }
|
|
||||||
public List<T> results { get; set; }
|
|
||||||
public int total_results { get; set; }
|
|
||||||
public int total_pages { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard1.4</TargetFramework>
|
|
||||||
<!--<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>-->
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,67 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Ombi.Api;
|
|
||||||
using Ombi.TheMovieDbApi.Models;
|
|
||||||
|
|
||||||
namespace Ombi.TheMovieDbApi
|
|
||||||
{
|
|
||||||
public class TheMovieDbApi : IMovieDbApi
|
|
||||||
{
|
|
||||||
public TheMovieDbApi()
|
|
||||||
{
|
|
||||||
Api = new Api.Api();
|
|
||||||
}
|
|
||||||
private const string ApiToken = "b8eabaf5608b88d0298aa189dd90bf00";
|
|
||||||
private static readonly Uri BaseUri = new Uri("http://api.themoviedb.org/3/");
|
|
||||||
public Api.Api Api { get; }
|
|
||||||
|
|
||||||
public async Task<MovieResponse> GetMovieInformation(int movieId)
|
|
||||||
{
|
|
||||||
var url = BaseUri.ChangePath("movie/{0}", movieId.ToString());
|
|
||||||
url = AddHeaders(url);
|
|
||||||
return await Api.Get<MovieResponse>(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TheMovieDbContainer<SearchResult>> SearchMovie(string searchTerm)
|
|
||||||
{
|
|
||||||
var url = BaseUri.ChangePath("search/movie/");
|
|
||||||
url = AddHeaders(url);
|
|
||||||
url = url.AddQueryParameter("query", searchTerm);
|
|
||||||
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TheMovieDbContainer<SearchResult>> PopularMovies()
|
|
||||||
{
|
|
||||||
var url = BaseUri.ChangePath("movie/popular");
|
|
||||||
url = AddHeaders(url);
|
|
||||||
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TheMovieDbContainer<SearchResult>> TopRated()
|
|
||||||
{
|
|
||||||
var url = BaseUri.ChangePath("movie/top_rated");
|
|
||||||
url = AddHeaders(url);
|
|
||||||
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TheMovieDbContainer<SearchResult>> Upcoming()
|
|
||||||
{
|
|
||||||
var url = BaseUri.ChangePath("movie/upcoming");
|
|
||||||
url = AddHeaders(url);
|
|
||||||
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TheMovieDbContainer<SearchResult>> NowPlaying()
|
|
||||||
{
|
|
||||||
var url = BaseUri.ChangePath("movie/now_playing");
|
|
||||||
url = AddHeaders(url);
|
|
||||||
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Uri AddHeaders(Uri url)
|
|
||||||
{
|
|
||||||
return url.AddQueryParameter("api_key", ApiToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 15
|
|
||||||
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
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9D30CCF8-A115-4EB7-A34D-07780D752789}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
..\appveyor.yml = ..\appveyor.yml
|
|
||||||
Build\publish windows.bat = Build\publish windows.bat
|
|
||||||
Build\publish.bat = Build\publish.bat
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Core", "Ombi.Core\Ombi.Core.csproj", "{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Api", "Api", "{9293CA11-360A-4C20-A674-B9E794431BF5}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.TheMovieDbApi", "Ombi.TheMovieDbApi\Ombi.TheMovieDbApi.csproj", "{132DA282-5894-4570-8916-D8C18ED2CE84}"
|
|
||||||
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
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.DependencyInjection", "Ombi.DependencyInjection\Ombi.DependencyInjection.csproj", "{B39E4558-C557-48E7-AA74-19C5CD809617}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{132DA282-5894-4570-8916-D8C18ED2CE84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{132DA282-5894-4570-8916-D8C18ED2CE84}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{132DA282-5894-4570-8916-D8C18ED2CE84}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{132DA282-5894-4570-8916-D8C18ED2CE84}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{EA31F915-31F9-4318-B521-1500CDF40DDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{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
|
|
||||||
{B39E4558-C557-48E7-AA74-19C5CD809617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B39E4558-C557-48E7-AA74-19C5CD809617}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{132DA282-5894-4570-8916-D8C18ED2CE84} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
|
||||||
{EA31F915-31F9-4318-B521-1500CDF40DDF} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
17
Ombi/Ombi/.gitignore
vendored
17
Ombi/Ombi/.gitignore
vendored
|
@ -1,17 +0,0 @@
|
||||||
/app/**/*.js
|
|
||||||
/app/**/*.js.map
|
|
||||||
/wwwroot/**
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
/bower_components
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/.sass-cache
|
|
||||||
/connect.lock
|
|
||||||
/coverage/*
|
|
||||||
/libpeerconnection.log
|
|
||||||
npm-debug.log
|
|
||||||
testem.log
|
|
||||||
/typings
|
|
||||||
/systemjs.config.js*
|
|
|
@ -1,36 +0,0 @@
|
||||||
#region Copyright
|
|
||||||
// /************************************************************************
|
|
||||||
// Copyright (c) 2017 Jamie Rees
|
|
||||||
// File: BaseApiController.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 Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Ombi.Controllers
|
|
||||||
{
|
|
||||||
[Route("api/[controller]")]
|
|
||||||
public class BaseApiController : Controller
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Ombi.Controllers
|
|
||||||
{
|
|
||||||
public class HomeController : Controller
|
|
||||||
{
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult About()
|
|
||||||
{
|
|
||||||
ViewData["Message"] = "Your application description page.";
|
|
||||||
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult Contact()
|
|
||||||
{
|
|
||||||
ViewData["Message"] = "Your contact page.";
|
|
||||||
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult Error()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
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<RequestEngineResult> SearchMovie([FromBody]SearchMovieViewModel movie)
|
|
||||||
{
|
|
||||||
return await RequestEngine.RequestMovie(movie);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Ombi.Core;
|
|
||||||
using Ombi.Core.Models.Search;
|
|
||||||
|
|
||||||
namespace Ombi.Controllers
|
|
||||||
{
|
|
||||||
public class SearchController : BaseApiController
|
|
||||||
{
|
|
||||||
public SearchController(IMovieEngine movie)
|
|
||||||
{
|
|
||||||
MovieEngine = movie;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IMovieEngine MovieEngine { get; }
|
|
||||||
|
|
||||||
[HttpGet("movie/{searchTerm}")]
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> SearchMovie(string searchTerm)
|
|
||||||
{
|
|
||||||
return await MovieEngine.ProcessMovieSearch(searchTerm);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("movie/popular")]
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> Popular()
|
|
||||||
{
|
|
||||||
return await MovieEngine.PopularMovies();
|
|
||||||
}
|
|
||||||
[HttpGet("movie/nowplaying")]
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
|
|
||||||
{
|
|
||||||
return await MovieEngine.NowPlayingMovies();
|
|
||||||
}
|
|
||||||
[HttpGet("movie/toprated")]
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
|
|
||||||
{
|
|
||||||
return await MovieEngine.TopRatedMovies();
|
|
||||||
}
|
|
||||||
[HttpGet("movie/upcoming")]
|
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
|
|
||||||
{
|
|
||||||
return await MovieEngine.UpcomingMovies();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
|
||||||
<RuntimeIdentifiers>win10-x64;osx.10.12-x64;ubuntu.16.10-x64;debian.8-x64;</RuntimeIdentifiers>
|
|
||||||
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="1.1.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="wwwroot\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="ViewModels\**" />
|
|
||||||
<Content Remove="ViewModels\**" />
|
|
||||||
<EmbeddedResource Remove="ViewModels\**" />
|
|
||||||
<None Remove="ViewModels\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
|
||||||
<ProjectReference Include="..\Ombi.DependencyInjection\Ombi.DependencyInjection.csproj" />
|
|
||||||
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.TheMovieDbApi.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -1,24 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
|
|
||||||
namespace Ombi
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
var host = new WebHostBuilder()
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseStartup<Startup>()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
host.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:52038/",
|
|
||||||
"sslPort": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Ombi": {
|
|
||||||
"commandName": "Project"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
using System.IO;
|
|
||||||
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.DependencyInjection;
|
|
||||||
using Ombi.Store.Context;
|
|
||||||
|
|
||||||
namespace Ombi
|
|
||||||
{
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
public Startup(IHostingEnvironment env)
|
|
||||||
{
|
|
||||||
var builder = new ConfigurationBuilder()
|
|
||||||
.SetBasePath(env.ContentRootPath)
|
|
||||||
.AddJsonFile("appsettings.json", false, true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
|
|
||||||
.AddEnvironmentVariables();
|
|
||||||
Configuration = builder.Build();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public IConfigurationRoot Configuration { get; }
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
// Add framework services.
|
|
||||||
services.AddMvc();
|
|
||||||
services.RegisterDependencies(); // Ioc and EF
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|
||||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
|
||||||
{
|
|
||||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
|
||||||
loggerFactory.AddDebug();
|
|
||||||
|
|
||||||
if (env.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseDeveloperExceptionPage();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
app.UseExceptionHandler("/Home/Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
var provider = new FileExtensionContentTypeProvider();
|
|
||||||
provider.Mappings[".map"] = "application/octet-stream";
|
|
||||||
|
|
||||||
app.UseStaticFiles(new StaticFileOptions()
|
|
||||||
{
|
|
||||||
ContentTypeProvider = provider
|
|
||||||
});
|
|
||||||
|
|
||||||
app.UseStaticFiles(new StaticFileOptions
|
|
||||||
{
|
|
||||||
FileProvider = new PhysicalFileProvider(
|
|
||||||
Path.Combine(Directory.GetCurrentDirectory(), @"app")),
|
|
||||||
RequestPath = new PathString("/app"),
|
|
||||||
});
|
|
||||||
|
|
||||||
app.UseMvc(routes =>
|
|
||||||
{
|
|
||||||
routes.MapRoute(
|
|
||||||
name: "default",
|
|
||||||
template: "{controller=Home}/{action=Index}/{id?}");
|
|
||||||
|
|
||||||
routes.MapSpaFallbackRoute(
|
|
||||||
name: "spa-fallback",
|
|
||||||
defaults: new { controller = "Home", action = "Index" });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
body {
|
|
||||||
}
|
|
|
@ -1,242 +0,0 @@
|
||||||
$primary-colour: #df691a;
|
|
||||||
$primary-colour-outline: #ff761b;
|
|
||||||
$bg-colour: #333333;
|
|
||||||
$bg-colour-disabled: #252424;
|
|
||||||
$i:
|
|
||||||
!important
|
|
||||||
;
|
|
||||||
|
|
||||||
.form-control-custom {
|
|
||||||
background-color: $bg-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control-custom-disabled {
|
|
||||||
background-color: $bg-colour-disabled $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li.active > a,
|
|
||||||
.nav-tabs > li.active > a:hover,
|
|
||||||
.nav-tabs > li.active > a:focus {
|
|
||||||
background: $primary-colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-top-wrapper {
|
|
||||||
background-color: $bg-colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-top-wrapper:hover {
|
|
||||||
background-color: $primary-colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: Open Sans Regular,Helvetica Neue,Helvetica,Arial,sans-serif;
|
|
||||||
color: #eee;
|
|
||||||
background-color: #1f1f1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-striped > tbody > tr:nth-of-type(odd) {
|
|
||||||
background-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-hover > tbody > tr:hover {
|
|
||||||
background-color: #282828;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldset {
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
legend {
|
|
||||||
border-bottom: 1px solid #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control {
|
|
||||||
color: #fefefe;
|
|
||||||
background-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.radio input[type="radio"],
|
|
||||||
.radio-inline input[type="radio"],
|
|
||||||
.checkbox input[type="checkbox"],
|
|
||||||
.checkbox-inline input[type="checkbox"] {
|
|
||||||
margin-left: -0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-horizontal .radio,
|
|
||||||
.form-horizontal .checkbox,
|
|
||||||
.form-horizontal .radio-inline,
|
|
||||||
.form-horizontal .checkbox-inline {
|
|
||||||
margin-top: -15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu {
|
|
||||||
background-color: #282828;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu .divider {
|
|
||||||
background-color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu > li > a:hover,
|
|
||||||
.dropdown-menu > li > a:focus {
|
|
||||||
background-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-addon {
|
|
||||||
background-color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav > li > a:hover,
|
|
||||||
.nav > li > a:focus {
|
|
||||||
background-color: #df691a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li > a:hover {
|
|
||||||
border-color: #df691a #df691a transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li.active > a,
|
|
||||||
.nav-tabs > li.active > a:hover,
|
|
||||||
.nav-tabs > li.active > a:focus {
|
|
||||||
background-color: #df691a;
|
|
||||||
border: 1px solid #df691a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs.nav-justified > .active > a,
|
|
||||||
.nav-tabs.nav-justified > .active > a:hover,
|
|
||||||
.nav-tabs.nav-justified > .active > a:focus {
|
|
||||||
border: 1px solid #df691a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*.navbar {
|
|
||||||
position: relative;
|
|
||||||
min-height: 40px;
|
|
||||||
margin-bottom: 21px;
|
|
||||||
z-index: 1000;
|
|
||||||
padding: 0px 3px;
|
|
||||||
font-size: 24px;
|
|
||||||
background-color: #000;
|
|
||||||
box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.2);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
.navbar-default {
|
|
||||||
background-color: #0a0a0a;
|
|
||||||
border-color: #0a0a0a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-default .navbar-brand {
|
|
||||||
color: #DF691A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs {
|
|
||||||
border-bottom: 1px solid $bg-colour-disabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-default .navbar-nav > li > a:hover,
|
|
||||||
.navbar-default .navbar-nav > li > a:focus {
|
|
||||||
color: #F0ad4e;
|
|
||||||
background-color: #282828;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-default .navbar-nav > .active > a,
|
|
||||||
.navbar-default .navbar-nav > .active > a:hover,
|
|
||||||
.navbar-default .navbar-nav > .active > a:focus {
|
|
||||||
background-color: #282828;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-default .navbar-nav > .open > a,
|
|
||||||
.navbar-default .navbar-nav > .open > a:hover,
|
|
||||||
.navbar-default .navbar-nav > .open > a:focus {
|
|
||||||
background-color: #df691a;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination > li > a,
|
|
||||||
.pagination > li > span {
|
|
||||||
background-color: #282828;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination > li > a:hover,
|
|
||||||
.pagination > li > span:hover,
|
|
||||||
.pagination > li > a:focus,
|
|
||||||
.pagination > li > span:focus {
|
|
||||||
background-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination > .disabled > span,
|
|
||||||
.pagination > .disabled > span:hover,
|
|
||||||
.pagination > .disabled > span:focus,
|
|
||||||
.pagination > .disabled > a,
|
|
||||||
.pagination > .disabled > a:hover,
|
|
||||||
.pagination > .disabled > a:focus {
|
|
||||||
color: #fefefe;
|
|
||||||
background-color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item {
|
|
||||||
background-color: #282828;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.list-group-item:hover,
|
|
||||||
button.list-group-item:hover,
|
|
||||||
a.list-group-item:focus,
|
|
||||||
button.list-group-item:focus {
|
|
||||||
background-color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-addon,
|
|
||||||
.input-group-addon {
|
|
||||||
color: #df691a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-header,
|
|
||||||
.modal-footer {
|
|
||||||
background-color: #282828;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content {
|
|
||||||
position: relative;
|
|
||||||
background-color: #282828;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 0;
|
|
||||||
-webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
|
|
||||||
box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
|
|
||||||
-webkit-background-clip: padding-box;
|
|
||||||
-moz-background-clip: padding-box;
|
|
||||||
background-clip: padding-box;
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 10px;
|
|
||||||
padding: 3px 7px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #ebebeb;
|
|
||||||
line-height: 1;
|
|
||||||
vertical-align: middle;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-align: center;
|
|
||||||
background-color: $bg-colour;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-datetimepicker-widget.dropdown-menu {
|
|
||||||
background-color: $bg-colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
|
|
||||||
border-bottom: 6px solid $bg-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar-wrapper {
|
|
||||||
background: $bg-colour-disabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cacherRunning {
|
|
||||||
background-color: $bg-colour;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 15px;
|
|
||||||
padding: 3px 0;
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
@import "./bootstrap.css";
|
|
||||||
//@import "./lib/tether.css";
|
|
||||||
@import "../node_modules/primeng/resources/themes/omega/theme.scss";
|
|
||||||
@import "./lib/primeng.css";
|
|
||||||
|
|
||||||
$fa-font-path: "../fonts/lib";
|
|
||||||
@import "../bower_components/font-awesome/scss/font-awesome.scss";
|
|
|
@ -1,704 +0,0 @@
|
||||||
@import './_imports.scss';
|
|
||||||
|
|
||||||
$form-color: #4e5d6c;
|
|
||||||
$form-color-lighter: #637689;
|
|
||||||
$primary-colour: #df691a;
|
|
||||||
$primary-colour-outline: #ff761b;
|
|
||||||
$info-colour: #5bc0de;
|
|
||||||
$warning-colour: #f0ad4e;
|
|
||||||
$danger-colour: #d9534f;
|
|
||||||
$success-colour: #5cb85c;
|
|
||||||
$i:!important;
|
|
||||||
|
|
||||||
@media (min-width: 768px ) {
|
|
||||||
.row {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-align-text {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.landing-block .media {
|
|
||||||
max-width: 450px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 48em) {
|
|
||||||
.home {
|
|
||||||
padding-top: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 48em) {
|
|
||||||
.home {
|
|
||||||
padding-top: 4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-default .navbar-nav > .active > a,
|
|
||||||
.navbar-default .navbar-nav > .active > a:hover,
|
|
||||||
.navbar-default .navbar-nav > .active > a:focus {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
border: 1px dashed #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
border-radius: .25rem $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-group-separated .btn,
|
|
||||||
.btn-group-separated .btn + .btn {
|
|
||||||
margin-left: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.multiSelect {
|
|
||||||
background-color: $form-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control-custom {
|
|
||||||
background-color: $form-color $i;
|
|
||||||
color: white $i;
|
|
||||||
border-radius: 0;
|
|
||||||
box-shadow: 0 0 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 3.5rem $i;
|
|
||||||
font-weight: 600 $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.request-title {
|
|
||||||
margin-top: 0 $i;
|
|
||||||
font-size: 1.9rem $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 1.1rem $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: inline-block $i;
|
|
||||||
margin-bottom: .5rem $i;
|
|
||||||
font-size: 16px $i;
|
|
||||||
}
|
|
||||||
.small-label {
|
|
||||||
display: inline-block $i;
|
|
||||||
margin-bottom: .5rem $i;
|
|
||||||
font-size: 11px $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small-checkbox{
|
|
||||||
min-height:0 $i;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.round-checkbox {
|
|
||||||
border-radius:8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li {
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li.active > a,
|
|
||||||
.nav-tabs > li.active > a:hover,
|
|
||||||
.nav-tabs > li.active > a:focus {
|
|
||||||
background: #4e5d6c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li > a > .fa {
|
|
||||||
padding: 3px 5px 3px 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li.nav-tab-right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li.nav-tab-right a {
|
|
||||||
margin-right: 0;
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs > li.nav-tab-icononly .fa {
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar .nav a .fa,
|
|
||||||
.dropdown-menu a .fa {
|
|
||||||
font-size: 130%;
|
|
||||||
top: 1px;
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu a .fa {
|
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-danger-outline {
|
|
||||||
color: $danger-colour $i;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: $danger-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-danger-outline:focus,
|
|
||||||
.btn-danger-outline.focus,
|
|
||||||
.btn-danger-outline:active,
|
|
||||||
.btn-danger-outline.active,
|
|
||||||
.btn-danger-outline:hover,
|
|
||||||
.open > .btn-danger-outline.dropdown-toggle {
|
|
||||||
color: #fff $i;
|
|
||||||
background-color: $danger-colour $i;
|
|
||||||
border-color: $danger-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.btn-primary-outline {
|
|
||||||
color: $primary-colour-outline $i;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: $primary-colour-outline $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary-outline:focus,
|
|
||||||
.btn-primary-outline.focus,
|
|
||||||
.btn-primary-outline:active,
|
|
||||||
.btn-primary-outline.active,
|
|
||||||
.btn-primary-outline:hover,
|
|
||||||
.open > .btn-primary-outline.dropdown-toggle {
|
|
||||||
color: #fff $i;
|
|
||||||
background-color: $primary-colour $i;
|
|
||||||
border-color: $primary-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-info-outline {
|
|
||||||
color: $info-colour $i;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: $info-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-info-outline:focus,
|
|
||||||
.btn-info-outline.focus,
|
|
||||||
.btn-info-outline:active,
|
|
||||||
.btn-info-outline.active,
|
|
||||||
.btn-info-outline:hover,
|
|
||||||
.open > .btn-info-outline.dropdown-toggle {
|
|
||||||
color: #fff $i;
|
|
||||||
background-color: $info-colour $i;
|
|
||||||
border-color: $info-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-warning-outline {
|
|
||||||
color: $warning-colour $i;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: $warning-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-warning-outline:focus,
|
|
||||||
.btn-warning-outline.focus,
|
|
||||||
.btn-warning-outline:active,
|
|
||||||
.btn-warning-outline.active,
|
|
||||||
.btn-warning-outline:hover,
|
|
||||||
.open > .btn-warning-outline.dropdown-toggle {
|
|
||||||
color: #fff $i;
|
|
||||||
background-color: $warning-colour $i;
|
|
||||||
border-color: $warning-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-success-outline {
|
|
||||||
color: $success-colour $i;
|
|
||||||
background-color: transparent;
|
|
||||||
background-image: none;
|
|
||||||
border-color: $success-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-success-outline:focus,
|
|
||||||
.btn-success-outline.focus,
|
|
||||||
.btn-success-outline:active,
|
|
||||||
.btn-success-outline.active,
|
|
||||||
.btn-success-outline:hover,
|
|
||||||
.open > .btn-success-outline.dropdown-toggle {
|
|
||||||
color: #fff $i;
|
|
||||||
background-color: $success-colour $i;
|
|
||||||
border-color: $success-colour $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
#movieList .mix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tvList .mix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
$border-radius: 10px;
|
|
||||||
|
|
||||||
.scroll-top-wrapper {
|
|
||||||
position: fixed;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
z-index: 99999999;
|
|
||||||
background-color: $form-color;
|
|
||||||
color: #eeeeee;
|
|
||||||
width: 50px;
|
|
||||||
height: 48px;
|
|
||||||
line-height: 48px;
|
|
||||||
right: 30px;
|
|
||||||
bottom: 30px;
|
|
||||||
padding-top: 2px;
|
|
||||||
border-top-left-radius: $border-radius;
|
|
||||||
border-top-right-radius: $border-radius;
|
|
||||||
border-bottom-right-radius: $border-radius;
|
|
||||||
border-bottom-left-radius: $border-radius;
|
|
||||||
-webkit-transition: all 0.5s ease-in-out;
|
|
||||||
-moz-transition: all 0.5s ease-in-out;
|
|
||||||
-ms-transition: all 0.5s ease-in-out;
|
|
||||||
-o-transition: all 0.5s ease-in-out;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-top-wrapper:hover {
|
|
||||||
background-color: $form-color-lighter;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-top-wrapper.show {
|
|
||||||
visibility: visible;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-top-wrapper i.fa {
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.no-search-results {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-search-results .no-search-results-icon {
|
|
||||||
font-size: 10em;
|
|
||||||
color: $form-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-search-results .no-search-results-text {
|
|
||||||
margin: 20px 0;
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control-search {
|
|
||||||
padding: 13px 105px 13px 16px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control-withbuttons {
|
|
||||||
padding-right: 105px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-addon .btn-group {
|
|
||||||
position: absolute;
|
|
||||||
right: 45px;
|
|
||||||
z-index: 3;
|
|
||||||
top: 10px;
|
|
||||||
box-shadow: 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-addon .btn-group .btn {
|
|
||||||
border: 1px solid rgba(255,255,255,.7) !important;
|
|
||||||
padding: 3px 12px;
|
|
||||||
color: rgba(255,255,255,.7) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-split .btn {
|
|
||||||
border-radius: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-split .btn:not(.dropdown-toggle) {
|
|
||||||
border-radius: .25rem 0 0 .25rem $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-split .btn.dropdown-toggle {
|
|
||||||
border-radius: 0 .25rem .25rem 0 $i;
|
|
||||||
padding: 12px 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#updateAvailable {
|
|
||||||
background-color: #df691a;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 15px;
|
|
||||||
padding: 3px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cacherRunning {
|
|
||||||
background-color: $form-color;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 15px;
|
|
||||||
padding: 3px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox label {
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
padding-left: 25px;
|
|
||||||
margin-right: 15px;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox label:before {
|
|
||||||
content: "";
|
|
||||||
display: inline-block;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
margin-right: 10px;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: 1px;
|
|
||||||
border: 2px solid #eee;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox input[type=checkbox] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox input[type=checkbox]:checked + label:before {
|
|
||||||
content: "\2713";
|
|
||||||
font-size: 13px;
|
|
||||||
color: #fafafa;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small-checkbox label {
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
padding-left: 25px;
|
|
||||||
margin-right: 15px;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small-checkbox label:before {
|
|
||||||
content: "";
|
|
||||||
display: inline-block;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
margin-right: 10px;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: 1px;
|
|
||||||
border: 2px solid #eee;
|
|
||||||
border-radius: 8px;
|
|
||||||
min-height:0px $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small-checkbox input[type=checkbox] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small-checkbox input[type=checkbox]:checked + label:before {
|
|
||||||
content: "\2713";
|
|
||||||
font-size: 13px;
|
|
||||||
color: #fafafa;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small-checkbox label {
|
|
||||||
min-height: 0 $i;
|
|
||||||
padding-left: 20px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
font-weight: normal;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-sm {
|
|
||||||
padding-top: 2px;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-pane .form-horizontal .form-group {
|
|
||||||
margin-right: 15px;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-datetimepicker-widget.dropdown-menu {
|
|
||||||
background-color: $form-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
|
|
||||||
border-bottom: 6px solid $form-color $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-datetimepicker-widget table td.active,
|
|
||||||
.bootstrap-datetimepicker-widget table td.active:hover {
|
|
||||||
color: #fff $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.landing-header {
|
|
||||||
display: block;
|
|
||||||
margin: 60px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.landing-block {
|
|
||||||
background: #2f2f2f $i;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.landing-block .media {
|
|
||||||
margin: 30px auto;
|
|
||||||
max-width: 450px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.landing-block .media .media-left {
|
|
||||||
display: inline-block;
|
|
||||||
float: left;
|
|
||||||
width: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.landing-block .media .media-left i.fa {
|
|
||||||
font-size: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.landing-title {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-custom {
|
|
||||||
margin-top: 0 $i;
|
|
||||||
margin-bottom: 0 $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip_templates {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shadow {
|
|
||||||
-moz-box-shadow: 3px 3px 5px 6px #191919;
|
|
||||||
-webkit-box-shadow: 3px 3px 5px 6px #191919;
|
|
||||||
box-shadow: 3px 3px 5px 6px #191919;
|
|
||||||
}
|
|
||||||
.img-circle {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper {
|
|
||||||
padding-left: 0;
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper.toggled {
|
|
||||||
padding-right: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar-wrapper {
|
|
||||||
z-index: 1000;
|
|
||||||
position: fixed;
|
|
||||||
right: 250px;
|
|
||||||
width: 0;
|
|
||||||
height: 100%;
|
|
||||||
margin-right: -250px;
|
|
||||||
overflow-y: auto;
|
|
||||||
background: #4e5d6c;
|
|
||||||
padding-left:0;
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper.toggled #sidebar-wrapper {
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#page-content-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper.toggled #page-content-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
margin-left: -250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sidebar Styles */
|
|
||||||
|
|
||||||
.sidebar-nav {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
width: 500px;
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-nav li {
|
|
||||||
text-indent: 20px;
|
|
||||||
line-height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-nav li a {
|
|
||||||
display: block;
|
|
||||||
text-decoration: none;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-nav li a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #fff;
|
|
||||||
background: rgba(255,255,255,0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-nav li a:active,
|
|
||||||
.sidebar-nav li a:focus {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-nav > .sidebar-brand {
|
|
||||||
height: 65px;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-nav > .sidebar-brand a {
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-nav > .sidebar-brand a:hover {
|
|
||||||
color: #fff;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(min-width:768px) {
|
|
||||||
#wrapper {
|
|
||||||
padding-right: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper.toggled {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar-wrapper {
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper.toggled #sidebar-wrapper {
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#page-content-wrapper {
|
|
||||||
padding: 20px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper.toggled #page-content-wrapper {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#lightbox {
|
|
||||||
|
|
||||||
background-color: grey;
|
|
||||||
filter:alpha(opacity=50); /* IE */
|
|
||||||
opacity: 0.5; /* Safari, Opera */
|
|
||||||
-moz-opacity:0.50; /* FireFox */
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
z-index: 20;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
background-position:center;
|
|
||||||
position:absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.list-group-item-dropdown {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
padding: 10px 15px;
|
|
||||||
margin-bottom: -1px;
|
|
||||||
background-color: #3e3e3e;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wizard-heading{
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.wizard-img{
|
|
||||||
width: 300px;
|
|
||||||
display: block $i;
|
|
||||||
margin: 0 auto $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pace {
|
|
||||||
-webkit-pointer-events: none;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pace-inactive {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pace .pace-progress {
|
|
||||||
background: $primary-colour;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 2000;
|
|
||||||
top: 0;
|
|
||||||
right: 100%;
|
|
||||||
width: 100%;
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-brand {
|
|
||||||
float: left;
|
|
||||||
font-size: 19px;
|
|
||||||
line-height: 21px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gravatar{
|
|
||||||
border-radius:1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Bootstrap overrides
|
|
||||||
|
|
||||||
html {
|
|
||||||
font-size: 10px;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.42857143;
|
|
||||||
color: #333;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
6998
Ombi/Ombi/Styles/bootstrap.css
vendored
6998
Ombi/Ombi/Styles/bootstrap.css
vendored
File diff suppressed because it is too large
Load diff
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
@*<!DOCTYPE html>*@
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>@ViewData["Title"] - Ombi</title>
|
|
||||||
<base href="@Url.Content("~/")" />
|
|
||||||
<script src="@Url.Content("~/lib/pace.js")?v=@ViewBag.AssemblyVersion"></script>
|
|
||||||
<link href="@Url.Content("~/css/lib/pace-theme-minimal.css")" rel="stylesheet" />
|
|
||||||
<link href="@Url.Content("~/css/base.css")" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="@Url.Content("~/css/Themes/plex.css")" rel="stylesheet" type="text/css" />
|
|
||||||
@*<link href="@Url.Content("~/css/lib/primeng.css")" rel="stylesheet" />*@
|
|
||||||
|
|
||||||
<script src="@Url.Content("~/lib/system.js")?v="></script>
|
|
||||||
<script src="@Url.Content("~/lib/jquery.js")?v="></script>
|
|
||||||
<script src="@Url.Content("~/lib/tether.js")?v="></script>
|
|
||||||
<script src="@Url.Content("~/lib/bootstrap.js")?v="></script>
|
|
||||||
<script src="@Url.Content("~/lib/systemjs.config.js")?v="></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
@RenderBody()
|
|
||||||
<ombi></ombi>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,2 +0,0 @@
|
||||||
@using Ombi
|
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
|
|
@ -1,3 +0,0 @@
|
||||||
@{
|
|
||||||
Layout = "_Layout";
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
|
|
||||||
<nav class="navbar navbar-default navbar-fixed-top">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a class="navbar-brand" [routerLink]="['/']">Ombi</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li ><a [routerLink]="['/search']"><i class="fa fa-search"></i> Search</a></li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li ><a [routerLink]="['/settings/ombi']"><i class="fa fa-search"></i> Settings</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="container" style="padding-top: 5%">
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ombi',
|
|
||||||
moduleId: module.id,
|
|
||||||
templateUrl: './app.component.html'
|
|
||||||
})
|
|
||||||
export class AppComponent {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
import { HttpModule } from '@angular/http';
|
|
||||||
|
|
||||||
import { SearchComponent } from './search/search.component';
|
|
||||||
import { PageNotFoundComponent } from './errors/not-found.component';
|
|
||||||
|
|
||||||
// Services
|
|
||||||
import { SearchService } from './services/search.service';
|
|
||||||
import { RequestService } from './services/request.service';
|
|
||||||
|
|
||||||
// Modules
|
|
||||||
import { SettingsModule } from './settings/settings.module';
|
|
||||||
|
|
||||||
import { ButtonModule } from 'primeng/primeng';
|
|
||||||
import { GrowlModule } from 'primeng/components/growl/growl';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{ path: '*', component: PageNotFoundComponent },
|
|
||||||
{ path: 'search', component: SearchComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
RouterModule.forRoot(routes),
|
|
||||||
BrowserModule,
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
HttpModule,
|
|
||||||
GrowlModule,
|
|
||||||
ButtonModule,
|
|
||||||
FormsModule,
|
|
||||||
SettingsModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
AppComponent,
|
|
||||||
PageNotFoundComponent,
|
|
||||||
SearchComponent
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
SearchService,
|
|
||||||
RequestService
|
|
||||||
],
|
|
||||||
bootstrap: [AppComponent]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
|
@ -1,27 +0,0 @@
|
||||||
// Config
|
|
||||||
|
|
||||||
enum envs {
|
|
||||||
local = 0,
|
|
||||||
next = 1,
|
|
||||||
live = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
var envVar = "#{Environment}";
|
|
||||||
var env = envs.local;
|
|
||||||
if (envs[envVar]) {
|
|
||||||
env = envs[envVar];
|
|
||||||
}
|
|
||||||
|
|
||||||
export var config = {
|
|
||||||
envs: envs,
|
|
||||||
env: env,
|
|
||||||
systemJS: {
|
|
||||||
bundle: <boolean>{
|
|
||||||
[envs.local]: false,
|
|
||||||
[envs.next]: true,
|
|
||||||
[envs.live]: true
|
|
||||||
}[env]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default config;
|
|
|
@ -1,7 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
moduleId: module.id,
|
|
||||||
template: '<h2>Page not found</h2>'
|
|
||||||
})
|
|
||||||
export class PageNotFoundComponent { }
|
|
|
@ -1,4 +0,0 @@
|
||||||
export interface IRequestEngineResult {
|
|
||||||
requestAdded: boolean,
|
|
||||||
message: string
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
export interface ISearchMovieResult {
|
|
||||||
backdropPath: string,
|
|
||||||
adult: boolean,
|
|
||||||
overview: string,
|
|
||||||
releaseDate: Date,
|
|
||||||
genreIds: number[],
|
|
||||||
id: number,
|
|
||||||
originalTitle: string,
|
|
||||||
originalLanguage: string,
|
|
||||||
title: string,
|
|
||||||
posterPath: string,
|
|
||||||
popularity: number,
|
|
||||||
voteCount: number,
|
|
||||||
video: boolean,
|
|
||||||
voteAverage: number,
|
|
||||||
alreadyInCp: boolean,
|
|
||||||
trailer: string,
|
|
||||||
homepage: string,
|
|
||||||
imdbId:string
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
import './polyfills';
|
|
||||||
|
|
||||||
import { enableProdMode } from '@angular/core';
|
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
||||||
|
|
||||||
import { AppModule } from './app.module';
|
|
||||||
import { config } from './config';
|
|
||||||
|
|
||||||
if (config.env !== config.envs.local) {
|
|
||||||
enableProdMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
|
|
@ -1,14 +0,0 @@
|
||||||
// TypeScript transpiles our app to ES5 but some dependencies are written in ES6 so must polyfill
|
|
||||||
import 'core-js/es6/string';
|
|
||||||
import 'core-js/es6/array';
|
|
||||||
import 'core-js/es6/object';
|
|
||||||
|
|
||||||
import 'core-js/es7/reflect';
|
|
||||||
import 'zone.js/dist/zone';
|
|
||||||
|
|
||||||
import { config } from './config';
|
|
||||||
|
|
||||||
if (config.env === config.envs.local) {
|
|
||||||
Error['stackTraceLimit'] = Infinity;
|
|
||||||
require('zone.js/dist/long-stack-trace-zone');
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
<h1 id="searchTitle">Search</h1>
|
|
||||||
<h4>Search Paragraph</h4>
|
|
||||||
<br />
|
|
||||||
<!-- Nav tabs -->
|
|
||||||
|
|
||||||
|
|
||||||
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
|
|
||||||
|
|
||||||
<li role="presentation" class="active">
|
|
||||||
<a id="movieTabButton" href="#MoviesTab" aria-controls="home" role="tab" data-toggle="tab"><i class="fa fa-film"></i> Movies</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li role="presentation">
|
|
||||||
<a id="actorTabButton" href="#ActorsTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-users"></i> Actors</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li role="presentation">
|
|
||||||
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-television"></i> TV Shows</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<!--
|
|
||||||
<li role="presentation">
|
|
||||||
<a href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-music"></i> Albums</a>
|
|
||||||
</li>-->
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Tab panes -->
|
|
||||||
<div class="tab-content">
|
|
||||||
|
|
||||||
<!-- Movie tab -->
|
|
||||||
<div role="tabpanel" class="tab-pane active" id="MoviesTab">
|
|
||||||
<div class="input-group">
|
|
||||||
<input id="movieSearchContent" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons" (keyup)="search($event)">
|
|
||||||
<div class="input-group-addon">
|
|
||||||
<div class="btn-group">
|
|
||||||
<a href="#" class="btn btn-sm btn-primary-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
|
||||||
Suggestions
|
|
||||||
<i class="fa fa-chevron-down"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a (click)="popularMovies()">Popular Movies</a></li>
|
|
||||||
<li><a (click)="upcomingMovies()">Upcoming Movies</a></li>
|
|
||||||
<li><a (click)="topRatedMovies()">Top Rated Movies</a></li>
|
|
||||||
<li><a (click)="nowPlayingMovies()">Now Playing Movies</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<i id="movieSearchButton" class="fa fa-search"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<!-- Movie content -->
|
|
||||||
<div id="movieList">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Actors tab -->
|
|
||||||
<div role="tabpanel" class="tab-pane" id="ActorsTab">
|
|
||||||
<div class="input-group">
|
|
||||||
<input id="actorSearchContent" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons">
|
|
||||||
<div class="input-group-addon">
|
|
||||||
<i id="actorSearchButton" class="fa fa-search"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox">
|
|
||||||
<input type="checkbox" id="actorsSearchNew" name="actorsSearchNew"><label for="actorsSearchNew">@UI.Search_NewOnly</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<!-- Movie content -->
|
|
||||||
<div id="actorMovieList">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- TV tab -->
|
|
||||||
<div role="tabpanel" class="tab-pane" id="TvShowTab">
|
|
||||||
<div class="input-group">
|
|
||||||
<input id="tvSearchContent" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons">
|
|
||||||
<div class="input-group-addon">
|
|
||||||
<div class="btn-group">
|
|
||||||
<a href="#" class="btn btn-sm btn-primary-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
|
||||||
@UI.Search_Suggestions
|
|
||||||
<i class="fa fa-chevron-down"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a id="popularShows" >Popular Shows</a></li>
|
|
||||||
<li><a id="trendingShows" href="#">Trending Shows</a></li>
|
|
||||||
<li><a id="mostWatchedShows" href="#">Most Watched Shows</a></li>
|
|
||||||
<li><a id="anticipatedShows" href="#">Most Anticipated Shows</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><i id="tvSearchButton" class="fa fa-search"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<!-- TV content -->
|
|
||||||
<div id="tvList">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Music tab -->
|
|
||||||
<!-- <div role="tabpanel" class="tab-pane" id="MusicTab">
|
|
||||||
<div class="input-group">
|
|
||||||
<input id="musicSearchContent" type="text" class="form-control form-control-custom form-control-search">
|
|
||||||
<div class="input-group-addon">
|
|
||||||
<i id="musicSearchButton" class="fa fa-search"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<div id="musicList">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<div *ngFor="let result of movieResults">
|
|
||||||
<div class="row">
|
|
||||||
<div id="{{id}}imgDiv" class="col-sm-2">
|
|
||||||
|
|
||||||
|
|
||||||
<img *ngIf="result.posterPath" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{result.posterPath}}" alt="poster">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div>
|
|
||||||
<a href="https://www.themoviedb.org/movie/{{result.id}}/" target="_blank">
|
|
||||||
<h4>{{result.title}} ({{result.releaseDate}})</h4>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
|
||||||
<span *ngIf="result.firstAired" class="label label-info" target="_blank">Air Date: {{result.firstAired}}</span>
|
|
||||||
|
|
||||||
|
|
||||||
<span *ngIf="result.releaseDate" class="label label-info" target="_blank">Release Date: {{result.releaseDate}}</span>
|
|
||||||
|
|
||||||
<span *ngIf="result.available" class="label label-success">@UI.Search_Available</span>
|
|
||||||
|
|
||||||
<span *ngIf="result.approved" class="label label-info">@UI.Search_Processing_Request</span>
|
|
||||||
|
|
||||||
<div *ngIf="result.requested; then requested else notRequested"></div>
|
|
||||||
<template #requested>
|
|
||||||
<span class="label label-warning">Pending Approval</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #notRequested>
|
|
||||||
<span class="label label-danger">Not Yet Requested</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<span id="{{id}}netflixTab"></span>
|
|
||||||
|
|
||||||
<a *ngIf="result.homepage" href="{{result.homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
|
|
||||||
|
|
||||||
<a *ngIf="result.trailer" href="{{result.trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
|
|
||||||
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
<p style="font-size:0.9rem !important">{{result.overview}}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<input name="{{type}}Id" type="text" value="{{result.id}}" hidden="hidden" />
|
|
||||||
|
|
||||||
<div *ngIf="result.available">
|
|
||||||
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> Available</button>
|
|
||||||
|
|
||||||
<div *ngIf="result.url">
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{result.url}}" target="_blank"><i class="fa fa-eye"></i> View In Plex</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="result.requested; then requestedBtn else notRequestedBtn"></div>
|
|
||||||
<template #requestedBtn>
|
|
||||||
<button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button>
|
|
||||||
</template>
|
|
||||||
<template #notRequestedBtn>
|
|
||||||
<button id="{{result.id}}" style="text-align: right" class="btn btn-primary-outline" (click)="request(result)"><i class="fa fa-plus"></i> Request</button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!--{{#if_eq type "tv"}}
|
|
||||||
{{#if_eq tvFullyAvailable true}}
|
|
||||||
@*//TODO Not used yet*@
|
|
||||||
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button><br />
|
|
||||||
{{else}}
|
|
||||||
{{#if_eq enableTvRequestsForOnlySeries true}}
|
|
||||||
<button id="{{id}}" style="text-align: right" class="btn {{#if available}}btn-success-outline{{else}}btn-primary-outline dropdownTv{{/if}} btn-primary-outline" season-select="0" type="button" {{#if available}} disabled{{/if}}><i class="fa fa-plus"></i> {{#if available}}@UI.Search_Available{{else}}@UI.Search_Request{{/if}}</button>
|
|
||||||
{{else}}
|
|
||||||
<div class="dropdown">
|
|
||||||
<button id="{{id}}" class="btn {{#if available}}btn-success-outline{{else}}btn-primary-outline{{/if}} dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
|
||||||
<i class="fa fa-plus"></i> {{#if available}}@UI.Search_Available{{else}}@UI.Search_Request {{/if}}
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
|
||||||
<li><a id="{{id}}" season-select="0" class="dropdownTv " href="#">@UI.Search_AllSeasons</a></li>
|
|
||||||
{{#if_eq disableTvRequestsBySeason false}}
|
|
||||||
<li><a id="{{id}}" season-select="1" class="dropdownTv" href="#">@UI.Search_FirstSeason</a></li>
|
|
||||||
<li><a id="{{id}}" season-select="2" class="dropdownTv" href="#">@UI.Search_LatestSeason</a></li>
|
|
||||||
<li><a id="SeasonSelect" data-identifier="{{id}}" data-toggle="modal" data-target="#seasonsModal" href="#">@UI.Search_SelectSeason...</a></li>
|
|
||||||
{{/if_eq}}
|
|
||||||
{{#if_eq disableTvRequestsByEpisode false}}
|
|
||||||
<li><a id="EpisodeSelect" data-identifier="{{id}}" data-toggle="modal" data-target="#episodesModal" href="#">@UI.Search_SelectEpisode...</a></li>
|
|
||||||
{{/if_eq}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{{/if_eq}}
|
|
||||||
{{#if available}}
|
|
||||||
{{#if url}}
|
|
||||||
<br />
|
|
||||||
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if_eq}}
|
|
||||||
{{/if_eq}}-->
|
|
||||||
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<div *ngIf="result.available">
|
|
||||||
<input name="providerId" type="text" value="{{id}}" hidden="hidden" />
|
|
||||||
<input name="type" type="text" value="{{type}}" hidden="hidden" />
|
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-sm btn-danger-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
|
||||||
<i class="fa fa-exclamation"></i> @UI.Search_ReportIssue
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
|
||||||
<li><a issue-select="0" class="dropdownIssue" href="#">@UI.Issues_WrongAudio</a></li>
|
|
||||||
<li><a issue-select="1" class="dropdownIssue" href="#">@UI.Issues_NoSubs</a></li>
|
|
||||||
<li><a issue-select="2" class="dropdownIssue" href="#">@UI.Issues_WrongContent</a></li>
|
|
||||||
<li><a issue-select="3" class="dropdownIssue" href="#">@UI.Issues_Playback</a></li>
|
|
||||||
<li><a issue-select="4" class="dropdownIssue" href="#" data-toggle="modal" data-target="#issuesModal">@UI.Issues_Other</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
|
@ -1,78 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Subject } from 'rxjs/Subject';
|
|
||||||
import 'rxjs/add/operator/debounceTime';
|
|
||||||
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 { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ombi',
|
|
||||||
moduleId: module.id,
|
|
||||||
templateUrl: './search.component.html',
|
|
||||||
providers: [SearchService, RequestService]
|
|
||||||
})
|
|
||||||
export class SearchComponent implements OnInit {
|
|
||||||
|
|
||||||
searchText: string;
|
|
||||||
searchChanged: Subject<string> = new Subject<string>();
|
|
||||||
movieResults: ISearchMovieResult[];
|
|
||||||
result: IRequestEngineResult;
|
|
||||||
|
|
||||||
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
|
|
||||||
.subscribe(x => {
|
|
||||||
this.searchText = x as string;
|
|
||||||
if (this.searchText === "") {
|
|
||||||
this.clearResults();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.searchService.searchMovie(this.searchText).subscribe(x => this.movieResults = x);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.searchText = "";
|
|
||||||
this.movieResults = [];
|
|
||||||
this.result = {
|
|
||||||
message: "",
|
|
||||||
requestAdded:false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
search(text: any) {
|
|
||||||
this.searchChanged.next(text.target.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
request(searchResult: ISearchMovieResult) {
|
|
||||||
this.requestService.requestMovie(searchResult).subscribe(x => this.result = x);
|
|
||||||
}
|
|
||||||
|
|
||||||
popularMovies() {
|
|
||||||
this.clearResults();
|
|
||||||
this.searchService.popularMovies().subscribe(x => this.movieResults = x);
|
|
||||||
}
|
|
||||||
nowPlayingMovies() {
|
|
||||||
this.clearResults();
|
|
||||||
this.searchService.nowPlayingMovies().subscribe(x => this.movieResults = x);
|
|
||||||
}
|
|
||||||
topRatedMovies() {
|
|
||||||
this.clearResults();
|
|
||||||
this.searchService.topRatedMovies().subscribe(x => this.movieResults = x);
|
|
||||||
}
|
|
||||||
upcomingMovies() {
|
|
||||||
this.clearResults();
|
|
||||||
this.searchService.upcomignMovies().subscribe(x => this.movieResults = x);
|
|
||||||
}
|
|
||||||
|
|
||||||
private clearResults() {
|
|
||||||
this.movieResults = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
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<IRequestEngineResult> {
|
|
||||||
return this.http.post('/api/Request/Movie/', JSON.stringify(movie), ServiceHelpers.RequestOptions).map(ServiceHelpers.extractData);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Http } from '@angular/http';
|
|
||||||
import { Observable } from 'rxjs/Rx';
|
|
||||||
|
|
||||||
import { ServiceHelpers } from './service.helpers';
|
|
||||||
import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SearchService {
|
|
||||||
constructor(private http: Http) {
|
|
||||||
}
|
|
||||||
|
|
||||||
searchMovie(searchTerm: string): Observable<ISearchMovieResult[]> {
|
|
||||||
return this.http.get('/api/Search/Movie/' + searchTerm).map(ServiceHelpers.extractData);
|
|
||||||
}
|
|
||||||
|
|
||||||
popularMovies(): Observable<ISearchMovieResult[]> {
|
|
||||||
return this.http.get('/api/Search/Movie/Popular').map(ServiceHelpers.extractData);
|
|
||||||
}
|
|
||||||
upcomignMovies(): Observable<ISearchMovieResult[]> {
|
|
||||||
return this.http.get('/api/Search/Movie/upcoming').map(ServiceHelpers.extractData);
|
|
||||||
}
|
|
||||||
nowPlayingMovies(): Observable<ISearchMovieResult[]> {
|
|
||||||
return this.http.get('/api/Search/Movie/nowplaying').map(ServiceHelpers.extractData);
|
|
||||||
}
|
|
||||||
topRatedMovies(): Observable<ISearchMovieResult[]> {
|
|
||||||
return this.http.get('/api/Search/Movie/toprated').map(ServiceHelpers.extractData);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { Headers, RequestOptions, Response } from '@angular/http';
|
|
||||||
|
|
||||||
export class ServiceHelpers {
|
|
||||||
public static Headers = new Headers({ 'Content-Type': 'application/json' });
|
|
||||||
|
|
||||||
public static RequestOptions = new RequestOptions({
|
|
||||||
headers: ServiceHelpers.Headers
|
|
||||||
});
|
|
||||||
|
|
||||||
public static extractData(res: Response) {
|
|
||||||
console.log(res);
|
|
||||||
return res.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
@Component({
|
|
||||||
selector: 'ombi',
|
|
||||||
moduleId: module.id,
|
|
||||||
templateUrl: './ombi.component.html',
|
|
||||||
})
|
|
||||||
export class OmbiComponent {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { NgModule, } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
|
|
||||||
import { OmbiComponent } from './ombi/ombi.component'
|
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{ path: 'Settings/Ombi', component: OmbiComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
RouterModule.forChild(routes),
|
|
||||||
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
OmbiComponent
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
RouterModule
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class SettingsModule { }
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"IncludeScopes": false,
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Debug",
|
|
||||||
"System": "Information",
|
|
||||||
"Microsoft": "Information"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"IncludeScopes": false,
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"name": "ombi",
|
|
||||||
"private": true,
|
|
||||||
"dependencies": {
|
|
||||||
"PACE": "pace#^1.0.2",
|
|
||||||
"font-awesome": "^4.7.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
// Configure bundling and minification for the project.
|
|
||||||
// More info at https://go.microsoft.com/fwlink/?LinkId=808241
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"outputFileName": "wwwroot/css/site.min.css",
|
|
||||||
// An array of relative input file paths. Globbing patterns supported
|
|
||||||
"inputFiles": [
|
|
||||||
"wwwroot/css/site.css"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"outputFileName": "wwwroot/js/site.min.js",
|
|
||||||
"inputFiles": [
|
|
||||||
"wwwroot/js/site.js"
|
|
||||||
],
|
|
||||||
// Optionally specify minification options
|
|
||||||
"minify": {
|
|
||||||
"enabled": true,
|
|
||||||
"renameLocals": true
|
|
||||||
},
|
|
||||||
// Optionally generate .map file
|
|
||||||
"sourceMap": false
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,270 +0,0 @@
|
||||||
/// <binding BeforeBuild='build' ProjectOpened='watch' />
|
|
||||||
'use strict';
|
|
||||||
var gulp = require('gulp');
|
|
||||||
var sass = require('gulp-sass');
|
|
||||||
var changed = require('gulp-changed');
|
|
||||||
var rename = require('gulp-rename');
|
|
||||||
//var uglify = require('gulp-uglify');
|
|
||||||
var sourcemaps = require('gulp-sourcemaps');
|
|
||||||
var path = require('path');
|
|
||||||
var del = require('del');
|
|
||||||
var merge = require('merge-stream');
|
|
||||||
var gulpif = require('gulp-if');
|
|
||||||
var runSequence = require('run-sequence');
|
|
||||||
var cleancss = require('gulp-clean-css');
|
|
||||||
var filter = require('gulp-filter');
|
|
||||||
var systemJSBuilder = require('systemjs-builder');
|
|
||||||
var run = require('gulp-run');
|
|
||||||
|
|
||||||
var paths = {
|
|
||||||
wwwroot: './wwwroot/',
|
|
||||||
npm: { // These will be resolved automatically and copied to output directory as its name, only works for pre-bundled modules e.g. angular
|
|
||||||
src: [
|
|
||||||
'@angular/animations',
|
|
||||||
'@angular/animations/browser',
|
|
||||||
'@angular/core',
|
|
||||||
'@angular/common',
|
|
||||||
'@angular/compiler',
|
|
||||||
'@angular/platform-browser',
|
|
||||||
'@angular/platform-browser-dynamic',
|
|
||||||
'@angular/http',
|
|
||||||
'@angular/router',
|
|
||||||
'@angular/forms'
|
|
||||||
],
|
|
||||||
dest: './lib'
|
|
||||||
},
|
|
||||||
lib: { // These are simple single-file dependencies with optional rename, for more files or folders use modules
|
|
||||||
src: [
|
|
||||||
{
|
|
||||||
file: './node_modules/@angular/platform-browser/bundles/platform-browser-animations.umd.js',
|
|
||||||
rename: '@angular/platform-browser/animations'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: './node_modules/systemjs/dist/system.src.js',
|
|
||||||
rename: 'system'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: './node_modules/systemjs/dist/system-polyfills.src.js',
|
|
||||||
rename: 'system-polyfills'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: './node_modules/jquery/dist/jquery.min.js',
|
|
||||||
rename: 'jquery'
|
|
||||||
},
|
|
||||||
'./bower_components/PACE/pace.js',
|
|
||||||
'./node_modules/bootstrap/dist/js/bootstrap.js',
|
|
||||||
'./node_modules/tether/dist/js/tether.js',
|
|
||||||
'./systemjs.config.js'
|
|
||||||
],
|
|
||||||
dest: './lib/'
|
|
||||||
},
|
|
||||||
libcss: [ // Normal css files to be copied
|
|
||||||
{
|
|
||||||
src: [
|
|
||||||
'./bower_components/PACE/themes/purple/pace-theme-minimal.css',
|
|
||||||
'./bower_components/font-awesome/css/font-awesome.css',
|
|
||||||
'./node_modules/primeng/resources/primeng.css',
|
|
||||||
'./node_modules/tether/dist/css/tether.css'
|
|
||||||
],
|
|
||||||
dest: './css/lib/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: './Styles/**/*.css',
|
|
||||||
dest: './css',
|
|
||||||
filter: '**/*.css'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
libfonts: [ // Library fonts
|
|
||||||
{
|
|
||||||
src: [
|
|
||||||
'./bower_components/font-awesome/fonts/*'
|
|
||||||
],
|
|
||||||
dest: './fonts/lib/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: [
|
|
||||||
'./node_modules/primeng/resources/themes/omega/fonts/*'
|
|
||||||
],
|
|
||||||
dest: './fonts/'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
libimages: [ // Library images
|
|
||||||
{
|
|
||||||
src: [
|
|
||||||
'./node_modules/primeng/resources/themes/omega/images/*'
|
|
||||||
],
|
|
||||||
dest: './images/'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
modules: [ // This is for modules with multiple files that require each other, used when npm can't be used
|
|
||||||
{
|
|
||||||
name: 'zone.js',
|
|
||||||
src: ['./node_modules/zone.js/**/*.js'],
|
|
||||||
dest: './lib/zone.js/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'rxjs',
|
|
||||||
src: ['./node_modules/rxjs/**/*.js', '!./node_modules/rxjs/src/**/*.js'],
|
|
||||||
dest: './lib/rxjs/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'core-js',
|
|
||||||
src: ['./node_modules/core-js/**/*.js'],
|
|
||||||
dest: './lib/core-js/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'primeng',
|
|
||||||
src: './node_modules/primeng/**/*.js',
|
|
||||||
dest: './lib/primeng/'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
sass: { // Simple sass->css compilation
|
|
||||||
src: ['./Styles/**/*.scss', '!./Styles/primeng/**'],
|
|
||||||
dest: './css/',
|
|
||||||
filter: '**/*.css'
|
|
||||||
},
|
|
||||||
bundle: { // This is the config for the bundler, you shouldn't need to change this
|
|
||||||
root: './',
|
|
||||||
dest: './lib/bundle.js',
|
|
||||||
bundle: 'app/main.js',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gulp.task('npm', function () {
|
|
||||||
var streams = []
|
|
||||||
for (let module of paths.npm.src) {
|
|
||||||
let file = require.resolve(module);
|
|
||||||
streams.push(
|
|
||||||
gulp.src(file)
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.init()))
|
|
||||||
//.pipe(gulpif(global.full, uglify({ source_map: true })))
|
|
||||||
.pipe(rename((path => { path.basename = module })))
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.write('../maps')))
|
|
||||||
.pipe(gulp.dest(path.join(paths.wwwroot, paths.npm.dest)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return merge(streams);
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('lib', function () {
|
|
||||||
var streams = []
|
|
||||||
for (let module of paths.lib.src) {
|
|
||||||
streams.push(
|
|
||||||
gulp.src(typeof module === "string" ? module : module.file)
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.init()))
|
|
||||||
//.pipe(gulpif(global.full, uglify({ source_map: true })))
|
|
||||||
.pipe(rename(function (path) {
|
|
||||||
if (typeof module !== "string" && module.rename) {
|
|
||||||
path.basename = module.rename;
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.write('maps')))
|
|
||||||
.pipe(gulp.dest(path.join(paths.wwwroot, paths.lib.dest)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return merge(streams);
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('libcss', function () {
|
|
||||||
var streams = []
|
|
||||||
for (let module of paths.libcss) {
|
|
||||||
var f = filter("**/*.css", { restore: true });
|
|
||||||
streams.push(
|
|
||||||
gulp.src(module.src)
|
|
||||||
.pipe(f)
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.init()))
|
|
||||||
.pipe(gulpif(global.full, cleancss()))
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.write(`${module.name ? '.' : ''}./maps/${module.name ? module.name : ''}`)))
|
|
||||||
.pipe(f.restore)
|
|
||||||
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return merge(streams);
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task('libfonts', function () {
|
|
||||||
var streams = []
|
|
||||||
for (let module of paths.libfonts) {
|
|
||||||
streams.push(
|
|
||||||
gulp.src(module.src)
|
|
||||||
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return merge(streams);
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task('libimages', function () {
|
|
||||||
var streams = []
|
|
||||||
for (let module of paths.libimages) {
|
|
||||||
streams.push(
|
|
||||||
gulp.src(module.src)
|
|
||||||
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return merge(streams);
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('modules', function () {
|
|
||||||
var streams = []
|
|
||||||
for (let module of paths.modules) {
|
|
||||||
streams.push(
|
|
||||||
gulp.src(module.src)
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.init()))
|
|
||||||
// .pipe(gulpif(global.full, uglify({ source_map: true })))
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.write(`${module.name ? '.' : ''}./maps/${module.name ? module.name : ''}`)))
|
|
||||||
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return merge(streams);
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('sass', function () {
|
|
||||||
return gulp.src(paths.sass.src)
|
|
||||||
.pipe(changed(paths.sass.dest))
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.init()))
|
|
||||||
.pipe(sass({ outputStyle: global.full ? 'compressed' : 'nested' }).on('error', sass.logError))
|
|
||||||
.pipe(gulpif(global.full, sourcemaps.write('maps')))
|
|
||||||
.pipe(gulp.dest(path.join(paths.wwwroot, paths.sass.dest)))
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('bundle', function () {
|
|
||||||
var builder = new systemJSBuilder(paths.bundle.root);
|
|
||||||
builder.config({
|
|
||||||
baseURL: paths.wwwroot,
|
|
||||||
packages: {
|
|
||||||
'.': {
|
|
||||||
defaultExtension: 'js'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
paths: {
|
|
||||||
'*': 'lib/*',
|
|
||||||
'app/*': 'app/*'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
del.sync(path.join(paths.wwwroot, paths.bundle.dest), { force: true });
|
|
||||||
return builder.bundle(paths.bundle.bundle, path.join(paths.wwwroot, paths.bundle.dest), {
|
|
||||||
sourceMaps: true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('typescript', function () {
|
|
||||||
return run('tsc').exec();
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('fullvar', () => { global.full = true });
|
|
||||||
gulp.task('libs')
|
|
||||||
gulp.task('copy', ['lib', 'libcss', 'libfonts', 'libimages', 'npm', 'modules']);
|
|
||||||
gulp.task('compile', ['sass']);
|
|
||||||
gulp.task('build', callback => runSequence('copy', 'compile', callback));
|
|
||||||
gulp.task('full', callback => runSequence('build', callback));
|
|
||||||
|
|
||||||
// Use this in a build server environment to compile and bundle everything
|
|
||||||
gulp.task('publish', callback => runSequence('fullvar', 'full', 'typescript', 'bundle', callback));
|
|
||||||
|
|
||||||
// Auto compiles sass files on change, note that this doesn't seem to pick up new files at the moment
|
|
||||||
gulp.task('watch', function () {
|
|
||||||
gulp.watch(paths.sass.src, ['sass']);
|
|
||||||
gulp.watch('./Styles/**/*.css', ['libcss']); // legacy css
|
|
||||||
});
|
|
|
@ -1,45 +0,0 @@
|
||||||
{
|
|
||||||
"name": "ombi",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@angular/animations": "^4.0.0",
|
|
||||||
"@angular/common": "^4.0.0",
|
|
||||||
"@angular/compiler": "^4.0.0",
|
|
||||||
"@angular/compiler-cli": "^4.0.0",
|
|
||||||
"@angular/core": "^4.0.0",
|
|
||||||
"@angular/forms": "^4.0.0",
|
|
||||||
"@angular/http": "^4.0.0",
|
|
||||||
"@angular/platform-browser": "^4.0.0",
|
|
||||||
"@angular/platform-browser-dynamic": "^4.0.0",
|
|
||||||
"@angular/platform-server": "^4.0.0",
|
|
||||||
"@angular/router": "^4.0.0",
|
|
||||||
"@types/jquery": "^2.0.33",
|
|
||||||
"@types/systemjs": "^0.20.2",
|
|
||||||
"core-js": "^2.4.1",
|
|
||||||
"del": "^2.2.2",
|
|
||||||
"gulp": "~3.9.1",
|
|
||||||
"gulp-changed": "^1.3.0",
|
|
||||||
"gulp-clean-css": "^3.0.4",
|
|
||||||
"gulp-filter": "^5.0.0",
|
|
||||||
"gulp-if": "^2.0.2",
|
|
||||||
"gulp-rename": "^1.2.2",
|
|
||||||
"gulp-run": "^1.7.1",
|
|
||||||
"gulp-sass": "^2.3.2",
|
|
||||||
"gulp-sourcemaps": "^1.9.0",
|
|
||||||
"gulp-systemjs-builder": "^0.15.0",
|
|
||||||
"gulp-uglify": "^2.1.2",
|
|
||||||
"jquery": "2.2.1",
|
|
||||||
"merge-stream": "^1.0.1",
|
|
||||||
"nanoscroller": "^0.8.7",
|
|
||||||
"primeng": "^2.0.5",
|
|
||||||
"run-sequence": "^1.2.2",
|
|
||||||
"rxjs": "^5.0.3",
|
|
||||||
"systemjs": "^0.19.41",
|
|
||||||
"systemjs-builder": "^0.15.34",
|
|
||||||
"tether": "^1.4.0",
|
|
||||||
"typescript": "^2.2.1",
|
|
||||||
"zone.js": "^0.8.5",
|
|
||||||
"bootstrap": "3.3.6"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
System.import('/app/config.js').then((module: any) => {
|
|
||||||
var config = module.config.systemJS;
|
|
||||||
System.config({
|
|
||||||
baseURL: '/lib',
|
|
||||||
packages: {
|
|
||||||
'.': {
|
|
||||||
defaultExtension: 'js'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
map: { app: '../app' }
|
|
||||||
})
|
|
||||||
|
|
||||||
if (config.bundle) {
|
|
||||||
System.import('bundle').then(() => {
|
|
||||||
System.import('/app/main');
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
System.import('/app/main')
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"lib": [ "es5", "es2015" ],
|
|
||||||
"module": "commonjs",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"sourceMap": true,
|
|
||||||
"strictNullChecks": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noImplicitThis": true,
|
|
||||||
"noImplicitReturns": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"suppressImplicitAnyIndexErrors": true,
|
|
||||||
"alwaysStrict": true,
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"skipLibCheck": true
|
|
||||||
},
|
|
||||||
"compileOnSave": true
|
|
||||||
}
|
|
55
appveyor.yml
55
appveyor.yml
|
@ -1,56 +1,21 @@
|
||||||
version: 3.0.{build}
|
version: 2.2.{build}
|
||||||
configuration: Release
|
configuration: Release
|
||||||
os: Visual Studio 2015 Preview
|
|
||||||
assembly_info:
|
assembly_info:
|
||||||
patch: true
|
patch: true
|
||||||
file: '**\AssemblyInfo.*'
|
file: '**\AssemblyInfo.*'
|
||||||
assembly_version: '3.0.0'
|
assembly_version: '2.2.1'
|
||||||
assembly_file_version: '{version}'
|
assembly_file_version: '{version}'
|
||||||
assembly_informational_version: '3.0.0'
|
assembly_informational_version: '2.2.1'
|
||||||
before_build:
|
before_build:
|
||||||
- cmd: cd ombi/ombi
|
- cmd: appveyor-retry nuget restore
|
||||||
- appveyor-retry dotnet restore
|
build:
|
||||||
- appveyor-retry npm install bower -g
|
verbosity: minimal
|
||||||
- appveyor-retry npm install -g gulp
|
|
||||||
- appveyor-retry npm install -g typescript
|
|
||||||
- appveyor-retry npm install
|
|
||||||
- appveyor-retry bower install
|
|
||||||
- gulp publish
|
|
||||||
build_script:
|
|
||||||
- dotnet build
|
|
||||||
after_build:
|
after_build:
|
||||||
- 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: >-
|
- cmd: >-
|
||||||
7z a Ombi_windows.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.1\win10-x64\publish
|
7z a Ombi.zip %APPVEYOR_BUILD_FOLDER%\Ombi.UI\bin\Release\
|
||||||
|
|
||||||
|
appveyor PushArtifact Ombi.zip
|
||||||
|
|
||||||
7z a Ombi_osx.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.1\osx.10.12-x64\publish
|
|
||||||
|
|
||||||
|
|
||||||
7z a Ombi_ubuntu.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.1\ubuntu.16.10-x64\publish
|
|
||||||
|
|
||||||
|
|
||||||
7z a Ombi_debian.zip %APPVEYOR_BUILD_FOLDER%\Ombi\Ombi\bin\Release\netcoreapp1.1\debian.8-x64\publish
|
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact Ombi_windows.zip
|
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact Ombi_osx.zip
|
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact Ombi_ubuntu.zip
|
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact Ombi_debian.zip
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cache:
|
|
||||||
- '%USERPROFILE%\.nuget\packages'
|
|
||||||
deploy:
|
deploy:
|
||||||
- provider: GitHub
|
- provider: GitHub
|
||||||
release: Ombi v$(appveyor_build_version)
|
release: Ombi v$(appveyor_build_version)
|
||||||
|
@ -59,3 +24,7 @@ deploy:
|
||||||
draft: true
|
draft: true
|
||||||
on:
|
on:
|
||||||
branch: master
|
branch: master
|
||||||
|
- provider: Environment
|
||||||
|
name: Microserver
|
||||||
|
on:
|
||||||
|
branch: dev
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue