mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-23 06:25:24 -07:00
Compare commits
No commits in common. "develop" and "v4.29.1" have entirely different histories.
508 changed files with 19055 additions and 37269 deletions
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
name: "\U0001F41B Bug report"
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Logs (Logs directory where Ombi is located)**
|
||||
If applicable, a snippet of the logs that seems relevant to the bug if present.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
|
||||
**Ombi Version (please complete the following information):**
|
||||
- Version [e.g. 4.0.958]
|
||||
- Media Server [e.g. Plex]
|
||||
- Database Type: SQLite (Please change if using MySQL)
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
50
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
50
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -1,50 +0,0 @@
|
|||
name: "\U0001F41B Bug report"
|
||||
description: 'Report a reproducible bug in Ombi'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Thanks for taking the time to file a bug report! Please fill out this form as completely as possible.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
If you leave out sections there is a high likelihood your issue will be closed.
|
||||
If you have a question or you think your issue might be caused by your application code, you can get help from the community on [Discord](https://discord.gg/Sa7wNWb).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: |
|
||||
Clearly describe what the expected behavior is vs. what is actually happening. Please include any reproduction steps that is required to reproduce this issue.
|
||||
If your summary is simply, for example: "I cannot setup Plex", then you will need to [continue debugging on your own](https://docs.ombi.app/) to more precisely define your issue before proceeding.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Ombi Version
|
||||
description: What version of ombi are you running?
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What platform(s) does this occur on?
|
||||
multiple: true
|
||||
options:
|
||||
- Docker
|
||||
- Windows
|
||||
- Linux
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What database are you using?
|
||||
options:
|
||||
- SQLite (Default)
|
||||
- MySQL
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -3,8 +3,8 @@ contact_links:
|
|||
- name: Docs
|
||||
url: https://docs.ombi.app/
|
||||
about: The Ombi documentation should help guide you through installation and setup as well as help resolve common problems and answer frequently asked questions
|
||||
- name: Discord support
|
||||
url: https://discord.gg/Sa7wNWb
|
||||
- name: Reddit support
|
||||
url: https://www.reddit.com/r/Ombi
|
||||
about: Ask questions about Ombi
|
||||
- name: Feature suggestions
|
||||
url: https://ombifeatures.featureupvote.com
|
||||
|
|
26
.github/workflows/build.yml
vendored
26
.github/workflows/build.yml
vendored
|
@ -12,10 +12,10 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
node-version: '14'
|
||||
|
||||
- name: NodeModules Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node_modules-${{ hashFiles('**/yarn.lock') }}
|
||||
|
@ -27,7 +27,7 @@ jobs:
|
|||
run: yarn --cwd ./src/Ombi/ClientApp run build
|
||||
|
||||
- name: Publish UI Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: angular_dist
|
||||
path: |
|
||||
|
@ -39,10 +39,10 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
@ -84,10 +84,10 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: win-x64
|
||||
- os: win10-x64
|
||||
format: zip
|
||||
compression: zip
|
||||
- os: win-x86
|
||||
- os: win10-x86
|
||||
format: zip
|
||||
compression: zip
|
||||
- os: linux-x64
|
||||
|
@ -106,13 +106,13 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: '6.0.x'
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
@ -130,7 +130,7 @@ jobs:
|
|||
working-directory: src/Ombi
|
||||
|
||||
- name: Download Angular
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: angular_dist
|
||||
path: ~/src/Ombi/dist
|
||||
|
@ -156,7 +156,7 @@ jobs:
|
|||
directory: 'src/Ombi/${{ matrix.os }}'
|
||||
|
||||
- name: Publish Release
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}
|
||||
path: |
|
||||
|
@ -170,7 +170,7 @@ jobs:
|
|||
|
||||
- name: Download Artifacts
|
||||
id: download
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
|
@ -190,7 +190,7 @@ jobs:
|
|||
if: contains(github.ref, 'develop')
|
||||
with:
|
||||
prerelease: true
|
||||
generate_release_notes: false
|
||||
generate_release_notes: true
|
||||
body: ${{ needs.versioning.outputs.changelog }}
|
||||
name: ${{ needs.versioning.outputs.tag }}
|
||||
tag_name: ${{ needs.versioning.outputs.tag }}
|
||||
|
|
82
.github/workflows/chromatic.yml
vendored
82
.github/workflows/chromatic.yml
vendored
|
@ -1,47 +1,47 @@
|
|||
# name: 'Chromatic'
|
||||
name: 'Chromatic'
|
||||
|
||||
# # Event for the workflow
|
||||
# on:
|
||||
# push:
|
||||
# workflow_dispatch:
|
||||
# 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
|
||||
# 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@v4
|
||||
# with:
|
||||
# path: '**/node_modules'
|
||||
# key: node_modules-${{ hashFiles('**/yarn.lock') }}
|
||||
- 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: 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
|
||||
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/develop'
|
||||
# uses: chromaui/action@v1
|
||||
# with:
|
||||
# projectToken: 7c47e1a1a4bd
|
||||
# autoAcceptChanges: true # 👈 Option to accept all changes
|
||||
# workingDir: ./src/Ombi/ClientApp
|
||||
# buildScriptName: storybookbuild
|
||||
# exitOnceUploaded: true
|
||||
- name: Publish to Chromatic and auto accept changes
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
uses: chromaui/action@v1
|
||||
with:
|
||||
projectToken: 7c47e1a1a4bd
|
||||
autoAcceptChanges: true # 👈 Option to accept all changes
|
||||
workingDir: ./src/Ombi/ClientApp
|
||||
buildScriptName: storybookbuild
|
||||
exitOnceUploaded: true
|
||||
|
|
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
|
@ -37,7 +37,7 @@ jobs:
|
|||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
|
@ -48,7 +48,7 @@ jobs:
|
|||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
@ -62,4 +62,4 @@ jobs:
|
|||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
uses: github/codeql-action/analyze@v1
|
||||
|
|
|
@ -22,9 +22,9 @@ jobs:
|
|||
dotnet-version: 6.0.x
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
node-version: '14'
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
'**/node_modules'
|
||||
|
@ -43,9 +43,6 @@ jobs:
|
|||
- name: Run Docker Image
|
||||
run: nohup docker run --rm -p 5000:5000 ombi &
|
||||
|
||||
- name: Run Wiremock
|
||||
run: nohup docker run --rm -p 32400:8080 --name wiremock wiremock/wiremock:2.35.0 &
|
||||
|
||||
- name: Sleep for server to start
|
||||
run: sleep 20
|
||||
|
||||
|
@ -61,7 +58,7 @@ jobs:
|
|||
# nohup dotnet run --project ./src/Ombi -- --host http://*:3577 &
|
||||
|
||||
- name: Cypress Tests
|
||||
uses: cypress-io/github-action@v4
|
||||
uses: cypress-io/github-action@v2.8.2
|
||||
with:
|
||||
record: true
|
||||
browser: chrome
|
||||
|
@ -73,9 +70,3 @@ jobs:
|
|||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Stop Docker
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -q | xargs -I {} docker logs {}
|
||||
docker container kill $(docker ps -q)
|
16
.github/workflows/pr.yml
vendored
16
.github/workflows/pr.yml
vendored
|
@ -17,10 +17,10 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
node-version: '14'
|
||||
|
||||
- name: NodeModules Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node_modules-${{ hashFiles('**/yarn.lock') }}
|
||||
|
@ -38,10 +38,10 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
@ -76,10 +76,10 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: win-x64
|
||||
- os: win10-x64
|
||||
format: zip
|
||||
compression: zip
|
||||
- os: win-x86
|
||||
- os: win10-x86
|
||||
format: zip
|
||||
compression: zip
|
||||
- os: linux-x64
|
||||
|
@ -98,10 +98,10 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Nuget Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -7,7 +7,7 @@
|
|||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
|
@ -252,4 +252,3 @@ _Pvt_Extensions
|
|||
/src/Ombi/healthchecksdb
|
||||
/src/Ombi/ClientApp/package-lock.json
|
||||
/src/Ombi.Core/Properties/launchSettings.json
|
||||
.yarn
|
||||
|
|
1840
CHANGELOG.md
1840
CHANGELOG.md
File diff suppressed because it is too large
Load diff
1233
assets/Ombi-icon.ai
1233
assets/Ombi-icon.ai
File diff suppressed because one or more lines are too long
2309
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
Normal file
2309
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
Normal file
File diff suppressed because it is too large
Load diff
440
src/.idea/.idea.Ombi/.idea/dbnavigator.xml
generated
440
src/.idea/.idea.Ombi/.idea/dbnavigator.xml
generated
|
@ -1,440 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DBNavigator.Project.DDLFileAttachmentManager">
|
||||
<mappings />
|
||||
<preferences />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseAssistantManager">
|
||||
<assistants />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseBrowserManager">
|
||||
<autoscroll-to-editor value="false" />
|
||||
<autoscroll-from-editor value="true" />
|
||||
<show-object-properties value="true" />
|
||||
<loaded-nodes />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||
<open-files />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ExecutionManager">
|
||||
<retain-sticky-names value="false" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ParserDiagnosticsManager">
|
||||
<diagnostics-history />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.Settings">
|
||||
<connections />
|
||||
<browser-settings>
|
||||
<general>
|
||||
<display-mode value="TABBED" />
|
||||
<navigation-history-size value="100" />
|
||||
<show-object-details value="false" />
|
||||
<enable-sticky-paths value="true" />
|
||||
</general>
|
||||
<filters>
|
||||
<object-type-filter>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="true" />
|
||||
<object-type name="ROLE" enabled="true" />
|
||||
<object-type name="PRIVILEGE" enabled="true" />
|
||||
<object-type name="CHARSET" enabled="true" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||
<object-type name="NESTED_TABLE" enabled="true" />
|
||||
<object-type name="COLUMN" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="true" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||
<object-type name="ARGUMENT" enabled="true" />
|
||||
<object-type name="JAVA_CLASS" enabled="true" />
|
||||
<object-type name="JAVA_INNER_CLASS" enabled="true" />
|
||||
<object-type name="JAVA_FIELD" enabled="true" />
|
||||
<object-type name="JAVA_METHOD" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="true" />
|
||||
<object-type name="CLUSTER" enabled="true" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
<object-type name="CREDENTIAL" enabled="true" />
|
||||
<object-type name="AI_PROFILE" enabled="true" />
|
||||
</object-type-filter>
|
||||
</filters>
|
||||
<sorting>
|
||||
<object-type name="COLUMN" sorting-type="NAME" />
|
||||
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
|
||||
</sorting>
|
||||
<default-editors>
|
||||
<object-type name="VIEW" editor-type="SELECTION" />
|
||||
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||
<object-type name="TYPE" editor-type="SELECTION" />
|
||||
</default-editors>
|
||||
</browser-settings>
|
||||
<navigation-settings>
|
||||
<lookup-filters>
|
||||
<lookup-objects>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="false" />
|
||||
<object-type name="ROLE" enabled="false" />
|
||||
<object-type name="PRIVILEGE" enabled="false" />
|
||||
<object-type name="CHARSET" enabled="false" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="false" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="JAVA CLASS" enabled="true" />
|
||||
<object-type name="INNER CLASS" enabled="true" />
|
||||
<object-type name="JAVA FIELD" enabled="true" />
|
||||
<object-type name="JAVA METHOD" enabled="true" />
|
||||
<object-type name="JAVA PARAMETER" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="false" />
|
||||
<object-type name="CLUSTER" enabled="false" />
|
||||
<object-type name="DBLINK" enabled="false" />
|
||||
<object-type name="CREDENTIAL" enabled="false" />
|
||||
</lookup-objects>
|
||||
<force-database-load value="false" />
|
||||
<prompt-connection-selection value="true" />
|
||||
<prompt-schema-selection value="true" />
|
||||
</lookup-filters>
|
||||
</navigation-settings>
|
||||
<dataset-grid-settings>
|
||||
<general>
|
||||
<enable-zooming value="true" />
|
||||
<enable-column-tooltip value="true" />
|
||||
</general>
|
||||
<sorting>
|
||||
<nulls-first value="true" />
|
||||
<max-sorting-columns value="4" />
|
||||
</sorting>
|
||||
<audit-columns>
|
||||
<column-names value="" />
|
||||
<visible value="true" />
|
||||
<editable value="false" />
|
||||
</audit-columns>
|
||||
</dataset-grid-settings>
|
||||
<dataset-editor-settings>
|
||||
<text-editor-popup>
|
||||
<active value="false" />
|
||||
<active-if-empty value="false" />
|
||||
<data-length-threshold value="100" />
|
||||
<popup-delay value="1000" />
|
||||
</text-editor-popup>
|
||||
<values-actions-popup>
|
||||
<show-popup-button value="true" />
|
||||
<element-count-threshold value="1000" />
|
||||
<data-length-threshold value="250" />
|
||||
</values-actions-popup>
|
||||
<general>
|
||||
<fetch-block-size value="100" />
|
||||
<fetch-timeout value="30" />
|
||||
<trim-whitespaces value="true" />
|
||||
<convert-empty-strings-to-null value="true" />
|
||||
<select-content-on-cell-edit value="true" />
|
||||
<large-value-preview-active value="true" />
|
||||
</general>
|
||||
<filters>
|
||||
<prompt-filter-dialog value="true" />
|
||||
<default-filter-type value="BASIC" />
|
||||
</filters>
|
||||
<qualified-text-editor text-length-threshold="300">
|
||||
<content-types>
|
||||
<content-type name="Text" enabled="true" />
|
||||
<content-type name="Properties" enabled="true" />
|
||||
<content-type name="XML" enabled="true" />
|
||||
<content-type name="DTD" enabled="true" />
|
||||
<content-type name="HTML" enabled="true" />
|
||||
<content-type name="XHTML" enabled="true" />
|
||||
<content-type name="CSS" enabled="true" />
|
||||
<content-type name="SQL" enabled="true" />
|
||||
<content-type name="PL/SQL" enabled="true" />
|
||||
<content-type name="JavaScript" enabled="true" />
|
||||
<content-type name="JSON" enabled="true" />
|
||||
<content-type name="JSON5" enabled="true" />
|
||||
<content-type name="YAML" enabled="true" />
|
||||
<content-type name="C#" enabled="true" />
|
||||
</content-types>
|
||||
</qualified-text-editor>
|
||||
<record-navigation>
|
||||
<navigation-target value="VIEWER" />
|
||||
</record-navigation>
|
||||
</dataset-editor-settings>
|
||||
<code-editor-settings>
|
||||
<general>
|
||||
<show-object-navigation-gutter value="false" />
|
||||
<show-spec-declaration-navigation-gutter value="true" />
|
||||
<enable-spellchecking value="true" />
|
||||
<enable-reference-spellchecking value="false" />
|
||||
</general>
|
||||
<confirmations>
|
||||
<save-changes value="false" />
|
||||
<revert-changes value="true" />
|
||||
<exit-on-changes value="ASK" />
|
||||
</confirmations>
|
||||
</code-editor-settings>
|
||||
<code-completion-settings>
|
||||
<filters>
|
||||
<basic-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="false" />
|
||||
<filter-element type="OBJECT" id="view" selected="false" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||
<filter-element type="OBJECT" id="index" selected="false" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||
<filter-element type="OBJECT" id="function" selected="false" />
|
||||
<filter-element type="OBJECT" id="package" selected="false" />
|
||||
<filter-element type="OBJECT" id="type" selected="false" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</basic-filter>
|
||||
<extended-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</extended-filter>
|
||||
</filters>
|
||||
<sorting enabled="true">
|
||||
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||
<sorting-element type="OBJECT" id="column" />
|
||||
<sorting-element type="OBJECT" id="table" />
|
||||
<sorting-element type="OBJECT" id="view" />
|
||||
<sorting-element type="OBJECT" id="materialized view" />
|
||||
<sorting-element type="OBJECT" id="index" />
|
||||
<sorting-element type="OBJECT" id="constraint" />
|
||||
<sorting-element type="OBJECT" id="trigger" />
|
||||
<sorting-element type="OBJECT" id="synonym" />
|
||||
<sorting-element type="OBJECT" id="sequence" />
|
||||
<sorting-element type="OBJECT" id="procedure" />
|
||||
<sorting-element type="OBJECT" id="function" />
|
||||
<sorting-element type="OBJECT" id="package" />
|
||||
<sorting-element type="OBJECT" id="type" />
|
||||
<sorting-element type="OBJECT" id="dimension" />
|
||||
<sorting-element type="OBJECT" id="cluster" />
|
||||
<sorting-element type="OBJECT" id="dblink" />
|
||||
<sorting-element type="OBJECT" id="schema" />
|
||||
<sorting-element type="OBJECT" id="role" />
|
||||
<sorting-element type="OBJECT" id="user" />
|
||||
<sorting-element type="RESERVED_WORD" id="function" />
|
||||
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||
</sorting>
|
||||
<format>
|
||||
<enforce-code-style-case value="true" />
|
||||
</format>
|
||||
</code-completion-settings>
|
||||
<execution-engine-settings>
|
||||
<statement-execution>
|
||||
<fetch-block-size value="100" />
|
||||
<execution-timeout value="20" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<focus-result value="false" />
|
||||
<prompt-execution value="false" />
|
||||
</statement-execution>
|
||||
<script-execution>
|
||||
<command-line-interfaces />
|
||||
<execution-timeout value="300" />
|
||||
</script-execution>
|
||||
<method-execution>
|
||||
<execution-timeout value="30" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<parameter-history-size value="10" />
|
||||
</method-execution>
|
||||
</execution-engine-settings>
|
||||
<operation-settings>
|
||||
<transactions>
|
||||
<uncommitted-changes>
|
||||
<on-project-close value="ASK" />
|
||||
<on-disconnect value="ASK" />
|
||||
<on-autocommit-toggle value="ASK" />
|
||||
</uncommitted-changes>
|
||||
<multiple-uncommitted-changes>
|
||||
<on-commit value="ASK" />
|
||||
<on-rollback value="ASK" />
|
||||
</multiple-uncommitted-changes>
|
||||
</transactions>
|
||||
<session-browser>
|
||||
<disconnect-session value="ASK" />
|
||||
<kill-session value="ASK" />
|
||||
<reload-on-filter-change value="false" />
|
||||
</session-browser>
|
||||
<compiler>
|
||||
<compile-type value="KEEP" />
|
||||
<compile-dependencies value="ASK" />
|
||||
<always-show-controls value="false" />
|
||||
</compiler>
|
||||
</operation-settings>
|
||||
<ddl-file-settings>
|
||||
<extensions>
|
||||
<mapping file-type-id="VIEW" extensions="vw" />
|
||||
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||
<mapping file-type-id="JAVA_SOURCE" extensions="sql" />
|
||||
</extensions>
|
||||
<general>
|
||||
<lookup-ddl-files value="true" />
|
||||
<create-ddl-files value="false" />
|
||||
<synchronize-ddl-files value="true" />
|
||||
<use-qualified-names value="false" />
|
||||
<make-scripts-rerunnable value="true" />
|
||||
</general>
|
||||
</ddl-file-settings>
|
||||
<assistant-settings>
|
||||
<credential-settings>
|
||||
<credentials />
|
||||
</credential-settings>
|
||||
</assistant-settings>
|
||||
<general-settings>
|
||||
<regional-settings>
|
||||
<date-format value="MEDIUM" />
|
||||
<number-format value="UNGROUPED" />
|
||||
<locale value="SYSTEM_DEFAULT" />
|
||||
<use-custom-formats value="false" />
|
||||
</regional-settings>
|
||||
<environment>
|
||||
<environment-types>
|
||||
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||
</environment-types>
|
||||
<visibility-settings>
|
||||
<connection-tabs value="true" />
|
||||
<dialog-headers value="true" />
|
||||
<object-editor-tabs value="true" />
|
||||
<script-editor-tabs value="false" />
|
||||
<execution-result-tabs value="true" />
|
||||
</visibility-settings>
|
||||
</environment>
|
||||
</general-settings>
|
||||
</component>
|
||||
</project>
|
2
src/.idea/.idea.Ombi/.idea/indexLayout.xml
generated
2
src/.idea/.idea.Ombi/.idea/indexLayout.xml
generated
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<component name="ContentModelUserStore">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
|
|
8
src/.idea/.idea.Ombi/.idea/modules.xml
generated
Normal file
8
src/.idea/.idea.Ombi/.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/.idea.Ombi/riderModule.iml" filepath="$PROJECT_DIR$/.idea/.idea.Ombi/riderModule.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RiderProjectSettingsUpdater">
|
||||
<option name="singleClickDiffPreview" value="1" />
|
||||
<option name="vcsConfiguration" value="3" />
|
||||
</component>
|
||||
</project>
|
222
src/.idea/.idea.Ombi/.idea/workspace.xml
generated
222
src/.idea/.idea.Ombi/.idea/workspace.xml
generated
|
@ -1,20 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="57001998-efde-494a-80b3-d7acfc91f770" name="Default Changelist" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/Ombi/ClientApp/src/app/settings/plex/plex.component.html" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi/ClientApp/src/app/settings/plex/plex.component.html" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Ombi.Core/Engine/Interfaces/IMusicSearchEngineV2.cs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Ombi.Core/Models/Search/V2/Music/ArtistInformation.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.Ombi/.idea/contentModel.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Ombi/.idea/contentModel.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.Ombi/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Ombi/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/config/applicationhost.config" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/config/applicationhost.config" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Ombi.Api.MusicBrainz/Models/Artist/ArtistInformation.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi.Api.MusicBrainz/Models/Artist/ArtistInformation.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Ombi.DependencyInjection/IocExtensions.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi.DependencyInjection/IocExtensions.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Ombi/ClientApp/src/app/media-details/components/artist/artist-details.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi/ClientApp/src/app/media-details/components/artist/artist-details.component.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Ombi/ClientApp/src/app/services/searchV2.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi/ClientApp/src/app/services/searchV2.service.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Ombi/Controllers/V2/SearchController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi/Controllers/V2/SearchController.cs" afterDir="false" />
|
||||
</list>
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="DpaMonitoringSettings">
|
||||
<option name="firstShow" value="false" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
|
@ -232,75 +237,27 @@
|
|||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
||||
</component>
|
||||
<component name="GitHubPullRequestSearchHistory">{
|
||||
"lastFilter": {
|
||||
"state": "OPEN",
|
||||
"assignee": "tidusjar"
|
||||
}
|
||||
}</component>
|
||||
<component name="GitToolBoxStore">
|
||||
<option name="recentBranches">
|
||||
<RecentBranches>
|
||||
<option name="branchesForRepo">
|
||||
<list>
|
||||
<RecentBranchesForRepo>
|
||||
<option name="branches">
|
||||
<list>
|
||||
<RecentBranch>
|
||||
<option name="branchName" value="wizard-database" />
|
||||
<option name="lastUsedInstant" value="1735917525" />
|
||||
</RecentBranch>
|
||||
<RecentBranch>
|
||||
<option name="branchName" value="develop" />
|
||||
<option name="lastUsedInstant" value="1735917524" />
|
||||
</RecentBranch>
|
||||
</list>
|
||||
</option>
|
||||
<option name="repositoryRootUrl" value="file://$PROJECT_DIR$/.." />
|
||||
</RecentBranchesForRepo>
|
||||
</list>
|
||||
</option>
|
||||
</RecentBranches>
|
||||
</option>
|
||||
</component>
|
||||
<component name="GithubProjectSettings">
|
||||
<option name="branchProtectionPatterns">
|
||||
<list>
|
||||
<option value="master" />
|
||||
<option value="develop" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="GithubPullRequestsUISettings">{
|
||||
"selectedUrlAndAccountId": {
|
||||
"url": "https://github.com/ombi-app/ombi",
|
||||
"accountId": "22dd09fe-fb9e-48a4-bfcc-3c152edf3f25"
|
||||
}
|
||||
}</component>
|
||||
<component name="HighlightingSettingsPerFile">
|
||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/990126b794024fe2bd16aebdd37eba1d7b600/93/25662f04/ServerVersion.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/3bd4df5aff92cabbc4d630be64227073db1b8539b3a1e47786b4b189d7cdb7/DbContext.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/449b441523c469ed34ff5a5e14f0bafcd8f097aa463655303dc19048fa44ac3/EntityFrameworkServiceCollectionExtensions.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/7d81b2d4f22bee75e5438c707251ae43cb0974c207db91ffc159118c84b4eb9/ServiceProvider.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/a424e6912048b4cd25715f158e789aae24db5c2911d9e622d39bc6ac3246c6/MySqlConnectionStringBuilder.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/bd1d5c50194fea68ff3559c160230b0ab50f5acf4ce3061bffd6d62958e2182/ExceptionDispatchInfo.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/e9881a453a581134c1a18331ac1f8f1201a5382a685bf2a40777fa22619/DbContextOptions`.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/IMusicBrainzApi.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/Interfaces/IMusicSearchEngineV2.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/MusicSearchEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/RecentlyAddedEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/UserStatsEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/V2/IMultiSearchEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Models/Search/V2/Music/ArtistInformation.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.DependencyInjection/IocExtensions.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Helpers.Tests/EmbyHelperTests.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Schedule.Tests/OmbiQuartzTests.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi/Controllers/V1/TokenController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/Models/Artist/ArtistInformation.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi/Controllers/V2/SearchController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.DependencyInjection/IocExtensions.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/V2/IMultiSearchEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/IMusicBrainzApi.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/Interfaces/IMusicSearchEngineV2.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Models/Search/V2/Music/ArtistInformation.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="mock:///Dummy.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/RecentlyAddedEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="mock:///Dummy.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi/Controllers/V1/TokenController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/MusicSearchEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi/Program.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Ombi.Core/Engine/UserStatsEngine.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="mock:///Dummy.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
|
@ -318,17 +275,12 @@
|
|||
<component name="PackageJsonUpdateNotifier">
|
||||
<dismissed value="$PROJECT_DIR$/Ombi/ClientApp/package.json" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"customColor": "",
|
||||
"associatedIndex": 0
|
||||
}</component>
|
||||
<component name="ProjectFrameBounds" extendedState="6">
|
||||
<option name="x" value="1087" />
|
||||
<option name="y" value="-1113" />
|
||||
<option name="width" value="1400" />
|
||||
<option name="height" value="1000" />
|
||||
</component>
|
||||
<component name="ProjectId" id="2wGwbN5gDqLwyiO1WJdlwJzZ5M9" />
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
|
||||
<ConfirmationsSetting value="2" id="Add" />
|
||||
</component>
|
||||
|
@ -391,26 +343,27 @@
|
|||
<pane id="FileSystemExplorer" />
|
||||
</panes>
|
||||
</component>
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
<component name="PropertiesComponent">
|
||||
<property name="ASKED_SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
||||
<property name="Rider.DefaultBreakpoints.AreToggled" value="true" />
|
||||
<property name="Rider.ProjectViewActivator.IsNotFirstRun" value="true" />
|
||||
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="nodejs_package_manager_path" value="npm" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
".NET Launch Settings Profile.Ombi.Schedule.Tests.executor": "Run",
|
||||
".NET Launch Settings Profile.Ombi.executor": "Debug",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"fb34c741-04ca-4b4f-8ea1-651a011b42c8.executor": "Debug",
|
||||
"git-widget-placeholder": "watchlist-expired-notification",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "yarn",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RunManager" selected=".NET Launch Settings Profile.Ombi">
|
||||
<component name="RunDashboard">
|
||||
<option name="ruleStates">
|
||||
<list>
|
||||
<RuleState>
|
||||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
<RuleState>
|
||||
<option name="name" value="StatusDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager" selected=".NET Launch Settings Profile.Ombi: IIS Express">
|
||||
<configuration name="Ombi" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
|
||||
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/Ombi/Ombi.csproj" />
|
||||
<option name="LAUNCH_PROFILE_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||
|
@ -423,7 +376,7 @@
|
|||
<option name="SEND_DEBUG_REQUEST" value="1" />
|
||||
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Ombi: IIS Express" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
|
||||
|
@ -438,7 +391,7 @@
|
|||
<option name="SEND_DEBUG_REQUEST" value="1" />
|
||||
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Ombi.Schedule.Tests" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
|
||||
|
@ -453,7 +406,7 @@
|
|||
<option name="SEND_DEBUG_REQUEST" value="1" />
|
||||
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Ombi.Schedule.Tests: IIS Express" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
|
||||
|
@ -468,7 +421,7 @@
|
|||
<option name="SEND_DEBUG_REQUEST" value="1" />
|
||||
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Ombi.Updater" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
|
||||
|
@ -483,11 +436,10 @@
|
|||
<option name="SEND_DEBUG_REQUEST" value="1" />
|
||||
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="57001998-efde-494a-80b3-d7acfc91f770" name="Default Changelist" comment="" />
|
||||
|
@ -496,9 +448,6 @@
|
|||
<option name="presentableId" value="Default" />
|
||||
<updated>1563957157468</updated>
|
||||
<workItem from="1563957162999" duration="5401000" />
|
||||
<workItem from="1745681294313" duration="1814000" />
|
||||
<workItem from="1747080279165" duration="838000" />
|
||||
<workItem from="1747082180432" duration="1994000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
@ -544,11 +493,7 @@
|
|||
</layout>
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="UnityProjectConfiguration" hasMinimizedUI="false" />
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
|
||||
<option name="version" value="1" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
|
@ -560,7 +505,7 @@
|
|||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||
<url>file://$PROJECT_DIR$/Ombi/Controllers/V1/TokenController.cs</url>
|
||||
<line>48</line>
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi/Controllers/V1/TokenController.cs">
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi/Controllers/V1/TokenController.cs" initialLine="48">
|
||||
<startOffsets>
|
||||
<option value="1518" />
|
||||
</startOffsets>
|
||||
|
@ -573,12 +518,12 @@
|
|||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||
<url>file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs</url>
|
||||
<line>59</line>
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" containingFunctionPresentation="Method 'MultiSearch'">
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" initialLine="59">
|
||||
<startOffsets>
|
||||
<option value="2369" />
|
||||
<option value="2276" />
|
||||
</startOffsets>
|
||||
<endOffsets>
|
||||
<option value="2576" />
|
||||
<option value="2316" />
|
||||
</endOffsets>
|
||||
</properties>
|
||||
<option name="timeStamp" value="4" />
|
||||
|
@ -586,12 +531,12 @@
|
|||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||
<url>file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs</url>
|
||||
<line>49</line>
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" containingFunctionPresentation="Method 'MultiSearch'">
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" initialLine="49">
|
||||
<startOffsets>
|
||||
<option value="1903" />
|
||||
<option value="2001" />
|
||||
</startOffsets>
|
||||
<endOffsets>
|
||||
<option value="1945" />
|
||||
<option value="2002" />
|
||||
</endOffsets>
|
||||
</properties>
|
||||
<option name="timeStamp" value="5" />
|
||||
|
@ -599,55 +544,16 @@
|
|||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||
<url>file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs</url>
|
||||
<line>30</line>
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs" containingFunctionPresentation="Method 'SearchArtist'">
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs" initialLine="30">
|
||||
<startOffsets>
|
||||
<option value="833" />
|
||||
<option value="917" />
|
||||
</startOffsets>
|
||||
<endOffsets>
|
||||
<option value="834" />
|
||||
<option value="1016" />
|
||||
</endOffsets>
|
||||
</properties>
|
||||
<option name="timeStamp" value="7" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||
<url>file://$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs</url>
|
||||
<line>110</line>
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs" containingFunctionPresentation="Method 'Execute'">
|
||||
<startOffsets>
|
||||
<option value="5123" />
|
||||
</startOffsets>
|
||||
<endOffsets>
|
||||
<option value="5206" />
|
||||
</endOffsets>
|
||||
</properties>
|
||||
<option name="timeStamp" value="10" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||
<url>file://$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs</url>
|
||||
<line>77</line>
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs" containingFunctionPresentation="Method 'Execute'">
|
||||
<startOffsets>
|
||||
<option value="3324" />
|
||||
</startOffsets>
|
||||
<endOffsets>
|
||||
<option value="3365" />
|
||||
</endOffsets>
|
||||
</properties>
|
||||
<option name="timeStamp" value="11" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||
<url>file://$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs</url>
|
||||
<line>100</line>
|
||||
<properties documentPath="$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs" containingFunctionPresentation="Method 'Execute'">
|
||||
<startOffsets>
|
||||
<option value="4602" />
|
||||
</startOffsets>
|
||||
<endOffsets>
|
||||
<option value="4636" />
|
||||
</endOffsets>
|
||||
</properties>
|
||||
<option name="timeStamp" value="12" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
<watches-manager>
|
||||
|
|
14
src/.idea/.idea.Ombi/riderModule.iml
generated
Normal file
14
src/.idea/.idea.Ombi/riderModule.iml
generated
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="RIDER_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$USER_HOME$/.nuget/packages/microsoft.net.test.sdk/16.0.1/build/netcoreapp1.0" />
|
||||
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.13.0/build/netcoreapp1.0/NUnit3.TestAdapter.dll" />
|
||||
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.13.0/build/netcoreapp1.0/NUnit3.TestAdapter.pdb" />
|
||||
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.13.0/build/netcoreapp1.0/nunit.engine.netstandard.dll" />
|
||||
<content url="file://$MODULE_DIR$/../../../CHANGELOG.md" />
|
||||
<content url="file://$MODULE_DIR$/../../../appveyor.yml" />
|
||||
<content url="file://$MODULE_DIR$/../../../build.cake" />
|
||||
<content url="file://$MODULE_DIR$/../.." />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
25
src/.vscode/tasks.json
vendored
25
src/.vscode/tasks.json
vendored
|
@ -1,31 +1,22 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"version": "0.1.0",
|
||||
"command": "dotnet",
|
||||
"isShellCommand": true,
|
||||
"args": [],
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"taskName": "build",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceRoot}/Ombi/Ombi.csproj"
|
||||
],
|
||||
"problemMatcher": "$msCompile",
|
||||
"group": {
|
||||
"_id": "build",
|
||||
"isDefault": false
|
||||
}
|
||||
"isBuildCommand": true,
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "lint",
|
||||
"type": "shell",
|
||||
"taskName": "lint",
|
||||
"command": "npm",
|
||||
"args": [
|
||||
"run",
|
||||
"lint"
|
||||
],
|
||||
"problemMatcher": []
|
||||
"isShellCommand": true,
|
||||
"args": ["run", "lint"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace Ombi.Api.Discord.Models
|
|||
{
|
||||
public string content { get; set; }
|
||||
public string username { get; set; }
|
||||
public string avatar_url { get; set; }
|
||||
public List<DiscordEmbeds> embeds { get; set; }
|
||||
}
|
||||
|
||||
|
@ -33,6 +32,7 @@ namespace Ombi.Api.Discord.Models
|
|||
{
|
||||
public string name { get; set; }
|
||||
public string url { get; set; }
|
||||
public string iconurl { get; set; }
|
||||
}
|
||||
|
||||
public class DiscordField
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace Ombi.Api.Emby
|
|||
return obj;
|
||||
}
|
||||
|
||||
public async Task<EmbyUser> LogIn(string username, string password, string apiKey, string baseUri, string clientIpAddress)
|
||||
public async Task<EmbyUser> LogIn(string username, string password, string apiKey, string baseUri)
|
||||
{
|
||||
var request = new Request("emby/users/authenticatebyname", baseUri, HttpMethod.Post);
|
||||
var body = new
|
||||
|
@ -71,11 +71,6 @@ namespace Ombi.Api.Emby
|
|||
$"MediaBrowser Client=\"Ombi\", Device=\"Ombi\", DeviceId=\"v3\", Version=\"v3\"");
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(clientIpAddress))
|
||||
{
|
||||
request.AddHeader("X-Forwarded-For", clientIpAddress);
|
||||
}
|
||||
|
||||
var obj = await Api.Request<EmbyUser>(request);
|
||||
return obj;
|
||||
}
|
||||
|
@ -253,49 +248,5 @@ namespace Ombi.Api.Emby
|
|||
req.AddContentHeader("Content-Type", "application/json");
|
||||
req.AddHeader("Device", "Ombi");
|
||||
}
|
||||
|
||||
public async Task<EmbyItemContainer<EmbyMovie>> GetMoviesPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) =>
|
||||
await GetPlayed<EmbyMovie>("Movie", apiKey, userId, baseUri, startIndex, count, parentIdFilder, "ProviderIds");
|
||||
|
||||
public async Task<EmbyItemContainer<EmbyEpisodes>> GetTvPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) =>
|
||||
await GetPlayed<EmbyEpisodes>("Episode", apiKey, userId, baseUri, startIndex, count, parentIdFilder);
|
||||
|
||||
private async Task<EmbyItemContainer<T>> GetPlayed<T>(
|
||||
string type,
|
||||
string apiKey,
|
||||
string userId,
|
||||
string baseUri,
|
||||
int startIndex,
|
||||
int count,
|
||||
string parentIdFilder = default,
|
||||
string fields = default)
|
||||
{
|
||||
var request = new Request($"emby/items", baseUri, HttpMethod.Get);
|
||||
|
||||
request.AddQueryString("Recursive", true.ToString());
|
||||
request.AddQueryString("IncludeItemTypes", type);
|
||||
if (!string.IsNullOrEmpty(fields))
|
||||
{
|
||||
request.AddQueryString("Fields", fields);
|
||||
}
|
||||
request.AddQueryString("UserId", userId);
|
||||
request.AddQueryString("isPlayed", true.ToString());
|
||||
|
||||
// paginate and display recently played items first
|
||||
request.AddQueryString("sortBy", "DatePlayed");
|
||||
request.AddQueryString("SortOrder", "Descending");
|
||||
request.AddQueryString("startIndex", startIndex.ToString());
|
||||
request.AddQueryString("limit", count.ToString());
|
||||
|
||||
if (!string.IsNullOrEmpty(parentIdFilder))
|
||||
{
|
||||
request.AddQueryString("ParentId", parentIdFilder);
|
||||
}
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
var obj = await Api.Request<EmbyItemContainer<T>>(request);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Ombi.Api.Emby
|
|||
{
|
||||
Task<EmbySystemInfo> GetSystemInformation(string apiKey, string baseUrl);
|
||||
Task<List<EmbyUser>> GetUsers(string baseUri, string apiKey);
|
||||
Task<EmbyUser> LogIn(string username, string password, string apiKey, string baseUri, string clientIpAddress);
|
||||
Task<EmbyUser> LogIn(string username, string password, string apiKey, string baseUri);
|
||||
|
||||
Task<EmbyItemContainer<EmbyMovie>> GetAllMovies(string apiKey, string parentIdFilder, int startIndex, int count, string userId,
|
||||
string baseUri);
|
||||
|
@ -32,8 +32,5 @@ namespace Ombi.Api.Emby
|
|||
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);
|
||||
|
||||
Task<EmbyItemContainer<EmbyMovie>> GetMoviesPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);
|
||||
Task<EmbyItemContainer<EmbyEpisodes>> GetTvPlayed(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri);
|
||||
}
|
||||
}
|
|
@ -5,8 +5,30 @@ namespace Ombi.Api.Emby.Models.Movie
|
|||
public class EmbyMovie
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string ServerId { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Container { get; set; }
|
||||
public DateTime PremiereDate { get; set; }
|
||||
public object[] ProductionLocations { get; set; }
|
||||
public string OfficialRating { get; set; }
|
||||
public float CommunityRating { get; set; }
|
||||
public long RunTimeTicks { get; set; }
|
||||
public string PlayAccess { get; set; }
|
||||
public int ProductionYear { get; set; }
|
||||
public bool IsPlaceHolder { get; set; }
|
||||
public bool IsHD { get; set; }
|
||||
public bool IsFolder { get; set; }
|
||||
public string Type { get; set; }
|
||||
public int LocalTrailerCount { get; set; }
|
||||
public EmbyUserdata UserData { get; set; }
|
||||
public string VideoType { get; set; }
|
||||
public EmbyImagetags ImageTags { get; set; }
|
||||
public string[] BackdropImageTags { get; set; }
|
||||
public string LocationType { get; set; }
|
||||
public string MediaType { get; set; }
|
||||
public bool HasSubtitles { get; set; }
|
||||
public int CriticRating { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public EmbyProviderids ProviderIds { get; set; }
|
||||
public EmbyMediastream[] MediaStreams { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -5,8 +5,30 @@ namespace Ombi.Api.Jellyfin.Models.Movie
|
|||
public class JellyfinMovie
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string ServerId { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Container { get; set; }
|
||||
public DateTime PremiereDate { get; set; }
|
||||
public object[] ProductionLocations { get; set; }
|
||||
public string OfficialRating { get; set; }
|
||||
public float CommunityRating { get; set; }
|
||||
public long RunTimeTicks { get; set; }
|
||||
public string PlayAccess { get; set; }
|
||||
public int ProductionYear { get; set; }
|
||||
public bool IsPlaceHolder { get; set; }
|
||||
public bool IsHD { get; set; }
|
||||
public bool IsFolder { get; set; }
|
||||
public string Type { get; set; }
|
||||
public int LocalTrailerCount { get; set; }
|
||||
public JellyfinUserdata UserData { get; set; }
|
||||
public string VideoType { get; set; }
|
||||
public JellyfinImagetags ImageTags { get; set; }
|
||||
public string[] BackdropImageTags { get; set; }
|
||||
public string LocationType { get; set; }
|
||||
public string MediaType { get; set; }
|
||||
public bool HasSubtitles { get; set; }
|
||||
public int CriticRating { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public JellyfinProviderids ProviderIds { get; set; }
|
||||
public JellyfinMediastream[] MediaStreams { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Ombi.Api.Plex
|
|||
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<PlexUsers> GetUsers(string authToken);
|
||||
Task<PlexFriends> GetUsers(string authToken);
|
||||
Task<PlexAccount> GetAccount(string authToken);
|
||||
Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId);
|
||||
Task<OAuthContainer> GetPin(int pinId);
|
||||
|
@ -29,6 +29,5 @@ namespace Ombi.Api.Plex
|
|||
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);
|
||||
Task<bool> Ping(string authToken, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
|
@ -2,42 +2,46 @@
|
|||
|
||||
namespace Ombi.Api.Plex.Models.Friends
|
||||
{
|
||||
[XmlRoot(ElementName = "User")]
|
||||
public class UserFriends
|
||||
[XmlRoot(ElementName = "Server")]
|
||||
public class Server
|
||||
{
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// Title is for Home Users only
|
||||
/// </summary>
|
||||
[XmlAttribute(AttributeName = "serverId")]
|
||||
public string ServerId { get; set; }
|
||||
[XmlAttribute(AttributeName = "machineIdentifier")]
|
||||
public string MachineIdentifier { get; set; }
|
||||
[XmlAttribute(AttributeName = "name")]
|
||||
public string Name { get; set; }
|
||||
[XmlAttribute(AttributeName = "lastSeenAt")]
|
||||
public string LastSeenAt { get; set; }
|
||||
[XmlAttribute(AttributeName = "numLibraries")]
|
||||
public string NumLibraries { get; set; }
|
||||
[XmlAttribute(AttributeName = "owned")]
|
||||
public string Owned { get; set; }
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "User")]
|
||||
public class UserFriends
|
||||
{
|
||||
[XmlElement(ElementName = "Server")]
|
||||
public Server Server { get; set; }
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public string Id { get; set; }
|
||||
[XmlAttribute(AttributeName = "title")]
|
||||
public string Title { get; set; }
|
||||
[XmlAttribute(AttributeName = "username")]
|
||||
public string Username { get; set; }
|
||||
[XmlAttribute(AttributeName = "email")]
|
||||
public string Email { get; set; }
|
||||
/// <summary>
|
||||
/// DO NOT USE THIS
|
||||
/// Home Users can actually be an unmanaged account with an email/username to log in.
|
||||
/// </summary>
|
||||
[XmlAttribute(AttributeName = "home")]
|
||||
public bool HomeUser { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "Server")]
|
||||
public PlexUserServer[] Server { get; set; }
|
||||
}
|
||||
|
||||
public class PlexUserServer
|
||||
{
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "serverId")]
|
||||
public string ServerId { get; set; }
|
||||
[XmlAttribute(AttributeName = "recommendationsPlaylistId")]
|
||||
public string RecommendationsPlaylistId { get; set; }
|
||||
[XmlAttribute(AttributeName = "thumb")]
|
||||
public string Thumb { get; set; }
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "MediaContainer")]
|
||||
public class PlexUsers
|
||||
public class PlexFriends
|
||||
{
|
||||
[XmlElement(ElementName = "User")]
|
||||
public UserFriends[] User { get; set; }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -65,10 +65,10 @@ namespace Ombi.Api.Plex
|
|||
}
|
||||
|
||||
private const string SignInUri = "https://plex.tv/users/sign_in.json";
|
||||
private const string FriendsUri = "https://plex.tv/api/users";
|
||||
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://discover.provider.plex.tv/";
|
||||
private const string WatchlistUri = "https://metadata.provider.plex.tv/";
|
||||
|
||||
/// <summary>
|
||||
/// Sign into the Plex API
|
||||
|
@ -195,12 +195,12 @@ namespace Ombi.Api.Plex
|
|||
/// </summary>
|
||||
/// <param name="authToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PlexUsers> GetUsers(string authToken)
|
||||
public async Task<PlexFriends> GetUsers(string authToken)
|
||||
{
|
||||
var request = new Request(string.Empty, FriendsUri, HttpMethod.Get, ContentType.Xml);
|
||||
await AddHeaders(request, authToken);
|
||||
|
||||
return await Api.Request<PlexUsers>(request);
|
||||
return await Api.Request<PlexFriends>(request);
|
||||
}
|
||||
|
||||
public async Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId)
|
||||
|
@ -320,30 +320,6 @@ namespace Ombi.Api.Plex
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings the Plex API to validate if a token is still valid
|
||||
/// </summary>
|
||||
/// <param name="authToken">The authentication token to validate</param>
|
||||
/// <param name="cancellationToken">Cancellation token</param>
|
||||
/// <returns>True if the token is valid, false otherwise</returns>
|
||||
public async Task<bool> Ping(string authToken, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = new Request("api/v2/ping", "https://plex.tv/", HttpMethod.Get);
|
||||
await AddHeaders(request, authToken);
|
||||
|
||||
// We don't need to parse the response, just check if the request succeeds
|
||||
await Api.Request(request, cancellationToken);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If the request fails (401, 403, etc.), the token is invalid
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds the required headers and also the authorization header
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.Radarr.Models;
|
||||
using Ombi.Api.Radarr.Models.V3;
|
||||
|
@ -15,8 +14,7 @@ namespace Ombi.Api.Radarr
|
|||
Task<MovieResponse> GetMovie(int id, string apiKey, string baseUrl);
|
||||
Task<MovieResponse> UpdateMovie(MovieResponse movie, string apiKey, string baseUrl);
|
||||
Task<bool> MovieSearch(int[] movieIds, string apiKey, string baseUrl);
|
||||
Task<RadarrAddMovie> AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath,string apiKey, string baseUrl, bool searchNow, string minimumAvailability, List<int> tags);
|
||||
Task<RadarrAddMovie> AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath,string apiKey, string baseUrl, bool searchNow, string minimumAvailability);
|
||||
Task<List<Tag>> GetTags(string apiKey, string baseUrl);
|
||||
Task<Tag> CreateTag(string apiKey, string baseUrl, string tagName);
|
||||
}
|
||||
}
|
|
@ -29,6 +29,5 @@ namespace Ombi.Api.Radarr.Models
|
|||
public int year { get; set; }
|
||||
public string minimumAvailability { get; set; }
|
||||
public long sizeOnDisk { get; set; }
|
||||
public int[] tags { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
@ -11,7 +11,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace Ombi.Api.Radarr
|
|||
return await Api.Request<MovieResponse>(request);
|
||||
}
|
||||
|
||||
public async Task<RadarrAddMovie> AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath, string apiKey, string baseUrl, bool searchNow, string minimumAvailability, List<int> tags)
|
||||
public async Task<RadarrAddMovie> AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath, string apiKey, string baseUrl, bool searchNow, string minimumAvailability)
|
||||
{
|
||||
var request = new Request("/api/v3/movie", baseUrl, HttpMethod.Post);
|
||||
|
||||
|
@ -86,8 +86,7 @@ namespace Ombi.Api.Radarr
|
|||
monitored = true,
|
||||
year = year,
|
||||
minimumAvailability = minimumAvailability,
|
||||
sizeOnDisk = 0,
|
||||
tags = tags.Any() ? tags.ToArray() : Enumerable.Empty<int>().ToArray()
|
||||
sizeOnDisk = 0
|
||||
};
|
||||
|
||||
if (searchNow)
|
||||
|
@ -157,14 +156,5 @@ namespace Ombi.Api.Radarr
|
|||
{
|
||||
request.AddHeader("X-Api-Key", key);
|
||||
}
|
||||
|
||||
public Task<Tag> CreateTag(string apiKey, string baseUrl, string tagName)
|
||||
{
|
||||
var request = new Request($"/api/v3/tag", baseUrl, HttpMethod.Post);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
request.AddJsonBody(new { Label = tagName });
|
||||
|
||||
return Api.Request<Tag>(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
@ -13,7 +13,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.Sonarr.Models;
|
||||
using System.Net.Http;
|
||||
using Ombi.Api.Sonarr.Models.V3;
|
||||
|
||||
namespace Ombi.Api.Sonarr
|
||||
|
@ -8,8 +9,5 @@ namespace Ombi.Api.Sonarr
|
|||
public interface ISonarrV3Api : ISonarrApi
|
||||
{
|
||||
Task<IEnumerable<LanguageProfiles>> LanguageProfiles(string apiKey, string baseUrl);
|
||||
Task<Tag> CreateTag(string apiKey, string baseUrl, string tagName);
|
||||
Task<Tag> GetTag(int tagId, string apiKey, string baseUrl);
|
||||
Task<List<MonitoredEpisodeResult>> MonitorEpisode(int[] episodeIds, bool monitor, string apiKey, string baseUrl);
|
||||
}
|
||||
}
|
|
@ -113,17 +113,6 @@ namespace Ombi.Api.Sonarr.Models
|
|||
public int real { get; set; }
|
||||
}
|
||||
|
||||
public class MonitoredEpisodeResult
|
||||
{
|
||||
public int seriesId { get; set; }
|
||||
public int tvdbId { get; set; }
|
||||
public int episodeFileId { get; set; }
|
||||
public int seasonNumber { get; set; }
|
||||
public int episodeNumber { get; set; }
|
||||
public string overview { get; set; }
|
||||
public bool monitored { get; set; }
|
||||
public int id { get; set; }
|
||||
}
|
||||
|
||||
public class EpisodeUpdateResult
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace Ombi.Api.Sonarr.Models
|
|||
public string seriesType { get; set; }
|
||||
public int id { get; set; }
|
||||
public List<SonarrImage> images { get; set; }
|
||||
public List<int> tags { get; set; }
|
||||
|
||||
// V3 Property
|
||||
public int languageProfileId { get; set; }
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace Ombi.Api.Sonarr.Models
|
|||
public string titleSlug { get; set; }
|
||||
public string certification { get; set; }
|
||||
public string[] genres { get; set; }
|
||||
public List<int> tags { get; set; }
|
||||
public object[] tags { get; set; }
|
||||
public DateTime added { get; set; }
|
||||
public Ratings ratings { get; set; }
|
||||
public int qualityProfileId { get; set; }
|
||||
|
|
|
@ -3,6 +3,23 @@ namespace Ombi.Api.Sonarr
|
|||
public class SystemStatus
|
||||
{
|
||||
public string version { get; set; }
|
||||
public string buildTime { get; set; }
|
||||
public bool isDebug { get; set; }
|
||||
public bool isProduction { get; set; }
|
||||
public bool isAdmin { get; set; }
|
||||
public bool isUserInteractive { get; set; }
|
||||
public string startupPath { get; set; }
|
||||
public string appData { get; set; }
|
||||
public string osVersion { get; set; }
|
||||
public bool isMonoRuntime { get; set; }
|
||||
public bool isMono { get; set; }
|
||||
public bool isLinux { get; set; }
|
||||
public bool isOsx { get; set; }
|
||||
public bool isWindows { get; set; }
|
||||
public string branch { get; set; }
|
||||
public string authentication { get; set; }
|
||||
public string sqliteVersion { get; set; }
|
||||
public string urlBase { get; set; }
|
||||
public string runtimeVersion { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Ombi.Api.Sonarr
|
|||
{
|
||||
public SonarrV3Api(IApi api) : base(api)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override string ApiBaseUrl => "/api/v3/";
|
||||
|
@ -29,30 +30,5 @@ namespace Ombi.Api.Sonarr
|
|||
request.AddHeader("X-Api-Key", apiKey);
|
||||
return await Api.Request<List<SonarrProfile>>(request);
|
||||
}
|
||||
|
||||
public Task<Tag> CreateTag(string apiKey, string baseUrl, string tagName)
|
||||
{
|
||||
var request = new Request($"{ApiBaseUrl}tag", baseUrl, HttpMethod.Post);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
request.AddJsonBody(new { Label = tagName });
|
||||
|
||||
return Api.Request<Tag>(request);
|
||||
}
|
||||
|
||||
public Task<Tag> GetTag(int tagId, string apiKey, string baseUrl)
|
||||
{
|
||||
var request = new Request($"{ApiBaseUrl}tag/{tagId}", baseUrl, HttpMethod.Get);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
|
||||
return Api.Request<Tag>(request);
|
||||
}
|
||||
|
||||
public async Task<List<MonitoredEpisodeResult>> MonitorEpisode(int[] episodeIds, bool monitor, string apiKey, string baseUrl)
|
||||
{
|
||||
var request = new Request($"{ApiBaseUrl}episode/monitor", baseUrl, HttpMethod.Put);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
request.AddJsonBody(new { episodeIds = episodeIds, monitored = monitor });
|
||||
return await Api.Request<List<MonitoredEpisodeResult>>(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
@ -11,8 +11,8 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Polly" Version="7.2.3" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -52,7 +52,6 @@ namespace Ombi.Core.Tests.Engine
|
|||
_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());
|
||||
_mocker.Setup<IUserPlayedMovieRepository, IQueryable<UserPlayedMovie>>(x => x.GetAll()).Returns(new List<UserPlayedMovie>().AsQueryable().BuildMock());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -300,13 +300,13 @@ namespace Ombi.Core.Tests.Engine
|
|||
{
|
||||
UserId = "id1",
|
||||
RequestType = RequestType.Movie,
|
||||
RequestDate = today.AddMinutes(-1),
|
||||
RequestDate = today.AddHours(-1),
|
||||
},
|
||||
new RequestLog
|
||||
{
|
||||
UserId = "id1",
|
||||
RequestType = RequestType.Movie,
|
||||
RequestDate = today.AddMinutes(-2),
|
||||
RequestDate = today.AddHours(-2),
|
||||
},
|
||||
};
|
||||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
|
|
|
@ -298,13 +298,13 @@ namespace Ombi.Core.Tests.Engine
|
|||
{
|
||||
UserId = "id1",
|
||||
RequestType = RequestType.Album,
|
||||
RequestDate = today.AddMinutes(-1),
|
||||
RequestDate = today.AddHours(-1),
|
||||
},
|
||||
new RequestLog
|
||||
{
|
||||
UserId = "id1",
|
||||
RequestType = RequestType.Album,
|
||||
RequestDate = today.AddMinutes(-2),
|
||||
RequestDate = today.AddHours(-2),
|
||||
},
|
||||
};
|
||||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
|
|
|
@ -304,7 +304,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
{
|
||||
UserId = "id1",
|
||||
RequestType = RequestType.TvShow,
|
||||
RequestDate = today.AddMinutes(-1),
|
||||
RequestDate = today.AddHours(-1),
|
||||
EpisodeCount = 1,
|
||||
},
|
||||
new RequestLog
|
||||
|
@ -312,7 +312,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
UserId = "id1",
|
||||
RequestType = RequestType.TvShow,
|
||||
EpisodeCount = 1,
|
||||
RequestDate = today.AddMinutes(-2),
|
||||
RequestDate = today.AddHours(-2),
|
||||
},
|
||||
};
|
||||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
|
@ -345,7 +345,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
{
|
||||
UserId = "id1",
|
||||
RequestType = RequestType.TvShow,
|
||||
RequestDate = today.AddMinutes(-1),
|
||||
RequestDate = today.AddHours(-1),
|
||||
EpisodeCount = 5,
|
||||
},
|
||||
new RequestLog
|
||||
|
@ -353,7 +353,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
UserId = "id1",
|
||||
RequestType = RequestType.TvShow,
|
||||
EpisodeCount = 4,
|
||||
RequestDate = today.AddMinutes(-2),
|
||||
RequestDate = today.AddHours(-2),
|
||||
},
|
||||
};
|
||||
var repoMock = _mocker.GetMock<IRepository<RequestLog>>();
|
||||
|
|
|
@ -46,9 +46,8 @@ namespace Ombi.Core.Tests.Engine.V2
|
|||
var requestSubs = new Mock<IRepository<RequestSubscription>>();
|
||||
var mediaCache = new Mock<IMediaCacheService>();
|
||||
var featureService = new Mock<IFeatureService>();
|
||||
var userPlayedMovieRepository = new Mock<IUserPlayedMovieRepository>();
|
||||
_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, featureService.Object, userPlayedMovieRepository.Object);
|
||||
logger.Object, userManager.Object, requestLogRepo.Object, cache.Object, ombiSettings.Object, requestSubs.Object, mediaCache.Object, featureService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture" Version="4.18.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
|
||||
<PackageReference Include="AutoFixture" Version="4.17.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
<PackageReference Include="Moq.AutoMock" Version="3.4.0" />
|
||||
<PackageReference Include="Nunit" Version="3.13.3" />
|
||||
|
@ -18,7 +18,8 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"></packagereference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.3.2"></packagereference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -54,17 +54,6 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
Assert.True(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenAdminAndRequest4KMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Admin)).ReturnsAsync(true);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenAdminAndRequestTV()
|
||||
{
|
||||
|
@ -87,17 +76,6 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
Assert.True(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenAutoApprove4KMovieAndRequest4KMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApprove4KMovie)).ReturnsAsync(true);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnFail_WhenAutoApproveMovie_And_RequestTV()
|
||||
{
|
||||
|
@ -137,7 +115,7 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public async Task Should_ReturnFail_WhenAutoApproveTV_And_RequestMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveTv)).ReturnsAsync(true);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -148,7 +126,7 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public async Task Should_ReturnFail_WhenNoClaimsAndRequestMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), It.IsAny<string>())).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
|
|
@ -51,20 +51,11 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovieWithAutoApproveRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(true);
|
||||
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_WhenRequestingMovie4KWithMovie4KRole()
|
||||
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, Is4kRequest = true };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -83,29 +74,15 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovie4KWithAutoApprove4K()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(false);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(false);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Request4KMovie)).ReturnsAsync(false);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApprove4KMovie)).ReturnsAsync(true);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnFailure_WhenRequestingMovie4KWithout4KRoles()
|
||||
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);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApprove4KMovie)).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.False(result.Success);
|
||||
Assert.True(result.Success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -173,7 +173,6 @@ namespace Ombi.Core.Tests.Services
|
|||
|
||||
|
||||
[Test]
|
||||
[Ignore("Flaky")]
|
||||
public async Task GetRecentlyRequested_HideUsernames()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<CustomizationSettings>, Task<CustomizationSettings>>(x => x.GetSettingsAsync())
|
||||
|
@ -183,25 +182,20 @@ namespace Ombi.Core.Tests.Services
|
|||
var releaseDate = new DateTime(2019, 01, 01);
|
||||
var requestDate = DateTime.Now;
|
||||
|
||||
var movies = _fixture.CreateMany<MovieRequests>(10).ToList();
|
||||
var movies = _fixture.CreateMany<MovieRequests>(10);
|
||||
var albums = _fixture.CreateMany<AlbumRequest>(10);
|
||||
var chilRequests = _fixture.CreateMany<ChildRequests>(10);
|
||||
movies.Add(_fixture.Build<MovieRequests>().With(x => x.RequestedUserId, "a").With(x => x.Title, "unit").Create());
|
||||
|
||||
_mocker.Setup<IMovieRequestRepository, IQueryable<MovieRequests>>(x => x.GetAll()).Returns(movies.AsQueryable().BuildMock());
|
||||
_mocker.Setup<IMusicRequestRepository, IQueryable<AlbumRequest>>(x => x.GetAll()).Returns(albums.AsQueryable().BuildMock());
|
||||
_mocker.Setup<ITvRequestRepository, IQueryable<ChildRequests>>(x => x.GetChild()).Returns(chilRequests.AsQueryable().BuildMock());
|
||||
_mocker.Setup<ICurrentUser, Task<OmbiUser>>(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "test", Id = "a", Alias = "alias", UserType = UserType.LocalUser });
|
||||
_mocker.Setup<ICurrentUser, Task<OmbiUser>>(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "test", Alias = "alias", UserType = UserType.LocalUser });
|
||||
_mocker.Setup<ICurrentUser, string>(x => x.Username).Returns("test");
|
||||
_mocker.Setup<OmbiUserManager, Task<bool>>(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), It.IsAny<string>())).ReturnsAsync(false);
|
||||
|
||||
var result = await _subject.GetRecentlyRequested(CancellationToken.None);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(result.Count, Is.EqualTo(1));
|
||||
Assert.That(result.First().Title, Is.EqualTo("unit"));
|
||||
});
|
||||
CollectionAssert.IsEmpty(result.Where(x => !string.IsNullOrEmpty(x.Username) && !string.IsNullOrEmpty(x.UserId)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,8 +69,6 @@ namespace Ombi.Core.Authentication
|
|||
private readonly ISettingsService<EmbySettings> _embySettings;
|
||||
private readonly ISettingsService<JellyfinSettings> _jellyfinSettings;
|
||||
private readonly ISettingsService<AuthenticationSettings> _authSettings;
|
||||
private string _clientIpAddress;
|
||||
public string ClientIpAddress { get => _clientIpAddress; set => _clientIpAddress = value; }
|
||||
|
||||
public override async Task<bool> CheckPasswordAsync(OmbiUser user, string password)
|
||||
{
|
||||
|
@ -90,7 +88,7 @@ namespace Ombi.Core.Authentication
|
|||
}
|
||||
if (user.UserType == UserType.EmbyUser || user.UserType == UserType.EmbyConnectUser)
|
||||
{
|
||||
return await CheckEmbyPasswordAsync(user, password, ClientIpAddress);
|
||||
return await CheckEmbyPasswordAsync(user, password);
|
||||
}
|
||||
if (user.UserType == UserType.JellyfinUser)
|
||||
{
|
||||
|
@ -170,7 +168,7 @@ namespace Ombi.Core.Authentication
|
|||
/// <param name="user"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> CheckEmbyPasswordAsync(OmbiUser user, string password, string clientIpAddress="")
|
||||
private async Task<bool> CheckEmbyPasswordAsync(OmbiUser user, string password)
|
||||
{
|
||||
var embySettings = await _embySettings.GetSettingsAsync();
|
||||
var client = _embyApi.CreateClient(embySettings);
|
||||
|
@ -198,7 +196,7 @@ namespace Ombi.Core.Authentication
|
|||
{
|
||||
try
|
||||
{
|
||||
var result = await client.LogIn(user.UserName, password, server.ApiKey, server.FullUri, clientIpAddress);
|
||||
var result = await client.LogIn(user.UserName, password, server.ApiKey, server.FullUri);
|
||||
if (result != null)
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Api.Plex;
|
||||
|
||||
namespace Ombi.Core.Authentication
|
||||
{
|
||||
public interface IPlexTokenKeepAliveService
|
||||
{
|
||||
Task<bool> KeepTokenAliveAsync(string token, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public class PlexTokenKeepAliveService : IPlexTokenKeepAliveService
|
||||
{
|
||||
private readonly IPlexApi _plexApi;
|
||||
private readonly ILogger<PlexTokenKeepAliveService> _logger;
|
||||
|
||||
public PlexTokenKeepAliveService(IPlexApi plexApi, ILogger<PlexTokenKeepAliveService> logger)
|
||||
{
|
||||
_plexApi = plexApi;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<bool> KeepTokenAliveAsync(string token, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
_logger.LogWarning("Token is null or empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use the Ping method to validate the token
|
||||
var isValid = await _plexApi.Ping(token, cancellationToken);
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
_logger.LogWarning("Token validation failed - token may be expired or invalid");
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error occurred while keeping token alive");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,8 +33,7 @@ namespace Ombi.Core.Engine
|
|||
INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger<MovieRequestEngine> log,
|
||||
OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache,
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService,
|
||||
IFeatureService featureService,
|
||||
IUserPlayedMovieRepository userPlayedMovieRepository)
|
||||
IFeatureService featureService)
|
||||
: base(user, requestService, r, manager, cache, ombiSettings, sub)
|
||||
{
|
||||
MovieApi = movieApi;
|
||||
|
@ -44,7 +43,6 @@ namespace Ombi.Core.Engine
|
|||
_requestLog = rl;
|
||||
_mediaCacheService = mediaCacheService;
|
||||
_featureService = featureService;
|
||||
_userPlayedMovieRepository = userPlayedMovieRepository;
|
||||
}
|
||||
|
||||
private IMovieDbApi MovieApi { get; }
|
||||
|
@ -54,7 +52,6 @@ namespace Ombi.Core.Engine
|
|||
private readonly IRepository<RequestLog> _requestLog;
|
||||
private readonly IMediaCacheService _mediaCacheService;
|
||||
private readonly IFeatureService _featureService;
|
||||
protected readonly IUserPlayedMovieRepository _userPlayedMovieRepository;
|
||||
|
||||
/// <summary>
|
||||
/// Requests the movie.
|
||||
|
@ -80,8 +77,7 @@ namespace Ombi.Core.Engine
|
|||
var userDetails = await GetUser();
|
||||
var canRequestOnBehalf = model.RequestOnBehalf.HasValue();
|
||||
|
||||
var isAdmin = Username.Equals("API", StringComparison.CurrentCultureIgnoreCase)
|
||||
|| await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser)
|
||||
var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser)
|
||||
|| await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin);
|
||||
if (canRequestOnBehalf && !isAdmin)
|
||||
{
|
||||
|
@ -256,7 +252,7 @@ namespace Ombi.Core.Engine
|
|||
var requests = await (OrderMovies(allRequests, orderFilter.OrderType)).Skip(position).Take(count)
|
||||
.ToListAsync();
|
||||
|
||||
await FillAdditionalFields(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -300,7 +296,7 @@ namespace Ombi.Core.Engine
|
|||
var total = requests.Count();
|
||||
requests = requests.Skip(position).Take(count).ToList();
|
||||
|
||||
await FillAdditionalFields(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -385,7 +381,7 @@ namespace Ombi.Core.Engine
|
|||
// TODO fix this so we execute this on the server
|
||||
requests = requests.Skip(position).Take(count).ToList();
|
||||
|
||||
await FillAdditionalFields(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -428,7 +424,7 @@ namespace Ombi.Core.Engine
|
|||
var total = requests.Count();
|
||||
requests = requests.Skip(position).Take(count).ToList();
|
||||
|
||||
await FillAdditionalFields(shouldHide, requests);
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
return new RequestsViewModel<MovieRequests>
|
||||
{
|
||||
Collection = requests,
|
||||
|
@ -510,25 +506,18 @@ namespace Ombi.Core.Engine
|
|||
allRequests = await MovieRepository.GetWithUser().ToListAsync();
|
||||
}
|
||||
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide.UserId, allRequests);
|
||||
|
||||
return allRequests;
|
||||
}
|
||||
|
||||
public async Task<MovieRequests> GetRequest(int requestId)
|
||||
{
|
||||
var shouldHide = await HideFromOtherUsers();
|
||||
// TODO: this query should return the request only if the user is allowed to see it (see shouldHide implementations)
|
||||
var request = await MovieRepository.GetWithUser().Where(x => x.Id == requestId).FirstOrDefaultAsync();
|
||||
await FillAdditionalFields(shouldHide, new List<MovieRequests> { request });
|
||||
await CheckForSubscription((await GetUser()).Id, new List<MovieRequests> { request });
|
||||
|
||||
return request;
|
||||
}
|
||||
private async Task FillAdditionalFields(HideResult shouldHide, List<MovieRequests> requests)
|
||||
{
|
||||
await CheckForSubscription(shouldHide.UserId, requests);
|
||||
await CheckForPlayed(shouldHide, requests);
|
||||
}
|
||||
|
||||
private async Task CheckForSubscription(string UserId, List<MovieRequests> movieRequests)
|
||||
{
|
||||
|
@ -555,23 +544,6 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
}
|
||||
|
||||
private async Task CheckForPlayed(HideResult shouldHide, List<MovieRequests> movieRequests)
|
||||
{
|
||||
var theMovieDbIds = movieRequests.Select(x => x.TheMovieDbId);
|
||||
var plays = await _userPlayedMovieRepository.GetAll().Where(x =>
|
||||
theMovieDbIds.Contains(x.TheMovieDbId))
|
||||
.ToListAsync();
|
||||
foreach (var request in movieRequests)
|
||||
{
|
||||
request.WatchedByRequestedUser = plays.Exists(x => x.TheMovieDbId == request.TheMovieDbId && x.UserId == request.RequestedUserId);
|
||||
|
||||
if (!shouldHide.Hide)
|
||||
{
|
||||
request.PlayedByUsersCount = plays.Count(x => x.TheMovieDbId == request.TheMovieDbId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches the movie request.
|
||||
/// </summary>
|
||||
|
@ -591,20 +563,20 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
|
||||
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToList();
|
||||
await FillAdditionalFields(shouldHide, results);
|
||||
await CheckForSubscription(shouldHide.UserId, results);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ApproveMovieById(int requestId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.GetWithUser().FirstOrDefaultAsync(x => x.Id == requestId);
|
||||
var request = await MovieRepository.Find(requestId);
|
||||
return await ApproveMovie(request, is4K);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.GetWithUser().FirstOrDefaultAsync(x => x.Id == modelId);
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -790,7 +762,7 @@ namespace Ombi.Core.Engine
|
|||
|
||||
public async Task<RequestEngineResult> ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = await MovieRepository.GetWithUser().FirstOrDefaultAsync(x => x.Id == requestId);
|
||||
var request = await MovieRepository.Find(requestId);
|
||||
if (request == null)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -805,7 +777,7 @@ namespace Ombi.Core.Engine
|
|||
|
||||
public async Task<RequestEngineResult> MarkUnavailable(int modelId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.GetWithUser().FirstOrDefaultAsync(x => x.Id == modelId);
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -834,7 +806,7 @@ namespace Ombi.Core.Engine
|
|||
|
||||
public async Task<RequestEngineResult> MarkAvailable(int modelId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.GetWithUser().FirstOrDefaultAsync(x => x.Id == modelId);
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
|
|
@ -35,8 +35,7 @@ namespace Ombi.Core.Engine
|
|||
public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, ICurrentUser user,
|
||||
INotificationHelper helper, IRuleEvaluator rule, OmbiUserManager manager, ILogger<TvRequestEngine> logger,
|
||||
ITvSender sender, IRepository<RequestLog> rl, ISettingsService<OmbiSettings> settings, ICacheService cache,
|
||||
IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService,
|
||||
IUserPlayedEpisodeRepository userPlayedEpisodeRepository) : base(user, requestService, rule, manager, cache, settings, sub)
|
||||
IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService) : base(user, requestService, rule, manager, cache, settings, sub)
|
||||
{
|
||||
TvApi = tvApi;
|
||||
MovieDbApi = movApi;
|
||||
|
@ -45,7 +44,6 @@ namespace Ombi.Core.Engine
|
|||
TvSender = sender;
|
||||
_requestLog = rl;
|
||||
_mediaCacheService = mediaCacheService;
|
||||
_userPlayedEpisodeRepository = userPlayedEpisodeRepository;
|
||||
}
|
||||
|
||||
private INotificationHelper NotificationHelper { get; }
|
||||
|
@ -56,7 +54,6 @@ namespace Ombi.Core.Engine
|
|||
private readonly ILogger<TvRequestEngine> _logger;
|
||||
private readonly IRepository<RequestLog> _requestLog;
|
||||
private readonly IMediaCacheService _mediaCacheService;
|
||||
private readonly IUserPlayedEpisodeRepository _userPlayedEpisodeRepository;
|
||||
|
||||
public async Task<RequestEngineResult> RequestTvShow(TvRequestViewModel tv)
|
||||
{
|
||||
|
@ -164,7 +161,7 @@ namespace Ombi.Core.Engine
|
|||
var user = await GetUser();
|
||||
var canRequestOnBehalf = tv.RequestOnBehalf.HasValue();
|
||||
|
||||
var isAdmin = Username.Equals("API", StringComparison.CurrentCultureIgnoreCase) || await UserManager.IsInRoleAsync(user, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(user, OmbiRoles.Admin);
|
||||
var isAdmin = await UserManager.IsInRoleAsync(user, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(user, OmbiRoles.Admin);
|
||||
if (tv.RequestOnBehalf.HasValue() && !isAdmin)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -295,7 +292,7 @@ namespace Ombi.Core.Engine
|
|||
.Skip(position).Take(count).ToListAsync();
|
||||
|
||||
}
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
|
||||
return new RequestsViewModel<TvRequests>
|
||||
{
|
||||
|
@ -331,7 +328,7 @@ namespace Ombi.Core.Engine
|
|||
return new RequestsViewModel<TvRequests>();
|
||||
}
|
||||
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
|
||||
return new RequestsViewModel<TvRequests>
|
||||
{
|
||||
|
@ -354,7 +351,7 @@ namespace Ombi.Core.Engine
|
|||
allRequests = await TvRepository.Get().ToListAsync();
|
||||
}
|
||||
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
return allRequests;
|
||||
}
|
||||
|
||||
|
@ -399,7 +396,7 @@ namespace Ombi.Core.Engine
|
|||
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
|
||||
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();
|
||||
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
|
||||
// Make sure we do not show duplicate child requests
|
||||
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
|
||||
|
@ -472,7 +469,7 @@ namespace Ombi.Core.Engine
|
|||
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
|
||||
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();
|
||||
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
|
||||
// Make sure we do not show duplicate child requests
|
||||
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
|
||||
|
@ -526,7 +523,7 @@ namespace Ombi.Core.Engine
|
|||
allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
|
||||
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
|
||||
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
|
||||
// Make sure we do not show duplicate child requests
|
||||
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
|
||||
|
@ -554,7 +551,7 @@ namespace Ombi.Core.Engine
|
|||
allRequests = await TvRepository.GetLite().ToListAsync();
|
||||
}
|
||||
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
return allRequests;
|
||||
}
|
||||
|
||||
|
@ -573,7 +570,7 @@ namespace Ombi.Core.Engine
|
|||
request = await TvRepository.Get().Where(x => x.Id == requestId).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
await FillAdditionalFields(shouldHide, new List<TvRequests>{request});
|
||||
await CheckForSubscription(shouldHide, new List<TvRequests>{request});
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -627,7 +624,7 @@ namespace Ombi.Core.Engine
|
|||
allRequests = await TvRepository.GetChild().Include(x => x.SeasonRequests).Where(x => x.ParentRequestId == tvId).ToListAsync();
|
||||
}
|
||||
|
||||
await FillAdditionalFields(shouldHide, allRequests);
|
||||
await CheckForSubscription(shouldHide, allRequests);
|
||||
|
||||
return allRequests;
|
||||
}
|
||||
|
@ -646,7 +643,7 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
var results = await allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToListAsync();
|
||||
|
||||
await FillAdditionalFields(shouldHide, results);
|
||||
await CheckForSubscription(shouldHide, results);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -867,20 +864,14 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
}
|
||||
|
||||
private async Task FillAdditionalFields(HideResult shouldHide, List<TvRequests> x)
|
||||
private async Task CheckForSubscription(HideResult shouldHide, List<TvRequests> x)
|
||||
{
|
||||
foreach (var tvRequest in x)
|
||||
{
|
||||
await FillAdditionalFields(shouldHide, tvRequest.ChildRequests);
|
||||
await CheckForSubscription(shouldHide, tvRequest.ChildRequests);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FillAdditionalFields(HideResult shouldHide, List<ChildRequests> childRequests)
|
||||
{
|
||||
await CheckForSubscription(shouldHide, childRequests);
|
||||
CheckForPlayed(shouldHide, childRequests);
|
||||
}
|
||||
|
||||
private async Task CheckForSubscription(HideResult shouldHide, List<ChildRequests> childRequests)
|
||||
{
|
||||
var sub = _subscriptionRepository.GetAll();
|
||||
|
@ -905,59 +896,6 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
}
|
||||
|
||||
private class EpisodeKey
|
||||
{
|
||||
public int SeasonNumber;
|
||||
public int EpisodeNumber;
|
||||
}
|
||||
|
||||
private void CheckForPlayed(HideResult shouldHide, List<ChildRequests> childRequests)
|
||||
{
|
||||
var theMovieDbIds = childRequests.Select(x => x.Id);
|
||||
foreach (var request in childRequests)
|
||||
{
|
||||
var requestedEpisodes = GetEpisodesKeys(request);
|
||||
|
||||
var playedEpisodes = _userPlayedEpisodeRepository
|
||||
.GetAll()
|
||||
.Where(x => x.TheMovieDbId == request.Id && x.UserId == request.RequestedUserId)
|
||||
.AsEnumerable()
|
||||
.Join(requestedEpisodes,
|
||||
played => new { played.SeasonNumber, played.EpisodeNumber },
|
||||
requested => new { requested.SeasonNumber, requested.EpisodeNumber },
|
||||
(played, requested) => new { played });
|
||||
|
||||
var playedCount = playedEpisodes.Count();
|
||||
var toWatchCount = requestedEpisodes.Count();
|
||||
if (playedCount == 0 || toWatchCount == 0)
|
||||
{
|
||||
request.RequestedUserPlayedProgress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.RequestedUserPlayedProgress = 100 * playedCount / toWatchCount;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private List<EpisodeKey> GetEpisodesKeys(ChildRequests request)
|
||||
{
|
||||
List<EpisodeKey> result = new List<EpisodeKey>();
|
||||
foreach(var season in request.SeasonRequests)
|
||||
{
|
||||
foreach(var episode in season.Episodes)
|
||||
{
|
||||
result.Add(new EpisodeKey
|
||||
{
|
||||
SeasonNumber = season.SeasonNumber,
|
||||
EpisodeNumber = episode.EpisodeNumber
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<RequestEngineResult> AddExistingRequest(ChildRequests newRequest, TvRequests existingRequest, string requestOnBehalf, int rootFolder, int qualityProfile)
|
||||
{
|
||||
// Add the child
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.VisualBasic;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
|
|
@ -200,14 +200,19 @@ namespace Ombi.Core.Engine.V2
|
|||
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies(int currentPosition, int amountToLoad)
|
||||
{
|
||||
var langCode = await DefaultLanguageCode(null);
|
||||
var isOldTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.OldTrendingSource);
|
||||
|
||||
var pages = PaginationHelper.GetNextPages(currentPosition, amountToLoad, _theMovieDbMaxPageItems);
|
||||
|
||||
var results = new List<MovieDbSearchResult>();
|
||||
foreach (var pagesToLoad in pages)
|
||||
{
|
||||
var search = () => (isOldTrendingSourceEnabled) ?
|
||||
MovieApi.NowPlaying(langCode, pagesToLoad.Page)
|
||||
: MovieApi.TrendingMovies(langCode, pagesToLoad.Page);
|
||||
|
||||
var apiResult = await Cache.GetOrAddAsync(nameof(NowPlayingMovies) + pagesToLoad.Page + langCode,
|
||||
() => MovieApi.TrendingMovies(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12));
|
||||
search, DateTimeOffset.Now.AddHours(12));
|
||||
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
|
||||
}
|
||||
return await TransformMovieResultsToResponse(results);
|
||||
|
|
|
@ -138,13 +138,17 @@ namespace Ombi.Core.Engine.V2
|
|||
public async Task<IEnumerable<SearchTvShowViewModel>> Trending(int currentlyLoaded, int amountToLoad)
|
||||
{
|
||||
var langCode = await DefaultLanguageCode(null);
|
||||
var isOldTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.OldTrendingSource);
|
||||
|
||||
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
|
||||
var results = new List<MovieDbSearchResult>();
|
||||
foreach (var pagesToLoad in pages)
|
||||
{
|
||||
var search = ( async () => (isOldTrendingSourceEnabled) ?
|
||||
await _movieApi.TopRatedTv(langCode, pagesToLoad.Page)
|
||||
: await _movieApi.TrendingTv(langCode, pagesToLoad.Page));
|
||||
var apiResult = await Cache.GetOrAddAsync(nameof(Trending) + langCode + pagesToLoad.Page,
|
||||
() => _movieApi.TrendingTv(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12));
|
||||
search, DateTimeOffset.Now.AddHours(12));
|
||||
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal;
|
||||
using Ombi.Core.Models;
|
||||
using Polly;
|
||||
using Pomelo.EntityFrameworkCore.MySql.Storage.Internal;
|
||||
|
||||
namespace Ombi.Core.Helpers;
|
||||
|
||||
public static class DatabaseConfigurationSetup
|
||||
{
|
||||
public static void ConfigurePostgres(DbContextOptionsBuilder options, PerDatabaseConfiguration config)
|
||||
{
|
||||
options.UseNpgsql(config.ConnectionString, b =>
|
||||
{
|
||||
b.EnableRetryOnFailure();
|
||||
}).ReplaceService<ISqlGenerationHelper, NpgsqlCaseInsensitiveSqlGenerationHelper>();
|
||||
}
|
||||
|
||||
public static void ConfigureMySql(DbContextOptionsBuilder options, PerDatabaseConfiguration config)
|
||||
{
|
||||
if (string.IsNullOrEmpty(config.ConnectionString))
|
||||
{
|
||||
throw new ArgumentNullException("ConnectionString for the MySql/Mariadb database is empty");
|
||||
}
|
||||
|
||||
options.UseMySql(config.ConnectionString, GetServerVersion(config.ConnectionString), b =>
|
||||
{
|
||||
//b.CharSetBehavior(Pomelo.EntityFrameworkCore.MySql.Infrastructure.CharSetBehavior.NeverAppend); // ##ISSUE, link to migrations?
|
||||
b.EnableRetryOnFailure();
|
||||
});
|
||||
}
|
||||
|
||||
private static ServerVersion GetServerVersion(string connectionString)
|
||||
{
|
||||
// Workaround Windows bug, that can lead to the following exception:
|
||||
//
|
||||
// MySqlConnector.MySqlException (0x80004005): SSL Authentication Error
|
||||
// ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
|
||||
// ---> System.ComponentModel.Win32Exception (0x8009030F): The message or signature supplied for verification has been altered
|
||||
//
|
||||
// See https://github.com/dotnet/runtime/issues/17005#issuecomment-305848835
|
||||
//
|
||||
// Also workaround for the fact, that ServerVersion.AutoDetect() does not use any retrying strategy.
|
||||
ServerVersion serverVersion = null;
|
||||
#pragma warning disable EF1001
|
||||
var retryPolicy = Policy.Handle<Exception>(exception => MySqlTransientExceptionDetector.ShouldRetryOn(exception))
|
||||
#pragma warning restore EF1001
|
||||
.WaitAndRetry(3, (count, context) => TimeSpan.FromMilliseconds(count * 250));
|
||||
|
||||
serverVersion = retryPolicy.Execute(() => serverVersion = ServerVersion.AutoDetect(connectionString));
|
||||
|
||||
return serverVersion;
|
||||
}
|
||||
public class NpgsqlCaseInsensitiveSqlGenerationHelper : NpgsqlSqlGenerationHelper
|
||||
{
|
||||
const string EFMigrationsHisory = "__EFMigrationsHistory";
|
||||
public NpgsqlCaseInsensitiveSqlGenerationHelper(RelationalSqlGenerationHelperDependencies dependencies)
|
||||
: base(dependencies) { }
|
||||
public override string DelimitIdentifier(string identifier) =>
|
||||
base.DelimitIdentifier(identifier == EFMigrationsHisory ? identifier : identifier.ToLower());
|
||||
public override void DelimitIdentifier(StringBuilder builder, string identifier)
|
||||
=> base.DelimitIdentifier(builder, identifier == EFMigrationsHisory ? identifier : identifier.ToLower());
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
namespace Ombi.Core.Helpers;
|
||||
|
||||
public class FileSystem : IFileSystem
|
||||
{
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
return System.IO.File.Exists(path);
|
||||
}
|
||||
// Implement other file system operations as needed
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
namespace Ombi.Core.Helpers;
|
||||
|
||||
public interface IFileSystem
|
||||
{
|
||||
bool FileExists(string path);
|
||||
// Add other file system operations as needed
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
using System.IO;
|
||||
|
||||
namespace Ombi.Core.Models;
|
||||
|
||||
public class DatabaseConfiguration
|
||||
{
|
||||
public const string SqliteDatabase = "Sqlite";
|
||||
|
||||
public DatabaseConfiguration()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DatabaseConfiguration(string defaultSqlitePath)
|
||||
{
|
||||
OmbiDatabase = new PerDatabaseConfiguration(SqliteDatabase, $"Data Source={Path.Combine(defaultSqlitePath, "Ombi.db")}");
|
||||
SettingsDatabase = new PerDatabaseConfiguration(SqliteDatabase, $"Data Source={Path.Combine(defaultSqlitePath, "OmbiSettings.db")}");
|
||||
ExternalDatabase = new PerDatabaseConfiguration(SqliteDatabase, $"Data Source={Path.Combine(defaultSqlitePath, "OmbiExternal.db")}");
|
||||
}
|
||||
public PerDatabaseConfiguration OmbiDatabase { get; set; }
|
||||
public PerDatabaseConfiguration SettingsDatabase { get; set; }
|
||||
public PerDatabaseConfiguration ExternalDatabase { get; set; }
|
||||
}
|
||||
|
||||
public class PerDatabaseConfiguration
|
||||
{
|
||||
public PerDatabaseConfiguration(string type, string connectionString)
|
||||
{
|
||||
Type = type;
|
||||
ConnectionString = connectionString;
|
||||
}
|
||||
|
||||
// Used in Deserialization
|
||||
public PerDatabaseConfiguration()
|
||||
{
|
||||
|
||||
}
|
||||
public string Type { get; set; }
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
|
@ -16,7 +16,6 @@ namespace Ombi.Core.Models.Requests
|
|||
public string Overview { get; set; }
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
public bool Approved { get; set; }
|
||||
public bool Denied { get; set; }
|
||||
public string MediaId { get; set; }
|
||||
|
||||
public string PosterPath { get; set; }
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
public class TesterResultModel
|
||||
{
|
||||
public bool IsValid { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string ExpectedSubDir { get; set; }
|
||||
public string AdditionalInformation { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
|
@ -13,8 +13,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="12.0.0" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.9" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.9" />
|
||||
<PackageReference Include="MusicBrainzAPI" Version="2.5.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
{
|
||||
if (obj is MovieRequests movie)
|
||||
{
|
||||
await ApproveMovie(movie);
|
||||
await Check4K(movie);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -45,14 +45,10 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
return Success();
|
||||
}
|
||||
|
||||
if (obj.RequestType == RequestType.Movie)
|
||||
if (obj.RequestType == RequestType.Movie && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie))
|
||||
{
|
||||
var movie = (MovieRequests)obj;
|
||||
var autoApproveRole = movie.Is4kRequest ? OmbiRoles.AutoApprove4KMovie : OmbiRoles.AutoApproveMovie;
|
||||
if (await _manager.IsInRoleAsync(user, autoApproveRole))
|
||||
{
|
||||
await ApproveMovie(movie);
|
||||
}
|
||||
await Check4K(movie);
|
||||
}
|
||||
if (obj.RequestType == RequestType.TvShow && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveTv))
|
||||
obj.Approved = true;
|
||||
|
@ -61,7 +57,7 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
return Success(); // We don't really care, we just don't set the obj to approve
|
||||
}
|
||||
|
||||
private async Task ApproveMovie(MovieRequests movie)
|
||||
private async Task Check4K(MovieRequests movie)
|
||||
{
|
||||
var featureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests);
|
||||
if (movie.Is4kRequest && featureEnabled)
|
||||
|
|
|
@ -36,14 +36,22 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
if (obj.RequestType == RequestType.Movie)
|
||||
{
|
||||
var movie = (MovieRequests)obj;
|
||||
|
||||
var requestRole = movie.Is4kRequest ? OmbiRoles.Request4KMovie : OmbiRoles.RequestMovie;
|
||||
var autoApproveRole = movie.Is4kRequest ? OmbiRoles.AutoApprove4KMovie : OmbiRoles.AutoApproveMovie;
|
||||
|
||||
if (await _manager.IsInRoleAsync(user, requestRole) || await _manager.IsInRoleAsync(user, autoApproveRole))
|
||||
var hasAutoApprove = await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie);
|
||||
if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMovie) || hasAutoApprove)
|
||||
{
|
||||
if (movie.Is4kRequest && !hasAutoApprove)
|
||||
{
|
||||
var has4kPermission = await _manager.IsInRoleAsync(user, OmbiRoles.Request4KMovie);
|
||||
if (has4kPermission)
|
||||
{
|
||||
return Success();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Success();
|
||||
}
|
||||
}
|
||||
return Fail(ErrorCode.NoPermissionsRequestMovie, "You do not have permissions to Request a Movie");
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@ using Ombi.Store.Entities;
|
|||
using Ombi.Store.Repository;
|
||||
using System.Collections.Generic;
|
||||
using Ombi.Api.Radarr.Models;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Ombi.Api.Sonarr;
|
||||
|
||||
namespace Ombi.Core.Senders
|
||||
{
|
||||
|
@ -69,7 +67,7 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
if (radarrSettings.Enabled)
|
||||
{
|
||||
return await SendToRadarr(model, radarrSettings, is4K);
|
||||
return await SendToRadarr(model, is4K, radarrSettings);
|
||||
}
|
||||
|
||||
var dogSettings = await _dogNzbSettings.GetSettingsAsync();
|
||||
|
@ -133,7 +131,7 @@ namespace Ombi.Core.Senders
|
|||
return await _dogNzbApi.AddMovie(settings.ApiKey, id);
|
||||
}
|
||||
|
||||
private async Task<SenderResult> SendToRadarr(MovieRequests model, RadarrSettings settings, bool is4k)
|
||||
private async Task<SenderResult> SendToRadarr(MovieRequests model, bool is4K, RadarrSettings settings)
|
||||
{
|
||||
var qualityToUse = int.Parse(settings.DefaultQualityProfile);
|
||||
|
||||
|
@ -141,23 +139,6 @@ namespace Ombi.Core.Senders
|
|||
|
||||
var profiles = await _userProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId);
|
||||
if (profiles != null)
|
||||
{
|
||||
if (is4k)
|
||||
{
|
||||
if (profiles.Radarr4KRootPath > 0)
|
||||
{
|
||||
var tempPath = await RadarrRootPath(profiles.Radarr4KRootPath, settings);
|
||||
if (tempPath.HasValue())
|
||||
{
|
||||
rootFolderPath = tempPath;
|
||||
}
|
||||
}
|
||||
if (profiles.Radarr4KQualityProfile > 0)
|
||||
{
|
||||
qualityToUse = profiles.Radarr4KQualityProfile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (profiles.RadarrRootPath > 0)
|
||||
{
|
||||
|
@ -172,21 +153,6 @@ namespace Ombi.Core.Senders
|
|||
qualityToUse = profiles.RadarrQualityProfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tags = new List<int>();
|
||||
if (settings.Tag.HasValue)
|
||||
{
|
||||
tags.Add(settings.Tag.Value);
|
||||
}
|
||||
if (settings.SendUserTags)
|
||||
{
|
||||
var userTag = await GetOrCreateTag(model, settings);
|
||||
if (userTag != null)
|
||||
{
|
||||
tags.Add(userTag.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Overrides on the request take priority
|
||||
if (model.QualityOverride > 0)
|
||||
|
@ -201,16 +167,14 @@ namespace Ombi.Core.Senders
|
|||
List<MovieResponse> movies;
|
||||
// Check if the movie already exists? Since it could be unmonitored
|
||||
|
||||
// Get the appropriate Radarr instance settings for existence check
|
||||
var existenceCheckSettings = is4k ? await _radarr4KSettings.GetSettingsAsync() : settings;
|
||||
movies = await _radarrV3Api.GetMovies(existenceCheckSettings.ApiKey, existenceCheckSettings.FullUri);
|
||||
movies = await _radarrV3Api.GetMovies(settings.ApiKey, settings.FullUri);
|
||||
|
||||
var existingMovie = movies.FirstOrDefault(x => x.tmdbId == model.TheMovieDbId);
|
||||
if (existingMovie == null)
|
||||
{
|
||||
var result = await _radarrV3Api.AddMovie(model.TheMovieDbId, model.Title, model.ReleaseDate.Year,
|
||||
qualityToUse, rootFolderPath, settings.ApiKey, settings.FullUri, !settings.AddOnly,
|
||||
settings.MinimumAvailability, tags);
|
||||
settings.MinimumAvailability);
|
||||
|
||||
if (!string.IsNullOrEmpty(result.Error?.message))
|
||||
{
|
||||
|
@ -248,23 +212,5 @@ namespace Ombi.Core.Senders
|
|||
var selectedPath = paths.FirstOrDefault(x => x.id == overrideId);
|
||||
return selectedPath?.path ?? string.Empty;
|
||||
}
|
||||
|
||||
private async Task<Tag> GetOrCreateTag(MovieRequests model, RadarrSettings s)
|
||||
{
|
||||
if (model.RequestedUser == null)
|
||||
{
|
||||
_log.LogWarning("Cannot create tag - RequestedUser is null for movie request {MovieTitle}", model.Title);
|
||||
return null;
|
||||
}
|
||||
|
||||
var tagName = model.RequestedUser.UserName;
|
||||
// Does tag exist?
|
||||
|
||||
var allTags = await _radarrV3Api.GetTags(s.ApiKey, s.FullUri);
|
||||
var existingTag = allTags.FirstOrDefault(x => x.label.Equals(tagName, StringComparison.InvariantCultureIgnoreCase));
|
||||
existingTag ??= await _radarrV3Api.CreateTag(s.ApiKey, s.FullUri, tagName);
|
||||
|
||||
return existingTag;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -100,7 +100,7 @@ namespace Ombi.Core.Senders
|
|||
addOptions = new Addoptions
|
||||
{
|
||||
monitored = true,
|
||||
monitor = MonitorTypes.Existing,
|
||||
monitor = MonitorTypes.None,
|
||||
searchForMissingAlbums = false,
|
||||
AlbumsToMonitor = new[] {model.ForeignAlbumId}
|
||||
},
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
using Ombi.Api.Sonarr.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Core.Senders
|
||||
{
|
||||
internal class SonarrSendOptions
|
||||
{
|
||||
public List<int> Tags { get; set; } = new List<int>();
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@ using System.Linq;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Api.DogNzb;
|
||||
using Ombi.Api.DogNzb.Models;
|
||||
using Ombi.Api.SickRage;
|
||||
using Ombi.Api.SickRage.Models;
|
||||
using Ombi.Api.Sonarr;
|
||||
|
@ -19,13 +21,16 @@ namespace Ombi.Core.Senders
|
|||
{
|
||||
public class TvSender : ITvSender
|
||||
{
|
||||
public TvSender(ISonarrV3Api sonarrV3Api, ILogger<TvSender> log, ISettingsService<SonarrSettings> sonarrSettings,
|
||||
ISettingsService<SickRageSettings> srSettings,
|
||||
public TvSender(ISonarrApi sonarrApi, ISonarrV3Api sonarrV3Api, ILogger<TvSender> log, ISettingsService<SonarrSettings> sonarrSettings,
|
||||
ISettingsService<DogNzbSettings> dog, IDogNzbApi dogApi, ISettingsService<SickRageSettings> srSettings,
|
||||
ISickRageApi srApi, IRepository<UserQualityProfiles> userProfiles, IRepository<RequestQueue> requestQueue, INotificationHelper notify)
|
||||
{
|
||||
SonarrApi = sonarrV3Api;
|
||||
SonarrApi = sonarrApi;
|
||||
SonarrV3Api = sonarrV3Api;
|
||||
Logger = log;
|
||||
SonarrSettings = sonarrSettings;
|
||||
DogNzbSettings = dog;
|
||||
DogNzbApi = dogApi;
|
||||
SickRageSettings = srSettings;
|
||||
SickRageApi = srApi;
|
||||
UserQualityProfiles = userProfiles;
|
||||
|
@ -33,10 +38,13 @@ namespace Ombi.Core.Senders
|
|||
_notificationHelper = notify;
|
||||
}
|
||||
|
||||
private ISonarrV3Api SonarrApi { get; }
|
||||
private ISonarrApi SonarrApi { get; }
|
||||
private ISonarrV3Api SonarrV3Api { get; }
|
||||
private IDogNzbApi DogNzbApi { get; }
|
||||
private ISickRageApi SickRageApi { get; }
|
||||
private ILogger<TvSender> Logger { get; }
|
||||
private ISettingsService<SonarrSettings> SonarrSettings { get; }
|
||||
private ISettingsService<DogNzbSettings> DogNzbSettings { get; }
|
||||
private ISettingsService<SickRageSettings> SickRageSettings { get; }
|
||||
private IRepository<UserQualityProfiles> UserQualityProfiles { get; }
|
||||
private readonly IRepository<RequestQueue> _requestQueueRepository;
|
||||
|
@ -59,7 +67,23 @@ namespace Ombi.Core.Senders
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
var dog = await DogNzbSettings.GetSettingsAsync();
|
||||
if (dog.Enabled)
|
||||
{
|
||||
var result = await SendToDogNzb(model, dog);
|
||||
if (!result.Failure)
|
||||
{
|
||||
return new SenderResult
|
||||
{
|
||||
Sent = true,
|
||||
Success = true
|
||||
};
|
||||
}
|
||||
return new SenderResult
|
||||
{
|
||||
Message = result.ErrorMessage
|
||||
};
|
||||
}
|
||||
var sr = await SickRageSettings.GetSettingsAsync();
|
||||
if (sr.Enabled)
|
||||
{
|
||||
|
@ -113,6 +137,12 @@ namespace Ombi.Core.Senders
|
|||
};
|
||||
}
|
||||
|
||||
private async Task<DogNzbAddResult> SendToDogNzb(ChildRequests model, DogNzbSettings settings)
|
||||
{
|
||||
var id = model.ParentRequest.ExternalProviderId;
|
||||
return await DogNzbApi.AddTvShow(settings.ApiKey, id.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send the request to Sonarr to process
|
||||
/// </summary>
|
||||
|
@ -125,22 +155,13 @@ namespace Ombi.Core.Senders
|
|||
{
|
||||
return null;
|
||||
}
|
||||
var options = new SonarrSendOptions();
|
||||
|
||||
int qualityToUse;
|
||||
var languageProfileId = s.LanguageProfile;
|
||||
string rootFolderPath;
|
||||
string seriesType;
|
||||
int? tagToUse = null;
|
||||
|
||||
Logger.LogInformation("Starting SendToSonarr for series {Title} (TvDbId: {TvDbId})", model.ParentRequest.Title, model.ParentRequest.TvDbId);
|
||||
Logger.LogInformation("Series type: {SeriesType}", model.SeriesType);
|
||||
|
||||
var profiles = await UserQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId);
|
||||
if (profiles != null)
|
||||
{
|
||||
Logger.LogInformation("Found user quality profile for user {UserId}", model.RequestedUserId);
|
||||
}
|
||||
|
||||
if (model.SeriesType == SeriesType.Anime)
|
||||
{
|
||||
|
@ -148,10 +169,8 @@ namespace Ombi.Core.Senders
|
|||
// For some reason, if we haven't got one use the first root folder in Sonarr
|
||||
if (!int.TryParse(s.RootPathAnime, out int animePath))
|
||||
{
|
||||
Logger.LogWarning("Failed to parse RootPathAnime: {RootPathAnime}, falling back to main root path", s.RootPathAnime);
|
||||
animePath = int.Parse(s.RootPath); // Set it to the main root folder if we have no anime folder.
|
||||
}
|
||||
Logger.LogInformation("Using anime path ID: {AnimePath}", animePath);
|
||||
rootFolderPath = await GetSonarrRootPath(animePath, s);
|
||||
languageProfileId = s.LanguageProfileAnime > 0 ? s.LanguageProfileAnime : s.LanguageProfile;
|
||||
|
||||
|
@ -163,7 +182,6 @@ namespace Ombi.Core.Senders
|
|||
{
|
||||
if (profiles.SonarrRootPathAnime > 0)
|
||||
{
|
||||
Logger.LogInformation("Using user's anime root path override: {RootPath}", profiles.SonarrRootPathAnime);
|
||||
rootFolderPath = await GetSonarrRootPath(profiles.SonarrRootPathAnime, s);
|
||||
}
|
||||
if (profiles.SonarrQualityProfileAnime > 0)
|
||||
|
@ -172,20 +190,17 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
seriesType = "anime";
|
||||
tagToUse = s.AnimeTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
int.TryParse(s.QualityProfile, out qualityToUse);
|
||||
// Get the root path from the rootfolder selected.
|
||||
// For some reason, if we haven't got one use the first root folder in Sonarr
|
||||
Logger.LogInformation("Using standard path ID: {RootPath}", s.RootPath);
|
||||
rootFolderPath = await GetSonarrRootPath(int.Parse(s.RootPath), s);
|
||||
if (profiles != null)
|
||||
{
|
||||
if (profiles.SonarrRootPath > 0)
|
||||
{
|
||||
Logger.LogInformation("Using user's standard root path override: {RootPath}", profiles.SonarrRootPath);
|
||||
rootFolderPath = await GetSonarrRootPath(profiles.SonarrRootPath, s);
|
||||
}
|
||||
if (profiles.SonarrQualityProfile > 0)
|
||||
|
@ -194,40 +209,37 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
seriesType = "standard";
|
||||
tagToUse = s.Tag;
|
||||
}
|
||||
|
||||
// Overrides on the request take priority
|
||||
if (model.ParentRequest.QualityOverride.HasValue && model.ParentRequest.QualityOverride.Value > 0)
|
||||
if (model.ParentRequest.QualityOverride.HasValue)
|
||||
{
|
||||
qualityToUse = model.ParentRequest.QualityOverride.Value;
|
||||
var qualityOverride = model.ParentRequest.QualityOverride.Value;
|
||||
if (qualityOverride > 0)
|
||||
{
|
||||
qualityToUse = qualityOverride;
|
||||
}
|
||||
}
|
||||
if (model.ParentRequest.RootFolder.HasValue)
|
||||
{
|
||||
var rootfolderOverride = model.ParentRequest.RootFolder.Value;
|
||||
if (rootfolderOverride > 0)
|
||||
{
|
||||
rootFolderPath = await GetSonarrRootPath(rootfolderOverride, s);
|
||||
}
|
||||
}
|
||||
|
||||
if (model.ParentRequest.RootFolder.HasValue && model.ParentRequest.RootFolder.Value > 0)
|
||||
if (model.ParentRequest.LanguageProfile.HasValue)
|
||||
{
|
||||
Logger.LogInformation("Using request root folder override: {RootFolder}", model.ParentRequest.RootFolder.Value);
|
||||
rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder.Value, s);
|
||||
}
|
||||
|
||||
if (model.ParentRequest.LanguageProfile.HasValue && model.ParentRequest.LanguageProfile.Value > 0)
|
||||
var languageProfile = model.ParentRequest.LanguageProfile.Value;
|
||||
if (languageProfile > 0)
|
||||
{
|
||||
languageProfileId = model.ParentRequest.LanguageProfile.Value;
|
||||
languageProfileId = languageProfile;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.LogInformation("Final root folder path: {RootFolderPath}", rootFolderPath);
|
||||
|
||||
try
|
||||
{
|
||||
if (tagToUse.HasValue)
|
||||
{
|
||||
options.Tags.Add(tagToUse.Value);
|
||||
}
|
||||
if (s.SendUserTags)
|
||||
{
|
||||
var userTag = await GetOrCreateTag(model, s);
|
||||
options.Tags.Add(userTag.id);
|
||||
}
|
||||
|
||||
// Does the series actually exist?
|
||||
var allSeries = await SonarrApi.GetSeries(s.ApiKey, s.FullUri);
|
||||
var existingSeries = allSeries.FirstOrDefault(x => x.tvdbId == model.ParentRequest.TvDbId);
|
||||
|
@ -253,11 +265,11 @@ namespace Ombi.Core.Senders
|
|||
ignoreEpisodesWithoutFiles = false, // We want all missing
|
||||
searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly.
|
||||
},
|
||||
languageProfileId = languageProfileId,
|
||||
tags = options.Tags
|
||||
languageProfileId = languageProfileId
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Montitor the correct seasons,
|
||||
// If we have that season in the model then it's monitored!
|
||||
var seasonsToAdd = GetSeasonsToCreate(model);
|
||||
|
@ -268,11 +280,11 @@ namespace Ombi.Core.Senders
|
|||
throw new Exception(string.Join(',', result.ErrorMessages));
|
||||
}
|
||||
existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri);
|
||||
await SendToSonarr(model, existingSeries, s, options);
|
||||
await SendToSonarr(model, existingSeries, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendToSonarr(model, existingSeries, s, options);
|
||||
await SendToSonarr(model, existingSeries, s);
|
||||
}
|
||||
|
||||
return new NewSeries
|
||||
|
@ -291,30 +303,7 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<Tag> GetOrCreateTag(ChildRequests model, SonarrSettings s)
|
||||
{
|
||||
var tagName = model.RequestedUser.UserName;
|
||||
// Does tag exist?
|
||||
|
||||
var allTags = await SonarrApi.GetTags(s.ApiKey, s.FullUri);
|
||||
var existingTag = allTags.FirstOrDefault(x => x.label.Equals(tagName, StringComparison.InvariantCultureIgnoreCase));
|
||||
existingTag ??= await SonarrApi.CreateTag(s.ApiKey, s.FullUri, tagName);
|
||||
|
||||
return existingTag;
|
||||
}
|
||||
|
||||
private async Task<Tag> GetTag(int tagId, SonarrSettings s)
|
||||
{
|
||||
var tag = await SonarrApi.GetTag(tagId, s.ApiKey, s.FullUri);
|
||||
if (tag == null)
|
||||
{
|
||||
Logger.LogError($"Tag ID {tagId} does not exist in sonarr. Please update the settings");
|
||||
return null;
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
private async Task SendToSonarr(ChildRequests model, SonarrSeries result, SonarrSettings s, SonarrSendOptions options)
|
||||
private async Task SendToSonarr(ChildRequests model, SonarrSeries result, SonarrSettings s)
|
||||
{
|
||||
// Check to ensure we have the all the seasons, ensure the Sonarr metadata has grabbed all the data
|
||||
Season existingSeason = null;
|
||||
|
@ -332,27 +321,15 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
|
||||
// Does the show have the correct tags we are expecting
|
||||
if (options.Tags.Any())
|
||||
{
|
||||
result.tags ??= options.Tags;
|
||||
var tagsToAdd = options.Tags.Except(result.tags);
|
||||
|
||||
if (tagsToAdd.Any())
|
||||
{
|
||||
result.tags.AddRange(tagsToAdd);
|
||||
}
|
||||
result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||
}
|
||||
var episodesToUpdate = new List<Episode>();
|
||||
// Ok, now let's sort out the episodes.
|
||||
|
||||
if (model.SeriesType == SeriesType.Anime)
|
||||
{
|
||||
result.seriesType = "anime";
|
||||
result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||
await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||
}
|
||||
|
||||
var episodesToUpdate = new List<Episode>();
|
||||
// Ok, now let's sort out the episodes.
|
||||
var sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri);
|
||||
var sonarrEpList = sonarrEpisodes.ToList() ?? new List<Episode>();
|
||||
while (!sonarrEpList.Any())
|
||||
|
@ -396,12 +373,17 @@ namespace Ombi.Core.Senders
|
|||
epToUnmonitored.Add(ep);
|
||||
}
|
||||
|
||||
await SonarrApi.MonitorEpisode(epToUnmonitored.Select(x => x.id).ToArray(), false, s.ApiKey, s.FullUri);
|
||||
foreach (var epToUpdate in epToUnmonitored)
|
||||
{
|
||||
await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri);
|
||||
}
|
||||
}
|
||||
|
||||
// Now update the episodes that need updating
|
||||
await SonarrApi.MonitorEpisode(episodesToUpdate.Select(x => x.id).ToArray(), true, s.ApiKey, s.FullUri);
|
||||
foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber))
|
||||
{
|
||||
await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri);
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.AddOnly)
|
||||
{
|
||||
|
@ -535,36 +517,17 @@ namespace Ombi.Core.Senders
|
|||
|
||||
private async Task<string> GetSonarrRootPath(int pathId, SonarrSettings sonarrSettings)
|
||||
{
|
||||
Logger.LogInformation("Getting Sonarr root path for ID: {PathId}", pathId);
|
||||
var rootFoldersResult = await SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri);
|
||||
|
||||
if (rootFoldersResult == null || !rootFoldersResult.Any())
|
||||
{
|
||||
Logger.LogError("No root folders returned from Sonarr API");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
Logger.LogInformation("Found {Count} root folders in Sonarr", rootFoldersResult.Count());
|
||||
foreach (var folder in rootFoldersResult)
|
||||
{
|
||||
Logger.LogDebug("Root folder - ID: {Id}, Path: {Path}", folder.id, folder.path);
|
||||
}
|
||||
|
||||
if (pathId == 0)
|
||||
{
|
||||
var defaultPath = rootFoldersResult.FirstOrDefault()?.path;
|
||||
Logger.LogInformation("Using first root folder as default: {Path}", defaultPath);
|
||||
return defaultPath;
|
||||
return rootFoldersResult.FirstOrDefault().path;
|
||||
}
|
||||
|
||||
var matchingFolder = rootFoldersResult.FirstOrDefault(r => r.id == pathId);
|
||||
if (matchingFolder != null)
|
||||
foreach (var r in rootFoldersResult.Where(r => r.id == pathId))
|
||||
{
|
||||
Logger.LogInformation("Found matching root folder for ID {PathId}: {Path}", pathId, matchingFolder.path);
|
||||
return matchingFolder.path;
|
||||
return r.path;
|
||||
}
|
||||
|
||||
Logger.LogError("No matching root folder found for ID: {PathId}", pathId);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Helpers;
|
||||
|
||||
namespace Ombi.Core.Services;
|
||||
|
||||
public class DatabaseConfigurationService : IDatabaseConfigurationService
|
||||
{
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public DatabaseConfigurationService(
|
||||
ILogger<DatabaseConfigurationService> logger,
|
||||
IFileSystem fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public async Task<bool> ConfigureDatabase(string databaseType, string connectionString, CancellationToken token)
|
||||
{
|
||||
var i = StartupSingleton.Instance;
|
||||
if (string.IsNullOrEmpty(i.StoragePath))
|
||||
{
|
||||
i.StoragePath = string.Empty;
|
||||
}
|
||||
|
||||
var databaseFileLocation = Path.Combine(i.StoragePath, "database.json");
|
||||
if (_fileSystem.FileExists(databaseFileLocation))
|
||||
{
|
||||
var error = $"The database file at '{databaseFileLocation}' already exists";
|
||||
_logger.LogError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
var configuration = new DatabaseConfiguration
|
||||
{
|
||||
ExternalDatabase = new PerDatabaseConfiguration(databaseType, connectionString),
|
||||
OmbiDatabase = new PerDatabaseConfiguration(databaseType, connectionString),
|
||||
SettingsDatabase = new PerDatabaseConfiguration(databaseType, connectionString)
|
||||
};
|
||||
|
||||
var json = JsonConvert.SerializeObject(configuration, Formatting.Indented);
|
||||
|
||||
_logger.LogInformation("Writing database configuration to file");
|
||||
|
||||
try
|
||||
{
|
||||
await File.WriteAllTextAsync(databaseFileLocation, json, token);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Failed to write database configuration to file");
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Database configuration written to file");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Services;
|
||||
|
||||
public interface IDatabaseConfigurationService
|
||||
{
|
||||
const string MySqlDatabase = "MySQL";
|
||||
const string PostgresDatabase = "Postgres";
|
||||
Task<bool> ConfigureDatabase(string databaseType, string connectionString, CancellationToken token);
|
||||
}
|
|
@ -73,10 +73,6 @@ namespace Ombi.Core.Services
|
|||
var lang = await DefaultLanguageCode();
|
||||
foreach (var item in await recentMovieRequests.ToListAsync(cancellationToken))
|
||||
{
|
||||
if (hideUsers.Hide && item.RequestedUserId != hideUsers.UserId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var images = await _cache.GetOrAddAsync($"{CacheKeys.TmdbImages}movie{item.TheMovieDbId}", () => _movieDbApi.GetMovieImages(item.TheMovieDbId.ToString(), cancellationToken), DateTimeOffset.Now.AddDays(1));
|
||||
model.Add(new RecentlyRequestedModel
|
||||
{
|
||||
|
@ -88,9 +84,8 @@ namespace Ombi.Core.Services
|
|||
Title = item.Title,
|
||||
Type = RequestType.Movie,
|
||||
Approved = item.Approved,
|
||||
Denied = item.Denied ?? false,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias,
|
||||
UserId = hideUsers.Hide ? string.Empty : item.RequestedUserId,
|
||||
Username = hideUsers.Hide ? string.Empty : item.RequestedUser.UserAlias,
|
||||
MediaId = item.TheMovieDbId.ToString(),
|
||||
PosterPath = images?.posters?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||
Background = images?.backdrops?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||
|
@ -99,33 +94,24 @@ namespace Ombi.Core.Services
|
|||
|
||||
foreach (var item in await recentMusicRequests.ToListAsync(cancellationToken))
|
||||
{
|
||||
if (hideUsers.Hide && item.RequestedUserId != hideUsers.UserId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
model.Add(new RecentlyRequestedModel
|
||||
{
|
||||
RequestId = item.Id,
|
||||
Available = item.Available,
|
||||
Overview = item.ArtistName,
|
||||
Approved = item.Approved,
|
||||
Denied = item.Denied ?? false,
|
||||
ReleaseDate = item.ReleaseDate,
|
||||
RequestDate = item.RequestedDate,
|
||||
Title = item.Title,
|
||||
Type = RequestType.Album,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias,
|
||||
UserId = hideUsers.Hide ? string.Empty : item.RequestedUserId,
|
||||
Username = hideUsers.Hide ? string.Empty : item.RequestedUser.UserAlias,
|
||||
MediaId = item.ForeignAlbumId,
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var item in await recentTvRequests.ToListAsync(cancellationToken))
|
||||
{
|
||||
if (hideUsers.Hide && item.RequestedUserId != hideUsers.UserId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var providerId = item.ParentRequest.ExternalProviderId.ToString();
|
||||
var images = await _cache.GetOrAddAsync($"{CacheKeys.TmdbImages}tv{providerId}", () => _movieDbApi.GetTvImages(providerId.ToString(), cancellationToken), DateTimeOffset.Now.AddDays(1));
|
||||
|
||||
|
@ -137,13 +123,12 @@ namespace Ombi.Core.Services
|
|||
Overview = item.ParentRequest.Overview,
|
||||
ReleaseDate = item.ParentRequest.ReleaseDate,
|
||||
Approved = item.Approved,
|
||||
Denied = item.Denied ?? false,
|
||||
RequestDate = item.RequestedDate,
|
||||
TvPartiallyAvailable = partialAvailability,
|
||||
Title = item.ParentRequest.Title,
|
||||
Type = RequestType.TvShow,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias,
|
||||
UserId = hideUsers.Hide ? string.Empty : item.RequestedUserId,
|
||||
Username = hideUsers.Hide ? string.Empty : item.RequestedUser.UserAlias,
|
||||
MediaId = providerId.ToString(),
|
||||
PosterPath = images?.posters?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||
Background = images?.backdrops?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||
|
|
|
@ -107,7 +107,6 @@ namespace Ombi.DependencyInjection
|
|||
services.AddTransient<IMusicSender, MusicSender>();
|
||||
services.AddTransient<IMassEmailSender, MassEmailSender>();
|
||||
services.AddTransient<IPlexOAuthManager, PlexOAuthManager>();
|
||||
services.AddTransient<IPlexTokenKeepAliveService, PlexTokenKeepAliveService>();
|
||||
services.AddTransient<IVoteEngine, VoteEngine>();
|
||||
services.AddTransient<IDemoMovieSearchEngine, DemoMovieSearchEngine>();
|
||||
services.AddTransient<IDemoTvSearchEngine, DemoTvSearchEngine>();
|
||||
|
@ -198,8 +197,6 @@ namespace Ombi.DependencyInjection
|
|||
services.AddScoped<IEmbyContentRepository, EmbyContentRepository>();
|
||||
services.AddScoped<IJellyfinContentRepository, JellyfinContentRepository>();
|
||||
services.AddScoped<INotificationTemplatesRepository, NotificationTemplatesRepository>();
|
||||
services.AddScoped<IUserPlayedMovieRepository, UserPlayedMovieRepository>();
|
||||
services.AddScoped<IUserPlayedEpisodeRepository, UserPlayedEpisodeRepository>();
|
||||
|
||||
services.AddScoped<ITvRequestRepository, TvRequestRepository>();
|
||||
services.AddScoped<IMovieRequestRepository, MovieRequestRepository>();
|
||||
|
@ -237,8 +234,6 @@ namespace Ombi.DependencyInjection
|
|||
services.AddScoped<IFeatureService, FeatureService>();
|
||||
services.AddTransient<IRecentlyRequestedService, RecentlyRequestedService>();
|
||||
services.AddTransient<IPlexService, PlexService>();
|
||||
services.AddSingleton<IFileSystem, FileSystem>();
|
||||
services.AddSingleton<IDatabaseConfigurationService, DatabaseConfigurationService>();
|
||||
}
|
||||
|
||||
public static void RegisterJobs(this IServiceCollection services)
|
||||
|
@ -249,7 +244,6 @@ namespace Ombi.DependencyInjection
|
|||
services.AddTransient<IPlexContentSync, PlexContentSync>();
|
||||
services.AddTransient<IPlexWatchlistImport, PlexWatchlistImport>();
|
||||
services.AddTransient<IEmbyContentSync, EmbyContentSync>();
|
||||
services.AddTransient<IEmbyPlayedSync, EmbyPlayedSync>();
|
||||
services.AddTransient<IEmbyEpisodeSync, EmbyEpisodeSync>();
|
||||
services.AddTransient<IEmbyAvaliabilityChecker, EmbyAvaliabilityChecker>();
|
||||
services.AddTransient<IJellyfinContentSync, JellyfinContentSync>();
|
||||
|
|
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