mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-22 14:13:36 -07:00
Merge branch 'develop' into recently-requested
This commit is contained in:
commit
32cbff19b0
595 changed files with 43308 additions and 10538 deletions
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
|
@ -3,6 +3,7 @@ name: CI Build
|
|||
on:
|
||||
push:
|
||||
branches: [ develop, master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-ui:
|
||||
|
@ -38,7 +39,7 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v2
|
||||
|
@ -67,7 +68,7 @@ jobs:
|
|||
uses: TriPSs/conventional-changelog-action@v3
|
||||
with:
|
||||
version-file: 'version.json'
|
||||
release-count: 20
|
||||
release-count: 40
|
||||
skip-on-empty: 'false'
|
||||
git-message: 'chore(release): :rocket: {version}'
|
||||
|
||||
|
@ -103,6 +104,12 @@ jobs:
|
|||
format: tar.gz
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v2
|
||||
|
@ -183,6 +190,7 @@ jobs:
|
|||
if: contains(github.ref, 'develop')
|
||||
with:
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
body: ${{ needs.versioning.outputs.changelog }}
|
||||
name: ${{ needs.versioning.outputs.tag }}
|
||||
tag_name: ${{ needs.versioning.outputs.tag }}
|
||||
|
|
47
.github/workflows/chromatic.yml
vendored
Normal file
47
.github/workflows/chromatic.yml
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
name: 'Chromatic'
|
||||
|
||||
# Event for the workflow
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
# List of jobs
|
||||
jobs:
|
||||
storybook-build:
|
||||
# Operating System
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: NodeModules Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node_modules-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: ./src/Ombi/ClientApp
|
||||
run: yarn
|
||||
|
||||
- name: Publish to Chromatic
|
||||
if: github.ref != 'refs/heads/master'
|
||||
uses: chromaui/action@v1
|
||||
with:
|
||||
projectToken: 7c47e1a1a4bd
|
||||
exitZeroOnChanges: true
|
||||
workingDir: ./src/Ombi/ClientApp
|
||||
buildScriptName: storybookbuild
|
||||
exitOnceUploaded: true
|
||||
|
||||
- name: Publish to Chromatic and auto accept changes
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: chromaui/action@v1
|
||||
with:
|
||||
projectToken: 7c47e1a1a4bd
|
||||
autoAcceptChanges: true # 👈 Option to accept all changes
|
||||
workingDir: ./src/Ombi/ClientApp
|
||||
buildScriptName: storybookbuild
|
||||
exitOnceUploaded: true
|
17
.github/workflows/cypress.yml
vendored
17
.github/workflows/cypress.yml
vendored
|
@ -7,6 +7,7 @@ on:
|
|||
branches: [ develop ]
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
automation-tests:
|
||||
|
@ -18,7 +19,7 @@ jobs:
|
|||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.x
|
||||
dotnet-version: 6.0.x
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
|
@ -33,15 +34,17 @@ jobs:
|
|||
- name: Install Frontend Deps
|
||||
run: yarn --cwd ./src/Ombi/ClientApp install
|
||||
|
||||
- name: Start Frontend
|
||||
run: |
|
||||
nohup yarn --cwd ./src/Ombi/ClientApp start &
|
||||
|
||||
- name: Install Automation Deps
|
||||
run: yarn --cwd ./tests install
|
||||
|
||||
- name: Start Backend
|
||||
run: |
|
||||
nohup dotnet run -p ./src/Ombi -- --host http://*:3577 &
|
||||
- name: Start Frontend
|
||||
run: |
|
||||
nohup yarn --cwd ./src/Ombi/ClientApp start &
|
||||
nohup dotnet run --project ./src/Ombi -- --host http://*:3577 &
|
||||
|
||||
- name: Cypress Tests
|
||||
uses: cypress-io/github-action@v2.8.2
|
||||
with:
|
||||
|
@ -50,8 +53,8 @@ jobs:
|
|||
headless: true
|
||||
working-directory: tests
|
||||
wait-on: http://localhost:3577/
|
||||
# 7 minutes
|
||||
wait-on-timeout: 420
|
||||
# 10 minutes
|
||||
wait-on-timeout: 600
|
||||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
3
.github/workflows/issue-check.yml
vendored
3
.github/workflows/issue-check.yml
vendored
|
@ -8,9 +8,6 @@ jobs:
|
|||
issueCheck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Output version
|
||||
run: |
|
||||
echo "log: ${{ github.event.issue.body }}"
|
||||
|
||||
- if: startsWith(github.event.issue.body , '**Describe the bug**') == false
|
||||
name: Close Issue
|
||||
|
|
2
.github/workflows/label.yml
vendored
2
.github/workflows/label.yml
vendored
|
@ -8,6 +8,8 @@
|
|||
name: Labeler
|
||||
on: [pull_request]
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
label:
|
||||
|
||||
|
|
14
.github/workflows/pr.yml
vendored
14
.github/workflows/pr.yml
vendored
|
@ -3,6 +3,12 @@ name: PR Build
|
|||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
repository-projects: write
|
||||
|
||||
jobs:
|
||||
build-ui:
|
||||
|
@ -27,11 +33,12 @@ jobs:
|
|||
|
||||
unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v2
|
||||
|
@ -44,7 +51,7 @@ jobs:
|
|||
- name: Run Unit Tests
|
||||
run: |
|
||||
cd src
|
||||
dotnet test --logger trx --results-directory "TestResults"
|
||||
dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx"
|
||||
|
||||
analysis:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -89,6 +96,9 @@ jobs:
|
|||
format: tar.gz
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v2
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -251,3 +251,4 @@ _Pvt_Extensions
|
|||
/src/Ombi/databases.json
|
||||
/src/Ombi/healthchecksdb
|
||||
/src/Ombi/ClientApp/package-lock.json
|
||||
/src/Ombi.Core/Properties/launchSettings.json
|
||||
|
|
7
.mergify.yml
Normal file
7
.mergify.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
pull_request_rules:
|
||||
- name: Automatic merge on approval
|
||||
conditions:
|
||||
- "#approved-reviews-by>=1"
|
||||
actions:
|
||||
merge:
|
||||
method: merge
|
359
CHANGELOG.md
359
CHANGELOG.md
|
@ -1,62 +1,361 @@
|
|||
## [4.3.3](https://github.com/Ombi-app/Ombi/compare/v4.3.2...v4.3.3) (2021-11-05)
|
||||
|
||||
|
||||
|
||||
## [4.3.2](https://github.com/Ombi-app/Ombi/compare/v4.3.1...v4.3.2) (2021-11-02)
|
||||
## [4.22.3](https://github.com/Ombi-app/Ombi/compare/v4.22.2...v4.22.3) (2022-07-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **translations:** 🌐 Localization - Ensuring all of the app including backend are localized [#4366](https://github.com/Ombi-app/Ombi/issues/4366) ([5e140ab](https://github.com/Ombi-app/Ombi/commit/5e140ab6183b887a7665f5e870eb0bd05d487ace))
|
||||
* Override Sonarr V3 Profiles endpoint ([#4678](https://github.com/Ombi-app/Ombi/issues/4678)) ([875da95](https://github.com/Ombi-app/Ombi/commit/875da959f353119b05138d68ee6d32a49e14b91e))
|
||||
|
||||
|
||||
|
||||
## [4.3.1](https://github.com/Ombi-app/Ombi/compare/v4.3.0...v4.3.1) (2021-10-27)
|
||||
## [4.22.2](https://github.com/Ombi-app/Ombi/compare/v4.22.1...v4.22.2) (2022-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* :bug: Hides no results message during search. ([#4375](https://github.com/Ombi-app/Ombi/issues/4375)) ([b819b0e](https://github.com/Ombi-app/Ombi/commit/b819b0e007e578bf3d8425f19591f87029c64d06))
|
||||
* fixed an issue where I broke images for some users ([81ddc85](https://github.com/Ombi-app/Ombi/commit/81ddc8553b9094c3f6843b036daebb2eb9262e00))
|
||||
|
||||
|
||||
|
||||
# [4.3.0](https://github.com/Ombi-app/Ombi/compare/v4.2.13...v4.3.0) (2021-10-20)
|
||||
## [4.22.1](https://github.com/Ombi-app/Ombi/compare/v4.22.0...v4.22.1) (2022-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([b0f3abb](https://github.com/Ombi-app/Ombi/commit/b0f3abb9ceebdbe5d6c20af98b7355df2999eb58))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([77d017b](https://github.com/Ombi-app/Ombi/commit/77d017b3d8ffd1714a2f6efecc8c900d56d062e4))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([f6e9784](https://github.com/Ombi-app/Ombi/commit/f6e9784367d3678d899ed79bef6caa52005b6661))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([601a877](https://github.com/Ombi-app/Ombi/commit/601a87762a2ad393ee5fa2fe52052ceeeefb1bef))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([a4a80ba](https://github.com/Ombi-app/Ombi/commit/a4a80ba4da49733a65e691003646c0f349bd4c5f))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([2961319](https://github.com/Ombi-app/Ombi/commit/2961319f61e95b2871480152b86ddca3375576a1))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([fc8d108](https://github.com/Ombi-app/Ombi/commit/fc8d108b660d53f499538328bfc271b05ac47d2b))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([1e03651](https://github.com/Ombi-app/Ombi/commit/1e03651c3b0eb77e45f9f6c55d31ee672eacd51e))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([c0dd327](https://github.com/Ombi-app/Ombi/commit/c0dd327426514e305a88750d7c3deb21c194108f))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([2156129](https://github.com/Ombi-app/Ombi/commit/2156129f175335746f204bb123035c070f518e96))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([aef0368](https://github.com/Ombi-app/Ombi/commit/aef0368de3aec306245bd1b16bc0de596a20d451))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([a38090b](https://github.com/Ombi-app/Ombi/commit/a38090b8dde17d1d150af0bca2830ea45d013a0e))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([c5f1d33](https://github.com/Ombi-app/Ombi/commit/c5f1d3355758a5c3648479d44e50397c7f6c1a9d))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([3846d56](https://github.com/Ombi-app/Ombi/commit/3846d56a6e561a1b1dc65c385151d90fdd6217ee))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([dafe9c1](https://github.com/Ombi-app/Ombi/commit/dafe9c1a19d84f00c13f0a51ba90927c24282926))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([edb418a](https://github.com/Ombi-app/Ombi/commit/edb418a6f05887c68a0c24c48decc691996f97e4))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([dadabf9](https://github.com/Ombi-app/Ombi/commit/dadabf93e1582a0c39321fd9bf3de3fb11e3f406))
|
||||
* **discover:** :bug: Created new Image component to handle 429's from TMDB ([#4698](https://github.com/Ombi-app/Ombi/issues/4698)) and fixed [#4635](https://github.com/Ombi-app/Ombi/issues/4635) ([#4699](https://github.com/Ombi-app/Ombi/issues/4699)) ([f22d3da](https://github.com/Ombi-app/Ombi/commit/f22d3da765799365455b919027f7563e52b347c3))
|
||||
|
||||
|
||||
|
||||
# [4.22.0](https://github.com/Ombi-app/Ombi/compare/v4.21.2...v4.22.0) (2022-07-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **request-limits:** :sparkles: Added the new request limit options into the user importer ([01d4f4d](https://github.com/Ombi-app/Ombi/commit/01d4f4d718fe85ac181dae52565fb1b427965b4f))
|
||||
* **request-limits:** :sparkles: Added the new request limit options to the bulk edit ([03bc23a](https://github.com/Ombi-app/Ombi/commit/03bc23a74e4308aa6b4c6b25636edcdeb65c1f0e))
|
||||
* **discover:** ✨ Added infinite scroll on advanced search results ([898bc89](https://github.com/Ombi-app/Ombi/commit/898bc89fa78245c1f3de9481f6c724f087a16e39))
|
||||
|
||||
|
||||
|
||||
## [4.2.13](https://github.com/Ombi-app/Ombi/compare/v4.2.12...v4.2.13) (2021-10-20)
|
||||
## [4.21.2](https://github.com/Ombi-app/Ombi/compare/v4.21.1...v4.21.2) (2022-07-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **translations:** 🌐 New translations %two_letters_code% from Crowdin [skip ci] ([8fbd267](https://github.com/Ombi-app/Ombi/commit/8fbd267b516ddaa80fd16c091bae532b860fbf45))
|
||||
* Landing and Login page improvements ([#4690](https://github.com/Ombi-app/Ombi/issues/4690)) ([6d423b5](https://github.com/Ombi-app/Ombi/commit/6d423b5447c52c5e59d8d2bd92a23b47468eb736))
|
||||
|
||||
|
||||
|
||||
## [4.21.1](https://github.com/Ombi-app/Ombi/compare/v4.21.0...v4.21.1) (2022-07-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **images:** Retry images with a backoff when we get a Too Many requests from TheMovieDb [#4685](https://github.com/Ombi-app/Ombi/issues/4685) ([3f1f35d](https://github.com/Ombi-app/Ombi/commit/3f1f35df3164db6739691cdda8f925c296239791))
|
||||
|
||||
|
||||
|
||||
# [4.21.0](https://github.com/Ombi-app/Ombi/compare/v4.20.4...v4.21.0) (2022-06-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Upgrade to Angular14 ([#4668](https://github.com/Ombi-app/Ombi/issues/4668)) ([b9d55a4](https://github.com/Ombi-app/Ombi/commit/b9d55a469b412558cbf67c1e25db7fdda5964cd8))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* stop populating obsolete subscribe fields ([#4625](https://github.com/Ombi-app/Ombi/issues/4625)) ([9a73463](https://github.com/Ombi-app/Ombi/commit/9a734637665f671b17c2bb440d93b35a891c142b))
|
||||
|
||||
|
||||
|
||||
## [4.20.4](https://github.com/Ombi-app/Ombi/compare/v4.20.3...v4.20.4) (2022-06-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fixed build ([f877921](https://github.com/Ombi-app/Ombi/commit/f8779219146051ea74f8b6408658ff7975afb88b))
|
||||
|
||||
|
||||
|
||||
## [4.20.3](https://github.com/Ombi-app/Ombi/compare/v4.20.2...v4.20.3) (2022-06-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **plex:** 🐛 Fixed an issue with the Plex Sync ([ab1a11a](https://github.com/Ombi-app/Ombi/commit/ab1a11af78efbe9d37bd55aa80a640796c138a98))
|
||||
|
||||
|
||||
|
||||
## [4.20.2](https://github.com/Ombi-app/Ombi/compare/v4.20.1...v4.20.2) (2022-06-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* :bug: Fixed the Request on Behalf of having blanks ([#4667](https://github.com/Ombi-app/Ombi/issues/4667)) ([7dd9b1c](https://github.com/Ombi-app/Ombi/commit/7dd9b1cac07f571dd35b362544e4fe0226c4b817))
|
||||
|
||||
|
||||
|
||||
## [4.20.1](https://github.com/Ombi-app/Ombi/compare/v4.20.0...v4.20.1) (2022-05-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* added media type tag to media type text ([#4638](https://github.com/Ombi-app/Ombi/issues/4638)) ([fe501d3](https://github.com/Ombi-app/Ombi/commit/fe501d34a0c36ac9f000b107eca49dbc6694d006))
|
||||
* **API:** Fix pagination in some edge cases ([#4649](https://github.com/Ombi-app/Ombi/issues/4649)) ([a70bf8f](https://github.com/Ombi-app/Ombi/commit/a70bf8f46c76d74c9dfdf908c53bd9955ca0a35d))
|
||||
* **discover:** Carousel touch not working when scrolling page and recommendations and similar movie navigation ([#4633](https://github.com/Ombi-app/Ombi/issues/4633)) ([d5ef1d5](https://github.com/Ombi-app/Ombi/commit/d5ef1d53e5f77d19dba8b8059c80b538a3e14f2a))
|
||||
* Improve Swagger documentation ([#4652](https://github.com/Ombi-app/Ombi/issues/4652)) ([181892b](https://github.com/Ombi-app/Ombi/commit/181892bcfe88e6d76febf49ef57745d04552d08e))
|
||||
* Missing Poster broken link fix ([#4637](https://github.com/Ombi-app/Ombi/issues/4637)) ([4070f0d](https://github.com/Ombi-app/Ombi/commit/4070f0d093b1c92487a1c80cabad8283a9650f51))
|
||||
* **sickrage:** Fixed issue with incorrect handling of SiCKRAGE episode results returned during episode status changes, now expects array of objects from data path if present ([#4648](https://github.com/Ombi-app/Ombi/issues/4648)) ([6d16442](https://github.com/Ombi-app/Ombi/commit/6d16442d4d714920367df065a3ced42b729f4233))
|
||||
* **sync:** Emby+Jellyfin - sync multi-episode files of 3+ episodes ([bd8fd89](https://github.com/Ombi-app/Ombi/commit/bd8fd890554c9d85d6da4d2cee813e82ce698e52))
|
||||
|
||||
|
||||
|
||||
# [4.20.0](https://github.com/Ombi-app/Ombi/compare/v4.19.1...v4.20.0) (2022-04-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **discover:** Show more relevant shows in upcoming TV ([8357819](https://github.com/Ombi-app/Ombi/commit/8357819b53b8c675c0b246d7006b5a778bdba33f))
|
||||
|
||||
|
||||
|
||||
## [4.19.1](https://github.com/Ombi-app/Ombi/compare/v4.19.0...v4.19.1) (2022-04-27)
|
||||
|
||||
|
||||
|
||||
# [4.19.0](https://github.com/Ombi-app/Ombi/compare/v4.18.0...v4.19.0) (2022-04-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **sync:** Detect reidentified movies in Emby and Jellyfin ([5938077](https://github.com/Ombi-app/Ombi/commit/5938077d82a5357f79c07b218b3986557a5816e8))
|
||||
* **sync:** Detect reidentified series in Emby and Jellyfin ([9096e91](https://github.com/Ombi-app/Ombi/commit/9096e91d55d268819bce22831f8a8b27f2a1776b))
|
||||
|
||||
|
||||
|
||||
# [4.18.0](https://github.com/Ombi-app/Ombi/compare/v4.17.0...v4.18.0) (2022-04-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **discover:** Fix cache mix up ([03d9422](https://github.com/Ombi-app/Ombi/commit/03d94220c7eaafb50c6c80a6ed1150794b873ac3))
|
||||
* **discover:** Fix new trending feature detection ([6794b88](https://github.com/Ombi-app/Ombi/commit/6794b887f6544fb41528bdd9728b7824b65e47ee))
|
||||
* **settings:** Allow toggling features when there are more than one ([a373359](https://github.com/Ombi-app/Ombi/commit/a373359ae8e6bad42b558a6e01a8ff2840d3bbaa))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **discover:** Add new trending source experimental feature ([1a0823c](https://github.com/Ombi-app/Ombi/commit/1a0823ca80559417c67323aaeaa1ef5243e98031))
|
||||
* **discover:** Default trending source to new logic ([4f12939](https://github.com/Ombi-app/Ombi/commit/4f12939e22020a67a5ee75e2907923faea136e8d))
|
||||
|
||||
|
||||
|
||||
# [4.17.0](https://github.com/Ombi-app/Ombi/compare/v4.16.17...v4.17.0) (2022-04-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **discover:** Add original language filter ([ef7ec86](https://github.com/Ombi-app/Ombi/commit/ef7ec861d8aede2a4817752c990617f583805391))
|
||||
|
||||
|
||||
|
||||
## [4.16.17](https://github.com/Ombi-app/Ombi/compare/v4.16.16...v4.16.17) (2022-04-25)
|
||||
|
||||
|
||||
|
||||
## [4.16.16](https://github.com/Ombi-app/Ombi/compare/v4.16.15...v4.16.16) (2022-04-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **4616:** :bug: fixed mandatory fields ([d8f2260](https://github.com/Ombi-app/Ombi/commit/d8f2260c7ae3ed48386743b7adbd06e284487034))
|
||||
|
||||
|
||||
|
||||
## [4.16.15](https://github.com/Ombi-app/Ombi/compare/v4.16.14...v4.16.15) (2022-04-24)
|
||||
|
||||
|
||||
|
||||
## [4.16.14](https://github.com/Ombi-app/Ombi/compare/v4.16.13...v4.16.14) (2022-04-19)
|
||||
|
||||
|
||||
|
||||
## [4.16.13](https://github.com/Ombi-app/Ombi/compare/v4.16.12...v4.16.13) (2022-04-19)
|
||||
|
||||
|
||||
|
||||
## [4.16.12](https://github.com/Ombi-app/Ombi/compare/v4.16.11...v4.16.12) (2022-04-19)
|
||||
|
||||
|
||||
|
||||
## [4.16.11](https://github.com/Ombi-app/Ombi/compare/v4.16.10...v4.16.11) (2022-04-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Set the default job for the watchlist import to hourly instead of daily ([75906af](https://github.com/Ombi-app/Ombi/commit/75906af0adee3e3c68d825c3aaa8f7b918461b1f))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([0e8a64b](https://github.com/Ombi-app/Ombi/commit/0e8a64b8ca00d210fbe843ac2c3f6af218d80cbc))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([7b0ad61](https://github.com/Ombi-app/Ombi/commit/7b0ad61bfcff3986b33180dc64022cba7ea8eefb))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([4fc2c1f](https://github.com/Ombi-app/Ombi/commit/4fc2c1f24534085a783a3d5791f5533b68272153))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([76ab733](https://github.com/Ombi-app/Ombi/commit/76ab733b91791e4d93d184f3c7d0779c6a388695))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([06e4cef](https://github.com/Ombi-app/Ombi/commit/06e4cefa7b4e55b860da9a64f461f6ec8fa17367))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([c12d89d](https://github.com/Ombi-app/Ombi/commit/c12d89d6781a337520977ad285f8d08c93f434dd))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([bc0c2f6](https://github.com/Ombi-app/Ombi/commit/bc0c2f622e34fb5a2711039d9ed7aad34f982b15))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([e4b00e6](https://github.com/Ombi-app/Ombi/commit/e4b00e6b3468bd9389eeb02fc6ad7daf27abc3b3))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([d1998d3](https://github.com/Ombi-app/Ombi/commit/d1998d326f999a38586d0a351a20c5448df95842))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([bee4ccb](https://github.com/Ombi-app/Ombi/commit/bee4ccb804594e7385b1fbdc9fe2ef5c42e0d21f))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([80233ed](https://github.com/Ombi-app/Ombi/commit/80233ed560cc976e83570d0655c3472f20171fb3))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([8a78adc](https://github.com/Ombi-app/Ombi/commit/8a78adc9bb62f277f2b213dcb3847ed6d0089fcb))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([d04c60a](https://github.com/Ombi-app/Ombi/commit/d04c60aa5909b47ba6bffa6f66b03079cbd43521))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([92a785e](https://github.com/Ombi-app/Ombi/commit/92a785e736fa4b72a45270da2d0f4661df433078))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([634982d](https://github.com/Ombi-app/Ombi/commit/634982df2661cefab5ea9f5163fe04a005cc0171))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([b404baa](https://github.com/Ombi-app/Ombi/commit/b404baad6d0aeaa1561701e0db8db4e78613a364))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([d14f11e](https://github.com/Ombi-app/Ombi/commit/d14f11e0eb20ab0a68e765ee77968b3b3e54e995))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([7cf64f9](https://github.com/Ombi-app/Ombi/commit/7cf64f909d78908edaabeffb8a39a7d02e73fe7e))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([0c9e1ec](https://github.com/Ombi-app/Ombi/commit/0c9e1ec090827080cc8f7393e5e91456ff37d691))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([3b0b730](https://github.com/Ombi-app/Ombi/commit/3b0b730cb02efe24f6d4026e5fdb20d37e495119))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([6ed1a03](https://github.com/Ombi-app/Ombi/commit/6ed1a03b7ff4077f09ea9e13394b18b0d138f4c3))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([2941acd](https://github.com/Ombi-app/Ombi/commit/2941acd3b2ec74a5e6aeea275ab5a39d2653f37f))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([c075a1a](https://github.com/Ombi-app/Ombi/commit/c075a1a66784d975eaf60f2dfbbcbe048f2f63d7))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([76bd81c](https://github.com/Ombi-app/Ombi/commit/76bd81c3ca55a98c6ec944a838dc01294a6193a6))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([0d38275](https://github.com/Ombi-app/Ombi/commit/0d3827507e002bcf58f673e97ffcc3bd25dcf337))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([5c99601](https://github.com/Ombi-app/Ombi/commit/5c99601b07aec1a65d0186a4c4327440811e64c6))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([01546a0](https://github.com/Ombi-app/Ombi/commit/01546a0f7f86379528b486463246ef9bdfb9033e))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([d7fea78](https://github.com/Ombi-app/Ombi/commit/d7fea7843aaaab7ddff8dc31ca6d2a9117471dcc))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([1a6b95d](https://github.com/Ombi-app/Ombi/commit/1a6b95d45c220310213b8d811272a63f0f6ff42b))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([fa10174](https://github.com/Ombi-app/Ombi/commit/fa1017422c4efd4b0897871bd3c671151774d7c3))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([0c31e62](https://github.com/Ombi-app/Ombi/commit/0c31e628df376aac6d56ae67c7c705a9a4a7c080))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([6399643](https://github.com/Ombi-app/Ombi/commit/63996437a02fe10ffae6822ffa15369bec0a6b36))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([5826e2d](https://github.com/Ombi-app/Ombi/commit/5826e2d9a1c3f1210a87fa270dc0c81bac32944a))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([d434514](https://github.com/Ombi-app/Ombi/commit/d43451405be489254d7cdc7755d5f516a1e495a5))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([0b9596d](https://github.com/Ombi-app/Ombi/commit/0b9596d807178f5e071113ec0347868ec7f0960b))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([8c4c0b2](https://github.com/Ombi-app/Ombi/commit/8c4c0b262978c1303767af360d802c4b4c2b4d24))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([289ab77](https://github.com/Ombi-app/Ombi/commit/289ab77b0e04aae235b6f6cebc86e0a8d1f0cf2b))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([30e3417](https://github.com/Ombi-app/Ombi/commit/30e3417285a4eed18d429d7776f0e74096e834c0))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([6c0a5da](https://github.com/Ombi-app/Ombi/commit/6c0a5dadd4b8f37760252eb0fe7f88908f55506d))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([d5bf969](https://github.com/Ombi-app/Ombi/commit/d5bf9692ce1fc0ccfe7beca6dd200c78be177bdc))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([8a9e7ea](https://github.com/Ombi-app/Ombi/commit/8a9e7ea588aefbcd73ed82625887e3614e1703ea))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([01047a3](https://github.com/Ombi-app/Ombi/commit/01047a3fd67153f3ff16f860d2c7b50213e8d9b2))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([698a23f](https://github.com/Ombi-app/Ombi/commit/698a23fb83f323cdd1dd57cb49803079d44214a7))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([24eb842](https://github.com/Ombi-app/Ombi/commit/24eb842fc4424f7bcc3ec2949d7f5472492e96f6))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([ac8b16a](https://github.com/Ombi-app/Ombi/commit/ac8b16a3051ad71dbd54a8973c7dd847b564a515))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([f428ce6](https://github.com/Ombi-app/Ombi/commit/f428ce6a700c081437703839bc84d2f2b1138bcc))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([94b16df](https://github.com/Ombi-app/Ombi/commit/94b16dfe09bf1d2cd6286777d74eb5d4496abbbb))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([4881775](https://github.com/Ombi-app/Ombi/commit/4881775eda69a8f136ce0d8fbbf970e3d0406dc9))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([8297db9](https://github.com/Ombi-app/Ombi/commit/8297db91e85da308bde6fb09ad78347dee063630))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([d1152ab](https://github.com/Ombi-app/Ombi/commit/d1152ab7674243daa528c524c0cdc87d81ad49c9))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([eb2788b](https://github.com/Ombi-app/Ombi/commit/eb2788b761b55c487a59a049427ca08f6c10e836))
|
||||
* **translations:** 🌐 New translations from Crowdin [skip ci] ([21a794c](https://github.com/Ombi-app/Ombi/commit/21a794cbc0a5fa735ca0347c8f7f1ac04a487fbc))
|
||||
|
||||
|
||||
|
||||
## [4.10.2](https://github.com/Ombi-app/Ombi/compare/v4.10.1...v4.10.2) (2022-01-22)
|
||||
|
||||
|
||||
|
||||
## [4.16.10](https://github.com/Ombi-app/Ombi/compare/v4.16.9...v4.16.10) (2022-04-13)
|
||||
|
||||
|
||||
|
||||
## [4.16.9](https://github.com/Ombi-app/Ombi/compare/v4.16.8...v4.16.9) (2022-04-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **plex-watchlist:** Only request the latest season when importing from the watchlist ([77a47ff](https://github.com/Ombi-app/Ombi/commit/77a47ff157c6c5feafe3f2a29a3fcba8df4fdfef))
|
||||
|
||||
|
||||
|
||||
## [4.16.8](https://github.com/Ombi-app/Ombi/compare/v4.16.7...v4.16.8) (2022-04-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **availability:** Fixed an issue where we wouldn't mark a available 4k movie as available (when 4K request feature is disabled) ([b492699](https://github.com/Ombi-app/Ombi/commit/b49269961d4830a530e3054976a47f519524948b))
|
||||
|
||||
|
||||
|
||||
## [4.16.7](https://github.com/Ombi-app/Ombi/compare/v4.16.6...v4.16.7) (2022-04-12)
|
||||
|
||||
|
||||
|
||||
## [4.16.6](https://github.com/Ombi-app/Ombi/compare/v4.16.5...v4.16.6) (2022-04-11)
|
||||
|
||||
|
||||
|
||||
## [4.16.5](https://github.com/Ombi-app/Ombi/compare/v4.16.4...v4.16.5) (2022-04-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **watchlist:** actually fixed it this time... ([d962a32](https://github.com/Ombi-app/Ombi/commit/d962a3211eca29520662ddce962676e3aea17ec5))
|
||||
|
||||
|
||||
|
||||
## [4.16.4](https://github.com/Ombi-app/Ombi/compare/v4.16.3...v4.16.4) (2022-04-08)
|
||||
|
||||
|
||||
|
||||
## [4.16.3](https://github.com/Ombi-app/Ombi/compare/v4.16.2...v4.16.3) (2022-04-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **plex-watchlist:** :bug: Fixed the issue where the watchlist didn't work for users logging in via OAuth ([6398f6a](https://github.com/Ombi-app/Ombi/commit/6398f6a4f7755281ebeac537e3ff623df5cfa0f3))
|
||||
|
||||
|
||||
|
||||
## [4.16.2](https://github.com/Ombi-app/Ombi/compare/v4.16.1...v4.16.2) (2022-04-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **wizard:** Fixed an issue when using Plex OAuth it could fail setting up ([b743cf4](https://github.com/Ombi-app/Ombi/commit/b743cf4fafa7341ad1b163276f006d7ab0e9dcff))
|
||||
|
||||
|
||||
|
||||
## [4.16.1](https://github.com/Ombi-app/Ombi/compare/v4.16.0...v4.16.1) (2022-04-07)
|
||||
|
||||
|
||||
|
||||
# [4.16.0](https://github.com/Ombi-app/Ombi/compare/v4.15.6...v4.16.0) (2022-04-07)
|
||||
|
||||
|
||||
|
||||
## [4.15.6](https://github.com/Ombi-app/Ombi/compare/v4.15.5...v4.15.6) (2022-04-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **radarr:** Fixed an issue where we couldn't sync radarr content [#4577](https://github.com/Ombi-app/Ombi/issues/4577) ([a5355a3](https://github.com/Ombi-app/Ombi/commit/a5355a3023e6900c4dd1b0da4722d7596c03907f))
|
||||
|
||||
|
||||
|
||||
## [4.15.5](https://github.com/Ombi-app/Ombi/compare/v4.15.4...v4.15.5) (2022-04-06)
|
||||
|
||||
|
||||
|
||||
## [4.15.4](https://github.com/Ombi-app/Ombi/compare/v4.15.3...v4.15.4) (2022-03-29)
|
||||
|
||||
|
||||
|
||||
## [4.15.3](https://github.com/Ombi-app/Ombi/compare/v4.15.2...v4.15.3) (2022-03-24)
|
||||
|
||||
|
||||
|
||||
## [4.15.2](https://github.com/Ombi-app/Ombi/compare/v4.15.1...v4.15.2) (2022-03-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **metadata:** improved the metadata job to also lookup the media in Plex to see if it has any more uptodate metadata ([83d1a15](https://github.com/Ombi-app/Ombi/commit/83d1a15cc9d0ee91be73bd91c4672cf1bcf2728a))
|
||||
|
||||
|
||||
|
||||
## [4.15.1](https://github.com/Ombi-app/Ombi/compare/v4.15.0...v4.15.1) (2022-03-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **mediaserver:** fixed an issue where we were not detecting available content correctly [#4542](https://github.com/Ombi-app/Ombi/issues/4542) ([9cdd6f4](https://github.com/Ombi-app/Ombi/commit/9cdd6f41cdab8825a984905c089611409c53c753))
|
||||
|
||||
|
||||
|
||||
|
|
173
README.md
173
README.md
|
@ -18,7 +18,7 @@ Don't worry, it's grandma friendly, and more importantly; has wife approval cert
|
|||
|
||||
| Service | Stable | Develop
|
||||
|----------|:---------------------------:|:----------------------------:|
|
||||
| Build Status | [](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [](https://dev.azure.com/tidusjar/Ombi/_build/latest?definitionId=18&branchName=feature%2Fv4)
|
||||
| Build Status | [](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [](https://dev.azure.com/tidusjar/Ombi/_build/latest?definitionId=18&branchName=feature%2Fv4)
|
||||
| Download |[](https://github.com/Ombi-app/Ombi/releases) | [](https://ci.appveyor.com/project/tidusjar/requestplex/branch/develop/artifacts) | [](https://github.com/ombi-app/ombi/releases) |
|
||||
|
||||
# Feature Requests
|
||||
|
@ -99,21 +99,28 @@ Here are some of the features Ombi has:
|
|||
<sub><b>Drew</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/sephrat">
|
||||
<img src="https://avatars.githubusercontent.com/u/34862846?v=4" width="50;" alt="sephrat"/>
|
||||
<br />
|
||||
<sub><b>Sephrat</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/anojht">
|
||||
<img src="https://avatars.githubusercontent.com/u/21053678?v=4" width="50;" alt="anojht"/>
|
||||
<br />
|
||||
<sub><b>Anojh Thayaparan</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Magikarplvl4">
|
||||
<img src="https://avatars.githubusercontent.com/u/2944704?v=4" width="50;" alt="Magikarplvl4"/>
|
||||
<br />
|
||||
<sub><b>Magikarp Lvl 4</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/MrTopCat">
|
||||
<img src="https://avatars.githubusercontent.com/u/774415?v=4" width="50;" alt="MrTopCat"/>
|
||||
|
@ -148,15 +155,15 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Dhruv Bhavsar</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/joshuaboniface">
|
||||
<img src="https://avatars.githubusercontent.com/u/4031396?v=4" width="50;" alt="joshuaboniface"/>
|
||||
<br />
|
||||
<sub><b>Joshua M. Boniface</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bruvv">
|
||||
<img src="https://avatars.githubusercontent.com/u/3063928?v=4" width="50;" alt="bruvv"/>
|
||||
|
@ -164,13 +171,6 @@ Here are some of the features Ombi has:
|
|||
<sub><b>Bruvv</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/sephrat">
|
||||
<img src="https://avatars.githubusercontent.com/u/34862846?v=4" width="50;" alt="sephrat"/>
|
||||
<br />
|
||||
<sub><b>Sephrat</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/louis-lau">
|
||||
<img src="https://avatars.githubusercontent.com/u/1346804?v=4" width="50;" alt="louis-lau"/>
|
||||
|
@ -222,10 +222,10 @@ Here are some of the features Ombi has:
|
|||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/stefangross">
|
||||
<img src="https://avatars.githubusercontent.com/u/8499989?v=4" width="50;" alt="stefangross"/>
|
||||
<a href="https://github.com/grimsan55">
|
||||
<img src="https://avatars.githubusercontent.com/u/8499989?v=4" width="50;" alt="grimsan55"/>
|
||||
<br />
|
||||
<sub><b>Stefangross</b></sub>
|
||||
<sub><b>Stefan</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
@ -243,6 +243,13 @@ Here are some of the features Ombi has:
|
|||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/fservida">
|
||||
<img src="https://avatars.githubusercontent.com/u/501958?v=4" width="50;" alt="fservida"/>
|
||||
<br />
|
||||
<sub><b>Francesco Servida</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Patricol">
|
||||
<img src="https://avatars.githubusercontent.com/u/13428020?v=4" width="50;" alt="Patricol"/>
|
||||
|
@ -277,6 +284,14 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Aptalca</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/dr3am37">
|
||||
<img src="https://avatars.githubusercontent.com/u/91037083?v=4" width="50;" alt="dr3am37"/>
|
||||
<br />
|
||||
<sub><b>Dr3amer</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/mhann">
|
||||
|
@ -284,8 +299,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Mhann</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ombi-bot">
|
||||
<img src="https://avatars.githubusercontent.com/u/51722903?v=4" width="50;" alt="ombi-bot"/>
|
||||
|
@ -313,7 +327,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Austin Jackson</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/D34DC3N73R">
|
||||
<img src="https://avatars.githubusercontent.com/u/9123670?v=4" width="50;" alt="D34DC3N73R"/>
|
||||
|
@ -327,8 +342,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>David Pooley</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Fredrik81">
|
||||
<img src="https://avatars.githubusercontent.com/u/21292774?v=4" width="50;" alt="Fredrik81"/>
|
||||
|
@ -356,7 +370,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Jeffrey Peters</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/MariusSchiffer">
|
||||
<img src="https://avatars.githubusercontent.com/u/183124?v=4" width="50;" alt="MariusSchiffer"/>
|
||||
|
@ -370,8 +385,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Qstick</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Vbgf">
|
||||
<img src="https://avatars.githubusercontent.com/u/5571734?v=4" width="50;" alt="Vbgf"/>
|
||||
|
@ -399,7 +413,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Abe Kline</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/XanderStrike">
|
||||
<img src="https://avatars.githubusercontent.com/u/1565303?v=4" width="50;" alt="XanderStrike"/>
|
||||
|
@ -413,8 +428,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Aljosa Asanovic</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Ashyni">
|
||||
<img src="https://avatars.githubusercontent.com/u/18462848?v=4" width="50;" alt="Ashyni"/>
|
||||
|
@ -442,7 +456,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Chris Lees</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/cdemi">
|
||||
<img src="https://avatars.githubusercontent.com/u/8025435?v=4" width="50;" alt="cdemi"/>
|
||||
|
@ -456,8 +471,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Codehhh</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/danopia">
|
||||
<img src="https://avatars.githubusercontent.com/u/40628?v=4" width="50;" alt="danopia"/>
|
||||
|
@ -485,7 +499,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Devin Buhl</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/elisspace">
|
||||
<img src="https://avatars.githubusercontent.com/u/18365129?v=4" width="50;" alt="elisspace"/>
|
||||
|
@ -499,8 +514,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Fish2</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/hariesramdhani">
|
||||
<img src="https://avatars.githubusercontent.com/u/24251244?v=4" width="50;" alt="hariesramdhani"/>
|
||||
|
@ -508,6 +522,13 @@ Here are some of the features Ombi has:
|
|||
<sub><b>Haries Ramdhani</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/comigor">
|
||||
<img src="https://avatars.githubusercontent.com/u/735858?v=4" width="50;" alt="comigor"/>
|
||||
<br />
|
||||
<sub><b>Igor Borges</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ImgBotApp">
|
||||
<img src="https://avatars.githubusercontent.com/u/31427850?v=4" width="50;" alt="ImgBotApp"/>
|
||||
|
@ -521,7 +542,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Jacob Pyke</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jamesmacwhite">
|
||||
<img src="https://avatars.githubusercontent.com/u/8067792?v=4" width="50;" alt="jamesmacwhite"/>
|
||||
|
@ -542,8 +564,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Joe Harvey</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jonbloom">
|
||||
<img src="https://avatars.githubusercontent.com/u/492819?v=4" width="50;" alt="jonbloom"/>
|
||||
|
@ -564,7 +585,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Kris Klosterman</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/kmlucy">
|
||||
<img src="https://avatars.githubusercontent.com/u/13952475?v=4" width="50;" alt="kmlucy"/>
|
||||
|
@ -579,20 +601,41 @@ Here are some of the features Ombi has:
|
|||
<sub><b>Lightkeeper</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Lucane">
|
||||
<img src="https://avatars.githubusercontent.com/u/7999446?v=4" width="50;" alt="Lucane"/>
|
||||
<br />
|
||||
<sub><b>Lucane</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/devbymadde">
|
||||
<img src="https://avatars.githubusercontent.com/u/6094593?v=4" width="50;" alt="devbymadde"/>
|
||||
<br />
|
||||
<sub><b>Madeleine Schönemann</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/marleypowell">
|
||||
<img src="https://avatars.githubusercontent.com/u/55280588?v=4" width="50;" alt="marleypowell"/>
|
||||
<br />
|
||||
<sub><b>Marley</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/mattmattmatt">
|
||||
<img src="https://avatars.githubusercontent.com/u/927830?v=4" width="50;" alt="mattmattmatt"/>
|
||||
<br />
|
||||
<sub><b>Matt</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/LMaxence">
|
||||
<img src="https://avatars.githubusercontent.com/u/29194680?v=4" width="50;" alt="LMaxence"/>
|
||||
<br />
|
||||
<sub><b>Maxence Lecanu</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AliMickey">
|
||||
|
@ -608,6 +651,13 @@ Here are some of the features Ombi has:
|
|||
<sub><b>Nathan Miller</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/cqxmzz">
|
||||
<img src="https://avatars.githubusercontent.com/u/3071863?v=4" width="50;" alt="cqxmzz"/>
|
||||
<br />
|
||||
<sub><b>Qiming Chen</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/randallbruder">
|
||||
<img src="https://avatars.githubusercontent.com/u/6447487?v=4" width="50;" alt="randallbruder"/>
|
||||
|
@ -621,15 +671,15 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Rob Gökemeijer</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/sambartik">
|
||||
<img src="https://avatars.githubusercontent.com/u/63553146?v=4" width="50;" alt="sambartik"/>
|
||||
<br />
|
||||
<sub><b>Samuel Bartík</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/seancallinan">
|
||||
<img src="https://avatars.githubusercontent.com/u/1139665?v=4" width="50;" alt="seancallinan"/>
|
||||
|
@ -644,6 +694,13 @@ Here are some of the features Ombi has:
|
|||
<sub><b>Shoghi</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Teifun2">
|
||||
<img src="https://avatars.githubusercontent.com/u/7461832?v=4" width="50;" alt="Teifun2"/>
|
||||
<br />
|
||||
<sub><b>Teifun2</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/thomasvt1">
|
||||
<img src="https://avatars.githubusercontent.com/u/2271011?v=4" width="50;" alt="thomasvt1"/>
|
||||
|
@ -657,7 +714,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Tim Trott</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/tombomb">
|
||||
<img src="https://avatars.githubusercontent.com/u/544509?v=4" width="50;" alt="tombomb"/>
|
||||
|
@ -671,8 +729,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Torkil</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bybeet">
|
||||
<img src="https://avatars.githubusercontent.com/u/1662279?v=4" width="50;" alt="bybeet"/>
|
||||
|
@ -700,7 +757,8 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Blake Drumm</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/camjac251">
|
||||
<img src="https://avatars.githubusercontent.com/u/6313132?v=4" width="50;" alt="camjac251"/>
|
||||
|
@ -714,8 +772,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Michael DiStaula</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/baikunz">
|
||||
<img src="https://avatars.githubusercontent.com/u/984911?v=4" width="50;" alt="baikunz"/>
|
||||
|
@ -723,6 +780,13 @@ Here are some of the features Ombi has:
|
|||
<sub><b>Dorian ALKOUM</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/echel0n">
|
||||
<img src="https://avatars.githubusercontent.com/u/1128022?v=4" width="50;" alt="echel0n"/>
|
||||
<br />
|
||||
<sub><b>Echel0n</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/m4tta">
|
||||
<img src="https://avatars.githubusercontent.com/u/427218?v=4" width="50;" alt="m4tta"/>
|
||||
|
@ -730,6 +794,14 @@ Here are some of the features Ombi has:
|
|||
<sub><b>M4tta</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/maartenheebink">
|
||||
<img src="https://avatars.githubusercontent.com/u/28894544?v=4" width="50;" alt="maartenheebink"/>
|
||||
<br />
|
||||
<sub><b>Maartenheebink</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/masterhuck">
|
||||
<img src="https://avatars.githubusercontent.com/u/4671442?v=4" width="50;" alt="masterhuck"/>
|
||||
|
@ -757,8 +829,7 @@ Here are some of the features Ombi has:
|
|||
<br />
|
||||
<sub><b>Mike</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/zobe123">
|
||||
<img src="https://avatars.githubusercontent.com/u/13840542?v=4" width="50;" alt="zobe123"/>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
commit_message: "fix(translations): 🌐 New translations from Crowdin [skip ci]"
|
||||
append_commit_message: false
|
||||
pull_request_title: "🌐 Translations Update"
|
||||
pull_request_labels:
|
||||
- translations
|
||||
|
||||
files:
|
||||
- source: /src/Ombi/wwwroot/translations/en.json
|
||||
translation: /src/Ombi/wwwroot/translations/%two_letters_code%.json
|
||||
- source: /src/Ombi.I18n/Resources/Texts.resx
|
||||
translation: /src/Ombi.I18n/Resources/Texts.%two_letters_code%.resx
|
||||
|
|
17
makefile
Normal file
17
makefile
Normal file
|
@ -0,0 +1,17 @@
|
|||
backend:
|
||||
cd src/Ombi && dotnet watch run -- --host http://*:3577
|
||||
|
||||
frontend:
|
||||
cd src/Ombi/ClientApp && yarn start
|
||||
|
||||
install-frontend:
|
||||
cd src/Ombi/ClientApp && yarn
|
||||
|
||||
install-frontend-tests:
|
||||
cd tests && yarn
|
||||
|
||||
frontend-tests:
|
||||
cd tests && npx cypress run
|
||||
|
||||
backend-tests:
|
||||
cd src/Ombi.Core.Tests && dotnet test
|
4
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
4
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
|
@ -929,7 +929,7 @@
|
|||
<e p="EmbyConfiguration.cs" t="Include" />
|
||||
<e p="EmbyConnectUser.cs" t="Include" />
|
||||
<e p="EmbyItemContainer.cs" t="Include" />
|
||||
<e p="EmbyMediaType.cs" t="Include" />
|
||||
<e p="MediaType.cs" t="Include" />
|
||||
<e p="EmbyPolicy.cs" t="Include" />
|
||||
<e p="EmbySystemInfo.cs" t="Include" />
|
||||
<e p="EmbyUser.cs" t="Include" />
|
||||
|
@ -1876,7 +1876,7 @@
|
|||
<e p="PlexAvailabilityChecker.cs" t="Include" />
|
||||
<e p="PlexContentSync.cs" t="Include" />
|
||||
<e p="PlexEpisodeSync.cs" t="Include" />
|
||||
<e p="PlexMediaType.cs" t="Include" />
|
||||
<e p="MediaType.cs" t="Include" />
|
||||
<e p="PlexRecentlyAddedSync.cs" t="Include" />
|
||||
<e p="PlexUserImporter.cs" t="Include" />
|
||||
</e>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Newtonsoft.Json;
|
||||
using Ombi.Api.Emby.Models;
|
||||
using Ombi.Api.Emby.Models.Media;
|
||||
using Ombi.Api.Emby.Models.Media.Tv;
|
||||
using Ombi.Api.Emby.Models.Movie;
|
||||
using Ombi.Helpers;
|
||||
|
@ -110,7 +106,7 @@ namespace Ombi.Api.Emby
|
|||
|
||||
request.AddQueryString("Fields", "ProviderIds,Overview");
|
||||
|
||||
request.AddQueryString("IsVirtualItem", "False");
|
||||
request.AddQueryString("IsMissing", "False");
|
||||
|
||||
return await Api.Request<EmbyItemContainer<EmbyMovie>>(request);
|
||||
}
|
||||
|
@ -124,22 +120,36 @@ namespace Ombi.Api.Emby
|
|||
return response;
|
||||
}
|
||||
|
||||
|
||||
public async Task<EmbyItemContainer<EmbyMovie>> GetAllMovies(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri)
|
||||
{
|
||||
return await GetAll<EmbyMovie>("Movie", apiKey, userId, baseUri, true, startIndex, count, parentIdFilder);
|
||||
}
|
||||
|
||||
public async Task<EmbyItemContainer<EmbyMovie>> RecentlyAddedMovies(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri)
|
||||
{
|
||||
return await RecentlyAdded<EmbyMovie>("Movie", apiKey, userId, baseUri, true, startIndex, count, parentIdFilder);
|
||||
}
|
||||
|
||||
public async Task<EmbyItemContainer<EmbyEpisodes>> GetAllEpisodes(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri)
|
||||
{
|
||||
return await GetAll<EmbyEpisodes>("Episode", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder);
|
||||
}
|
||||
|
||||
public async Task<EmbyItemContainer<EmbyEpisodes>> RecentlyAddedEpisodes(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri)
|
||||
{
|
||||
return await RecentlyAdded<EmbyEpisodes>("Episode", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder);
|
||||
}
|
||||
|
||||
public async Task<EmbyItemContainer<EmbySeries>> GetAllShows(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri)
|
||||
{
|
||||
return await GetAll<EmbySeries>("Series", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder);
|
||||
}
|
||||
|
||||
public async Task<EmbyItemContainer<EmbySeries>> RecentlyAddedShows(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri)
|
||||
{
|
||||
return await RecentlyAdded<EmbySeries>("Series", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder);
|
||||
}
|
||||
|
||||
public async Task<SeriesInformation> GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl)
|
||||
{
|
||||
return await GetInformation<SeriesInformation>(mediaId, apiKey, userId, baseUrl);
|
||||
|
@ -154,6 +164,31 @@ namespace Ombi.Api.Emby
|
|||
return await GetInformation<EpisodeInformation>(mediaId, apiKey, userId, baseUrl);
|
||||
}
|
||||
|
||||
private async Task<EmbyItemContainer<T>> RecentlyAdded<T>(string type, string apiKey, string userId, string baseUri, bool includeOverview, int startIndex, int count, string parentIdFilder = default)
|
||||
{
|
||||
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,MediaStreams,Overview" : "ProviderIds,MediaStreams ");
|
||||
request.AddQueryString("startIndex", startIndex.ToString());
|
||||
request.AddQueryString("limit", count.ToString());
|
||||
request.AddQueryString("sortBy", "DateCreated");
|
||||
request.AddQueryString("SortOrder", "Descending");
|
||||
if (!string.IsNullOrEmpty(parentIdFilder))
|
||||
{
|
||||
request.AddQueryString("ParentId", parentIdFilder);
|
||||
}
|
||||
|
||||
request.AddQueryString("IsMissing", "False");
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
|
||||
var obj = await Api.Request<EmbyItemContainer<T>>(request);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private async Task<T> GetInformation<T>(string mediaId, string apiKey, string userId, string baseUrl)
|
||||
{
|
||||
var request = new Request($"emby/users/{userId}/items/{mediaId}", baseUrl, HttpMethod.Get);
|
||||
|
@ -172,7 +207,7 @@ namespace Ombi.Api.Emby
|
|||
request.AddQueryString("IncludeItemTypes", type);
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds");
|
||||
|
||||
request.AddQueryString("IsVirtualItem", "False");
|
||||
request.AddQueryString("IsMissing", "False");
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
|
@ -186,7 +221,7 @@ namespace Ombi.Api.Emby
|
|||
|
||||
request.AddQueryString("Recursive", true.ToString());
|
||||
request.AddQueryString("IncludeItemTypes", type);
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds");
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview,MediaStreams" : "ProviderIds,MediaStreams");
|
||||
request.AddQueryString("startIndex", startIndex.ToString());
|
||||
request.AddQueryString("limit", count.ToString());
|
||||
if (!string.IsNullOrEmpty(parentIdFilder))
|
||||
|
@ -194,7 +229,7 @@ namespace Ombi.Api.Emby
|
|||
request.AddQueryString("ParentId", parentIdFilder);
|
||||
}
|
||||
|
||||
request.AddQueryString("IsVirtualItem", "False");
|
||||
request.AddQueryString("isMissing", "False");
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
|
|
|
@ -29,5 +29,8 @@ namespace Ombi.Api.Emby
|
|||
Task<MovieInformation> GetMovieInformation(string mediaId, string apiKey, string userId, string baseUrl);
|
||||
Task<EpisodeInformation> GetEpisodeInformation(string mediaId, string apiKey, string userId, string baseUrl);
|
||||
Task<PublicInfo> GetPublicInformation(string baseUrl);
|
||||
Task<EmbyItemContainer<EmbyMovie>> RecentlyAddedMovies(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);
|
||||
Task<EmbyItemContainer<EmbyEpisodes>> RecentlyAddedEpisodes(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);
|
||||
Task<EmbyItemContainer<EmbySeries>> RecentlyAddedShows(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
namespace Ombi.Api.Emby.Models
|
||||
{
|
||||
public enum EmbyMediaType
|
||||
{
|
||||
Movie = 0,
|
||||
Series = 1,
|
||||
Music = 2,
|
||||
Episode = 3
|
||||
}
|
||||
}
|
|
@ -2,35 +2,6 @@ namespace Ombi.Api.Emby.Models.Movie
|
|||
{
|
||||
public class EmbyMediastream
|
||||
{
|
||||
public string Codec { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string TimeBase { get; set; }
|
||||
public string CodecTimeBase { get; set; }
|
||||
public string NalLengthSize { get; set; }
|
||||
public bool IsInterlaced { get; set; }
|
||||
public bool IsAVC { get; set; }
|
||||
public int BitRate { get; set; }
|
||||
public int BitDepth { get; set; }
|
||||
public int RefFrames { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public bool IsForced { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int Width { get; set; }
|
||||
public float AverageFrameRate { get; set; }
|
||||
public float RealFrameRate { get; set; }
|
||||
public string Profile { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string AspectRatio { get; set; }
|
||||
public int Index { get; set; }
|
||||
public bool IsExternal { get; set; }
|
||||
public bool IsTextSubtitleStream { get; set; }
|
||||
public bool SupportsExternalStream { get; set; }
|
||||
public string PixelFormat { get; set; }
|
||||
public int Level { get; set; }
|
||||
public bool IsAnamorphic { get; set; }
|
||||
public string DisplayTitle { get; set; }
|
||||
public string ChannelLayout { get; set; }
|
||||
public int Channels { get; set; }
|
||||
public int SampleRate { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
namespace Ombi.Api.Emby.Models.Movie
|
||||
{
|
||||
public class EmbyProviderids
|
||||
{
|
||||
public string Tmdb { get; set; }
|
||||
public string Imdb { get; set; }
|
||||
public string TmdbCollection { get; set; }
|
||||
using Ombi.Api.MediaServer.Models;
|
||||
|
||||
public string Tvdb { get; set; }
|
||||
namespace Ombi.Api.Emby.Models.Movie
|
||||
{
|
||||
public class EmbyProviderids: BaseProviderids
|
||||
{
|
||||
public string TmdbCollection { get; set; }
|
||||
public string Zap2It { get; set; }
|
||||
public string TvRage { get; set; }
|
||||
}
|
||||
|
|
|
@ -30,5 +30,6 @@ namespace Ombi.Api.Emby.Models.Movie
|
|||
public int CriticRating { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public EmbyProviderids ProviderIds { get; set; }
|
||||
public EmbyMediastream[] MediaStreams { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,17 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.MediaServer\Ombi.Api.MediaServer.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace Ombi.Api.Jellyfin
|
|||
|
||||
request.AddQueryString("Fields", "ProviderIds,Overview");
|
||||
|
||||
request.AddQueryString("IsVirtualItem", "False");
|
||||
request.AddQueryString("isMissing", "False");
|
||||
|
||||
return await Api.Request<JellyfinItemContainer<JellyfinMovie>>(request);
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ namespace Ombi.Api.Jellyfin
|
|||
request.AddQueryString("IncludeItemTypes", type);
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds");
|
||||
|
||||
request.AddQueryString("IsVirtualItem", "False");
|
||||
request.AddQueryString("isMissing", "False");
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
|
@ -157,7 +157,7 @@ namespace Ombi.Api.Jellyfin
|
|||
|
||||
request.AddQueryString("Recursive", true.ToString());
|
||||
request.AddQueryString("IncludeItemTypes", type);
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview,ParentId" : "ProviderIds,ParentId");
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,MediaStreams Overview,ParentId" : "ProviderIds,ParentId,MediaStreams");
|
||||
request.AddQueryString("startIndex", startIndex.ToString());
|
||||
request.AddQueryString("limit", count.ToString());
|
||||
if(!string.IsNullOrEmpty(parentIdFilder))
|
||||
|
@ -165,7 +165,7 @@ namespace Ombi.Api.Jellyfin
|
|||
request.AddQueryString("ParentId", parentIdFilder);
|
||||
}
|
||||
|
||||
request.AddQueryString("IsVirtualItem", "False");
|
||||
request.AddQueryString("isMissing", "False");
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
namespace Ombi.Api.Jellyfin.Models
|
||||
{
|
||||
public enum JellyfinMediaType
|
||||
{
|
||||
Movie = 0,
|
||||
Series = 1,
|
||||
Music = 2,
|
||||
Episode = 3
|
||||
}
|
||||
}
|
|
@ -2,35 +2,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie
|
|||
{
|
||||
public class JellyfinMediastream
|
||||
{
|
||||
public string Codec { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string TimeBase { get; set; }
|
||||
public string CodecTimeBase { get; set; }
|
||||
public string NalLengthSize { get; set; }
|
||||
public bool IsInterlaced { get; set; }
|
||||
public bool IsAVC { get; set; }
|
||||
public int BitRate { get; set; }
|
||||
public int BitDepth { get; set; }
|
||||
public int RefFrames { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public bool IsForced { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int Width { get; set; }
|
||||
public float AverageFrameRate { get; set; }
|
||||
public float RealFrameRate { get; set; }
|
||||
public string Profile { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string AspectRatio { get; set; }
|
||||
public int Index { get; set; }
|
||||
public bool IsExternal { get; set; }
|
||||
public bool IsTextSubtitleStream { get; set; }
|
||||
public bool SupportsExternalStream { get; set; }
|
||||
public string PixelFormat { get; set; }
|
||||
public int Level { get; set; }
|
||||
public bool IsAnamorphic { get; set; }
|
||||
public string DisplayTitle { get; set; }
|
||||
public string ChannelLayout { get; set; }
|
||||
public int Channels { get; set; }
|
||||
public int SampleRate { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
namespace Ombi.Api.Jellyfin.Models.Movie
|
||||
{
|
||||
public class JellyfinProviderids
|
||||
{
|
||||
public string Tmdb { get; set; }
|
||||
public string Imdb { get; set; }
|
||||
public string TmdbCollection { get; set; }
|
||||
using Ombi.Api.MediaServer.Models;
|
||||
|
||||
public string Tvdb { get; set; }
|
||||
namespace Ombi.Api.Jellyfin.Models.Movie
|
||||
{
|
||||
public class JellyfinProviderids: BaseProviderids
|
||||
{
|
||||
public string TmdbCollection { get; set; }
|
||||
public string Zap2It { get; set; }
|
||||
public string TvRage { get; set; }
|
||||
}
|
||||
|
|
|
@ -30,5 +30,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie
|
|||
public int CriticRating { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public JellyfinProviderids ProviderIds { get; set; }
|
||||
public JellyfinMediastream[] MediaStreams { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,18 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.MediaServer\Ombi.Api.MediaServer.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
11
src/Ombi.Api.MediaServer/Models/BaseProviderids.cs
Normal file
11
src/Ombi.Api.MediaServer/Models/BaseProviderids.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Ombi.Api.MediaServer.Models
|
||||
{
|
||||
public class BaseProviderids
|
||||
{
|
||||
public string Tmdb { get; set; }
|
||||
public string Imdb { get; set; }
|
||||
public string Tvdb { get; set; }
|
||||
public bool Any() =>
|
||||
!string.IsNullOrEmpty(Imdb) || !string.IsNullOrEmpty(Tmdb) || !string.IsNullOrEmpty(Tvdb);
|
||||
}
|
||||
}
|
18
src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj
Normal file
18
src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj
Normal file
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.Plex.Models;
|
||||
using Ombi.Api.Plex.Models.Friends;
|
||||
|
@ -16,9 +17,9 @@ namespace Ombi.Api.Plex
|
|||
Task<PlexServer> GetServer(string authToken);
|
||||
Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost);
|
||||
Task<PlexContainer> GetLibrary(string authToken, string plexFullHost, string libraryId);
|
||||
Task<PlexMetadata> GetEpisodeMetaData(string authToken, string host, int ratingKey);
|
||||
Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, int itemId);
|
||||
Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, int ratingKey);
|
||||
Task<PlexMetadata> GetEpisodeMetaData(string authToken, string host, string ratingKey);
|
||||
Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, string itemId);
|
||||
Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, string ratingKey);
|
||||
Task<PlexContainer> GetAllEpisodes(string authToken, string host, string section, int start, int retCount);
|
||||
Task<PlexFriends> GetUsers(string authToken);
|
||||
Task<PlexAccount> GetAccount(string authToken);
|
||||
|
@ -26,5 +27,7 @@ namespace Ombi.Api.Plex
|
|||
Task<OAuthContainer> GetPin(int pinId);
|
||||
Task<Uri> GetOAuthUrl(string code, string applicationUrl);
|
||||
Task<PlexAddWrapper> AddUser(string emailAddress, string serverId, string authToken, int[] libs);
|
||||
Task<PlexWatchlistContainer> GetWatchlist(string plexToken, CancellationToken cancellationToken);
|
||||
Task<PlexWatchlistMetadataContainer> GetWatchlistMetadata(string ratingKey, string plexToken, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ombi.Api.Plex.Models
|
||||
{
|
||||
public class Metadata
|
||||
{
|
||||
public int ratingKey { get; set; }
|
||||
public string ratingKey { get; set; }
|
||||
public string key { get; set; }
|
||||
public string studio { get; set; }
|
||||
public string type { get; set; }
|
||||
|
@ -12,26 +13,18 @@ namespace Ombi.Api.Plex.Models
|
|||
public string contentRating { get; set; }
|
||||
public string summary { get; set; }
|
||||
public int index { get; set; }
|
||||
public float rating { get; set; }
|
||||
//public int viewCount { get; set; }
|
||||
//public int lastViewedAt { get; set; }
|
||||
public int year { get; set; }
|
||||
public string thumb { get; set; }
|
||||
public string art { get; set; }
|
||||
public string banner { get; set; }
|
||||
public string theme { get; set; }
|
||||
//public string duration { get; set; }
|
||||
//public string originallyAvailableAt { get; set; }
|
||||
public int leafCount { get; set; }
|
||||
public int viewedLeafCount { get; set; }
|
||||
public int childCount { get; set; }
|
||||
//public long addedAt { get; set; }
|
||||
//public int updatedAt { get; set; }
|
||||
public Genre[] Genre { get; set; }
|
||||
//public Role[] Role { get; set; }
|
||||
public string primaryExtraKey { get; set; }
|
||||
public int parentRatingKey { get; set; }
|
||||
public int grandparentRatingKey { get; set; }
|
||||
public string parentRatingKey { get; set; }
|
||||
public string grandparentRatingKey { get; set; }
|
||||
public string guid { get; set; }
|
||||
public int librarySectionID { get; set; }
|
||||
public string librarySectionKey { get; set; }
|
||||
|
@ -47,12 +40,10 @@ namespace Ombi.Api.Plex.Models
|
|||
public string chapterSource { get; set; }
|
||||
public Medium[] Media { get; set; }
|
||||
public List<PlexGuids> Guid { get; set; } = new List<PlexGuids>();
|
||||
// public Director[] Director { get; set; }
|
||||
// public Writer[] Writer { get; set; }
|
||||
}
|
||||
|
||||
public class PlexGuids
|
||||
{
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
src/Ombi.Api.Plex/Models/PlexWatchlist.cs
Normal file
14
src/Ombi.Api.Plex/Models/PlexWatchlist.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Api.Plex.Models
|
||||
{
|
||||
public class PlexWatchlist
|
||||
{
|
||||
public string librarySectionID { get; set; }
|
||||
public string librarySectionTitle { get; set; }
|
||||
public int offset { get; set; }
|
||||
public int totalSize { get; set; }
|
||||
public int size { get; set; }
|
||||
public List<Metadata> Metadata { get; set; } = new List<Metadata>();
|
||||
}
|
||||
}
|
9
src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs
Normal file
9
src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Api.Plex.Models
|
||||
{
|
||||
public class PlexWatchlistContainer
|
||||
{
|
||||
public PlexWatchlist MediaContainer { get; set; }
|
||||
}
|
||||
}
|
31
src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs
Normal file
31
src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Api.Plex.Models
|
||||
{
|
||||
public class PlexWatchlistMetadataContainer
|
||||
{
|
||||
public PlexWatchlistMetadata MediaContainer { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class PlexWatchlistMetadata
|
||||
{
|
||||
public int offset { get; set; }
|
||||
public int totalSize { get; set; }
|
||||
public string identifier { get; set; }
|
||||
public int size { get; set; }
|
||||
public WatchlistMetadata[] Metadata { get; set; }
|
||||
}
|
||||
|
||||
public class WatchlistMetadata
|
||||
{
|
||||
public string guid { get; set; }
|
||||
public string key { get; set; }
|
||||
public string primaryExtraKey { get; set; }
|
||||
public string ratingKey { get; set; }
|
||||
public string type { get; set; }
|
||||
public string slug { get; set; }
|
||||
public string title { get; set; }
|
||||
public List<PlexGuids> Guid { get; set; } = new List<PlexGuids>();
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Ombi.Api.Plex.Models;
|
||||
|
@ -66,6 +67,7 @@ namespace Ombi.Api.Plex
|
|||
private const string FriendsUri = "https://plex.tv/pms/friends/all";
|
||||
private const string GetAccountUri = "https://plex.tv/users/account.json";
|
||||
private const string ServerUri = "https://plex.tv/pms/servers.xml";
|
||||
private const string WatchlistUri = "https://metadata.provider.plex.tv/";
|
||||
|
||||
/// <summary>
|
||||
/// Sign into the Plex API
|
||||
|
@ -145,21 +147,21 @@ namespace Ombi.Api.Plex
|
|||
/// <param name="authToken"></param>
|
||||
/// <param name="plexFullHost"></param>
|
||||
/// <param name="ratingKey"></param>
|
||||
public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, int ratingKey)
|
||||
public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, string ratingKey)
|
||||
{
|
||||
var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get);
|
||||
await AddHeaders(request, authToken);
|
||||
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, string itemId)
|
||||
{
|
||||
var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get);
|
||||
await AddHeaders(request, authToken);
|
||||
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, string ratingKey)
|
||||
{
|
||||
var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get);
|
||||
await AddHeaders(request, authToken);
|
||||
|
@ -288,6 +290,26 @@ namespace Ombi.Api.Plex
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<PlexWatchlistContainer> GetWatchlist(string plexToken, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new Request("library/sections/watchlist/all", WatchlistUri, HttpMethod.Get);
|
||||
await AddHeaders(request, plexToken);
|
||||
|
||||
var result = await Api.Request<PlexWatchlistContainer>(request, cancellationToken);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<PlexWatchlistMetadataContainer> GetWatchlistMetadata(string ratingKey, string plexToken, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new Request($"library/metadata/{ratingKey}", WatchlistUri, HttpMethod.Get);
|
||||
await AddHeaders(request, plexToken);
|
||||
|
||||
var result = await Api.Request<PlexWatchlistMetadataContainer>(request, cancellationToken);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds the required headers and also the authorization header
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -44,7 +44,10 @@ namespace Ombi.Api.Radarr.Models
|
|||
public int id { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class MovieQuality
|
||||
{
|
||||
public V3.Quality quality { get; set; }
|
||||
}
|
||||
public class Moviefile
|
||||
{
|
||||
public int movieId { get; set; }
|
||||
|
@ -54,7 +57,7 @@ namespace Ombi.Api.Radarr.Models
|
|||
public DateTime dateAdded { get; set; }
|
||||
public string sceneName { get; set; }
|
||||
public int indexerFlags { get; set; }
|
||||
public V3.Quality quality { get; set; }
|
||||
public MovieQuality quality { get; set; }
|
||||
public Mediainfo mediaInfo { get; set; }
|
||||
public string originalFilePath { get; set; }
|
||||
public bool qualityCutoffNotMet { get; set; }
|
||||
|
@ -74,13 +77,10 @@ namespace Ombi.Api.Radarr.Models
|
|||
public class Mediainfo
|
||||
{
|
||||
public string audioAdditionalFeatures { get; set; }
|
||||
public int audioBitrate { get; set; }
|
||||
public float audioChannels { get; set; }
|
||||
public string audioCodec { get; set; }
|
||||
public string audioLanguages { get; set; }
|
||||
public int audioStreamCount { get; set; }
|
||||
public int videoBitDepth { get; set; }
|
||||
public int videoBitrate { get; set; }
|
||||
public string videoCodec { get; set; }
|
||||
public float videoFps { get; set; }
|
||||
public string resolution { get; set; }
|
||||
|
@ -119,4 +119,4 @@ namespace Ombi.Api.Radarr.Models
|
|||
public int id { get; set; }
|
||||
public string name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,5 +25,4 @@
|
|||
public int resolution { get; set; }
|
||||
public string modifier { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<AssemblyName>Ombi.Api.Service</AssemblyName>
|
||||
<RootNamespace>Ombi.Api.Service</RootNamespace>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
public class SickRageEpisodeSetStatus
|
||||
{
|
||||
public Data data { get; set; }
|
||||
public Data[] data { get; set; }
|
||||
public string message { get; set; }
|
||||
public string result { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Ombi.Api.Sonarr
|
|||
protected IApi Api { get; }
|
||||
protected virtual string ApiBaseUrl => "/api/";
|
||||
|
||||
public async Task<IEnumerable<SonarrProfile>> GetProfiles(string apiKey, string baseUrl)
|
||||
public virtual async Task<IEnumerable<SonarrProfile>> GetProfiles(string apiKey, string baseUrl)
|
||||
{
|
||||
var request = new Request($"{ApiBaseUrl}profile", baseUrl, HttpMethod.Get);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System.Net.Http;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Ombi.Api.Sonarr.Models;
|
||||
using Ombi.Api.Sonarr.Models.V3;
|
||||
|
||||
namespace Ombi.Api.Sonarr
|
||||
|
@ -21,5 +23,12 @@ namespace Ombi.Api.Sonarr
|
|||
|
||||
return await Api.Request<List<LanguageProfiles>>(request);
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<SonarrProfile>> GetProfiles(string apiKey, string baseUrl)
|
||||
{
|
||||
var request = new Request($"{ApiBaseUrl}qualityprofile", baseUrl, HttpMethod.Get);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
return await Api.Request<List<SonarrProfile>>(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -8,10 +8,8 @@ namespace Ombi.Api.TvMaze
|
|||
public interface ITvMazeApi
|
||||
{
|
||||
Task<IEnumerable<TvMazeEpisodes>> EpisodeLookup(int showId);
|
||||
Task<List<TvMazeSeasons>> GetSeasons(int id);
|
||||
Task<List<TvMazeSearch>> Search(string searchTerm);
|
||||
Task<TvMazeShow> ShowLookup(int showId);
|
||||
Task<TvMazeShow> ShowLookupByTheTvDbId(int theTvDbId);
|
||||
Task<FullSearch> GetTvFullInformation(int id);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -64,27 +64,5 @@ namespace Ombi.Api.TvMaze
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<TvMazeSeasons>> GetSeasons(int id)
|
||||
{
|
||||
var request = new Request($"shows/{id}/seasons", Uri, HttpMethod.Get);
|
||||
|
||||
request.AddContentHeader("Content-Type", "application/json");
|
||||
|
||||
return await Api.Request<List<TvMazeSeasons>>(request);
|
||||
}
|
||||
|
||||
public async Task<FullSearch> GetTvFullInformation(int id)
|
||||
{
|
||||
var request = new Request($"shows/{id}", Uri, HttpMethod.Get);
|
||||
|
||||
request.AddQueryString("embed[]", "cast");
|
||||
request.AddQueryString("embed[]", "crew");
|
||||
request.AddQueryString("embed[]", "episodes");
|
||||
|
||||
request.AddContentHeader("Content-Type", "application/json");
|
||||
|
||||
return await Api.Request<FullSearch>(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -66,6 +66,8 @@ namespace Ombi.Api
|
|||
startingTag = builder.Query.Contains("?") ? "&" : "?";
|
||||
}
|
||||
|
||||
value = Uri.EscapeDataString(value);
|
||||
|
||||
builder.Query = hasQuery
|
||||
? $"{builder.Query}{startingTag}{parameter}={value}"
|
||||
: $"{startingTag}{parameter}={value}";
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Polly" Version="7.1.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -10,6 +10,7 @@ using Ombi.Core.Authentication;
|
|||
using Ombi.Core.Engine.V2;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Tests.Engine
|
||||
{
|
||||
|
@ -25,7 +26,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
{
|
||||
MovieRepo = new Mock<IMovieRequestRepository>();
|
||||
TvRepo = new Mock<ITvRequestRepository>();
|
||||
var principle = new Mock<IPrincipal>();
|
||||
var principle = new Mock<ICurrentUser>();
|
||||
var identity = new Mock<IIdentity>();
|
||||
identity.Setup(x => x.Name).Returns("UnitTest");
|
||||
principle.Setup(x => x.Identity).Returns(identity.Object);
|
||||
|
|
|
@ -1,135 +1,520 @@
|
|||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Threading.Tasks;
|
||||
//using Moq;
|
||||
//using NUnit.Framework;
|
||||
//using Ombi.Core.Engine;
|
||||
//using Ombi.Core.Models.Requests;
|
||||
//using Ombi.Store.Entities.Requests;
|
||||
//using Ombi.Store.Repository;
|
||||
//using Assert = Xunit.Assert;
|
||||
using MockQueryable.Moq;
|
||||
using Moq;
|
||||
using Moq.AutoMock;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using Ombi.Test.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
//namespace Ombi.Core.Tests.Engine
|
||||
//{
|
||||
// [TestFixture]
|
||||
// public class MovieRequestEngineTests
|
||||
// {
|
||||
// public MovieRequestEngineTests()
|
||||
// {
|
||||
// RequestService = new Mock<IMovieRequestRepository>();
|
||||
// var requestService = new RequestService(null, RequestService.Object);
|
||||
// Engine = new MovieRequestEngine(null, requestService, null, null, null, null, null, null);
|
||||
// }
|
||||
namespace Ombi.Core.Tests.Engine
|
||||
{
|
||||
[TestFixture]
|
||||
public class MovieRequestEngineTests
|
||||
{
|
||||
private MovieRequestEngine _subject;
|
||||
private Mock<IMovieRequestRepository> _repoMock;
|
||||
private AutoMocker _mocker;
|
||||
|
||||
// private MovieRequestEngine Engine { get; }
|
||||
// private Mock<IMovieRequestRepository> RequestService { get; }
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mocker = new AutoMocker();
|
||||
var userManager = MockHelper.MockUserManager(new List<OmbiUser> { new OmbiUser { NormalizedUserName = "TEST", Id = "a" } });
|
||||
userManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), It.IsAny<string>())).ReturnsAsync(true);
|
||||
var principle = new Mock<IPrincipal>();
|
||||
var identity = new Mock<IIdentity>();
|
||||
identity.Setup(x => x.Name).Returns("Test");
|
||||
principle.Setup(x => x.Identity).Returns(identity.Object);
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identity.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { NormalizedUserName = "TEST", Id = "a" });
|
||||
|
||||
// [Test]
|
||||
// public async Task GetNewRequests_Should_ReturnEmpty_WhenThereAreNoNewRequests()
|
||||
// {
|
||||
// var requests = new List<MovieRequests>
|
||||
// {
|
||||
// new MovieRequests { Available = true },
|
||||
// new MovieRequests { Approved = true },
|
||||
// };
|
||||
_repoMock = new Mock<IMovieRequestRepository>();
|
||||
var requestServiceMock = new Mock<IRequestServiceMain>();
|
||||
requestServiceMock.Setup(x => x.MovieRequestService).Returns(_repoMock.Object);
|
||||
|
||||
// var r = DbHelper.GetQueryable(requests[0], requests[1]);
|
||||
// RequestService.Setup(x => x.Get()).Returns(r);
|
||||
_mocker.Use(principle.Object);
|
||||
_mocker.Use(currentUser.Object);
|
||||
_mocker.Use(userManager.Object);
|
||||
_mocker.Use(requestServiceMock);
|
||||
|
||||
// var result = await Engine.GetNewRequests();
|
||||
_subject = _mocker.CreateInstance<MovieRequestEngine>();
|
||||
var list = DbHelper.GetQueryableMockDbSet(new RequestSubscription());
|
||||
_mocker.Setup<IRepository<RequestSubscription>, IQueryable<RequestSubscription>>(x => x.GetAll()).Returns(new List<RequestSubscription>().AsQueryable().BuildMock().Object);
|
||||
}
|
||||
|
||||
// Assert.False(result.Any());
|
||||
// }
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_PendingRequests_Non4K()
|
||||
{
|
||||
var movies = RegularRequestData();
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
// [Test]
|
||||
// public async Task GetNewRequests_Should_ReturnOnlyNewRequests_WhenThereAreMultipleRequests()
|
||||
// {
|
||||
// var requests = new List<MovieRequests>
|
||||
// {
|
||||
// new MovieRequests { Available = true },
|
||||
// new MovieRequests { Approved = true },
|
||||
// new MovieRequests(),
|
||||
// };
|
||||
// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable);
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.PendingApproval);
|
||||
|
||||
// var result = await Engine.GetNewRequests();
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
// Assert.Single(result);
|
||||
// Assert.All(result, x =>
|
||||
// {
|
||||
// Assert.False(x.Available);
|
||||
// Assert.False(x.Approved);
|
||||
// });
|
||||
// }
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_PendingRequests_4K()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.MinValue
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
// [Test]
|
||||
// public async Task GetApprovedRequests_Should_ReturnEmpty_WhenThereAreNoApprovedRequests()
|
||||
// {
|
||||
// var requests = new List<MovieRequests>
|
||||
// {
|
||||
// new MovieRequests { Available = true },
|
||||
// };
|
||||
// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable);
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.PendingApproval);
|
||||
|
||||
// var result = await Engine.GetApprovedRequests();
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
// Assert.False(result.Any());
|
||||
// }
|
||||
|
||||
// [Test]
|
||||
// public async Task GetApprovedRequests_Should_ReturnOnlyApprovedRequests_WhenThereAreMultipleRequests()
|
||||
// {
|
||||
// var requests = new List<MovieRequests>
|
||||
// {
|
||||
// new MovieRequests { Available = true },
|
||||
// new MovieRequests { Approved = true },
|
||||
// new MovieRequests(),
|
||||
// };
|
||||
// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable);
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_PendingRequests_Both4K_And_Regular()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Approved = false,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.Now
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.MinValue
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
// var result = await Engine.GetApprovedRequests();
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.PendingApproval);
|
||||
|
||||
// Assert.Single(result);
|
||||
// Assert.All(result, x =>
|
||||
// {
|
||||
// Assert.False(x.Available);
|
||||
// Assert.True(x.Approved);
|
||||
// });
|
||||
// }
|
||||
Assert.That(result.Total, Is.EqualTo(2));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
// [Test]
|
||||
// public async Task GetAvailableRequests_Should_ReturnEmpty_WhenThereAreNoAvailableRequests()
|
||||
// {
|
||||
// var requests = new List<MovieRequests>
|
||||
// {
|
||||
// new MovieRequests { Approved = true },
|
||||
// };
|
||||
// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable);
|
||||
|
||||
// var result = await Engine.GetAvailableRequests();
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_ProcessingRequests_Non4K()
|
||||
{
|
||||
var movies = RegularRequestData();
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
// Assert.False(result.Any());
|
||||
// }
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.ProcessingRequest);
|
||||
|
||||
// [Test]
|
||||
// public async Task GetAvailableRequests_Should_ReturnOnlyAvailableRequests_WhenThereAreMultipleRequests()
|
||||
// {
|
||||
// var requests = new List<MovieRequests>
|
||||
// {
|
||||
// new MovieRequests { Available = true },
|
||||
// new MovieRequests { Approved = true },
|
||||
// new MovieRequests(),
|
||||
// };
|
||||
// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable);
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
// var result = await Engine.GetAvailableRequests();
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_ProcessingRequests_4K()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.MinValue
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
// Assert.Single(result);
|
||||
// Assert.All(result, x =>
|
||||
// {
|
||||
// Assert.True(x.Available);
|
||||
// Assert.False(x.Approved);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.ProcessingRequest);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_ProcessingRequests_Both4K_And_Regular()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Approved = false,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.Now
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Approved = true,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.Now
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.ProcessingRequest);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(2));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_AvailableRequests_Non4K()
|
||||
{
|
||||
List<MovieRequests> movies = RegularRequestData();
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.Available);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_AvailableRequests_4K()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.MinValue
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Available);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_AvailableRequests_Both4K_And_Regular()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Available = true,
|
||||
Approved = false,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.Now
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Approved = true,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.Now
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Available);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(2));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_DeniedRequests_Non4K()
|
||||
{
|
||||
List<MovieRequests> movies = RegularRequestData();
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.Denied);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_DeniedRequests_4K()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.MinValue
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Denied);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(1));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task GetRequestByStatus_DeniedRequests_Both4K_And_Regular()
|
||||
{
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Available = true,
|
||||
Approved = false,
|
||||
Approved4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.Now
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved4K = false,
|
||||
Available4K = true,
|
||||
Denied = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied4K = true,
|
||||
Has4KRequest = true,
|
||||
RequestedDate = DateTime.MinValue
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Has4KRequest = true,
|
||||
Approved4K = false,
|
||||
Approved = true,
|
||||
Available4K = false,
|
||||
Denied4K = false,
|
||||
RequestedDate = DateTime.Now
|
||||
}
|
||||
};
|
||||
_repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable());
|
||||
|
||||
var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Denied);
|
||||
|
||||
Assert.That(result.Total, Is.EqualTo(2));
|
||||
Assert.That(result.Collection.First().Id, Is.EqualTo(2));
|
||||
Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
private static List<MovieRequests> RegularRequestData()
|
||||
{
|
||||
return new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id= 1,
|
||||
Approved = true,
|
||||
RequestedDate = DateTime.Now
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 2,
|
||||
Approved = false,
|
||||
Available = true,
|
||||
RequestedDate = DateTime.Now
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 3,
|
||||
Denied = true,
|
||||
RequestedDate = DateTime.Now
|
||||
},
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 4,
|
||||
Approved = false,
|
||||
RequestedDate = DateTime.Now
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
|
@ -36,6 +37,13 @@ namespace Ombi.Core.Tests.Engine
|
|||
var identityMock = new Mock<IIdentity>();
|
||||
identityMock.SetupGet(x => x.Name).Returns("Test");
|
||||
principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object);
|
||||
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identityMock.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" });
|
||||
|
||||
_mocker.Use(currentUser.Object);
|
||||
_mocker.Use(principleMock.Object);
|
||||
|
||||
_subject = _mocker.CreateInstance<RequestLimitService>();
|
||||
|
@ -429,6 +437,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
Id = "id1"
|
||||
};
|
||||
var lastWeek = new DateTime(2020, 09, 05).AddMonths(-1).AddDays(-1);
|
||||
var today = new DateTime(2020, 09, 15, 13, 0, 0);
|
||||
var log = new List<RequestLog>
|
||||
{
|
||||
new RequestLog
|
||||
|
@ -441,7 +450,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.GetRemainingMovieRequests(user);
|
||||
var result = await _subject.GetRemainingMovieRequests(user, today);
|
||||
|
||||
Assert.That(result, Is.InstanceOf<RequestQuotaCountModel>()
|
||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||
|
@ -474,7 +483,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.GetRemainingMovieRequests(user);
|
||||
var result = await _subject.GetRemainingMovieRequests(user, today);
|
||||
|
||||
Assert.That(result, Is.InstanceOf<RequestQuotaCountModel>()
|
||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||
|
@ -494,7 +503,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
MovieRequestLimitType = RequestLimitType.Month,
|
||||
Id = "id1"
|
||||
};
|
||||
var today = DateTime.UtcNow;
|
||||
var today = new DateTime(2022,2,2,13,0,0);
|
||||
var firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
|
||||
var log = new List<RequestLog>
|
||||
{
|
||||
|
@ -514,7 +523,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.GetRemainingMovieRequests(user);
|
||||
var result = await _subject.GetRemainingMovieRequests(user, today);
|
||||
|
||||
Assert.That(result, Is.InstanceOf<RequestQuotaCountModel>()
|
||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
|
@ -36,7 +37,12 @@ namespace Ombi.Core.Tests.Engine
|
|||
var identityMock = new Mock<IIdentity>();
|
||||
identityMock.SetupGet(x => x.Name).Returns("Test");
|
||||
principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object);
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identityMock.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" });
|
||||
_mocker.Use(principleMock.Object);
|
||||
_mocker.Use(currentUser.Object);
|
||||
|
||||
_subject = _mocker.CreateInstance<RequestLimitService>();
|
||||
}
|
||||
|
@ -494,7 +500,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
MusicRequestLimitType = RequestLimitType.Month,
|
||||
Id = "id1"
|
||||
};
|
||||
var today = DateTime.UtcNow;
|
||||
var today = new DateTime(2022, 2, 2, 13, 0, 0);
|
||||
var firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
|
||||
var log = new List<RequestLog>
|
||||
{
|
||||
|
@ -514,7 +520,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.GetRemainingMusicRequests(user);
|
||||
var result = await _subject.GetRemainingMusicRequests(user, today);
|
||||
|
||||
Assert.That(result, Is.InstanceOf<RequestQuotaCountModel>()
|
||||
.With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true)
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
|
@ -33,7 +34,12 @@ namespace Ombi.Core.Tests.Engine
|
|||
var identityMock = new Mock<IIdentity>();
|
||||
identityMock.SetupGet(x => x.Name).Returns("Test");
|
||||
principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object);
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identityMock.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" });
|
||||
_mocker.Use(principleMock.Object);
|
||||
_mocker.Use(currentUser.Object);
|
||||
|
||||
_subject = _mocker.CreateInstance<RequestLimitService>();
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
|
@ -32,7 +34,7 @@ namespace Ombi.Core.Tests.Engine.V2
|
|||
var requestService = new Mock<IRequestServiceMain>();
|
||||
_movieRequestRepository = new Mock<IMovieRequestRepository>();
|
||||
requestService.Setup(x => x.MovieRequestService).Returns(_movieRequestRepository.Object);
|
||||
var user = new Mock<IPrincipal>();
|
||||
var user = new Mock<ICurrentUser>();
|
||||
var notificationHelper = new Mock<INotificationHelper>();
|
||||
var rules = new Mock<IRuleEvaluator>();
|
||||
var movieSender = new Mock<IMovieSender>();
|
||||
|
@ -43,8 +45,9 @@ namespace Ombi.Core.Tests.Engine.V2
|
|||
var ombiSettings = new Mock<ISettingsService<OmbiSettings>>();
|
||||
var requestSubs = new Mock<IRepository<RequestSubscription>>();
|
||||
var mediaCache = new Mock<IMediaCacheService>();
|
||||
var featureService = new Mock<IFeatureService>();
|
||||
_engine = new MovieRequestEngine(movieApi.Object, requestService.Object, user.Object, notificationHelper.Object, rules.Object, movieSender.Object,
|
||||
logger.Object, userManager.Object, requestLogRepo.Object, cache.Object, ombiSettings.Object, requestSubs.Object, mediaCache.Object);
|
||||
logger.Object, userManager.Object, requestLogRepo.Object, cache.Object, ombiSettings.Object, requestSubs.Object, mediaCache.Object, featureService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -23,6 +23,7 @@ using Ombi.Store.Entities;
|
|||
using Ombi.Store.Repository;
|
||||
using Ombi.Test.Common;
|
||||
using Artist = Hqub.MusicBrainz.API.Entities.Artist;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Tests.Engine.V2
|
||||
{
|
||||
|
@ -45,7 +46,7 @@ namespace Ombi.Core.Tests.Engine.V2
|
|||
.ForEach(b => F.Behaviors.Remove(b));
|
||||
F.Behaviors.Add(new OmitOnRecursionBehavior());
|
||||
|
||||
var principle = new Mock<IPrincipal>();
|
||||
var principle = new Mock<ICurrentUser>();
|
||||
var requestService = new Mock<IRequestServiceMain>();
|
||||
var ruleEval = new Mock<IRuleEvaluator>();
|
||||
var um = MockHelper.MockUserManager(new List<OmbiUser>());
|
||||
|
|
|
@ -9,6 +9,7 @@ using NUnit.Framework;
|
|||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Settings;
|
||||
|
@ -32,8 +33,9 @@ namespace Ombi.Core.Tests.Engine
|
|||
TvRequestEngine = new Mock<ITvRequestEngine>();
|
||||
MovieRequestEngine = new Mock<IMovieRequestEngine>();
|
||||
MovieRequestEngine = new Mock<IMovieRequestEngine>();
|
||||
User = new Mock<IPrincipal>();
|
||||
User.Setup(x => x.Identity.Name).Returns("abc");
|
||||
User = new Mock<ICurrentUser>();
|
||||
User.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "abc" });
|
||||
|
||||
UserManager = MockHelper.MockUserManager(new List<OmbiUser> { new OmbiUser { Id = "abc", UserName = "abc", NormalizedUserName = "ABC" } });
|
||||
Rule = new Mock<IRuleEvaluator>();
|
||||
Engine = new VoteEngine(VoteRepository.Object, User.Object, UserManager.Object, Rule.Object, VoteSettings.Object, MusicRequestEngine.Object,
|
||||
|
@ -48,7 +50,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
|
||||
public Fixture F { get; set; }
|
||||
public VoteEngine Engine { get; set; }
|
||||
public Mock<IPrincipal> User { get; set; }
|
||||
public Mock<ICurrentUser> User { get; set; }
|
||||
public Mock<OmbiUserManager> UserManager { get; set; }
|
||||
public Mock<IRuleEvaluator> Rule { get; set; }
|
||||
public Mock<IRepository<Votes>> VoteRepository { get; set; }
|
||||
|
@ -83,7 +85,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
Assert.That(result.Result, Is.True);
|
||||
VoteRepository.Verify(x => x.Add(It.Is<Votes>(c => c.UserId == "abc" && c.VoteType == type)), Times.Once);
|
||||
VoteRepository.Verify(x => x.Delete(It.IsAny<Votes>()), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never);
|
||||
}
|
||||
public static IEnumerable<TestCaseData> VoteData
|
||||
{
|
||||
|
@ -129,7 +131,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
|
||||
Assert.That(result.Result, Is.False);
|
||||
VoteRepository.Verify(x => x.Delete(It.IsAny<Votes>()), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never);
|
||||
}
|
||||
public static IEnumerable<TestCaseData> AttemptedTwiceData
|
||||
{
|
||||
|
@ -175,7 +177,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
Assert.That(result.Result, Is.True);
|
||||
VoteRepository.Verify(x => x.Delete(It.IsAny<Votes>()), Times.Once);
|
||||
VoteRepository.Verify(x => x.Add(It.Is<Votes>(v => v.VoteType == type)), Times.Once);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never);
|
||||
}
|
||||
public static IEnumerable<TestCaseData> VoteConvertData
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
|
@ -9,7 +9,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture" Version="4.11.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.15.1" />
|
||||
<PackageReference Include="Moq.AutoMock" Version="3.0.0" />
|
||||
<PackageReference Include="Nunit" Version="3.12.0" />
|
||||
|
|
|
@ -10,6 +10,8 @@ using Ombi.Test.Common;
|
|||
using System.Collections.Generic;
|
||||
using Ombi.Store.Entities;
|
||||
using System;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Tests.Rule.Request
|
||||
{
|
||||
|
@ -26,23 +28,26 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public void Setup()
|
||||
{
|
||||
|
||||
PrincipalMock = new Mock<IPrincipal>();
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("abc");
|
||||
FeatureService = new Mock<IFeatureService>();
|
||||
|
||||
PrincipalMock = new Mock<ICurrentUser>();
|
||||
PrincipalMock.Setup(x => x.Username).Returns("abc");
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" });
|
||||
|
||||
UserManager = MockHelper.MockUserManager(_users);
|
||||
Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object);
|
||||
Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object, FeatureService.Object);
|
||||
}
|
||||
|
||||
|
||||
private AutoApproveRule Rule { get; set; }
|
||||
private Mock<IPrincipal> PrincipalMock { get; set; }
|
||||
private Mock<ICurrentUser> PrincipalMock { get; set; }
|
||||
private Mock<OmbiUserManager> UserManager { get; set; }
|
||||
private Mock<IFeatureService> FeatureService { get; set; }
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenAdminAndRequestMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Admin)).ReturnsAsync(true);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -64,7 +69,7 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public async Task Should_ReturnSuccess_WhenAutoApproveMovieAndRequestMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(true);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -96,7 +101,8 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenSystemUserAndRequestTV()
|
||||
{
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("sys");
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" });
|
||||
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveTv)).ReturnsAsync(false);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow };
|
||||
var result = await Rule.Execute(request);
|
||||
|
@ -137,5 +143,17 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
Assert.True(result.Success);
|
||||
Assert.False(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnFail_When4kRequestAndFeatureNotEnabled()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), It.IsAny<string>())).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.False(request.Approved);
|
||||
Assert.False(request.Approved4K);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Rule.Rules;
|
||||
using Ombi.Core.Rule.Rules.Request;
|
||||
using Ombi.Helpers;
|
||||
|
@ -26,8 +27,9 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public void Setup()
|
||||
{
|
||||
|
||||
PrincipalMock = new Mock<IPrincipal>();
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("abc");
|
||||
PrincipalMock = new Mock<ICurrentUser>();
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" });
|
||||
|
||||
|
||||
UserManager = MockHelper.MockUserManager(_users);
|
||||
Rule = new CanRequestRule(PrincipalMock.Object, UserManager.Object);
|
||||
|
@ -35,14 +37,49 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
|
||||
|
||||
private CanRequestRule Rule { get; set; }
|
||||
private Mock<IPrincipal> PrincipalMock { get; set; }
|
||||
private Mock<ICurrentUser> PrincipalMock { get; set; }
|
||||
private Mock<OmbiUserManager> UserManager { get; set; }
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovieWithMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovie4KWithMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Request4KMovie)).ReturnsAsync(true);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnFailure_WhenRequestingMovie4KWithMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Request4KMovie)).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.False(result.Success);
|
||||
Assert.False(string.IsNullOrEmpty(result.Message));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovie4KWithAutoApprove()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Request4KMovie)).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -52,7 +89,7 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public async Task Should_ReturnFail_WhenRequestingMovieWithoutMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(false);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.False(result.Success);
|
||||
|
@ -72,7 +109,8 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovieWithSystemRole()
|
||||
{
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("sys");
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" });
|
||||
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Admin)).ReturnsAsync(false);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
|
|
@ -9,7 +9,9 @@ using NUnit.Framework;
|
|||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Rule.Rules;
|
||||
using Ombi.Core.Rule.Rules.Request;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
|
@ -24,12 +26,14 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public void Setup()
|
||||
{
|
||||
ContextMock = new Mock<IMovieRequestRepository>();
|
||||
Rule = new ExistingMovieRequestRule(ContextMock.Object);
|
||||
FeatureService = new Mock<IFeatureService>();
|
||||
Rule = new ExistingMovieRequestRule(ContextMock.Object, FeatureService.Object);
|
||||
}
|
||||
|
||||
|
||||
private ExistingMovieRequestRule Rule { get; set; }
|
||||
private Mock<IMovieRequestRepository> ContextMock { get; set; }
|
||||
private Mock<IFeatureService> FeatureService { get; set; }
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_Has_Been_Requested_With_TheMovieDBId()
|
||||
|
@ -96,5 +100,82 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
Assert.That(result.Success, Is.True);
|
||||
Assert.That(result.Message, Is.Null.Or.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_HasAlready4K_Request()
|
||||
{
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "2",
|
||||
RequestType = RequestType.Movie,
|
||||
Is4kRequest = true
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
var o = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "1",
|
||||
Has4KRequest = true
|
||||
};
|
||||
var result = await Rule.Execute(o);
|
||||
|
||||
Assert.That(result.Success, Is.False);
|
||||
Assert.That(result.Message, Is.Not.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_4K_Request()
|
||||
{
|
||||
FeatureService.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true);
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "2",
|
||||
RequestType = RequestType.Movie,
|
||||
Is4kRequest = false
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
var o = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "1",
|
||||
Is4kRequest = true
|
||||
};
|
||||
var result = await Rule.Execute(o);
|
||||
|
||||
Assert.That(result.Success, Is.True);
|
||||
Assert.That(result.Message, Is.Null.Or.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_4K_Request_FeatureNotEnabled()
|
||||
{
|
||||
FeatureService.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(false);
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "2",
|
||||
RequestType = RequestType.Movie,
|
||||
Is4kRequest = false
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
var o = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "1",
|
||||
Is4kRequest = true
|
||||
};
|
||||
var result = await Rule.Execute(o);
|
||||
|
||||
Assert.That(result.Success, Is.False);
|
||||
Assert.That(result.Message, Is.Not.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using MockQueryable.Moq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Rule.Rules.Request;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
@ -176,17 +177,58 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
Assert.That(result.Success, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RequestMovie_IsSuccessful()
|
||||
{
|
||||
SetupMockData();
|
||||
|
||||
var req = new MovieRequests
|
||||
{
|
||||
RequestType = RequestType.Movie,
|
||||
TheMovieDbId = 123,
|
||||
Id = 1,
|
||||
};
|
||||
var result = await Rule.Execute(req);
|
||||
|
||||
|
||||
Assert.That(result.Success, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RequestMovie_IsAlreadyAvailable()
|
||||
{
|
||||
var content = new List<PlexServerContent> {
|
||||
new PlexServerContent
|
||||
{
|
||||
TheMovieDbId = 123.ToString(),
|
||||
}
|
||||
};
|
||||
PlexContentRepo.Setup(x => x.GetAll()).Returns(content.AsQueryable().BuildMock().Object);
|
||||
|
||||
var req = new MovieRequests
|
||||
{
|
||||
RequestType = RequestType.Movie,
|
||||
TheMovieDbId = 123,
|
||||
Id = 1,
|
||||
};
|
||||
var result = await Rule.Execute(req);
|
||||
|
||||
|
||||
Assert.That(result.Success, Is.False);
|
||||
Assert.That(result.ErrorCode, Is.EqualTo(ErrorCode.AlreadyRequested));
|
||||
}
|
||||
|
||||
private void SetupMockData()
|
||||
{
|
||||
var childRequests = new List<PlexServerContent>
|
||||
{
|
||||
new PlexServerContent
|
||||
{
|
||||
Type = PlexMediaTypeEntity.Show,
|
||||
Type = MediaType.Series,
|
||||
TheMovieDbId = "1",
|
||||
Title = "Test",
|
||||
ReleaseYear = "2001",
|
||||
Episodes = new List<PlexEpisode>
|
||||
Episodes = new List<IMediaServerEpisode>
|
||||
{
|
||||
new PlexEpisode
|
||||
{
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Rules.Search;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
|
@ -18,21 +21,23 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
public void Setup()
|
||||
{
|
||||
ContextMock = new Mock<IEmbyContentRepository>();
|
||||
SettingsMock = new Mock<ISettingsService<EmbySettings>>();
|
||||
Rule = new EmbyAvailabilityRule(ContextMock.Object, SettingsMock.Object);
|
||||
LoggerMock = new Mock<ILogger<EmbyAvailabilityRule>>();
|
||||
FeatureMock = new Mock<IFeatureService>();
|
||||
Rule = new EmbyAvailabilityRule(ContextMock.Object, LoggerMock.Object, FeatureMock.Object);
|
||||
}
|
||||
|
||||
private EmbyAvailabilityRule Rule { get; set; }
|
||||
private Mock<IEmbyContentRepository> ContextMock { get; set; }
|
||||
private Mock<ISettingsService<EmbySettings>> SettingsMock { get; set; }
|
||||
private Mock<ILogger<EmbyAvailabilityRule>> LoggerMock { get; set; }
|
||||
private Mock<IFeatureService> FeatureMock { get; set; }
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInEmby()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
ProviderId = "123"
|
||||
TheMovieDbId = "123",
|
||||
Quality = "1"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
|
@ -45,24 +50,13 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Has_Custom_Url_When_Specified_In_Settings()
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInEmby_4K()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings
|
||||
{
|
||||
Enable = true,
|
||||
Servers = new List<EmbyServers>
|
||||
{
|
||||
new EmbyServers
|
||||
{
|
||||
ServerHostname = "http://test.com/",
|
||||
ServerId = "8"
|
||||
}
|
||||
}
|
||||
});
|
||||
FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true);
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
EmbyId = 1.ToString(),
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
|
@ -71,28 +65,19 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.EmbyUrl, Is.EqualTo("http://test.com/web/index.html#!/item?id=1&serverId=8"));
|
||||
Assert.True(search.Available4K);
|
||||
Assert.False(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Uses_Default_Url_When()
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInEmby_Both()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings
|
||||
{
|
||||
Enable = true,
|
||||
Servers = new List<EmbyServers>
|
||||
{
|
||||
new EmbyServers
|
||||
{
|
||||
ServerHostname = string.Empty,
|
||||
ServerId = "8"
|
||||
}
|
||||
}
|
||||
});
|
||||
FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true);
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
EmbyId = 1.ToString()
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true,
|
||||
Quality = "1"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
|
@ -101,7 +86,8 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.EmbyUrl, Is.EqualTo("https://app.emby.media/web/index.html#!/item?id=1&serverId=8"));
|
||||
Assert.True(search.Available4K);
|
||||
Assert.True(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -30,13 +30,14 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
|
||||
|
||||
[Test]
|
||||
public async Task ShouldBe_Requested_WhenExisitngMovie()
|
||||
public async Task ShouldBe_Requested_WhenExistingMovie()
|
||||
{
|
||||
var list = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 123,
|
||||
Approved = true,
|
||||
RequestType = RequestType.Movie
|
||||
RequestType = RequestType.Movie,
|
||||
RequestedDate = System.DateTime.Now,
|
||||
};
|
||||
|
||||
MovieMock.Setup(x => x.GetRequestAsync(123)).ReturnsAsync(list);
|
||||
|
@ -130,5 +131,76 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
Assert.False(search.Approved);
|
||||
Assert.False(search.Requested);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ShouldBeFullyAvailable_NoFutureAiredEpisodes_NoRequest()
|
||||
{
|
||||
var search = new SearchTvShowViewModel()
|
||||
{
|
||||
Id = 999,
|
||||
SeasonRequests = new List<SeasonRequests>
|
||||
{
|
||||
new SeasonRequests
|
||||
{
|
||||
Episodes = new List<EpisodeRequests>
|
||||
{
|
||||
new EpisodeRequests
|
||||
{
|
||||
Available = true,
|
||||
AirDate = new System.DateTime(2020,01,01)
|
||||
},
|
||||
new EpisodeRequests
|
||||
{
|
||||
Available = true,
|
||||
AirDate = new System.DateTime(2020,01,02)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.FullyAvailable, Is.True);
|
||||
Assert.That(search.PartlyAvailable, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ShouldBeFullyAvailable_AndPartly_FutureAiredEpisodes_NoRequest()
|
||||
{
|
||||
var search = new SearchTvShowViewModel()
|
||||
{
|
||||
Id = 999,
|
||||
SeasonRequests = new List<SeasonRequests>
|
||||
{
|
||||
new SeasonRequests
|
||||
{
|
||||
Episodes = new List<EpisodeRequests>
|
||||
{
|
||||
new EpisodeRequests
|
||||
{
|
||||
Available = true,
|
||||
AirDate = new System.DateTime(2020,01,01)
|
||||
},
|
||||
new EpisodeRequests
|
||||
{
|
||||
Available = true,
|
||||
AirDate = new System.DateTime(2020,01,02)
|
||||
},
|
||||
new EpisodeRequests
|
||||
{
|
||||
Available = true,
|
||||
AirDate = new System.DateTime(2029,01,02)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.FullyAvailable, Is.True);
|
||||
Assert.That(search.PartlyAvailable, Is.True);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Rules.Search;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
|
@ -18,21 +21,23 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
public void Setup()
|
||||
{
|
||||
ContextMock = new Mock<IJellyfinContentRepository>();
|
||||
SettingsMock = new Mock<ISettingsService<JellyfinSettings>>();
|
||||
Rule = new JellyfinAvailabilityRule(ContextMock.Object, SettingsMock.Object);
|
||||
LoggerMock = new Mock<ILogger<JellyfinAvailabilityRule>>();
|
||||
FeatureMock = new Mock<IFeatureService>();
|
||||
Rule = new JellyfinAvailabilityRule(ContextMock.Object, LoggerMock.Object, FeatureMock.Object);
|
||||
}
|
||||
|
||||
private JellyfinAvailabilityRule Rule { get; set; }
|
||||
private Mock<IJellyfinContentRepository> ContextMock { get; set; }
|
||||
private Mock<ISettingsService<JellyfinSettings>> SettingsMock { get; set; }
|
||||
private Mock<ILogger<JellyfinAvailabilityRule>> LoggerMock { get; set; }
|
||||
private Mock<IFeatureService> FeatureMock { get; set; }
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
ProviderId = "123"
|
||||
TheMovieDbId = "123",
|
||||
Quality = "1080"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
|
@ -45,24 +50,13 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Has_Custom_Url_When_Specified_In_Settings()
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_4K()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings
|
||||
{
|
||||
Enable = true,
|
||||
Servers = new List<JellyfinServers>
|
||||
{
|
||||
new JellyfinServers
|
||||
{
|
||||
ServerHostname = "http://test.com/",
|
||||
ServerId = "8"
|
||||
}
|
||||
}
|
||||
});
|
||||
FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true);
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
JellyfinId = 1.ToString(),
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
|
@ -71,29 +65,37 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.JellyfinUrl, Is.EqualTo("http://test.com/web/index.html#!/details?id=1&serverId=8"));
|
||||
Assert.False(search.Available);
|
||||
Assert.True(search.Available4K);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_Both()
|
||||
{
|
||||
FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true);
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true,
|
||||
Quality = "1"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(search.Available);
|
||||
Assert.True(search.Available4K);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Uses_Default_Url_When()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings
|
||||
{
|
||||
Enable = true,
|
||||
Servers = new List<JellyfinServers>
|
||||
{
|
||||
new JellyfinServers
|
||||
{
|
||||
Ip = "8080",
|
||||
Port = 9090,
|
||||
ServerHostname = string.Empty,
|
||||
ServerId = "8"
|
||||
}
|
||||
}
|
||||
});
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
TheMovieDbId = "123",
|
||||
JellyfinId = 1.ToString()
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
|
|
|
@ -28,25 +28,67 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
{
|
||||
var list = new List<RadarrCache>(){new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 123
|
||||
TheMovieDbId = 123,
|
||||
HasRegular = true
|
||||
}}.AsQueryable();
|
||||
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
||||
var request = new SearchMovieViewModel { Id = 123 };
|
||||
var result =await Rule.Execute(request);
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnAvailabl_WhenMovieIsInRadarr_4K()
|
||||
{
|
||||
var list = new List<RadarrCache>(){new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 123,
|
||||
Has4K = true,
|
||||
HasFile = true
|
||||
}}.AsQueryable();
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
||||
var request = new SearchMovieViewModel { Id = 123 };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.False(request.Available);
|
||||
Assert.True(request.Available4K);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnAvailable_WhenMovieIsInRadarr_Both()
|
||||
{
|
||||
var list = new List<RadarrCache>(){new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 123,
|
||||
Has4K = true,
|
||||
HasRegular = true,
|
||||
HasFile = true
|
||||
}}.AsQueryable();
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
||||
var request = new SearchMovieViewModel { Id = 123 };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(request.Available);
|
||||
Assert.True(request.Available4K);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnNotApproved_WhenMovieIsNotInRadarr()
|
||||
{
|
||||
var list = DbHelper.GetQueryableMockDbSet(new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 000012
|
||||
TheMovieDbId = 000012,
|
||||
});
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
|
228
src/Ombi.Core.Tests/Senders/MassEmailSenderTests.cs
Normal file
228
src/Ombi.Core.Tests/Senders/MassEmailSenderTests.cs
Normal file
|
@ -0,0 +1,228 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using MockQueryable.Moq;
|
||||
using Moq;
|
||||
using Moq.AutoMock;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Senders;
|
||||
using Ombi.Notifications;
|
||||
using Ombi.Notifications.Models;
|
||||
using Ombi.Settings.Settings.Models.Notifications;
|
||||
using Ombi.Store.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Tests.Senders
|
||||
{
|
||||
[TestFixture]
|
||||
public class MassEmailSenderTests
|
||||
{
|
||||
|
||||
private MassEmailSender _subject;
|
||||
private AutoMocker _mocker;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mocker = new AutoMocker();
|
||||
_subject = _mocker.CreateInstance<MassEmailSender>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendMassEmail_SingleUser()
|
||||
{
|
||||
var model = new MassEmailModel
|
||||
{
|
||||
Body = "Test",
|
||||
Subject = "Subject",
|
||||
Users = new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mocker.Setup<OmbiUserManager, IQueryable<OmbiUser>>(x => x.Users).Returns(new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a",
|
||||
Email = "Test@test.com"
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.SendMassEmail(model);
|
||||
|
||||
_mocker.Verify<IEmailProvider>(x => x.SendAdHoc(It.Is<NotificationMessage>(m => m.Subject == model.Subject
|
||||
&& m.Message == model.Body
|
||||
&& m.To == "Test@test.com"), It.IsAny<EmailNotificationSettings>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendMassEmail_MultipleUsers()
|
||||
{
|
||||
var model = new MassEmailModel
|
||||
{
|
||||
Body = "Test",
|
||||
Subject = "Subject",
|
||||
Users = new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a"
|
||||
},
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "b"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mocker.Setup<OmbiUserManager, IQueryable<OmbiUser>>(x => x.Users).Returns(new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a",
|
||||
Email = "Test@test.com"
|
||||
},
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "b",
|
||||
Email = "b@test.com"
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.SendMassEmail(model);
|
||||
|
||||
_mocker.Verify<IEmailProvider>(x => x.SendAdHoc(It.Is<NotificationMessage>(m => m.Subject == model.Subject
|
||||
&& m.Message == model.Body
|
||||
&& m.To == "Test@test.com"), It.IsAny<EmailNotificationSettings>()), Times.Once);
|
||||
_mocker.Verify<IEmailProvider>(x => x.SendAdHoc(It.Is<NotificationMessage>(m => m.Subject == model.Subject
|
||||
&& m.Message == model.Body
|
||||
&& m.To == "b@test.com"), It.IsAny<EmailNotificationSettings>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendMassEmail_UserNoEmail()
|
||||
{
|
||||
var model = new MassEmailModel
|
||||
{
|
||||
Body = "Test",
|
||||
Subject = "Subject",
|
||||
Users = new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mocker.Setup<OmbiUserManager, IQueryable<OmbiUser>>(x => x.Users).Returns(new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a",
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.SendMassEmail(model);
|
||||
_mocker.Verify<ILogger<MassEmailSender>>(
|
||||
x => x.Log(
|
||||
LogLevel.Information,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.IsAny<Exception>(),
|
||||
It.IsAny<Func<It.IsAnyType, Exception, string>>()),
|
||||
Times.Once);
|
||||
|
||||
_mocker.Verify<IEmailProvider>(x => x.SendAdHoc(It.IsAny<NotificationMessage>(), It.IsAny<EmailNotificationSettings>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendMassEmail_Bcc()
|
||||
{
|
||||
var model = new MassEmailModel
|
||||
{
|
||||
Body = "Test",
|
||||
Subject = "Subject",
|
||||
Bcc = true,
|
||||
Users = new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a"
|
||||
},
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "b"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mocker.Setup<OmbiUserManager, IQueryable<OmbiUser>>(x => x.Users).Returns(new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a",
|
||||
Email = "Test@test.com"
|
||||
},
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "b",
|
||||
Email = "b@test.com"
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.SendMassEmail(model);
|
||||
|
||||
_mocker.Verify<IEmailProvider>(x => x.SendAdHoc(It.Is<NotificationMessage>(m => m.Subject == model.Subject
|
||||
&& m.Message == model.Body
|
||||
&& m.Other["bcc"] == "Test@test.com,b@test.com"), It.IsAny<EmailNotificationSettings>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendMassEmail_Bcc_NoEmails()
|
||||
{
|
||||
var model = new MassEmailModel
|
||||
{
|
||||
Body = "Test",
|
||||
Subject = "Subject",
|
||||
Bcc = true,
|
||||
Users = new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a"
|
||||
},
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "b"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mocker.Setup<OmbiUserManager, IQueryable<OmbiUser>>(x => x.Users).Returns(new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "a",
|
||||
},
|
||||
new OmbiUser
|
||||
{
|
||||
Id = "b",
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.SendMassEmail(model);
|
||||
|
||||
_mocker.Verify<IEmailProvider>(x => x.SendAdHoc(It.IsAny<NotificationMessage>(), It.IsAny<EmailNotificationSettings>()), Times.Never);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -116,16 +116,25 @@ namespace Ombi.Core.Authentication
|
|||
public async Task<OmbiUser> GetOmbiUserFromPlexToken(string plexToken)
|
||||
{
|
||||
var plexAccount = await _plexApi.GetAccount(plexToken);
|
||||
|
||||
|
||||
// Check for a ombi user
|
||||
if (plexAccount?.user != null)
|
||||
if (plexAccount?.user == null)
|
||||
{
|
||||
var potentialOmbiUser = await Users.FirstOrDefaultAsync(x =>
|
||||
x.ProviderUserId == plexAccount.user.id);
|
||||
return potentialOmbiUser;
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
var potentialOmbiUser = await Users.FirstOrDefaultAsync(x =>
|
||||
x.ProviderUserId == plexAccount.user.id);
|
||||
// Update ombi user with the token
|
||||
|
||||
if (potentialOmbiUser != null)
|
||||
{
|
||||
potentialOmbiUser.MediaServerToken = plexAccount.user.authentication_token;
|
||||
await UpdateAsync(potentialOmbiUser);
|
||||
}
|
||||
|
||||
return potentialOmbiUser;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,6 +151,10 @@ namespace Ombi.Core.Authentication
|
|||
var result = await _plexApi.SignIn(new UserRequest { password = password, login = login });
|
||||
if (result.user?.authentication_token != null)
|
||||
{
|
||||
// Update ombi user with the token
|
||||
user.MediaServerToken = result.user?.authentication_token;
|
||||
await UpdateAsync(user);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Ombi.Core.Engine
|
|||
private Dictionary<int, MovieRequests> _dbMovies;
|
||||
private Dictionary<int, TvRequests> _dbTv;
|
||||
|
||||
protected BaseMediaEngine(IPrincipal identity, IRequestServiceMain requestService,
|
||||
protected BaseMediaEngine(ICurrentUser identity, IRequestServiceMain requestService,
|
||||
IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub) : base(identity, um, rules)
|
||||
{
|
||||
RequestService = requestService;
|
||||
|
@ -78,6 +78,32 @@ namespace Ombi.Core.Engine
|
|||
return _dbTv;
|
||||
}
|
||||
|
||||
protected async Task<RequestEngineResult> CheckCanManageRequest(BaseRequest request) {
|
||||
var errorResult = new RequestEngineResult {
|
||||
Result = false,
|
||||
ErrorCode = ErrorCode.NoPermissions
|
||||
};
|
||||
var successResult = new RequestEngineResult { Result = true };
|
||||
|
||||
// Admins can always manage requests
|
||||
var isAdmin = await IsInRole(OmbiRoles.PowerUser) || await IsInRole(OmbiRoles.Admin);
|
||||
if (isAdmin) {
|
||||
return successResult;
|
||||
}
|
||||
|
||||
// Users with 'ManageOwnRequests' can only manage their own requests
|
||||
var canManageOwnRequests = await IsInRole(OmbiRoles.ManageOwnRequests);
|
||||
if (!canManageOwnRequests) {
|
||||
return errorResult;
|
||||
}
|
||||
var isRequestedBySameUser = ( await GetUser() ).Id == request.RequestedUser?.Id;
|
||||
if (isRequestedBySameUser) {
|
||||
return successResult;
|
||||
}
|
||||
|
||||
return errorResult;
|
||||
}
|
||||
|
||||
public RequestCountModel RequestCount()
|
||||
{
|
||||
var movieQuery = MovieRepository.GetAll();
|
||||
|
|
|
@ -11,6 +11,7 @@ using Ombi.Api.TheMovieDb;
|
|||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Config;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo
|
|||
{
|
||||
public class DemoMovieSearchEngine : MovieSearchEngine, IDemoMovieSearchEngine
|
||||
{
|
||||
public DemoMovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
public DemoMovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
ILogger<MovieSearchEngine> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s,
|
||||
IRepository<RequestSubscription> sub, IOptions<DemoLists> lists)
|
||||
: base(identity, service, movApi, mapper, logger, r, um, mem, s, sub)
|
||||
|
|
|
@ -4,6 +4,7 @@ using Ombi.Api.Trakt;
|
|||
using Ombi.Api.TvMaze;
|
||||
using Ombi.Config;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo
|
|||
public class DemoTvSearchEngine : TvSearchEngine, IDemoTvSearchEngine
|
||||
{
|
||||
|
||||
public DemoTvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
public DemoTvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache,
|
||||
ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub, IOptions<DemoLists> lists, IImageService imageService,
|
||||
ISettingsService<CustomizationSettings> custom)
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Ombi.Core.Engine
|
|||
Task<int> GetTotal();
|
||||
Task<RequestEngineResult> MarkAvailable(int modelId);
|
||||
Task<RequestEngineResult> MarkUnavailable(int modelId);
|
||||
Task RemoveAlbumRequest(int requestId);
|
||||
Task<RequestEngineResult> RemoveAlbumRequest(int requestId);
|
||||
Task<RequestEngineResult> RequestAlbum(MusicAlbumRequestViewModel model);
|
||||
Task<IEnumerable<AlbumRequest>> SearchAlbumRequest(string search);
|
||||
Task<bool> UserHasRequest(string userId);
|
||||
|
|
|
@ -1,42 +1,35 @@
|
|||
using System;
|
||||
using Ombi.Core.Rule;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine.Interfaces
|
||||
{
|
||||
public abstract class BaseEngine
|
||||
{
|
||||
protected BaseEngine(IPrincipal user, OmbiUserManager um, IRuleEvaluator rules)
|
||||
protected BaseEngine(ICurrentUser user, OmbiUserManager um, IRuleEvaluator rules)
|
||||
{
|
||||
UserPrinciple = user;
|
||||
CurrentUser = user;
|
||||
Rules = rules;
|
||||
UserManager = um;
|
||||
}
|
||||
|
||||
protected IPrincipal UserPrinciple { get; }
|
||||
protected ICurrentUser CurrentUser { get; }
|
||||
protected IRuleEvaluator Rules { get; }
|
||||
protected OmbiUserManager UserManager { get; }
|
||||
protected string Username => UserPrinciple.Identity.Name;
|
||||
protected OmbiUserManager UserManager { get; }
|
||||
protected string Username => CurrentUser.Username;
|
||||
protected Task<OmbiUser> GetUser() => CurrentUser.GetUser();
|
||||
|
||||
private OmbiUser _user;
|
||||
protected async Task<OmbiUser> GetUser()
|
||||
{
|
||||
if(!Username.HasValue())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var username = Username.ToUpper();
|
||||
return _user ??= await UserManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
|
||||
}
|
||||
/// <summary>
|
||||
/// Only used for background tasks
|
||||
/// </summary>
|
||||
public void SetUser(OmbiUser user) => CurrentUser.SetUser(user);
|
||||
|
||||
protected async Task<string> UserAlias()
|
||||
{
|
||||
|
@ -45,9 +38,14 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
|
||||
protected async Task<bool> IsInRole(string roleName)
|
||||
{
|
||||
return await UserManager.IsInRoleAsync(await GetUser(), roleName);
|
||||
if (Username.Equals("API", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var user = await GetUser();
|
||||
return await UserManager.IsInRoleAsync(user, roleName);
|
||||
}
|
||||
|
||||
|
||||
public async Task<IEnumerable<RuleResult>> RunRequestRules(BaseRequest model)
|
||||
{
|
||||
var ruleResults = await Rules.StartRequestRules(model);
|
||||
|
|
|
@ -14,13 +14,13 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
Task<IEnumerable<MovieRequests>> SearchMovieRequest(string search);
|
||||
Task<RequestEngineResult> RequestCollection(int collectionId, CancellationToken cancellationToken);
|
||||
|
||||
Task RemoveMovieRequest(int requestId);
|
||||
Task<RequestEngineResult> RemoveMovieRequest(int requestId);
|
||||
Task RemoveAllMovieRequests();
|
||||
Task<MovieRequests> GetRequest(int requestId);
|
||||
Task<MovieRequests> UpdateMovieRequest(MovieRequests request);
|
||||
Task<RequestEngineResult> ApproveMovie(MovieRequests request);
|
||||
Task<RequestEngineResult> ApproveMovieById(int requestId);
|
||||
Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason);
|
||||
Task<RequestEngineResult> ApproveMovie(MovieRequests request, bool is4K);
|
||||
Task<RequestEngineResult> ApproveMovieById(int requestId, bool is4K);
|
||||
Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason, bool is4K);
|
||||
Task<RequestsViewModel<MovieRequests>> GetRequests(int count, int position, string sortProperty, string sortOrder);
|
||||
|
||||
Task<RequestsViewModel<MovieRequests>> GetUnavailableRequests(int count, int position, string sortProperty,
|
||||
|
|
|
@ -19,11 +19,12 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
Task<IEnumerable<T>> GetRequests();
|
||||
Task<bool> UserHasRequest(string userId);
|
||||
|
||||
Task<RequestEngineResult> MarkUnavailable(int modelId);
|
||||
Task<RequestEngineResult> MarkAvailable(int modelId);
|
||||
Task<RequestEngineResult> MarkUnavailable(int modelId, bool is4K);
|
||||
Task<RequestEngineResult> MarkAvailable(int modelId, bool is4K);
|
||||
Task<int> GetTotal();
|
||||
Task UnSubscribeRequest(int requestId, RequestType type);
|
||||
Task SubscribeToRequest(int requestId, RequestType type);
|
||||
Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken);
|
||||
Task<RequestEngineResult> ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken);
|
||||
void SetUser(OmbiUser user);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
Task<TvRequests> UpdateTvRequest(TvRequests request);
|
||||
Task<IEnumerable<ChildRequests>> GetAllChldren(int tvId);
|
||||
Task<ChildRequests> UpdateChildRequest(ChildRequests request);
|
||||
Task RemoveTvChild(int requestId);
|
||||
Task<RequestEngineResult> RemoveTvChild(int requestId);
|
||||
Task<RequestEngineResult> ApproveChildRequest(int id);
|
||||
Task<IEnumerable<TvRequests>> GetRequestsLite();
|
||||
Task UpdateQualityProfile(int requestId, int profileId);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Models.Search.V2;
|
||||
|
||||
|
@ -10,6 +11,7 @@ namespace Ombi.Core
|
|||
{
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token);
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId, CancellationToken token);
|
||||
Task<ActorCredits> GetTvByActor(int actorId, string langCode);
|
||||
Task<IEnumerable<StreamingData>> GetStreamInformation(int movieDbId, CancellationToken cancellationToken);
|
||||
Task<IEnumerable<SearchTvShowViewModel>> Popular(int currentlyLoaded, int amountToLoad, string langCustomCode = null);
|
||||
Task<IEnumerable<SearchTvShowViewModel>> Anticipated(int currentlyLoaded, int amountToLoad);
|
||||
|
|
|
@ -22,15 +22,18 @@ using Ombi.Store.Entities.Requests;
|
|||
using Ombi.Store.Repository;
|
||||
using Ombi.Core.Models;
|
||||
using System.Threading;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
public class MovieRequestEngine : BaseMediaEngine, IMovieRequestEngine
|
||||
{
|
||||
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user,
|
||||
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, ICurrentUser user,
|
||||
INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger<MovieRequestEngine> log,
|
||||
OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache,
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService)
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService,
|
||||
IFeatureService featureService)
|
||||
: base(user, requestService, r, manager, cache, ombiSettings, sub)
|
||||
{
|
||||
MovieApi = movieApi;
|
||||
|
@ -39,6 +42,7 @@ namespace Ombi.Core.Engine
|
|||
Logger = log;
|
||||
_requestLog = rl;
|
||||
_mediaCacheService = mediaCacheService;
|
||||
_featureService = featureService;
|
||||
}
|
||||
|
||||
private IMovieDbApi MovieApi { get; }
|
||||
|
@ -47,6 +51,7 @@ namespace Ombi.Core.Engine
|
|||
private ILogger<MovieRequestEngine> Logger { get; }
|
||||
private readonly IRepository<RequestLog> _requestLog;
|
||||
private readonly IMediaCacheService _mediaCacheService;
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
/// <summary>
|
||||
/// Requests the movie.
|
||||
|
@ -72,7 +77,8 @@ namespace Ombi.Core.Engine
|
|||
var userDetails = await GetUser();
|
||||
var canRequestOnBehalf = model.RequestOnBehalf.HasValue();
|
||||
|
||||
var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin);
|
||||
var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser)
|
||||
|| await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin);
|
||||
if (canRequestOnBehalf && !isAdmin)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -93,32 +99,60 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
var requestModel = new MovieRequests
|
||||
var is4kFeatureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests);
|
||||
var is4kRequest = is4kFeatureEnabled && model.Is4kRequest;
|
||||
|
||||
MovieRequests requestModel;
|
||||
bool isExisting = false;
|
||||
// Do we already have a request? 4k or non 4k
|
||||
var existingRequest = await MovieRepository.GetRequestAsync(movieInfo.Id);
|
||||
if (existingRequest != null && is4kFeatureEnabled)
|
||||
{
|
||||
TheMovieDbId = movieInfo.Id,
|
||||
RequestType = RequestType.Movie,
|
||||
Overview = movieInfo.Overview,
|
||||
ImdbId = movieInfo.ImdbId,
|
||||
PosterPath = PosterPathHelper.FixPosterPath(movieInfo.PosterPath),
|
||||
Title = movieInfo.Title,
|
||||
ReleaseDate = !string.IsNullOrEmpty(movieInfo.ReleaseDate)
|
||||
? DateTime.Parse(movieInfo.ReleaseDate)
|
||||
: DateTime.MinValue,
|
||||
Status = movieInfo.Status,
|
||||
RequestedDate = DateTime.UtcNow,
|
||||
Approved = false,
|
||||
RequestedUserId = canRequestOnBehalf ? model.RequestOnBehalf : userDetails.Id,
|
||||
Background = movieInfo.BackdropPath,
|
||||
LangCode = model.LanguageCode,
|
||||
RequestedByAlias = model.RequestedByAlias,
|
||||
RootPathOverride = model.RootFolderOverride.GetValueOrDefault(),
|
||||
QualityOverride = model.QualityPathOverride.GetValueOrDefault()
|
||||
};
|
||||
if (model.Is4kRequest)
|
||||
{
|
||||
existingRequest.Is4kRequest = true;
|
||||
existingRequest.RequestedDate4k = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
existingRequest.RequestedDate = DateTime.Now;
|
||||
}
|
||||
isExisting = true;
|
||||
requestModel = existingRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
requestModel = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = movieInfo.Id,
|
||||
RequestType = RequestType.Movie,
|
||||
Overview = movieInfo.Overview,
|
||||
ImdbId = movieInfo.ImdbId,
|
||||
PosterPath = PosterPathHelper.FixPosterPath(movieInfo.PosterPath),
|
||||
Title = movieInfo.Title,
|
||||
ReleaseDate = !string.IsNullOrEmpty(movieInfo.ReleaseDate)
|
||||
? DateTime.Parse(movieInfo.ReleaseDate)
|
||||
: DateTime.MinValue,
|
||||
Status = movieInfo.Status,
|
||||
RequestedDate = model.Is4kRequest ? DateTime.MinValue : DateTime.Now,
|
||||
Approved = false,
|
||||
Approved4K = false,
|
||||
RequestedUserId = canRequestOnBehalf ? model.RequestOnBehalf : userDetails.Id,
|
||||
Background = movieInfo.BackdropPath,
|
||||
LangCode = model.LanguageCode,
|
||||
RequestedByAlias = model.RequestedByAlias,
|
||||
RootPathOverride = model.RootFolderOverride.GetValueOrDefault(),
|
||||
QualityOverride = model.QualityPathOverride.GetValueOrDefault(),
|
||||
RequestedDate4k = model.Is4kRequest ? DateTime.Now : DateTime.MinValue,
|
||||
Is4kRequest = model.Is4kRequest,
|
||||
Source = model.Source
|
||||
};
|
||||
}
|
||||
|
||||
var usDates = movieInfo.ReleaseDates?.Results?.FirstOrDefault(x => x.IsoCode == "US");
|
||||
requestModel.DigitalReleaseDate = usDates?.ReleaseDate
|
||||
?.FirstOrDefault(x => x.Type == ReleaseDateType.Digital)?.ReleaseDate;
|
||||
|
||||
|
||||
var ruleResults = (await RunRequestRules(requestModel)).ToList();
|
||||
var ruleResultInError = ruleResults.Find(x => !x.Success);
|
||||
if (ruleResultInError != null)
|
||||
|
@ -130,12 +164,12 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
if (requestModel.Approved) // The rules have auto approved this
|
||||
if (requestModel.Approved || requestModel.Approved4K) // The rules have auto approved this
|
||||
{
|
||||
var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf);
|
||||
var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf, isExisting, is4kRequest);
|
||||
if (requestEngineResult.Result)
|
||||
{
|
||||
var result = await ApproveMovie(requestModel);
|
||||
var result = await ApproveMovie(requestModel, model.Is4kRequest);
|
||||
if (result.IsError)
|
||||
{
|
||||
Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message);
|
||||
|
@ -153,7 +187,7 @@ namespace Ombi.Core.Engine
|
|||
// If there are no providers then it's successful but movie has not been sent
|
||||
}
|
||||
|
||||
return await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf);
|
||||
return await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf, isExisting, is4kRequest);
|
||||
}
|
||||
|
||||
|
||||
|
@ -218,7 +252,7 @@ namespace Ombi.Core.Engine
|
|||
var requests = await (OrderMovies(allRequests, orderFilter.OrderType)).Skip(position).Take(count)
|
||||
.ToListAsync();
|
||||
|
||||
await CheckForSubscription(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -262,7 +296,7 @@ namespace Ombi.Core.Engine
|
|||
var total = requests.Count();
|
||||
requests = requests.Skip(position).Take(count).ToList();
|
||||
|
||||
await CheckForSubscription(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -290,21 +324,44 @@ namespace Ombi.Core.Engine
|
|||
switch (status)
|
||||
{
|
||||
case RequestStatus.PendingApproval:
|
||||
allRequests = allRequests.Where(x => !x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value));
|
||||
allRequests = allRequests.Where(x =>
|
||||
(x.RequestedDate != DateTime.MinValue && !x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value))
|
||||
||
|
||||
(x.Has4KRequest && !x.Approved4K && !x.Available4K && (!x.Denied4K.HasValue || !x.Denied4K.Value))
|
||||
);
|
||||
break;
|
||||
case RequestStatus.ProcessingRequest:
|
||||
allRequests = allRequests.Where(x => x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value));
|
||||
allRequests = allRequests.Where(x =>
|
||||
(x.RequestedDate != DateTime.MinValue && x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value))
|
||||
||
|
||||
(x.Has4KRequest && x.Approved4K && !x.Available4K && (!x.Denied4K.HasValue || !x.Denied4K.Value))
|
||||
);
|
||||
break;
|
||||
case RequestStatus.Available:
|
||||
allRequests = allRequests.Where(x => x.Available);
|
||||
allRequests = allRequests.Where(x => x.Available || x.Available4K);
|
||||
break;
|
||||
case RequestStatus.Denied:
|
||||
allRequests = allRequests.Where(x => x.Denied.HasValue && x.Denied.Value && !x.Available);
|
||||
allRequests = allRequests.Where(x =>
|
||||
(x.Denied.HasValue && x.Denied.Value && !x.Available)
|
||||
||
|
||||
(x.Has4KRequest && x.Denied4K.HasValue && x.Denied4K.Value && !x.Available4K)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var requests = allRequests.ToList();
|
||||
var total = requests.Count;
|
||||
if (total == 0)
|
||||
{
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = Enumerable.Empty<MovieRequests>(),
|
||||
Total = total
|
||||
};
|
||||
}
|
||||
|
||||
var prop = TypeDescriptor.GetProperties(typeof(MovieRequests)).Find(sortProperty, true);
|
||||
|
||||
if (sortProperty.Contains('.'))
|
||||
|
@ -317,14 +374,14 @@ namespace Ombi.Core.Engine
|
|||
//var secondProp = TypeDescriptor.GetProperties(propType).Find(properties[1], true);
|
||||
}
|
||||
|
||||
// TODO fix this so we execute this on the server
|
||||
var requests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
|
||||
requests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
|
||||
? allRequests.ToList().OrderBy(x => prop.GetValue(x)).ToList()
|
||||
: allRequests.ToList().OrderByDescending(x => prop.GetValue(x)).ToList();
|
||||
var total = requests.Count();
|
||||
|
||||
// TODO fix this so we execute this on the server
|
||||
requests = requests.Skip(position).Take(count).ToList();
|
||||
|
||||
await CheckForSubscription(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -367,7 +424,7 @@ namespace Ombi.Core.Engine
|
|||
var total = requests.Count();
|
||||
requests = requests.Skip(position).Take(count).ToList();
|
||||
|
||||
await CheckForSubscription(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -449,7 +506,7 @@ namespace Ombi.Core.Engine
|
|||
allRequests = await MovieRepository.GetWithUser().ToListAsync();
|
||||
}
|
||||
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide.UserId, allRequests);
|
||||
|
||||
return allRequests;
|
||||
}
|
||||
|
@ -457,27 +514,30 @@ namespace Ombi.Core.Engine
|
|||
public async Task<MovieRequests> GetRequest(int requestId)
|
||||
{
|
||||
var request = await MovieRepository.GetWithUser().Where(x => x.Id == requestId).FirstOrDefaultAsync();
|
||||
await CheckForSubscription(new HideResult(), new List<MovieRequests> { request });
|
||||
await CheckForSubscription((await GetUser()).Id, new List<MovieRequests> { request });
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private async Task CheckForSubscription(HideResult shouldHide, List<MovieRequests> movieRequests)
|
||||
private async Task CheckForSubscription(string UserId, List<MovieRequests> movieRequests)
|
||||
{
|
||||
var requestIds = movieRequests.Select(x => x.Id);
|
||||
var sub = await _subscriptionRepository.GetAll().Where(s =>
|
||||
s.UserId == shouldHide.UserId && requestIds.Contains(s.RequestId) && s.RequestType == RequestType.Movie)
|
||||
s.UserId == UserId && requestIds.Contains(s.RequestId) && s.RequestType == RequestType.Movie)
|
||||
.ToListAsync();
|
||||
foreach (var x in movieRequests)
|
||||
{
|
||||
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
|
||||
if (shouldHide.UserId == x.RequestedUserId)
|
||||
if (UserId == x.RequestedUserId)
|
||||
{
|
||||
x.ShowSubscribe = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
x.ShowSubscribe = true;
|
||||
if (!x.Available && !x.Available4K && (!x.Denied ?? true) && (!x.Denied4K ?? true))
|
||||
{
|
||||
x.ShowSubscribe = true;
|
||||
}
|
||||
var hasSub = sub.FirstOrDefault(r => r.RequestId == x.Id);
|
||||
x.Subscribed = hasSub != null;
|
||||
}
|
||||
|
@ -503,18 +563,18 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
|
||||
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToList();
|
||||
await CheckForSubscription(shouldHide, results);
|
||||
await CheckForSubscription(shouldHide.UserId, results);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ApproveMovieById(int requestId)
|
||||
public async Task<RequestEngineResult> ApproveMovieById(int requestId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(requestId);
|
||||
return await ApproveMovie(request);
|
||||
return await ApproveMovie(request, is4K);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason)
|
||||
public async Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
|
@ -525,13 +585,22 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
request.Denied = true;
|
||||
request.DeniedReason = denyReason;
|
||||
// We are denying a request
|
||||
await NotificationHelper.Notify(request, NotificationType.RequestDeclined);
|
||||
if (is4K)
|
||||
{
|
||||
request.Denied4K = true;
|
||||
request.DeniedReason4K = denyReason;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Denied = true;
|
||||
request.DeniedReason = denyReason;
|
||||
}
|
||||
await MovieRepository.Update(request);
|
||||
await _mediaCacheService.Purge();
|
||||
|
||||
// We are denying a request
|
||||
await NotificationHelper.Notify(request, NotificationType.RequestDeclined);
|
||||
|
||||
return new RequestEngineResult
|
||||
{
|
||||
Result = true,
|
||||
|
@ -539,7 +608,7 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ApproveMovie(MovieRequests request)
|
||||
public async Task<RequestEngineResult> ApproveMovie(MovieRequests request, bool is4K)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
|
@ -549,9 +618,18 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
request.MarkedAsApproved = DateTime.Now;
|
||||
request.Approved = true;
|
||||
request.Denied = false;
|
||||
if (is4K)
|
||||
{
|
||||
request.MarkedAsApproved4K = DateTime.Now;
|
||||
request.Approved4K = true;
|
||||
request.Denied4K = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.MarkedAsApproved = DateTime.Now;
|
||||
request.Approved = true;
|
||||
request.Denied = false;
|
||||
}
|
||||
await MovieRepository.Update(request);
|
||||
|
||||
var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification, string.Empty);
|
||||
|
@ -561,7 +639,7 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
await _mediaCacheService.Purge();
|
||||
|
||||
return await ProcessSendingMovie(request);
|
||||
return await ProcessSendingMovie(request, is4K);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> RequestCollection(int collectionId, CancellationToken cancellationToken)
|
||||
|
@ -589,11 +667,11 @@ namespace Ombi.Core.Engine
|
|||
return new RequestEngineResult { Result = true, Message = $"The collection {collections.name} has been successfully added!", RequestId = results.FirstOrDefault().RequestId };
|
||||
}
|
||||
|
||||
private async Task<RequestEngineResult> ProcessSendingMovie(MovieRequests request)
|
||||
private async Task<RequestEngineResult> ProcessSendingMovie(MovieRequests request, bool is4K)
|
||||
{
|
||||
if (request.Approved)
|
||||
if (is4K ? request.Approved4K : request.Approved)
|
||||
{
|
||||
var result = await Sender.Send(request);
|
||||
var result = await Sender.Send(request, is4K);
|
||||
if (result.Success && result.Sent)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -654,11 +732,20 @@ namespace Ombi.Core.Engine
|
|||
/// </summary>
|
||||
/// <param name="requestId">The request identifier.</param>
|
||||
/// <returns></returns>
|
||||
public async Task RemoveMovieRequest(int requestId)
|
||||
public async Task<RequestEngineResult> RemoveMovieRequest(int requestId)
|
||||
{
|
||||
var request = await MovieRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId);
|
||||
|
||||
var result = await CheckCanManageRequest(request);
|
||||
if (result.IsError)
|
||||
return result;
|
||||
|
||||
await MovieRepository.Delete(request);
|
||||
await _mediaCacheService.Purge();
|
||||
return new RequestEngineResult
|
||||
{
|
||||
Result = true,
|
||||
};
|
||||
}
|
||||
|
||||
public async Task RemoveAllMovieRequests()
|
||||
|
@ -673,7 +760,7 @@ namespace Ombi.Core.Engine
|
|||
return await MovieRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken)
|
||||
public async Task<RequestEngineResult> ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = await MovieRepository.Find(requestId);
|
||||
if (request == null)
|
||||
|
@ -685,10 +772,10 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
return await ProcessSendingMovie(request);
|
||||
return await ProcessSendingMovie(request, is4K);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> MarkUnavailable(int modelId)
|
||||
public async Task<RequestEngineResult> MarkUnavailable(int modelId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
|
@ -699,7 +786,14 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
request.Available = false;
|
||||
if (is4K)
|
||||
{
|
||||
request.Available4K = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Available = false;
|
||||
}
|
||||
await MovieRepository.Update(request);
|
||||
await _mediaCacheService.Purge();
|
||||
|
||||
|
@ -710,7 +804,7 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> MarkAvailable(int modelId)
|
||||
public async Task<RequestEngineResult> MarkAvailable(int modelId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
|
@ -720,9 +814,16 @@ namespace Ombi.Core.Engine
|
|||
ErrorMessage = "Request does not exist"
|
||||
};
|
||||
}
|
||||
|
||||
request.Available = true;
|
||||
request.MarkedAsAvailable = DateTime.Now;
|
||||
if (!is4K)
|
||||
{
|
||||
request.Available = true;
|
||||
request.MarkedAsAvailable = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Available4K = true;
|
||||
request.MarkedAsAvailable4K = DateTime.Now;
|
||||
}
|
||||
await NotificationHelper.Notify(request, NotificationType.RequestAvailable);
|
||||
await MovieRepository.Update(request);
|
||||
await _mediaCacheService.Purge();
|
||||
|
@ -734,9 +835,20 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
private async Task<RequestEngineResult> AddMovieRequest(MovieRequests model, string movieName, string requestOnBehalf)
|
||||
private async Task<RequestEngineResult> AddMovieRequest(MovieRequests model, string movieName, string requestOnBehalf, bool isExisting, bool is4k)
|
||||
{
|
||||
await MovieRepository.Add(model);
|
||||
if (is4k)
|
||||
{
|
||||
model.Has4KRequest = true;
|
||||
}
|
||||
if (!isExisting)
|
||||
{
|
||||
await MovieRepository.Add(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
await MovieRepository.Update(model);
|
||||
}
|
||||
|
||||
var result = await RunSpecificRule(model, SpecificRules.CanSendNotification, requestOnBehalf);
|
||||
if (result.Success)
|
||||
|
|
|
@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
|
|||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -15,14 +16,13 @@ using Ombi.Store.Repository;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
public class MovieSearchEngine : BaseMediaEngine, IMovieEngine
|
||||
{
|
||||
public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
public MovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
ILogger<MovieSearchEngine> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub)
|
||||
: base(identity, service, r, um, mem, s, sub)
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
langCode = await DefaultLanguageCode(langCode);
|
||||
var movieInfo = await Cache.GetOrAddAsync(nameof(LookupImdbInformation) + langCode + theMovieDbId,
|
||||
() => MovieApi.GetMovieInformationWithExtraInfo(theMovieDbId, langCode),
|
||||
() => MovieApi.GetMovieInformationWithExtraInfo(theMovieDbId, langCode),
|
||||
DateTimeOffset.Now.AddHours(12));
|
||||
var viewMovie = Mapper.Map<SearchMovieViewModel>(movieInfo);
|
||||
|
||||
|
@ -81,11 +81,11 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
|
||||
// Get this person movie credits
|
||||
var credits = await MovieApi.GetActorMovieCredits(person.id, langaugeCode);
|
||||
// Grab results from both cast and crew, prefer items in cast. we can handle directors like this.
|
||||
var movieResults = (from role in credits.cast select new { Id = role.id, Title = role.title, ReleaseDate = role.release_date }).ToList();
|
||||
var movieResults = (from role in credits.cast select new { Id = role.id, Title = role.title, ReleaseDate = role.release_date }).ToList();
|
||||
movieResults.AddRange((from job in credits.crew select new { Id = job.id, Title = job.title, ReleaseDate = job.release_date }).ToList());
|
||||
|
||||
movieResults = movieResults.Take(10).ToList();
|
||||
|
@ -120,7 +120,7 @@ namespace Ombi.Core.Engine
|
|||
/// <returns></returns>
|
||||
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies()
|
||||
{
|
||||
|
||||
|
||||
var result = await Cache.GetOrAddAsync(CacheKeys.PopularMovies, async () =>
|
||||
{
|
||||
var langCode = await DefaultLanguageCode(null);
|
||||
|
@ -160,7 +160,7 @@ namespace Ombi.Core.Engine
|
|||
var result = await Cache.GetOrAddAsync(CacheKeys.UpcomingMovies, async () =>
|
||||
{
|
||||
var langCode = await DefaultLanguageCode(null);
|
||||
return await MovieApi.Upcoming(langCode);
|
||||
return await MovieApi.UpcomingMovies(langCode);
|
||||
}, DateTimeOffset.Now.AddHours(12));
|
||||
if (result != null)
|
||||
{
|
||||
|
@ -201,7 +201,7 @@ namespace Ombi.Core.Engine
|
|||
|
||||
protected async Task<SearchMovieViewModel> ProcessSingleMovie(SearchMovieViewModel viewMovie, bool lookupExtraInfo = false)
|
||||
{
|
||||
if (lookupExtraInfo && viewMovie.ImdbId.IsNullOrEmpty())
|
||||
if (lookupExtraInfo && viewMovie.ImdbId.IsNullOrEmpty() && viewMovie.Id > 0)
|
||||
{
|
||||
var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id);
|
||||
viewMovie.Id = showInfo.Id; // TheMovieDbId
|
||||
|
@ -215,34 +215,9 @@ namespace Ombi.Core.Engine
|
|||
|
||||
await RunSearchRules(viewMovie);
|
||||
|
||||
// This requires the rules to be run first to populate the RequestId property
|
||||
await CheckForSubscription(viewMovie);
|
||||
|
||||
return viewMovie;
|
||||
}
|
||||
|
||||
private async Task CheckForSubscription(SearchMovieViewModel viewModel)
|
||||
{
|
||||
// Check if this user requested it
|
||||
var user = await GetUser();
|
||||
if (user == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var request = await RequestService.MovieRequestService.GetAll()
|
||||
.AnyAsync(x => x.RequestedUserId.Equals(user.Id) && x.TheMovieDbId == viewModel.Id);
|
||||
if (request || viewModel.Available)
|
||||
{
|
||||
viewModel.ShowSubscribe = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewModel.ShowSubscribe = true;
|
||||
var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s => s.UserId == user.Id
|
||||
&& s.RequestId == viewModel.RequestId && s.RequestType == RequestType.Movie);
|
||||
viewModel.Subscribed = sub != null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<SearchMovieViewModel> ProcessSingleMovie(MovieDbSearchResult movie)
|
||||
{
|
||||
|
|
|
@ -24,12 +24,13 @@ using Ombi.Settings.Settings.Models.External;
|
|||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository;
|
||||
using System.ComponentModel;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
public class MusicRequestEngine : BaseMediaEngine, IMusicRequestEngine
|
||||
{
|
||||
public MusicRequestEngine(IRequestServiceMain requestService, IPrincipal user,
|
||||
public MusicRequestEngine(IRequestServiceMain requestService, ICurrentUser user,
|
||||
INotificationHelper helper, IRuleEvaluator r, ILogger<MusicRequestEngine> log,
|
||||
OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache,
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, ILidarrApi lidarr,
|
||||
|
@ -269,7 +270,10 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
else
|
||||
{
|
||||
x.ShowSubscribe = true;
|
||||
if (!x.Available && (!x.Denied ?? false))
|
||||
{
|
||||
x.ShowSubscribe = true;
|
||||
}
|
||||
var hasSub = sub.FirstOrDefault(r => r.RequestId == x.Id);
|
||||
x.Subscribed = hasSub != null;
|
||||
}
|
||||
|
@ -404,10 +408,20 @@ namespace Ombi.Core.Engine
|
|||
/// </summary>
|
||||
/// <param name="requestId">The request identifier.</param>
|
||||
/// <returns></returns>
|
||||
public async Task RemoveAlbumRequest(int requestId)
|
||||
public async Task<RequestEngineResult> RemoveAlbumRequest(int requestId)
|
||||
{
|
||||
var request = await MusicRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId);
|
||||
|
||||
var result = await CheckCanManageRequest(request);
|
||||
if (result.IsError)
|
||||
return result;
|
||||
|
||||
await MusicRepository.Delete(request);
|
||||
|
||||
return new RequestEngineResult
|
||||
{
|
||||
Result = true,
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<bool> UserHasRequest(string userId)
|
||||
|
|
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