mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 13:23:20 -07:00
merge
This commit is contained in:
commit
0a4acb314c
221 changed files with 12313 additions and 15406 deletions
210
CHANGELOG.md
210
CHANGELOG.md
|
@ -1,5 +1,215 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v3.0.3587 (2018-08-19)
|
||||||
|
|
||||||
|
### **New Features**
|
||||||
|
|
||||||
|
- Added the ability to invite Plex Friends from the user management screen. [Jamie]
|
||||||
|
|
||||||
|
- Added rich notifications for mobile. [Jamie]
|
||||||
|
|
||||||
|
- Updater fixes. [Jamie]
|
||||||
|
|
||||||
|
- Added updater test mode. [Jamie Rees]
|
||||||
|
|
||||||
|
- Added a new API method to delete issue comments. [TidusJar]
|
||||||
|
|
||||||
|
- Updated @ngu/carousel to beta version to remove rxjs-compat dependency. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Update to Angular 6/Webpack 4. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Update CHANGELOG.md. [Jamie]
|
||||||
|
|
||||||
|
- Updated the way we create the wizard user, errors show now be fed back to the user. [Jamie]
|
||||||
|
|
||||||
|
- Added Brazillian Portuguese as a language and also Polish. [Jamie]
|
||||||
|
|
||||||
|
- Updated swagger. [Jamie]
|
||||||
|
|
||||||
|
- Updated to 2.1.1. [Jamie]
|
||||||
|
|
||||||
|
### **Fixes**
|
||||||
|
|
||||||
|
- #2408 Added the feature to delete comments on issues. [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Swedish) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (French) [Jamie]
|
||||||
|
|
||||||
|
- Fixed #2440. [TidusJar]
|
||||||
|
|
||||||
|
- Delete cake.config. [Chris Pritchard]
|
||||||
|
|
||||||
|
- Initial attempt at getting anime seriestype working. [Chris Pritchard]
|
||||||
|
|
||||||
|
- Add cake.config. [Chris Pritchard]
|
||||||
|
|
||||||
|
- Fixed the issue where we wouldn't correctly mark some shows as available when there was no provider id #2429. [Jamie]
|
||||||
|
|
||||||
|
- Fixed the 'loop' in the cacher #2429. [Jamie]
|
||||||
|
|
||||||
|
- Fixed #2427. [Jamie]
|
||||||
|
|
||||||
|
- Fixed #2424. [Jamie]
|
||||||
|
|
||||||
|
- Fixed #2409. [Jamie]
|
||||||
|
|
||||||
|
- More updater. [Jamie]
|
||||||
|
|
||||||
|
- Humanize the request type enum in notifications e.g. TvShow will now appear as "Tv Show" #2416. [TidusJar]
|
||||||
|
|
||||||
|
- Made the quality override and root folder override load when we load the show (It will now appear) [Jamie]
|
||||||
|
|
||||||
|
- Fixed #2415 where power users could not set the Sonarr Quality Override or Root Folder Override. [Jamie]
|
||||||
|
|
||||||
|
- #2371 Fixed the issue where certain actions would not setup the series correctly in Sonarr. [Jamie]
|
||||||
|
|
||||||
|
- Tightened up the security from an API perspecitve. [TidusJar]
|
||||||
|
|
||||||
|
- Stop the root folder and profile calls from erroring. [TidusJar]
|
||||||
|
|
||||||
|
- New translations en.json (Polish) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Polish) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Polish) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Portuguese, Brazilian) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Portuguese, Brazilian) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Portuguese, Brazilian) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Portuguese, Brazilian) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Portuguese, Brazilian) [Jamie]
|
||||||
|
|
||||||
|
- Fixed all linting. [TidusJar]
|
||||||
|
|
||||||
|
- Comment out envparam stuff. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Fixed prod build issue. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Missed a tiny bit. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Fix test. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Fix test build. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Linting + remove debug. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Switch to Yarn and disable auto publish in release mode. [Matt Jeanes]
|
||||||
|
|
||||||
|
- Fix for #2409. [TidusJar]
|
||||||
|
|
||||||
|
- New translations en.json (Swedish) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Spanish) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Portuguese, Brazilian) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Polish) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Norwegian) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Italian) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (German) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (French) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Dutch) [Jamie]
|
||||||
|
|
||||||
|
- New translations en.json (Danish) [Jamie]
|
||||||
|
|
||||||
|
- Possible fix for #2298. [D34DC3N73R]
|
||||||
|
|
||||||
|
- Fixed the text for #2370. [Jamie]
|
||||||
|
|
||||||
|
- Fixed where you couldn't bulk edit the limits to 0 #2318. [Jamie]
|
||||||
|
|
||||||
|
- Upgraded to .net 2.1.2 (Includes security fixes) [Jamie]
|
||||||
|
|
||||||
|
|
||||||
|
## v3.0.3477 (2018-07-18)
|
||||||
|
|
||||||
|
### **New Features**
|
||||||
|
|
||||||
|
- Updated the Emby availability checker to bring it more in line with what we do with Plex. [TidusJar]
|
||||||
|
|
||||||
|
- Added the ability to impersonate a user when using the API Key. This allows people to use the API and request as a certain user. #2363. [Jamie Rees]
|
||||||
|
|
||||||
|
- Added more background images and it will loop through the available ones. [Jamie Rees]
|
||||||
|
|
||||||
|
- Added chunk hashing to resolve #2330. [Jamie Rees]
|
||||||
|
|
||||||
|
- Added API at /api/v1/status/info to get branch and version information #2331. [Jamie Rees]
|
||||||
|
|
||||||
|
- Update to .net 2.1.1. [Jamie]
|
||||||
|
|
||||||
|
### **Fixes**
|
||||||
|
|
||||||
|
- Fix #2322 caused by continue statement inside try catch block. [Anojh]
|
||||||
|
|
||||||
|
- Fixed #2367. [TidusJar]
|
||||||
|
|
||||||
|
- Fixed the issue where you could not delete a user #2365. [TidusJar]
|
||||||
|
|
||||||
|
- Another attempt to fix #2366. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed the Plex OAuth warning. [Jamie]
|
||||||
|
|
||||||
|
- Revert "Fixed Plex OAuth, should no longer show Insecure warning" [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed Plex OAuth, should no longer show Insecure warning. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed the View On Emby URL since the Link changed #2368. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed the issue where episodes were not being marked as available in the search #2367. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed #2371. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed collection issues in Emby #2366. [Jamie Rees]
|
||||||
|
|
||||||
|
- Do not delete the Emby Information every time we run, let's keep the content now. [Jamie Rees]
|
||||||
|
|
||||||
|
- Emby Improvements: Batch up the amount we get from the server. [Jamie Rees]
|
||||||
|
|
||||||
|
- Log errors when they are uncaught. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fix unclosed table tags causing overflow #2322. [Anojh]
|
||||||
|
|
||||||
|
- This should now fix #2350. [Jamie]
|
||||||
|
|
||||||
|
- Improve the validation around the Application URL. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed #2341. [Jamie Rees]
|
||||||
|
|
||||||
|
- Stop spamming errors when FanArt doesn't have the image. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed #2338. [Jamie Rees]
|
||||||
|
|
||||||
|
- Removed some logging statements. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed the api key being case sensative #2350. [Jamie Rees]
|
||||||
|
|
||||||
|
- Improved the Emby API #2230 Thanks Luke! [Jamie Rees]
|
||||||
|
|
||||||
|
- Revert. [Jamie Rees]
|
||||||
|
|
||||||
|
- Fixed a small error in the Mobile Notification Provider. [Jamie Rees]
|
||||||
|
|
||||||
|
- Minor style tweaks. [Randall Bruder]
|
||||||
|
|
||||||
|
- Downgrade to .net core 2.0. [Jamie Rees]
|
||||||
|
|
||||||
|
- Downgrade Microsoft.AspNetCore.All package back to 2.0.8. [Jamie Rees]
|
||||||
|
|
||||||
|
- Removed old code. [Jamie Rees]
|
||||||
|
|
||||||
|
- Swap out the old way of validating the API key with a real middlewear this time. [Jamie Rees]
|
||||||
|
|
||||||
|
|
||||||
## v3.0.3421 (2018-06-23)
|
## v3.0.3421 (2018-06-23)
|
||||||
|
|
||||||
### **New Features**
|
### **New Features**
|
||||||
|
|
10
appveyor.yml
10
appveyor.yml
|
@ -15,19 +15,19 @@ test: off
|
||||||
after_build:
|
after_build:
|
||||||
- cmd: >-
|
- cmd: >-
|
||||||
|
|
||||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.0\windows.zip"
|
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.1\windows.zip"
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.0\osx.tar.gz"
|
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.1\osx.tar.gz"
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.0\linux.tar.gz"
|
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.1\linux.tar.gz"
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.0\linux-arm.tar.gz"
|
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.1\linux-arm.tar.gz"
|
||||||
|
|
||||||
|
|
||||||
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.0\windows-32bit.zip"
|
appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.1\windows-32bit.zip"
|
||||||
|
|
||||||
|
|
||||||
# appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.0\linux-arm64.tar.gz"
|
# appveyor PushArtifact "%APPVEYOR_BUILD_FOLDER%\src\Ombi\bin\Release\netcoreapp2.0\linux-arm64.tar.gz"
|
||||||
|
|
44
build.cake
44
build.cake
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
#tool "nuget:?package=GitVersion.CommandLine"
|
#tool "nuget:?package=GitVersion.CommandLine"
|
||||||
#addin "Cake.Gulp"
|
#addin "Cake.Gulp"
|
||||||
#addin "nuget:?package=Cake.Npm&version=0.13.0"
|
|
||||||
#addin "SharpZipLib"
|
#addin "SharpZipLib"
|
||||||
#addin nuget:?package=Cake.Compression&version=0.1.4
|
#addin nuget:?package=Cake.Compression&version=0.1.4
|
||||||
#addin "Cake.Incubator"
|
#addin "Cake.Incubator"
|
||||||
|
#addin "Cake.Yarn"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// ARGUMENTS
|
// ARGUMENTS
|
||||||
|
@ -26,7 +26,7 @@ var csProj = "./src/Ombi/Ombi.csproj"; // Path to the project.csproj
|
||||||
var solutionFile = "Ombi.sln"; // Solution file if needed
|
var solutionFile = "Ombi.sln"; // Solution file if needed
|
||||||
GitVersion versionInfo = null;
|
GitVersion versionInfo = null;
|
||||||
|
|
||||||
var frameworkVer = "netcoreapp2.0";
|
var frameworkVer = "netcoreapp2.1";
|
||||||
|
|
||||||
var buildSettings = new DotNetCoreBuildSettings
|
var buildSettings = new DotNetCoreBuildSettings
|
||||||
{
|
{
|
||||||
|
@ -122,36 +122,19 @@ Task("SetVersionInfo")
|
||||||
|
|
||||||
Task("NPM")
|
Task("NPM")
|
||||||
.Does(() => {
|
.Does(() => {
|
||||||
var settings = new NpmInstallSettings {
|
Yarn.FromPath(webProjDir).Install();
|
||||||
LogLevel = NpmLogLevel.Silent,
|
|
||||||
WorkingDirectory = webProjDir,
|
|
||||||
Production = true
|
|
||||||
};
|
|
||||||
|
|
||||||
NpmInstall(settings);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("Gulp Publish")
|
Task("Gulp Publish")
|
||||||
.IsDependentOn("NPM")
|
.IsDependentOn("NPM")
|
||||||
.Does(() => {
|
.Does(() => {
|
||||||
|
Yarn.FromPath(webProjDir).RunScript("publish");
|
||||||
var runScriptSettings = new NpmRunScriptSettings {
|
|
||||||
ScriptName="publish",
|
|
||||||
WorkingDirectory = webProjDir,
|
|
||||||
};
|
|
||||||
|
|
||||||
NpmRunScript(runScriptSettings);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("TSLint")
|
Task("TSLint")
|
||||||
.Does(() =>
|
.Does(() =>
|
||||||
{
|
{
|
||||||
var settings = new NpmRunScriptSettings {
|
Yarn.FromPath(webProjDir).RunScript("lint");
|
||||||
WorkingDirectory = webProjDir,
|
|
||||||
ScriptName = "lint"
|
|
||||||
};
|
|
||||||
|
|
||||||
NpmRunScript(settings);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("PrePublish")
|
Task("PrePublish")
|
||||||
|
@ -178,7 +161,7 @@ Task("Publish")
|
||||||
.IsDependentOn("Publish-OSX")
|
.IsDependentOn("Publish-OSX")
|
||||||
.IsDependentOn("Publish-Linux")
|
.IsDependentOn("Publish-Linux")
|
||||||
.IsDependentOn("Publish-Linux-ARM")
|
.IsDependentOn("Publish-Linux-ARM")
|
||||||
//.IsDependentOn("Publish-Linux-ARM-64Bit")
|
.IsDependentOn("Publish-Linux-ARM-64Bit")
|
||||||
.IsDependentOn("Package");
|
.IsDependentOn("Package");
|
||||||
|
|
||||||
Task("Publish-Windows")
|
Task("Publish-Windows")
|
||||||
|
@ -189,6 +172,8 @@ Task("Publish-Windows")
|
||||||
|
|
||||||
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
||||||
CopyFile(buildDir + "/"+frameworkVer+"/win10-x64/Swagger.xml", buildDir + "/"+frameworkVer+"/win10-x64/published/Swagger.xml");
|
CopyFile(buildDir + "/"+frameworkVer+"/win10-x64/Swagger.xml", buildDir + "/"+frameworkVer+"/win10-x64/published/Swagger.xml");
|
||||||
|
|
||||||
|
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer +"/win10-x64/published/updater");
|
||||||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -200,6 +185,9 @@ Task("Publish-Windows-32bit")
|
||||||
|
|
||||||
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
||||||
CopyFile(buildDir + "/"+frameworkVer+"/win10-x86/Swagger.xml", buildDir + "/"+frameworkVer+"/win10-x86/published/Swagger.xml");
|
CopyFile(buildDir + "/"+frameworkVer+"/win10-x86/Swagger.xml", buildDir + "/"+frameworkVer+"/win10-x86/published/Swagger.xml");
|
||||||
|
|
||||||
|
|
||||||
|
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer +"/win10-x86/published/updater");
|
||||||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -211,6 +199,8 @@ Task("Publish-OSX")
|
||||||
|
|
||||||
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
||||||
CopyFile(buildDir + "/"+frameworkVer+"/osx-x64/Swagger.xml", buildDir + "/"+frameworkVer+"/osx-x64/published/Swagger.xml");
|
CopyFile(buildDir + "/"+frameworkVer+"/osx-x64/Swagger.xml", buildDir + "/"+frameworkVer+"/osx-x64/published/Swagger.xml");
|
||||||
|
|
||||||
|
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer +"/osx-x64/published/updater");
|
||||||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -222,6 +212,8 @@ Task("Publish-Linux")
|
||||||
|
|
||||||
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi/Ombi.csproj", publishSettings);
|
||||||
CopyFile(buildDir + "/"+frameworkVer+"/linux-x64/Swagger.xml", buildDir + "/"+frameworkVer+"/linux-x64/published/Swagger.xml");
|
CopyFile(buildDir + "/"+frameworkVer+"/linux-x64/Swagger.xml", buildDir + "/"+frameworkVer+"/linux-x64/published/Swagger.xml");
|
||||||
|
|
||||||
|
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer +"/linux-x64/published/updater");
|
||||||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -235,6 +227,8 @@ Task("Publish-Linux-ARM")
|
||||||
CopyFile(
|
CopyFile(
|
||||||
buildDir + "/"+frameworkVer+"/linux-arm/Swagger.xml",
|
buildDir + "/"+frameworkVer+"/linux-arm/Swagger.xml",
|
||||||
buildDir + "/"+frameworkVer+"/linux-arm/published/Swagger.xml");
|
buildDir + "/"+frameworkVer+"/linux-arm/published/Swagger.xml");
|
||||||
|
|
||||||
|
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer +"/linux-arm/published/updater");
|
||||||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -248,6 +242,8 @@ Task("Publish-Linux-ARM-64Bit")
|
||||||
CopyFile(
|
CopyFile(
|
||||||
buildDir + "/"+frameworkVer+"/linux-arm64/Swagger.xml",
|
buildDir + "/"+frameworkVer+"/linux-arm64/Swagger.xml",
|
||||||
buildDir + "/"+frameworkVer+"/linux-arm64/published/Swagger.xml");
|
buildDir + "/"+frameworkVer+"/linux-arm64/published/Swagger.xml");
|
||||||
|
|
||||||
|
publishSettings.OutputDirectory = Directory(buildDir) + Directory(frameworkVer +"/linux-arm64/published/updater");
|
||||||
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
DotNetCorePublish("./src/Ombi.Updater/Ombi.Updater.csproj", publishSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
291
package-lock.json
generated
Normal file
291
package-lock.json
generated
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
{
|
||||||
|
"requires": true,
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||||
|
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||||
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||||
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
|
"requires": {
|
||||||
|
"sprintf-js": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-code-frame": {
|
||||||
|
"version": "6.26.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||||
|
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||||
|
"requires": {
|
||||||
|
"chalk": "1.1.3",
|
||||||
|
"esutils": "2.0.2",
|
||||||
|
"js-tokens": "3.0.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "2.2.1",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"has-ansi": "2.0.0",
|
||||||
|
"strip-ansi": "3.0.1",
|
||||||
|
"supports-color": "2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||||
|
},
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"builtin-modules": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "3.2.1",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"supports-color": "5.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "5.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||||
|
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
|
||||||
|
"requires": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
|
||||||
|
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="
|
||||||
|
},
|
||||||
|
"concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||||
|
},
|
||||||
|
"diff": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||||
|
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
|
||||||
|
},
|
||||||
|
"escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||||
|
},
|
||||||
|
"esprima": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
|
||||||
|
},
|
||||||
|
"esutils": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
||||||
|
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
|
||||||
|
},
|
||||||
|
"fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "7.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||||
|
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||||
|
"requires": {
|
||||||
|
"fs.realpath": "1.0.0",
|
||||||
|
"inflight": "1.0.6",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"once": "1.4.0",
|
||||||
|
"path-is-absolute": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-ansi": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||||
|
},
|
||||||
|
"inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||||
|
"requires": {
|
||||||
|
"once": "1.4.0",
|
||||||
|
"wrappy": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"js-tokens": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||||
|
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
|
||||||
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "3.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
|
||||||
|
"integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "1.0.10",
|
||||||
|
"esprima": "4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "1.1.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||||
|
"requires": {
|
||||||
|
"wrappy": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||||
|
},
|
||||||
|
"path-parse": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
|
||||||
|
},
|
||||||
|
"resolve": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
|
||||||
|
"requires": {
|
||||||
|
"path-parse": "1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
|
||||||
|
},
|
||||||
|
"sprintf-js": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
||||||
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz",
|
||||||
|
"integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw=="
|
||||||
|
},
|
||||||
|
"tslint": {
|
||||||
|
"version": "5.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.10.0.tgz",
|
||||||
|
"integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=",
|
||||||
|
"requires": {
|
||||||
|
"babel-code-frame": "6.26.0",
|
||||||
|
"builtin-modules": "1.1.1",
|
||||||
|
"chalk": "2.4.1",
|
||||||
|
"commander": "2.15.1",
|
||||||
|
"diff": "3.5.0",
|
||||||
|
"glob": "7.1.2",
|
||||||
|
"js-yaml": "3.12.0",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"resolve": "1.7.1",
|
||||||
|
"semver": "5.5.0",
|
||||||
|
"tslib": "1.9.2",
|
||||||
|
"tsutils": "2.27.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tsutils": {
|
||||||
|
"version": "2.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.27.1.tgz",
|
||||||
|
"integrity": "sha512-AE/7uzp32MmaHvNNFES85hhUDHFdFZp6OAiZcd6y4ZKKIg6orJTm8keYWBhIhrJQH3a4LzNKat7ZPXZt5aTf6w==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "1.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -91,27 +91,31 @@ namespace Ombi.Api.Emby
|
||||||
request.AddContentHeader("Content-Type", "application/json");
|
request.AddContentHeader("Content-Type", "application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EmbyItemContainer<MovieInformation>> GetCollection(string mediaId, string apiKey, string userId, string baseUrl)
|
public async Task<EmbyItemContainer<EmbyMovie>> GetCollection(string mediaId, string apiKey, string userId, string baseUrl)
|
||||||
{
|
{
|
||||||
var request = new Request($"emby/users/{userId}/items?parentId={mediaId}", baseUrl, HttpMethod.Get);
|
var request = new Request($"emby/users/{userId}/items?parentId={mediaId}", baseUrl, HttpMethod.Get);
|
||||||
AddHeaders(request, apiKey);
|
AddHeaders(request, apiKey);
|
||||||
|
|
||||||
return await Api.Request<EmbyItemContainer<MovieInformation>>(request);
|
request.AddQueryString("Fields", "ProviderIds,Overview");
|
||||||
|
|
||||||
|
request.AddQueryString("VirtualItem", "False");
|
||||||
|
|
||||||
|
return await Api.Request<EmbyItemContainer<EmbyMovie>>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EmbyItemContainer<EmbyMovie>> GetAllMovies(string apiKey, string userId, string baseUri)
|
public async Task<EmbyItemContainer<EmbyMovie>> GetAllMovies(string apiKey, int startIndex, int count, string userId, string baseUri)
|
||||||
{
|
{
|
||||||
return await GetAll<EmbyMovie>("Movie", apiKey, userId, baseUri, true);
|
return await GetAll<EmbyMovie>("Movie", apiKey, userId, baseUri, true, startIndex, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EmbyItemContainer<EmbyEpisodes>> GetAllEpisodes(string apiKey, string userId, string baseUri)
|
public async Task<EmbyItemContainer<EmbyEpisodes>> GetAllEpisodes(string apiKey, int startIndex, int count, string userId, string baseUri)
|
||||||
{
|
{
|
||||||
return await GetAll<EmbyEpisodes>("Episode", apiKey, userId, baseUri);
|
return await GetAll<EmbyEpisodes>("Episode", apiKey, userId, baseUri, false, startIndex, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EmbyItemContainer<EmbySeries>> GetAllShows(string apiKey, string userId, string baseUri)
|
public async Task<EmbyItemContainer<EmbySeries>> GetAllShows(string apiKey, int startIndex, int count, string userId, string baseUri)
|
||||||
{
|
{
|
||||||
return await GetAll<EmbySeries>("Series", apiKey, userId, baseUri);
|
return await GetAll<EmbySeries>("Series", apiKey, userId, baseUri, false, startIndex, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SeriesInformation> GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl)
|
public async Task<SeriesInformation> GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl)
|
||||||
|
@ -145,7 +149,25 @@ namespace Ombi.Api.Emby
|
||||||
request.AddQueryString("IncludeItemTypes", type);
|
request.AddQueryString("IncludeItemTypes", type);
|
||||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds");
|
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds");
|
||||||
|
|
||||||
request.AddQueryString("VirtualItem","False");
|
request.AddQueryString("VirtualItem", "False");
|
||||||
|
|
||||||
|
AddHeaders(request, apiKey);
|
||||||
|
|
||||||
|
|
||||||
|
var obj = await Api.Request<EmbyItemContainer<T>>(request);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
private async Task<EmbyItemContainer<T>> GetAll<T>(string type, string apiKey, string userId, string baseUri, bool includeOverview, int startIndex, int count)
|
||||||
|
{
|
||||||
|
var request = new Request($"emby/users/{userId}/items", baseUri, HttpMethod.Get);
|
||||||
|
|
||||||
|
request.AddQueryString("Recursive", true.ToString());
|
||||||
|
request.AddQueryString("IncludeItemTypes", type);
|
||||||
|
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds");
|
||||||
|
request.AddQueryString("startIndex", startIndex.ToString());
|
||||||
|
request.AddQueryString("limit", count.ToString());
|
||||||
|
|
||||||
|
request.AddQueryString("VirtualItem", "False");
|
||||||
|
|
||||||
AddHeaders(request, apiKey);
|
AddHeaders(request, apiKey);
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,17 @@ namespace Ombi.Api.Emby
|
||||||
Task<EmbyUser> LogIn(string username, string password, string apiKey, string baseUri);
|
Task<EmbyUser> LogIn(string username, string password, string apiKey, string baseUri);
|
||||||
Task<EmbyConnectUser> LoginConnectUser(string username, string password);
|
Task<EmbyConnectUser> LoginConnectUser(string username, string password);
|
||||||
|
|
||||||
Task<EmbyItemContainer<EmbyMovie>> GetAllMovies(string apiKey, string userId, string baseUri);
|
Task<EmbyItemContainer<EmbyMovie>> GetAllMovies(string apiKey, int startIndex, int count, string userId,
|
||||||
Task<EmbyItemContainer<EmbyEpisodes>> GetAllEpisodes(string apiKey, string userId, string baseUri);
|
string baseUri);
|
||||||
Task<EmbyItemContainer<EmbySeries>> GetAllShows(string apiKey, string userId, string baseUri);
|
|
||||||
|
|
||||||
Task<EmbyItemContainer<MovieInformation>> GetCollection(string mediaId, string apiKey, string userId,
|
Task<EmbyItemContainer<EmbyEpisodes>> GetAllEpisodes(string apiKey, int startIndex, int count, string userId,
|
||||||
string baseUrl);
|
string baseUri);
|
||||||
|
|
||||||
|
Task<EmbyItemContainer<EmbySeries>> GetAllShows(string apiKey, int startIndex, int count, string userId,
|
||||||
|
string baseUri);
|
||||||
|
|
||||||
|
Task<EmbyItemContainer<EmbyMovie>> GetCollection(string mediaId,
|
||||||
|
string apiKey, string userId, string baseUrl);
|
||||||
|
|
||||||
Task<SeriesInformation> GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl);
|
Task<SeriesInformation> GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl);
|
||||||
Task<MovieInformation> GetMovieInformation(string mediaId, string apiKey, string userId, string baseUrl);
|
Task<MovieInformation> GetMovieInformation(string mediaId, string apiKey, string userId, string baseUrl);
|
||||||
|
|
|
@ -6,6 +6,6 @@ namespace Ombi.Api.Notifications
|
||||||
{
|
{
|
||||||
public interface IOneSignalApi
|
public interface IOneSignalApi
|
||||||
{
|
{
|
||||||
Task<OneSignalNotificationResponse> PushNotification(List<string> playerIds, string message);
|
Task<OneSignalNotificationResponse> PushNotification(List<string> playerIds, string message, bool isAdminNotification, int requestId, int requestType);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,18 +4,22 @@
|
||||||
{
|
{
|
||||||
public string app_id { get; set; }
|
public string app_id { get; set; }
|
||||||
public string[] include_player_ids { get; set; }
|
public string[] include_player_ids { get; set; }
|
||||||
public Data data { get; set; }
|
public object data { get; set; }
|
||||||
|
public Button[] buttons { get; set; }
|
||||||
public Contents contents { get; set; }
|
public Contents contents { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Data
|
|
||||||
{
|
|
||||||
public string foo { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Contents
|
public class Contents
|
||||||
{
|
{
|
||||||
public string en { get; set; }
|
public string en { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Button
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public string text { get; set; }
|
||||||
|
//public string icon { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,6 +4,10 @@
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Humanizer.Core" Version="2.4.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Ombi.Api.Notifications
|
||||||
private readonly IApplicationConfigRepository _appConfig;
|
private readonly IApplicationConfigRepository _appConfig;
|
||||||
private const string ApiUrl = "https://onesignal.com/api/v1/notifications";
|
private const string ApiUrl = "https://onesignal.com/api/v1/notifications";
|
||||||
|
|
||||||
public async Task<OneSignalNotificationResponse> PushNotification(List<string> playerIds, string message)
|
public async Task<OneSignalNotificationResponse> PushNotification(List<string> playerIds, string message, bool isAdminNotification, int requestId, int requestType)
|
||||||
{
|
{
|
||||||
if (!playerIds.Any())
|
if (!playerIds.Any())
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,17 @@ namespace Ombi.Api.Notifications
|
||||||
include_player_ids = playerIds.ToArray()
|
include_player_ids = playerIds.ToArray()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (isAdminNotification)
|
||||||
|
{
|
||||||
|
// Add the action buttons
|
||||||
|
body.data = new { requestid = requestId, requestType = requestType};
|
||||||
|
body.buttons = new[]
|
||||||
|
{
|
||||||
|
new Button {id = "approve", text = "Approve Request"},
|
||||||
|
new Button {id = "deny", text = "Deny Request"},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
request.AddJsonBody(body);
|
request.AddJsonBody(body);
|
||||||
|
|
||||||
var result = await _api.Request<OneSignalNotificationResponse>(request);
|
var result = await _api.Request<OneSignalNotificationResponse>(request);
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace Ombi.Api.Plex
|
||||||
public interface IPlexApi
|
public interface IPlexApi
|
||||||
{
|
{
|
||||||
Task<PlexStatus> GetStatus(string authToken, string uri);
|
Task<PlexStatus> GetStatus(string authToken, string uri);
|
||||||
|
Task<PlexLibrariesForMachineId> GetLibrariesForMachineId(string authToken, string machineId);
|
||||||
Task<PlexAuthentication> SignIn(UserRequest user);
|
Task<PlexAuthentication> SignIn(UserRequest user);
|
||||||
Task<PlexServer> GetServer(string authToken);
|
Task<PlexServer> GetServer(string authToken);
|
||||||
Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost);
|
Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost);
|
||||||
|
@ -22,8 +23,8 @@ namespace Ombi.Api.Plex
|
||||||
Task<PlexFriends> GetUsers(string authToken);
|
Task<PlexFriends> GetUsers(string authToken);
|
||||||
Task<PlexAccount> GetAccount(string authToken);
|
Task<PlexAccount> GetAccount(string authToken);
|
||||||
Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId);
|
Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId);
|
||||||
Task<OAuthPin> CreatePin();
|
|
||||||
Task<OAuthPin> GetPin(int pinId);
|
Task<OAuthPin> GetPin(int pinId);
|
||||||
Uri GetOAuthUrl(int pinId, string code, string applicationUrl, bool wizard);
|
Task<Uri> GetOAuthUrl(int pinId, string code, string applicationUrl);
|
||||||
|
Task<PlexAddWrapper> AddUser(string emailAddress, string serverId, string authToken, int[] libs);
|
||||||
}
|
}
|
||||||
}
|
}
|
84
src/Ombi.Api.Plex/Models/PlexAdd.cs
Normal file
84
src/Ombi.Api.Plex/Models/PlexAdd.cs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace Ombi.Api.Plex.Models
|
||||||
|
{
|
||||||
|
[XmlRoot(ElementName = "Section")]
|
||||||
|
public class Section
|
||||||
|
{
|
||||||
|
[XmlAttribute(AttributeName = "id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "title")]
|
||||||
|
public string Title { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "shared")]
|
||||||
|
public string Shared { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "SharedServer")]
|
||||||
|
public class SharedServer
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "Section")]
|
||||||
|
public List<Section> Section { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "username")]
|
||||||
|
public string Username { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "email")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "userID")]
|
||||||
|
public string UserID { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "accessToken")]
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "acceptedAt")]
|
||||||
|
public string AcceptedAt { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "invitedAt")]
|
||||||
|
public string InvitedAt { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "allowSync")]
|
||||||
|
public string AllowSync { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "allowCameraUpload")]
|
||||||
|
public string AllowCameraUpload { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "allowChannels")]
|
||||||
|
public string AllowChannels { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "allowTuners")]
|
||||||
|
public string AllowTuners { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "owned")]
|
||||||
|
public string Owned { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "MediaContainer")]
|
||||||
|
public class PlexAdd
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "SharedServer")]
|
||||||
|
public SharedServer SharedServer { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "friendlyName")]
|
||||||
|
public string FriendlyName { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "identifier")]
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "machineIdentifier")]
|
||||||
|
public string MachineIdentifier { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "size")]
|
||||||
|
public string Size { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "Response")]
|
||||||
|
public class AddUserError
|
||||||
|
{
|
||||||
|
[XmlAttribute(AttributeName = "code")]
|
||||||
|
public string Code { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "status")]
|
||||||
|
public string Status { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PlexAddWrapper
|
||||||
|
{
|
||||||
|
public PlexAdd Add { get; set; }
|
||||||
|
public AddUserError Error { get; set; }
|
||||||
|
public bool HasError => Error != null;
|
||||||
|
}
|
||||||
|
}
|
66
src/Ombi.Api.Plex/Models/PlexLibrariesForMachineId.cs
Normal file
66
src/Ombi.Api.Plex/Models/PlexLibrariesForMachineId.cs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
namespace Ombi.Api.Plex.Models
|
||||||
|
{
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "Section")]
|
||||||
|
public class SectionLite
|
||||||
|
{
|
||||||
|
[XmlAttribute(AttributeName = "id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "title")]
|
||||||
|
public string Title { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "Server")]
|
||||||
|
public class ServerLib
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "Section")]
|
||||||
|
public List<SectionLite> Section { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "address")]
|
||||||
|
public string Address { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "port")]
|
||||||
|
public string Port { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "version")]
|
||||||
|
public string Version { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "scheme")]
|
||||||
|
public string Scheme { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "host")]
|
||||||
|
public string Host { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "localAddresses")]
|
||||||
|
public string LocalAddresses { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "machineIdentifier")]
|
||||||
|
public string MachineIdentifier { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "createdAt")]
|
||||||
|
public string CreatedAt { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "updatedAt")]
|
||||||
|
public string UpdatedAt { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "owned")]
|
||||||
|
public string Owned { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "synced")]
|
||||||
|
public string Synced { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "MediaContainer")]
|
||||||
|
public class PlexLibrariesForMachineId
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "Server")]
|
||||||
|
public ServerLib Server { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "friendlyName")]
|
||||||
|
public string FriendlyName { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "identifier")]
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "machineIdentifier")]
|
||||||
|
public string MachineIdentifier { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "size")]
|
||||||
|
public string Size { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,14 +16,16 @@ namespace Ombi.Api.Plex
|
||||||
{
|
{
|
||||||
public class PlexApi : IPlexApi
|
public class PlexApi : IPlexApi
|
||||||
{
|
{
|
||||||
public PlexApi(IApi api, ISettingsService<CustomizationSettings> settings)
|
public PlexApi(IApi api, ISettingsService<CustomizationSettings> settings, ISettingsService<PlexSettings> p)
|
||||||
{
|
{
|
||||||
Api = api;
|
Api = api;
|
||||||
_custom = settings;
|
_custom = settings;
|
||||||
|
_plexSettings = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IApi Api { get; }
|
private IApi Api { get; }
|
||||||
private readonly ISettingsService<CustomizationSettings> _custom;
|
private readonly ISettingsService<CustomizationSettings> _custom;
|
||||||
|
private readonly ISettingsService<PlexSettings> _plexSettings;
|
||||||
|
|
||||||
private string _app;
|
private string _app;
|
||||||
private string ApplicationName
|
private string ApplicationName
|
||||||
|
@ -39,7 +41,18 @@ namespace Ombi.Api.Plex
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_app = settings.ApplicationName;
|
// Check for non-ascii characters (New .Net Core HTTPLib does not allow this)
|
||||||
|
var chars = settings.ApplicationName.ToCharArray();
|
||||||
|
var hasNonAscii = false;
|
||||||
|
foreach (var c in chars)
|
||||||
|
{
|
||||||
|
if (c > 128)
|
||||||
|
{
|
||||||
|
hasNonAscii = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_app = hasNonAscii ? "Ombi" : settings.ApplicationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _app;
|
return _app;
|
||||||
|
@ -69,7 +82,7 @@ namespace Ombi.Api.Plex
|
||||||
};
|
};
|
||||||
var request = new Request(SignInUri, string.Empty, HttpMethod.Post);
|
var request = new Request(SignInUri, string.Empty, HttpMethod.Post);
|
||||||
|
|
||||||
AddHeaders(request);
|
await AddHeaders(request);
|
||||||
request.AddJsonBody(userModel);
|
request.AddJsonBody(userModel);
|
||||||
|
|
||||||
var obj = await Api.Request<PlexAuthentication>(request);
|
var obj = await Api.Request<PlexAuthentication>(request);
|
||||||
|
@ -80,14 +93,14 @@ namespace Ombi.Api.Plex
|
||||||
public async Task<PlexStatus> GetStatus(string authToken, string uri)
|
public async Task<PlexStatus> GetStatus(string authToken, string uri)
|
||||||
{
|
{
|
||||||
var request = new Request(uri, string.Empty, HttpMethod.Get);
|
var request = new Request(uri, string.Empty, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
return await Api.Request<PlexStatus>(request);
|
return await Api.Request<PlexStatus>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PlexAccount> GetAccount(string authToken)
|
public async Task<PlexAccount> GetAccount(string authToken)
|
||||||
{
|
{
|
||||||
var request = new Request(GetAccountUri, string.Empty, HttpMethod.Get);
|
var request = new Request(GetAccountUri, string.Empty, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
return await Api.Request<PlexAccount>(request);
|
return await Api.Request<PlexAccount>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +108,7 @@ namespace Ombi.Api.Plex
|
||||||
{
|
{
|
||||||
var request = new Request(ServerUri, string.Empty, HttpMethod.Get, ContentType.Xml);
|
var request = new Request(ServerUri, string.Empty, HttpMethod.Get, ContentType.Xml);
|
||||||
|
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
|
|
||||||
return await Api.Request<PlexServer>(request);
|
return await Api.Request<PlexServer>(request);
|
||||||
}
|
}
|
||||||
|
@ -103,17 +116,24 @@ namespace Ombi.Api.Plex
|
||||||
public async Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost)
|
public async Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost)
|
||||||
{
|
{
|
||||||
var request = new Request("library/sections", plexFullHost, HttpMethod.Get);
|
var request = new Request("library/sections", plexFullHost, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
return await Api.Request<PlexContainer>(request);
|
return await Api.Request<PlexContainer>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PlexContainer> GetLibrary(string authToken, string plexFullHost, string libraryId)
|
public async Task<PlexContainer> GetLibrary(string authToken, string plexFullHost, string libraryId)
|
||||||
{
|
{
|
||||||
var request = new Request($"library/sections/{libraryId}/all", plexFullHost, HttpMethod.Get);
|
var request = new Request($"library/sections/{libraryId}/all", plexFullHost, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
return await Api.Request<PlexContainer>(request);
|
return await Api.Request<PlexContainer>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<PlexLibrariesForMachineId> GetLibrariesForMachineId(string authToken, string machineId)
|
||||||
|
{
|
||||||
|
var request = new Request("", $"https://plex.tv/api/servers/{machineId}", HttpMethod.Get, ContentType.Xml);
|
||||||
|
await AddHeaders(request, authToken);
|
||||||
|
return await Api.Request<PlexLibrariesForMachineId>(request);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
// 192.168.1.69:32400/library/metadata/3662/allLeaves
|
// 192.168.1.69:32400/library/metadata/3662/allLeaves
|
||||||
// The metadata ratingkey should be in the Cache
|
// The metadata ratingkey should be in the Cache
|
||||||
|
@ -128,21 +148,21 @@ namespace Ombi.Api.Plex
|
||||||
public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, int ratingKey)
|
public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, int ratingKey)
|
||||||
{
|
{
|
||||||
var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get);
|
var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
return await Api.Request<PlexMetadata>(request);
|
return await Api.Request<PlexMetadata>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, int itemId)
|
public async Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, int itemId)
|
||||||
{
|
{
|
||||||
var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get);
|
var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
return await Api.Request<PlexMetadata>(request);
|
return await Api.Request<PlexMetadata>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, int ratingKey)
|
public async Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, int ratingKey)
|
||||||
{
|
{
|
||||||
var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get);
|
var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
return await Api.Request<PlexMetadata>(request);
|
return await Api.Request<PlexMetadata>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +181,9 @@ namespace Ombi.Api.Plex
|
||||||
|
|
||||||
request.AddQueryString("type", "4");
|
request.AddQueryString("type", "4");
|
||||||
AddLimitHeaders(request, start, retCount);
|
AddLimitHeaders(request, start, retCount);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
|
|
||||||
return await Api.Request<PlexContainer>(request);
|
return await Api.Request<PlexContainer>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -174,8 +194,8 @@ namespace Ombi.Api.Plex
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<PlexFriends> GetUsers(string authToken)
|
public async Task<PlexFriends> GetUsers(string authToken)
|
||||||
{
|
{
|
||||||
var request = new Request(string.Empty,FriendsUri, HttpMethod.Get, ContentType.Xml);
|
var request = new Request(string.Empty, FriendsUri, HttpMethod.Get, ContentType.Xml);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
|
|
||||||
return await Api.Request<PlexFriends>(request);
|
return await Api.Request<PlexFriends>(request);
|
||||||
}
|
}
|
||||||
|
@ -183,43 +203,36 @@ namespace Ombi.Api.Plex
|
||||||
public async Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId)
|
public async Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId)
|
||||||
{
|
{
|
||||||
var request = new Request($"library/sections/{sectionId}/recentlyAdded", uri, HttpMethod.Get);
|
var request = new Request($"library/sections/{sectionId}/recentlyAdded", uri, HttpMethod.Get);
|
||||||
AddHeaders(request, authToken);
|
await AddHeaders(request, authToken);
|
||||||
AddLimitHeaders(request, 0, 50);
|
AddLimitHeaders(request, 0, 50);
|
||||||
|
|
||||||
return await Api.Request<PlexMetadata>(request);
|
return await Api.Request<PlexMetadata>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OAuthPin> CreatePin()
|
|
||||||
{
|
|
||||||
var request = new Request($"api/v2/pins", "https://plex.tv/", HttpMethod.Post);
|
|
||||||
request.AddQueryString("strong", "true");
|
|
||||||
AddHeaders(request);
|
|
||||||
|
|
||||||
return await Api.Request<OAuthPin>(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<OAuthPin> GetPin(int pinId)
|
public async Task<OAuthPin> GetPin(int pinId)
|
||||||
{
|
{
|
||||||
var request = new Request($"api/v2/pins/{pinId}", "https://plex.tv/", HttpMethod.Get);
|
var request = new Request($"api/v2/pins/{pinId}", "https://plex.tv/", HttpMethod.Get);
|
||||||
AddHeaders(request);
|
await AddHeaders(request);
|
||||||
|
|
||||||
return await Api.Request<OAuthPin>(request);
|
return await Api.Request<OAuthPin>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri GetOAuthUrl(int pinId, string code, string applicationUrl, bool wizard)
|
public async Task<Uri> GetOAuthUrl(int pinId, string code, string applicationUrl)
|
||||||
{
|
{
|
||||||
var request = new Request("auth#", "https://app.plex.tv", HttpMethod.Get);
|
var request = new Request("auth#", "https://app.plex.tv", HttpMethod.Get);
|
||||||
AddHeaders(request);
|
await AddHeaders(request);
|
||||||
var forwardUrl = wizard
|
|
||||||
? new Request($"Wizard/OAuth/{pinId}", applicationUrl, HttpMethod.Get)
|
|
||||||
: new Request($"Login/OAuth/{pinId}", applicationUrl, HttpMethod.Get);
|
|
||||||
|
|
||||||
request.AddQueryString("forwardUrl", forwardUrl.FullUri.ToString());
|
|
||||||
request.AddQueryString("pinID", pinId.ToString());
|
request.AddQueryString("pinID", pinId.ToString());
|
||||||
request.AddQueryString("code", code);
|
request.AddQueryString("code", code);
|
||||||
request.AddQueryString("context[device][product]", "Ombi");
|
request.AddQueryString("context[device][product]", ApplicationName);
|
||||||
request.AddQueryString("context[device][environment]", "bundled");
|
request.AddQueryString("context[device][environment]", "bundled");
|
||||||
request.AddQueryString("clientID", $"OmbiV3");
|
request.AddQueryString("context[device][layout]", "desktop");
|
||||||
|
request.AddQueryString("context[device][platform]", "Web");
|
||||||
|
request.AddQueryString("context[device][device]", "Ombi (Web)");
|
||||||
|
|
||||||
|
var s = await GetSettings();
|
||||||
|
await CheckInstallId(s);
|
||||||
|
request.AddQueryString("clientID", s.InstallId.ToString("N"));
|
||||||
|
|
||||||
if (request.FullUri.Fragment.Equals("#"))
|
if (request.FullUri.Fragment.Equals("#"))
|
||||||
{
|
{
|
||||||
|
@ -233,26 +246,58 @@ namespace Ombi.Api.Plex
|
||||||
return request.FullUri;
|
return request.FullUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<PlexAddWrapper> AddUser(string emailAddress, string serverId, string authToken, int[] libs)
|
||||||
|
{
|
||||||
|
var request = new Request(string.Empty, $"https://plex.tv/api/servers/{serverId}/shared_servers", HttpMethod.Post, ContentType.Xml);
|
||||||
|
await AddHeaders(request, authToken);
|
||||||
|
request.AddJsonBody(new
|
||||||
|
{
|
||||||
|
server_id = serverId,
|
||||||
|
shared_server = new
|
||||||
|
{
|
||||||
|
library_section_ids = libs.Length > 0 ? libs : new int[]{},
|
||||||
|
invited_email = emailAddress
|
||||||
|
},
|
||||||
|
sharing_settings = new { }
|
||||||
|
});
|
||||||
|
var result = await Api.RequestContent(request);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var add = Api.DeserializeXml<PlexAdd>(result);
|
||||||
|
return new PlexAddWrapper{Add = add};
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
var error = Api.DeserializeXml<AddUserError>(result);
|
||||||
|
return new PlexAddWrapper{Error = error};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the required headers and also the authorization header
|
/// Adds the required headers and also the authorization header
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="authToken"></param>
|
/// <param name="authToken"></param>
|
||||||
private void AddHeaders(Request request, string authToken)
|
private async Task AddHeaders(Request request, string authToken)
|
||||||
{
|
{
|
||||||
request.AddHeader("X-Plex-Token", authToken);
|
request.AddHeader("X-Plex-Token", authToken);
|
||||||
AddHeaders(request);
|
await AddHeaders(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the main required headers to the Plex Request
|
/// Adds the main required headers to the Plex Request
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
private void AddHeaders(Request request)
|
private async Task AddHeaders(Request request)
|
||||||
{
|
{
|
||||||
request.AddHeader("X-Plex-Client-Identifier", $"OmbiV3");
|
var s = await GetSettings();
|
||||||
|
await CheckInstallId(s);
|
||||||
|
request.AddHeader("X-Plex-Client-Identifier", s.InstallId.ToString("N"));
|
||||||
request.AddHeader("X-Plex-Product", ApplicationName);
|
request.AddHeader("X-Plex-Product", ApplicationName);
|
||||||
request.AddHeader("X-Plex-Version", "3");
|
request.AddHeader("X-Plex-Version", "3");
|
||||||
|
request.AddHeader("X-Plex-Device", "Ombi (Web)");
|
||||||
|
request.AddHeader("X-Plex-Platform", "Web");
|
||||||
request.AddContentHeader("Content-Type", request.ContentType == ContentType.Json ? "application/json" : "application/xml");
|
request.AddContentHeader("Content-Type", request.ContentType == ContentType.Json ? "application/json" : "application/xml");
|
||||||
request.AddHeader("Accept", "application/json");
|
request.AddHeader("Accept", "application/json");
|
||||||
}
|
}
|
||||||
|
@ -262,5 +307,19 @@ namespace Ombi.Api.Plex
|
||||||
request.AddHeader("X-Plex-Container-Start", from.ToString());
|
request.AddHeader("X-Plex-Container-Start", from.ToString());
|
||||||
request.AddHeader("X-Plex-Container-Size", to.ToString());
|
request.AddHeader("X-Plex-Container-Size", to.ToString());
|
||||||
}
|
}
|
||||||
|
private async Task CheckInstallId(PlexSettings s)
|
||||||
|
{
|
||||||
|
if (s.InstallId == null || s.InstallId == Guid.Empty)
|
||||||
|
{
|
||||||
|
s.InstallId = Guid.NewGuid();
|
||||||
|
await _plexSettings.SaveSettingsAsync(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlexSettings _settings;
|
||||||
|
private async Task<PlexSettings> GetSettings()
|
||||||
|
{
|
||||||
|
return _settings ?? (_settings = await _plexSettings.GetSettingsAsync());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace Ombi.Api.Radarr
|
||||||
tmdbId = tmdbId,
|
tmdbId = tmdbId,
|
||||||
qualityProfileId = qualityId,
|
qualityProfileId = qualityId,
|
||||||
rootFolderPath = rootPath,
|
rootFolderPath = rootPath,
|
||||||
titleSlug = title,
|
titleSlug = title + year,
|
||||||
monitored = true,
|
monitored = true,
|
||||||
year = year,
|
year = year,
|
||||||
minimumAvailability = minimumAvailability
|
minimumAvailability = minimumAvailability
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Options" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Options" Version="2.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -6,6 +6,30 @@ namespace Ombi.Api.Sonarr.Models
|
||||||
{
|
{
|
||||||
public class Episode
|
public class Episode
|
||||||
{
|
{
|
||||||
|
public Episode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Episode(Episode ep)
|
||||||
|
{
|
||||||
|
seriesId = ep.seriesId;
|
||||||
|
episodeFileId = ep.episodeFileId;
|
||||||
|
seasonNumber = ep.seasonNumber;
|
||||||
|
episodeNumber = ep.episodeNumber;
|
||||||
|
title = ep.title;
|
||||||
|
airDate = ep.airDate;
|
||||||
|
airDateUtc = ep.airDateUtc;
|
||||||
|
overview = ep.overview;
|
||||||
|
hasFile = ep.hasFile;
|
||||||
|
monitored = ep.monitored;
|
||||||
|
unverifiedSceneNumbering = ep.unverifiedSceneNumbering;
|
||||||
|
id = ep.id;
|
||||||
|
absoluteEpisodeNumber = ep.absoluteEpisodeNumber;
|
||||||
|
sceneAbsoluteEpisodeNumber = ep.sceneAbsoluteEpisodeNumber;
|
||||||
|
sceneEpisodeNumber = ep.sceneEpisodeNumber;
|
||||||
|
sceneSeasonNumber = ep.sceneSeasonNumber;
|
||||||
|
}
|
||||||
public int seriesId { get; set; }
|
public int seriesId { get; set; }
|
||||||
public int episodeFileId { get; set; }
|
public int episodeFileId { get; set; }
|
||||||
public int seasonNumber { get; set; }
|
public int seasonNumber { get; set; }
|
||||||
|
@ -27,6 +51,24 @@ namespace Ombi.Api.Sonarr.Models
|
||||||
|
|
||||||
public class Episodefile
|
public class Episodefile
|
||||||
{
|
{
|
||||||
|
public Episodefile()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Episodefile(Episodefile e)
|
||||||
|
{
|
||||||
|
seriesId = e.seriesId;
|
||||||
|
seasonNumber = e.seasonNumber;
|
||||||
|
relativePath = e.relativePath;
|
||||||
|
path = e.path;
|
||||||
|
size = e.size;
|
||||||
|
dateAdded = e.dateAdded;
|
||||||
|
sceneName = e.sceneName;
|
||||||
|
quality = new EpisodeQuality(e.quality);
|
||||||
|
qualityCutoffNotMet = e.qualityCutoffNotMet;
|
||||||
|
id = e.id;
|
||||||
|
}
|
||||||
public int seriesId { get; set; }
|
public int seriesId { get; set; }
|
||||||
public int seasonNumber { get; set; }
|
public int seasonNumber { get; set; }
|
||||||
public string relativePath { get; set; }
|
public string relativePath { get; set; }
|
||||||
|
@ -41,12 +83,32 @@ namespace Ombi.Api.Sonarr.Models
|
||||||
|
|
||||||
public class EpisodeQuality
|
public class EpisodeQuality
|
||||||
{
|
{
|
||||||
|
public EpisodeQuality()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public EpisodeQuality(EpisodeQuality e)
|
||||||
|
{
|
||||||
|
quality = new Quality(e.quality);
|
||||||
|
revision = new Revision(e.revision);
|
||||||
|
}
|
||||||
public Quality quality { get; set; }
|
public Quality quality { get; set; }
|
||||||
public Revision revision { get; set; }
|
public Revision revision { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Revision
|
public class Revision
|
||||||
{
|
{
|
||||||
|
public Revision()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Revision(Revision r)
|
||||||
|
{
|
||||||
|
version = r.version;
|
||||||
|
real = r.real;
|
||||||
|
}
|
||||||
public int version { get; set; }
|
public int version { get; set; }
|
||||||
public int real { get; set; }
|
public int real { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace Ombi.Api.Sonarr.Models
|
||||||
public string cleanTitle { get; set; }
|
public string cleanTitle { get; set; }
|
||||||
public string imdbId { get; set; }
|
public string imdbId { get; set; }
|
||||||
public string titleSlug { get; set; }
|
public string titleSlug { get; set; }
|
||||||
|
public string seriesType { get; set; }
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
public List<SonarrImage> images { get; set; }
|
public List<SonarrImage> images { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,16 @@ namespace Ombi.Api.Sonarr.Models
|
||||||
{
|
{
|
||||||
public class Quality
|
public class Quality
|
||||||
{
|
{
|
||||||
|
public Quality()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Quality(Quality q)
|
||||||
|
{
|
||||||
|
id = q.id;
|
||||||
|
name = q.name;
|
||||||
|
}
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,15 +80,20 @@ namespace Ombi.Api
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// XML
|
// XML
|
||||||
XmlSerializer serializer = new XmlSerializer(typeof(T));
|
return DeserializeXml<T>(receivedString);
|
||||||
StringReader reader = new StringReader(receivedString);
|
|
||||||
var value = (T)serializer.Deserialize(reader);
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T DeserializeXml<T>(string receivedString)
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(T));
|
||||||
|
StringReader reader = new StringReader(receivedString);
|
||||||
|
var value = (T) serializer.Deserialize(reader);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<string> RequestContent(Request request)
|
public async Task<string> RequestContent(Request request)
|
||||||
{
|
{
|
||||||
using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri))
|
using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri))
|
||||||
|
|
|
@ -7,5 +7,6 @@ namespace Ombi.Api
|
||||||
Task Request(Request request);
|
Task Request(Request request);
|
||||||
Task<T> Request<T>(Request request);
|
Task<T> Request<T>(Request request);
|
||||||
Task<string> RequestContent(Request request);
|
Task<string> RequestContent(Request request);
|
||||||
|
T DeserializeXml<T>(string receivedString);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,9 +9,9 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="Polly" Version="5.8.0" />
|
<PackageReference Include="Polly" Version="6.1.0" />
|
||||||
<PackageReference Include="System.Xml.XmlSerializer" Version="4.3.0" />
|
<PackageReference Include="System.Xml.XmlSerializer" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<PackageReference Include="Nunit" Version="3.8.1" />
|
<PackageReference Include="Nunit" Version="3.8.1" />
|
||||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
|
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
|
||||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.7.2"></packagereference>
|
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.8.0"></packagereference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -29,7 +29,10 @@ namespace Ombi.Core.Tests.Rule.Search
|
||||||
{
|
{
|
||||||
ProviderId = "123"
|
ProviderId = "123"
|
||||||
});
|
});
|
||||||
var search = new SearchMovieViewModel();
|
var search = new SearchMovieViewModel()
|
||||||
|
{
|
||||||
|
TheMovieDbId = "123",
|
||||||
|
};
|
||||||
var result = await Rule.Execute(search);
|
var result = await Rule.Execute(search);
|
||||||
|
|
||||||
Assert.True(result.Success);
|
Assert.True(result.Success);
|
||||||
|
|
|
@ -20,12 +20,6 @@ namespace Ombi.Core.Authentication
|
||||||
private readonly IPlexApi _api;
|
private readonly IPlexApi _api;
|
||||||
private readonly ISettingsService<CustomizationSettings> _customizationSettingsService;
|
private readonly ISettingsService<CustomizationSettings> _customizationSettingsService;
|
||||||
|
|
||||||
public async Task<OAuthPin> RequestPin()
|
|
||||||
{
|
|
||||||
var pin = await _api.CreatePin();
|
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetAccessTokenFromPin(int pinId)
|
public async Task<string> GetAccessTokenFromPin(int pinId)
|
||||||
{
|
{
|
||||||
var pin = await _api.GetPin(pinId);
|
var pin = await _api.GetPin(pinId);
|
||||||
|
@ -34,19 +28,6 @@ namespace Ombi.Core.Authentication
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pin.authToken.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
// Looks like we do not have a pin yet, we should retry a few times.
|
|
||||||
var retryCount = 0;
|
|
||||||
var retryMax = 5;
|
|
||||||
var retryWaitMs = 1000;
|
|
||||||
while (pin.authToken.IsNullOrEmpty() && retryCount < retryMax)
|
|
||||||
{
|
|
||||||
retryCount++;
|
|
||||||
await Task.Delay(retryWaitMs);
|
|
||||||
pin = await _api.GetPin(pinId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pin.authToken;
|
return pin.authToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +39,14 @@ namespace Ombi.Core.Authentication
|
||||||
public async Task<Uri> GetOAuthUrl(int pinId, string code, string websiteAddress = null)
|
public async Task<Uri> GetOAuthUrl(int pinId, string code, string websiteAddress = null)
|
||||||
{
|
{
|
||||||
var settings = await _customizationSettingsService.GetSettingsAsync();
|
var settings = await _customizationSettingsService.GetSettingsAsync();
|
||||||
var url = _api.GetOAuthUrl(pinId, code, settings.ApplicationUrl.IsNullOrEmpty() ? websiteAddress : settings.ApplicationUrl, false);
|
var url = await _api.GetOAuthUrl(pinId, code, settings.ApplicationUrl.IsNullOrEmpty() ? websiteAddress : settings.ApplicationUrl);
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri GetWizardOAuthUrl(int pinId, string code, string websiteAddress)
|
public async Task<Uri> GetWizardOAuthUrl(int pinId, string code, string websiteAddress)
|
||||||
{
|
{
|
||||||
var url = _api.GetOAuthUrl(pinId, code, websiteAddress, true);
|
var url = await _api.GetOAuthUrl(pinId, code, websiteAddress);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
src/Ombi.Core/Engine/IUserStatsEngine.cs
Normal file
9
src/Ombi.Core/Engine/IUserStatsEngine.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Engine
|
||||||
|
{
|
||||||
|
public interface IUserStatsEngine
|
||||||
|
{
|
||||||
|
Task<UserStatsSummary> GetSummary(SummaryRequest request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,13 +15,13 @@ namespace Ombi.Core.Engine.Interfaces
|
||||||
Task<RequestEngineResult> DenyChildRequest(int requestId);
|
Task<RequestEngineResult> DenyChildRequest(int requestId);
|
||||||
Task<RequestsViewModel<TvRequests>> GetRequestsLite(int count, int position, OrderFilterModel type);
|
Task<RequestsViewModel<TvRequests>> GetRequestsLite(int count, int position, OrderFilterModel type);
|
||||||
Task<IEnumerable<TvRequests>> SearchTvRequest(string search);
|
Task<IEnumerable<TvRequests>> SearchTvRequest(string search);
|
||||||
Task<IEnumerable<TreeNode<TvRequests, List<ChildRequests>>>> SearchTvRequestTree(string search);
|
|
||||||
Task<TvRequests> UpdateTvRequest(TvRequests request);
|
Task<TvRequests> UpdateTvRequest(TvRequests request);
|
||||||
Task<IEnumerable<TreeNode<TvRequests, List<ChildRequests>>>> GetRequestsTreeNode(int count, int position);
|
|
||||||
Task<IEnumerable<ChildRequests>> GetAllChldren(int tvId);
|
Task<IEnumerable<ChildRequests>> GetAllChldren(int tvId);
|
||||||
Task<ChildRequests> UpdateChildRequest(ChildRequests request);
|
Task<ChildRequests> UpdateChildRequest(ChildRequests request);
|
||||||
Task RemoveTvChild(int requestId);
|
Task RemoveTvChild(int requestId);
|
||||||
Task<RequestEngineResult> ApproveChildRequest(int id);
|
Task<RequestEngineResult> ApproveChildRequest(int id);
|
||||||
Task<IEnumerable<TvRequests>> GetRequestsLite();
|
Task<IEnumerable<TvRequests>> GetRequestsLite();
|
||||||
|
Task UpdateQualityProfile(int requestId, int profileId);
|
||||||
|
Task UpdateRootPath(int requestId, int rootPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,16 +7,10 @@ namespace Ombi.Core.Engine.Interfaces
|
||||||
public interface ITvSearchEngine
|
public interface ITvSearchEngine
|
||||||
{
|
{
|
||||||
Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm);
|
Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm);
|
||||||
Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> SearchTreeNode(string searchTerm);
|
|
||||||
Task<TreeNode<SearchTvShowViewModel>> GetShowInformationTreeNode(int tvdbid);
|
|
||||||
Task<SearchTvShowViewModel> GetShowInformation(int tvdbid);
|
Task<SearchTvShowViewModel> GetShowInformation(int tvdbid);
|
||||||
Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> PopularTree();
|
|
||||||
Task<IEnumerable<SearchTvShowViewModel>> Popular();
|
Task<IEnumerable<SearchTvShowViewModel>> Popular();
|
||||||
Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> AnticipatedTree();
|
|
||||||
Task<IEnumerable<SearchTvShowViewModel>> Anticipated();
|
Task<IEnumerable<SearchTvShowViewModel>> Anticipated();
|
||||||
Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> MostWatchesTree();
|
|
||||||
Task<IEnumerable<SearchTvShowViewModel>> MostWatches();
|
Task<IEnumerable<SearchTvShowViewModel>> MostWatches();
|
||||||
Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> TrendingTree();
|
|
||||||
Task<IEnumerable<SearchTvShowViewModel>> Trending();
|
Task<IEnumerable<SearchTvShowViewModel>> Trending();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -452,6 +452,7 @@ namespace Ombi.Core.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Available = true;
|
request.Available = true;
|
||||||
|
request.MarkedAsAvailable = DateTime.Now;
|
||||||
NotificationHelper.Notify(request, NotificationType.RequestAvailable);
|
NotificationHelper.Notify(request, NotificationType.RequestAvailable);
|
||||||
await MovieRepository.Update(request);
|
await MovieRepository.Update(request);
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Engine
|
|
||||||
{
|
|
||||||
|
|
||||||
public class TreeNode<T>
|
|
||||||
{
|
|
||||||
public string Label { get; set; }
|
|
||||||
public T Data { get; set; }
|
|
||||||
public List<TreeNode<T>> Children { get; set; }
|
|
||||||
public bool Leaf { get; set; }
|
|
||||||
public bool Expanded { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TreeNode<T,U>
|
|
||||||
{
|
|
||||||
public string Label { get; set; }
|
|
||||||
public T Data { get; set; }
|
|
||||||
public List<TreeNode<U>> Children { get; set; }
|
|
||||||
public bool Leaf { get; set; }
|
|
||||||
public bool Expanded { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -143,7 +143,7 @@ namespace Ombi.Core.Engine
|
||||||
.Include(x => x.ChildRequests)
|
.Include(x => x.ChildRequests)
|
||||||
.ThenInclude(x => x.SeasonRequests)
|
.ThenInclude(x => x.SeasonRequests)
|
||||||
.ThenInclude(x => x.Episodes)
|
.ThenInclude(x => x.Episodes)
|
||||||
.OrderByDescending(x => x.ChildRequests.Max(y => y.RequestedDate))
|
.OrderByDescending(x => x.ChildRequests.Select(y => y.RequestedDate).FirstOrDefault())
|
||||||
.Skip(position).Take(count).ToListAsync();
|
.Skip(position).Take(count).ToListAsync();
|
||||||
|
|
||||||
// Filter out children
|
// Filter out children
|
||||||
|
@ -156,8 +156,9 @@ namespace Ombi.Core.Engine
|
||||||
.Include(x => x.ChildRequests)
|
.Include(x => x.ChildRequests)
|
||||||
.ThenInclude(x => x.SeasonRequests)
|
.ThenInclude(x => x.SeasonRequests)
|
||||||
.ThenInclude(x => x.Episodes)
|
.ThenInclude(x => x.Episodes)
|
||||||
.OrderByDescending(x => x.ChildRequests.Max(y => y.RequestedDate))
|
.OrderByDescending(x => x.ChildRequests.Select(y => y.RequestedDate).FirstOrDefault())
|
||||||
.Skip(position).Take(count).ToListAsync();
|
.Skip(position).Take(count).ToListAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
|
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
|
||||||
|
@ -171,24 +172,30 @@ namespace Ombi.Core.Engine
|
||||||
public async Task<RequestsViewModel<TvRequests>> GetRequestsLite(int count, int position, OrderFilterModel type)
|
public async Task<RequestsViewModel<TvRequests>> GetRequestsLite(int count, int position, OrderFilterModel type)
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var shouldHide = await HideFromOtherUsers();
|
||||||
List<TvRequests> allRequests;
|
List<TvRequests> allRequests = null;
|
||||||
if (shouldHide.Hide)
|
if (shouldHide.Hide)
|
||||||
{
|
{
|
||||||
allRequests = await TvRepository.GetLite(shouldHide.UserId)
|
var tv = TvRepository.GetLite(shouldHide.UserId);
|
||||||
.OrderByDescending(x => x.ChildRequests.Max(y => y.RequestedDate))
|
if (tv.Any() && tv.Select(x => x.ChildRequests).Any())
|
||||||
.Skip(position).Take(count).ToListAsync();
|
{
|
||||||
|
allRequests = await tv.OrderByDescending(x => x.ChildRequests.Select(y => y.RequestedDate).FirstOrDefault()).Skip(position).Take(count).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
// Filter out children
|
// Filter out children
|
||||||
|
|
||||||
FilterChildren(allRequests, shouldHide);
|
FilterChildren(allRequests, shouldHide);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
allRequests = await TvRepository.GetLite()
|
var tv = TvRepository.GetLite();
|
||||||
.OrderByDescending(x => x.ChildRequests.Max(y => y.RequestedDate))
|
if (tv.Any() && tv.Select(x => x.ChildRequests).Any())
|
||||||
.Skip(position).Take(count).ToListAsync();
|
{
|
||||||
|
allRequests = await tv.OrderByDescending(x => x.ChildRequests.Select(y => y.RequestedDate).FirstOrDefault()).Skip(position).Take(count).ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allRequests == null)
|
||||||
|
{
|
||||||
|
return new RequestsViewModel<TvRequests>();
|
||||||
}
|
}
|
||||||
|
|
||||||
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
|
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
|
||||||
|
|
||||||
return new RequestsViewModel<TvRequests>
|
return new RequestsViewModel<TvRequests>
|
||||||
|
@ -196,38 +203,6 @@ namespace Ombi.Core.Engine
|
||||||
Collection = allRequests
|
Collection = allRequests
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TreeNode<TvRequests, List<ChildRequests>>>> GetRequestsTreeNode(int count, int position)
|
|
||||||
{
|
|
||||||
var shouldHide = await HideFromOtherUsers();
|
|
||||||
List<TvRequests> allRequests;
|
|
||||||
if (shouldHide.Hide)
|
|
||||||
{
|
|
||||||
allRequests = await TvRepository.Get(shouldHide.UserId)
|
|
||||||
.Include(x => x.ChildRequests)
|
|
||||||
.ThenInclude(x => x.SeasonRequests)
|
|
||||||
.ThenInclude(x => x.Episodes)
|
|
||||||
.Where(x => x.ChildRequests.Any())
|
|
||||||
.OrderByDescending(x => x.ChildRequests.Max(y => y.RequestedDate))
|
|
||||||
.Skip(position).Take(count).ToListAsync();
|
|
||||||
|
|
||||||
FilterChildren(allRequests, shouldHide);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
allRequests = await TvRepository.Get()
|
|
||||||
.Include(x => x.ChildRequests)
|
|
||||||
.ThenInclude(x => x.SeasonRequests)
|
|
||||||
.ThenInclude(x => x.Episodes)
|
|
||||||
.Where(x => x.ChildRequests.Any())
|
|
||||||
.OrderByDescending(x => x.ChildRequests.Max(y => y.RequestedDate))
|
|
||||||
.Skip(position).Take(count).ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
|
|
||||||
return ParseIntoTreeNode(allRequests);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<TvRequests>> GetRequests()
|
public async Task<IEnumerable<TvRequests>> GetRequests()
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var shouldHide = await HideFromOtherUsers();
|
||||||
|
@ -288,6 +263,10 @@ namespace Ombi.Core.Engine
|
||||||
|
|
||||||
private static void FilterChildren(IEnumerable<TvRequests> allRequests, HideResult shouldHide)
|
private static void FilterChildren(IEnumerable<TvRequests> allRequests, HideResult shouldHide)
|
||||||
{
|
{
|
||||||
|
if (allRequests == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Filter out children
|
// Filter out children
|
||||||
foreach (var t in allRequests)
|
foreach (var t in allRequests)
|
||||||
{
|
{
|
||||||
|
@ -350,21 +329,22 @@ namespace Ombi.Core.Engine
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TreeNode<TvRequests, List<ChildRequests>>>> SearchTvRequestTree(string search)
|
public async Task UpdateRootPath(int requestId, int rootPath)
|
||||||
{
|
{
|
||||||
var shouldHide = await HideFromOtherUsers();
|
var allRequests = TvRepository.Get();
|
||||||
IQueryable<TvRequests> allRequests;
|
var results = await allRequests.FirstOrDefaultAsync(x => x.Id == requestId);
|
||||||
if (shouldHide.Hide)
|
results.RootFolder = rootPath;
|
||||||
{
|
|
||||||
allRequests = TvRepository.Get(shouldHide.UserId);
|
await TvRepository.Update(results);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
public async Task UpdateQualityProfile(int requestId, int profileId)
|
||||||
allRequests = TvRepository.Get();
|
{
|
||||||
}
|
var allRequests = TvRepository.Get();
|
||||||
var results = await allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToListAsync();
|
var results = await allRequests.FirstOrDefaultAsync(x => x.Id == requestId);
|
||||||
results.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
|
results.QualityOverride = profileId;
|
||||||
return ParseIntoTreeNode(results);
|
|
||||||
|
await TvRepository.Update(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TvRequests> UpdateTvRequest(TvRequests request)
|
public async Task<TvRequests> UpdateTvRequest(TvRequests request)
|
||||||
|
@ -516,6 +496,7 @@ namespace Ombi.Core.Engine
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
request.Available = true;
|
request.Available = true;
|
||||||
|
request.MarkedAsAvailable = DateTime.Now;
|
||||||
foreach (var season in request.SeasonRequests)
|
foreach (var season in request.SeasonRequests)
|
||||||
{
|
{
|
||||||
foreach (var e in season.Episodes)
|
foreach (var e in season.Episodes)
|
||||||
|
@ -585,29 +566,7 @@ namespace Ombi.Core.Engine
|
||||||
return await AfterRequest(model.ChildRequests.FirstOrDefault());
|
return await AfterRequest(model.ChildRequests.FirstOrDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<TreeNode<TvRequests, List<ChildRequests>>> ParseIntoTreeNode(IEnumerable<TvRequests> result)
|
private static List<ChildRequests> SortEpisodes(List<ChildRequests> items)
|
||||||
{
|
|
||||||
var node = new List<TreeNode<TvRequests, List<ChildRequests>>>();
|
|
||||||
|
|
||||||
foreach (var value in result)
|
|
||||||
{
|
|
||||||
node.Add(new TreeNode<TvRequests, List<ChildRequests>>
|
|
||||||
{
|
|
||||||
Data = value,
|
|
||||||
Children = new List<TreeNode<List<ChildRequests>>>
|
|
||||||
{
|
|
||||||
new TreeNode<List<ChildRequests>>
|
|
||||||
{
|
|
||||||
Data = SortEpisodes(value.ChildRequests),
|
|
||||||
Leaf = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<ChildRequests> SortEpisodes(List<ChildRequests> items)
|
|
||||||
{
|
{
|
||||||
foreach (var value in items)
|
foreach (var value in items)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,11 +59,6 @@ namespace Ombi.Core.Engine
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> SearchTreeNode(string searchTerm)
|
|
||||||
{
|
|
||||||
var result = await Search(searchTerm);
|
|
||||||
return result.Select(ParseIntoTreeNode).ToList();
|
|
||||||
}
|
|
||||||
public async Task<SearchTvShowViewModel> GetShowInformation(int tvdbid)
|
public async Task<SearchTvShowViewModel> GetShowInformation(int tvdbid)
|
||||||
{
|
{
|
||||||
var show = await TvMazeApi.ShowLookupByTheTvDbId(tvdbid);
|
var show = await TvMazeApi.ShowLookupByTheTvDbId(tvdbid);
|
||||||
|
@ -116,19 +111,6 @@ namespace Ombi.Core.Engine
|
||||||
return await ProcessResult(mapped);
|
return await ProcessResult(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TreeNode<SearchTvShowViewModel>> GetShowInformationTreeNode(int tvdbid)
|
|
||||||
{
|
|
||||||
var result = await GetShowInformation(tvdbid);
|
|
||||||
return ParseIntoTreeNode(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> PopularTree()
|
|
||||||
{
|
|
||||||
var result = await Cache.GetOrAdd(CacheKeys.PopularTv, async () => await TraktApi.GetPopularShows(), DateTime.Now.AddHours(12));
|
|
||||||
var processed = await ProcessResults(result);
|
|
||||||
return processed.Select(ParseIntoTreeNode).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> Popular()
|
public async Task<IEnumerable<SearchTvShowViewModel>> Popular()
|
||||||
{
|
{
|
||||||
var result = await Cache.GetOrAdd(CacheKeys.PopularTv, async () => await TraktApi.GetPopularShows(), DateTime.Now.AddHours(12));
|
var result = await Cache.GetOrAdd(CacheKeys.PopularTv, async () => await TraktApi.GetPopularShows(), DateTime.Now.AddHours(12));
|
||||||
|
@ -136,12 +118,6 @@ namespace Ombi.Core.Engine
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> AnticipatedTree()
|
|
||||||
{
|
|
||||||
var result = await Cache.GetOrAdd(CacheKeys.AnticipatedTv, async () => await TraktApi.GetAnticipatedShows(), DateTime.Now.AddHours(12));
|
|
||||||
var processed = await ProcessResults(result);
|
|
||||||
return processed.Select(ParseIntoTreeNode).ToList();
|
|
||||||
}
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> Anticipated()
|
public async Task<IEnumerable<SearchTvShowViewModel>> Anticipated()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -150,12 +126,6 @@ namespace Ombi.Core.Engine
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> MostWatchesTree()
|
|
||||||
{
|
|
||||||
var result = await Cache.GetOrAdd(CacheKeys.MostWatchesTv, async () => await TraktApi.GetMostWatchesShows(), DateTime.Now.AddHours(12));
|
|
||||||
var processed = await ProcessResults(result);
|
|
||||||
return processed.Select(ParseIntoTreeNode).ToList();
|
|
||||||
}
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatches()
|
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatches()
|
||||||
{
|
{
|
||||||
var result = await Cache.GetOrAdd(CacheKeys.MostWatchesTv, async () => await TraktApi.GetMostWatchesShows(), DateTime.Now.AddHours(12));
|
var result = await Cache.GetOrAdd(CacheKeys.MostWatchesTv, async () => await TraktApi.GetMostWatchesShows(), DateTime.Now.AddHours(12));
|
||||||
|
@ -163,13 +133,6 @@ namespace Ombi.Core.Engine
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TreeNode<SearchTvShowViewModel>>> TrendingTree()
|
|
||||||
{
|
|
||||||
var result = await Cache.GetOrAdd(CacheKeys.TrendingTv, async () => await TraktApi.GetTrendingShows(), DateTime.Now.AddHours(12));
|
|
||||||
var processed = await ProcessResults(result);
|
|
||||||
return processed.Select(ParseIntoTreeNode).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> Trending()
|
public async Task<IEnumerable<SearchTvShowViewModel>> Trending()
|
||||||
{
|
{
|
||||||
var result = await Cache.GetOrAdd(CacheKeys.TrendingTv, async () => await TraktApi.GetTrendingShows(), DateTime.Now.AddHours(12));
|
var result = await Cache.GetOrAdd(CacheKeys.TrendingTv, async () => await TraktApi.GetTrendingShows(), DateTime.Now.AddHours(12));
|
||||||
|
@ -177,22 +140,6 @@ namespace Ombi.Core.Engine
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TreeNode<SearchTvShowViewModel> ParseIntoTreeNode(SearchTvShowViewModel result)
|
|
||||||
{
|
|
||||||
return new TreeNode<SearchTvShowViewModel>
|
|
||||||
{
|
|
||||||
Data = result,
|
|
||||||
Children = new List<TreeNode<SearchTvShowViewModel>>
|
|
||||||
{
|
|
||||||
new TreeNode<SearchTvShowViewModel>
|
|
||||||
{
|
|
||||||
Data = result, Leaf = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Leaf = false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<IEnumerable<SearchTvShowViewModel>> ProcessResults<T>(IEnumerable<T> items)
|
private async Task<IEnumerable<SearchTvShowViewModel>> ProcessResults<T>(IEnumerable<T> items)
|
||||||
{
|
{
|
||||||
var retVal = new List<SearchTvShowViewModel>();
|
var retVal = new List<SearchTvShowViewModel>();
|
||||||
|
|
77
src/Ombi.Core/Engine/UserStatsEngine.cs
Normal file
77
src/Ombi.Core/Engine/UserStatsEngine.cs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Ombi.Core.Authentication;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
using Ombi.Store.Repository.Requests;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Engine
|
||||||
|
{
|
||||||
|
public class UserStatsEngine : IUserStatsEngine
|
||||||
|
{
|
||||||
|
public UserStatsEngine(OmbiUserManager um, IMovieRequestRepository movieRequest, ITvRequestRepository tvRequest)
|
||||||
|
{
|
||||||
|
_userManager = um;
|
||||||
|
_movieRequest = movieRequest;
|
||||||
|
_tvRequest = tvRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly OmbiUserManager _userManager;
|
||||||
|
private readonly IMovieRequestRepository _movieRequest;
|
||||||
|
private readonly ITvRequestRepository _tvRequest;
|
||||||
|
|
||||||
|
public async Task<UserStatsSummary> GetSummary(SummaryRequest request)
|
||||||
|
{
|
||||||
|
// get all movie requests
|
||||||
|
var movies = _movieRequest.GetWithUser();
|
||||||
|
var filteredMovies = movies.Where(x => x.RequestedDate >= request.From && x.RequestedDate <= request.To);
|
||||||
|
var tv = _tvRequest.GetLite();
|
||||||
|
var children = tv.SelectMany(x =>
|
||||||
|
x.ChildRequests.Where(c => c.RequestedDate >= request.From && c.RequestedDate <= request.To));
|
||||||
|
|
||||||
|
var moviesCount = filteredMovies.CountAsync();
|
||||||
|
var childrenCount = children.CountAsync();
|
||||||
|
var availableMovies =
|
||||||
|
movies.Select(x => x.MarkedAsAvailable >= request.From && x.MarkedAsAvailable <= request.To).CountAsync();
|
||||||
|
var availableChildren = tv.SelectMany(x =>
|
||||||
|
x.ChildRequests.Where(c => c.MarkedAsAvailable >= request.From && c.MarkedAsAvailable <= request.To)).CountAsync();
|
||||||
|
|
||||||
|
var userMovie = filteredMovies.GroupBy(x => x.RequestedUserId).OrderBy(x => x.Key).FirstOrDefaultAsync();
|
||||||
|
var userTv = children.GroupBy(x => x.RequestedUserId).OrderBy(x => x.Key).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
return new UserStatsSummary
|
||||||
|
{
|
||||||
|
TotalMovieRequests = await moviesCount,
|
||||||
|
TotalTvRequests = await childrenCount,
|
||||||
|
CompletedRequestsTv = await availableChildren,
|
||||||
|
CompletedRequestsMovies = await availableMovies,
|
||||||
|
MostRequestedUserMovie = (await userMovie).FirstOrDefault().RequestedUser,
|
||||||
|
MostRequestedUserTv = (await userTv).FirstOrDefault().RequestedUser,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SummaryRequest
|
||||||
|
{
|
||||||
|
public DateTime From { get; set; }
|
||||||
|
public DateTime To { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatsSummary
|
||||||
|
{
|
||||||
|
public int TotalRequests => TotalTvRequests + TotalMovieRequests;
|
||||||
|
public int TotalMovieRequests { get; set; }
|
||||||
|
public int TotalTvRequests { get; set; }
|
||||||
|
public int TotalIssues { get; set; }
|
||||||
|
public int CompletedRequestsMovies { get; set; }
|
||||||
|
public int CompletedRequestsTv { get; set; }
|
||||||
|
public int CompletedRequests => CompletedRequestsMovies + CompletedRequestsTv;
|
||||||
|
public OmbiUser MostRequestedUserMovie { get; set; }
|
||||||
|
public OmbiUser MostRequestedUserTv { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ombi.Api.Plex.Models;
|
using Ombi.Api.Plex.Models;
|
||||||
using Ombi.Api.Plex.Models.OAuth;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Authentication
|
namespace Ombi.Core.Authentication
|
||||||
{
|
{
|
||||||
public interface IPlexOAuthManager
|
public interface IPlexOAuthManager
|
||||||
{
|
{
|
||||||
Task<string> GetAccessTokenFromPin(int pinId);
|
Task<string> GetAccessTokenFromPin(int pinId);
|
||||||
Task<OAuthPin> RequestPin();
|
|
||||||
Task<Uri> GetOAuthUrl(int pinId, string code, string websiteAddress = null);
|
Task<Uri> GetOAuthUrl(int pinId, string code, string websiteAddress = null);
|
||||||
Uri GetWizardOAuthUrl(int pinId, string code, string websiteAddress);
|
Task<Uri> GetWizardOAuthUrl(int pinId, string code, string websiteAddress);
|
||||||
Task<PlexAccount> GetAccount(string accessToken);
|
Task<PlexAccount> GetAccount(string accessToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,9 +12,9 @@
|
||||||
<PackageReference Include="AutoMapper" Version="6.1.1" />
|
<PackageReference Include="AutoMapper" Version="6.1.1" />
|
||||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="3.2.0" />
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="3.2.0" />
|
||||||
<PackageReference Include="Hangfire" Version="1.6.19" />
|
<PackageReference Include="Hangfire" Version="1.6.19" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.5" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="2.0.0-preview1-final" />
|
||||||
<PackageReference Include="MiniProfiler.AspNetCore" Version="4.0.0-alpha6-79" />
|
<PackageReference Include="MiniProfiler.AspNetCore" Version="4.0.0-alpha6-79" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
|
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Linq;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Ombi.Core.Models.Search;
|
using Ombi.Core.Models.Search;
|
||||||
|
@ -59,10 +61,19 @@ namespace Ombi.Core.Rule.Rules.Search
|
||||||
{
|
{
|
||||||
EmbyEpisode epExists = null;
|
EmbyEpisode epExists = null;
|
||||||
|
|
||||||
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
|
if (item.HasImdb)
|
||||||
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
|
{
|
||||||
x.Series.ProviderId == item.ProviderId.ToString());
|
epExists = await allEpisodes.FirstOrDefaultAsync(e => e.EpisodeNumber == episode.EpisodeNumber && e.SeasonNumber == season.SeasonNumber
|
||||||
|
&& e.ImdbId == item.ImdbId);
|
||||||
|
} if (item.HasTvDb && epExists == null)
|
||||||
|
{
|
||||||
|
epExists = await allEpisodes.FirstOrDefaultAsync(e => e.EpisodeNumber == episode.EpisodeNumber && e.SeasonNumber == season.SeasonNumber
|
||||||
|
&& e.Series.TvDbId == item.TvDbId);
|
||||||
|
} if (item.HasTheMovieDb && epExists == null)
|
||||||
|
{
|
||||||
|
epExists = await allEpisodes.FirstOrDefaultAsync(e => e.EpisodeNumber == episode.EpisodeNumber && e.SeasonNumber == season.SeasonNumber
|
||||||
|
&& e.TheMovieDbId == item.TheMovieDbId);
|
||||||
|
}
|
||||||
|
|
||||||
if (epExists != null)
|
if (epExists != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,6 +120,7 @@ namespace Ombi.Core.Senders
|
||||||
|
|
||||||
int qualityToUse;
|
int qualityToUse;
|
||||||
string rootFolderPath;
|
string rootFolderPath;
|
||||||
|
string seriesType;
|
||||||
|
|
||||||
if (model.SeriesType == SeriesType.Anime)
|
if (model.SeriesType == SeriesType.Anime)
|
||||||
{
|
{
|
||||||
|
@ -128,6 +129,8 @@ namespace Ombi.Core.Senders
|
||||||
// TODO make this overrideable via the UI
|
// TODO make this overrideable via the UI
|
||||||
rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPathAnime), s);
|
rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPathAnime), s);
|
||||||
int.TryParse(s.QualityProfileAnime, out qualityToUse);
|
int.TryParse(s.QualityProfileAnime, out qualityToUse);
|
||||||
|
seriesType = "anime";
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -136,6 +139,7 @@ namespace Ombi.Core.Senders
|
||||||
// For some reason, if we haven't got one use the first root folder in Sonarr
|
// For some reason, if we haven't got one use the first root folder in Sonarr
|
||||||
// TODO make this overrideable via the UI
|
// TODO make this overrideable via the UI
|
||||||
rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s);
|
rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s);
|
||||||
|
seriesType = "standard";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.ParentRequest.QualityOverride.HasValue)
|
if (model.ParentRequest.QualityOverride.HasValue)
|
||||||
|
@ -163,27 +167,18 @@ namespace Ombi.Core.Senders
|
||||||
rootFolderPath = rootFolderPath,
|
rootFolderPath = rootFolderPath,
|
||||||
qualityProfileId = qualityToUse,
|
qualityProfileId = qualityToUse,
|
||||||
titleSlug = model.ParentRequest.Title,
|
titleSlug = model.ParentRequest.Title,
|
||||||
|
seriesType = seriesType,
|
||||||
addOptions = new AddOptions
|
addOptions = new AddOptions
|
||||||
{
|
{
|
||||||
ignoreEpisodesWithFiles = true, // There shouldn't be any episodes with files, this is a new season
|
ignoreEpisodesWithFiles = false, // There shouldn't be any episodes with files, this is a new season
|
||||||
ignoreEpisodesWithoutFiles = true, // We want all missing
|
ignoreEpisodesWithoutFiles = false, // We want all missing
|
||||||
searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly.
|
searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Montitor the correct seasons,
|
// Montitor the correct seasons,
|
||||||
// If we have that season in the model then it's monitored!
|
// If we have that season in the model then it's monitored!
|
||||||
var seasonsToAdd = new List<Season>();
|
var seasonsToAdd = GetSeasonsToCreate(model);
|
||||||
for (var i = 0; i < model.ParentRequest.TotalSeasons + 1; i++)
|
|
||||||
{
|
|
||||||
var index = i;
|
|
||||||
var season = new Season
|
|
||||||
{
|
|
||||||
seasonNumber = i,
|
|
||||||
monitored = model.SeasonRequests.Any(x => x.SeasonNumber == index && x.SeasonNumber != 0)
|
|
||||||
};
|
|
||||||
seasonsToAdd.Add(season);
|
|
||||||
}
|
|
||||||
newSeries.seasons = seasonsToAdd;
|
newSeries.seasons = seasonsToAdd;
|
||||||
var result = await SonarrApi.AddSeries(newSeries, s.ApiKey, s.FullUri);
|
var result = await SonarrApi.AddSeries(newSeries, s.ApiKey, s.FullUri);
|
||||||
existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri);
|
existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri);
|
||||||
|
@ -237,7 +232,7 @@ namespace Ombi.Core.Senders
|
||||||
{
|
{
|
||||||
var sonarrEp = sonarrEpList.FirstOrDefault(x =>
|
var sonarrEp = sonarrEpList.FirstOrDefault(x =>
|
||||||
x.episodeNumber == ep.EpisodeNumber && x.seasonNumber == req.SeasonNumber);
|
x.episodeNumber == ep.EpisodeNumber && x.seasonNumber == req.SeasonNumber);
|
||||||
if (sonarrEp != null)
|
if (sonarrEp != null && !sonarrEp.monitored)
|
||||||
{
|
{
|
||||||
sonarrEp.monitored = true;
|
sonarrEp.monitored = true;
|
||||||
episodesToUpdate.Add(sonarrEp);
|
episodesToUpdate.Add(sonarrEp);
|
||||||
|
@ -245,22 +240,64 @@ namespace Ombi.Core.Senders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var seriesChanges = false;
|
var seriesChanges = false;
|
||||||
|
|
||||||
foreach (var season in model.SeasonRequests)
|
foreach (var season in model.SeasonRequests)
|
||||||
{
|
{
|
||||||
var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber);
|
var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber);
|
||||||
var sonarrEpCount = sonarrSeason.Count();
|
var sonarrEpCount = sonarrSeason.Count();
|
||||||
var ourRequestCount = season.Episodes.Count;
|
var ourRequestCount = season.Episodes.Count;
|
||||||
|
|
||||||
|
var existingSeason =
|
||||||
|
result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber);
|
||||||
|
if (existingSeason == null)
|
||||||
|
{
|
||||||
|
Logger.LogError("There was no season numer {0} in Sonarr for title {1}", season.SeasonNumber, model.ParentRequest.Title);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (sonarrEpCount == ourRequestCount)
|
if (sonarrEpCount == ourRequestCount)
|
||||||
{
|
{
|
||||||
// We have the same amount of requests as all of the episodes in the season.
|
// We have the same amount of requests as all of the episodes in the season.
|
||||||
var existingSeason =
|
|
||||||
result.seasons.First(x => x.seasonNumber == season.SeasonNumber);
|
if (!existingSeason.monitored)
|
||||||
existingSeason.monitored = true;
|
{
|
||||||
seriesChanges = true;
|
existingSeason.monitored = true;
|
||||||
|
seriesChanges = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Make sure this season is set to monitored
|
||||||
|
if (!existingSeason.monitored)
|
||||||
|
{
|
||||||
|
// We need to monitor it, problem being is all episodes will now be monitored
|
||||||
|
// So we need to monior the series but unmonitor every episode
|
||||||
|
// Except the episodes that are already monitored before we update the series (we do not want to unmonitor episodes that are monitored beforehand)
|
||||||
|
existingSeason.monitored = true;
|
||||||
|
var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber);
|
||||||
|
sea.monitored = true;
|
||||||
|
//var previouslyMonitoredEpisodes = sonarrEpList.Where(x =>
|
||||||
|
// x.seasonNumber == existingSeason.seasonNumber && x.monitored).Select(x => x.episodeNumber).ToList(); // We probably don't actually care about this
|
||||||
|
result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||||
|
var epToUnmonitor = new List<Episode>();
|
||||||
|
var newEpList = sonarrEpList.ConvertAll(ep => new Episode(ep)); // Clone it so we don't modify the orignal member
|
||||||
|
foreach (var ep in newEpList.Where(x => x.seasonNumber == existingSeason.seasonNumber).ToList())
|
||||||
|
{
|
||||||
|
//if (previouslyMonitoredEpisodes.Contains(ep.episodeNumber))
|
||||||
|
//{
|
||||||
|
// // This was previously monitored.
|
||||||
|
// continue;
|
||||||
|
//}
|
||||||
|
ep.monitored = false;
|
||||||
|
epToUnmonitor.Add(ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var epToUpdate in epToUnmonitor)
|
||||||
|
{
|
||||||
|
await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Now update the episodes that need updating
|
// Now update the episodes that need updating
|
||||||
foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber))
|
foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber))
|
||||||
{
|
{
|
||||||
|
@ -280,6 +317,24 @@ namespace Ombi.Core.Senders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<Season> GetSeasonsToCreate(ChildRequests model)
|
||||||
|
{
|
||||||
|
// Let's get a list of seasons just incase we need to change it
|
||||||
|
var seasonsToUpdate = new List<Season>();
|
||||||
|
for (var i = 0; i < model.ParentRequest.TotalSeasons + 1; i++)
|
||||||
|
{
|
||||||
|
var index = i;
|
||||||
|
var sea = new Season
|
||||||
|
{
|
||||||
|
seasonNumber = i,
|
||||||
|
monitored = model.SeasonRequests.Any(x => x.SeasonNumber == index && x.SeasonNumber != 0)
|
||||||
|
};
|
||||||
|
seasonsToUpdate.Add(sea);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seasonsToUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> SendToSickRage(ChildRequests model, SickRageSettings settings, string qualityId = null)
|
private async Task<bool> SendToSickRage(ChildRequests model, SickRageSettings settings, string qualityId = null)
|
||||||
{
|
{
|
||||||
var tvdbid = model.ParentRequest.TvDbId;
|
var tvdbid = model.ParentRequest.TvDbId;
|
||||||
|
|
|
@ -79,6 +79,7 @@ namespace Ombi.DependencyInjection
|
||||||
services.AddTransient<ITvRequestEngine, TvRequestEngine>();
|
services.AddTransient<ITvRequestEngine, TvRequestEngine>();
|
||||||
services.AddTransient<ITvSearchEngine, TvSearchEngine>();
|
services.AddTransient<ITvSearchEngine, TvSearchEngine>();
|
||||||
services.AddTransient<IRuleEvaluator, RuleEvaluator>();
|
services.AddTransient<IRuleEvaluator, RuleEvaluator>();
|
||||||
|
services.AddTransient<IUserStatsEngine, UserStatsEngine>();
|
||||||
services.AddTransient<IMovieSender, MovieSender>();
|
services.AddTransient<IMovieSender, MovieSender>();
|
||||||
services.AddTransient<IRecentlyAddedEngine, RecentlyAddedEngine>();
|
services.AddTransient<IRecentlyAddedEngine, RecentlyAddedEngine>();
|
||||||
services.AddTransient<ITvSender, TvSender>();
|
services.AddTransient<ITvSender, TvSender>();
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="2.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Ombi.Helpers
|
||||||
public static string GetEmbyMediaUrl(string mediaId)
|
public static string GetEmbyMediaUrl(string mediaId)
|
||||||
{
|
{
|
||||||
var url =
|
var url =
|
||||||
$"http://app.emby.media/itemdetails.html?id={mediaId}";
|
$"http://app.emby.media/#!/itemdetails.html?id={mediaId}";
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EasyCrypto" Version="3.3.2" />
|
<PackageReference Include="EasyCrypto" Version="3.3.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="Nito.AsyncEx" Version="5.0.0-pre-05" />
|
<PackageReference Include="Nito.AsyncEx" Version="5.0.0-pre-05" />
|
||||||
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
||||||
|
|
|
@ -182,14 +182,16 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{@RECENTLYADDED}
|
{@RECENTLYADDED}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<!-- END MAIN CONTENT AREA -->
|
<!-- END MAIN CONTENT AREA -->
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<!-- START FOOTER -->
|
<!-- START FOOTER -->
|
||||||
<div class="footer" style="clear: both; padding-top: 10px; text-align: center; width: 100%;">
|
<div class="footer" style="clear: both; padding-top: 10px; text-align: center; width: 100%;">
|
||||||
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
|
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-top: 10px; padding-bottom: 10px; font-size: 12px; color: #999999; text-align: center;" valign="top" align="center">
|
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-top: 10px; padding-bottom: 10px; font-size: 12px; color: #999999; text-align: center;" valign="top" align="center">
|
||||||
Powered by <a href="https://github.com/tidusjar/Ombi" style="color: #999999; font-size: 12px; text-align: center; text-decoration: underline;">Ombi</a>
|
Powered by <a href="https://github.com/tidusjar/Ombi" style="color: #999999; font-size: 12px; text-align: center; text-decoration: underline;">Ombi</a>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Nunit" Version="3.8.1" />
|
<PackageReference Include="Nunit" Version="3.8.1" />
|
||||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
|
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
|
||||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.7.2"></packagereference>
|
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.8.0"></packagereference>
|
||||||
<PackageReference Include="Moq" Version="4.7.99" />
|
<PackageReference Include="Moq" Version="4.7.99" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Ombi.Notifications.Agents
|
||||||
|
|
||||||
// Get admin devices
|
// Get admin devices
|
||||||
var playerIds = await GetAdmins(NotificationType.NewRequest);
|
var playerIds = await GetAdmins(NotificationType.NewRequest);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task NewIssue(NotificationOptions model, MobileNotificationSettings settings)
|
protected override async Task NewIssue(NotificationOptions model, MobileNotificationSettings settings)
|
||||||
|
@ -75,7 +75,7 @@ namespace Ombi.Notifications.Agents
|
||||||
|
|
||||||
// Get admin devices
|
// Get admin devices
|
||||||
var playerIds = await GetAdmins(NotificationType.Issue);
|
var playerIds = await GetAdmins(NotificationType.Issue);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task IssueComment(NotificationOptions model, MobileNotificationSettings settings)
|
protected override async Task IssueComment(NotificationOptions model, MobileNotificationSettings settings)
|
||||||
|
@ -97,13 +97,13 @@ namespace Ombi.Notifications.Agents
|
||||||
{
|
{
|
||||||
// Send to user
|
// Send to user
|
||||||
var playerIds = GetUsers(model, NotificationType.IssueComment);
|
var playerIds = GetUsers(model, NotificationType.IssueComment);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Send to admin
|
// Send to admin
|
||||||
var playerIds = await GetAdmins(NotificationType.IssueComment);
|
var playerIds = await GetAdmins(NotificationType.IssueComment);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ namespace Ombi.Notifications.Agents
|
||||||
// Send to user
|
// Send to user
|
||||||
var playerIds = GetUsers(model, NotificationType.IssueResolved);
|
var playerIds = GetUsers(model, NotificationType.IssueResolved);
|
||||||
|
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ namespace Ombi.Notifications.Agents
|
||||||
};
|
};
|
||||||
// Get admin devices
|
// Get admin devices
|
||||||
var playerIds = await GetAdmins(NotificationType.Test);
|
var playerIds = await GetAdmins(NotificationType.Test);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task RequestDeclined(NotificationOptions model, MobileNotificationSettings settings)
|
protected override async Task RequestDeclined(NotificationOptions model, MobileNotificationSettings settings)
|
||||||
|
@ -168,7 +168,7 @@ namespace Ombi.Notifications.Agents
|
||||||
// Send to user
|
// Send to user
|
||||||
var playerIds = GetUsers(model, NotificationType.RequestDeclined);
|
var playerIds = GetUsers(model, NotificationType.RequestDeclined);
|
||||||
await AddSubscribedUsers(playerIds);
|
await AddSubscribedUsers(playerIds);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task RequestApproved(NotificationOptions model, MobileNotificationSettings settings)
|
protected override async Task RequestApproved(NotificationOptions model, MobileNotificationSettings settings)
|
||||||
|
@ -188,7 +188,7 @@ namespace Ombi.Notifications.Agents
|
||||||
var playerIds = GetUsers(model, NotificationType.RequestApproved);
|
var playerIds = GetUsers(model, NotificationType.RequestApproved);
|
||||||
|
|
||||||
await AddSubscribedUsers(playerIds);
|
await AddSubscribedUsers(playerIds);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task AvailableRequest(NotificationOptions model, MobileNotificationSettings settings)
|
protected override async Task AvailableRequest(NotificationOptions model, MobileNotificationSettings settings)
|
||||||
|
@ -207,20 +207,20 @@ namespace Ombi.Notifications.Agents
|
||||||
var playerIds = GetUsers(model, NotificationType.RequestAvailable);
|
var playerIds = GetUsers(model, NotificationType.RequestAvailable);
|
||||||
|
|
||||||
await AddSubscribedUsers(playerIds);
|
await AddSubscribedUsers(playerIds);
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
protected override Task Send(NotificationMessage model, MobileNotificationSettings settings)
|
protected override Task Send(NotificationMessage model, MobileNotificationSettings settings)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task Send(List<string> playerIds, NotificationMessage model, MobileNotificationSettings settings)
|
protected async Task Send(List<string> playerIds, NotificationMessage model, MobileNotificationSettings settings, NotificationOptions requestModel, bool isAdminNotification = false)
|
||||||
{
|
{
|
||||||
if (playerIds == null || !playerIds.Any())
|
if (playerIds == null || !playerIds.Any())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var response = await _api.PushNotification(playerIds, model.Message);
|
var response = await _api.PushNotification(playerIds, model.Message, isAdminNotification, requestModel.RequestId, (int)requestModel.RequestType);
|
||||||
_logger.LogDebug("Sent message to {0} recipients with message id {1}", response.recipients, response.id);
|
_logger.LogDebug("Sent message to {0} recipients with message id {1}", response.recipients, response.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ namespace Ombi.Notifications.Agents
|
||||||
}
|
}
|
||||||
|
|
||||||
var playerIds = user.NotificationUserIds.Select(x => x.PlayerId).ToList();
|
var playerIds = user.NotificationUserIds.Select(x => x.PlayerId).ToList();
|
||||||
await Send(playerIds, notification, settings);
|
await Send(playerIds, notification, settings, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<List<string>> GetAdmins(NotificationType type)
|
private async Task<List<string>> GetAdmins(NotificationType type)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Humanizer;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Notifications.Models;
|
using Ombi.Notifications.Models;
|
||||||
using Ombi.Settings.Settings.Models;
|
using Ombi.Settings.Settings.Models;
|
||||||
|
@ -39,7 +40,7 @@ namespace Ombi.Notifications
|
||||||
RequestedDate = req?.RequestedDate.ToString("D");
|
RequestedDate = req?.RequestedDate.ToString("D");
|
||||||
if (Type.IsNullOrEmpty())
|
if (Type.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
Type = req?.RequestType.ToString();
|
Type = req?.RequestType.Humanize();
|
||||||
}
|
}
|
||||||
Overview = req?.Overview;
|
Overview = req?.Overview;
|
||||||
Year = req?.ReleaseDate.Year.ToString();
|
Year = req?.ReleaseDate.Year.ToString();
|
||||||
|
@ -91,7 +92,7 @@ namespace Ombi.Notifications
|
||||||
RequestedDate = req?.RequestedDate.ToString("D");
|
RequestedDate = req?.RequestedDate.ToString("D");
|
||||||
if (Type.IsNullOrEmpty())
|
if (Type.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
Type = req?.RequestType.ToString();
|
Type = req?.RequestType.Humanize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Overview = req?.ParentRequest.Overview;
|
Overview = req?.ParentRequest.Overview;
|
||||||
|
@ -161,7 +162,7 @@ namespace Ombi.Notifications
|
||||||
IssueSubject = opts.Substitutes.TryGetValue("IssueSubject", out val) ? val : string.Empty;
|
IssueSubject = opts.Substitutes.TryGetValue("IssueSubject", out val) ? val : string.Empty;
|
||||||
NewIssueComment = opts.Substitutes.TryGetValue("NewIssueComment", out val) ? val : string.Empty;
|
NewIssueComment = opts.Substitutes.TryGetValue("NewIssueComment", out val) ? val : string.Empty;
|
||||||
UserName = opts.Substitutes.TryGetValue("IssueUser", out val) ? val : string.Empty;
|
UserName = opts.Substitutes.TryGetValue("IssueUser", out val) ? val : string.Empty;
|
||||||
Type = opts.Substitutes.TryGetValue("RequestType", out val) ? val : string.Empty;
|
Type = opts.Substitutes.TryGetValue("RequestType", out val) ? val.Humanize() : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// User Defined
|
// User Defined
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Ensure.That" Version="7.0.0-pre32" />
|
<PackageReference Include="Ensure.That" Version="7.0.0-pre32" />
|
||||||
<PackageReference Include="MailKit" Version="2.0.3" />
|
<PackageReference Include="MailKit" Version="2.0.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.2" />
|
||||||
<PackageReference Include="Moq" Version="4.7.99" />
|
<PackageReference Include="Moq" Version="4.7.99" />
|
||||||
<PackageReference Include="Nunit" Version="3.10.1" />
|
<PackageReference Include="Nunit" Version="3.10.1" />
|
||||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.8.0" />
|
<PackageReference Include="NUnit.ConsoleRunner" Version="3.8.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.7.0"></packagereference>
|
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.8.0"></packagereference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -89,6 +89,7 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
_log.LogInformation("We have found the request {0} on Emby, sending the notification", movie?.Title ?? string.Empty);
|
_log.LogInformation("We have found the request {0} on Emby, sending the notification", movie?.Title ?? string.Empty);
|
||||||
|
|
||||||
movie.Available = true;
|
movie.Available = true;
|
||||||
|
movie.MarkedAsAvailable = DateTime.Now;
|
||||||
if (movie.Available)
|
if (movie.Available)
|
||||||
{
|
{
|
||||||
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
|
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
|
||||||
|
@ -121,24 +122,53 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
|
|
||||||
foreach (var child in tv)
|
foreach (var child in tv)
|
||||||
{
|
{
|
||||||
IQueryable<EmbyEpisode> seriesEpisodes;
|
|
||||||
if (child.ParentRequest.TvDbId > 0)
|
var useImdb = false;
|
||||||
|
var useTvDb = false;
|
||||||
|
if (child.ParentRequest.ImdbId.HasValue())
|
||||||
{
|
{
|
||||||
seriesEpisodes = embyEpisodes.Where(x => x.Series.TvDbId == child.ParentRequest.TvDbId.ToString());
|
useImdb = true;
|
||||||
}
|
}
|
||||||
else if(child.ParentRequest.ImdbId.HasValue())
|
|
||||||
|
if (child.ParentRequest.TvDbId.ToString().HasValue())
|
||||||
{
|
{
|
||||||
seriesEpisodes = embyEpisodes.Where(x => x.Series.ImdbId == child.ParentRequest.ImdbId);
|
useTvDb = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
var tvDbId = child.ParentRequest.TvDbId;
|
||||||
|
var imdbId = child.ParentRequest.ImdbId;
|
||||||
|
IQueryable<EmbyEpisode> seriesEpisodes = null;
|
||||||
|
if (useImdb)
|
||||||
|
{
|
||||||
|
seriesEpisodes = embyEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useTvDb && (seriesEpisodes == null || !seriesEpisodes.Any()))
|
||||||
|
{
|
||||||
|
seriesEpisodes = embyEpisodes.Where(x => x.Series.TvDbId == tvDbId.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seriesEpisodes == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!seriesEpisodes.Any())
|
||||||
|
{
|
||||||
|
// Let's try and match the series by name
|
||||||
|
seriesEpisodes = embyEpisodes.Where(x =>
|
||||||
|
x.Series.Title.Equals(child.Title, StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var season in child.SeasonRequests)
|
foreach (var season in child.SeasonRequests)
|
||||||
{
|
{
|
||||||
foreach (var episode in season.Episodes)
|
foreach (var episode in season.Episodes)
|
||||||
{
|
{
|
||||||
|
if (episode.Available)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var foundEp = await seriesEpisodes.FirstOrDefaultAsync(
|
var foundEp = await seriesEpisodes.FirstOrDefaultAsync(
|
||||||
x => x.EpisodeNumber == episode.EpisodeNumber &&
|
x => x.EpisodeNumber == episode.EpisodeNumber &&
|
||||||
x.SeasonNumber == episode.Season.SeasonNumber);
|
x.SeasonNumber == episode.Season.SeasonNumber);
|
||||||
|
@ -156,13 +186,14 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
{
|
{
|
||||||
// We have fulfulled this request!
|
// We have fulfulled this request!
|
||||||
child.Available = true;
|
child.Available = true;
|
||||||
|
child.MarkedAsAvailable = DateTime.Now;
|
||||||
BackgroundJob.Enqueue(() => _notificationService.Publish(new NotificationOptions
|
BackgroundJob.Enqueue(() => _notificationService.Publish(new NotificationOptions
|
||||||
{
|
{
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
NotificationType = NotificationType.RequestAvailable,
|
NotificationType = NotificationType.RequestAvailable,
|
||||||
RequestId = child.ParentRequestId,
|
RequestId = child.Id,
|
||||||
RequestType = RequestType.TvShow,
|
RequestType = RequestType.TvShow,
|
||||||
Recipient = child.RequestedUser.Email,
|
Recipient = child.RequestedUser.Email
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,40 +68,96 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
if (!ValidateSettings(server))
|
if (!ValidateSettings(server))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await _repo.ExecuteSql("DELETE FROM EmbyEpisode");
|
//await _repo.ExecuteSql("DELETE FROM EmbyEpisode");
|
||||||
await _repo.ExecuteSql("DELETE FROM EmbyContent");
|
//await _repo.ExecuteSql("DELETE FROM EmbyContent");
|
||||||
|
|
||||||
|
var movies = await _api.GetAllMovies(server.ApiKey, 0, 200, server.AdministratorId, server.FullUri);
|
||||||
|
var totalCount = movies.TotalRecordCount;
|
||||||
|
var processed = 1;
|
||||||
|
|
||||||
var movies = await _api.GetAllMovies(server.ApiKey, server.AdministratorId, server.FullUri);
|
|
||||||
var mediaToAdd = new HashSet<EmbyContent>();
|
var mediaToAdd = new HashSet<EmbyContent>();
|
||||||
foreach (var movie in movies.Items)
|
|
||||||
{
|
|
||||||
// Regular movie
|
|
||||||
await ProcessMovies(movie, mediaToAdd);
|
|
||||||
}
|
|
||||||
// TV Time
|
|
||||||
var tv = await _api.GetAllShows(server.ApiKey, server.AdministratorId, server.FullUri);
|
|
||||||
|
|
||||||
foreach (var tvShow in tv.Items)
|
while (processed < totalCount)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb))
|
foreach (var movie in movies.Items)
|
||||||
{
|
{
|
||||||
Log.Error("Provider Id on tv {0} is null", tvShow.Name);
|
if (movie.Type.Equals("boxset", StringComparison.InvariantCultureIgnoreCase))
|
||||||
continue;
|
{
|
||||||
|
var movieInfo =
|
||||||
|
await _api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri);
|
||||||
|
foreach (var item in movieInfo.Items)
|
||||||
|
{
|
||||||
|
await ProcessMovies(item, mediaToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
processed++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
processed++;
|
||||||
|
// Regular movie
|
||||||
|
await ProcessMovies(movie, mediaToAdd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingTv = await _repo.GetByEmbyId(tvShow.Id);
|
// Get the next batch
|
||||||
if (existingTv == null)
|
movies = await _api.GetAllMovies(server.ApiKey, processed, 200, server.AdministratorId, server.FullUri);
|
||||||
mediaToAdd.Add(new EmbyContent
|
await _repo.AddRange(mediaToAdd);
|
||||||
|
mediaToAdd.Clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TV Time
|
||||||
|
var tv = await _api.GetAllShows(server.ApiKey, 0, 200, server.AdministratorId, server.FullUri);
|
||||||
|
var totalTv = tv.TotalRecordCount;
|
||||||
|
processed = 1;
|
||||||
|
while (processed < totalTv)
|
||||||
|
{
|
||||||
|
foreach (var tvShow in tv.Items)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
TvDbId = tvShow.ProviderIds?.Tvdb,
|
|
||||||
ImdbId = tvShow.ProviderIds?.Imdb,
|
processed++;
|
||||||
TheMovieDbId = tvShow.ProviderIds?.Tmdb,
|
if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb))
|
||||||
Title = tvShow.Name,
|
{
|
||||||
Type = EmbyMediaType.Series,
|
_logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name);
|
||||||
EmbyId = tvShow.Id,
|
continue;
|
||||||
Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id),
|
}
|
||||||
AddedAt = DateTime.UtcNow
|
|
||||||
});
|
var existingTv = await _repo.GetByEmbyId(tvShow.Id);
|
||||||
|
if (existingTv == null)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Adding new TV Show {0}", tvShow.Name);
|
||||||
|
mediaToAdd.Add(new EmbyContent
|
||||||
|
{
|
||||||
|
TvDbId = tvShow.ProviderIds?.Tvdb,
|
||||||
|
ImdbId = tvShow.ProviderIds?.Imdb,
|
||||||
|
TheMovieDbId = tvShow.ProviderIds?.Tmdb,
|
||||||
|
Title = tvShow.Name,
|
||||||
|
Type = EmbyMediaType.Series,
|
||||||
|
EmbyId = tvShow.Id,
|
||||||
|
Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id),
|
||||||
|
AddedAt = DateTime.UtcNow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogDebug("We already have TV Show {0}", tvShow.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get the next batch
|
||||||
|
tv = await _api.GetAllShows(server.ApiKey, processed, 200, server.AdministratorId, server.FullUri);
|
||||||
|
await _repo.AddRange(mediaToAdd);
|
||||||
|
mediaToAdd.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaToAdd.Any())
|
if (mediaToAdd.Any())
|
||||||
|
@ -112,8 +168,10 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
{
|
{
|
||||||
// Check if it exists
|
// Check if it exists
|
||||||
var existingMovie = await _repo.GetByEmbyId(movieInfo.Id);
|
var existingMovie = await _repo.GetByEmbyId(movieInfo.Id);
|
||||||
|
var alreadyGoingToAdd = content.Any(x => x.EmbyId == movieInfo.Id);
|
||||||
if (existingMovie == null)
|
if (existingMovie == null && !alreadyGoingToAdd)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Adding new movie {0}", movieInfo.Name);
|
||||||
content.Add(new EmbyContent
|
content.Add(new EmbyContent
|
||||||
{
|
{
|
||||||
ImdbId = movieInfo.ProviderIds.Imdb,
|
ImdbId = movieInfo.ProviderIds.Imdb,
|
||||||
|
@ -124,6 +182,12 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id),
|
Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id),
|
||||||
AddedAt = DateTime.UtcNow,
|
AddedAt = DateTime.UtcNow,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we have this
|
||||||
|
_logger.LogDebug("We already have movie {0}", movieInfo.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateSettings(EmbyServers server)
|
private bool ValidateSettings(EmbyServers server)
|
||||||
|
|
|
@ -73,37 +73,51 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
|
|
||||||
private async Task CacheEpisodes(EmbyServers server)
|
private async Task CacheEpisodes(EmbyServers server)
|
||||||
{
|
{
|
||||||
var allEpisodes = await _api.GetAllEpisodes(server.ApiKey, server.AdministratorId, server.FullUri);
|
var allEpisodes = await _api.GetAllEpisodes(server.ApiKey, 0, 200, server.AdministratorId, server.FullUri);
|
||||||
var epToAdd = new List<EmbyEpisode>();
|
var total = allEpisodes.TotalRecordCount;
|
||||||
|
var processed = 1;
|
||||||
foreach (var ep in allEpisodes.Items)
|
var epToAdd = new HashSet<EmbyEpisode>();
|
||||||
|
while (processed < total)
|
||||||
{
|
{
|
||||||
// Let's make sure we have the parent request, stop those pesky forign key errors,
|
foreach (var ep in allEpisodes.Items)
|
||||||
// Damn me having data integrity
|
|
||||||
var parent = await _repo.GetByEmbyId(ep.SeriesId);
|
|
||||||
if (parent == null)
|
|
||||||
{
|
{
|
||||||
_logger.LogInformation("The episode {0} does not relate to a series, so we cannot save this", ep.Name);
|
processed++;
|
||||||
continue;
|
// Let's make sure we have the parent request, stop those pesky forign key errors,
|
||||||
|
// Damn me having data integrity
|
||||||
|
var parent = await _repo.GetByEmbyId(ep.SeriesId);
|
||||||
|
if (parent == null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("The episode {0} does not relate to a series, so we cannot save this",
|
||||||
|
ep.Name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingEpisode = await _repo.GetEpisodeByEmbyId(ep.Id);
|
||||||
|
// Make sure it's not in the hashset too
|
||||||
|
var existingInList = epToAdd.Any(x => x.EmbyId == ep.Id);
|
||||||
|
|
||||||
|
if (existingEpisode == null && !existingInList)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Adding new episode {0} to parent {1}", ep.Name, ep.SeriesName);
|
||||||
|
// add it
|
||||||
|
epToAdd.Add(new EmbyEpisode
|
||||||
|
{
|
||||||
|
EmbyId = ep.Id,
|
||||||
|
EpisodeNumber = ep.IndexNumber,
|
||||||
|
SeasonNumber = ep.ParentIndexNumber,
|
||||||
|
ParentId = ep.SeriesId,
|
||||||
|
TvDbId = ep.ProviderIds.Tvdb,
|
||||||
|
TheMovieDbId = ep.ProviderIds.Tmdb,
|
||||||
|
ImdbId = ep.ProviderIds.Imdb,
|
||||||
|
Title = ep.Name,
|
||||||
|
AddedAt = DateTime.UtcNow
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingEpisode = await _repo.GetEpisodeByEmbyId(ep.Id);
|
await _repo.AddRange(epToAdd);
|
||||||
if (existingEpisode == null)
|
epToAdd.Clear();
|
||||||
{
|
allEpisodes = await _api.GetAllEpisodes(server.ApiKey, processed, 200, server.AdministratorId, server.FullUri);
|
||||||
// add it
|
|
||||||
epToAdd.Add(new EmbyEpisode
|
|
||||||
{
|
|
||||||
EmbyId = ep.Id,
|
|
||||||
EpisodeNumber = ep.IndexNumber,
|
|
||||||
SeasonNumber = ep.ParentIndexNumber,
|
|
||||||
ParentId = ep.SeriesId,
|
|
||||||
TvDbId = ep.ProviderIds.Tvdb,
|
|
||||||
TheMovieDbId = ep.ProviderIds.Tmdb,
|
|
||||||
ImdbId = ep.ProviderIds.Imdb,
|
|
||||||
Title = ep.Name,
|
|
||||||
AddedAt = DateTime.UtcNow
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (epToAdd.Any())
|
if (epToAdd.Any())
|
||||||
|
|
|
@ -492,41 +492,42 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
var orderedTv = series.OrderByDescending(x => x.AddedAt);
|
var orderedTv = series.OrderByDescending(x => x.AddedAt);
|
||||||
foreach (var t in orderedTv)
|
foreach (var t in orderedTv)
|
||||||
{
|
{
|
||||||
|
if (!t.HasTvDb)
|
||||||
|
{
|
||||||
|
// We may need to use themoviedb for the imdbid or their own id to get info
|
||||||
|
if (t.HasTheMovieDb)
|
||||||
|
{
|
||||||
|
int.TryParse(t.TheMovieDbId, out var movieId);
|
||||||
|
var externals = await _movieApi.GetTvExternals(movieId);
|
||||||
|
if (externals == null || externals.tvdb_id <= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
t.TvDbId = externals.tvdb_id.ToString();
|
||||||
|
}
|
||||||
|
// WE could check the below but we need to get the moviedb and then perform the above, let the metadata job figure this out.
|
||||||
|
//else if(t.HasImdb)
|
||||||
|
//{
|
||||||
|
// // Check the imdbid
|
||||||
|
// var externals = await _movieApi.Find(t.ImdbId, ExternalSource.imdb_id);
|
||||||
|
// if (externals?.tv_results == null || externals.tv_results.Length <= 0)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// t.TvDbId = externals.tv_results.FirstOrDefault()..ToString();
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int.TryParse(t.TvDbId, out var tvdbId);
|
||||||
|
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!t.HasTvDb)
|
|
||||||
{
|
|
||||||
// We may need to use themoviedb for the imdbid or their own id to get info
|
|
||||||
if (t.HasTheMovieDb)
|
|
||||||
{
|
|
||||||
int.TryParse(t.TheMovieDbId, out var movieId);
|
|
||||||
var externals = await _movieApi.GetTvExternals(movieId);
|
|
||||||
if (externals == null || externals.tvdb_id <= 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
t.TvDbId = externals.tvdb_id.ToString();
|
|
||||||
}
|
|
||||||
// WE could check the below but we need to get the moviedb and then perform the above, let the metadata job figure this out.
|
|
||||||
//else if(t.HasImdb)
|
|
||||||
//{
|
|
||||||
// // Check the imdbid
|
|
||||||
// var externals = await _movieApi.Find(t.ImdbId, ExternalSource.imdb_id);
|
|
||||||
// if (externals?.tv_results == null || externals.tv_results.Length <= 0)
|
|
||||||
// {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// t.TvDbId = externals.tv_results.FirstOrDefault()..ToString();
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int.TryParse(t.TvDbId, out var tvdbId);
|
|
||||||
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
|
|
||||||
if (info == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var banner = info.image?.original;
|
var banner = info.image?.original;
|
||||||
if (!string.IsNullOrEmpty(banner))
|
if (!string.IsNullOrEmpty(banner))
|
||||||
{
|
{
|
||||||
|
@ -588,7 +589,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
{
|
{
|
||||||
AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -676,20 +677,20 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
var orderedTv = series.OrderByDescending(x => x.AddedAt);
|
var orderedTv = series.OrderByDescending(x => x.AddedAt);
|
||||||
foreach (var t in orderedTv)
|
foreach (var t in orderedTv)
|
||||||
{
|
{
|
||||||
|
if (!t.TvDbId.HasValue())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int.TryParse(t.TvDbId, out var tvdbId);
|
||||||
|
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!t.TvDbId.HasValue())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int.TryParse(t.TvDbId, out var tvdbId);
|
|
||||||
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
|
|
||||||
if (info == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var banner = info.image?.original;
|
var banner = info.image?.original;
|
||||||
if (!string.IsNullOrEmpty(banner))
|
if (!string.IsNullOrEmpty(banner))
|
||||||
{
|
{
|
||||||
|
@ -752,7 +753,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
{
|
{
|
||||||
AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Starting Update job");
|
Logger.LogDebug(LoggingEvents.Updater, "Starting Update job");
|
||||||
|
|
||||||
var settings = await Settings.GetSettingsAsync();
|
var settings = await Settings.GetSettingsAsync();
|
||||||
if (!settings.AutoUpdateEnabled)
|
if (!settings.AutoUpdateEnabled && !settings.TestMode)
|
||||||
{
|
{
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Auto update is not enabled");
|
Logger.LogDebug(LoggingEvents.Updater, "Auto update is not enabled");
|
||||||
return;
|
return;
|
||||||
|
@ -83,7 +83,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
|
|
||||||
var productVersion = AssemblyHelper.GetRuntimeVersion();
|
var productVersion = AssemblyHelper.GetRuntimeVersion();
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Product Version {0}", productVersion);
|
Logger.LogDebug(LoggingEvents.Updater, "Product Version {0}", productVersion);
|
||||||
|
var serverVersion = string.Empty;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var productArray = GetVersion();
|
var productArray = GetVersion();
|
||||||
|
@ -96,13 +96,17 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Branch {0}", branch);
|
Logger.LogDebug(LoggingEvents.Updater, "Branch {0}", branch);
|
||||||
|
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Looking for updates now");
|
Logger.LogDebug(LoggingEvents.Updater, "Looking for updates now");
|
||||||
|
//TODO this fails because the branch = featureupdater when it should be feature/updater
|
||||||
var updates = await Processor.Process(branch);
|
var updates = await Processor.Process(branch);
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Updates: {0}", updates);
|
Logger.LogDebug(LoggingEvents.Updater, "Updates: {0}", updates);
|
||||||
var serverVersion = updates.UpdateVersionString;
|
|
||||||
|
|
||||||
|
serverVersion = updates.UpdateVersionString;
|
||||||
|
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Service Version {0}", updates.UpdateVersionString);
|
Logger.LogDebug(LoggingEvents.Updater, "Service Version {0}", updates.UpdateVersionString);
|
||||||
|
|
||||||
if (!serverVersion.Equals(version, StringComparison.CurrentCultureIgnoreCase))
|
|
||||||
|
if (!serverVersion.Equals(version, StringComparison.CurrentCultureIgnoreCase) || settings.TestMode)
|
||||||
{
|
{
|
||||||
// Let's download the correct zip
|
// Let's download the correct zip
|
||||||
var desc = RuntimeInformation.OSDescription;
|
var desc = RuntimeInformation.OSDescription;
|
||||||
|
@ -135,7 +139,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
if (process == Architecture.Arm)
|
if (process == Architecture.Arm)
|
||||||
{
|
{
|
||||||
download = updates.Downloads.FirstOrDefault(x => x.Name.Contains("arm.", CompareOptions.IgnoreCase));
|
download = updates.Downloads.FirstOrDefault(x => x.Name.Contains("arm.", CompareOptions.IgnoreCase));
|
||||||
} else if (process == Architecture.Arm64)
|
}
|
||||||
|
else if (process == Architecture.Arm64)
|
||||||
{
|
{
|
||||||
download = updates.Downloads.FirstOrDefault(x => x.Name.Contains("arm64.", CompareOptions.IgnoreCase));
|
download = updates.Downloads.FirstOrDefault(x => x.Name.Contains("arm64.", CompareOptions.IgnoreCase));
|
||||||
}
|
}
|
||||||
|
@ -206,33 +211,35 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
updaterExtension = ".exe";
|
updaterExtension = ".exe";
|
||||||
}
|
}
|
||||||
var updaterFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
var updaterFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||||
"TempUpdate", $"Ombi.Updater{updaterExtension}");
|
"TempUpdate", "updater", $"Ombi.Updater{updaterExtension}");
|
||||||
|
|
||||||
// Make sure the file is an executable
|
// Make sure the file is an executable
|
||||||
ExecLinuxCommand($"chmod +x {updaterFile}");
|
//ExecLinuxCommand($"chmod +x {updaterFile}");
|
||||||
|
|
||||||
|
|
||||||
// There must be an update
|
// There must be an update
|
||||||
var start = new ProcessStartInfo
|
var start = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
UseShellExecute = true,
|
UseShellExecute = false,
|
||||||
CreateNoWindow = false, // Ignored if UseShellExecute is set to true
|
CreateNoWindow = true, // Ignored if UseShellExecute is set to true
|
||||||
FileName = updaterFile,
|
FileName = updaterFile,
|
||||||
Arguments = GetArgs(settings),
|
Arguments = GetArgs(settings),
|
||||||
WorkingDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "TempUpdate"),
|
WorkingDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "TempUpdate"),
|
||||||
};
|
};
|
||||||
if (settings.Username.HasValue())
|
//if (settings.Username.HasValue())
|
||||||
|
//{
|
||||||
|
// start.UserName = settings.Username;
|
||||||
|
//}
|
||||||
|
//if (settings.Password.HasValue())
|
||||||
|
//{
|
||||||
|
// start.Password = settings.Password.ToSecureString();
|
||||||
|
//}
|
||||||
|
using (var proc = new Process { StartInfo = start })
|
||||||
{
|
{
|
||||||
start.UserName = settings.Username;
|
proc.Start();
|
||||||
}
|
}
|
||||||
if (settings.Password.HasValue())
|
|
||||||
{
|
|
||||||
start.Password = settings.Password.ToSecureString();
|
|
||||||
}
|
|
||||||
var proc = new Process { StartInfo = start };
|
|
||||||
|
|
||||||
|
|
||||||
proc.Start();
|
|
||||||
|
|
||||||
Logger.LogDebug(LoggingEvents.Updater, "Bye bye");
|
Logger.LogDebug(LoggingEvents.Updater, "Bye bye");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,10 +261,10 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"--applicationPath \"{currentLocation}\" --processname \"{processName}\" ");
|
sb.Append($"--applicationPath \"{currentLocation}\" --processname \"{processName}\" ");
|
||||||
if (settings.WindowsService)
|
//if (settings.WindowsService)
|
||||||
{
|
//{
|
||||||
sb.Append($"--windowsServiceName \"{settings.WindowsServiceName}\" ");
|
// sb.Append($"--windowsServiceName \"{settings.WindowsServiceName}\" ");
|
||||||
}
|
//}
|
||||||
var sb2 = new StringBuilder();
|
var sb2 = new StringBuilder();
|
||||||
if (url?.Value.HasValue() ?? false)
|
if (url?.Value.HasValue() ?? false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Ombi.Schedule.Jobs.Plex.Models
|
||||||
public IEnumerable<int> Content { get; set; }
|
public IEnumerable<int> Content { get; set; }
|
||||||
public IEnumerable<int> Episodes { get; set; }
|
public IEnumerable<int> Episodes { get; set; }
|
||||||
|
|
||||||
public bool HasProcessedContent => Content.Any();
|
public bool HasProcessedContent => Content?.Any() ?? false;
|
||||||
public bool HasProcessedEpisodes => Episodes.Any();
|
public bool HasProcessedEpisodes => Episodes?.Any() ?? false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -79,11 +79,16 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
{
|
{
|
||||||
seriesEpisodes = plexEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());
|
seriesEpisodes = plexEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());
|
||||||
}
|
}
|
||||||
if (useTvDb)
|
if (useTvDb && (seriesEpisodes == null || !seriesEpisodes.Any()) )
|
||||||
{
|
{
|
||||||
seriesEpisodes = plexEpisodes.Where(x => x.Series.TvDbId == tvDbId.ToString());
|
seriesEpisodes = plexEpisodes.Where(x => x.Series.TvDbId == tvDbId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seriesEpisodes == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!seriesEpisodes.Any())
|
if (!seriesEpisodes.Any())
|
||||||
{
|
{
|
||||||
// Let's try and match the series by name
|
// Let's try and match the series by name
|
||||||
|
@ -118,6 +123,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
{
|
{
|
||||||
// We have fulfulled this request!
|
// We have fulfulled this request!
|
||||||
child.Available = true;
|
child.Available = true;
|
||||||
|
child.MarkedAsAvailable = DateTime.Now;
|
||||||
_backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions
|
_backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions
|
||||||
{
|
{
|
||||||
DateTime = DateTime.Now,
|
DateTime = DateTime.Now,
|
||||||
|
@ -158,6 +164,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
}
|
}
|
||||||
|
|
||||||
movie.Available = true;
|
movie.Available = true;
|
||||||
|
movie.MarkedAsAvailable = DateTime.Now;
|
||||||
if (movie.Available)
|
if (movie.Available)
|
||||||
{
|
{
|
||||||
_backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions
|
_backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions
|
||||||
|
|
|
@ -150,9 +150,9 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
var retVal = new ProcessedContent();
|
var retVal = new ProcessedContent();
|
||||||
var contentProcessed = new Dictionary<int, int>();
|
var contentProcessed = new Dictionary<int, int>();
|
||||||
var episodesProcessed = new List<int>();
|
var episodesProcessed = new List<int>();
|
||||||
Logger.LogInformation("Getting all content from server {0}", servers.Name);
|
Logger.LogDebug("Getting all content from server {0}", servers.Name);
|
||||||
var allContent = await GetAllContent(servers, recentlyAddedSearch);
|
var allContent = await GetAllContent(servers, recentlyAddedSearch);
|
||||||
Logger.LogInformation("We found {0} items", allContent.Count);
|
Logger.LogDebug("We found {0} items", allContent.Count);
|
||||||
|
|
||||||
// Let's now process this.
|
// Let's now process this.
|
||||||
var contentToAdd = new HashSet<PlexServerContent>();
|
var contentToAdd = new HashSet<PlexServerContent>();
|
||||||
|
@ -163,7 +163,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
{
|
{
|
||||||
if (content.viewGroup.Equals(PlexMediaType.Episode.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
if (content.viewGroup.Equals(PlexMediaType.Episode.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Found some episodes, this must be a recently added sync");
|
Logger.LogDebug("Found some episodes, this must be a recently added sync");
|
||||||
var count = 0;
|
var count = 0;
|
||||||
foreach (var epInfo in content.Metadata ?? new Metadata[]{})
|
foreach (var epInfo in content.Metadata ?? new Metadata[]{})
|
||||||
{
|
{
|
||||||
|
@ -208,7 +208,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
// Process Shows
|
// Process Shows
|
||||||
Logger.LogInformation("Processing TV Shows");
|
Logger.LogDebug("Processing TV Shows");
|
||||||
var count = 0;
|
var count = 0;
|
||||||
foreach (var show in content.Metadata ?? new Metadata[] { })
|
foreach (var show in content.Metadata ?? new Metadata[] { })
|
||||||
{
|
{
|
||||||
|
@ -237,7 +237,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
}
|
}
|
||||||
if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Processing Movies");
|
Logger.LogDebug("Processing Movies");
|
||||||
foreach (var movie in content?.Metadata ?? new Metadata[] { })
|
foreach (var movie in content?.Metadata ?? new Metadata[] { })
|
||||||
{
|
{
|
||||||
// Let's check if we have this movie
|
// Let's check if we have this movie
|
||||||
|
@ -251,7 +251,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
//var existing = await Repo.GetByKey(movie.ratingKey);
|
//var existing = await Repo.GetByKey(movie.ratingKey);
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("We already have movie {0}", movie.title);
|
Logger.LogDebug("We already have movie {0}", movie.title);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
await Repo.Delete(hasSameKey);
|
await Repo.Delete(hasSameKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.LogInformation("Adding movie {0}", movie.title);
|
Logger.LogDebug("Adding movie {0}", movie.title);
|
||||||
var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri,
|
var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri,
|
||||||
movie.ratingKey);
|
movie.ratingKey);
|
||||||
var providerIds = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata
|
var providerIds = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata
|
||||||
|
@ -381,6 +381,19 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
|
|
||||||
if (existingContent != null)
|
if (existingContent != null)
|
||||||
{
|
{
|
||||||
|
// Let's make sure that we have some sort of ID e.g. Imdbid for this,
|
||||||
|
// Looks like it's possible to not have an Id for a show
|
||||||
|
// I suspect we cached that show just as it was added to Plex.
|
||||||
|
|
||||||
|
if (!existingContent.HasImdb && !existingContent.HasTheMovieDb && !existingContent.HasTvDb)
|
||||||
|
{
|
||||||
|
var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri,
|
||||||
|
existingContent.Key);
|
||||||
|
GetProviderIds(showMetadata, existingContent);
|
||||||
|
|
||||||
|
await Repo.Update(existingContent);
|
||||||
|
}
|
||||||
|
|
||||||
// Just check the key
|
// Just check the key
|
||||||
if (existingKey != null)
|
if (existingKey != null)
|
||||||
{
|
{
|
||||||
|
@ -421,7 +434,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.LogInformation("We already have show {0} checking for new seasons",
|
Logger.LogDebug("We already have show {0} checking for new seasons",
|
||||||
existingContent.Title);
|
existingContent.Title);
|
||||||
// Ok so we have it, let's check if there are any new seasons
|
// Ok so we have it, let's check if there are any new seasons
|
||||||
var itemAdded = false;
|
var itemAdded = false;
|
||||||
|
@ -472,16 +485,13 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.LogInformation("New show {0}, so add it", show.title);
|
Logger.LogDebug("New show {0}, so add it", show.title);
|
||||||
|
|
||||||
// Get the show metadata... This sucks since the `metadata` var contains all information about the show
|
// Get the show metadata... This sucks since the `metadata` var contains all information about the show
|
||||||
// But it does not contain the `guid` property that we need to pull out thetvdb id...
|
// But it does not contain the `guid` property that we need to pull out thetvdb id...
|
||||||
var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri,
|
var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri,
|
||||||
show.ratingKey);
|
show.ratingKey);
|
||||||
var providerIds =
|
|
||||||
PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata.FirstOrDefault()
|
|
||||||
.guid);
|
|
||||||
|
|
||||||
var item = new PlexServerContent
|
var item = new PlexServerContent
|
||||||
{
|
{
|
||||||
AddedAt = DateTime.Now,
|
AddedAt = DateTime.Now,
|
||||||
|
@ -492,20 +502,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey),
|
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey),
|
||||||
Seasons = new List<PlexSeasonsContent>()
|
Seasons = new List<PlexSeasonsContent>()
|
||||||
};
|
};
|
||||||
if (providerIds.Type == ProviderType.ImdbId)
|
GetProviderIds(showMetadata, item);
|
||||||
{
|
|
||||||
item.ImdbId = providerIds.ImdbId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (providerIds.Type == ProviderType.TheMovieDbId)
|
|
||||||
{
|
|
||||||
item.TheMovieDbId = providerIds.TheMovieDb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (providerIds.Type == ProviderType.TvDbId)
|
|
||||||
{
|
|
||||||
item.TvDbId = providerIds.TheTvDb;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's just double check to make sure we do not have it now we have some id's
|
// Let's just double check to make sure we do not have it now we have some id's
|
||||||
var existingImdb = false;
|
var existingImdb = false;
|
||||||
|
@ -547,6 +544,27 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void GetProviderIds(PlexMetadata showMetadata, PlexServerContent existingContent)
|
||||||
|
{
|
||||||
|
var providerIds =
|
||||||
|
PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata.FirstOrDefault()
|
||||||
|
.guid);
|
||||||
|
if (providerIds.Type == ProviderType.ImdbId)
|
||||||
|
{
|
||||||
|
existingContent.ImdbId = providerIds.ImdbId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providerIds.Type == ProviderType.TheMovieDbId)
|
||||||
|
{
|
||||||
|
existingContent.TheMovieDbId = providerIds.TheMovieDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providerIds.Type == ProviderType.TvDbId)
|
||||||
|
{
|
||||||
|
existingContent.TvDbId = providerIds.TheTvDb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all the library sections.
|
/// Gets all the library sections.
|
||||||
/// If the user has specified only certain libraries then we will only look for those
|
/// If the user has specified only certain libraries then we will only look for those
|
||||||
|
@ -573,7 +591,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
.Select(x => x.Key.ToString()).ToList();
|
.Select(x => x.Key.ToString()).ToList();
|
||||||
if (!keys.Contains(dir.key))
|
if (!keys.Contains(dir.key))
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Lib {0} is not monitored, so skipping", dir.key);
|
Logger.LogDebug("Lib {0} is not monitored, so skipping", dir.key);
|
||||||
// We are not monitoring this lib
|
// We are not monitoring this lib
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,10 @@ namespace Ombi.Schedule.Jobs.Sonarr
|
||||||
await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM SonarrEpisodeCache");
|
await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM SonarrEpisodeCache");
|
||||||
foreach (var s in sonarrSeries)
|
foreach (var s in sonarrSeries)
|
||||||
{
|
{
|
||||||
|
if (!s.monitored)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
_log.LogDebug("Syncing series: {0}", s.title);
|
_log.LogDebug("Syncing series: {0}", s.title);
|
||||||
var episodes = await _api.GetEpisodes(s.id, settings.ApiKey, settings.FullUri);
|
var episodes = await _api.GetEpisodes(s.id, settings.ApiKey, settings.FullUri);
|
||||||
var monitoredEpisodes = episodes.Where(x => x.monitored || x.hasFile);
|
var monitoredEpisodes = episodes.Where(x => x.monitored || x.hasFile);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Ombi.Settings.Settings.Models.External;
|
using Ombi.Settings.Settings.Models.External;
|
||||||
|
|
||||||
namespace Ombi.Core.Settings.Models.External
|
namespace Ombi.Core.Settings.Models.External
|
||||||
|
@ -6,6 +7,10 @@ namespace Ombi.Core.Settings.Models.External
|
||||||
public sealed class PlexSettings : Ombi.Settings.Settings.Models.Settings
|
public sealed class PlexSettings : Ombi.Settings.Settings.Models.Settings
|
||||||
{
|
{
|
||||||
public bool Enable { get; set; }
|
public bool Enable { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// This is the ClientId for OAuth
|
||||||
|
/// </summary>
|
||||||
|
public Guid InstallId { get; set; }
|
||||||
public List<PlexServers> Servers { get; set; }
|
public List<PlexServers> Servers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,5 +10,6 @@
|
||||||
public string ScriptLocation { get; set; }
|
public string ScriptLocation { get; set; }
|
||||||
public string WindowsServiceName { get; set; }
|
public string WindowsServiceName { get; set; }
|
||||||
public bool WindowsService { get; set; }
|
public bool WindowsService { get; set; }
|
||||||
|
public bool TestMode { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -183,7 +183,7 @@ namespace Ombi.Store.Context
|
||||||
notificationToAdd = new NotificationTemplates
|
notificationToAdd = new NotificationTemplates
|
||||||
{
|
{
|
||||||
NotificationType = notificationType,
|
NotificationType = notificationType,
|
||||||
Message = "Hello! You {Title} on {ApplicationName}! This is now available! :)",
|
Message = "Hello! Your request for {Title} on {ApplicationName}! This is now available! :)",
|
||||||
Subject = "{ApplicationName}: {Title} is now available!",
|
Subject = "{ApplicationName}: {Title} is now available!",
|
||||||
Agent = agent,
|
Agent = agent,
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Ombi.Store.Entities
|
||||||
{
|
{
|
||||||
public enum RequestType
|
public enum RequestType
|
||||||
{
|
{
|
||||||
TvShow,
|
TvShow = 0,
|
||||||
Movie
|
Movie = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,13 @@ namespace Ombi.Store.Entities.Requests
|
||||||
{
|
{
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public bool Approved { get; set; }
|
public bool Approved { get; set; }
|
||||||
|
public DateTime MarkedAsApproved { get; set; }
|
||||||
public DateTime RequestedDate { get; set; }
|
public DateTime RequestedDate { get; set; }
|
||||||
public bool Available { get; set; }
|
public bool Available { get; set; }
|
||||||
|
public DateTime? MarkedAsAvailable { get; set; }
|
||||||
public string RequestedUserId { get; set; }
|
public string RequestedUserId { get; set; }
|
||||||
public bool? Denied { get; set; }
|
public bool? Denied { get; set; }
|
||||||
|
public DateTime MarkedAsDenied { get; set; }
|
||||||
public string DeniedReason { get; set; }
|
public string DeniedReason { get; set; }
|
||||||
public RequestType RequestType { get; set; }
|
public RequestType RequestType { get; set; }
|
||||||
|
|
||||||
|
|
981
src/Ombi.Store/Migrations/20180703200952_EmbyUrlFix.Designer.cs
generated
Normal file
981
src/Ombi.Store/Migrations/20180703200952_EmbyUrlFix.Designer.cs
generated
Normal file
|
@ -0,0 +1,981 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
using Ombi.Store.Context;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
using Ombi.Store.Entities.Requests;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(OmbiContext))]
|
||||||
|
[Migration("20180703200952_EmbyUrlFix")]
|
||||||
|
partial class EmbyUrlFix
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.0.3-rtm-10026");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ApplicationConfiguration");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AuditArea");
|
||||||
|
|
||||||
|
b.Property<int>("AuditType");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateTime");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("User");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Audit");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CouchPotatoCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("EmbyId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId");
|
||||||
|
|
||||||
|
b.Property<string>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TvDbId");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<string>("Url");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("EmbyContent");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("EmbyId");
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<string>("ParentId");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<string>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
|
b.ToTable("EmbyEpisode");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Content");
|
||||||
|
|
||||||
|
b.Property<string>("SettingsName");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("GlobalSettings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("Agent");
|
||||||
|
|
||||||
|
b.Property<bool>("Enabled");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<int>("NotificationType");
|
||||||
|
|
||||||
|
b.Property<string>("Subject");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("NotificationTemplates");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("PlayerId");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("NotificationUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount");
|
||||||
|
|
||||||
|
b.Property<string>("Alias");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed");
|
||||||
|
|
||||||
|
b.Property<string>("EmbyConnectUserId");
|
||||||
|
|
||||||
|
b.Property<int?>("EpisodeRequestLimit");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastLoggedIn");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||||
|
|
||||||
|
b.Property<int?>("MovieRequestLimit");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderUserId");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserAccessToken");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<int>("UserType");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<int>("GrandparentKey");
|
||||||
|
|
||||||
|
b.Property<int>("Key");
|
||||||
|
|
||||||
|
b.Property<int>("ParentKey");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GrandparentKey");
|
||||||
|
|
||||||
|
b.ToTable("PlexEpisode");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("ParentKey");
|
||||||
|
|
||||||
|
b.Property<int>("PlexContentId");
|
||||||
|
|
||||||
|
b.Property<int?>("PlexServerContentId");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonKey");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlexServerContentId");
|
||||||
|
|
||||||
|
b.ToTable("PlexSeasonsContent");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<int>("Key");
|
||||||
|
|
||||||
|
b.Property<string>("Quality");
|
||||||
|
|
||||||
|
b.Property<string>("ReleaseYear");
|
||||||
|
|
||||||
|
b.Property<string>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TvDbId");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<string>("Url");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PlexServerContent");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("HasFile");
|
||||||
|
|
||||||
|
b.Property<int>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("RadarrCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<int>("ContentId");
|
||||||
|
|
||||||
|
b.Property<int>("ContentType");
|
||||||
|
|
||||||
|
b.Property<int?>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<int?>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("RecentlyAddedLog");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Approved");
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<bool?>("Denied");
|
||||||
|
|
||||||
|
b.Property<string>("DeniedReason");
|
||||||
|
|
||||||
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<int>("ParentRequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RequestedDate");
|
||||||
|
|
||||||
|
b.Property<string>("RequestedUserId");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesType");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentRequestId");
|
||||||
|
|
||||||
|
b.HasIndex("RequestedUserId");
|
||||||
|
|
||||||
|
b.ToTable("ChildRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("IssueCategory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Comment");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date");
|
||||||
|
|
||||||
|
b.Property<int?>("IssuesId");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IssuesId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("IssueComments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<int>("IssueCategoryId");
|
||||||
|
|
||||||
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId");
|
||||||
|
|
||||||
|
b.Property<int?>("RequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("ResovledDate");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("Subject");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("UserReportedId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IssueCategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("IssueId");
|
||||||
|
|
||||||
|
b.HasIndex("UserReportedId");
|
||||||
|
|
||||||
|
b.ToTable("Issues");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Approved");
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<string>("Background");
|
||||||
|
|
||||||
|
b.Property<bool?>("Denied");
|
||||||
|
|
||||||
|
b.Property<string>("DeniedReason");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DigitalReleaseDate");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<string>("Overview");
|
||||||
|
|
||||||
|
b.Property<string>("PosterPath");
|
||||||
|
|
||||||
|
b.Property<int>("QualityOverride");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ReleaseDate");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RequestedDate");
|
||||||
|
|
||||||
|
b.Property<string>("RequestedUserId");
|
||||||
|
|
||||||
|
b.Property<int>("RootPathOverride");
|
||||||
|
|
||||||
|
b.Property<string>("Status");
|
||||||
|
|
||||||
|
b.Property<int>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RequestedUserId");
|
||||||
|
|
||||||
|
b.ToTable("MovieRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeCount");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RequestDate");
|
||||||
|
|
||||||
|
b.Property<int>("RequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("RequestLog");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Background");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<string>("Overview");
|
||||||
|
|
||||||
|
b.Property<string>("PosterPath");
|
||||||
|
|
||||||
|
b.Property<int?>("QualityOverride");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ReleaseDate");
|
||||||
|
|
||||||
|
b.Property<int?>("RootFolder");
|
||||||
|
|
||||||
|
b.Property<string>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("TvRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("RequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("RequestSubscription");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SickRageCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SickRageEpisodeCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SonarrCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("HasFile");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SonarrEpisodeCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Token");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("Tokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AirDate");
|
||||||
|
|
||||||
|
b.Property<bool>("Approved");
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("Requested");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Url");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SeasonId");
|
||||||
|
|
||||||
|
b.ToTable("EpisodeRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("ChildRequestId");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ChildRequestId");
|
||||||
|
|
||||||
|
b.ToTable("SeasonRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.EmbyContent", "Series")
|
||||||
|
.WithMany("Episodes")
|
||||||
|
.HasForeignKey("ParentId")
|
||||||
|
.HasPrincipalKey("EmbyId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany("NotificationUserIds")
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series")
|
||||||
|
.WithMany("Episodes")
|
||||||
|
.HasForeignKey("GrandparentKey")
|
||||||
|
.HasPrincipalKey("Key")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.PlexServerContent")
|
||||||
|
.WithMany("Seasons")
|
||||||
|
.HasForeignKey("PlexServerContentId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
|
||||||
|
.WithMany("ChildRequests")
|
||||||
|
.HasForeignKey("ParentRequestId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RequestedUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues")
|
||||||
|
.WithMany("Comments")
|
||||||
|
.HasForeignKey("IssuesId");
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("IssueCategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests")
|
||||||
|
.WithMany("Issues")
|
||||||
|
.HasForeignKey("IssueId");
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.MovieRequests")
|
||||||
|
.WithMany("Issues")
|
||||||
|
.HasForeignKey("IssueId");
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserReportedId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RequestedUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season")
|
||||||
|
.WithMany("Episodes")
|
||||||
|
.HasForeignKey("SeasonId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest")
|
||||||
|
.WithMany("SeasonRequests")
|
||||||
|
.HasForeignKey("ChildRequestId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
src/Ombi.Store/Migrations/20180703200952_EmbyUrlFix.cs
Normal file
20
src/Ombi.Store/Migrations/20180703200952_EmbyUrlFix.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations
|
||||||
|
{
|
||||||
|
public partial class EmbyUrlFix : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.Sql(
|
||||||
|
@"UPDATE EmbyContent SET Url = replace( Url, 'http://app.emby.media/itemdetails.html', 'http://app.emby.media/#!/itemdetails.html' ) WHERE Url LIKE 'http://app.emby.media/itemdetails.html%';");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
988
src/Ombi.Store/Migrations/20180730085903_UserStats.Designer.cs
generated
Normal file
988
src/Ombi.Store/Migrations/20180730085903_UserStats.Designer.cs
generated
Normal file
|
@ -0,0 +1,988 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Ombi.Store.Context;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(OmbiContext))]
|
||||||
|
[Migration("20180730085903_UserStats")]
|
||||||
|
partial class UserStats
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ApplicationConfiguration");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AuditArea");
|
||||||
|
|
||||||
|
b.Property<int>("AuditType");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateTime");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("User");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Audit");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CouchPotatoCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("EmbyId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId");
|
||||||
|
|
||||||
|
b.Property<string>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TvDbId");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<string>("Url");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("EmbyContent");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("EmbyId");
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<string>("ParentId");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<string>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
|
b.ToTable("EmbyEpisode");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Content");
|
||||||
|
|
||||||
|
b.Property<string>("SettingsName");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("GlobalSettings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("Agent");
|
||||||
|
|
||||||
|
b.Property<bool>("Enabled");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<int>("NotificationType");
|
||||||
|
|
||||||
|
b.Property<string>("Subject");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("NotificationTemplates");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("PlayerId");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("NotificationUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount");
|
||||||
|
|
||||||
|
b.Property<string>("Alias");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed");
|
||||||
|
|
||||||
|
b.Property<string>("EmbyConnectUserId");
|
||||||
|
|
||||||
|
b.Property<int?>("EpisodeRequestLimit");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastLoggedIn");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||||
|
|
||||||
|
b.Property<int?>("MovieRequestLimit");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderUserId");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserAccessToken");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<int>("UserType");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<int>("GrandparentKey");
|
||||||
|
|
||||||
|
b.Property<int>("Key");
|
||||||
|
|
||||||
|
b.Property<int>("ParentKey");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GrandparentKey");
|
||||||
|
|
||||||
|
b.ToTable("PlexEpisode");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("ParentKey");
|
||||||
|
|
||||||
|
b.Property<int>("PlexContentId");
|
||||||
|
|
||||||
|
b.Property<int?>("PlexServerContentId");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonKey");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlexServerContentId");
|
||||||
|
|
||||||
|
b.ToTable("PlexSeasonsContent");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<int>("Key");
|
||||||
|
|
||||||
|
b.Property<string>("Quality");
|
||||||
|
|
||||||
|
b.Property<string>("ReleaseYear");
|
||||||
|
|
||||||
|
b.Property<string>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TvDbId");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<string>("Url");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PlexServerContent");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("HasFile");
|
||||||
|
|
||||||
|
b.Property<int>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("RadarrCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt");
|
||||||
|
|
||||||
|
b.Property<int>("ContentId");
|
||||||
|
|
||||||
|
b.Property<int>("ContentType");
|
||||||
|
|
||||||
|
b.Property<int?>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<int?>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("RecentlyAddedLog");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Approved");
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<bool?>("Denied");
|
||||||
|
|
||||||
|
b.Property<string>("DeniedReason");
|
||||||
|
|
||||||
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsApproved");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MarkedAsAvailable");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsDenied");
|
||||||
|
|
||||||
|
b.Property<int>("ParentRequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RequestedDate");
|
||||||
|
|
||||||
|
b.Property<string>("RequestedUserId");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesType");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentRequestId");
|
||||||
|
|
||||||
|
b.HasIndex("RequestedUserId");
|
||||||
|
|
||||||
|
b.ToTable("ChildRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("IssueCategory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Comment");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date");
|
||||||
|
|
||||||
|
b.Property<int?>("IssuesId");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IssuesId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("IssueComments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<int>("IssueCategoryId");
|
||||||
|
|
||||||
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId");
|
||||||
|
|
||||||
|
b.Property<int?>("RequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("ResovledDate");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("Subject");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("UserReportedId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IssueCategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("IssueId");
|
||||||
|
|
||||||
|
b.HasIndex("UserReportedId");
|
||||||
|
|
||||||
|
b.ToTable("Issues");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Approved");
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<string>("Background");
|
||||||
|
|
||||||
|
b.Property<bool?>("Denied");
|
||||||
|
|
||||||
|
b.Property<string>("DeniedReason");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DigitalReleaseDate");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsApproved");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MarkedAsAvailable");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsDenied");
|
||||||
|
|
||||||
|
b.Property<string>("Overview");
|
||||||
|
|
||||||
|
b.Property<string>("PosterPath");
|
||||||
|
|
||||||
|
b.Property<int>("QualityOverride");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ReleaseDate");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RequestedDate");
|
||||||
|
|
||||||
|
b.Property<string>("RequestedUserId");
|
||||||
|
|
||||||
|
b.Property<int>("RootPathOverride");
|
||||||
|
|
||||||
|
b.Property<string>("Status");
|
||||||
|
|
||||||
|
b.Property<int>("TheMovieDbId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RequestedUserId");
|
||||||
|
|
||||||
|
b.ToTable("MovieRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeCount");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RequestDate");
|
||||||
|
|
||||||
|
b.Property<int>("RequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("RequestLog");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Background");
|
||||||
|
|
||||||
|
b.Property<string>("ImdbId");
|
||||||
|
|
||||||
|
b.Property<string>("Overview");
|
||||||
|
|
||||||
|
b.Property<string>("PosterPath");
|
||||||
|
|
||||||
|
b.Property<int?>("QualityOverride");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ReleaseDate");
|
||||||
|
|
||||||
|
b.Property<int?>("RootFolder");
|
||||||
|
|
||||||
|
b.Property<string>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("TvRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("RequestId");
|
||||||
|
|
||||||
|
b.Property<int>("RequestType");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("RequestSubscription");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SickRageCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SickRageEpisodeCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SonarrCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("HasFile");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SonarrEpisodeCache");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Token");
|
||||||
|
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("Tokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("AirDate");
|
||||||
|
|
||||||
|
b.Property<bool>("Approved");
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<int>("EpisodeNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("Requested");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonId");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Url");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SeasonId");
|
||||||
|
|
||||||
|
b.ToTable("EpisodeRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("ChildRequestId");
|
||||||
|
|
||||||
|
b.Property<int>("SeasonNumber");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ChildRequestId");
|
||||||
|
|
||||||
|
b.ToTable("SeasonRequests");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.EmbyContent", "Series")
|
||||||
|
.WithMany("Episodes")
|
||||||
|
.HasForeignKey("ParentId")
|
||||||
|
.HasPrincipalKey("EmbyId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany("NotificationUserIds")
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series")
|
||||||
|
.WithMany("Episodes")
|
||||||
|
.HasForeignKey("GrandparentKey")
|
||||||
|
.HasPrincipalKey("Key")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.PlexServerContent")
|
||||||
|
.WithMany("Seasons")
|
||||||
|
.HasForeignKey("PlexServerContentId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
|
||||||
|
.WithMany("ChildRequests")
|
||||||
|
.HasForeignKey("ParentRequestId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RequestedUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues")
|
||||||
|
.WithMany("Comments")
|
||||||
|
.HasForeignKey("IssuesId");
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("IssueCategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests")
|
||||||
|
.WithMany("Issues")
|
||||||
|
.HasForeignKey("IssueId");
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.MovieRequests")
|
||||||
|
.WithMany("Issues")
|
||||||
|
.HasForeignKey("IssueId");
|
||||||
|
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserReportedId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RequestedUserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season")
|
||||||
|
.WithMany("Episodes")
|
||||||
|
.HasForeignKey("SeasonId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest")
|
||||||
|
.WithMany("SeasonRequests")
|
||||||
|
.HasForeignKey("ChildRequestId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
src/Ombi.Store/Migrations/20180730085903_UserStats.cs
Normal file
72
src/Ombi.Store/Migrations/20180730085903_UserStats.cs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations
|
||||||
|
{
|
||||||
|
public partial class UserStats : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "MarkedAsApproved",
|
||||||
|
table: "MovieRequests",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "MarkedAsAvailable",
|
||||||
|
table: "MovieRequests",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "MarkedAsDenied",
|
||||||
|
table: "MovieRequests",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "MarkedAsApproved",
|
||||||
|
table: "ChildRequests",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "MarkedAsAvailable",
|
||||||
|
table: "ChildRequests",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "MarkedAsDenied",
|
||||||
|
table: "ChildRequests",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "MarkedAsApproved",
|
||||||
|
table: "MovieRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "MarkedAsAvailable",
|
||||||
|
table: "MovieRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "MarkedAsDenied",
|
||||||
|
table: "MovieRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "MarkedAsApproved",
|
||||||
|
table: "ChildRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "MarkedAsAvailable",
|
||||||
|
table: "ChildRequests");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "MarkedAsDenied",
|
||||||
|
table: "ChildRequests");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,9 @@
|
||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
|
||||||
using Ombi.Helpers;
|
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
using Ombi.Store.Entities;
|
|
||||||
using Ombi.Store.Entities.Requests;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ombi.Store.Migrations
|
namespace Ombi.Store.Migrations
|
||||||
{
|
{
|
||||||
|
@ -20,7 +14,7 @@ namespace Ombi.Store.Migrations
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "2.0.3-rtm-10026");
|
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846");
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
{
|
{
|
||||||
|
@ -481,6 +475,12 @@ namespace Ombi.Store.Migrations
|
||||||
|
|
||||||
b.Property<int?>("IssueId");
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsApproved");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MarkedAsAvailable");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsDenied");
|
||||||
|
|
||||||
b.Property<int>("ParentRequestId");
|
b.Property<int>("ParentRequestId");
|
||||||
|
|
||||||
b.Property<int>("RequestType");
|
b.Property<int>("RequestType");
|
||||||
|
@ -595,6 +595,12 @@ namespace Ombi.Store.Migrations
|
||||||
|
|
||||||
b.Property<int?>("IssueId");
|
b.Property<int?>("IssueId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsApproved");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("MarkedAsAvailable");
|
||||||
|
|
||||||
|
b.Property<DateTime>("MarkedAsDenied");
|
||||||
|
|
||||||
b.Property<string>("Overview");
|
b.Property<string>("Overview");
|
||||||
|
|
||||||
b.Property<string>("PosterPath");
|
b.Property<string>("PosterPath");
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.1.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="1.1.9" />
|
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="1.1.9" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.1" />
|
||||||
<PackageReference Include="Moq" Version="4.7.99" />
|
<PackageReference Include="Moq" Version="4.7.99" />
|
||||||
<PackageReference Include="Nunit" Version="3.8.1" />
|
<PackageReference Include="Nunit" Version="3.8.1" />
|
||||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
|
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
|
||||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.7.0"></packagereference>
|
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.8.0"></packagereference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Ombi.Updater
|
||||||
ProcessInfo GetCurrentProcess();
|
ProcessInfo GetCurrentProcess();
|
||||||
int GetCurrentProcessId();
|
int GetCurrentProcessId();
|
||||||
ProcessInfo GetProcessById(int id);
|
ProcessInfo GetProcessById(int id);
|
||||||
void Kill(StartupOptions opts);
|
bool Kill(StartupOptions opts);
|
||||||
void KillAll(string processName);
|
void KillAll(string processName);
|
||||||
void SetPriority(int processId, ProcessPriorityClass priority);
|
void SetPriority(int processId, ProcessPriorityClass priority);
|
||||||
void WaitForExit(Process process);
|
void WaitForExit(Process process);
|
||||||
|
|
|
@ -22,29 +22,23 @@ namespace Ombi.Updater
|
||||||
{
|
{
|
||||||
// Kill Ombi Process
|
// Kill Ombi Process
|
||||||
var p = new ProcessProvider();
|
var p = new ProcessProvider();
|
||||||
|
bool killed = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
p.Kill(opt);
|
killed = p.Kill(opt);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the process has been killed
|
if (!killed)
|
||||||
while (p.FindProcessByName(opt.ProcessName).Any())
|
|
||||||
{
|
{
|
||||||
Thread.Sleep(500);
|
|
||||||
_log.LogDebug("Found another process called {0}, KILLING!", opt.ProcessName);
|
_log.LogDebug("Couldn't kill the ombi process");
|
||||||
var proc = p.FindProcessByName(opt.ProcessName).FirstOrDefault();
|
return;
|
||||||
if (proc != null)
|
|
||||||
{
|
|
||||||
_log.LogDebug($"[{proc.Id}] - {proc.Name} - Path: {proc.StartPath}");
|
|
||||||
opt.OmbiProcessId = proc.Id;
|
|
||||||
p.Kill(opt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_log.LogDebug("Starting to move the files");
|
_log.LogDebug("Starting to move the files");
|
||||||
|
@ -111,21 +105,23 @@ namespace Ombi.Updater
|
||||||
var location = System.Reflection.Assembly.GetEntryAssembly().Location;
|
var location = System.Reflection.Assembly.GetEntryAssembly().Location;
|
||||||
location = Path.GetDirectoryName(location);
|
location = Path.GetDirectoryName(location);
|
||||||
_log.LogDebug("We are currently in dir {0}", location);
|
_log.LogDebug("We are currently in dir {0}", location);
|
||||||
|
var updatedLocation = Directory.GetParent(location).FullName;
|
||||||
|
_log.LogDebug("The files are in {0}", updatedLocation); // Since the updater is a folder deeper
|
||||||
_log.LogDebug("Ombi is installed at {0}", options.ApplicationPath);
|
_log.LogDebug("Ombi is installed at {0}", options.ApplicationPath);
|
||||||
|
|
||||||
//Now Create all of the directories
|
//Now Create all of the directories
|
||||||
foreach (string dirPath in Directory.GetDirectories(location, "*",
|
foreach (string dirPath in Directory.GetDirectories(updatedLocation, "*",
|
||||||
SearchOption.AllDirectories))
|
SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
var newDir = dirPath.Replace(location, options.ApplicationPath);
|
var newDir = dirPath.Replace(updatedLocation, options.ApplicationPath);
|
||||||
Directory.CreateDirectory(newDir);
|
Directory.CreateDirectory(newDir);
|
||||||
_log.LogDebug("Created dir {0}", newDir);
|
_log.LogDebug("Created dir {0}", newDir);
|
||||||
}
|
}
|
||||||
//Copy all the files & Replaces any files with the same name
|
//Copy all the files & Replaces any files with the same name
|
||||||
foreach (string currentPath in Directory.GetFiles(location, "*.*",
|
foreach (string currentPath in Directory.GetFiles(updatedLocation, "*.*",
|
||||||
SearchOption.AllDirectories))
|
SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
var newFile = currentPath.Replace(location, options.ApplicationPath);
|
var newFile = currentPath.Replace(updatedLocation, options.ApplicationPath);
|
||||||
File.Copy(currentPath, newFile, true);
|
File.Copy(currentPath, newFile, true);
|
||||||
_log.LogDebug("Replaced file {0}", newFile);
|
_log.LogDebug("Replaced file {0}", newFile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RuntimeIdentifiers>win10-x64;win10-x86;osx-x64;ubuntu-x64;debian.8-x64;centos.7-x64;linux-x64;linux-arm;linux-arm64;</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x64;win10-x86;osx-x64;ubuntu-x64;debian.8-x64;centos.7-x64;linux-x64;linux-arm;linux-arm64;</RuntimeIdentifiers>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||||
<FileVersion>3.0.0.0</FileVersion>
|
<FileVersion>3.0.0.0</FileVersion>
|
||||||
<Version></Version>
|
<Version></Version>
|
||||||
|
@ -12,14 +12,14 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
|
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.1.1" />
|
||||||
<PackageReference Include="Serilog" Version="2.6.0-dev-00892" />
|
<PackageReference Include="Serilog" Version="2.6.0-dev-00892" />
|
||||||
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
|
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="3.2.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="3.2.0" />
|
||||||
|
|
|
@ -73,33 +73,32 @@ namespace Ombi.Updater
|
||||||
process.PriorityClass = priority;
|
process.PriorityClass = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Kill(StartupOptions opts)
|
public bool Kill(StartupOptions opts)
|
||||||
{
|
{
|
||||||
if (opts.IsWindowsService)
|
//if (opts.IsWindowsService)
|
||||||
{
|
//{
|
||||||
Console.WriteLine("Stopping Service {0}", opts.WindowsServiceName);
|
// Console.WriteLine("Stopping Service {0}", opts.WindowsServiceName);
|
||||||
var process = new Process();
|
// var process = new Process();
|
||||||
var startInfo =
|
// var startInfo =
|
||||||
new ProcessStartInfo
|
// new ProcessStartInfo
|
||||||
{
|
// {
|
||||||
WindowStyle = ProcessWindowStyle.Hidden,
|
// WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
FileName = "cmd.exe",
|
// FileName = "cmd.exe",
|
||||||
Arguments = $"/C net stop \"{opts.WindowsServiceName}\""
|
// Arguments = $"/C net stop \"{opts.WindowsServiceName}\""
|
||||||
};
|
// };
|
||||||
process.StartInfo = startInfo;
|
// process.StartInfo = startInfo;
|
||||||
process.Start();
|
// process.Start();
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
var process = Process.GetProcesses().FirstOrDefault(p => p.ProcessName == opts.ProcessName);
|
var process = Process.GetProcesses().FirstOrDefault(p => p.ProcessName == opts.ProcessName);
|
||||||
|
|
||||||
if (process == null)
|
if (process == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Cannot find process with name: {0}", opts.ProcessName);
|
Console.WriteLine("Cannot find process with name: {0}", opts.ProcessName);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.Refresh();
|
|
||||||
|
|
||||||
if (process.Id > 0)
|
if (process.Id > 0)
|
||||||
{
|
{
|
||||||
|
@ -108,8 +107,12 @@ namespace Ombi.Updater
|
||||||
Console.WriteLine("[{0}]: Waiting for exit", process.Id);
|
Console.WriteLine("[{0}]: Waiting for exit", process.Id);
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
Console.WriteLine("[{0}]: Process terminated successfully", process.Id);
|
Console.WriteLine("[{0}]: Process terminated successfully", process.Id);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KillAll(string processName)
|
public void KillAll(string processName)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"Ombi.Updater": {
|
"Ombi.Updater": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "--applicationPath \\\"C:\\\\Users\\\\Jamie\\\\Source\\\\Repos\\\\Ombi\\\\src\\\\Ombi\\\\bin\\\\Debug\\\\netcoreapp2.0\\\" --processname \\\"Ombi\\\" --startupArgs http://*:5000"
|
"commandLineArgs": "--applicationPath \"C:\\_git\\ombi\\src\\Ombi.Updater\\bin\\Debug\\netcoreapp2.0\" --processname \"Ombi\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
23
src/Ombi/.gitignore
vendored
23
src/Ombi/.gitignore
vendored
|
@ -1,23 +1,10 @@
|
||||||
/wwwroot/css/**
|
node_modules
|
||||||
/wwwroot/fonts/**
|
bin
|
||||||
/wwwroot/lib/**
|
obj
|
||||||
/wwwroot/maps/**
|
wwwroot/dist
|
||||||
/wwwroot/dist/**
|
*.log
|
||||||
/wwwroot/*.js.map
|
|
||||||
/wwwroot/*.js
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
/bower_components
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/.sass-cache
|
/.sass-cache
|
||||||
/connect.lock
|
/connect.lock
|
||||||
/coverage/*
|
/coverage/*
|
||||||
/libpeerconnection.log
|
|
||||||
npm-debug.log
|
|
||||||
testem.log
|
|
||||||
#/typings
|
|
||||||
/systemjs.config.js*
|
|
||||||
/Logs/**
|
/Logs/**
|
||||||
**.db
|
**.db
|
||||||
|
|
15
src/Ombi/.vscode/tasks.json
vendored
15
src/Ombi/.vscode/tasks.json
vendored
|
@ -4,7 +4,7 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"taskName": "restore",
|
"label": "restore",
|
||||||
"command": "npm",
|
"command": "npm",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -14,7 +14,16 @@
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"taskName": "build",
|
"label": "clean",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "shell",
|
||||||
|
"args": [
|
||||||
|
"clean"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -27,7 +36,7 @@
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"taskName": "lint",
|
"label": "lint",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "npm",
|
"command": "npm",
|
||||||
"args": [
|
"args": [
|
||||||
|
|
|
@ -94,9 +94,31 @@ namespace Ombi
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var identity = new GenericIdentity("API");
|
// Check if we have a UserName header if so we can impersonate that user
|
||||||
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
|
if (context.Request.Headers.Keys.Contains("UserName", StringComparer.InvariantCultureIgnoreCase))
|
||||||
context.User = principal;
|
{
|
||||||
|
var username = context.Request.Headers["UserName"].FirstOrDefault();
|
||||||
|
var um = context.RequestServices.GetService<OmbiUserManager>();
|
||||||
|
var user = await um.Users.FirstOrDefaultAsync(x =>
|
||||||
|
x.UserName.Equals(username, StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||||
|
await context.Response.WriteAsync("Invalid User");
|
||||||
|
await next.Invoke(context);
|
||||||
|
}
|
||||||
|
var roles = await um.GetRolesAsync(user);
|
||||||
|
var identity = new GenericIdentity(user.UserName);
|
||||||
|
var principal = new GenericPrincipal(identity, roles.ToArray());
|
||||||
|
context.User = principal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var identity = new GenericIdentity("API");
|
||||||
|
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
|
||||||
|
context.User = principal;
|
||||||
|
}
|
||||||
|
|
||||||
await next.Invoke(context);
|
await next.Invoke(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { animate, style, transition, trigger } from "@angular/animations";
|
import { animate, style, transition, trigger } from "@angular/animations";
|
||||||
import { AnimationEntryMetadata } from "@angular/core";
|
import { AnimationTriggerMetadata } from "@angular/animations";
|
||||||
|
|
||||||
export const fadeInOutAnimation: AnimationEntryMetadata = trigger("fadeInOut", [
|
export const fadeInOutAnimation: AnimationTriggerMetadata = trigger("fadeInOut", [
|
||||||
transition(":enter", [ // :enter is alias to 'void => *'
|
transition(":enter", [ // :enter is alias to 'void => *'
|
||||||
style({ opacity: 0 }),
|
style({ opacity: 0 }),
|
||||||
animate(1000, style({ opacity: 1 })),
|
animate(1000, style({ opacity: 1 })),
|
||||||
|
|
|
@ -134,6 +134,12 @@
|
||||||
<li [ngClass]="{'active': 'no' === translate.currentLang}">
|
<li [ngClass]="{'active': 'no' === translate.currentLang}">
|
||||||
<a (click)="translate.use('no')" [translate]="'NavigationBar.Language.Norwegian'"></a>
|
<a (click)="translate.use('no')" [translate]="'NavigationBar.Language.Norwegian'"></a>
|
||||||
</li>
|
</li>
|
||||||
|
<li [ngClass]="{'active': 'pt' === translate.currentLang}">
|
||||||
|
<a (click)="translate.use('pt')" [translate]="'NavigationBar.Language.BrazillianPortuguese'"></a>
|
||||||
|
</li>
|
||||||
|
<li [ngClass]="{'active': 'pl' === translate.currentLang}">
|
||||||
|
<a (click)="translate.use('pl')" [translate]="'NavigationBar.Language.Polish'"></a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -33,20 +33,20 @@ export class AppComponent implements OnInit {
|
||||||
private readonly jobService: JobService,
|
private readonly jobService: JobService,
|
||||||
public readonly translate: TranslateService,
|
public readonly translate: TranslateService,
|
||||||
private readonly identityService: IdentityService,
|
private readonly identityService: IdentityService,
|
||||||
private readonly platformLocation: PlatformLocation) {
|
private readonly platformLocation: PlatformLocation) {
|
||||||
|
|
||||||
const base = this.platformLocation.getBaseHrefFromDOM();
|
const base = this.platformLocation.getBaseHrefFromDOM();
|
||||||
if (base.length > 1) {
|
if (base.length > 1) {
|
||||||
__webpack_public_path__ = base + "/dist/";
|
__webpack_public_path__ = base + "/dist/";
|
||||||
}
|
}
|
||||||
|
|
||||||
this.translate.addLangs(["en", "de", "fr","da","es","it","nl","sv","no"]);
|
this.translate.addLangs(["en", "de", "fr", "da", "es", "it", "nl", "sv", "no", "pl", "pt"]);
|
||||||
// this language will be used as a fallback when a translation isn't found in the current language
|
// this language will be used as a fallback when a translation isn't found in the current language
|
||||||
this.translate.setDefaultLang("en");
|
this.translate.setDefaultLang("en");
|
||||||
|
|
||||||
// See if we can match the supported langs with the current browser lang
|
// See if we can match the supported langs with the current browser lang
|
||||||
const browserLang: string = translate.getBrowserLang();
|
const browserLang: string = translate.getBrowserLang();
|
||||||
this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl|sv|no/) ? browserLang : "en");
|
this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl|sv|no|pl|pt/) ? browserLang : "en");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
|
@ -88,8 +88,8 @@ export class AppComponent implements OnInit {
|
||||||
|
|
||||||
public openMobileApp(event: any) {
|
public openMobileApp(event: any) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if(!this.customizationSettings.applicationUrl) {
|
if (!this.customizationSettings.applicationUrl) {
|
||||||
this.notificationService.warning("Mobile","Please ask your admin to setup the Application URL!");
|
this.notificationService.warning("Mobile", "Please ask your admin to setup the Application URL!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import {CommonModule, PlatformLocation} from "@angular/common";
|
import { CommonModule, PlatformLocation } from "@angular/common";
|
||||||
import {HttpClient, HttpClientModule} from "@angular/common/http";
|
import { HttpClient, HttpClientModule } from "@angular/common/http";
|
||||||
import {NgModule} from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||||
import {HttpModule} from "@angular/http";
|
import { HttpModule } from "@angular/http";
|
||||||
import {MatButtonModule, MatCardModule, MatInputModule, MatTabsModule} from "@angular/material";
|
import { MatButtonModule, MatCardModule, MatInputModule, MatTabsModule } from "@angular/material";
|
||||||
import {BrowserModule} from "@angular/platform-browser";
|
import { BrowserModule } from "@angular/platform-browser";
|
||||||
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
|
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import {RouterModule, Routes} from "@angular/router";
|
import { RouterModule, Routes } from "@angular/router";
|
||||||
|
|
||||||
import { JwtModule } from "@auth0/angular-jwt";
|
import { JwtModule } from "@auth0/angular-jwt";
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import { TranslateLoader, TranslateModule } from "@ngx-translate/core";
|
||||||
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
||||||
import { CookieService } from "ng2-cookies";
|
import { CookieService } from "ng2-cookies";
|
||||||
import { GrowlModule } from "primeng/components/growl/growl";
|
import { GrowlModule } from "primeng/components/growl/growl";
|
||||||
import { ButtonModule, CaptchaModule, ConfirmationService, ConfirmDialogModule, DataTableModule,DialogModule, SharedModule, SidebarModule, TooltipModule } from "primeng/primeng";
|
import { ButtonModule, CaptchaModule, ConfirmationService, ConfirmDialogModule, DataTableModule, DialogModule, SharedModule, SidebarModule, TooltipModule } from "primeng/primeng";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { AppComponent } from "./app.component";
|
import { AppComponent } from "./app.component";
|
||||||
|
@ -36,7 +36,7 @@ import { ImageService } from "./services";
|
||||||
import { LandingPageService } from "./services";
|
import { LandingPageService } from "./services";
|
||||||
import { NotificationService } from "./services";
|
import { NotificationService } from "./services";
|
||||||
import { SettingsService } from "./services";
|
import { SettingsService } from "./services";
|
||||||
import { IssuesService, JobService, StatusService } from "./services";
|
import { IssuesService, JobService, PlexTvService, StatusService } from "./services";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: "*", component: PageNotFoundComponent },
|
{ path: "*", component: PageNotFoundComponent },
|
||||||
|
@ -67,6 +67,14 @@ export function HttpLoaderFactory(http: HttpClient, platformLocation: PlatformLo
|
||||||
return new TranslateHttpLoader(http, "/translations/", `.json?v=${version}`);
|
return new TranslateHttpLoader(http, "/translations/", `.json?v=${version}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function JwtTokenGetter() {
|
||||||
|
const token = localStorage.getItem("id_token");
|
||||||
|
if (!token) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forRoot(routes),
|
RouterModule.forRoot(routes),
|
||||||
|
@ -89,18 +97,12 @@ export function HttpLoaderFactory(http: HttpClient, platformLocation: PlatformLo
|
||||||
CaptchaModule,
|
CaptchaModule,
|
||||||
TooltipModule,
|
TooltipModule,
|
||||||
ConfirmDialogModule,
|
ConfirmDialogModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
JwtModule.forRoot({
|
JwtModule.forRoot({
|
||||||
config: {
|
config: {
|
||||||
tokenGetter: () => {
|
tokenGetter: JwtTokenGetter,
|
||||||
const token = localStorage.getItem("id_token");
|
|
||||||
if (!token) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
loader: {
|
loader: {
|
||||||
provide: TranslateLoader,
|
provide: TranslateLoader,
|
||||||
|
@ -119,7 +121,7 @@ export function HttpLoaderFactory(http: HttpClient, platformLocation: PlatformLo
|
||||||
TokenResetPasswordComponent,
|
TokenResetPasswordComponent,
|
||||||
CookieComponent,
|
CookieComponent,
|
||||||
LoginOAuthComponent,
|
LoginOAuthComponent,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
NotificationService,
|
NotificationService,
|
||||||
AuthService,
|
AuthService,
|
||||||
|
@ -133,6 +135,7 @@ export function HttpLoaderFactory(http: HttpClient, platformLocation: PlatformLo
|
||||||
CookieService,
|
CookieService,
|
||||||
JobService,
|
JobService,
|
||||||
IssuesService,
|
IssuesService,
|
||||||
|
PlexTvService,
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
export interface IUserLogin {
|
import { IPlexPin } from "../interfaces";
|
||||||
|
|
||||||
|
export interface IUserLogin {
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
rememberMe: boolean;
|
rememberMe: boolean;
|
||||||
usePlexOAuth: boolean;
|
usePlexOAuth: boolean;
|
||||||
|
plexTvPin: IPlexPin;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILocalUser {
|
export interface ILocalUser {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { PlatformLocation } from "@angular/common";
|
import { PlatformLocation } from "@angular/common";
|
||||||
import { HttpClient } from "@angular/common/http";
|
import { HttpClient } from "@angular/common/http";
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { JwtHelperService } from "@auth0/angular-jwt";
|
import { JwtHelperService } from "@auth0/angular-jwt";
|
||||||
import { Observable } from "rxjs/Rx";
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
import { ServiceHelpers } from "../services";
|
import { ServiceHelpers } from "../services";
|
||||||
import { ILocalUser, IUserLogin } from "./IUserLogin";
|
import { ILocalUser, IUserLogin } from "./IUserLogin";
|
||||||
|
@ -26,13 +26,13 @@ export class AuthService extends ServiceHelpers {
|
||||||
return this.http.post<boolean>(`${this.url}/requirePassword`, JSON.stringify(login), {headers: this.headers});
|
return this.http.post<boolean>(`${this.url}/requirePassword`, JSON.stringify(login), {headers: this.headers});
|
||||||
}
|
}
|
||||||
|
|
||||||
public loggedIn() {
|
public loggedIn() {
|
||||||
const token: string = this.jwtHelperService.tokenGetter();
|
const token: string = this.jwtHelperService.tokenGetter();
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenExpired: boolean = this.jwtHelperService.isTokenExpired(token);
|
const tokenExpired: boolean = this.jwtHelperService.isTokenExpired(token);
|
||||||
return !tokenExpired;
|
return !tokenExpired;
|
||||||
}
|
}
|
||||||
|
@ -53,9 +53,9 @@ export class AuthService extends ServiceHelpers {
|
||||||
} else {
|
} else {
|
||||||
u.roles.push(roles);
|
u.roles.push(roles);
|
||||||
}
|
}
|
||||||
return <ILocalUser>u;
|
return <ILocalUser> u;
|
||||||
}
|
}
|
||||||
return <ILocalUser>{};
|
return <ILocalUser> { };
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasRole(role: string): boolean {
|
public hasRole(role: string): boolean {
|
||||||
|
|
|
@ -11,7 +11,7 @@ export class CookieComponent implements OnInit {
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
const cookie = this.cookieService.getAll();
|
const cookie = this.cookieService.getAll();
|
||||||
if(cookie.Auth) {
|
if (cookie.Auth) {
|
||||||
const jwtVal = cookie.Auth;
|
const jwtVal = cookie.Auth;
|
||||||
localStorage.setItem("id_token", jwtVal);
|
localStorage.setItem("id_token", jwtVal);
|
||||||
this.router.navigate(["search"]);
|
this.router.navigate(["search"]);
|
||||||
|
|
|
@ -46,6 +46,7 @@ export interface IIssueComments {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IIssuesChat {
|
export interface IIssuesChat {
|
||||||
|
id: number;
|
||||||
comment: string;
|
comment: string;
|
||||||
date: Date;
|
date: Date;
|
||||||
username: string;
|
username: string;
|
||||||
|
|
|
@ -2,6 +2,16 @@
|
||||||
user: IPlexUser;
|
user: IPlexUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPlexPin {
|
||||||
|
id: number;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlexOAuthViewModel {
|
||||||
|
wizard: boolean;
|
||||||
|
pin: IPlexPin;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPlexOAuthAccessToken {
|
export interface IPlexOAuthAccessToken {
|
||||||
accessToken: string;
|
accessToken: string;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +34,19 @@ export interface IPlexLibResponse {
|
||||||
data: IPlexLibraries;
|
data: IPlexLibraries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPlexLibSimpleResponse {
|
||||||
|
successful: boolean;
|
||||||
|
message: string;
|
||||||
|
data: IPlexSection[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlexSection {
|
||||||
|
id: string;
|
||||||
|
key: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IMediaContainer {
|
export interface IMediaContainer {
|
||||||
directory: IDirectory[];
|
directory: IDirectory[];
|
||||||
}
|
}
|
||||||
|
@ -39,6 +62,28 @@ export interface IPlexServerViewModel {
|
||||||
servers: IPlexServerResult;
|
servers: IPlexServerResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPlexServerAddViewModel {
|
||||||
|
success: boolean;
|
||||||
|
servers: IPlexServersAdd[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlexServersAdd {
|
||||||
|
serverId: number;
|
||||||
|
machineId: string;
|
||||||
|
serverName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlexUserViewModel {
|
||||||
|
username: string;
|
||||||
|
machineIdentifier: string;
|
||||||
|
libsSelected: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlexUserAddResponse {
|
||||||
|
success: boolean;
|
||||||
|
error: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPlexServerResult {
|
export interface IPlexServerResult {
|
||||||
friendlyName: string;
|
friendlyName: string;
|
||||||
machineIdentifier: string;
|
machineIdentifier: string;
|
||||||
|
|
|
@ -20,7 +20,7 @@ export interface IRecentlyAddedTvShows extends IRecentlyAddedMovies {
|
||||||
|
|
||||||
export interface IRecentlyAddedRangeModel {
|
export interface IRecentlyAddedRangeModel {
|
||||||
from: Date;
|
from: Date;
|
||||||
to: Date;
|
to: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum RecentlyAddedType {
|
export enum RecentlyAddedType {
|
||||||
|
|
|
@ -71,6 +71,10 @@ export interface ITvRequests {
|
||||||
status: string;
|
status: string;
|
||||||
childRequests: IChildRequests[];
|
childRequests: IChildRequests[];
|
||||||
qualityOverride: number;
|
qualityOverride: number;
|
||||||
|
background: any;
|
||||||
|
totalSeasons: number;
|
||||||
|
tvDbId: number;
|
||||||
|
open: boolean; // THIS IS FOR THE UI
|
||||||
|
|
||||||
// For UI display
|
// For UI display
|
||||||
qualityOverrideTitle: string;
|
qualityOverrideTitle: string;
|
||||||
|
|
|
@ -28,8 +28,16 @@ export interface ISearchTvResult {
|
||||||
available: boolean;
|
available: boolean;
|
||||||
plexUrl: string;
|
plexUrl: string;
|
||||||
embyUrl: string;
|
embyUrl: string;
|
||||||
|
quality: string;
|
||||||
firstSeason: boolean;
|
firstSeason: boolean;
|
||||||
latestSeason: boolean;
|
latestSeason: boolean;
|
||||||
|
theTvDbId: string;
|
||||||
|
subscribed: boolean;
|
||||||
|
showSubscribe: boolean;
|
||||||
|
fullyAvailable: boolean;
|
||||||
|
partlyAvailable: boolean;
|
||||||
|
background: any;
|
||||||
|
open: boolean; // THIS IS FOR THE UI
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITvRequestViewModel {
|
export interface ITvRequestViewModel {
|
||||||
|
|
|
@ -27,6 +27,7 @@ export interface IUpdateSettings extends ISettings {
|
||||||
windowsService: boolean;
|
windowsService: boolean;
|
||||||
windowsServiceName: string;
|
windowsServiceName: string;
|
||||||
isWindows: boolean;
|
isWindows: boolean;
|
||||||
|
testMode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEmbySettings extends ISettings {
|
export interface IEmbySettings extends ISettings {
|
||||||
|
|
|
@ -23,6 +23,11 @@ export interface ICreateWizardUser {
|
||||||
usePlexAdminAccount: boolean;
|
usePlexAdminAccount: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IWizardUserResult {
|
||||||
|
result: boolean;
|
||||||
|
errors: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export enum UserType {
|
export enum UserType {
|
||||||
LocalUser = 1,
|
LocalUser = 1,
|
||||||
PlexUser = 2,
|
PlexUser = 2,
|
||||||
|
|
|
@ -51,15 +51,17 @@
|
||||||
<div *ngIf="comments" class="panel-body msg_container_base">
|
<div *ngIf="comments" class="panel-body msg_container_base">
|
||||||
<div *ngIf="comments.length <= 0" class="row msg_container base_receive">
|
<div *ngIf="comments.length <= 0" class="row msg_container base_receive">
|
||||||
<div class="col-md-10 col-xs-10">
|
<div class="col-md-10 col-xs-10">
|
||||||
<div class="messages msg_sent">
|
|
||||||
<p [translate]="'Issues.NoComments'"></p>
|
<div class="messages msg_sent">
|
||||||
|
<p [translate]="'Issues.NoComments'"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let comment of comments" class="row msg_container" [ngClass]="{'base_sent': comment.adminComment, 'base_receive': !comment.adminComment}">
|
<div *ngFor="let comment of comments" class="row msg_container" [ngClass]="{'base_sent': comment.adminComment, 'base_receive': !comment.adminComment}">
|
||||||
<div class="col-md-10 col-xs-10">
|
<div class="col-md-10 col-xs-10">
|
||||||
<div class="messages msg_sent">
|
|
||||||
|
<div class="messages msg_sent"> <i *ngIf="isAdmin" style="float:right;" class="fa fa-times" aria-hidden="true" (click)="deleteComment(comment.id)"></i>
|
||||||
<p>{{comment.comment}}</p>
|
<p>{{comment.comment}}</p>
|
||||||
<time>{{comment.username}} • {{comment.date | date:'short'}}</time>
|
<time>{{comment.username}} • {{comment.date | date:'short'}}</time>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -37,10 +37,10 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private imageService: ImageService,
|
private imageService: ImageService,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
private readonly platformLocation: PlatformLocation) {
|
private readonly platformLocation: PlatformLocation) {
|
||||||
this.route.params
|
this.route.params
|
||||||
.subscribe((params: any) => {
|
.subscribe((params: any) => {
|
||||||
this.issueId = parseInt(params.id);
|
this.issueId = parseInt(params.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.isAdmin = this.authService.hasRole("Admin") || this.authService.hasRole("PowerUser");
|
this.isAdmin = this.authService.hasRole("Admin") || this.authService.hasRole("PowerUser");
|
||||||
|
@ -53,8 +53,8 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
this.defaultPoster = "../../../images/";
|
this.defaultPoster = "../../../images/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.issueService.getIssue(this.issueId).subscribe(x => {
|
this.issueService.getIssue(this.issueId).subscribe(x => {
|
||||||
this.issue = {
|
this.issue = {
|
||||||
comments: x.comments,
|
comments: x.comments,
|
||||||
|
@ -63,8 +63,8 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
issueCategoryId: x.issueCategoryId,
|
issueCategoryId: x.issueCategoryId,
|
||||||
subject: x.subject,
|
subject: x.subject,
|
||||||
description: x.description,
|
description: x.description,
|
||||||
status:x.status,
|
status: x.status,
|
||||||
resolvedDate:x.resolvedDate,
|
resolvedDate: x.resolvedDate,
|
||||||
title: x.title,
|
title: x.title,
|
||||||
requestType: x.requestType,
|
requestType: x.requestType,
|
||||||
requestId: x.requestId,
|
requestId: x.requestId,
|
||||||
|
@ -97,6 +97,13 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public deleteComment(id: number) {
|
||||||
|
this.issueService.deleteComment(id).subscribe(x => {
|
||||||
|
this.loadComments();
|
||||||
|
this.notificationService.success("Comment Deleted");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private loadComments() {
|
private loadComments() {
|
||||||
this.issueService.getComments(this.issueId).subscribe(x => this.comments = x);
|
this.issueService.getComments(this.issueId).subscribe(x => this.comments = x);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +124,7 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.imageService.getTvBackground(Number(issue.providerId)).subscribe(x => {
|
this.imageService.getTvBackground(Number(issue.providerId)).subscribe(x => {
|
||||||
if(x) {
|
if (x) {
|
||||||
this.backgroundPath = this.sanitizer.bypassSecurityTrustStyle
|
this.backgroundPath = this.sanitizer.bypassSecurityTrustStyle
|
||||||
("url(" + x + ")");
|
("url(" + x + ")");
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ export class IssuesComponent implements OnInit {
|
||||||
|
|
||||||
constructor(private issueService: IssuesService) { }
|
constructor(private issueService: IssuesService) { }
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.getPending();
|
this.getPending();
|
||||||
this.getInProg();
|
this.getInProg();
|
||||||
this.getResolved();
|
this.getResolved();
|
||||||
this.issueService.getIssuesCount().subscribe(x => this.count = x);
|
this.issueService.getIssuesCount().subscribe(x => this.count = x);
|
||||||
|
@ -61,5 +61,4 @@ export class IssuesComponent implements OnInit {
|
||||||
this.resolvedIssues = x;
|
this.resolvedIssues = x;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ export class IssuesTableComponent {
|
||||||
@Input() public issues: IIssues[];
|
@Input() public issues: IIssues[];
|
||||||
@Input() public totalRecords: number;
|
@Input() public totalRecords: number;
|
||||||
|
|
||||||
@Output() public changePage = new EventEmitter<IPagenator>();
|
@Output() public changePage = new EventEmitter<IPagenator>();
|
||||||
|
|
||||||
public IssueStatus = IssueStatus;
|
public IssueStatus = IssueStatus;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ export class IssuesTableComponent {
|
||||||
//event.rows = Number of rows to display in new page
|
//event.rows = Number of rows to display in new page
|
||||||
//event.page = Index of the new page
|
//event.page = Index of the new page
|
||||||
//event.pageCount = Total number of pages
|
//event.pageCount = Total number of pages
|
||||||
|
|
||||||
this.changePage.emit(event);
|
this.changePage.emit(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { TranslateService } from "@ngx-translate/core";
|
||||||
import { PlatformLocation } from "@angular/common";
|
import { PlatformLocation } from "@angular/common";
|
||||||
import { AuthService } from "../auth/auth.service";
|
import { AuthService } from "../auth/auth.service";
|
||||||
import { IAuthenticationSettings, ICustomizationSettings } from "../interfaces";
|
import { IAuthenticationSettings, ICustomizationSettings } from "../interfaces";
|
||||||
import { NotificationService } from "../services";
|
import { NotificationService, PlexTvService } from "../services";
|
||||||
import { SettingsService } from "../services";
|
import { SettingsService } from "../services";
|
||||||
import { StatusService } from "../services";
|
import { StatusService } from "../services";
|
||||||
|
|
||||||
|
@ -30,9 +30,10 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
public landingFlag: boolean;
|
public landingFlag: boolean;
|
||||||
public baseUrl: string;
|
public baseUrl: string;
|
||||||
public loginWithOmbi: boolean;
|
public loginWithOmbi: boolean;
|
||||||
|
public pinTimer: any;
|
||||||
|
|
||||||
public get appName(): string {
|
public get appName(): string {
|
||||||
if(this.customizationSettings.applicationName) {
|
if (this.customizationSettings.applicationName) {
|
||||||
return this.customizationSettings.applicationName;
|
return this.customizationSettings.applicationName;
|
||||||
} else {
|
} else {
|
||||||
return "Ombi";
|
return "Ombi";
|
||||||
|
@ -40,13 +41,14 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private timer: any;
|
private timer: any;
|
||||||
|
private clientId: string;
|
||||||
|
|
||||||
private errorBody: string;
|
private errorBody: string;
|
||||||
private errorValidation: string;
|
private errorValidation: string;
|
||||||
|
|
||||||
constructor(private authService: AuthService, private router: Router, private notify: NotificationService, private status: StatusService,
|
constructor(private authService: AuthService, private router: Router, private notify: NotificationService, private status: StatusService,
|
||||||
private fb: FormBuilder, private settingsService: SettingsService, private images: ImageService, private sanitizer: DomSanitizer,
|
private fb: FormBuilder, private settingsService: SettingsService, private images: ImageService, private sanitizer: DomSanitizer,
|
||||||
private route: ActivatedRoute, private location: PlatformLocation, private readonly translate: TranslateService) {
|
private route: ActivatedRoute, private location: PlatformLocation, private translate: TranslateService, private plexTv: PlexTvService) {
|
||||||
this.route.params
|
this.route.params
|
||||||
.subscribe((params: any) => {
|
.subscribe((params: any) => {
|
||||||
this.landingFlag = params.landing;
|
this.landingFlag = params.landing;
|
||||||
|
@ -71,20 +73,21 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(authService.loggedIn()) {
|
if (authService.loggedIn()) {
|
||||||
this.router.navigate(["search"]);
|
this.router.navigate(["search"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.settingsService.getAuthentication().subscribe(x => this.authenticationSettings = x);
|
this.settingsService.getAuthentication().subscribe(x => this.authenticationSettings = x);
|
||||||
|
this.settingsService.getClientId().subscribe(x => this.clientId = x);
|
||||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
||||||
this.images.getRandomBackground().subscribe(x => {
|
this.images.getRandomBackground().subscribe(x => {
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")");
|
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")");
|
||||||
});
|
});
|
||||||
this.timer = setInterval(() => {
|
this.timer = setInterval(() => {
|
||||||
this.cycleBackground();
|
this.cycleBackground();
|
||||||
}, 10000);
|
}, 7000);
|
||||||
|
|
||||||
const base = this.location.getBaseHrefFromDOM();
|
const base = this.location.getBaseHrefFromDOM();
|
||||||
if (base.length > 1) {
|
if (base.length > 1) {
|
||||||
|
@ -101,9 +104,9 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const value = form.value;
|
const value = form.value;
|
||||||
const user = { password: value.password, username: value.username, rememberMe: value.rememberMe, usePlexOAuth: false };
|
const user = { password: value.password, username: value.username, rememberMe: value.rememberMe, usePlexOAuth: false, plexTvPin: { id: 0, code: "" } };
|
||||||
this.authService.requiresPassword(user).subscribe(x => {
|
this.authService.requiresPassword(user).subscribe(x => {
|
||||||
if(x && this.authenticationSettings.allowNoPassword) {
|
if (x && this.authenticationSettings.allowNoPassword) {
|
||||||
// Looks like this user requires a password
|
// Looks like this user requires a password
|
||||||
this.authenticationSettings.allowNoPassword = false;
|
this.authenticationSettings.allowNoPassword = false;
|
||||||
return;
|
return;
|
||||||
|
@ -113,6 +116,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
localStorage.setItem("id_token", x.access_token);
|
localStorage.setItem("id_token", x.access_token);
|
||||||
|
|
||||||
if (this.authService.loggedIn()) {
|
if (this.authService.loggedIn()) {
|
||||||
|
this.ngOnDestroy();
|
||||||
this.router.navigate(["search"]);
|
this.router.navigate(["search"]);
|
||||||
} else {
|
} else {
|
||||||
this.notify.error(this.errorBody);
|
this.notify.error(this.errorBody);
|
||||||
|
@ -123,28 +127,58 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public oauth() {
|
public oauth() {
|
||||||
this.authService.login({usePlexOAuth: true, password:"",rememberMe:true,username:""}).subscribe(x => {
|
this.plexTv.GetPin(this.clientId, this.appName).subscribe((pin: any) => {
|
||||||
if (window.frameElement) {
|
|
||||||
// in frame
|
this.authService.login({ usePlexOAuth: true, password: "", rememberMe: true, username: "", plexTvPin: pin }).subscribe(x => {
|
||||||
window.open(x.url, "_blank");
|
|
||||||
} else {
|
window.open(x.url, "_blank", `toolbar=0,
|
||||||
// not in frame
|
location=0,
|
||||||
window.location.href = x.url;
|
status=0,
|
||||||
}
|
menubar=0,
|
||||||
|
scrollbars=1,
|
||||||
|
resizable=1,
|
||||||
|
width=500,
|
||||||
|
height=500`);
|
||||||
|
|
||||||
|
this.pinTimer = setInterval(() => {
|
||||||
|
this.notify.info("Authenticating", "Loading... Please Wait");
|
||||||
|
this.getPinResult(x.pinId);
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getPinResult(pinId: number) {
|
||||||
|
this.authService.oAuth(pinId).subscribe(x => {
|
||||||
|
if(x.access_token) {
|
||||||
|
localStorage.setItem("id_token", x.access_token);
|
||||||
|
|
||||||
|
if (this.authService.loggedIn()) {
|
||||||
|
this.ngOnDestroy();
|
||||||
|
this.router.navigate(["search"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, err => {
|
||||||
|
this.notify.error(err.statusText);
|
||||||
|
|
||||||
|
this.router.navigate(["login"]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public ngOnDestroy() {
|
public ngOnDestroy() {
|
||||||
clearInterval(this.timer);
|
clearInterval(this.timer);
|
||||||
|
clearInterval(this.pinTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private cycleBackground() {
|
private cycleBackground() {
|
||||||
this.images.getRandomBackground().subscribe(x => {
|
this.images.getRandomBackground().subscribe(x => {
|
||||||
this.background = "";
|
this.background = "";
|
||||||
});
|
});
|
||||||
this.images.getRandomBackground().subscribe(x => {
|
this.images.getRandomBackground().subscribe(x => {
|
||||||
this.background = this.sanitizer
|
this.background = this.sanitizer
|
||||||
.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%), url(" + x.url + ")");
|
.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%), url(" + x.url + ")");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ export class LoginOAuthComponent implements OnInit {
|
||||||
this.route.params
|
this.route.params
|
||||||
.subscribe((params: any) => {
|
.subscribe((params: any) => {
|
||||||
this.pin = params.pin;
|
this.pin = params.pin;
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,21 +25,20 @@ export class LoginOAuthComponent implements OnInit {
|
||||||
|
|
||||||
public auth() {
|
public auth() {
|
||||||
this.authService.oAuth(this.pin).subscribe(x => {
|
this.authService.oAuth(this.pin).subscribe(x => {
|
||||||
if(x.access_token) {
|
if (x.access_token) {
|
||||||
localStorage.setItem("id_token", x.access_token);
|
localStorage.setItem("id_token", x.access_token);
|
||||||
|
|
||||||
if (this.authService.loggedIn()) {
|
if (this.authService.loggedIn()) {
|
||||||
this.router.navigate(["search"]);
|
this.router.navigate(["search"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(x.errorMessage) {
|
if (x.errorMessage) {
|
||||||
this.error = x.errorMessage;
|
this.error = x.errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
}, err => {
|
}, err => {
|
||||||
this.notify.error(err.statusText);
|
this.notify.error(err.statusText);
|
||||||
|
|
||||||
this.router.navigate(["login"]);
|
this.router.navigate(["login"]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
import { DomSanitizer } from "@angular/platform-browser";
|
||||||
|
|
||||||
import { ICustomizationSettings } from "../interfaces";
|
import { ICustomizationSettings } from "../interfaces";
|
||||||
import { IdentityService, ImageService,NotificationService, SettingsService } from "../services";
|
import { IdentityService, ImageService, NotificationService, SettingsService } from "../services";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./resetpassword.component.html",
|
templateUrl: "./resetpassword.component.html",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { NguCarousel } from "@ngu/carousel";
|
import { NguCarouselConfig } from "@ngu/carousel";
|
||||||
|
|
||||||
import { ImageService, RecentlyAddedService } from "../services";
|
import { ImageService, RecentlyAddedService } from "../services";
|
||||||
import { IRecentlyAddedMovies, IRecentlyAddedTvShows } from "./../interfaces";
|
import { IRecentlyAddedMovies, IRecentlyAddedTvShows } from "./../interfaces";
|
||||||
|
@ -41,13 +41,13 @@ export class RecentlyAddedComponent implements OnInit {
|
||||||
public range: Date[];
|
public range: Date[];
|
||||||
|
|
||||||
public groupTv: boolean = false;
|
public groupTv: boolean = false;
|
||||||
|
|
||||||
// https://github.com/sheikalthaf/ngu-carousel
|
// https://github.com/sheikalthaf/ngu-carousel
|
||||||
public carouselTile: NguCarousel;
|
public carouselTile: NguCarouselConfig;
|
||||||
|
|
||||||
constructor(private recentlyAddedService: RecentlyAddedService,
|
constructor(private recentlyAddedService: RecentlyAddedService,
|
||||||
private imageService: ImageService) {}
|
private imageService: ImageService) {}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.getMovies();
|
this.getMovies();
|
||||||
this.getShows();
|
this.getShows();
|
||||||
|
@ -67,10 +67,10 @@ export class RecentlyAddedComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public close() {
|
||||||
if(this.range.length < 2) {
|
if (this.range.length < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!this.range[1]) {
|
if (!this.range[1]) {
|
||||||
// If we do not have a second date then just set it to now
|
// If we do not have a second date then just set it to now
|
||||||
this.range[1] = new Date();
|
this.range[1] = new Date();
|
||||||
}
|
}
|
||||||
|
@ -82,13 +82,13 @@ export class RecentlyAddedComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getShows() {
|
private getShows() {
|
||||||
if(this.groupTv) {
|
if (this.groupTv) {
|
||||||
this.recentlyAddedService.getRecentlyAddedTvGrouped().subscribe(x => {
|
this.recentlyAddedService.getRecentlyAddedTvGrouped().subscribe(x => {
|
||||||
this.tv = x;
|
this.tv = x;
|
||||||
|
|
||||||
this.tv.forEach((t) => {
|
this.tv.forEach((t) => {
|
||||||
this.imageService.getTvPoster(t.tvDbId).subscribe(p => {
|
this.imageService.getTvPoster(t.tvDbId).subscribe(p => {
|
||||||
if(p) {
|
if (p) {
|
||||||
t.posterPath = p;
|
t.posterPath = p;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -97,10 +97,10 @@ export class RecentlyAddedComponent implements OnInit {
|
||||||
} else {
|
} else {
|
||||||
this.recentlyAddedService.getRecentlyAddedTv().subscribe(x => {
|
this.recentlyAddedService.getRecentlyAddedTv().subscribe(x => {
|
||||||
this.tv = x;
|
this.tv = x;
|
||||||
|
|
||||||
this.tv.forEach((t) => {
|
this.tv.forEach((t) => {
|
||||||
this.imageService.getTvPoster(t.tvDbId).subscribe(p => {
|
this.imageService.getTvPoster(t.tvDbId).subscribe(p => {
|
||||||
if(p) {
|
if (p) {
|
||||||
t.posterPath = p;
|
t.posterPath = p;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -114,11 +114,11 @@ export class RecentlyAddedComponent implements OnInit {
|
||||||
this.movies = x;
|
this.movies = x;
|
||||||
|
|
||||||
this.movies.forEach((movie) => {
|
this.movies.forEach((movie) => {
|
||||||
if(movie.theMovieDbId) {
|
if (movie.theMovieDbId) {
|
||||||
this.imageService.getMoviePoster(movie.theMovieDbId).subscribe(p => {
|
this.imageService.getMoviePoster(movie.theMovieDbId).subscribe(p => {
|
||||||
movie.posterPath = p;
|
movie.posterPath = p;
|
||||||
});
|
});
|
||||||
} else if(movie.imdbId) {
|
} else if (movie.imdbId) {
|
||||||
this.imageService.getMoviePoster(movie.imdbId).subscribe(p => {
|
this.imageService.getMoviePoster(movie.imdbId).subscribe(p => {
|
||||||
movie.posterPath = p;
|
movie.posterPath = p;
|
||||||
});
|
});
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue