mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-18 21:35:51 -04:00
Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 68d32e4d31 | |||
| 29f540c4f2 | |||
| 31eed11d1b | |||
| ba0bbddce9 | |||
| a243a886f5 | |||
| 033bc24984 | |||
| e071850d4c | |||
| fa212872ab | |||
| c34137c423 | |||
| 67848ebff5 | |||
| d0406ced40 | |||
| ae88645180 | |||
| 8519b64947 | |||
| d67d89f54a | |||
| 2b2bd16d4d | |||
| 0c23511b7a | |||
| 4dc3612347 | |||
| 2139246c4a | |||
| c1a5e8e759 | |||
| e70e76adcb | |||
| 1dbb856ced | |||
| 74396a7abb | |||
| e7e9e2b154 | |||
| b40423f3a3 | |||
| b3e46d02c6 | |||
| 081d8a8e53 | |||
| 2f271635f9 | |||
| c460153e66 | |||
| 8a674181be | |||
| 7537cef93c | |||
| 808b6d16e9 | |||
| d1189e62c5 | |||
| ef86c83799 | |||
| aeb45e5f7e | |||
| 149c7c534c | |||
| 74ae66ba14 | |||
| f94e7b562a | |||
| f5a7a2f29a | |||
| 1514a00b8f | |||
| 3ed0652feb | |||
| f4e2a510f2 | |||
| 8edd15b5f8 | |||
| 2fdfd0fba5 | |||
| 8b201af053 | |||
| 976bc1a6a5 | |||
| 16ba7194a9 | |||
| a151fbbcbe | |||
| 71db67af2c | |||
| 1d2231a96d | |||
| 0837d3a8a0 | |||
| 05e5d610a3 | |||
| d2f99f1330 | |||
| 27001b48f6 | |||
| 97ab4cbcbd | |||
| 8b3a71a537 | |||
| e22141e2ed | |||
| 11211dc2ed | |||
| e71e518d30 | |||
| f9049566c1 | |||
| 0bc61bea38 | |||
| 032fc68892 | |||
| 33cc228ac1 | |||
| d5832a6a07 | |||
| 5f8aeeac17 | |||
| 54e57bf16a | |||
| b1f76082b2 | |||
| 73fed04228 | |||
| ca3d5c184e | |||
| 861962d06c | |||
| 5057fcc40f | |||
| 78e5fdf3bc | |||
| aab14d02f9 | |||
| eb1c3c8b82 | |||
| 4025af7895 | |||
| 95ca863697 | |||
| 74e0db2829 | |||
| 2459ddb6f4 | |||
| 3e2e085b6b | |||
| 931cdacf66 | |||
| 18c622de40 | |||
| 53e6fa7cf1 | |||
| 4afd3f3bfe | |||
| da425b04b1 | |||
| 663ac972cd |
@@ -0,0 +1,5 @@
|
|||||||
|
FROM mono:4.8
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y git ssh tar gzip ca-certificates
|
||||||
|
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -E -
|
||||||
|
RUN apt-get install -y nodejs npm
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
docker:
|
||||||
|
- image: gallileo/radarr-cci-primary:4.8
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run: git submodule update --init --recursive
|
||||||
|
- run:
|
||||||
|
name: Clean Build
|
||||||
|
command: ./build.sh Clean
|
||||||
|
- run:
|
||||||
|
name: Restore Nuget
|
||||||
|
command: ./build.sh NugetMono
|
||||||
|
- run:
|
||||||
|
name: Build
|
||||||
|
command: ./build.sh Build
|
||||||
|
- run:
|
||||||
|
name: Gulp
|
||||||
|
command: ./build.sh Gulp
|
||||||
|
- run:
|
||||||
|
name: Package
|
||||||
|
command: ./build.sh Package
|
||||||
|
- run:
|
||||||
|
name: Preparing Tests
|
||||||
|
command: mkdir _tests/reports
|
||||||
|
- run:
|
||||||
|
name: Testing
|
||||||
|
command: ./test.sh Linux Unit
|
||||||
|
- store_test_results:
|
||||||
|
path: _tests/reports/
|
||||||
|
- store_artifacts:
|
||||||
|
path: _output
|
||||||
|
- store_artifacts:
|
||||||
|
path: _output_mono
|
||||||
|
- store_artifacts:
|
||||||
|
path: _output_osx
|
||||||
|
- store_artifacts:
|
||||||
|
path: _output_osx_app
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
|
<xsl:output method="xml" indent="yes"/>
|
||||||
|
|
||||||
|
<xsl:template match="/test-run">
|
||||||
|
<testsuites tests="{@testcasecount}" failures="{@failed}" disabled="{@skipped}" time="{@duration}">
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</testsuites>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="test-suite">
|
||||||
|
<xsl:if test="test-case">
|
||||||
|
<testsuite tests="{@testcasecount}" time="{@duration}" errors="{@testcasecount - @passed - @skipped - @failed}" failures="{@failed}" skipped="{@skipped}" timestamp="{@start-time}">
|
||||||
|
<xsl:attribute name="name">
|
||||||
|
<xsl:for-each select="ancestor-or-self::test-suite/@name">
|
||||||
|
<xsl:value-of select="concat(., '.')"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:apply-templates select="test-case"/>
|
||||||
|
</testsuite>
|
||||||
|
<xsl:apply-templates select="test-suite"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="not(test-case)">
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="test-case">
|
||||||
|
<testcase name="{@name}" assertions="{@asserts}" time="{@duration}" status="{@result}" classname="{@classname}">
|
||||||
|
<xsl:if test="@runstate = 'Skipped' or @runstate = 'Ignored'">
|
||||||
|
<skipped/>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</testcase>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="command-line"/>
|
||||||
|
<xsl:template match="settings"/>
|
||||||
|
|
||||||
|
<xsl:template match="output">
|
||||||
|
<system-out>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</system-out>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="stack-trace">
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="test-case/failure">
|
||||||
|
<failure message="{./message}">
|
||||||
|
<xsl:value-of select="./stack-trace"/>
|
||||||
|
</failure>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="test-suite/failure"/>
|
||||||
|
|
||||||
|
<xsl:template match="test-case/reason">
|
||||||
|
<skipped message="{./message}"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="test-case/assertions">
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="test-suite/reason"/>
|
||||||
|
|
||||||
|
<xsl:template match="properties"/>
|
||||||
|
</xsl:stylesheet>
|
||||||
|
|
||||||
@@ -4,13 +4,17 @@ Check first that your problem is not listed in our wiki section:
|
|||||||
* https://github.com/Radarr/Radarr/wiki/Common-Problems
|
* https://github.com/Radarr/Radarr/wiki/Common-Problems
|
||||||
* https://github.com/Radarr/Radarr/wiki/FAQ
|
* https://github.com/Radarr/Radarr/wiki/FAQ
|
||||||
|
|
||||||
|
**Just because you receive an exception in your logs, doesn't mean it's a bug and should be reported here. Often it's something else, such as a permission error. If you are unsure ask on the Discord or Subreddit first.**
|
||||||
|
|
||||||
|
Visit our [Discord server](https://discord.gg/NWYch8M) or [Subreddit](https://reddit.com/r/radarr) for support or longer discussions. Support questions posed on here will be closed immediately.
|
||||||
|
|
||||||
Provide a description of the feature request or bug here, the more details the better.
|
Provide a description of the feature request or bug here, the more details the better.
|
||||||
Please also try to include the following if you are reporting a bug
|
Please also include the following if you are reporting a bug. If you do not include it, the issue will probably be closed as we cannot help you.
|
||||||
|
|
||||||
**Radarr Version:**
|
**Radarr Version:**
|
||||||
|
|
||||||
**Logs:**
|
**Mono Version:**
|
||||||
|
|
||||||
|
**Debug Logs:**
|
||||||
|
|
||||||
Please use the search bar and make sure you are not submitting an already submitted issue.
|
Please use the search bar and make sure you are not submitting an already submitted issue.
|
||||||
Visit our [Discord server](https://discord.gg/NWYch8M) for support or longer discussions.
|
|
||||||
|
|||||||
+112
@@ -1,5 +1,117 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## (unreleased)
|
||||||
|
|
||||||
|
### **New features**
|
||||||
|
- Handle ctrl-c more gracefully. [Leonardo Galli]
|
||||||
|
- Device names for Join notifications (#2544) [Qstick]
|
||||||
|
- Same File Size MediaFile Specification (#2532) [Qstick]
|
||||||
|
- Updated NLog to version 4.4.12. Should fix #2218. [Leonardo Galli]
|
||||||
|
- Importing extra files from downloaded movies and generate metadata such as .nfo (#2506) [Qstick]
|
||||||
|
- Quotes around alternative titles (#2522) [Qstick]
|
||||||
|
- Backup improvements from Sonarr (#2513) [Qstick]
|
||||||
|
- NzbDrone references in FirewallAdapter.cs (#2504) [Qstick]
|
||||||
|
|
||||||
|
### **Fixes**
|
||||||
|
- Alt Titles from TMDB not getting added when mappings server throws 404. [Leonardo Galli]
|
||||||
|
- Unable to execute custom scripts if IMDB ID is null (#2543) [Qstick]
|
||||||
|
- Cleanup TV related code in API (#2530) [Qstick]
|
||||||
|
- Omgwtfnbs parsing being too greedy. [Leonardo Galli]
|
||||||
|
- Help icon not centered (#2531) [Qstick]
|
||||||
|
- Radarr Changes every file due to timezones (#2533) [Qstick]
|
||||||
|
- Filters not working. Fuck you backbone. [Leonardo Galli]
|
||||||
|
- Cleanup Series Code from UI (#2525) [Qstick]
|
||||||
|
- Apostrophe getting replaced by an empty string causing no search results. [Leonardo Galli]
|
||||||
|
- Integration Unit Tests (#2500) [Qstick]
|
||||||
|
- XSS vulnerability in the navbar search. (#2505) [Scott]
|
||||||
|
- StartNzbDroneService.cs unit test (#2499) [Qstick]
|
||||||
|
- SelectAll and deselectAll MovieEditor buttons. [geogolem]
|
||||||
|
- Fix build problem on windows. [geogolem]
|
||||||
|
- Revert "Fixed: Removed hebrew ISO, since english movies are still in english. (#1922)" [Leonardo Galli]
|
||||||
|
- Error with deluge when it doesn’t report a Hash. [Leonardo Galli]
|
||||||
|
- Logging error when accessing mount point. [Leonardo Galli]
|
||||||
|
- Invalid runtime from CP causing issues importing. [Leonardo Galli]
|
||||||
|
- Typo in TMDB Settings. [Leonardo Galli]
|
||||||
|
- Hopefully fixed errors with Delay Profiles. [Leonardo Galli]
|
||||||
|
- Error when importing files and old folder doesn’t exist. [Leonardo Galli]
|
||||||
|
- Zooqle torrents not getting added, since their torrent file is messed up. [Leonardo Galli]
|
||||||
|
|
||||||
|
|
||||||
|
## v0.2.0.935 (2018-02-06)
|
||||||
|
|
||||||
|
### **New features**
|
||||||
|
- Include total space with root folders. [Leonardo Galli]
|
||||||
|
- Manual Import now adds year after movie title for filtering. This should help finding movies such as IT. [Leonardo Galli]
|
||||||
|
- Option to require indexer flags per indexer. (e.g. only download freeleech torrents from a private tracker) (#2460) [Leonardo Galli]
|
||||||
|
- Files downloaded with different quality than grabbed will get rejected. [Leonardo Galli]
|
||||||
|
- TMDbSettings.cs to allow pipe for or for genre ids (#2389) [crhammock]
|
||||||
|
- Dynamic paths cleanup old folders now! [Leonardo Galli]
|
||||||
|
|
||||||
|
### **Fixes**
|
||||||
|
- No Physical Release Date causing exception when setting last write time. [Leonardo Galli]
|
||||||
|
- Movies not getting unmonitored when folder gets deleted. [Leonardo Galli]
|
||||||
|
- Rare case of null quality causing issues with manual import. [Leonardo Galli]
|
||||||
|
- Manual Import not automatically choosing right movie. [Leonardo Galli]
|
||||||
|
- Rare case of RequiredIndexerFlags failing with old Newznab indexers. [Leonardo Galli]
|
||||||
|
- Folder name getting messed up when adding movies via a list. [Leonardo Galli]
|
||||||
|
- Error when adding an already excluded movie to the exclusion list. [Leonardo Galli]
|
||||||
|
- Last commit still not compiling (whoops squared) [Leonardo Galli]
|
||||||
|
- Last commit not compiling (whoops) [Leonardo Galli]
|
||||||
|
- Clean Library being to agressive when lists are having failures. [Leonardo Galli]
|
||||||
|
- Error when nno quality was associated with a movie file. [Leonardo Galli]
|
||||||
|
- Allowing in use Profiles to be Deleted. [Leonardo Galli]
|
||||||
|
- Error when Movie has no imdbid when searching Rargb. [Leonardo Galli]
|
||||||
|
- Rargb failing when imdbid is not found. [Leonardo Galli]
|
||||||
|
- {Original Filename} not allowed in Movie Filename. [Leonardo Galli]
|
||||||
|
- Look for changes to package.json before using old build cache (#2445) [Qstick]
|
||||||
|
- HistoryDetailsLayoutTemplate.hbs (#2361) [Pieter Janssens]
|
||||||
|
|
||||||
|
|
||||||
|
## v0.2.0.910 (2017-12-13)
|
||||||
|
|
||||||
|
### **New features**
|
||||||
|
- Separate naming tags for AudioLanguage and SubtitleLanguage (#2261) (Fixes #2257) [fhscholl]
|
||||||
|
- Include APFS disks in disk space calculation. [Leonardo Galli]
|
||||||
|
- Upgrade MediaInfo to 17.10 (Windows/macOS) [Leonardo Galli]
|
||||||
|
- Support for VF2 french tag. (#2291) (Fixes #2290) [kriegalex]
|
||||||
|
- Customize Slack Channel (#2308) (Fixes #2298) [grokdesigns]
|
||||||
|
- SceneName to MovieFile API output (#2250) (Fixes #2245) [fhscholl]
|
||||||
|
- Functionality to XBMC and Plex to update indivdual titles. Also: Notification Cleanup (#2240) [fhscholl]
|
||||||
|
- FolderPath to the Movie Webhook (#2230) [adnanklink]
|
||||||
|
- Download_Id to On Download/On Upgrade (#2229) [adnanklink]
|
||||||
|
- Movie_Quality to onGrab (#2221) (Fixes #1833) [fhscholl]
|
||||||
|
- Webhook Improvements (#2220) (Fixes #1751) [fhscholl]
|
||||||
|
- Message about adblockers preventing the log table from loading (#2213) (Fixes #2209) [James White]
|
||||||
|
- Sabnzbd Update test cases and rename to MovieCategory (#2212) [James White]
|
||||||
|
- Nzbget Rename TvCategory references to MovieCategory (#2211) [James White]
|
||||||
|
- Change default port of qBittorrent download client config (#2187) [James White]
|
||||||
|
- Initial state for torrents added to qBittorrent (#2176) [James White]
|
||||||
|
- Adjust ambiguous date options (#2165) [James White]
|
||||||
|
- A default name for Radarr.ics (#2163) [James White]
|
||||||
|
|
||||||
|
### **Fixes**
|
||||||
|
- Fixed MediaCover endpoint. [Taloth Saldono]
|
||||||
|
- Don't handle content requests in IndexHtmlMapper. [Mark McDowall]
|
||||||
|
- Movies parsed from lists with no year and only title getting added mutliple times. [Leonardo Galli]
|
||||||
|
- Security Vulnerabilities allowing authentication to be bypassed (discovered by Kyle Neideck) [Taloth Saldono]
|
||||||
|
- Movie Editor Path screwed up. Might also fix some other movie editor issues. (Fixes #2170) [Leonardo Galli]
|
||||||
|
- Tags disappearing (Fixes #2204) [Leonardo Galli]
|
||||||
|
- Moment.js deprecated zone and add functions (Fixes #2232) (Fixes #2231) (#2264) [Fish2]
|
||||||
|
- CPU locking at a 100% in certain instances. (#2258) (Fixes #2218) [Mike]
|
||||||
|
- Revert "Fixed: moment.js deprecated zone and Added: and lossless compression of images (#2232) (Fixes #2231)" [Fish2]
|
||||||
|
- Moment.js deprecated zone and Added: and lossless compression of images (#2232) (Fixes #2231) [Fish2]
|
||||||
|
- Fixes #2218. (#2254) [Mike]
|
||||||
|
- Minor error message tweak (#1778) [Oliver Rivett-Carnac]
|
||||||
|
- UTorrent initial state feature (#2192) [James White]
|
||||||
|
- Add IsUpgrade and related deleted file paths for CustomScript (#2205) [fhscholl]
|
||||||
|
- Typo on margin-bottom (#2182) [James White]
|
||||||
|
- Manual Import. Fixes #2160. [Leonardo Galli]
|
||||||
|
- Remove unit on zero values (#2178) [James White]
|
||||||
|
- Jackett apikey cleaned from log again. (#2177) [James White]
|
||||||
|
- Manual Movie Page Filtering. [Leonardo Galli]
|
||||||
|
- MediaInfo not getting read when quality isn't Bluray, Web-dl or HDTV. Fixes #1465. Fixes #1572. [Leonardo Galli]
|
||||||
|
|
||||||
|
|
||||||
## v0.2.0.870 (2017-10-09)
|
## v0.2.0.870 (2017-10-09)
|
||||||
|
|
||||||
### **New features**
|
### **New features**
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ Radarr is currently undergoing rapid development and pull requests are actively
|
|||||||
|
|
||||||
### Planned Features
|
### Planned Features
|
||||||
|
|
||||||
* Downloading Metadata such as trailers or subtitles (\*)
|
* Importing Metadata such as trailers or subtitles (\*)
|
||||||
* Adding metadata such as posters and information for Kodi and others to use (\*)
|
* Adding metadata such as posters and information for Kodi and others to use (\*)
|
||||||
* Dynamically renaming folders with quality info, etc. (\*)
|
* Dynamically renaming folders with quality info, etc. (\*)
|
||||||
* Supporting custom folder structures, such as all movie files in one folder (\*)
|
* Supporting custom folder structures, such as all movie files in one folder (\*)
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ artifacts:
|
|||||||
|
|
||||||
cache:
|
cache:
|
||||||
- '%USERPROFILE%\.nuget\packages'
|
- '%USERPROFILE%\.nuget\packages'
|
||||||
- node_modules
|
- node_modules -> package.json
|
||||||
|
|
||||||
pull_requests:
|
pull_requests:
|
||||||
do_not_increment_build_number: true
|
do_not_increment_build_number: true
|
||||||
|
|||||||
@@ -69,11 +69,21 @@ BuildWithMSBuild()
|
|||||||
CheckExitCode MSBuild.exe $slnFile //p:Configuration=Release //p:Platform=x86 //t:Build //m //p:AllowedReferenceRelatedFileExtensions=.pdb
|
CheckExitCode MSBuild.exe $slnFile //p:Configuration=Release //p:Platform=x86 //t:Build //m //p:AllowedReferenceRelatedFileExtensions=.pdb
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildWithXbuild()
|
RestoreNuget()
|
||||||
|
{
|
||||||
|
export MONO_IOMAP=case
|
||||||
|
mono $nuget restore $slnFile
|
||||||
|
}
|
||||||
|
|
||||||
|
CleanWithXbuild()
|
||||||
{
|
{
|
||||||
export MONO_IOMAP=case
|
export MONO_IOMAP=case
|
||||||
CheckExitCode xbuild /t:Clean $slnFile
|
CheckExitCode xbuild /t:Clean $slnFile
|
||||||
mono $nuget restore $slnFile
|
}
|
||||||
|
|
||||||
|
BuildWithXbuild()
|
||||||
|
{
|
||||||
|
export MONO_IOMAP=case
|
||||||
CheckExitCode xbuild /p:Configuration=Release /p:Platform=x86 /t:Build /p:AllowedReferenceRelatedFileExtensions=.pdb $slnFile
|
CheckExitCode xbuild /p:Configuration=Release /p:Platform=x86 /t:Build /p:AllowedReferenceRelatedFileExtensions=.pdb $slnFile
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +96,8 @@ Build()
|
|||||||
if [ $runtime = "dotnet" ] ; then
|
if [ $runtime = "dotnet" ] ; then
|
||||||
BuildWithMSBuild
|
BuildWithMSBuild
|
||||||
else
|
else
|
||||||
|
CleanWithXbuild
|
||||||
|
RestoreNuget
|
||||||
BuildWithXbuild
|
BuildWithXbuild
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -256,10 +268,42 @@ case "$(uname -s)" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
Build
|
if [ $# -eq 0 ]
|
||||||
RunGulp
|
then
|
||||||
PackageMono
|
Build
|
||||||
PackageOsx
|
RunGulp
|
||||||
PackageOsxApp
|
PackageMono
|
||||||
PackageTests
|
PackageOsx
|
||||||
CleanupWindowsPackage
|
PackageOsxApp
|
||||||
|
PackageTests
|
||||||
|
CleanupWindowsPackage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "CleanXbuild" ]
|
||||||
|
then rm -rf $outputFolder
|
||||||
|
CleanWithXbuild
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "NugetMono" ]
|
||||||
|
then rm -rf $outputFolder
|
||||||
|
RestoreNuget
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "Build" ]
|
||||||
|
then BuildWithXbuild
|
||||||
|
CleanFolder $outputFolder false
|
||||||
|
AddJsonNet
|
||||||
|
rm $outputFolder/Mono.Posix.dll
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "Gulp" ]
|
||||||
|
then RunGulp
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "Package" ]
|
||||||
|
then PackageMono
|
||||||
|
PackageOsx
|
||||||
|
PackageOsxApp
|
||||||
|
PackageTests
|
||||||
|
CleanupWindowsPackage
|
||||||
|
fi
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Sonarr</string>
|
<string>Radarr</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
|
|||||||
+3479
File diff suppressed because it is too large
Load Diff
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ContentModelUserStore">
|
||||||
|
<explicitIncludes />
|
||||||
|
<explicitExcludes />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -51,9 +51,8 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -96,7 +96,7 @@ namespace MonoTorrent.BEncoding
|
|||||||
if (stream == null)
|
if (stream == null)
|
||||||
throw new ArgumentNullException("stream");
|
throw new ArgumentNullException("stream");
|
||||||
|
|
||||||
return Decode(new RawReader(stream));
|
return Decode(new RawReader(stream, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.Movie;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Blacklist
|
namespace NzbDrone.Api.Blacklist
|
||||||
@@ -20,7 +19,6 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
public string Indexer { get; set; }
|
public string Indexer { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public MovieResource Movie { get; set; }
|
public MovieResource Movie { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BlacklistResourceMapper
|
public static class BlacklistResourceMapper
|
||||||
@@ -41,8 +39,7 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
Protocol = model.Protocol,
|
Protocol = model.Protocol,
|
||||||
Indexer = model.Indexer,
|
Indexer = model.Indexer,
|
||||||
Message = model.Message,
|
Message = model.Message,
|
||||||
Movie = model.Movie.ToResource(),
|
Movie = model.Movie.ToResource()
|
||||||
Series = model.Series.ToResource()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
@@ -17,7 +15,6 @@ using NzbDrone.Core.Validation.Paths;
|
|||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.SignalR;
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Calendar
|
namespace NzbDrone.Api.Calendar
|
||||||
|
|||||||
@@ -41,6 +41,16 @@ namespace NzbDrone.Api.ClientSchema
|
|||||||
};
|
};
|
||||||
|
|
||||||
var value = propertyInfo.GetValue(model, null);
|
var value = propertyInfo.GetValue(model, null);
|
||||||
|
|
||||||
|
if (propertyInfo.PropertyType.HasAttribute<FlagsAttribute>())
|
||||||
|
{
|
||||||
|
int intVal = (int)value;
|
||||||
|
value = Enum.GetValues(propertyInfo.PropertyType)
|
||||||
|
.Cast<int>()
|
||||||
|
.Where(f=> (f & intVal) == f)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
field.Value = value;
|
field.Value = value;
|
||||||
@@ -131,6 +141,12 @@ namespace NzbDrone.Api.ClientSchema
|
|||||||
|
|
||||||
propertyInfo.SetValue(target, value, null);
|
propertyInfo.SetValue(target, value, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (propertyInfo.PropertyType.HasAttribute<FlagsAttribute>())
|
||||||
|
{
|
||||||
|
int value = field.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s)).Sum();
|
||||||
|
propertyInfo.SetValue(target, value, null);
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
|
||||||
@@ -22,6 +22,7 @@ namespace NzbDrone.Api.Config
|
|||||||
|
|
||||||
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
|
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
|
||||||
public bool CopyUsingHardlinks { get; set; }
|
public bool CopyUsingHardlinks { get; set; }
|
||||||
|
public bool ImportExtraFiles { get; set; }
|
||||||
public string ExtraFileExtensions { get; set; }
|
public string ExtraFileExtensions { get; set; }
|
||||||
public bool EnableMediaInfo { get; set; }
|
public bool EnableMediaInfo { get; set; }
|
||||||
}
|
}
|
||||||
@@ -48,6 +49,7 @@ namespace NzbDrone.Api.Config
|
|||||||
|
|
||||||
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
|
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
|
||||||
CopyUsingHardlinks = model.CopyUsingHardlinks,
|
CopyUsingHardlinks = model.CopyUsingHardlinks,
|
||||||
|
ImportExtraFiles = model.ImportExtraFiles,
|
||||||
ExtraFileExtensions = model.ExtraFileExtensions,
|
ExtraFileExtensions = model.ExtraFileExtensions,
|
||||||
EnableMediaInfo = model.EnableMediaInfo
|
EnableMediaInfo = model.EnableMediaInfo
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
using NzbDrone.Core.Datastore.Events;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
|
||||||
using NzbDrone.SignalR;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
|
||||||
{
|
|
||||||
public class EpisodeFileModule : NzbDroneRestModuleWithSignalR<EpisodeFileResource, EpisodeFile>,
|
|
||||||
IHandle<EpisodeFileAddedEvent>
|
|
||||||
{
|
|
||||||
private readonly IMediaFileService _mediaFileService;
|
|
||||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
|
||||||
private readonly ISeriesService _seriesService;
|
|
||||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public EpisodeFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
|
||||||
IMediaFileService mediaFileService,
|
|
||||||
IRecycleBinProvider recycleBinProvider,
|
|
||||||
ISeriesService seriesService,
|
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
|
||||||
Logger logger)
|
|
||||||
: base(signalRBroadcaster)
|
|
||||||
{
|
|
||||||
_mediaFileService = mediaFileService;
|
|
||||||
_recycleBinProvider = recycleBinProvider;
|
|
||||||
_seriesService = seriesService;
|
|
||||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
|
||||||
_logger = logger;
|
|
||||||
GetResourceById = GetEpisodeFile;
|
|
||||||
GetResourceAll = GetEpisodeFiles;
|
|
||||||
UpdateResource = SetQuality;
|
|
||||||
DeleteResource = DeleteEpisodeFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EpisodeFileResource GetEpisodeFile(int id)
|
|
||||||
{
|
|
||||||
var episodeFile = _mediaFileService.Get(id);
|
|
||||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
|
||||||
|
|
||||||
return episodeFile.ToResource(series, _qualityUpgradableSpecification);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<EpisodeFileResource> GetEpisodeFiles()
|
|
||||||
{
|
|
||||||
if (!Request.Query.SeriesId.HasValue)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("seriesId is missing");
|
|
||||||
}
|
|
||||||
|
|
||||||
var seriesId = (int)Request.Query.SeriesId;
|
|
||||||
|
|
||||||
var series = _seriesService.GetSeries(seriesId);
|
|
||||||
|
|
||||||
return _mediaFileService.GetFilesBySeries(seriesId).ConvertAll(f => f.ToResource(series, _qualityUpgradableSpecification));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetQuality(EpisodeFileResource episodeFileResource)
|
|
||||||
{
|
|
||||||
var episodeFile = _mediaFileService.Get(episodeFileResource.Id);
|
|
||||||
episodeFile.Quality = episodeFileResource.Quality;
|
|
||||||
_mediaFileService.Update(episodeFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeleteEpisodeFile(int id)
|
|
||||||
{
|
|
||||||
var episodeFile = _mediaFileService.Get(id);
|
|
||||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
|
||||||
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
|
||||||
|
|
||||||
_logger.Info("Deleting episode file: {0}", fullPath);
|
|
||||||
_recycleBinProvider.DeleteFile(fullPath);
|
|
||||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeFileAddedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
|
||||||
{
|
|
||||||
public class EpisodeFileResource : RestResource
|
|
||||||
{
|
|
||||||
public int SeriesId { get; set; }
|
|
||||||
public int SeasonNumber { get; set; }
|
|
||||||
public string RelativePath { get; set; }
|
|
||||||
public string Path { get; set; }
|
|
||||||
public long Size { get; set; }
|
|
||||||
public DateTime DateAdded { get; set; }
|
|
||||||
public string SceneName { get; set; }
|
|
||||||
public QualityModel Quality { get; set; }
|
|
||||||
|
|
||||||
public bool QualityCutoffNotMet { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EpisodeFileResourceMapper
|
|
||||||
{
|
|
||||||
private static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new EpisodeFileResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
RelativePath = model.RelativePath,
|
|
||||||
//Path
|
|
||||||
Size = model.Size,
|
|
||||||
DateAdded = model.DateAdded,
|
|
||||||
SceneName = model.SceneName,
|
|
||||||
Quality = model.Quality,
|
|
||||||
//QualityCutoffNotMet
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model, Core.Tv.Series series, Core.DecisionEngine.IQualityUpgradableSpecification qualityUpgradableSpecification)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new EpisodeFileResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
RelativePath = model.RelativePath,
|
|
||||||
Path = Path.Combine(series.Path, model.RelativePath),
|
|
||||||
Size = model.Size,
|
|
||||||
DateAdded = model.DateAdded,
|
|
||||||
SceneName = model.SceneName,
|
|
||||||
Quality = model.Quality,
|
|
||||||
QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, model.Quality)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
|
||||||
using NzbDrone.SignalR;
|
|
||||||
using Nancy;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
|
||||||
{
|
|
||||||
public class EpisodeModule : EpisodeModuleWithSignalR
|
|
||||||
{
|
|
||||||
public EpisodeModule(ISeriesService seriesService,
|
|
||||||
IEpisodeService episodeService,
|
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
|
||||||
IBroadcastSignalRMessage signalRBroadcaster)
|
|
||||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster)
|
|
||||||
{
|
|
||||||
GetResourceAll = GetEpisodes;
|
|
||||||
UpdateResource = SetMonitored;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<EpisodeResource> GetEpisodes()
|
|
||||||
{
|
|
||||||
if (!Request.Query.SeriesId.HasValue)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("seriesId is missing");
|
|
||||||
}
|
|
||||||
|
|
||||||
var seriesId = (int)Request.Query.SeriesId;
|
|
||||||
|
|
||||||
var resources = MapToResource(_episodeService.GetEpisodeBySeries(seriesId), false, true);
|
|
||||||
|
|
||||||
return resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetMonitored(EpisodeResource episodeResource)
|
|
||||||
{
|
|
||||||
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Api.EpisodeFiles;
|
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.Datastore.Events;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
|
||||||
using NzbDrone.Core.Download;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.SignalR;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
|
||||||
{
|
|
||||||
public abstract class EpisodeModuleWithSignalR : NzbDroneRestModuleWithSignalR<EpisodeResource, Episode>,
|
|
||||||
IHandle<EpisodeGrabbedEvent>,
|
|
||||||
IHandle<EpisodeDownloadedEvent>
|
|
||||||
{
|
|
||||||
protected readonly IEpisodeService _episodeService;
|
|
||||||
protected readonly ISeriesService _seriesService;
|
|
||||||
protected readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
|
||||||
|
|
||||||
protected EpisodeModuleWithSignalR(IEpisodeService episodeService,
|
|
||||||
ISeriesService seriesService,
|
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
|
||||||
IBroadcastSignalRMessage signalRBroadcaster)
|
|
||||||
: base(signalRBroadcaster)
|
|
||||||
{
|
|
||||||
_episodeService = episodeService;
|
|
||||||
_seriesService = seriesService;
|
|
||||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
|
||||||
|
|
||||||
GetResourceById = GetEpisode;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EpisodeModuleWithSignalR(IEpisodeService episodeService,
|
|
||||||
ISeriesService seriesService,
|
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
|
||||||
IBroadcastSignalRMessage signalRBroadcaster,
|
|
||||||
string resource)
|
|
||||||
: base(signalRBroadcaster, resource)
|
|
||||||
{
|
|
||||||
_episodeService = episodeService;
|
|
||||||
_seriesService = seriesService;
|
|
||||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
|
||||||
|
|
||||||
GetResourceById = GetEpisode;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EpisodeResource GetEpisode(int id)
|
|
||||||
{
|
|
||||||
var episode = _episodeService.GetEpisode(id);
|
|
||||||
var resource = MapToResource(episode, true, true);
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EpisodeResource MapToResource(Episode episode, bool includeSeries, bool includeEpisodeFile)
|
|
||||||
{
|
|
||||||
var resource = episode.ToResource();
|
|
||||||
|
|
||||||
if (includeSeries || includeEpisodeFile)
|
|
||||||
{
|
|
||||||
var series = episode.Series ?? _seriesService.GetSeries(episode.SeriesId);
|
|
||||||
|
|
||||||
if (includeSeries)
|
|
||||||
{
|
|
||||||
resource.Series = series.ToResource();
|
|
||||||
}
|
|
||||||
if (includeEpisodeFile && episode.EpisodeFileId != 0)
|
|
||||||
{
|
|
||||||
resource.EpisodeFile = episode.EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<EpisodeResource> MapToResource(List<Episode> episodes, bool includeSeries, bool includeEpisodeFile)
|
|
||||||
{
|
|
||||||
var result = episodes.ToResource();
|
|
||||||
|
|
||||||
if (includeSeries || includeEpisodeFile)
|
|
||||||
{
|
|
||||||
var seriesDict = new Dictionary<int, Core.Tv.Series>();
|
|
||||||
for (var i = 0; i < episodes.Count; i++)
|
|
||||||
{
|
|
||||||
var episode = episodes[i];
|
|
||||||
var resource = result[i];
|
|
||||||
|
|
||||||
var series = episode.Series ?? seriesDict.GetValueOrDefault(episodes[i].SeriesId) ?? _seriesService.GetSeries(episodes[i].SeriesId);
|
|
||||||
seriesDict[series.Id] = series;
|
|
||||||
|
|
||||||
if (includeSeries)
|
|
||||||
{
|
|
||||||
resource.Series = series.ToResource();
|
|
||||||
}
|
|
||||||
if (includeEpisodeFile && episodes[i].EpisodeFileId != 0)
|
|
||||||
{
|
|
||||||
resource.EpisodeFile = episodes[i].EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeGrabbedEvent message)
|
|
||||||
{
|
|
||||||
foreach (var episode in message.Episode.Episodes)
|
|
||||||
{
|
|
||||||
var resource = episode.ToResource();
|
|
||||||
resource.Grabbed = true;
|
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeDownloadedEvent message)
|
|
||||||
{
|
|
||||||
foreach (var episode in message.Episode.Episodes)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, episode.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using NzbDrone.Api.EpisodeFiles;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
|
||||||
{
|
|
||||||
public class EpisodeResource : RestResource
|
|
||||||
{
|
|
||||||
public int SeriesId { get; set; }
|
|
||||||
public int EpisodeFileId { get; set; }
|
|
||||||
public int SeasonNumber { get; set; }
|
|
||||||
public int EpisodeNumber { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public string AirDate { get; set; }
|
|
||||||
public DateTime? AirDateUtc { get; set; }
|
|
||||||
public string Overview { get; set; }
|
|
||||||
public EpisodeFileResource EpisodeFile { get; set; }
|
|
||||||
|
|
||||||
public bool HasFile { get; set; }
|
|
||||||
public bool Monitored { get; set; }
|
|
||||||
public int? AbsoluteEpisodeNumber { get; set; }
|
|
||||||
public int? SceneAbsoluteEpisodeNumber { get; set; }
|
|
||||||
public int? SceneEpisodeNumber { get; set; }
|
|
||||||
public int? SceneSeasonNumber { get; set; }
|
|
||||||
public bool UnverifiedSceneNumbering { get; set; }
|
|
||||||
public string SeriesTitle { get; set; }
|
|
||||||
public SeriesResource Series { get; set; }
|
|
||||||
|
|
||||||
//Hiding this so people don't think its usable (only used to set the initial state)
|
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
|
||||||
public bool Grabbed { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EpisodeResourceMapper
|
|
||||||
{
|
|
||||||
public static EpisodeResource ToResource(this Episode model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new EpisodeResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
EpisodeFileId = model.EpisodeFileId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
EpisodeNumber = model.EpisodeNumber,
|
|
||||||
Title = model.Title,
|
|
||||||
AirDate = model.AirDate,
|
|
||||||
AirDateUtc = model.AirDateUtc,
|
|
||||||
Overview = model.Overview,
|
|
||||||
//EpisodeFile
|
|
||||||
|
|
||||||
HasFile = model.HasFile,
|
|
||||||
Monitored = model.Monitored,
|
|
||||||
AbsoluteEpisodeNumber = model.AbsoluteEpisodeNumber,
|
|
||||||
SceneAbsoluteEpisodeNumber = model.SceneAbsoluteEpisodeNumber,
|
|
||||||
SceneEpisodeNumber = model.SceneEpisodeNumber,
|
|
||||||
SceneSeasonNumber = model.SceneSeasonNumber,
|
|
||||||
UnverifiedSceneNumbering = model.UnverifiedSceneNumbering,
|
|
||||||
SeriesTitle = model.SeriesTitle,
|
|
||||||
//Series = model.Series.MapToResource(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<EpisodeResource> ToResource(this IEnumerable<Episode> models)
|
|
||||||
{
|
|
||||||
if (models == null) return null;
|
|
||||||
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
|
||||||
{
|
|
||||||
public class RenameEpisodeModule : NzbDroneRestModule<RenameEpisodeResource>
|
|
||||||
{
|
|
||||||
private readonly IRenameEpisodeFileService _renameEpisodeFileService;
|
|
||||||
|
|
||||||
public RenameEpisodeModule(IRenameEpisodeFileService renameEpisodeFileService)
|
|
||||||
: base("rename")
|
|
||||||
{
|
|
||||||
_renameEpisodeFileService = renameEpisodeFileService;
|
|
||||||
|
|
||||||
GetResourceAll = GetEpisodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<RenameEpisodeResource> GetEpisodes()
|
|
||||||
{
|
|
||||||
if (!Request.Query.SeriesId.HasValue)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("seriesId is missing");
|
|
||||||
}
|
|
||||||
|
|
||||||
var seriesId = (int)Request.Query.SeriesId;
|
|
||||||
|
|
||||||
if (Request.Query.SeasonNumber.HasValue)
|
|
||||||
{
|
|
||||||
var seasonNumber = (int)Request.Query.SeasonNumber;
|
|
||||||
return _renameEpisodeFileService.GetRenamePreviews(seriesId, seasonNumber).ToResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _renameEpisodeFileService.GetRenamePreviews(seriesId).ToResource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
|
||||||
{
|
|
||||||
public class RenameEpisodeResource : RestResource
|
|
||||||
{
|
|
||||||
public int SeriesId { get; set; }
|
|
||||||
public int SeasonNumber { get; set; }
|
|
||||||
public List<int> EpisodeNumbers { get; set; }
|
|
||||||
public int EpisodeFileId { get; set; }
|
|
||||||
public string ExistingPath { get; set; }
|
|
||||||
public string NewPath { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RenameEpisodeResourceMapper
|
|
||||||
{
|
|
||||||
public static RenameEpisodeResource ToResource(this Core.MediaFiles.RenameEpisodeFilePreview model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new RenameEpisodeResource
|
|
||||||
{
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
EpisodeNumbers = model.EpisodeNumbers.ToList(),
|
|
||||||
EpisodeFileId = model.EpisodeFileId,
|
|
||||||
ExistingPath = model.ExistingPath,
|
|
||||||
NewPath = model.NewPath
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<RenameEpisodeResource> ToResource(this IEnumerable<Core.MediaFiles.RenameEpisodeFilePreview> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Core.Extras.Files;
|
||||||
|
using NzbDrone.Core.Extras.Metadata.Files;
|
||||||
|
using NzbDrone.Core.Extras.Others;
|
||||||
|
using NzbDrone.Core.Extras.Subtitles;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.ExtraFiles
|
||||||
|
{
|
||||||
|
public class ExtraFileModule : NzbDroneRestModule<ExtraFileResource>
|
||||||
|
{
|
||||||
|
private readonly IExtraFileService<SubtitleFile> _subtitleFileService;
|
||||||
|
private readonly IExtraFileService<MetadataFile> _metadataFileService;
|
||||||
|
private readonly IExtraFileService<OtherExtraFile> _otherFileService;
|
||||||
|
|
||||||
|
public ExtraFileModule(IExtraFileService<SubtitleFile> subtitleFileService, IExtraFileService<MetadataFile> metadataFileService, IExtraFileService<OtherExtraFile> otherExtraFileService)
|
||||||
|
: base("/extrafile")
|
||||||
|
{
|
||||||
|
_subtitleFileService = subtitleFileService;
|
||||||
|
_metadataFileService = metadataFileService;
|
||||||
|
_otherFileService = otherExtraFileService;
|
||||||
|
GetResourceAll = GetFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ExtraFileResource> GetFiles()
|
||||||
|
{
|
||||||
|
if (!Request.Query.MovieId.HasValue)
|
||||||
|
{
|
||||||
|
throw new BadRequestException("MovieId is missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
var extraFiles = new List<ExtraFileResource>();
|
||||||
|
|
||||||
|
List<SubtitleFile> subtitleFiles = _subtitleFileService.GetFilesByMovie(Request.Query.MovieId);
|
||||||
|
List<MetadataFile> metadataFiles = _metadataFileService.GetFilesByMovie(Request.Query.MovieId);
|
||||||
|
List<OtherExtraFile> otherExtraFiles = _otherFileService.GetFilesByMovie(Request.Query.MovieId);
|
||||||
|
|
||||||
|
extraFiles.AddRange(subtitleFiles.ToResource());
|
||||||
|
extraFiles.AddRange(metadataFiles.ToResource());
|
||||||
|
extraFiles.AddRange(otherExtraFiles.ToResource());
|
||||||
|
|
||||||
|
return extraFiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Core.Extras.Files;
|
||||||
|
using NzbDrone.Core.Extras.Metadata.Files;
|
||||||
|
using NzbDrone.Core.Extras.Others;
|
||||||
|
using NzbDrone.Core.Extras.Subtitles;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.ExtraFiles
|
||||||
|
{
|
||||||
|
public class ExtraFileResource : RestResource
|
||||||
|
{
|
||||||
|
public int MovieId { get; set; }
|
||||||
|
public int? MovieFileId { get; set; }
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
public string Extension { get; set; }
|
||||||
|
public ExtraFileType Type { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ExtraFileResourceMapper
|
||||||
|
{
|
||||||
|
public static ExtraFileResource ToResource(this MetadataFile model)
|
||||||
|
{
|
||||||
|
if (model == null) return null;
|
||||||
|
|
||||||
|
return new ExtraFileResource
|
||||||
|
{
|
||||||
|
Id = model.Id,
|
||||||
|
MovieId = model.MovieId,
|
||||||
|
MovieFileId = model.MovieFileId,
|
||||||
|
RelativePath = model.RelativePath,
|
||||||
|
Extension = model.Extension,
|
||||||
|
Type = ExtraFileType.Metadata
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtraFileResource ToResource(this SubtitleFile model)
|
||||||
|
{
|
||||||
|
if (model == null) return null;
|
||||||
|
|
||||||
|
return new ExtraFileResource
|
||||||
|
{
|
||||||
|
Id = model.Id,
|
||||||
|
MovieId = model.MovieId,
|
||||||
|
MovieFileId = model.MovieFileId,
|
||||||
|
RelativePath = model.RelativePath,
|
||||||
|
Extension = model.Extension,
|
||||||
|
Type = ExtraFileType.Subtitle
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtraFileResource ToResource(this OtherExtraFile model)
|
||||||
|
{
|
||||||
|
if (model == null) return null;
|
||||||
|
|
||||||
|
return new ExtraFileResource
|
||||||
|
{
|
||||||
|
Id = model.Id,
|
||||||
|
MovieId = model.MovieId,
|
||||||
|
MovieFileId = model.MovieFileId,
|
||||||
|
RelativePath = model.RelativePath,
|
||||||
|
Extension = model.Extension,
|
||||||
|
Type = ExtraFileType.Other
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ExtraFileResource> ToResource(this IEnumerable<SubtitleFile> movies)
|
||||||
|
{
|
||||||
|
return movies.Select(ToResource).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ExtraFileResource> ToResource(this IEnumerable<MetadataFile> movies)
|
||||||
|
{
|
||||||
|
return movies.Select(ToResource).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ExtraFileResource> ToResource(this IEnumerable<OtherExtraFile> movies)
|
||||||
|
{
|
||||||
|
return movies.Select(ToResource).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Api.Movie;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.Episodes;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Core.History;
|
using NzbDrone.Core.History;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
@@ -12,9 +10,7 @@ namespace NzbDrone.Api.History
|
|||||||
{
|
{
|
||||||
public class HistoryResource : RestResource
|
public class HistoryResource : RestResource
|
||||||
{
|
{
|
||||||
public int EpisodeId { get; set; }
|
|
||||||
public int MovieId { get; set; }
|
public int MovieId { get; set; }
|
||||||
public int SeriesId { get; set; }
|
|
||||||
public string SourceTitle { get; set; }
|
public string SourceTitle { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public bool QualityCutoffNotMet { get; set; }
|
public bool QualityCutoffNotMet { get; set; }
|
||||||
@@ -25,8 +21,6 @@ namespace NzbDrone.Api.History
|
|||||||
|
|
||||||
public Dictionary<string, string> Data { get; set; }
|
public Dictionary<string, string> Data { get; set; }
|
||||||
public MovieResource Movie { get; set; }
|
public MovieResource Movie { get; set; }
|
||||||
public EpisodeResource Episode { get; set; }
|
|
||||||
public SeriesResource Series { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HistoryResourceMapper
|
public static class HistoryResourceMapper
|
||||||
@@ -38,9 +32,6 @@ namespace NzbDrone.Api.History
|
|||||||
return new HistoryResource
|
return new HistoryResource
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.Id,
|
||||||
|
|
||||||
EpisodeId = model.EpisodeId,
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
MovieId = model.MovieId,
|
MovieId = model.MovieId,
|
||||||
SourceTitle = model.SourceTitle,
|
SourceTitle = model.SourceTitle,
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
@@ -51,8 +42,6 @@ namespace NzbDrone.Api.History
|
|||||||
EventType = model.EventType,
|
EventType = model.EventType,
|
||||||
|
|
||||||
Data = model.Data
|
Data = model.Data
|
||||||
//Episode
|
|
||||||
//Series
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Common.Crypto;
|
using NzbDrone.Common.Crypto;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
@@ -15,9 +14,7 @@ namespace NzbDrone.Api.ManualImport
|
|||||||
public string RelativePath { get; set; }
|
public string RelativePath { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
public MovieResource Movie { get; set; }
|
||||||
public int? SeasonNumber { get; set; }
|
|
||||||
public List<EpisodeResource> Episodes { get; set; }
|
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public int QualityWeight { get; set; }
|
public int QualityWeight { get; set; }
|
||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
@@ -38,9 +35,7 @@ namespace NzbDrone.Api.ManualImport
|
|||||||
RelativePath = model.RelativePath,
|
RelativePath = model.RelativePath,
|
||||||
Name = model.Name,
|
Name = model.Name,
|
||||||
Size = model.Size,
|
Size = model.Size,
|
||||||
Series = model.Series.ToResource(),
|
Movie = model.Movie.ToResource(),
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
Episodes = model.Episodes.ToResource(),
|
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
//QualityWeight
|
//QualityWeight
|
||||||
DownloadId = model.DownloadId,
|
DownloadId = model.DownloadId,
|
||||||
|
|||||||
+3
-4
@@ -1,8 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
@@ -11,7 +10,7 @@ using NzbDrone.Core.Tv;
|
|||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.SignalR;
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
namespace NzbDrone.Api.MovieFiles
|
||||||
{
|
{
|
||||||
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>, IHandle<MovieFileAddedEvent>
|
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>, IHandle<MovieFileAddedEvent>
|
||||||
{
|
{
|
||||||
@@ -72,4 +71,4 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
BroadcastResourceChange(ModelAction.Updated, message.MovieFile.Id);
|
BroadcastResourceChange(ModelAction.Updated, message.MovieFile.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -1,14 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.MovieFiles
|
||||||
{
|
{
|
||||||
public class MovieFileResource : RestResource
|
public class MovieFileResource : RestResource
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api;
|
using NzbDrone.Api;
|
||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
@@ -18,7 +17,7 @@ using NzbDrone.Core.RootFolders;
|
|||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Tv.Events;
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class AlternativeTitleModule : NzbDroneRestModule<AlternativeTitleResource>
|
public class AlternativeTitleModule : NzbDroneRestModule<AlternativeTitleResource>
|
||||||
{
|
{
|
||||||
@@ -54,4 +53,4 @@ namespace NzbDrone.Api.Movie
|
|||||||
return _altTitleService.GetById(id).ToResource();
|
return _altTitleService.GetById(id).ToResource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -1,16 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Movies.AlternativeTitles;
|
using NzbDrone.Core.Movies.AlternativeTitles;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class AlternativeTitleResource : RestResource
|
public class AlternativeTitleResource : RestResource
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api;
|
using NzbDrone.Api;
|
||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Messaging;
|
using NzbDrone.Common.Messaging;
|
||||||
@@ -19,7 +18,7 @@ using NzbDrone.Core.RootFolders;
|
|||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Tv.Events;
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class AlternativeYearModule : NzbDroneRestModule<AlternativeYearResource>
|
public class AlternativeYearModule : NzbDroneRestModule<AlternativeYearResource>
|
||||||
{
|
{
|
||||||
@@ -60,4 +59,4 @@ namespace NzbDrone.Api.Movie
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Movies.AlternativeTitles;
|
using NzbDrone.Core.Movies.AlternativeTitles;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class AlternativeYearResource : RestResource
|
public class AlternativeYearResource : RestResource
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
@@ -6,7 +6,7 @@ using NzbDrone.Core.MetadataSource;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.NetImport;
|
using NzbDrone.Core.NetImport;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class FetchMovieListModule : NzbDroneRestModule<MovieResource>
|
public class FetchMovieListModule : NzbDroneRestModule<MovieResource>
|
||||||
{
|
{
|
||||||
@@ -57,4 +57,4 @@ namespace NzbDrone.Api.Movie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
@@ -16,7 +15,7 @@ using NzbDrone.Core.RootFolders;
|
|||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
|
|
||||||
public class UnmappedComparer : IComparer<UnmappedFolder>
|
public class UnmappedComparer : IComparer<UnmappedFolder>
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
@@ -9,7 +9,7 @@ using NzbDrone.Api.REST;
|
|||||||
using NzbDrone.Core.NetImport;
|
using NzbDrone.Core.NetImport;
|
||||||
using NzbDrone.Api.NetImport;
|
using NzbDrone.Api.NetImport;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class MovieDiscoverModule : NzbDroneRestModule<MovieResource>
|
public class MovieDiscoverModule : NzbDroneRestModule<MovieResource>
|
||||||
{
|
{
|
||||||
@@ -60,4 +60,4 @@ namespace NzbDrone.Api.Movie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
@@ -7,7 +7,7 @@ using NzbDrone.Api.Extensions;
|
|||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class MovieEditorModule : NzbDroneApiModule
|
public class MovieEditorModule : NzbDroneApiModule
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
@@ -7,7 +7,7 @@ using System.Linq;
|
|||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class MovieLookupModule : NzbDroneRestModule<MovieResource>
|
public class MovieLookupModule : NzbDroneRestModule<MovieResource>
|
||||||
{
|
{
|
||||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
private readonly IProvideMovieInfo _movieInfo;
|
private readonly IProvideMovieInfo _movieInfo;
|
||||||
|
|
||||||
public MovieLookupModule(ISearchForNewMovie searchProxy, IProvideMovieInfo movieInfo)
|
public MovieLookupModule(ISearchForNewMovie searchProxy, IProvideMovieInfo movieInfo)
|
||||||
: base("/movies/lookup")
|
: base("/movie/lookup")
|
||||||
{
|
{
|
||||||
_movieInfo = movieInfo;
|
_movieInfo = movieInfo;
|
||||||
_searchProxy = searchProxy;
|
_searchProxy = searchProxy;
|
||||||
@@ -64,4 +64,4 @@ namespace NzbDrone.Api.Movie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,298 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using FluentValidation;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Api.Extensions;
|
||||||
|
using NzbDrone.Core.Datastore.Events;
|
||||||
|
using NzbDrone.Core.MediaCover;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.MovieStats;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using Microsoft.CSharp.RuntimeBinder;
|
||||||
|
using Nancy;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movies
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
class MovieModule
|
public class MovieModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
|
||||||
|
IHandle<EpisodeImportedEvent>,
|
||||||
|
IHandle<EpisodeFileDeletedEvent>,
|
||||||
|
IHandle<MovieUpdatedEvent>,
|
||||||
|
IHandle<MovieEditedEvent>,
|
||||||
|
IHandle<MovieDeletedEvent>,
|
||||||
|
IHandle<MovieRenamedEvent>,
|
||||||
|
IHandle<MediaCoversUpdatedEvent>
|
||||||
|
|
||||||
{
|
{
|
||||||
|
protected readonly IMovieService _moviesService;
|
||||||
|
private readonly IMovieStatisticsService _moviesStatisticsService;
|
||||||
|
private readonly IMapCoversToLocal _coverMapper;
|
||||||
|
|
||||||
|
private const string TITLE_SLUG_ROUTE = "/titleslug/(?<slug>[^/]+)";
|
||||||
|
|
||||||
|
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
|
IMovieService moviesService,
|
||||||
|
IMovieStatisticsService moviesStatisticsService,
|
||||||
|
ISceneMappingService sceneMappingService,
|
||||||
|
IMapCoversToLocal coverMapper,
|
||||||
|
RootFolderValidator rootFolderValidator,
|
||||||
|
MoviePathValidator moviesPathValidator,
|
||||||
|
MovieExistsValidator moviesExistsValidator,
|
||||||
|
DroneFactoryValidator droneFactoryValidator,
|
||||||
|
MovieAncestorValidator moviesAncestorValidator,
|
||||||
|
ProfileExistsValidator profileExistsValidator
|
||||||
|
)
|
||||||
|
: base(signalRBroadcaster)
|
||||||
|
{
|
||||||
|
_moviesService = moviesService;
|
||||||
|
_moviesStatisticsService = moviesStatisticsService;
|
||||||
|
|
||||||
|
_coverMapper = coverMapper;
|
||||||
|
|
||||||
|
GetResourceAll = AllMovie;
|
||||||
|
GetResourcePaged = GetMoviePaged;
|
||||||
|
GetResourceById = GetMovie;
|
||||||
|
Get[TITLE_SLUG_ROUTE] = GetByTitleSlug; /*(options) => {
|
||||||
|
return ReqResExtensions.AsResponse(GetByTitleSlug(options.slug), Nancy.HttpStatusCode.OK);
|
||||||
|
};*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CreateResource = AddMovie;
|
||||||
|
UpdateResource = UpdateMovie;
|
||||||
|
DeleteResource = DeleteMovie;
|
||||||
|
|
||||||
|
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(s => s.Path)
|
||||||
|
.Cascade(CascadeMode.StopOnFirstFailure)
|
||||||
|
.IsValidPath()
|
||||||
|
.SetValidator(rootFolderValidator)
|
||||||
|
.SetValidator(moviesPathValidator)
|
||||||
|
.SetValidator(droneFactoryValidator)
|
||||||
|
.SetValidator(moviesAncestorValidator)
|
||||||
|
.When(s => !s.Path.IsNullOrWhiteSpace());
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator);
|
||||||
|
|
||||||
|
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
||||||
|
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
||||||
|
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
||||||
|
PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
|
||||||
|
|
||||||
|
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
|
IMovieService moviesService,
|
||||||
|
IMovieStatisticsService moviesStatisticsService,
|
||||||
|
ISceneMappingService sceneMappingService,
|
||||||
|
IMapCoversToLocal coverMapper,
|
||||||
|
string resource)
|
||||||
|
: base(signalRBroadcaster, resource)
|
||||||
|
{
|
||||||
|
_moviesService = moviesService;
|
||||||
|
_moviesStatisticsService = moviesStatisticsService;
|
||||||
|
|
||||||
|
_coverMapper = coverMapper;
|
||||||
|
|
||||||
|
GetResourceAll = AllMovie;
|
||||||
|
GetResourceById = GetMovie;
|
||||||
|
CreateResource = AddMovie;
|
||||||
|
UpdateResource = UpdateMovie;
|
||||||
|
DeleteResource = DeleteMovie;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MovieResource GetMovie(int id)
|
||||||
|
{
|
||||||
|
var movies = _moviesService.GetMovie(id);
|
||||||
|
return MapToResource(movies);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PagingResource<MovieResource> GetMoviePaged(PagingResource<MovieResource> pagingResource)
|
||||||
|
{
|
||||||
|
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>();
|
||||||
|
|
||||||
|
pagingSpec.FilterExpression = _moviesService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue, pagingResource.FilterType);
|
||||||
|
|
||||||
|
return ApplyToPage(_moviesService.Paged, pagingSpec, MapToResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MovieResource MapToResource(Core.Tv.Movie movies)
|
||||||
|
{
|
||||||
|
if (movies == null) return null;
|
||||||
|
|
||||||
|
var resource = movies.ToResource();
|
||||||
|
MapCoversToLocal(resource);
|
||||||
|
//FetchAndLinkMovieStatistics(resource);
|
||||||
|
//PopulateAlternateTitles(resource);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MovieResource> AllMovie()
|
||||||
|
{
|
||||||
|
var moviesStats = _moviesStatisticsService.MovieStatistics();
|
||||||
|
var moviesResources = _moviesService.GetAllMovies().ToResource();
|
||||||
|
|
||||||
|
MapCoversToLocal(moviesResources.ToArray());
|
||||||
|
LinkMovieStatistics(moviesResources, moviesStats);
|
||||||
|
PopulateAlternateTitles(moviesResources);
|
||||||
|
|
||||||
|
return moviesResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response GetByTitleSlug(dynamic options)
|
||||||
|
{
|
||||||
|
var slug = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
slug = options.slug;
|
||||||
|
// do stuff with x
|
||||||
|
}
|
||||||
|
catch (RuntimeBinderException)
|
||||||
|
{
|
||||||
|
return new NotFoundResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return MapToResource(_moviesService.FindByTitleSlug(slug)).AsResponse(Nancy.HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
catch (ModelNotFoundException)
|
||||||
|
{
|
||||||
|
return new NotFoundResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int AddMovie(MovieResource moviesResource)
|
||||||
|
{
|
||||||
|
var model = moviesResource.ToModel();
|
||||||
|
|
||||||
|
return _moviesService.AddMovie(model).Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateMovie(MovieResource moviesResource)
|
||||||
|
{
|
||||||
|
var model = moviesResource.ToModel(_moviesService.GetMovie(moviesResource.Id));
|
||||||
|
|
||||||
|
_moviesService.UpdateMovie(model);
|
||||||
|
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, moviesResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteMovie(int id)
|
||||||
|
{
|
||||||
|
var deleteFiles = false;
|
||||||
|
var addExclusion = false;
|
||||||
|
var deleteFilesQuery = Request.Query.deleteFiles;
|
||||||
|
var addExclusionQuery = Request.Query.addExclusion;
|
||||||
|
|
||||||
|
if (deleteFilesQuery.HasValue)
|
||||||
|
{
|
||||||
|
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
|
||||||
|
}
|
||||||
|
if (addExclusionQuery.HasValue)
|
||||||
|
{
|
||||||
|
addExclusion = Convert.ToBoolean(addExclusionQuery.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapCoversToLocal(params MovieResource[] movies)
|
||||||
|
{
|
||||||
|
foreach (var moviesResource in movies)
|
||||||
|
{
|
||||||
|
_coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FetchAndLinkMovieStatistics(MovieResource resource)
|
||||||
|
{
|
||||||
|
LinkMovieStatistics(resource, _moviesStatisticsService.MovieStatistics(resource.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LinkMovieStatistics(List<MovieResource> resources, List<MovieStatistics> moviesStatistics)
|
||||||
|
{
|
||||||
|
var dictMovieStats = moviesStatistics.ToDictionary(v => v.MovieId);
|
||||||
|
|
||||||
|
foreach (var movies in resources)
|
||||||
|
{
|
||||||
|
var stats = dictMovieStats.GetValueOrDefault(movies.Id);
|
||||||
|
if (stats == null) continue;
|
||||||
|
|
||||||
|
LinkMovieStatistics(movies, stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
|
||||||
|
{
|
||||||
|
//resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateAlternateTitles(List<MovieResource> resources)
|
||||||
|
{
|
||||||
|
foreach (var resource in resources)
|
||||||
|
{
|
||||||
|
PopulateAlternateTitles(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateAlternateTitles(MovieResource resource)
|
||||||
|
{
|
||||||
|
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
|
||||||
|
|
||||||
|
//if (mappings == null) return;
|
||||||
|
|
||||||
|
//Not necessary anymore
|
||||||
|
|
||||||
|
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(EpisodeImportedEvent message)
|
||||||
|
{
|
||||||
|
//BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.MovieId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(EpisodeFileDeletedEvent message)
|
||||||
|
{
|
||||||
|
if (message.Reason == DeleteMediaFileReason.Upgrade) return;
|
||||||
|
|
||||||
|
//BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.MovieId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieUpdatedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieEditedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieDeletedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieRenamedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(MediaCoversUpdatedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using NzbDrone.Api.Movie;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.MovieFiles;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movies
|
||||||
{
|
{
|
||||||
public class MovieResource : RestResource
|
public class MovieResource : RestResource
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using NzbDrone.Api.ClientSchema;
|
using NzbDrone.Api.ClientSchema;
|
||||||
using NzbDrone.Core.NetImport;
|
using NzbDrone.Core.NetImport;
|
||||||
using NzbDrone.Core.NetImport.ImportExclusions;
|
using NzbDrone.Core.NetImport.ImportExclusions;
|
||||||
using NzbDrone.Core.Validation.Paths;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
namespace NzbDrone.Api.NetImport
|
namespace NzbDrone.Api.NetImport
|
||||||
{
|
{
|
||||||
public class ImportExclusionsModule : NzbDroneRestModule<ImportExclusionsResource>
|
public class ImportExclusionsModule : NzbDroneRestModule<ImportExclusionsResource>
|
||||||
{
|
{
|
||||||
private readonly IImportExclusionsService _exclusionService;
|
private readonly IImportExclusionsService _exclusionService;
|
||||||
|
|
||||||
public ImportExclusionsModule(NetImportFactory netImportFactory, IImportExclusionsService exclusionService) : base("exclusions")
|
public ImportExclusionsModule(NetImportFactory netImportFactory, IImportExclusionsService exclusionService) : base("exclusions")
|
||||||
{
|
{
|
||||||
_exclusionService = exclusionService;
|
_exclusionService = exclusionService;
|
||||||
GetResourceAll = GetAll;
|
GetResourceAll = GetAll;
|
||||||
CreateResource = AddExclusion;
|
CreateResource = AddExclusion;
|
||||||
DeleteResource = RemoveExclusion;
|
DeleteResource = RemoveExclusion;
|
||||||
GetResourceById = GetById;
|
GetResourceById = GetById;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportExclusionsResource> GetAll()
|
public List<ImportExclusionsResource> GetAll()
|
||||||
{
|
{
|
||||||
return _exclusionService.GetAllExclusions().ToResource();
|
return _exclusionService.GetAllExclusions().ToResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImportExclusionsResource GetById(int id)
|
public ImportExclusionsResource GetById(int id)
|
||||||
{
|
{
|
||||||
return _exclusionService.GetById(id).ToResource();
|
return _exclusionService.GetById(id).ToResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int AddExclusion(ImportExclusionsResource exclusionResource)
|
public int AddExclusion(ImportExclusionsResource exclusionResource)
|
||||||
{
|
{
|
||||||
@@ -40,6 +40,6 @@ namespace NzbDrone.Api.NetImport
|
|||||||
public void RemoveExclusion (int id)
|
public void RemoveExclusion (int id)
|
||||||
{
|
{
|
||||||
_exclusionService.RemoveExclusion(new ImportExclusion { Id = id });
|
_exclusionService.RemoveExclusion(new ImportExclusion { Id = id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.NetImport;
|
using NzbDrone.Core.NetImport;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.NetImport
|
namespace NzbDrone.Api.NetImport
|
||||||
{
|
{
|
||||||
public class ImportExclusionsResource : ProviderResource
|
public class ImportExclusionsResource : ProviderResource
|
||||||
{
|
{
|
||||||
//public int Id { get; set; }
|
//public int Id { get; set; }
|
||||||
public int TmdbId { get; set; }
|
public int TmdbId { get; set; }
|
||||||
public string MovieTitle { get; set; }
|
public string MovieTitle { get; set; }
|
||||||
public int MovieYear { get; set; }
|
public int MovieYear { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ImportExclusionsResourceMapper
|
public static class ImportExclusionsResourceMapper
|
||||||
{
|
{
|
||||||
public static ImportExclusionsResource ToResource(this Core.NetImport.ImportExclusions.ImportExclusion model)
|
public static ImportExclusionsResource ToResource(this Core.NetImport.ImportExclusions.ImportExclusion model)
|
||||||
{
|
{
|
||||||
if (model == null) return null;
|
if (model == null) return null;
|
||||||
|
|
||||||
return new ImportExclusionsResource
|
return new ImportExclusionsResource
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.Id,
|
||||||
TmdbId = model.TmdbId,
|
TmdbId = model.TmdbId,
|
||||||
MovieTitle = model.MovieTitle,
|
MovieTitle = model.MovieTitle,
|
||||||
MovieYear = model.MovieYear
|
MovieYear = model.MovieYear
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ImportExclusionsResource> ToResource(this IEnumerable<Core.NetImport.ImportExclusions.ImportExclusion> exclusions)
|
public static List<ImportExclusionsResource> ToResource(this IEnumerable<Core.NetImport.ImportExclusions.ImportExclusion> exclusions)
|
||||||
{
|
{
|
||||||
return exclusions.Select(ToResource).ToList();
|
return exclusions.Select(ToResource).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Core.NetImport.ImportExclusions.ImportExclusion ToModel(this ImportExclusionsResource resource)
|
public static Core.NetImport.ImportExclusions.ImportExclusion ToModel(this ImportExclusionsResource resource)
|
||||||
{
|
{
|
||||||
return new Core.NetImport.ImportExclusions.ImportExclusion
|
return new Core.NetImport.ImportExclusions.ImportExclusion
|
||||||
{
|
{
|
||||||
TmdbId = resource.TmdbId,
|
TmdbId = resource.TmdbId,
|
||||||
MovieTitle = resource.MovieTitle,
|
MovieTitle = resource.MovieTitle,
|
||||||
MovieYear = resource.MovieYear
|
MovieYear = resource.MovieYear
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Extensions;
|
using Nancy.Extensions;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Api.Movie;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Core.MetadataSource;
|
using NzbDrone.Core.MetadataSource;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using NzbDrone.Core.NetImport;
|
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.NetImport
|
namespace NzbDrone.Api.NetImport
|
||||||
|
|||||||
@@ -72,9 +72,8 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NodaTime, Version=1.3.0.0, Culture=neutral, PublicKeyToken=4226afe0d9b296d1, processorArchitecture=MSIL">
|
<Reference Include="NodaTime, Version=1.3.0.0, Culture=neutral, PublicKeyToken=4226afe0d9b296d1, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\NodaTime.dll</HintPath>
|
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\NodaTime.dll</HintPath>
|
||||||
@@ -115,17 +114,19 @@
|
|||||||
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
|
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
|
||||||
<Compile Include="Extensions\Pipelines\UrlBasePipeline.cs" />
|
<Compile Include="Extensions\Pipelines\UrlBasePipeline.cs" />
|
||||||
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
|
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
|
||||||
|
<Compile Include="ExtraFiles\ExtraFileResource.cs" />
|
||||||
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
|
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
|
||||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||||
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
||||||
<Compile Include="Indexers\ReleasePushModule.cs" />
|
<Compile Include="Indexers\ReleasePushModule.cs" />
|
||||||
|
<Compile Include="ExtraFiles\ExtraFileModule.cs" />
|
||||||
<Compile Include="Movies\AlternativeTitleModule.cs" />
|
<Compile Include="Movies\AlternativeTitleModule.cs" />
|
||||||
<Compile Include="Movies\AlternativeYearResource.cs" />
|
<Compile Include="Movies\AlternativeYearResource.cs" />
|
||||||
<Compile Include="Movies\AlternativeYearModule.cs" />
|
<Compile Include="Movies\AlternativeYearModule.cs" />
|
||||||
<Compile Include="Movies\MovieModuleWithSignalR.cs" />
|
<Compile Include="Movies\MovieModuleWithSignalR.cs" />
|
||||||
<Compile Include="Movies\MovieBulkImportModule.cs" />
|
<Compile Include="Movies\MovieBulkImportModule.cs" />
|
||||||
<Compile Include="Movies\MovieFileModule.cs" />
|
<Compile Include="MovieFiles\MovieFileModule.cs" />
|
||||||
<Compile Include="Series\MovieModule.cs" />
|
<Compile Include="Movies\MovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieModule.cs" />
|
<Compile Include="Movies\RenameMovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieResource.cs" />
|
<Compile Include="Movies\RenameMovieResource.cs" />
|
||||||
<Compile Include="Movies\MovieEditorModule.cs" />
|
<Compile Include="Movies\MovieEditorModule.cs" />
|
||||||
@@ -160,13 +161,6 @@
|
|||||||
<Compile Include="DiskSpace\DiskSpaceResource.cs" />
|
<Compile Include="DiskSpace\DiskSpaceResource.cs" />
|
||||||
<Compile Include="DownloadClient\DownloadClientModule.cs" />
|
<Compile Include="DownloadClient\DownloadClientModule.cs" />
|
||||||
<Compile Include="DownloadClient\DownloadClientResource.cs" />
|
<Compile Include="DownloadClient\DownloadClientResource.cs" />
|
||||||
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
|
|
||||||
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
|
|
||||||
<Compile Include="Episodes\EpisodeModule.cs" />
|
|
||||||
<Compile Include="Episodes\EpisodeModuleWithSignalR.cs" />
|
|
||||||
<Compile Include="Episodes\EpisodeResource.cs" />
|
|
||||||
<Compile Include="Episodes\RenameEpisodeModule.cs" />
|
|
||||||
<Compile Include="Episodes\RenameEpisodeResource.cs" />
|
|
||||||
<Compile Include="ErrorManagement\ApiException.cs" />
|
<Compile Include="ErrorManagement\ApiException.cs" />
|
||||||
<Compile Include="ErrorManagement\ErrorHandler.cs" />
|
<Compile Include="ErrorManagement\ErrorHandler.cs" />
|
||||||
<Compile Include="ErrorManagement\ErrorModel.cs" />
|
<Compile Include="ErrorManagement\ErrorModel.cs" />
|
||||||
@@ -242,19 +236,13 @@
|
|||||||
<Compile Include="REST\RestResource.cs" />
|
<Compile Include="REST\RestResource.cs" />
|
||||||
<Compile Include="RootFolders\RootFolderModule.cs" />
|
<Compile Include="RootFolders\RootFolderModule.cs" />
|
||||||
<Compile Include="RootFolders\RootFolderResource.cs" />
|
<Compile Include="RootFolders\RootFolderResource.cs" />
|
||||||
<Compile Include="SeasonPass\SeasonPassResource.cs" />
|
<Compile Include="Movies\AlternativeTitleResource.cs" />
|
||||||
<Compile Include="Series\AlternativeTitleResource.cs" />
|
<Compile Include="MovieFiles\MovieFileResource.cs" />
|
||||||
<Compile Include="Series\MovieFileResource.cs" />
|
<Compile Include="Movies\FetchMovieListModule.cs" />
|
||||||
<Compile Include="Series\FetchMovieListModule.cs" />
|
<Compile Include="Movies\MovieLookupModule.cs" />
|
||||||
<Compile Include="Series\SeasonResource.cs" />
|
|
||||||
<Compile Include="SeasonPass\SeasonPassModule.cs" />
|
|
||||||
<Compile Include="Series\SeriesEditorModule.cs" />
|
|
||||||
<Compile Include="Series\MovieLookupModule.cs" />
|
|
||||||
<Compile Include="Series\SeriesLookupModule.cs" />
|
|
||||||
<Compile Include="Series\SeriesModule.cs" />
|
<Compile Include="Series\SeriesModule.cs" />
|
||||||
<Compile Include="Series\MovieResource.cs" />
|
<Compile Include="Movies\MovieResource.cs" />
|
||||||
<Compile Include="Series\SeriesResource.cs" />
|
<Compile Include="Series\SeriesResource.cs" />
|
||||||
<Compile Include="Series\SeasonStatisticsResource.cs" />
|
|
||||||
<Compile Include="System\Backup\BackupModule.cs" />
|
<Compile Include="System\Backup\BackupModule.cs" />
|
||||||
<Compile Include="System\Backup\BackupResource.cs" />
|
<Compile Include="System\Backup\BackupResource.cs" />
|
||||||
<Compile Include="System\Tasks\TaskModule.cs" />
|
<Compile Include="System\Tasks\TaskModule.cs" />
|
||||||
@@ -269,12 +257,10 @@
|
|||||||
<Compile Include="Validation\RssSyncIntervalValidator.cs" />
|
<Compile Include="Validation\RssSyncIntervalValidator.cs" />
|
||||||
<Compile Include="Validation\EmptyCollectionValidator.cs" />
|
<Compile Include="Validation\EmptyCollectionValidator.cs" />
|
||||||
<Compile Include="Validation\RuleBuilderExtensions.cs" />
|
<Compile Include="Validation\RuleBuilderExtensions.cs" />
|
||||||
<Compile Include="Wanted\CutoffModule.cs" />
|
|
||||||
<Compile Include="Wanted\LegacyMissingModule.cs" />
|
<Compile Include="Wanted\LegacyMissingModule.cs" />
|
||||||
<Compile Include="Wanted\MissingModule.cs" />
|
|
||||||
<Compile Include="Wanted\MovieCutoffModule.cs" />
|
<Compile Include="Wanted\MovieCutoffModule.cs" />
|
||||||
<Compile Include="Wanted\MovieMissingModule.cs" />
|
<Compile Include="Wanted\MovieMissingModule.cs" />
|
||||||
<Compile Include="Series\MovieDiscoverModule.cs" />
|
<Compile Include="Movies\MovieDiscoverModule.cs" />
|
||||||
<Compile Include="NetImport\ImportExclusionsModule.cs" />
|
<Compile Include="NetImport\ImportExclusionsModule.cs" />
|
||||||
<Compile Include="NetImport\ImportExclusionsResource.cs" />
|
<Compile Include="NetImport\ImportExclusionsResource.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Parse
|
namespace NzbDrone.Api.Parse
|
||||||
@@ -18,23 +17,22 @@ namespace NzbDrone.Api.Parse
|
|||||||
private ParseResource Parse()
|
private ParseResource Parse()
|
||||||
{
|
{
|
||||||
var title = Request.Query.Title.Value as string;
|
var title = Request.Query.Title.Value as string;
|
||||||
var parsedEpisodeInfo = Parser.ParseTitle(title);
|
var parsedMovieInfo = Parser.ParseMovieTitle(title, false);
|
||||||
|
|
||||||
if (parsedEpisodeInfo == null)
|
if (parsedMovieInfo == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
|
var remoteMovie = _parsingService.Map(parsedMovieInfo, "");
|
||||||
|
|
||||||
if (remoteEpisode != null)
|
if (remoteMovie != null)
|
||||||
{
|
{
|
||||||
return new ParseResource
|
return new ParseResource
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
ParsedEpisodeInfo = remoteEpisode.ParsedEpisodeInfo,
|
ParsedMovieInfo = remoteMovie.RemoteMovie.ParsedMovieInfo,
|
||||||
Series = remoteEpisode.Series.ToResource(),
|
Movie = remoteMovie.Movie.ToResource()
|
||||||
Episodes = remoteEpisode.Episodes.ToResource()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -42,9 +40,9 @@ namespace NzbDrone.Api.Parse
|
|||||||
return new ParseResource
|
return new ParseResource
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
ParsedEpisodeInfo = parsedEpisodeInfo
|
ParsedMovieInfo = parsedMovieInfo
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Series;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Parse
|
namespace NzbDrone.Api.Parse
|
||||||
@@ -9,8 +8,7 @@ namespace NzbDrone.Api.Parse
|
|||||||
public class ParseResource : RestResource
|
public class ParseResource : RestResource
|
||||||
{
|
{
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; }
|
public ParsedMovieInfo ParsedMovieInfo { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
public MovieResource Movie { get; set; }
|
||||||
public List<EpisodeResource> Episodes { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Api.Episodes;
|
|
||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Core.Download.TrackedDownloads;
|
using NzbDrone.Core.Download.TrackedDownloads;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -13,8 +11,6 @@ namespace NzbDrone.Api.Queue
|
|||||||
{
|
{
|
||||||
public class QueueResource : RestResource
|
public class QueueResource : RestResource
|
||||||
{
|
{
|
||||||
public SeriesResource Series { get; set; }
|
|
||||||
public EpisodeResource Episode { get; set; }
|
|
||||||
public MovieResource Movie { get; set; }
|
public MovieResource Movie { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public decimal Size { get; set; }
|
public decimal Size { get; set; }
|
||||||
@@ -38,9 +34,6 @@ namespace NzbDrone.Api.Queue
|
|||||||
return new QueueResource
|
return new QueueResource
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.Id,
|
||||||
|
|
||||||
Series = model.Series.ToResource(),
|
|
||||||
Episode = model.Episode.ToResource(),
|
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
Size = model.Size,
|
Size = model.Size,
|
||||||
Title = model.Title,
|
Title = model.Title,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.RootFolders;
|
using NzbDrone.Core.RootFolders;
|
||||||
@@ -9,6 +9,7 @@ namespace NzbDrone.Api.RootFolders
|
|||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public long? FreeSpace { get; set; }
|
public long? FreeSpace { get; set; }
|
||||||
|
public long? TotalSpace { get; set; }
|
||||||
|
|
||||||
public List<UnmappedFolder> UnmappedFolders { get; set; }
|
public List<UnmappedFolder> UnmappedFolders { get; set; }
|
||||||
}
|
}
|
||||||
@@ -25,6 +26,7 @@ namespace NzbDrone.Api.RootFolders
|
|||||||
|
|
||||||
Path = model.Path,
|
Path = model.Path,
|
||||||
FreeSpace = model.FreeSpace,
|
FreeSpace = model.FreeSpace,
|
||||||
|
TotalSpace = model.TotalSpace,
|
||||||
UnmappedFolders = model.UnmappedFolders
|
UnmappedFolders = model.UnmappedFolders
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -48,4 +50,4 @@ namespace NzbDrone.Api.RootFolders
|
|||||||
return models.Select(ToResource).ToList();
|
return models.Select(ToResource).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
using Nancy;
|
|
||||||
using NzbDrone.Api.Extensions;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.SeasonPass
|
|
||||||
{
|
|
||||||
public class SeasonPassModule : NzbDroneApiModule
|
|
||||||
{
|
|
||||||
private readonly IEpisodeMonitoredService _episodeMonitoredService;
|
|
||||||
|
|
||||||
public SeasonPassModule(IEpisodeMonitoredService episodeMonitoredService)
|
|
||||||
: base("/seasonpass")
|
|
||||||
{
|
|
||||||
_episodeMonitoredService = episodeMonitoredService;
|
|
||||||
Post["/"] = series => UpdateAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response UpdateAll()
|
|
||||||
{
|
|
||||||
//Read from request
|
|
||||||
var request = Request.Body.FromJson<SeasonPassResource>();
|
|
||||||
|
|
||||||
foreach (var s in request.Series)
|
|
||||||
{
|
|
||||||
_episodeMonitoredService.SetEpisodeMonitoredStatus(s, request.MonitoringOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "ok".AsResponse(HttpStatusCode.Accepted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.SeasonPass
|
|
||||||
{
|
|
||||||
public class SeasonPassResource
|
|
||||||
{
|
|
||||||
public List<Core.Tv.Series> Series { get; set; }
|
|
||||||
public MonitoringOptions MonitoringOptions { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,298 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using FluentValidation;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Api.Extensions;
|
|
||||||
using NzbDrone.Core.Datastore.Events;
|
|
||||||
using NzbDrone.Core.MediaCover;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
using NzbDrone.Core.MovieStats;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.Tv.Events;
|
|
||||||
using NzbDrone.Core.Validation.Paths;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
|
||||||
using NzbDrone.Core.Validation;
|
|
||||||
using NzbDrone.SignalR;
|
|
||||||
using NzbDrone.Core.Datastore;
|
|
||||||
using Microsoft.CSharp.RuntimeBinder;
|
|
||||||
using Nancy;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
|
||||||
{
|
|
||||||
public class MovieModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
|
|
||||||
IHandle<EpisodeImportedEvent>,
|
|
||||||
IHandle<EpisodeFileDeletedEvent>,
|
|
||||||
IHandle<MovieUpdatedEvent>,
|
|
||||||
IHandle<MovieEditedEvent>,
|
|
||||||
IHandle<MovieDeletedEvent>,
|
|
||||||
IHandle<MovieRenamedEvent>,
|
|
||||||
IHandle<MediaCoversUpdatedEvent>
|
|
||||||
|
|
||||||
{
|
|
||||||
protected readonly IMovieService _moviesService;
|
|
||||||
private readonly IMovieStatisticsService _moviesStatisticsService;
|
|
||||||
private readonly IMapCoversToLocal _coverMapper;
|
|
||||||
|
|
||||||
private const string TITLE_SLUG_ROUTE = "/titleslug/(?<slug>[^/]+)";
|
|
||||||
|
|
||||||
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
|
||||||
IMovieService moviesService,
|
|
||||||
IMovieStatisticsService moviesStatisticsService,
|
|
||||||
ISceneMappingService sceneMappingService,
|
|
||||||
IMapCoversToLocal coverMapper,
|
|
||||||
RootFolderValidator rootFolderValidator,
|
|
||||||
MoviePathValidator moviesPathValidator,
|
|
||||||
MovieExistsValidator moviesExistsValidator,
|
|
||||||
DroneFactoryValidator droneFactoryValidator,
|
|
||||||
MovieAncestorValidator moviesAncestorValidator,
|
|
||||||
ProfileExistsValidator profileExistsValidator
|
|
||||||
)
|
|
||||||
: base(signalRBroadcaster)
|
|
||||||
{
|
|
||||||
_moviesService = moviesService;
|
|
||||||
_moviesStatisticsService = moviesStatisticsService;
|
|
||||||
|
|
||||||
_coverMapper = coverMapper;
|
|
||||||
|
|
||||||
GetResourceAll = AllMovie;
|
|
||||||
GetResourcePaged = GetMoviePaged;
|
|
||||||
GetResourceById = GetMovie;
|
|
||||||
Get[TITLE_SLUG_ROUTE] = GetByTitleSlug; /*(options) => {
|
|
||||||
return ReqResExtensions.AsResponse(GetByTitleSlug(options.slug), Nancy.HttpStatusCode.OK);
|
|
||||||
};*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CreateResource = AddMovie;
|
|
||||||
UpdateResource = UpdateMovie;
|
|
||||||
DeleteResource = DeleteMovie;
|
|
||||||
|
|
||||||
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
|
|
||||||
|
|
||||||
SharedValidator.RuleFor(s => s.Path)
|
|
||||||
.Cascade(CascadeMode.StopOnFirstFailure)
|
|
||||||
.IsValidPath()
|
|
||||||
.SetValidator(rootFolderValidator)
|
|
||||||
.SetValidator(moviesPathValidator)
|
|
||||||
.SetValidator(droneFactoryValidator)
|
|
||||||
.SetValidator(moviesAncestorValidator)
|
|
||||||
.When(s => !s.Path.IsNullOrWhiteSpace());
|
|
||||||
|
|
||||||
SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator);
|
|
||||||
|
|
||||||
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
|
||||||
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
|
||||||
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
|
||||||
PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
|
|
||||||
|
|
||||||
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
|
||||||
IMovieService moviesService,
|
|
||||||
IMovieStatisticsService moviesStatisticsService,
|
|
||||||
ISceneMappingService sceneMappingService,
|
|
||||||
IMapCoversToLocal coverMapper,
|
|
||||||
string resource)
|
|
||||||
: base(signalRBroadcaster, resource)
|
|
||||||
{
|
|
||||||
_moviesService = moviesService;
|
|
||||||
_moviesStatisticsService = moviesStatisticsService;
|
|
||||||
|
|
||||||
_coverMapper = coverMapper;
|
|
||||||
|
|
||||||
GetResourceAll = AllMovie;
|
|
||||||
GetResourceById = GetMovie;
|
|
||||||
CreateResource = AddMovie;
|
|
||||||
UpdateResource = UpdateMovie;
|
|
||||||
DeleteResource = DeleteMovie;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MovieResource GetMovie(int id)
|
|
||||||
{
|
|
||||||
var movies = _moviesService.GetMovie(id);
|
|
||||||
return MapToResource(movies);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PagingResource<MovieResource> GetMoviePaged(PagingResource<MovieResource> pagingResource)
|
|
||||||
{
|
|
||||||
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>();
|
|
||||||
|
|
||||||
pagingSpec.FilterExpression = _moviesService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue, pagingResource.FilterType);
|
|
||||||
|
|
||||||
return ApplyToPage(_moviesService.Paged, pagingSpec, MapToResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected MovieResource MapToResource(Core.Tv.Movie movies)
|
|
||||||
{
|
|
||||||
if (movies == null) return null;
|
|
||||||
|
|
||||||
var resource = movies.ToResource();
|
|
||||||
MapCoversToLocal(resource);
|
|
||||||
//FetchAndLinkMovieStatistics(resource);
|
|
||||||
//PopulateAlternateTitles(resource);
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<MovieResource> AllMovie()
|
|
||||||
{
|
|
||||||
var moviesStats = _moviesStatisticsService.MovieStatistics();
|
|
||||||
var moviesResources = _moviesService.GetAllMovies().ToResource();
|
|
||||||
|
|
||||||
MapCoversToLocal(moviesResources.ToArray());
|
|
||||||
LinkMovieStatistics(moviesResources, moviesStats);
|
|
||||||
PopulateAlternateTitles(moviesResources);
|
|
||||||
|
|
||||||
return moviesResources;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response GetByTitleSlug(dynamic options)
|
|
||||||
{
|
|
||||||
var slug = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
slug = options.slug;
|
|
||||||
// do stuff with x
|
|
||||||
}
|
|
||||||
catch (RuntimeBinderException)
|
|
||||||
{
|
|
||||||
return new NotFoundResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return MapToResource(_moviesService.FindByTitleSlug(slug)).AsResponse(Nancy.HttpStatusCode.OK);
|
|
||||||
}
|
|
||||||
catch (ModelNotFoundException)
|
|
||||||
{
|
|
||||||
return new NotFoundResponse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int AddMovie(MovieResource moviesResource)
|
|
||||||
{
|
|
||||||
var model = moviesResource.ToModel();
|
|
||||||
|
|
||||||
return _moviesService.AddMovie(model).Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateMovie(MovieResource moviesResource)
|
|
||||||
{
|
|
||||||
var model = moviesResource.ToModel(_moviesService.GetMovie(moviesResource.Id));
|
|
||||||
|
|
||||||
_moviesService.UpdateMovie(model);
|
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, moviesResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeleteMovie(int id)
|
|
||||||
{
|
|
||||||
var deleteFiles = false;
|
|
||||||
var addExclusion = false;
|
|
||||||
var deleteFilesQuery = Request.Query.deleteFiles;
|
|
||||||
var addExclusionQuery = Request.Query.addExclusion;
|
|
||||||
|
|
||||||
if (deleteFilesQuery.HasValue)
|
|
||||||
{
|
|
||||||
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
|
|
||||||
}
|
|
||||||
if (addExclusionQuery.HasValue)
|
|
||||||
{
|
|
||||||
addExclusion = Convert.ToBoolean(addExclusionQuery.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MapCoversToLocal(params MovieResource[] movies)
|
|
||||||
{
|
|
||||||
foreach (var moviesResource in movies)
|
|
||||||
{
|
|
||||||
_coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FetchAndLinkMovieStatistics(MovieResource resource)
|
|
||||||
{
|
|
||||||
LinkMovieStatistics(resource, _moviesStatisticsService.MovieStatistics(resource.Id));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LinkMovieStatistics(List<MovieResource> resources, List<MovieStatistics> moviesStatistics)
|
|
||||||
{
|
|
||||||
var dictMovieStats = moviesStatistics.ToDictionary(v => v.MovieId);
|
|
||||||
|
|
||||||
foreach (var movies in resources)
|
|
||||||
{
|
|
||||||
var stats = dictMovieStats.GetValueOrDefault(movies.Id);
|
|
||||||
if (stats == null) continue;
|
|
||||||
|
|
||||||
LinkMovieStatistics(movies, stats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
|
|
||||||
{
|
|
||||||
//resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PopulateAlternateTitles(List<MovieResource> resources)
|
|
||||||
{
|
|
||||||
foreach (var resource in resources)
|
|
||||||
{
|
|
||||||
PopulateAlternateTitles(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PopulateAlternateTitles(MovieResource resource)
|
|
||||||
{
|
|
||||||
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
|
|
||||||
|
|
||||||
//if (mappings == null) return;
|
|
||||||
|
|
||||||
//Not necessary anymore
|
|
||||||
|
|
||||||
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeImportedEvent message)
|
|
||||||
{
|
|
||||||
//BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.MovieId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeFileDeletedEvent message)
|
|
||||||
{
|
|
||||||
if (message.Reason == DeleteMediaFileReason.Upgrade) return;
|
|
||||||
|
|
||||||
//BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.MovieId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MovieUpdatedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MovieEditedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MovieDeletedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MovieRenamedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MediaCoversUpdatedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
namespace NzbDrone.Api.Series
|
|
||||||
{
|
|
||||||
public class SeasonResource
|
|
||||||
{
|
|
||||||
public int SeasonNumber { get; set; }
|
|
||||||
public bool Monitored { get; set; }
|
|
||||||
public SeasonStatisticsResource Statistics { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SeasonResourceMapper
|
|
||||||
{
|
|
||||||
public static SeasonResource ToResource(this Season model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new SeasonResource
|
|
||||||
{
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
Monitored = model.Monitored
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Season ToModel(this SeasonResource resource)
|
|
||||||
{
|
|
||||||
if (resource == null) return null;
|
|
||||||
|
|
||||||
return new Season
|
|
||||||
{
|
|
||||||
SeasonNumber = resource.SeasonNumber,
|
|
||||||
Monitored = resource.Monitored
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<SeasonResource> ToResource(this IEnumerable<Season> models)
|
|
||||||
{
|
|
||||||
return models.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Season> ToModel(this IEnumerable<SeasonResource> resources)
|
|
||||||
{
|
|
||||||
return resources.Select(ToModel).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
using System;
|
|
||||||
using NzbDrone.Core.SeriesStats;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Series
|
|
||||||
{
|
|
||||||
public class SeasonStatisticsResource
|
|
||||||
{
|
|
||||||
public DateTime? NextAiring { get; set; }
|
|
||||||
public DateTime? PreviousAiring { get; set; }
|
|
||||||
public int EpisodeFileCount { get; set; }
|
|
||||||
public int EpisodeCount { get; set; }
|
|
||||||
public int TotalEpisodeCount { get; set; }
|
|
||||||
public long SizeOnDisk { get; set; }
|
|
||||||
|
|
||||||
public decimal PercentOfEpisodes
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (EpisodeCount == 0) return 0;
|
|
||||||
|
|
||||||
return (decimal)EpisodeFileCount / (decimal)EpisodeCount * 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SeasonStatisticsResourceMapper
|
|
||||||
{
|
|
||||||
public static SeasonStatisticsResource ToResource(this SeasonStatistics model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new SeasonStatisticsResource
|
|
||||||
{
|
|
||||||
NextAiring = model.NextAiring,
|
|
||||||
PreviousAiring = model.PreviousAiring,
|
|
||||||
EpisodeFileCount = model.EpisodeFileCount,
|
|
||||||
EpisodeCount = model.EpisodeFileCount,
|
|
||||||
TotalEpisodeCount = model.TotalEpisodeCount,
|
|
||||||
SizeOnDisk = model.SizeOnDisk
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Nancy;
|
|
||||||
using NzbDrone.Api.Extensions;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Series
|
|
||||||
{
|
|
||||||
public class SeriesEditorModule : NzbDroneApiModule
|
|
||||||
{
|
|
||||||
private readonly ISeriesService _seriesService;
|
|
||||||
|
|
||||||
public SeriesEditorModule(ISeriesService seriesService)
|
|
||||||
: base("/series/editor")
|
|
||||||
{
|
|
||||||
_seriesService = seriesService;
|
|
||||||
Put["/"] = series => SaveAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response SaveAll()
|
|
||||||
{
|
|
||||||
var resources = Request.Body.FromJson<List<SeriesResource>>();
|
|
||||||
|
|
||||||
var series = resources.Select(seriesResource => seriesResource.ToModel(_seriesService.GetSeries(seriesResource.Id))).ToList();
|
|
||||||
|
|
||||||
return _seriesService.UpdateSeries(series)
|
|
||||||
.ToResource()
|
|
||||||
.AsResponse(HttpStatusCode.Accepted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Nancy;
|
|
||||||
using NzbDrone.Api.Extensions;
|
|
||||||
using NzbDrone.Core.MediaCover;
|
|
||||||
using NzbDrone.Core.MetadataSource;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Series
|
|
||||||
{
|
|
||||||
public class SeriesLookupModule : NzbDroneRestModule<SeriesResource>
|
|
||||||
{
|
|
||||||
private readonly ISearchForNewSeries _searchProxy;
|
|
||||||
|
|
||||||
public SeriesLookupModule(ISearchForNewSeries searchProxy)
|
|
||||||
: base("/series/lookup")
|
|
||||||
{
|
|
||||||
_searchProxy = searchProxy;
|
|
||||||
Get["/"] = x => Search();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Response Search()
|
|
||||||
{
|
|
||||||
var tvDbResults = _searchProxy.SearchForNewSeries((string)Request.Query.term);
|
|
||||||
return MapToResource(tvDbResults).AsResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static IEnumerable<SeriesResource> MapToResource(IEnumerable<Core.Tv.Series> series)
|
|
||||||
{
|
|
||||||
foreach (var currentSeries in series)
|
|
||||||
{
|
|
||||||
var resource = currentSeries.ToResource();
|
|
||||||
var poster = currentSeries.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster);
|
|
||||||
if (poster != null)
|
|
||||||
{
|
|
||||||
resource.RemotePoster = poster.Url;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return resource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,242 +1,47 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using FluentValidation;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Core.Datastore.Events;
|
|
||||||
using NzbDrone.Core.MediaCover;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
using NzbDrone.Core.SeriesStats;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.Tv.Events;
|
|
||||||
using NzbDrone.Core.Validation.Paths;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
|
||||||
using NzbDrone.Core.Validation;
|
|
||||||
using NzbDrone.SignalR;
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Series
|
namespace NzbDrone.Api.Series
|
||||||
{
|
{
|
||||||
public class SeriesModule : NzbDroneRestModuleWithSignalR<SeriesResource, Core.Tv.Series>,
|
[Obsolete("SeriesModule is Obsolete, Remove with new UI")]
|
||||||
IHandle<EpisodeImportedEvent>,
|
public class SeriesModule : NzbDroneRestModuleWithSignalR<SeriesResource, Core.Tv.Series>
|
||||||
IHandle<EpisodeFileDeletedEvent>,
|
|
||||||
IHandle<SeriesUpdatedEvent>,
|
|
||||||
IHandle<SeriesEditedEvent>,
|
|
||||||
IHandle<SeriesDeletedEvent>,
|
|
||||||
IHandle<SeriesRenamedEvent>,
|
|
||||||
IHandle<MediaCoversUpdatedEvent>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
private readonly ISeriesService _seriesService;
|
public SeriesModule(IBroadcastSignalRMessage signalRBroadcaster
|
||||||
private readonly ISeriesStatisticsService _seriesStatisticsService;
|
)
|
||||||
private readonly ISceneMappingService _sceneMappingService;
|
|
||||||
private readonly IMapCoversToLocal _coverMapper;
|
|
||||||
|
|
||||||
public SeriesModule(IBroadcastSignalRMessage signalRBroadcaster,
|
|
||||||
ISeriesService seriesService,
|
|
||||||
ISeriesStatisticsService seriesStatisticsService,
|
|
||||||
ISceneMappingService sceneMappingService,
|
|
||||||
IMapCoversToLocal coverMapper,
|
|
||||||
RootFolderValidator rootFolderValidator,
|
|
||||||
SeriesPathValidator seriesPathValidator,
|
|
||||||
SeriesExistsValidator seriesExistsValidator,
|
|
||||||
DroneFactoryValidator droneFactoryValidator,
|
|
||||||
SeriesAncestorValidator seriesAncestorValidator,
|
|
||||||
ProfileExistsValidator profileExistsValidator
|
|
||||||
)
|
|
||||||
: base(signalRBroadcaster)
|
: base(signalRBroadcaster)
|
||||||
{
|
{
|
||||||
_seriesService = seriesService;
|
|
||||||
_seriesStatisticsService = seriesStatisticsService;
|
|
||||||
_sceneMappingService = sceneMappingService;
|
|
||||||
|
|
||||||
_coverMapper = coverMapper;
|
|
||||||
|
|
||||||
GetResourceAll = AllSeries;
|
GetResourceAll = AllSeries;
|
||||||
GetResourceById = GetSeries;
|
GetResourceById = GetSeries;
|
||||||
CreateResource = AddSeries;
|
CreateResource = AddSeries;
|
||||||
UpdateResource = UpdateSeries;
|
UpdateResource = UpdateSeries;
|
||||||
DeleteResource = DeleteSeries;
|
DeleteResource = DeleteSeries;
|
||||||
|
|
||||||
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
|
|
||||||
|
|
||||||
SharedValidator.RuleFor(s => s.Path)
|
|
||||||
.Cascade(CascadeMode.StopOnFirstFailure)
|
|
||||||
.IsValidPath()
|
|
||||||
.SetValidator(rootFolderValidator)
|
|
||||||
.SetValidator(seriesPathValidator)
|
|
||||||
.SetValidator(droneFactoryValidator)
|
|
||||||
.SetValidator(seriesAncestorValidator)
|
|
||||||
.When(s => !s.Path.IsNullOrWhiteSpace());
|
|
||||||
|
|
||||||
SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator);
|
|
||||||
|
|
||||||
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
|
||||||
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
|
||||||
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
|
||||||
PostValidator.RuleFor(s => s.TvdbId).GreaterThan(0).SetValidator(seriesExistsValidator);
|
|
||||||
|
|
||||||
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SeriesResource GetSeries(int id)
|
private SeriesResource GetSeries(int id)
|
||||||
{
|
{
|
||||||
var series = _seriesService.GetSeries(id);
|
return new SeriesResource();
|
||||||
return MapToResource(series);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SeriesResource MapToResource(Core.Tv.Series series)
|
|
||||||
{
|
|
||||||
if (series == null) return null;
|
|
||||||
|
|
||||||
var resource = series.ToResource();
|
|
||||||
MapCoversToLocal(resource);
|
|
||||||
FetchAndLinkSeriesStatistics(resource);
|
|
||||||
PopulateAlternateTitles(resource);
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SeriesResource> AllSeries()
|
private List<SeriesResource> AllSeries()
|
||||||
{
|
{
|
||||||
var seriesStats = _seriesStatisticsService.SeriesStatistics();
|
return new List<SeriesResource>();
|
||||||
var seriesResources = _seriesService.GetAllSeries().ToResource();
|
|
||||||
|
|
||||||
MapCoversToLocal(seriesResources.ToArray());
|
|
||||||
LinkSeriesStatistics(seriesResources, seriesStats);
|
|
||||||
PopulateAlternateTitles(seriesResources);
|
|
||||||
|
|
||||||
return seriesResources;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int AddSeries(SeriesResource seriesResource)
|
private int AddSeries(SeriesResource seriesResource)
|
||||||
{
|
{
|
||||||
var model = seriesResource.ToModel();
|
return 0;
|
||||||
|
|
||||||
return _seriesService.AddSeries(model).Id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSeries(SeriesResource seriesResource)
|
private void UpdateSeries(SeriesResource seriesResource)
|
||||||
{
|
{
|
||||||
var model = seriesResource.ToModel(_seriesService.GetSeries(seriesResource.Id));
|
throw new NotImplementedException();
|
||||||
|
|
||||||
_seriesService.UpdateSeries(model);
|
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, seriesResource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteSeries(int id)
|
private void DeleteSeries(int id)
|
||||||
{
|
{
|
||||||
var deleteFiles = false;
|
throw new NotImplementedException();
|
||||||
var deleteFilesQuery = Request.Query.deleteFiles;
|
|
||||||
|
|
||||||
if (deleteFilesQuery.HasValue)
|
|
||||||
{
|
|
||||||
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
_seriesService.DeleteSeries(id, deleteFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MapCoversToLocal(params SeriesResource[] series)
|
|
||||||
{
|
|
||||||
foreach (var seriesResource in series)
|
|
||||||
{
|
|
||||||
_coverMapper.ConvertToLocalUrls(seriesResource.Id, seriesResource.Images);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FetchAndLinkSeriesStatistics(SeriesResource resource)
|
|
||||||
{
|
|
||||||
LinkSeriesStatistics(resource, _seriesStatisticsService.SeriesStatistics(resource.Id));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LinkSeriesStatistics(List<SeriesResource> resources, List<SeriesStatistics> seriesStatistics)
|
|
||||||
{
|
|
||||||
var dictSeriesStats = seriesStatistics.ToDictionary(v => v.SeriesId);
|
|
||||||
|
|
||||||
foreach (var series in resources)
|
|
||||||
{
|
|
||||||
var stats = dictSeriesStats.GetValueOrDefault(series.Id);
|
|
||||||
if (stats == null) continue;
|
|
||||||
|
|
||||||
LinkSeriesStatistics(series, stats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LinkSeriesStatistics(SeriesResource resource, SeriesStatistics seriesStatistics)
|
|
||||||
{
|
|
||||||
resource.TotalEpisodeCount = seriesStatistics.TotalEpisodeCount;
|
|
||||||
resource.EpisodeCount = seriesStatistics.EpisodeCount;
|
|
||||||
resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount;
|
|
||||||
resource.NextAiring = seriesStatistics.NextAiring;
|
|
||||||
resource.PreviousAiring = seriesStatistics.PreviousAiring;
|
|
||||||
resource.SizeOnDisk = seriesStatistics.SizeOnDisk;
|
|
||||||
|
|
||||||
if (seriesStatistics.SeasonStatistics != null)
|
|
||||||
{
|
|
||||||
var dictSeasonStats = seriesStatistics.SeasonStatistics.ToDictionary(v => v.SeasonNumber);
|
|
||||||
|
|
||||||
foreach (var season in resource.Seasons)
|
|
||||||
{
|
|
||||||
season.Statistics = SeasonStatisticsResourceMapper.ToResource(dictSeasonStats.GetValueOrDefault(season.SeasonNumber));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PopulateAlternateTitles(List<SeriesResource> resources)
|
|
||||||
{
|
|
||||||
foreach (var resource in resources)
|
|
||||||
{
|
|
||||||
PopulateAlternateTitles(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PopulateAlternateTitles(SeriesResource resource)
|
|
||||||
{
|
|
||||||
var mappings = _sceneMappingService.FindByTvdbId(resource.TvdbId);
|
|
||||||
|
|
||||||
if (mappings == null) return;
|
|
||||||
|
|
||||||
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeImportedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.SeriesId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeFileDeletedEvent message)
|
|
||||||
{
|
|
||||||
if (message.Reason == DeleteMediaFileReason.Upgrade) return;
|
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.SeriesId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(SeriesUpdatedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(SeriesEditedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(SeriesDeletedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Deleted, message.Series.ToResource());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(SeriesRenamedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MediaCoversUpdatedEvent message)
|
|
||||||
{
|
|
||||||
//BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,232 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.MediaCover;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Series
|
namespace NzbDrone.Api.Series
|
||||||
{
|
{
|
||||||
|
[Obsolete("SeriesResource is Obsolete, Remove with new UI")]
|
||||||
public class SeriesResource : RestResource
|
public class SeriesResource : RestResource
|
||||||
{
|
{
|
||||||
public SeriesResource()
|
public SeriesResource()
|
||||||
{
|
{
|
||||||
Monitored = true;
|
Title = "Series Endpoint Obsolete";
|
||||||
}
|
}
|
||||||
|
|
||||||
//Todo: Sorters should be done completely on the client
|
|
||||||
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
|
|
||||||
//Todo: We should get the entire Profile instead of ID and Name separately
|
|
||||||
|
|
||||||
//View Only
|
//View Only
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
//public List<AlternativeTitleResource> AlternateTitles { get; set; }
|
|
||||||
public string SortTitle { get; set; }
|
|
||||||
|
|
||||||
public int SeasonCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (Seasons == null) return 0;
|
|
||||||
|
|
||||||
return Seasons.Where(s => s.SeasonNumber > 0).Count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int? TotalEpisodeCount { get; set; }
|
|
||||||
public int? EpisodeCount { get; set; }
|
|
||||||
public int? EpisodeFileCount { get; set; }
|
|
||||||
public long? SizeOnDisk { get; set; }
|
|
||||||
public SeriesStatusType Status { get; set; }
|
|
||||||
public string Overview { get; set; }
|
|
||||||
public DateTime? NextAiring { get; set; }
|
|
||||||
public DateTime? PreviousAiring { get; set; }
|
|
||||||
public string Network { get; set; }
|
|
||||||
public string AirTime { get; set; }
|
|
||||||
public List<MediaCover> Images { get; set; }
|
|
||||||
|
|
||||||
public string RemotePoster { get; set; }
|
|
||||||
public List<SeasonResource> Seasons { get; set; }
|
|
||||||
public int Year { get; set; }
|
|
||||||
|
|
||||||
//View & Edit
|
|
||||||
public string Path { get; set; }
|
|
||||||
public int ProfileId { get; set; }
|
|
||||||
|
|
||||||
//Editing Only
|
|
||||||
public bool SeasonFolder { get; set; }
|
|
||||||
public bool Monitored { get; set; }
|
|
||||||
|
|
||||||
public bool UseSceneNumbering { get; set; }
|
|
||||||
public int Runtime { get; set; }
|
|
||||||
public int TvdbId { get; set; }
|
|
||||||
public int TvRageId { get; set; }
|
|
||||||
public int TvMazeId { get; set; }
|
|
||||||
public DateTime? FirstAired { get; set; }
|
|
||||||
public DateTime? LastInfoSync { get; set; }
|
|
||||||
public SeriesTypes SeriesType { get; set; }
|
|
||||||
public string CleanTitle { get; set; }
|
|
||||||
public string ImdbId { get; set; }
|
|
||||||
public string TitleSlug { get; set; }
|
|
||||||
public string RootFolderPath { get; set; }
|
|
||||||
public string Certification { get; set; }
|
|
||||||
public List<string> Genres { get; set; }
|
|
||||||
public HashSet<int> Tags { get; set; }
|
|
||||||
public DateTime Added { get; set; }
|
|
||||||
public AddSeriesOptions AddOptions { get; set; }
|
|
||||||
public Ratings Ratings { get; set; }
|
|
||||||
|
|
||||||
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
|
||||||
|
|
||||||
//Used to support legacy consumers
|
|
||||||
public int QualityProfileId
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ProfileId;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value > 0 && ProfileId == 0)
|
|
||||||
{
|
|
||||||
ProfileId = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SeriesResourceMapper
|
|
||||||
{
|
|
||||||
public static SeriesResource ToResource(this Core.Tv.Series model)
|
|
||||||
{
|
|
||||||
if (model == null) return null;
|
|
||||||
|
|
||||||
return new SeriesResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
Title = model.Title,
|
|
||||||
//AlternateTitles
|
|
||||||
SortTitle = model.SortTitle,
|
|
||||||
|
|
||||||
//TotalEpisodeCount
|
|
||||||
//EpisodeCount
|
|
||||||
//EpisodeFileCount
|
|
||||||
//SizeOnDisk
|
|
||||||
Status = model.Status,
|
|
||||||
Overview = model.Overview,
|
|
||||||
//NextAiring
|
|
||||||
//PreviousAiring
|
|
||||||
Network = model.Network,
|
|
||||||
AirTime = model.AirTime,
|
|
||||||
Images = model.Images,
|
|
||||||
|
|
||||||
Seasons = model.Seasons.ToResource(),
|
|
||||||
Year = model.Year,
|
|
||||||
|
|
||||||
Path = model.Path,
|
|
||||||
ProfileId = model.ProfileId,
|
|
||||||
|
|
||||||
SeasonFolder = model.SeasonFolder,
|
|
||||||
Monitored = model.Monitored,
|
|
||||||
|
|
||||||
UseSceneNumbering = model.UseSceneNumbering,
|
|
||||||
Runtime = model.Runtime,
|
|
||||||
TvdbId = model.TvdbId,
|
|
||||||
TvRageId = model.TvRageId,
|
|
||||||
TvMazeId = model.TvMazeId,
|
|
||||||
FirstAired = model.FirstAired,
|
|
||||||
LastInfoSync = model.LastInfoSync,
|
|
||||||
SeriesType = model.SeriesType,
|
|
||||||
CleanTitle = model.CleanTitle,
|
|
||||||
ImdbId = model.ImdbId,
|
|
||||||
TitleSlug = model.TitleSlug,
|
|
||||||
RootFolderPath = model.RootFolderPath,
|
|
||||||
Certification = model.Certification,
|
|
||||||
Genres = model.Genres,
|
|
||||||
Tags = model.Tags,
|
|
||||||
Added = model.Added,
|
|
||||||
AddOptions = model.AddOptions,
|
|
||||||
Ratings = model.Ratings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Core.Tv.Series ToModel(this SeriesResource resource)
|
|
||||||
{
|
|
||||||
if (resource == null) return null;
|
|
||||||
|
|
||||||
return new Core.Tv.Series
|
|
||||||
{
|
|
||||||
Id = resource.Id,
|
|
||||||
|
|
||||||
Title = resource.Title,
|
|
||||||
//AlternateTitles
|
|
||||||
SortTitle = resource.SortTitle,
|
|
||||||
|
|
||||||
//TotalEpisodeCount
|
|
||||||
//EpisodeCount
|
|
||||||
//EpisodeFileCount
|
|
||||||
//SizeOnDisk
|
|
||||||
Status = resource.Status,
|
|
||||||
Overview = resource.Overview,
|
|
||||||
//NextAiring
|
|
||||||
//PreviousAiring
|
|
||||||
Network = resource.Network,
|
|
||||||
AirTime = resource.AirTime,
|
|
||||||
Images = resource.Images,
|
|
||||||
|
|
||||||
Seasons = resource.Seasons.ToModel(),
|
|
||||||
Year = resource.Year,
|
|
||||||
|
|
||||||
Path = resource.Path,
|
|
||||||
ProfileId = resource.ProfileId,
|
|
||||||
|
|
||||||
SeasonFolder = resource.SeasonFolder,
|
|
||||||
Monitored = resource.Monitored,
|
|
||||||
|
|
||||||
UseSceneNumbering = resource.UseSceneNumbering,
|
|
||||||
Runtime = resource.Runtime,
|
|
||||||
TvdbId = resource.TvdbId,
|
|
||||||
TvRageId = resource.TvRageId,
|
|
||||||
TvMazeId = resource.TvMazeId,
|
|
||||||
FirstAired = resource.FirstAired,
|
|
||||||
LastInfoSync = resource.LastInfoSync,
|
|
||||||
SeriesType = resource.SeriesType,
|
|
||||||
CleanTitle = resource.CleanTitle,
|
|
||||||
ImdbId = resource.ImdbId,
|
|
||||||
TitleSlug = resource.TitleSlug,
|
|
||||||
RootFolderPath = resource.RootFolderPath,
|
|
||||||
Certification = resource.Certification,
|
|
||||||
Genres = resource.Genres,
|
|
||||||
Tags = resource.Tags,
|
|
||||||
Added = resource.Added,
|
|
||||||
AddOptions = resource.AddOptions,
|
|
||||||
Ratings = resource.Ratings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Core.Tv.Series ToModel(this SeriesResource resource, Core.Tv.Series series)
|
|
||||||
{
|
|
||||||
series.TvdbId = resource.TvdbId;
|
|
||||||
|
|
||||||
series.Seasons = resource.Seasons.ToModel();
|
|
||||||
series.Path = resource.Path;
|
|
||||||
series.ProfileId = resource.ProfileId;
|
|
||||||
|
|
||||||
series.SeasonFolder = resource.SeasonFolder;
|
|
||||||
series.Monitored = resource.Monitored;
|
|
||||||
|
|
||||||
series.SeriesType = resource.SeriesType;
|
|
||||||
series.RootFolderPath = resource.RootFolderPath;
|
|
||||||
series.Tags = resource.Tags;
|
|
||||||
series.AddOptions = resource.AddOptions;
|
|
||||||
|
|
||||||
return series;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<SeriesResource> ToResource(this IEnumerable<Core.Tv.Series> series)
|
|
||||||
{
|
|
||||||
return series.Select(ToResource).ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ namespace NzbDrone.Api.System.Backup
|
|||||||
|
|
||||||
return backups.Select(b => new BackupResource
|
return backups.Select(b => new BackupResource
|
||||||
{
|
{
|
||||||
Id = b.Path.GetHashCode(),
|
Id = b.Name.GetHashCode(),
|
||||||
Name = Path.GetFileName(b.Path),
|
Name = b.Name,
|
||||||
Path = b.Path,
|
Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}",
|
||||||
Type = b.Type,
|
Type = b.Type,
|
||||||
Time = b.Time
|
Time = b.Time
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
using NzbDrone.Api.Episodes;
|
|
||||||
using NzbDrone.Core.Datastore;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.SignalR;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Wanted
|
|
||||||
{
|
|
||||||
public class CutoffModule : EpisodeModuleWithSignalR
|
|
||||||
{
|
|
||||||
private readonly IEpisodeCutoffService _episodeCutoffService;
|
|
||||||
|
|
||||||
public CutoffModule(IEpisodeCutoffService episodeCutoffService,
|
|
||||||
IEpisodeService episodeService,
|
|
||||||
ISeriesService seriesService,
|
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
|
||||||
IBroadcastSignalRMessage signalRBroadcaster)
|
|
||||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff-old")
|
|
||||||
{
|
|
||||||
_episodeCutoffService = episodeCutoffService;
|
|
||||||
GetResourcePaged = GetCutoffUnmetEpisodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PagingResource<EpisodeResource> GetCutoffUnmetEpisodes(PagingResource<EpisodeResource> pagingResource)
|
|
||||||
{
|
|
||||||
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>("airDateUtc", SortDirection.Descending);
|
|
||||||
|
|
||||||
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
|
|
||||||
{
|
|
||||||
pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resource = ApplyToPage(_episodeCutoffService.EpisodesWhereCutoffUnmet, pagingSpec, v => MapToResource(v, true, true));
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
using NzbDrone.Api.Episodes;
|
|
||||||
using NzbDrone.Core.Datastore;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.SignalR;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Wanted
|
|
||||||
{
|
|
||||||
public class MissingModule : EpisodeModuleWithSignalR
|
|
||||||
{
|
|
||||||
public MissingModule(IEpisodeService episodeService,
|
|
||||||
ISeriesService seriesService,
|
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
|
||||||
IBroadcastSignalRMessage signalRBroadcaster)
|
|
||||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing_episodes")
|
|
||||||
{
|
|
||||||
GetResourcePaged = GetMissingEpisodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PagingResource<EpisodeResource> GetMissingEpisodes(PagingResource<EpisodeResource> pagingResource)
|
|
||||||
{
|
|
||||||
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>("airDateUtc", SortDirection.Descending);
|
|
||||||
|
|
||||||
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
|
|
||||||
{
|
|
||||||
pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resource = ApplyToPage(_episodeService.EpisodesWithoutFiles, pagingSpec, v => MapToResource(v, true, false));
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Api.Movies;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
@@ -32,4 +31,4 @@ namespace NzbDrone.Api.Wanted
|
|||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using NzbDrone.Api.Movie;
|
|
||||||
using NzbDrone.Api.Movies;
|
using NzbDrone.Api.Movies;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
<package id="Nancy.Authentication.Basic" version="1.4.1" targetFramework="net40" />
|
<package id="Nancy.Authentication.Basic" version="1.4.1" targetFramework="net40" />
|
||||||
<package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net40" />
|
<package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -49,9 +49,8 @@
|
|||||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
||||||
<package id="Moq" version="4.0.10827" />
|
<package id="Moq" version="4.0.10827" />
|
||||||
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
|
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -46,9 +46,8 @@
|
|||||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||||
<package id="Selenium.Support" version="3.0.1" targetFramework="net40" />
|
<package id="Selenium.Support" version="3.0.1" targetFramework="net40" />
|
||||||
<package id="Selenium.WebDriver" version="3.0.1" targetFramework="net40" />
|
<package id="Selenium.WebDriver" version="3.0.1" targetFramework="net40" />
|
||||||
|
|||||||
@@ -45,9 +45,8 @@
|
|||||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
||||||
<package id="Moq" version="4.0.10827" />
|
<package id="Moq" version="4.0.10827" />
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -245,6 +245,25 @@ namespace NzbDrone.Common.Disk
|
|||||||
File.Move(source, destination);
|
File.Move(source, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void MoveFolder(string source, string destination, bool overwrite = false)
|
||||||
|
{
|
||||||
|
Ensure.That(source, () => source).IsValidPath();
|
||||||
|
Ensure.That(destination, () => destination).IsValidPath();
|
||||||
|
|
||||||
|
if (source.PathEquals(destination))
|
||||||
|
{
|
||||||
|
throw new IOException(string.Format("Source and destination can't be the same {0}", source));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FolderExists(destination) && overwrite)
|
||||||
|
{
|
||||||
|
DeleteFolder(destination, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveReadOnlyFolder(source);
|
||||||
|
Directory.Move(source, destination);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract bool TryCreateHardLink(string source, string destination);
|
public abstract bool TryCreateHardLink(string source, string destination);
|
||||||
|
|
||||||
public void DeleteFolder(string path, bool recursive)
|
public void DeleteFolder(string path, bool recursive)
|
||||||
@@ -371,6 +390,20 @@ namespace NzbDrone.Common.Disk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void RemoveReadOnlyFolder(string path)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(path))
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(path);
|
||||||
|
|
||||||
|
if (dirInfo.Attributes.HasFlag(FileAttributes.ReadOnly))
|
||||||
|
{
|
||||||
|
var newAttributes = dirInfo.Attributes & ~(FileAttributes.ReadOnly);
|
||||||
|
dirInfo.Attributes = newAttributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public FileAttributes GetFileAttributes(string path)
|
public FileAttributes GetFileAttributes(string path)
|
||||||
{
|
{
|
||||||
return File.GetAttributes(path);
|
return File.GetAttributes(path);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace NzbDrone.Common.Disk
|
|||||||
void DeleteFile(string path);
|
void DeleteFile(string path);
|
||||||
void CopyFile(string source, string destination, bool overwrite = false);
|
void CopyFile(string source, string destination, bool overwrite = false);
|
||||||
void MoveFile(string source, string destination, bool overwrite = false);
|
void MoveFile(string source, string destination, bool overwrite = false);
|
||||||
|
void MoveFolder(string source, string destination, bool overwrite = false);
|
||||||
bool TryCreateHardLink(string source, string destination);
|
bool TryCreateHardLink(string source, string destination);
|
||||||
void DeleteFolder(string path, bool recursive);
|
void DeleteFolder(string path, bool recursive);
|
||||||
string ReadAllText(string filePath);
|
string ReadAllText(string filePath);
|
||||||
|
|||||||
@@ -43,9 +43,8 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Org.Mentalis, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Org.Mentalis, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\DotNet4.SocksProxy.1.3.2.0\lib\net40\Org.Mentalis.dll</HintPath>
|
<HintPath>..\packages\DotNet4.SocksProxy.1.3.2.0\lib\net40\Org.Mentalis.dll</HintPath>
|
||||||
@@ -259,4 +258,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
@@ -98,9 +98,9 @@ namespace NzbDrone.Common.Processes
|
|||||||
var process = new Process
|
var process = new Process
|
||||||
{
|
{
|
||||||
StartInfo = new ProcessStartInfo(url)
|
StartInfo = new ProcessStartInfo(url)
|
||||||
{
|
{
|
||||||
UseShellExecute = true
|
UseShellExecute = true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
process.Start();
|
process.Start();
|
||||||
@@ -129,16 +129,34 @@ namespace NzbDrone.Common.Processes
|
|||||||
{
|
{
|
||||||
foreach (DictionaryEntry environmentVariable in environmentVariables)
|
foreach (DictionaryEntry environmentVariable in environmentVariables)
|
||||||
{
|
{
|
||||||
startInfo.EnvironmentVariables.Add(environmentVariable.Key.ToString(), environmentVariable.Value.ToString());
|
try
|
||||||
|
{
|
||||||
|
_logger.Trace("Setting environment variable '{0}' to '{1}'", environmentVariable.Key, environmentVariable.Value);
|
||||||
|
startInfo.EnvironmentVariables.Add(environmentVariable.Key.ToString(), environmentVariable.Value.ToString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (environmentVariable.Value == null)
|
||||||
|
{
|
||||||
|
_logger.Error(e, "Unable to set environment variable '{0}', value is null", environmentVariable.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Error(e, "Unable to set environment variable '{0}'", environmentVariable.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug("Starting {0} {1}", path, args);
|
logger.Debug("Starting {0} {1}", path, args);
|
||||||
|
|
||||||
var process = new Process
|
var process = new Process
|
||||||
{
|
{
|
||||||
StartInfo = startInfo
|
StartInfo = startInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
process.OutputDataReceived += (sender, eventArgs) =>
|
process.OutputDataReceived += (sender, eventArgs) =>
|
||||||
{
|
{
|
||||||
@@ -315,7 +333,7 @@ namespace NzbDrone.Common.Processes
|
|||||||
|
|
||||||
var monoProcesses = Process.GetProcessesByName("mono")
|
var monoProcesses = Process.GetProcessesByName("mono")
|
||||||
.Union(Process.GetProcessesByName("mono-sgen"))
|
.Union(Process.GetProcessesByName("mono-sgen"))
|
||||||
.Union(Process.GetProcessesByName("mono-sgen32"))
|
.Union(Process.GetProcessesByName("mono-sgen32"))
|
||||||
.Where(process =>
|
.Where(process =>
|
||||||
process.Modules.Cast<ProcessModule>()
|
process.Modules.Cast<ProcessModule>()
|
||||||
.Any(module =>
|
.Any(module =>
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
<package id="DotNet4.SocksProxy" version="1.3.2.0" targetFramework="net40" />
|
<package id="DotNet4.SocksProxy" version="1.3.2.0" targetFramework="net40" />
|
||||||
<package id="ICSharpCode.SharpZipLib.Patched" version="0.86.5" targetFramework="net40" />
|
<package id="ICSharpCode.SharpZipLib.Patched" version="0.86.5" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -75,9 +75,8 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
<package id="Microsoft.Owin" version="2.1.0" targetFramework="net40" />
|
<package id="Microsoft.Owin" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="Microsoft.Owin.Hosting" version="2.1.0" targetFramework="net40" />
|
<package id="Microsoft.Owin.Hosting" version="2.1.0" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
<package id="Owin" version="1.0" targetFramework="net40" />
|
<package id="Owin" version="1.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -340,7 +340,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
|||||||
|
|
||||||
result.IsLocalhost.Should().BeTrue();
|
result.IsLocalhost.Should().BeTrue();
|
||||||
result.OutputRootFolders.Should().NotBeNull();
|
result.OutputRootFolders.Should().NotBeNull();
|
||||||
result.OutputRootFolders.First().Should().Be(@"/remote/mount/tv");
|
result.OutputRootFolders.First().Should().Be(@"/remote/mount/movie");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -544,7 +544,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
|||||||
public void should_test_failed_if_tv_sorting_contains_category()
|
public void should_test_failed_if_tv_sorting_contains_category()
|
||||||
{
|
{
|
||||||
_config.Misc.enable_tv_sorting = true;
|
_config.Misc.enable_tv_sorting = true;
|
||||||
_config.Misc.tv_categories = new[] { "tv" };
|
_config.Misc.tv_categories = new[] { "movie" };
|
||||||
|
|
||||||
var result = new NzbDroneValidationResult(Subject.Test());
|
var result = new NzbDroneValidationResult(Subject.Test());
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -328,7 +328,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
|||||||
|
|
||||||
result.IsLocalhost.Should().BeTrue();
|
result.IsLocalhost.Should().BeTrue();
|
||||||
result.OutputRootFolders.Should().NotBeNull();
|
result.OutputRootFolders.Should().NotBeNull();
|
||||||
result.OutputRootFolders.First().Should().Be(@"C:\Downloads\Finished\utorrent\tv".AsOsAgnostic());
|
result.OutputRootFolders.First().Should().Be(@"C:\Downloads\Finished\utorrent\movie".AsOsAgnostic());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -20,27 +20,27 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
public class DeleteBadMediaCoversFixture : CoreTest<DeleteBadMediaCovers>
|
public class DeleteBadMediaCoversFixture : CoreTest<DeleteBadMediaCovers>
|
||||||
{
|
{
|
||||||
private List<MetadataFile> _metadata;
|
private List<MetadataFile> _metadata;
|
||||||
private List<Series> _series;
|
private List<Movie> _movies;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Series>.CreateListOfSize(1)
|
_movies = Builder<Movie>.CreateListOfSize(1)
|
||||||
.All()
|
.All()
|
||||||
.With(c => c.Path = "C:\\TV\\".AsOsAgnostic())
|
.With(c => c.Path = "C:\\Movie\\".AsOsAgnostic())
|
||||||
.Build().ToList();
|
.Build().ToList();
|
||||||
|
|
||||||
|
|
||||||
_metadata = Builder<MetadataFile>.CreateListOfSize(1)
|
_metadata = Builder<MetadataFile>.CreateListOfSize(1)
|
||||||
.Build().ToList();
|
.Build().ToList();
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<IMovieService>()
|
||||||
.Setup(c => c.GetAllSeries())
|
.Setup(c => c.GetAllMovies())
|
||||||
.Returns(_series);
|
.Returns(_movies);
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IMetadataFileService>()
|
Mocker.GetMock<IMetadataFileService>()
|
||||||
.Setup(c => c.GetFilesBySeries(_series.First().Id))
|
.Setup(c => c.GetFilesByMovie(_movies.First().Id))
|
||||||
.Returns(_metadata);
|
.Returns(_metadata);
|
||||||
|
|
||||||
|
|
||||||
@@ -51,8 +51,8 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_not_process_non_image_files()
|
public void should_not_process_non_image_files()
|
||||||
{
|
{
|
||||||
_metadata.First().RelativePath = "season\\file.xml".AsOsAgnostic();
|
_metadata.First().RelativePath = "extrafiles\\file.xml".AsOsAgnostic();
|
||||||
_metadata.First().Type = MetadataType.EpisodeMetadata;
|
_metadata.First().Type = MetadataType.MovieMetadata;
|
||||||
|
|
||||||
Subject.Clean();
|
Subject.Clean();
|
||||||
|
|
||||||
@@ -101,10 +101,10 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
public void should_delete_html_images()
|
public void should_delete_html_images()
|
||||||
{
|
{
|
||||||
|
|
||||||
var imagePath = "C:\\TV\\Season\\image.jpg".AsOsAgnostic();
|
var imagePath = "C:\\Movie\\image.jpg".AsOsAgnostic();
|
||||||
_metadata.First().LastUpdated = new DateTime(2014, 12, 29);
|
_metadata.First().LastUpdated = new DateTime(2014, 12, 29);
|
||||||
_metadata.First().RelativePath = "Season\\image.jpg".AsOsAgnostic();
|
_metadata.First().RelativePath = "image.jpg".AsOsAgnostic();
|
||||||
_metadata.First().Type = MetadataType.SeriesImage;
|
_metadata.First().Type = MetadataType.MovieImage;
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(c => c.OpenReadStream(imagePath))
|
.Setup(c => c.OpenReadStream(imagePath))
|
||||||
@@ -123,10 +123,10 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
public void should_delete_empty_images()
|
public void should_delete_empty_images()
|
||||||
{
|
{
|
||||||
|
|
||||||
var imagePath = "C:\\TV\\Season\\image.jpg".AsOsAgnostic();
|
var imagePath = "C:\\Movie\\image.jpg".AsOsAgnostic();
|
||||||
_metadata.First().LastUpdated = new DateTime(2014, 12, 29);
|
_metadata.First().LastUpdated = new DateTime(2014, 12, 29);
|
||||||
_metadata.First().Type = MetadataType.SeasonImage;
|
_metadata.First().Type = MetadataType.MovieImage;
|
||||||
_metadata.First().RelativePath = "Season\\image.jpg".AsOsAgnostic();
|
_metadata.First().RelativePath = "image.jpg".AsOsAgnostic();
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(c => c.OpenReadStream(imagePath))
|
.Setup(c => c.OpenReadStream(imagePath))
|
||||||
@@ -144,9 +144,9 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
public void should_not_delete_non_html_files()
|
public void should_not_delete_non_html_files()
|
||||||
{
|
{
|
||||||
|
|
||||||
var imagePath = "C:\\TV\\Season\\image.jpg".AsOsAgnostic();
|
var imagePath = "C:\\Movie\\image.jpg".AsOsAgnostic();
|
||||||
_metadata.First().LastUpdated = new DateTime(2014, 12, 29);
|
_metadata.First().LastUpdated = new DateTime(2014, 12, 29);
|
||||||
_metadata.First().RelativePath = "Season\\image.jpg".AsOsAgnostic();
|
_metadata.First().RelativePath = "image.jpg".AsOsAgnostic();
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(c => c.OpenReadStream(imagePath))
|
.Setup(c => c.OpenReadStream(imagePath))
|
||||||
|
|||||||
+25
-40
@@ -1,4 +1,4 @@
|
|||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Extras.Metadata;
|
using NzbDrone.Core.Extras.Metadata;
|
||||||
@@ -12,12 +12,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
public class CleanupDuplicateMetadataFilesFixture : DbTest<CleanupDuplicateMetadataFiles, MetadataFile>
|
public class CleanupDuplicateMetadataFilesFixture : DbTest<CleanupDuplicateMetadataFiles, MetadataFile>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_when_they_are_for_the_same_series_but_different_consumers()
|
public void should_not_delete_metadata_files_when_they_are_for_the_same_movie_but_different_consumers()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.SeriesMetadata)
|
.With(m => m.Type = MetadataType.MovieMetadata)
|
||||||
.With(m => m.SeriesId = 1)
|
.With(m => m.MovieId = 1)
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
Db.InsertMany(files);
|
Db.InsertMany(files);
|
||||||
@@ -26,11 +26,11 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_for_different_series()
|
public void should_not_delete_metadata_files_for_different_movie()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.SeriesMetadata)
|
.With(m => m.Type = MetadataType.MovieMetadata)
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
.With(m => m.Consumer = "XbmcMetadata")
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
@@ -40,12 +40,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_metadata_files_when_they_are_for_the_same_series_and_consumer()
|
public void should_delete_metadata_files_when_they_are_for_the_same_movie_and_consumer()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.SeriesMetadata)
|
.With(m => m.Type = MetadataType.MovieMetadata)
|
||||||
.With(m => m.SeriesId = 1)
|
.With(m => m.MovieId = 1)
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
.With(m => m.Consumer = "XbmcMetadata")
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_when_there_is_only_one_for_that_series_and_consumer()
|
public void should_not_delete_metadata_files_when_there_is_only_one_for_that_movie_and_consumer()
|
||||||
{
|
{
|
||||||
var file = Builder<MetadataFile>.CreateNew()
|
var file = Builder<MetadataFile>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
@@ -66,12 +66,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_when_they_are_for_the_same_episode_but_different_consumers()
|
public void should_not_delete_metadata_files_when_they_are_for_the_same_movie_file_but_different_consumers()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.EpisodeMetadata)
|
.With(m => m.Type = MetadataType.MovieMetadata)
|
||||||
.With(m => m.EpisodeFileId = 1)
|
.With(m => m.MovieFileId = 1)
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
Db.InsertMany(files);
|
Db.InsertMany(files);
|
||||||
@@ -80,11 +80,11 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_for_different_episode()
|
public void should_not_delete_metadata_files_for_different_movie_file()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.EpisodeMetadata)
|
.With(m => m.Type = MetadataType.MovieMetadata)
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
.With(m => m.Consumer = "XbmcMetadata")
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
@@ -94,12 +94,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_metadata_files_when_they_are_for_the_same_episode_and_consumer()
|
public void should_delete_metadata_files_when_they_are_for_the_same_movie_file_and_consumer()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.EpisodeMetadata)
|
.With(m => m.Type = MetadataType.MovieMetadata)
|
||||||
.With(m => m.EpisodeFileId = 1)
|
.With(m => m.MovieFileId = 1)
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
.With(m => m.Consumer = "XbmcMetadata")
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_when_there_is_only_one_for_that_episode_and_consumer()
|
public void should_not_delete_metadata_files_when_there_is_only_one_for_that_movie_file_and_consumer()
|
||||||
{
|
{
|
||||||
var file = Builder<MetadataFile>.CreateNew()
|
var file = Builder<MetadataFile>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
@@ -120,12 +120,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_image_when_they_are_for_the_same_episode_but_different_consumers()
|
public void should_not_delete_image_when_they_are_for_the_same_movie_file_but_different_consumers()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.EpisodeImage)
|
.With(m => m.Type = MetadataType.MovieImage)
|
||||||
.With(m => m.EpisodeFileId = 1)
|
.With(m => m.MovieFileId = 1)
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
Db.InsertMany(files);
|
Db.InsertMany(files);
|
||||||
@@ -134,11 +134,11 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_image_for_different_episode()
|
public void should_not_delete_image_for_different_movie_file()
|
||||||
{
|
{
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(m => m.Type = MetadataType.EpisodeImage)
|
.With(m => m.Type = MetadataType.MovieImage)
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
.With(m => m.Consumer = "XbmcMetadata")
|
||||||
.BuildListOfNew();
|
.BuildListOfNew();
|
||||||
|
|
||||||
@@ -148,22 +148,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_image_when_they_are_for_the_same_episode_and_consumer()
|
public void should_not_delete_image_when_there_is_only_one_for_that_movie_file_and_consumer()
|
||||||
{
|
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
|
||||||
.All()
|
|
||||||
.With(m => m.Type = MetadataType.EpisodeImage)
|
|
||||||
.With(m => m.EpisodeFileId = 1)
|
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
|
||||||
.BuildListOfNew();
|
|
||||||
|
|
||||||
Db.InsertMany(files);
|
|
||||||
Subject.Clean();
|
|
||||||
AllStoredModels.Count.Should().Be(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_delete_image_when_there_is_only_one_for_that_episode_and_consumer()
|
|
||||||
{
|
{
|
||||||
var file = Builder<MetadataFile>.CreateNew()
|
var file = Builder<MetadataFile>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|||||||
+32
-32
@@ -1,4 +1,4 @@
|
|||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Extras.Metadata;
|
using NzbDrone.Core.Extras.Metadata;
|
||||||
@@ -15,10 +15,10 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
public class CleanupOrphanedMetadataFilesFixture : DbTest<CleanupOrphanedMetadataFiles, MetadataFile>
|
public class CleanupOrphanedMetadataFilesFixture : DbTest<CleanupOrphanedMetadataFiles, MetadataFile>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_metadata_files_that_dont_have_a_coresponding_series()
|
public void should_delete_metadata_files_that_dont_have_a_coresponding_movie()
|
||||||
{
|
{
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
.With(m => m.EpisodeFileId = null)
|
.With(m => m.MovieFileId = null)
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(metadataFile);
|
Db.Insert(metadataFile);
|
||||||
@@ -27,16 +27,16 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_that_have_a_coresponding_series()
|
public void should_not_delete_metadata_files_that_have_a_coresponding_movie()
|
||||||
{
|
{
|
||||||
var series = Builder<Series>.CreateNew()
|
var movie = Builder<Movie>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(series);
|
Db.Insert(movie);
|
||||||
|
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
.With(m => m.SeriesId = series.Id)
|
.With(m => m.MovieId = movie.Id)
|
||||||
.With(m => m.EpisodeFileId = null)
|
.With(m => m.MovieFileId = null)
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(metadataFile);
|
Db.Insert(metadataFile);
|
||||||
@@ -45,16 +45,16 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_metadata_files_that_dont_have_a_coresponding_episode_file()
|
public void should_delete_metadata_files_that_dont_have_a_coresponding_movie_file()
|
||||||
{
|
{
|
||||||
var series = Builder<Series>.CreateNew()
|
var movie = Builder<Movie>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(series);
|
Db.Insert(movie);
|
||||||
|
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
.With(m => m.SeriesId = series.Id)
|
.With(m => m.MovieId = movie.Id)
|
||||||
.With(m => m.EpisodeFileId = 10)
|
.With(m => m.MovieFileId = 10)
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(metadataFile);
|
Db.Insert(metadataFile);
|
||||||
@@ -63,21 +63,21 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_that_have_a_coresponding_episode_file()
|
public void should_not_delete_metadata_files_that_have_a_coresponding_movie_file()
|
||||||
{
|
{
|
||||||
var series = Builder<Series>.CreateNew()
|
var movie = Builder<Movie>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
var movieFile = Builder<MovieFile>.CreateNew()
|
||||||
.With(h => h.Quality = new QualityModel())
|
.With(h => h.Quality = new QualityModel())
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(series);
|
Db.Insert(movie);
|
||||||
Db.Insert(episodeFile);
|
Db.Insert(movieFile);
|
||||||
|
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
.With(m => m.SeriesId = series.Id)
|
.With(m => m.MovieId = movie.Id)
|
||||||
.With(m => m.EpisodeFileId = episodeFile.Id)
|
.With(m => m.MovieFileId = movieFile.Id)
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(metadataFile);
|
Db.Insert(metadataFile);
|
||||||
@@ -86,17 +86,17 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_episode_metadata_files_that_have_episodefileid_of_zero()
|
public void should_delete_movie_metadata_files_that_have_moviefileid_of_zero()
|
||||||
{
|
{
|
||||||
var series = Builder<Series>.CreateNew()
|
var movie = Builder<Movie>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(series);
|
Db.Insert(movie);
|
||||||
|
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
.With(m => m.SeriesId = series.Id)
|
.With(m => m.MovieId = movie.Id)
|
||||||
.With(m => m.Type = MetadataType.EpisodeMetadata)
|
.With(m => m.Type = MetadataType.MovieMetadata)
|
||||||
.With(m => m.EpisodeFileId = 0)
|
.With(m => m.MovieFileId = 0)
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(metadataFile);
|
Db.Insert(metadataFile);
|
||||||
@@ -105,17 +105,17 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_episode_image_files_that_have_episodefileid_of_zero()
|
public void should_delete_movie_image_files_that_have_moviefileid_of_zero()
|
||||||
{
|
{
|
||||||
var series = Builder<Series>.CreateNew()
|
var movie = Builder<Movie>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(series);
|
Db.Insert(movie);
|
||||||
|
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
.With(m => m.SeriesId = series.Id)
|
.With(m => m.MovieId = movie.Id)
|
||||||
.With(m => m.Type = MetadataType.EpisodeImage)
|
.With(m => m.Type = MetadataType.MovieImage)
|
||||||
.With(m => m.EpisodeFileId = 0)
|
.With(m => m.MovieFileId = 0)
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(metadataFile);
|
Db.Insert(metadataFile);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
|
|||||||
Subject.ConvertToLocalUrls(12, covers);
|
Subject.ConvertToLocalUrls(12, covers);
|
||||||
|
|
||||||
|
|
||||||
covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg?lastWrite=1234");
|
covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using NzbDrone.Core.Test.Framework;
|
|||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MediaFiles
|
namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
@@ -77,7 +78,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Verify(c => c.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<ParsedMovieInfo>(), It.IsAny<bool>()),
|
.Verify(c => c.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), It.IsAny<ParsedMovieInfo>(), It.IsAny<bool>()),
|
||||||
Times.Never());
|
Times.Never());
|
||||||
|
|
||||||
VerifyNoImport();
|
VerifyNoImport();
|
||||||
@@ -128,7 +129,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
imported.Add(new ImportDecision(localMovie));
|
imported.Add(new ImportDecision(localMovie));
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
|
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedMovie>()
|
Mocker.GetMock<IImportApprovedMovie>()
|
||||||
@@ -154,7 +155,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
imported.Add(new ImportDecision(localMovie));
|
imported.Add(new ImportDecision(localMovie));
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
|
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedMovie>()
|
Mocker.GetMock<IImportApprovedMovie>()
|
||||||
@@ -226,7 +227,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
imported.Add(new ImportDecision(localMovie));
|
imported.Add(new ImportDecision(localMovie));
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
|
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedMovie>()
|
Mocker.GetMock<IImportApprovedMovie>()
|
||||||
@@ -280,7 +281,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
Subject.ProcessPath(fileName);
|
Subject.ProcessPath(fileName);
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<ParsedMovieInfo>(), true, false), Times.Once());
|
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), It.IsAny<ParsedMovieInfo>(), true, false), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -304,7 +305,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
var result = Subject.ProcessPath(fileName);
|
var result = Subject.ProcessPath(fileName);
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true, false), Times.Once());
|
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true, false), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -337,7 +338,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
imported.Add(new ImportDecision(localMovie));
|
imported.Add(new ImportDecision(localMovie));
|
||||||
|
|
||||||
Mocker.GetMock<IMakeImportDecision>()
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
|
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
|
|||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Marr.Data;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class SameFileSpecificationFixture : CoreTest<SameFileSpecification>
|
||||||
|
{
|
||||||
|
private LocalMovie _localMovie;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_localMovie = Builder<LocalMovie>.CreateNew()
|
||||||
|
.With(l => l.Size = 150.Megabytes())
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_accepted_if_no_existing_file()
|
||||||
|
{
|
||||||
|
_localMovie.Movie = Builder<Movie>.CreateNew()
|
||||||
|
.With(e => e.MovieFileId = 0)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_accepted_if_file_size_is_different()
|
||||||
|
{
|
||||||
|
_localMovie.Movie = Builder<Movie>.CreateNew()
|
||||||
|
.With(e => e.MovieFileId = 1)
|
||||||
|
.With(e => e.MovieFile = new LazyLoaded<MovieFile>(
|
||||||
|
new MovieFile
|
||||||
|
{
|
||||||
|
Size = _localMovie.Size + 100.Megabytes()
|
||||||
|
}))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_reject_if_file_size_is_the_same()
|
||||||
|
{
|
||||||
|
_localMovie.Movie = Builder<Movie>.CreateNew()
|
||||||
|
.With(e => e.MovieFileId = 1)
|
||||||
|
.With(e => e.MovieFile = new LazyLoaded<MovieFile>(
|
||||||
|
new MovieFile
|
||||||
|
{
|
||||||
|
Size = _localMovie.Size
|
||||||
|
}))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@@ -13,66 +13,56 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Roksbox
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FindMetadataFileFixture : CoreTest<RoksboxMetadata>
|
public class FindMetadataFileFixture : CoreTest<RoksboxMetadata>
|
||||||
{
|
{
|
||||||
private Series _series;
|
private Movie _movie;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Series>.CreateNew()
|
_movie = Builder<Movie>.CreateNew()
|
||||||
.With(s => s.Path = @"C:\Test\TV\The.Series".AsOsAgnostic())
|
.With(s => s.Path = @"C:\Test\Movies\The.Movie.2011".AsOsAgnostic())
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_null_if_filename_is_not_handled()
|
public void should_return_null_if_filename_is_not_handled()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "file.jpg");
|
var path = Path.Combine(_movie.Path, "file.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_movie, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Specials")]
|
[TestCase(".xml", MetadataType.MovieMetadata)]
|
||||||
[TestCase("specials")]
|
[TestCase(".jpg", MetadataType.MovieImage)]
|
||||||
[TestCase("Season 1")]
|
public void should_return_metadata_for_movie_if_valid_file_for_movie(string extension, MetadataType type)
|
||||||
public void should_return_season_image(string folder)
|
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, folder, folder + ".jpg");
|
var path = Path.Combine(_movie.Path, "the.movie.2011" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeasonImage);
|
Subject.FindMetadataFile(_movie, path).Type.Should().Be(type);
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(".xml", MetadataType.EpisodeMetadata)]
|
|
||||||
[TestCase(".jpg", MetadataType.EpisodeImage)]
|
|
||||||
public void should_return_metadata_for_episode_if_valid_file_for_episode(string extension, MetadataType type)
|
|
||||||
{
|
|
||||||
var path = Path.Combine(_series.Path, "the.series.s01e01.episode" + extension);
|
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(".xml")]
|
[TestCase(".xml")]
|
||||||
[TestCase(".jpg")]
|
[TestCase(".jpg")]
|
||||||
public void should_return_null_if_not_valid_file_for_episode(string extension)
|
public void should_return_null_if_not_valid_file_for_movie(string extension)
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "the.series.episode" + extension);
|
var path = Path.Combine(_movie.Path, "the.movie.here" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_movie, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_return_metadata_if_image_file_is_a_thumb()
|
public void should_not_return_metadata_if_image_file_is_a_thumb()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "the.series.s01e01.episode-thumb.jpg");
|
var path = Path.Combine(_movie.Path, "the.movie.2011-thumb.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_movie, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_series_image_for_folder_jpg_in_series_folder()
|
public void should_return_movie_image_for_folder_jpg_in_movie_folder()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, new DirectoryInfo(_series.Path).Name + ".jpg");
|
var path = Path.Combine(_movie.Path, new DirectoryInfo(_movie.Path).Name + ".jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeriesImage);
|
Subject.FindMetadataFile(_movie, path).Type.Should().Be(MetadataType.MovieImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@@ -13,58 +13,48 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Wdtv
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FindMetadataFileFixture : CoreTest<WdtvMetadata>
|
public class FindMetadataFileFixture : CoreTest<WdtvMetadata>
|
||||||
{
|
{
|
||||||
private Series _series;
|
private Movie _movie;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Series>.CreateNew()
|
_movie = Builder<Movie>.CreateNew()
|
||||||
.With(s => s.Path = @"C:\Test\TV\The.Series".AsOsAgnostic())
|
.With(s => s.Path = @"C:\Test\Movies\The.Movie".AsOsAgnostic())
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_null_if_filename_is_not_handled()
|
public void should_return_null_if_filename_is_not_handled()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "file.jpg");
|
var path = Path.Combine(_movie.Path, "file.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_movie, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Specials")]
|
[TestCase(".xml", MetadataType.MovieMetadata)]
|
||||||
[TestCase("specials")]
|
[TestCase(".metathumb", MetadataType.MovieImage)]
|
||||||
[TestCase("Season 1")]
|
public void should_return_metadata_for_movie_if_valid_file_for_movie(string extension, MetadataType type)
|
||||||
public void should_return_season_image(string folder)
|
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, folder, "folder.jpg");
|
var path = Path.Combine(_movie.Path, "the.movie.2011" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeasonImage);
|
Subject.FindMetadataFile(_movie, path).Type.Should().Be(type);
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(".xml", MetadataType.EpisodeMetadata)]
|
|
||||||
[TestCase(".metathumb", MetadataType.EpisodeImage)]
|
|
||||||
public void should_return_metadata_for_episode_if_valid_file_for_episode(string extension, MetadataType type)
|
|
||||||
{
|
|
||||||
var path = Path.Combine(_series.Path, "the.series.s01e01.episode" + extension);
|
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(".xml")]
|
[TestCase(".xml")]
|
||||||
[TestCase(".metathumb")]
|
[TestCase(".metathumb")]
|
||||||
public void should_return_null_if_not_valid_file_for_episode(string extension)
|
public void should_return_null_if_not_valid_file_for_movie(string extension)
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "the.series.episode" + extension);
|
var path = Path.Combine(_movie.Path, "the.movie" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_movie, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_series_image_for_folder_jpg_in_series_folder()
|
public void should_return_movie_image_for_folder_jpg_in_movie_folder()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "folder.jpg");
|
var path = Path.Combine(_movie.Path, "folder.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeriesImage);
|
Subject.FindMetadataFile(_movie, path).Type.Should().Be(MetadataType.MovieImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ namespace NzbDrone.Core.Test.NetImport
|
|||||||
|
|
||||||
var result = Subject.Fetch();
|
var result = Subject.Fetch();
|
||||||
|
|
||||||
result.First().Title.Should().Be("Think Like a Man Too");
|
result.Movies.First().Title.Should().Be("Think Like a Man Too");
|
||||||
result.First().ImdbId.Should().Be("tt2239832");
|
result.Movies.First().ImdbId.Should().Be("tt2239832");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,9 +84,8 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c">
|
||||||
<HintPath>..\packages\NLog.4.3.11\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||||
@@ -283,6 +282,7 @@
|
|||||||
<Compile Include="MediaFiles\EpisodeImport\Specifications\MatchesFolderSpecificationFixture.cs" />
|
<Compile Include="MediaFiles\EpisodeImport\Specifications\MatchesFolderSpecificationFixture.cs" />
|
||||||
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotSampleSpecificationFixture.cs" />
|
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotSampleSpecificationFixture.cs" />
|
||||||
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotUnpackingSpecificationFixture.cs" />
|
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotUnpackingSpecificationFixture.cs" />
|
||||||
|
<Compile Include="MediaFiles\EpisodeImport\Specifications\SameFileSpecificationFixture.cs" />
|
||||||
<Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecificationFixture.cs" />
|
<Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecificationFixture.cs" />
|
||||||
<Compile Include="MediaFiles\ImportApprovedEpisodesFixture.cs" />
|
<Compile Include="MediaFiles\ImportApprovedEpisodesFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileRepositoryFixture.cs" />
|
<Compile Include="MediaFiles\MediaFileRepositoryFixture.cs" />
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
|
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
|
||||||
<package id="NCrunch.Framework" version="1.46.0.9" targetFramework="net40" />
|
<package id="NCrunch.Framework" version="1.46.0.9" targetFramework="net40" />
|
||||||
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="6.0.6" targetFramework="net40" />
|
||||||
<package id="NLog" version="4.3.11" targetFramework="net40" />
|
<package id="NLog" version="4.4.12" targetFramework="net40" />
|
||||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||||
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
|
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
|
||||||
<package id="Unity" version="2.1.505.2" targetFramework="net40" />
|
<package id="Unity" version="2.1.505.2" targetFramework="net40" />
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace NzbDrone.Core.Backup
|
|||||||
{
|
{
|
||||||
public class Backup
|
public class Backup
|
||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Name { get; set; }
|
||||||
public BackupType Type { get; set; }
|
public BackupType Type { get; set; }
|
||||||
public DateTime Time { get; set; }
|
public DateTime Time { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,18 @@ namespace NzbDrone.Core.Backup
|
|||||||
{
|
{
|
||||||
public class BackupCommand : Command
|
public class BackupCommand : Command
|
||||||
{
|
{
|
||||||
public BackupType Type { get; set; }
|
public BackupType Type
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Trigger == CommandTrigger.Scheduled)
|
||||||
|
{
|
||||||
|
return BackupType.Scheduled;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BackupType.Manual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override bool SendUpdatesToClient => true;
|
public override bool SendUpdatesToClient => true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Data.SQLite;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -25,6 +26,7 @@ namespace NzbDrone.Core.Backup
|
|||||||
public class BackupService : IBackupService, IExecute<BackupCommand>
|
public class BackupService : IBackupService, IExecute<BackupCommand>
|
||||||
{
|
{
|
||||||
private readonly IMainDatabase _maindDb;
|
private readonly IMainDatabase _maindDb;
|
||||||
|
private readonly IMakeDatabaseBackup _makeDatabaseBackup;
|
||||||
private readonly IDiskTransferService _diskTransferService;
|
private readonly IDiskTransferService _diskTransferService;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
@@ -36,6 +38,7 @@ namespace NzbDrone.Core.Backup
|
|||||||
private static readonly Regex BackupFileRegex = new Regex(@"radarr_backup_[._0-9]+\.zip", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex BackupFileRegex = new Regex(@"radarr_backup_[._0-9]+\.zip", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
public BackupService(IMainDatabase maindDb,
|
public BackupService(IMainDatabase maindDb,
|
||||||
|
IMakeDatabaseBackup makeDatabaseBackup,
|
||||||
IDiskTransferService diskTransferService,
|
IDiskTransferService diskTransferService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IAppFolderInfo appFolderInfo,
|
IAppFolderInfo appFolderInfo,
|
||||||
@@ -43,6 +46,7 @@ namespace NzbDrone.Core.Backup
|
|||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_maindDb = maindDb;
|
_maindDb = maindDb;
|
||||||
|
_makeDatabaseBackup = makeDatabaseBackup;
|
||||||
_diskTransferService = diskTransferService;
|
_diskTransferService = diskTransferService;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_appFolderInfo = appFolderInfo;
|
_appFolderInfo = appFolderInfo;
|
||||||
@@ -68,7 +72,7 @@ namespace NzbDrone.Core.Backup
|
|||||||
{
|
{
|
||||||
CleanupOldBackups(backupType);
|
CleanupOldBackups(backupType);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackupConfigFile();
|
BackupConfigFile();
|
||||||
BackupDatabase();
|
BackupDatabase();
|
||||||
|
|
||||||
@@ -89,7 +93,7 @@ namespace NzbDrone.Core.Backup
|
|||||||
{
|
{
|
||||||
backups.AddRange(GetBackupFiles(folder).Select(b => new Backup
|
backups.AddRange(GetBackupFiles(folder).Select(b => new Backup
|
||||||
{
|
{
|
||||||
Path = Path.GetFileName(b),
|
Name = Path.GetFileName(b),
|
||||||
Type = backupType,
|
Type = backupType,
|
||||||
Time = _diskProvider.FileGetLastWrite(b)
|
Time = _diskProvider.FileGetLastWrite(b)
|
||||||
}));
|
}));
|
||||||
@@ -111,17 +115,7 @@ namespace NzbDrone.Core.Backup
|
|||||||
{
|
{
|
||||||
_logger.ProgressDebug("Backing up database");
|
_logger.ProgressDebug("Backing up database");
|
||||||
|
|
||||||
using (var unitOfWork = new UnitOfWork(() => _maindDb.GetDataMapper()))
|
_makeDatabaseBackup.BackupDatabase(_maindDb, _backupTempFolder);
|
||||||
{
|
|
||||||
unitOfWork.BeginTransaction(IsolationLevel.Serializable);
|
|
||||||
|
|
||||||
var databaseFile = _appFolderInfo.GetNzbDroneDatabase();
|
|
||||||
var tempDatabaseFile = Path.Combine(_backupTempFolder, Path.GetFileName(databaseFile));
|
|
||||||
|
|
||||||
_diskTransferService.TransferFile(databaseFile, tempDatabaseFile, TransferMode.Copy);
|
|
||||||
|
|
||||||
unitOfWork.Commit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BackupConfigFile()
|
private void BackupConfigFile()
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user