Compare commits
522 Commits
v0.2.0.196
...
v0.2.0.654
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ca66fb61a | ||
|
|
064844ac0c | ||
|
|
5540594ecf | ||
|
|
433ae019de | ||
|
|
10091b9454 | ||
|
|
475851775f | ||
|
|
0fff862fd2 | ||
|
|
23754c49dc | ||
|
|
fbf790e9fd | ||
|
|
6d00bd0f7a | ||
|
|
5bf95e0d9e | ||
|
|
8bb4b02be7 | ||
|
|
b26a036eed | ||
|
|
ef57882291 | ||
|
|
32a2407ad1 | ||
|
|
33b48eec95 | ||
|
|
3790dc9109 | ||
|
|
343d849536 | ||
|
|
c36b259fa9 | ||
|
|
6463913f22 | ||
|
|
e39deb4bdc | ||
|
|
9ca2c21547 | ||
|
|
f376360611 | ||
|
|
3e966d4d58 | ||
|
|
e036267c33 | ||
|
|
7d4378ca7a | ||
|
|
ee1ebfd893 | ||
|
|
403fd0f0c0 | ||
|
|
fc5ac8219f | ||
|
|
600a433faa | ||
|
|
5609facd9d | ||
|
|
36ea6c6b99 | ||
|
|
56ac87c760 | ||
|
|
47753c47a5 | ||
|
|
712c0eb84a | ||
|
|
8765155223 | ||
|
|
63d7596e98 | ||
|
|
640edf0cce | ||
|
|
280445e756 | ||
|
|
bae8d5e9a4 | ||
|
|
07254adf91 | ||
|
|
d33ec334f3 | ||
|
|
a80e9f11f2 | ||
|
|
4a0ef984fb | ||
|
|
685012280b | ||
|
|
6963078669 | ||
|
|
7182081fca | ||
|
|
87ee360818 | ||
|
|
ad222570be | ||
|
|
680681c8bd | ||
|
|
e2ae7536ad | ||
|
|
98c117a460 | ||
|
|
c54f8806b3 | ||
|
|
454d5c37f9 | ||
|
|
e9f084fd81 | ||
|
|
d1bbcdc039 | ||
|
|
c17deb7d92 | ||
|
|
7066b078ab | ||
|
|
b4bb8875d3 | ||
|
|
cb596488f2 | ||
|
|
3403ddf993 | ||
|
|
17118cf24d | ||
|
|
27ab70333c | ||
|
|
f4031f1e5f | ||
|
|
a9154559b8 | ||
|
|
0f2f2e4b32 | ||
|
|
6deefbb997 | ||
|
|
43a71da0a7 | ||
|
|
499e46e10a | ||
|
|
3f013271c9 | ||
|
|
529591bc18 | ||
|
|
79307d3c25 | ||
|
|
8f79563cf0 | ||
|
|
0dc67419be | ||
|
|
066c746e5f | ||
|
|
31fcac5bd9 | ||
|
|
1b29b89bf1 | ||
|
|
c593f4250d | ||
|
|
59c07cc5f3 | ||
|
|
2b1023e768 | ||
|
|
f10af08f95 | ||
|
|
18fcda5fd6 | ||
|
|
1ccfde334f | ||
|
|
421a191650 | ||
|
|
35e046bb87 | ||
|
|
8ece7e8b4d | ||
|
|
fadc5f0099 | ||
|
|
680430737d | ||
|
|
5d3750a295 | ||
|
|
e525f23281 | ||
|
|
2e41763b92 | ||
|
|
5b70ecaee0 | ||
|
|
06ad30397b | ||
|
|
f2218006a1 | ||
|
|
e26fd22540 | ||
|
|
05a83e4e95 | ||
|
|
3b3fe197ca | ||
|
|
149c5292f1 | ||
|
|
3cf5301e46 | ||
|
|
4b1f7da317 | ||
|
|
a25c056def | ||
|
|
0db27d9029 | ||
|
|
e6dfd89300 | ||
|
|
db6e91cd95 | ||
|
|
1bae7bb623 | ||
|
|
7cf2a8cb62 | ||
|
|
1a4fb6e7bb | ||
|
|
ae0fc019e5 | ||
|
|
3f438563b8 | ||
|
|
51e0cdf982 | ||
|
|
3d9fd3ff25 | ||
|
|
866cec096d | ||
|
|
71eaa98518 | ||
|
|
2899bbf330 | ||
|
|
72f40470a7 | ||
|
|
7c5c4e7594 | ||
|
|
77f369caab | ||
|
|
571730ddec | ||
|
|
5c22d0b61d | ||
|
|
fe0a54685f | ||
|
|
2d951bf378 | ||
|
|
54df46df8c | ||
|
|
b9eab860f5 | ||
|
|
24a394bf46 | ||
|
|
af2b5c2f1c | ||
|
|
961a6d89a4 | ||
|
|
b81d8c4678 | ||
|
|
73f0916fa0 | ||
|
|
6c10d77721 | ||
|
|
d9a3f303e7 | ||
|
|
1894d493f3 | ||
|
|
88140dd3aa | ||
|
|
fb1d13bc58 | ||
|
|
b71031f6d3 | ||
|
|
d03f4a515e | ||
|
|
0668f12e62 | ||
|
|
0083e95019 | ||
|
|
c7fcfe04be | ||
|
|
e11455c964 | ||
|
|
4d0226e0d5 | ||
|
|
7cfa0531dc | ||
|
|
5bd008f468 | ||
|
|
f36db9f77b | ||
|
|
4640519438 | ||
|
|
597a070383 | ||
|
|
07d3b1b3a5 | ||
|
|
665832f0cc | ||
|
|
0d60375a56 | ||
|
|
d4eeb666e0 | ||
|
|
593fa4239f | ||
|
|
3c1b5385ba | ||
|
|
ea22f5db79 | ||
|
|
e32bb6dbbf | ||
|
|
f897591d32 | ||
|
|
cf8f690d7a | ||
|
|
e3dc31cca5 | ||
|
|
ddc6ccbf15 | ||
|
|
18773bc665 | ||
|
|
91c71ed6a0 | ||
|
|
f3b5d9a1d6 | ||
|
|
83deba1c99 | ||
|
|
9787cf6cdd | ||
|
|
7433e89467 | ||
|
|
0aa6066a6f | ||
|
|
3dd14c72c8 | ||
|
|
0d85c7435c | ||
|
|
a3c0f4cb3f | ||
|
|
3f2da1441f | ||
|
|
f49d68ad6a | ||
|
|
f138d4f677 | ||
|
|
aa977eb2d5 | ||
|
|
e0f72e4853 | ||
|
|
83560ad937 | ||
|
|
5cace1d857 | ||
|
|
39322cbbca | ||
|
|
46daa11c46 | ||
|
|
98e2bd00ab | ||
|
|
0f2234bcdc | ||
|
|
3f05ef810e | ||
|
|
aab425ee5b | ||
|
|
f7bc889723 | ||
|
|
cc4fb5a40b | ||
|
|
bbb4880ba4 | ||
|
|
a2098a5797 | ||
|
|
93bdac31ea | ||
|
|
92a588751a | ||
|
|
272db9d483 | ||
|
|
9d75fc18a1 | ||
|
|
d8d60c6bb0 | ||
|
|
8c656626d6 | ||
|
|
b773119193 | ||
|
|
bdc0db3357 | ||
|
|
f3b3c9ff6a | ||
|
|
7d394dcff2 | ||
|
|
ff11388009 | ||
|
|
b492fece6c | ||
|
|
5394f1dee9 | ||
|
|
e742371d15 | ||
|
|
d03ee006fc | ||
|
|
897d76c4a2 | ||
|
|
349dd12161 | ||
|
|
d84e6c84f5 | ||
|
|
dfcdf8871c | ||
|
|
7122962dc8 | ||
|
|
6432928b7d | ||
|
|
ed1d6e59b5 | ||
|
|
8b2d85aee5 | ||
|
|
392d63fe57 | ||
|
|
1c086b057a | ||
|
|
6bbe55a46c | ||
|
|
7a269efcbc | ||
|
|
06bd6db601 | ||
|
|
3dc9d3a420 | ||
|
|
91ba503700 | ||
|
|
28d27dca5c | ||
|
|
e33265b58d | ||
|
|
22fcb04773 | ||
|
|
f9f67873ad | ||
|
|
b1d345f165 | ||
|
|
1c6a32b684 | ||
|
|
55ac2dd1bb | ||
|
|
997dce288d | ||
|
|
4d745d3600 | ||
|
|
dbd1080f5c | ||
|
|
76963d8109 | ||
|
|
6b106c1b38 | ||
|
|
0016cc59af | ||
|
|
8b9d0f7b19 | ||
|
|
3a4b01cf6f | ||
|
|
15acb9d204 | ||
|
|
21fa96f78f | ||
|
|
fe4e11d9c1 | ||
|
|
d22d5fcfc3 | ||
|
|
cdca4a8585 | ||
|
|
46552785f5 | ||
|
|
816c62979a | ||
|
|
ca164c2a24 | ||
|
|
bf3c6f95eb | ||
|
|
f07f2e77f6 | ||
|
|
50fdbd896c | ||
|
|
bab7bd20cd | ||
|
|
0678908fd9 | ||
|
|
9d29776e8e | ||
|
|
140a220340 | ||
|
|
731e607666 | ||
|
|
97ee66465d | ||
|
|
a0050fedd3 | ||
|
|
89e5001bad | ||
|
|
056fb154a8 | ||
|
|
3edc2b80cf | ||
|
|
a1745cd02e | ||
|
|
1c0f9b64ca | ||
|
|
7d6a518f30 | ||
|
|
9f2fcebc24 | ||
|
|
91295f50b0 | ||
|
|
68bf97f52c | ||
|
|
363048e68e | ||
|
|
9c20c0b889 | ||
|
|
50891e5dd7 | ||
|
|
f393a95501 | ||
|
|
a68dd6d2f7 | ||
|
|
dadf6708ab | ||
|
|
7a86c78896 | ||
|
|
81688399c0 | ||
|
|
1e28a2e5d4 | ||
|
|
c5bb259555 | ||
|
|
0d5d75d6ea | ||
|
|
5bae9bbbcc | ||
|
|
a3e681078f | ||
|
|
758228e159 | ||
|
|
1b900a006f | ||
|
|
9b5c5169ef | ||
|
|
e78a55ac6e | ||
|
|
e82cf70399 | ||
|
|
e7d65ee4ae | ||
|
|
1db3669afa | ||
|
|
93e55b7575 | ||
|
|
f850c65b56 | ||
|
|
297348fffe | ||
|
|
07ff6558d1 | ||
|
|
85843efcb0 | ||
|
|
3d4b1c3be5 | ||
|
|
a3f389af5e | ||
|
|
1aeb3c6fd6 | ||
|
|
6ab6c016c0 | ||
|
|
a1961603d7 | ||
|
|
50ac95dec5 | ||
|
|
a16e46cf38 | ||
|
|
ea33b75764 | ||
|
|
31e657d052 | ||
|
|
fe0dfef83c | ||
|
|
bc1a47ff5a | ||
|
|
4e8089dd42 | ||
|
|
6dc9f90a8b | ||
|
|
1aae3ae2b5 | ||
|
|
75436bcce4 | ||
|
|
61df3ef40e | ||
|
|
f45aab27d1 | ||
|
|
f477c46406 | ||
|
|
2af07d7e0d | ||
|
|
df691488a9 | ||
|
|
800e7ae508 | ||
|
|
fcf156293e | ||
|
|
94f44a0eb7 | ||
|
|
1e2c28f67a | ||
|
|
62b45f7ea7 | ||
|
|
f577590ad6 | ||
|
|
0941247f63 | ||
|
|
3170060f37 | ||
|
|
35b384439f | ||
|
|
0d1150d4d2 | ||
|
|
1f68b46575 | ||
|
|
32c5c4d741 | ||
|
|
0cb15121e5 | ||
|
|
808033a01c | ||
|
|
736e0d2e70 | ||
|
|
96741570c5 | ||
|
|
8feb3fee98 | ||
|
|
07e3e44a68 | ||
|
|
d67d405024 | ||
|
|
520836f475 | ||
|
|
6d6bf1044b | ||
|
|
195866f3aa | ||
|
|
10f0be0708 | ||
|
|
721773ef68 | ||
|
|
0d647ffb9a | ||
|
|
b6235e99c8 | ||
|
|
1d0a6af7d7 | ||
|
|
efd7af165c | ||
|
|
3f4ee6d841 | ||
|
|
55c437d980 | ||
|
|
ecfe103c50 | ||
|
|
a282ad7809 | ||
|
|
64176b8d26 | ||
|
|
278fb298b6 | ||
|
|
1d1b88cf05 | ||
|
|
0c50aa7872 | ||
|
|
0bfa01f072 | ||
|
|
3e9594f069 | ||
|
|
a07138680b | ||
|
|
5f6f2f2859 | ||
|
|
e185ba0191 | ||
|
|
3ab0b17379 | ||
|
|
942d97931e | ||
|
|
40809f1d91 | ||
|
|
f6a37186aa | ||
|
|
9522bf3095 | ||
|
|
c3c7387390 | ||
|
|
09fb58c3e9 | ||
|
|
3d33e630ec | ||
|
|
b51916fb2b | ||
|
|
c9ee92cc30 | ||
|
|
0e81416c2f | ||
|
|
6cd7d46208 | ||
|
|
6af6da16b4 | ||
|
|
4c5900373d | ||
|
|
2fd167c446 | ||
|
|
31149aeed9 | ||
|
|
977b87cbf3 | ||
|
|
42ed4ff48a | ||
|
|
060c71f439 | ||
|
|
63527858e7 | ||
|
|
2f4ea9cac7 | ||
|
|
a1f2369306 | ||
|
|
a35c5f79c1 | ||
|
|
d382e15749 | ||
|
|
5b7d513986 | ||
|
|
be083cfd53 | ||
|
|
f9844c284a | ||
|
|
e8065d07b3 | ||
|
|
8a0820ad1e | ||
|
|
8274cc016f | ||
|
|
b88281b458 | ||
|
|
a1cb5eb420 | ||
|
|
d458c4ecc8 | ||
|
|
b6e4f53597 | ||
|
|
4abbf55ee4 | ||
|
|
1fd909cff6 | ||
|
|
7ca53d1073 | ||
|
|
2bda0f700c | ||
|
|
16b2cc49d4 | ||
|
|
e3e67d1098 | ||
|
|
3276e3ec52 | ||
|
|
5e9a79afe8 | ||
|
|
c6912a193c | ||
|
|
47083e6be1 | ||
|
|
ca78cc5c3c | ||
|
|
76db305ffa | ||
|
|
5d2ef4786b | ||
|
|
9953a5ed06 | ||
|
|
dd194d41be | ||
|
|
8168cf82c5 | ||
|
|
e2d6e39168 | ||
|
|
a340bc4da3 | ||
|
|
4bcb0e17f8 | ||
|
|
25a51df894 | ||
|
|
f9c6ffcdaa | ||
|
|
b76c54ceac | ||
|
|
4be7772d53 | ||
|
|
cbc70a8ff3 | ||
|
|
dd8af0ad8c | ||
|
|
00541e6cc1 | ||
|
|
a8eec60c9d | ||
|
|
7bb319b6d6 | ||
|
|
50a5a2de9b | ||
|
|
dbe5946d10 | ||
|
|
d5caac5d3b | ||
|
|
487c5e22ce | ||
|
|
6efd63a292 | ||
|
|
f31dc3c054 | ||
|
|
c60be3a467 | ||
|
|
44b4e71c05 | ||
|
|
5ebd035b1c | ||
|
|
d50514f8bc | ||
|
|
7da2183080 | ||
|
|
a417ac2716 | ||
|
|
a89e662721 | ||
|
|
72aac6e551 | ||
|
|
4b1e4eecfb | ||
|
|
8e452f8b6d | ||
|
|
7e6db89eff | ||
|
|
16214e666b | ||
|
|
2b25ce237f | ||
|
|
f0a9955447 | ||
|
|
d0439296fe | ||
|
|
e2c2bdb65b | ||
|
|
bc3fdb0f80 | ||
|
|
186b2ada36 | ||
|
|
577125f345 | ||
|
|
687dd8a05f | ||
|
|
81861c6121 | ||
|
|
302462f48c | ||
|
|
d132f55830 | ||
|
|
6bbd64e59a | ||
|
|
290c4e1f2e | ||
|
|
1112616514 | ||
|
|
7fddbca4b7 | ||
|
|
692841478c | ||
|
|
23232b9830 | ||
|
|
b886566b25 | ||
|
|
2c56d60678 | ||
|
|
a0c8127ecf | ||
|
|
05f61df59e | ||
|
|
a0b80ad41a | ||
|
|
9e7cb708bf | ||
|
|
95d97c59d7 | ||
|
|
a75f3e1f8e | ||
|
|
d09d30544f | ||
|
|
1ad4006819 | ||
|
|
43d904d20b | ||
|
|
5339f8efdc | ||
|
|
b273bfb10e | ||
|
|
244e82722d | ||
|
|
e182d8b964 | ||
|
|
02e610a5f2 | ||
|
|
032bc2d5c4 | ||
|
|
e59db74cad | ||
|
|
fbe9ad6582 | ||
|
|
87da542758 | ||
|
|
b2317ada1f | ||
|
|
336aee7fda | ||
|
|
9e7468d723 | ||
|
|
f05ee13206 | ||
|
|
8b3b46b724 | ||
|
|
80e53f209d | ||
|
|
82f29cdc70 | ||
|
|
93d6505f85 | ||
|
|
2b7afd3272 | ||
|
|
6d4e1f6c2e | ||
|
|
2b579eb0d3 | ||
|
|
c0f323b05a | ||
|
|
791121fa06 | ||
|
|
f25d4463f5 | ||
|
|
f0bcb27beb | ||
|
|
00099a5e40 | ||
|
|
7c251157ed | ||
|
|
ec6b389d75 | ||
|
|
f38430d632 | ||
|
|
266f28883a | ||
|
|
cc3c2533fa | ||
|
|
f8162b34f2 | ||
|
|
3ff5b36d29 | ||
|
|
1fa736c6d8 | ||
|
|
309877bf76 | ||
|
|
a50b20a397 | ||
|
|
de5489ae9a | ||
|
|
12e74aa38b | ||
|
|
94eccc6c14 | ||
|
|
80ec66b47c | ||
|
|
9fffcfaea3 | ||
|
|
f481676c81 | ||
|
|
76a42b28f3 | ||
|
|
ad26e48408 | ||
|
|
0bab97e02f | ||
|
|
2413457323 | ||
|
|
585fd87ad6 | ||
|
|
ec5161e848 | ||
|
|
0ec54daaff | ||
|
|
bfcd05206f | ||
|
|
ddf10ed137 | ||
|
|
3ed1bebb7d | ||
|
|
b4d1c0e053 | ||
|
|
68f58fb37d | ||
|
|
f9923f4592 | ||
|
|
29ae088a3d | ||
|
|
dd553b9439 | ||
|
|
451f2d30e4 | ||
|
|
463d85e479 | ||
|
|
2c52795822 | ||
|
|
4f37a36619 | ||
|
|
5aaba98c57 | ||
|
|
a98b69859c | ||
|
|
734a36de06 | ||
|
|
eb299ce847 | ||
|
|
a7e071318b | ||
|
|
b02944a3b2 | ||
|
|
6878abe2a2 | ||
|
|
ec1c81e3ed | ||
|
|
47824426c6 | ||
|
|
4ded288c5d | ||
|
|
d123ca6063 | ||
|
|
0ee8b75b54 |
17
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,9 +1,16 @@
|
||||
**Description:**
|
||||
|
||||
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/FAQ
|
||||
|
||||
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
|
||||
|
||||
**Radarr Version:**
|
||||
|
||||
**Logs:**
|
||||
|
||||
|
||||
Please use the search bar and make sure you are not submitting an already submitted issue.
|
||||
|
||||
Provide a description of the feature request or bug, the more details the better.
|
||||
When possible include a log!
|
||||
|
||||
Please use our [Discord server](https://discord.gg/NWYch8M) for support or longer discussions.
|
||||
Visit our [Discord server](https://discord.gg/NWYch8M) for support or longer discussions.
|
||||
|
||||
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,13 +2,11 @@
|
||||
YES | NO
|
||||
|
||||
#### Description
|
||||
A few sentences describing the overall goals of the pull request's commits.
|
||||
|
||||
|
||||
#### Todos
|
||||
- [ ] Tests
|
||||
- [ ] Documentation
|
||||
|
||||
|
||||
#### Issues Fixed or Closed by this PR
|
||||
|
||||
*
|
||||
* #
|
||||
|
||||
@@ -4,7 +4,7 @@ addons:
|
||||
apt:
|
||||
packages:
|
||||
- nodejs
|
||||
- npm
|
||||
# - npm apparently not needed anymore.
|
||||
script:
|
||||
- ./build.sh
|
||||
- chmod +x test.sh
|
||||
|
||||
BIN
Logo/1024.png
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 48 KiB |
BIN
Logo/128.png
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 5.1 KiB |
BIN
Logo/16.png
|
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 701 B |
BIN
Logo/256.png
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 11 KiB |
BIN
Logo/32.png
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
Logo/400.png
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 17 KiB |
BIN
Logo/48.png
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
Logo/512.png
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 22 KiB |
BIN
Logo/64.png
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
Logo/800.png
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 37 KiB |
597
Logo/Radarr.svg
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 31 KiB |
BIN
Logo/text256.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
108
README.md
@@ -1,3 +1,41 @@
|
||||
<p align="center">
|
||||
<img src="/Logo/text256.png" alt="Radarr">
|
||||
</p>
|
||||
|
||||
Radarr is an __independent__ fork of [Sonarr](https://github.com/Sonarr/Sonarr) reworked for automatically downloading movies via Usenet and BitTorrent.
|
||||
|
||||
The project was inspired by other Usenet/BitTorrent movie downloaders such as CouchPotato.
|
||||
|
||||
## Getting Started
|
||||
|
||||
[](https://github.com/Radarr/Radarr/wiki/Installation)
|
||||
[](https://github.com/Radarr/Radarr/wiki/Docker)
|
||||
[](https://github.com/Radarr/Radarr/wiki/Setup-Guide)
|
||||
[](https://github.com/Radarr/Radarr/wiki/FAQ)
|
||||
|
||||
* [Install Radarr for your desired OS](https://github.com/Radarr/Radarr/wiki/Installation) *or* use [Docker](https://github.com/Radarr/Radarr/wiki/Docker)
|
||||
* *For Linux users*, run `radarr` and *optionally* have [Radarr start automatically](https://github.com/Radarr/Radarr/wiki/Autostart-on-Linux)
|
||||
* Connect to the UI through <http://localhost:7878> or <http://your-ip:7878> in your web browser
|
||||
* See the [Setup Guide](https://github.com/Radarr/Radarr/wiki/Setup-Guide) for further configuration
|
||||
|
||||
## Downloads
|
||||
|
||||
[](https://github.com/Radarr/Radarr/releases)
|
||||
[](https://ci.appveyor.com/project/galli-leo/radarr-usby1/build/artifacts)
|
||||
|
||||
[](https://store.docker.com/community/images/linuxserver/radarr)
|
||||
[](https://store.docker.com/community/images/hotio/radarr)
|
||||
[](https://store.docker.com/community/images/lsioarmhf/radarr)
|
||||
[](https://store.docker.com/community/images/lsioarmhf/radarr-aarch64)
|
||||
|
||||
## Support
|
||||
|
||||
[](https://discord.gg/AD3UP37)
|
||||
[](https://www.reddit.com/r/radarr)
|
||||
[](http://feathub.com/Radarr/Radarr)
|
||||
[](https://github.com/Radarr/Radarr/issues)
|
||||
[](https://github.com/Radarr/Radarr/wiki)
|
||||
|
||||
## Status
|
||||
|
||||
[](https://github.com/Radarr/Radarr/issues)
|
||||
@@ -12,57 +50,47 @@
|
||||
| AppVeyor | [](https://ci.appveyor.com/project/galli-leo/Radarr) | [](https://ci.appveyor.com/project/galli-leo/Radarr-usby1) |
|
||||
| Travis | [](https://travis-ci.org/Radarr/Radarr) | [](https://travis-ci.org/Radarr/Radarr) |
|
||||
|
||||
This fork of Sonarr aims to turn it into something like CouchPotato.
|
||||
**This project works independently of Sonarr and will not interfere with it.**
|
||||
|
||||
## Downloads
|
||||
|
||||
[](https://github.com/Radarr/Radarr/releases)
|
||||
|
||||
[](https://ci.appveyor.com/project/galli-leo/radarr-usby1/build/artifacts)
|
||||
|
||||
[](https://store.docker.com/community/images/linuxserver/radarr)
|
||||
[](https://store.docker.com/community/images/lsioarmhf/radarr)
|
||||
[](https://store.docker.com/community/images/lsioarmhf/radarr-aarch64)
|
||||
|
||||
To connect to the UI, fire up your browser and open <http://localhost:7878> or <http://your-ip:7878>.
|
||||
|
||||
## Support
|
||||
|
||||
[](https://discord.gg/AD3UP37)
|
||||
[](https://www.reddit.com/r/radarr)
|
||||
[](https://github.com/Radarr/Radarr/issues)
|
||||
Radarr is currently undergoing rapid development and pull requests are actively added into the repository.
|
||||
|
||||
## Features
|
||||
|
||||
### Currently Working
|
||||
|
||||
* Adding new movies
|
||||
* Manually searching for releases of movies
|
||||
* Automatically searching for releases
|
||||
* Automatically importing downloaded movies
|
||||
* Recognizing Special Editions, Director's Cut, etc.
|
||||
* Identifying releases with hardcoded subs
|
||||
* Rarbg.to, Torznab and Newznab Indexer
|
||||
* QBittorrent and Deluge download client (Other clients are coming)
|
||||
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
|
||||
|
||||
### Planned Features
|
||||
|
||||
* Scanning PreDB to know when a new release is available
|
||||
* Fixing the other Indexers and download clients
|
||||
* Importing of Sonarr config
|
||||
|
||||
### Major Features
|
||||
### Current Features
|
||||
|
||||
* Adding new movies with lots of information, such as trailers, ratings, etc.
|
||||
* Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc.
|
||||
* Can watch for better quality of the movies you have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
|
||||
* Automatic failed download handling will try another release if one fails
|
||||
* Manual search so you can pick any release or to see why a release was not downloaded automatically
|
||||
* Full integration with SABnzbd and NZBGet
|
||||
* Full integration with Kodi, Plex (notification, library update, metadata)
|
||||
* Automatically searching for releases as well as RSS Sync
|
||||
* Automatically importing downloaded movies
|
||||
* Recognizing Special Editions, Director's Cut, etc.
|
||||
* Identifying releases with hardcoded subs
|
||||
* All indexers supported by Sonarr also supported
|
||||
* New PassThePopcorn Indexer
|
||||
* QBittorrent, Deluge, rTorrent, Transmission and uTorrent download client (Other clients are coming)
|
||||
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
|
||||
* Scanning PreDB to know when a new release is available
|
||||
* Importing movies from various online sources, such as IMDb Watchlists (A complete list can be found [here](https://github.com/Radarr/Radarr/issues/114))
|
||||
* Full integration with Kodi, Plex (notification, library update)
|
||||
* And a beautiful UI
|
||||
|
||||
## Configuring Development Environment
|
||||
### Planned Features
|
||||
|
||||
* Downloading Metadata such as trailers or subtitles (\*)
|
||||
* Adding metadata such as posters and information for Kodi and others to use (\*)
|
||||
* Dynamically renaming folders with quality info, etc. (\*)
|
||||
* Supporting custom folder structures, such as all movie files in one folder (\*)
|
||||
* Supporting multiple editions per movies (waiting on The Movie Database to finish their implementation)
|
||||
* Supporting collections of movies, such as James Bond
|
||||
|
||||
**Note:** All features marked with (\*) are set to be in the first release of Radarr.
|
||||
|
||||
#### [Feature Requests](http://feathub.com/Radarr/Radarr)
|
||||
|
||||
## Configuring the Development Environment
|
||||
|
||||
### Requirements
|
||||
|
||||
@@ -88,7 +116,7 @@ To connect to the UI, fire up your browser and open <http://localhost:7878> or <
|
||||
|
||||
## Sponsors
|
||||
|
||||
[JetBrains](http://www.jetbrains.com) for providing us with free licenses to their great tools:
|
||||
Thanks to [JetBrains](http://www.jetbrains.com) for providing us with free licenses to their great tools:
|
||||
* [ReSharper](http://www.jetbrains.com/resharper)
|
||||
* [WebStorm](http://www.jetbrains.com/webstorm)
|
||||
* [TeamCity](http://www.jetbrains.com/teamcity)
|
||||
|
||||
29
appveyor.yml
@@ -1,9 +1,5 @@
|
||||
version: '0.2.0.{build}'
|
||||
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
|
||||
assembly_info:
|
||||
patch: true
|
||||
file: 'src\NzbDrone.Common\Properties\SharedAssemblyInfo.cs'
|
||||
@@ -20,17 +16,18 @@ install:
|
||||
build_script:
|
||||
- ps: ./build-appveyor.ps1
|
||||
|
||||
test: off
|
||||
# test:
|
||||
# assemblies:
|
||||
# - '_tests\*Test.dll'
|
||||
# categories:
|
||||
# except:
|
||||
# - IntegrationTest
|
||||
# - AutomationTest
|
||||
# test: off
|
||||
test:
|
||||
assemblies:
|
||||
- '_tests\*Test.dll'
|
||||
categories:
|
||||
except:
|
||||
- IntegrationTest
|
||||
- AutomationTest
|
||||
|
||||
artifacts:
|
||||
- path: '_artifacts\*.zip'
|
||||
- path: '_artifacts\*.exe'
|
||||
- path: '_artifacts\*.tar.gz'
|
||||
|
||||
cache:
|
||||
@@ -40,9 +37,17 @@ cache:
|
||||
pull_requests:
|
||||
do_not_increment_build_number: true
|
||||
|
||||
on_failure:
|
||||
- ps: Get-ChildItem .\_artifacts\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||
- ps: Get-ChildItem .\_artifacts\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||
- ps: Get-ChildItem .\_artifacts\*.tar.gz | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||
|
||||
only_commits:
|
||||
files:
|
||||
- src/
|
||||
- osx/
|
||||
- gulp/
|
||||
- logo/
|
||||
- setup/
|
||||
- appveyor.yml
|
||||
- build-appveyor.cake
|
||||
|
||||
@@ -264,6 +264,13 @@ Task("ArtifactsWindows").Does(() => {
|
||||
CopyDirectory(outputFolder, artifactsFolderWindows + "/Radarr");
|
||||
});
|
||||
|
||||
Task("ArtifactsWindowsInstaller").Does(() => {
|
||||
InnoSetup("./setup/nzbdrone.iss", new InnoSetupSettings {
|
||||
OutputDirectory = artifactsFolder,
|
||||
ToolPath = "./setup/inno/ISCC.exe"
|
||||
});
|
||||
});
|
||||
|
||||
Task("ArtifactsLinux").Does(() => {
|
||||
CopyDirectory(outputFolderMono, artifactsFolderLinux + "/Radarr");
|
||||
});
|
||||
@@ -280,7 +287,7 @@ Task("CompressArtifacts").Does(() => {
|
||||
var prefix = "";
|
||||
|
||||
if (AppVeyor.IsRunningOnAppVeyor) {
|
||||
prefix += AppVeyor.Environment.Repository.Branch + ".";
|
||||
prefix += AppVeyor.Environment.Repository.Branch.Replace("/", "-") + ".";
|
||||
prefix += AppVeyor.Environment.Build.Version + ".";
|
||||
}
|
||||
|
||||
@@ -293,6 +300,7 @@ Task("CompressArtifacts").Does(() => {
|
||||
Task("Artifacts")
|
||||
.IsDependentOn("CleanArtifacts")
|
||||
.IsDependentOn("ArtifactsWindows")
|
||||
.IsDependentOn("ArtifactsWindowsInstaller")
|
||||
.IsDependentOn("ArtifactsLinux")
|
||||
.IsDependentOn("ArtifactsOsx")
|
||||
.IsDependentOn("ArtifactsOsxApp")
|
||||
@@ -300,4 +308,4 @@ Task("Artifacts")
|
||||
|
||||
// Run
|
||||
RunTarget("Build");
|
||||
RunTarget("Artifacts");
|
||||
RunTarget("Artifacts");
|
||||
|
||||
4
build.sh
@@ -208,9 +208,9 @@ PackageTests()
|
||||
find $sourceFolder -path $testSearchPattern -exec cp -r -u -T "{}" $testPackageFolder \;
|
||||
|
||||
if [ $runtime = "dotnet" ] ; then
|
||||
$nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
|
||||
$nuget install NUnit.Runners -Version 3.2.1 -Output $testPackageFolder
|
||||
else
|
||||
mono $nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
|
||||
mono $nuget install NUnit.Runners -Version 3.2.1 -Output $testPackageFolder
|
||||
fi
|
||||
|
||||
cp $outputFolder/*.dll $testPackageFolder
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"run-sequence": "1.1.1",
|
||||
"streamqueue": "1.1.0",
|
||||
"tar.gz": "0.1.1",
|
||||
"url-search-params": "^0.6.1",
|
||||
"webpack": "1.12.0",
|
||||
"webpack-stream": "2.1.0"
|
||||
}
|
||||
|
||||
59
package.sh
@@ -23,6 +23,9 @@ if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
|
||||
DAY="`date +%d`"
|
||||
else
|
||||
VERSION=$1
|
||||
BRANCH=$2
|
||||
BRANCH=${BRANCH#refs\/heads\/}
|
||||
BRANCH=${BRANCH//\//-}
|
||||
fi
|
||||
outputFolder='./_output'
|
||||
outputFolderMono='./_output_mono'
|
||||
@@ -34,35 +37,41 @@ rm $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr
|
||||
chmod +x $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2
|
||||
mv $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2 $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr >& error.log
|
||||
|
||||
cp -r $outputFolder/ Radarr_Windows_$VERSION
|
||||
cp -r $outputFolderMono/ Radarr_Mono_$VERSION
|
||||
cp -r $outputFolderOsxApp/ Radarr_OSX_$VERSION
|
||||
|
||||
if [ $runtime = "dotnet" ] ; then
|
||||
./7za.exe a Radarr_Windows_$VERSION.zip ./Radarr_Windows_$VERSION/*
|
||||
./7za.exe a -ttar -so Radarr_Mono_$VERSION.tar ./Radarr_Mono_$VERSION/* | ./7za.exe a -si Radarr_Mono_$VERSION.tar.gz
|
||||
./7za.exe a -ttar -so Radarr_OSX_$VERSION.tar ./_output_osx/* | ./7za.exe a -si Radarr_OSX_$VERSION.tar.gz
|
||||
./7za.exe a -ttar -so Radarr_OSX_App_$VERSION.tar ./_output_osx_app/* | ./7za.exe a -si Radarr_OSX_App_$VERSION.tar.gz
|
||||
else
|
||||
zip -r Radarr_Windows_$VERSION.zip Radarr_Windows_$VERSION/* >& /dev/null
|
||||
zip -r Radarr_Mono_$VERSION.zip Radarr_Mono_$VERSION/* >& /dev/null #TODO update for tar.gz
|
||||
zip -r Radarr_OSX_$VERSION_App.zip Radarr_OSX_$VERSION/* >& /dev/null
|
||||
cp -r $outputFolder/ Radarr
|
||||
zip -r Radarr.$BRANCH.$VERSION.windows.zip Radarr
|
||||
rm -rf Radarr
|
||||
cp -r $outputFolderMono/ Radarr
|
||||
tar -zcvf Radarr.$BRANCH.$VERSION.linux.tar.gz Radarr
|
||||
rm -rf Radarr
|
||||
cp -r $outputFolderOsx/ Radarr
|
||||
tar -zcvf Radarr.$BRANCH.$VERSION.osx.tar.gz Radarr
|
||||
rm -rf Radarr
|
||||
#TODO update for tar.gz
|
||||
|
||||
cd _output_osx_app/
|
||||
zip -r ../Radarr.$BRANCH.$VERSION.osx-app.zip *
|
||||
fi
|
||||
ftp -n ftp.leonardogalli.ch << END_SCRIPT
|
||||
passive
|
||||
quote USER $FTP_USER
|
||||
quote PASS $FTP_PASS
|
||||
mkdir builds
|
||||
cd builds
|
||||
mkdir $YEAR
|
||||
cd $YEAR
|
||||
mkdir $MONTH
|
||||
cd $MONTH
|
||||
mkdir $DAY
|
||||
cd $DAY
|
||||
binary
|
||||
put Radarr_Windows_$VERSION.zip
|
||||
put Radarr_Mono_$VERSION.zip
|
||||
put Radarr_OSX_$VERSION.zip
|
||||
quit
|
||||
END_SCRIPT
|
||||
# ftp -n ftp.leonardogalli.ch << END_SCRIPT
|
||||
# passive
|
||||
# quote USER $FTP_USER
|
||||
# quote PASS $FTP_PASS
|
||||
# mkdir builds
|
||||
# cd builds
|
||||
# mkdir $YEAR
|
||||
# cd $YEAR
|
||||
# mkdir $MONTH
|
||||
# cd $MONTH
|
||||
# mkdir $DAY
|
||||
# cd $DAY
|
||||
# binary
|
||||
# put Radarr_Windows_$VERSION.zip
|
||||
# put Radarr_Mono_$VERSION.zip
|
||||
# put Radarr_OSX_$VERSION.zip
|
||||
# quit
|
||||
# END_SCRIPT
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
; Script generated by the Inno Setup Script Wizard.
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
#define AppName "Sonarr"
|
||||
#define AppPublisher "Team Sonarr"
|
||||
#define AppURL "https://sonarr.tv/"
|
||||
#define ForumsURL "https://forums.sonarr.tv/"
|
||||
#define AppExeName "NzbDrone.exe"
|
||||
#define AppName "Radarr"
|
||||
#define AppPublisher "Team Radarr"
|
||||
#define AppURL "https://radarr.video/"
|
||||
#define ForumsURL "https://github.com/Radarr/Radarr/issues"
|
||||
#define AppExeName "Radarr.exe"
|
||||
#define BuildNumber "2.0"
|
||||
#define BuildNumber GetEnv('BUILD_NUMBER')
|
||||
#define BranchName GetEnv('branch')
|
||||
#define BuildVersion GetEnv('APPVEYOR_BUILD_VERSION')
|
||||
#define BranchName GetEnv('APPVEYOR_REPO_BRANCH')
|
||||
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application.
|
||||
; Do not use the same AppId value in installers for other applications.
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId={{56C1065D-3523-4025-B76D-6F73F67F7F71}
|
||||
AppId={{56C1065D-3523-4025-B76D-6F73F67F7F82}
|
||||
AppName={#AppName}
|
||||
AppVersion=2.0
|
||||
AppVersion=0.2
|
||||
AppPublisher={#AppPublisher}
|
||||
AppPublisherURL={#AppURL}
|
||||
AppSupportURL={#ForumsURL}
|
||||
AppUpdatesURL={#AppURL}
|
||||
DefaultDirName={commonappdata}\NzbDrone\bin
|
||||
DefaultDirName={commonappdata}\Radarr\bin
|
||||
DisableDirPage=yes
|
||||
DefaultGroupName={#AppName}
|
||||
DisableProgramGroupPage=yes
|
||||
OutputBaseFilename=NzbDrone.{#BranchName}.{#BuildNumber}
|
||||
OutputBaseFilename=Radarr.{#BranchName}.{#BuildVersion}.installer
|
||||
SolidCompression=yes
|
||||
AppCopyright=Creative Commons 3.0 License
|
||||
AllowUNCPath=False
|
||||
UninstallDisplayIcon={app}\NzbDrone.exe
|
||||
UninstallDisplayIcon={app}\Radarr.exe
|
||||
DisableReadyPage=True
|
||||
CompressionThreads=2
|
||||
Compression=lzma2/normal
|
||||
@@ -44,7 +44,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
Name: "windowsService"; Description: "Install as a Windows Service"
|
||||
|
||||
[Files]
|
||||
Source: "..\_output\NzbDrone.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\_output\Radarr.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\_output\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
@@ -53,8 +53,8 @@ Name: "{group}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Parameters: "/icon"
|
||||
Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Parameters: "/icon"
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\nzbdrone.console.exe"; Parameters: "/u"; Flags: waituntilterminated;
|
||||
Filename: "{app}\nzbdrone.console.exe"; Parameters: "/i"; Flags: waituntilterminated; Tasks: windowsService
|
||||
Filename: "{app}\radarr.console.exe"; Parameters: "/u"; Flags: waituntilterminated;
|
||||
Filename: "{app}\radarr.console.exe"; Parameters: "/i"; Flags: waituntilterminated; Tasks: windowsService
|
||||
|
||||
[UninstallRun]
|
||||
Filename: "{app}\nzbdrone.console.exe"; Parameters: "/u"; Flags: waituntilterminated skipifdoesntexist
|
||||
Filename: "{app}\radarr.console.exe"; Parameters: "/u"; Flags: waituntilterminated skipifdoesntexist
|
||||
|
||||
@@ -33,12 +33,12 @@ namespace NzbDrone.Api.Authentication
|
||||
{
|
||||
if (_configFileProvider.AuthenticationMethod == AuthenticationType.Forms)
|
||||
{
|
||||
RegisterFormsAuth(pipelines);
|
||||
RegisterFormsAuth(pipelines);
|
||||
}
|
||||
|
||||
else if (_configFileProvider.AuthenticationMethod == AuthenticationType.Basic)
|
||||
{
|
||||
pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(_authenticationService, "Sonarr"));
|
||||
pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(_authenticationService, "Radarr"));
|
||||
}
|
||||
|
||||
pipelines.BeforeRequest.AddItemToEndOfPipeline((Func<NancyContext, Response>) RequiresAuthentication);
|
||||
@@ -64,6 +64,8 @@ namespace NzbDrone.Api.Authentication
|
||||
new DefaultHmacProvider(new PassphraseKeyGenerator(_configService.HmacPassphrase, Encoding.ASCII.GetBytes(_configService.HmacSalt)))
|
||||
);
|
||||
|
||||
FormsAuthentication.FormsAuthenticationCookieName = "_ncfaradarr"; //For those people that both have sonarr and radarr.
|
||||
|
||||
FormsAuthentication.Enable(pipelines, new FormsAuthenticationConfiguration
|
||||
{
|
||||
RedirectUrl = _configFileProvider.UrlBase + "/login",
|
||||
|
||||
@@ -16,13 +16,13 @@ namespace NzbDrone.Api.Calendar
|
||||
{
|
||||
public class CalendarFeedModule : NzbDroneFeedModule
|
||||
{
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly ITagService _tagService;
|
||||
|
||||
public CalendarFeedModule(IEpisodeService episodeService, ITagService tagService)
|
||||
public CalendarFeedModule(IMovieService movieService, ITagService tagService)
|
||||
: base("calendar")
|
||||
{
|
||||
_episodeService = episodeService;
|
||||
_movieService = movieService;
|
||||
_tagService = tagService;
|
||||
|
||||
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Api.Calendar
|
||||
var start = DateTime.Today.AddDays(-pastDays);
|
||||
var end = DateTime.Today.AddDays(futureDays);
|
||||
var unmonitored = false;
|
||||
var premiersOnly = false;
|
||||
//var premiersOnly = false;
|
||||
var tags = new List<int>();
|
||||
|
||||
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
||||
@@ -46,7 +46,7 @@ namespace NzbDrone.Api.Calendar
|
||||
var queryPastDays = Request.Query.PastDays;
|
||||
var queryFutureDays = Request.Query.FutureDays;
|
||||
var queryUnmonitored = Request.Query.Unmonitored;
|
||||
var queryPremiersOnly = Request.Query.PremiersOnly;
|
||||
// var queryPremiersOnly = Request.Query.PremiersOnly;
|
||||
var queryTags = Request.Query.Tags;
|
||||
|
||||
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
||||
@@ -69,10 +69,10 @@ namespace NzbDrone.Api.Calendar
|
||||
unmonitored = bool.Parse(queryUnmonitored.Value);
|
||||
}
|
||||
|
||||
if (queryPremiersOnly.HasValue)
|
||||
{
|
||||
premiersOnly = bool.Parse(queryPremiersOnly.Value);
|
||||
}
|
||||
//if (queryPremiersOnly.HasValue)
|
||||
//{
|
||||
// premiersOnly = bool.Parse(queryPremiersOnly.Value);
|
||||
//}
|
||||
|
||||
if (queryTags.HasValue)
|
||||
{
|
||||
@@ -80,43 +80,56 @@ namespace NzbDrone.Api.Calendar
|
||||
tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id));
|
||||
}
|
||||
|
||||
var episodes = _episodeService.EpisodesBetweenDates(start, end, unmonitored);
|
||||
var movies = _movieService.GetMoviesBetweenDates(start, end, unmonitored);
|
||||
var calendar = new Ical.Net.Calendar
|
||||
{
|
||||
ProductId = "-//sonarr.tv//Sonarr//EN"
|
||||
ProductId = "-//radarr.video//Radarr//EN"
|
||||
};
|
||||
|
||||
|
||||
|
||||
foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value))
|
||||
foreach (var movie in movies.OrderBy(v => v.Added))
|
||||
{
|
||||
if (premiersOnly && (episode.SeasonNumber == 0 || episode.EpisodeNumber != 1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tags.Any() && tags.None(episode.Series.Tags.Contains))
|
||||
if (tags.Any() && tags.None(movie.Tags.Contains))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var occurrence = calendar.Create<Event>();
|
||||
occurrence.Uid = "NzbDrone_episode_" + episode.Id;
|
||||
occurrence.Status = episode.HasFile ? EventStatus.Confirmed : EventStatus.Tentative;
|
||||
occurrence.Start = new CalDateTime(episode.AirDateUtc.Value) { HasTime = true };
|
||||
occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(episode.Series.Runtime)) { HasTime = true };
|
||||
occurrence.Description = episode.Overview;
|
||||
occurrence.Categories = new List<string>() { episode.Series.Network };
|
||||
occurrence.Uid = "NzbDrone_movie_" + movie.Id;
|
||||
occurrence.Status = movie.HasFile ? EventStatus.Confirmed : EventStatus.Tentative;
|
||||
|
||||
switch (episode.Series.SeriesType)
|
||||
switch (movie.Status)
|
||||
{
|
||||
case SeriesTypes.Daily:
|
||||
occurrence.Summary = $"{episode.Series.Title} - {episode.Title}";
|
||||
case MovieStatusType.PreDB:
|
||||
if (movie.PhysicalRelease != null)
|
||||
{
|
||||
occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true };
|
||||
occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||
}
|
||||
break;
|
||||
|
||||
case MovieStatusType.InCinemas:
|
||||
if (movie.InCinemas != null)
|
||||
{
|
||||
occurrence.Start = new CalDateTime(movie.InCinemas.Value) { HasTime = true };
|
||||
occurrence.End = new CalDateTime(movie.InCinemas.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||
}
|
||||
break;
|
||||
case MovieStatusType.Announced:
|
||||
continue; // no date
|
||||
default:
|
||||
occurrence.Summary =$"{episode.Series.Title} - {episode.SeasonNumber}x{episode.EpisodeNumber:00} - {episode.Title}";
|
||||
if (movie.PhysicalRelease != null)
|
||||
{
|
||||
occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true };
|
||||
occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
occurrence.Description = movie.Overview;
|
||||
occurrence.Categories = new List<string>() { movie.Studio };
|
||||
|
||||
occurrence.Summary = $"{movie.Title}";
|
||||
|
||||
}
|
||||
|
||||
var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext());
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Api.Series;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Reflection;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Profiles;
|
||||
|
||||
namespace NzbDrone.Api.ClientSchema
|
||||
{
|
||||
@@ -73,14 +76,14 @@ namespace NzbDrone.Api.ClientSchema
|
||||
|
||||
if (propertyInfo.PropertyType == typeof(int))
|
||||
{
|
||||
var value = Convert.ToInt32(field.Value);
|
||||
propertyInfo.SetValue(target, value, null);
|
||||
var value = field.Value.ToString().ParseInt32();
|
||||
propertyInfo.SetValue(target, value ?? 0, null);
|
||||
}
|
||||
|
||||
else if (propertyInfo.PropertyType == typeof(long))
|
||||
{
|
||||
var value = Convert.ToInt64(field.Value);
|
||||
propertyInfo.SetValue(target, value, null);
|
||||
var value = field.Value.ToString().ParseInt64();
|
||||
propertyInfo.SetValue(target, value ?? 0, null);
|
||||
}
|
||||
|
||||
else if (propertyInfo.PropertyType == typeof(int?))
|
||||
@@ -147,6 +150,18 @@ namespace NzbDrone.Api.ClientSchema
|
||||
|
||||
private static List<SelectOption> GetSelectOptions(Type selectOptions)
|
||||
{
|
||||
if (selectOptions == typeof(Profile))
|
||||
{
|
||||
return new List<SelectOption>();
|
||||
}
|
||||
|
||||
if (selectOptions == typeof(Quality))
|
||||
{
|
||||
var qOptions = from Quality q in selectOptions.GetProperties(BindingFlags.Static | BindingFlags.Public)
|
||||
select new SelectOption {Name = q.Name, Value = q.Id};
|
||||
return qOptions.OrderBy(o => o.Value).ToList();
|
||||
}
|
||||
|
||||
var options = from Enum e in Enum.GetValues(selectOptions)
|
||||
select new SelectOption { Value = Convert.ToInt32(e), Name = e.ToString() };
|
||||
|
||||
|
||||
@@ -12,13 +12,13 @@ namespace NzbDrone.Api.Config
|
||||
MappedNetworkDriveValidator mappedNetworkDriveValidator)
|
||||
: base(configService)
|
||||
{
|
||||
SharedValidator.RuleFor(c => c.DownloadedEpisodesFolder)
|
||||
SharedValidator.RuleFor(c => c.DownloadedMoviesFolder)
|
||||
.Cascade(CascadeMode.StopOnFirstFailure)
|
||||
.IsValidPath()
|
||||
.SetValidator(rootFolderValidator)
|
||||
.SetValidator(mappedNetworkDriveValidator)
|
||||
.SetValidator(pathExistsValidator)
|
||||
.When(c => !string.IsNullOrWhiteSpace(c.DownloadedEpisodesFolder));
|
||||
.When(c => !string.IsNullOrWhiteSpace(c.DownloadedMoviesFolder));
|
||||
}
|
||||
|
||||
protected override DownloadClientConfigResource ToResource(IConfigService model)
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace NzbDrone.Api.Config
|
||||
{
|
||||
public class DownloadClientConfigResource : RestResource
|
||||
{
|
||||
public string DownloadedEpisodesFolder { get; set; }
|
||||
public string DownloadedMoviesFolder { get; set; }
|
||||
public string DownloadClientWorkingFolders { get; set; }
|
||||
public int DownloadedEpisodesScanInterval { get; set; }
|
||||
public int DownloadedMoviesScanInterval { get; set; }
|
||||
|
||||
public bool EnableCompletedDownloadHandling { get; set; }
|
||||
public bool RemoveCompletedDownloads { get; set; }
|
||||
@@ -22,9 +22,9 @@ namespace NzbDrone.Api.Config
|
||||
{
|
||||
return new DownloadClientConfigResource
|
||||
{
|
||||
DownloadedEpisodesFolder = model.DownloadedEpisodesFolder,
|
||||
DownloadedMoviesFolder = model.DownloadedMoviesFolder,
|
||||
DownloadClientWorkingFolders = model.DownloadClientWorkingFolders,
|
||||
DownloadedEpisodesScanInterval = model.DownloadedEpisodesScanInterval,
|
||||
DownloadedMoviesScanInterval = model.DownloadedMoviesScanInterval,
|
||||
|
||||
EnableCompletedDownloadHandling = model.EnableCompletedDownloadHandling,
|
||||
RemoveCompletedDownloads = model.RemoveCompletedDownloads,
|
||||
|
||||
@@ -8,6 +8,10 @@ namespace NzbDrone.Api.Config
|
||||
public int MinimumAge { get; set; }
|
||||
public int Retention { get; set; }
|
||||
public int RssSyncInterval { get; set; }
|
||||
public bool PreferIndexerFlags { get; set; }
|
||||
public int AvailabilityDelay { get; set; }
|
||||
public bool AllowHardcodedSubs { get; set; }
|
||||
public string WhitelistedHardcodedSubs { get; set; }
|
||||
}
|
||||
|
||||
public static class IndexerConfigResourceMapper
|
||||
@@ -19,6 +23,11 @@ namespace NzbDrone.Api.Config
|
||||
MinimumAge = model.MinimumAge,
|
||||
Retention = model.Retention,
|
||||
RssSyncInterval = model.RssSyncInterval,
|
||||
PreferIndexerFlags = model.PreferIndexerFlags,
|
||||
AvailabilityDelay = model.AvailabilityDelay,
|
||||
AllowHardcodedSubs = model.AllowHardcodedSubs,
|
||||
WhitelistedHardcodedSubs = model.WhitelistedHardcodedSubs,
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
22
src/NzbDrone.Api/Config/NetImportConfigModule.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using FluentValidation;
|
||||
using NzbDrone.Api.Validation;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
namespace NzbDrone.Api.Config
|
||||
{
|
||||
public class NetImportConfigModule : NzbDroneConfigModule<NetImportConfigResource>
|
||||
{
|
||||
|
||||
public NetImportConfigModule(IConfigService configService)
|
||||
: base(configService)
|
||||
{
|
||||
SharedValidator.RuleFor(c => c.NetImportSyncInterval)
|
||||
.IsValidNetImportSyncInterval();
|
||||
}
|
||||
|
||||
protected override NetImportConfigResource ToResource(IConfigService model)
|
||||
{
|
||||
return NetImportConfigResourceMapper.ToResource(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/NzbDrone.Api/Config/NetImportConfigResource.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
namespace NzbDrone.Api.Config
|
||||
{
|
||||
public class NetImportConfigResource : RestResource
|
||||
{
|
||||
public int NetImportSyncInterval { get; set; }
|
||||
public string ListSyncLevel { get; set; }
|
||||
public string ImportExclusions { get; set; }
|
||||
public string TraktAuthToken { get; set; }
|
||||
public string TraktRefreshToken { get; set; }
|
||||
public int TraktTokenExpiry { get; set; }
|
||||
}
|
||||
|
||||
public static class NetImportConfigResourceMapper
|
||||
{
|
||||
public static NetImportConfigResource ToResource(IConfigService model)
|
||||
{
|
||||
return new NetImportConfigResource
|
||||
{
|
||||
NetImportSyncInterval = model.NetImportSyncInterval,
|
||||
ListSyncLevel = model.ListSyncLevel,
|
||||
ImportExclusions = model.ImportExclusions,
|
||||
TraktAuthToken = model.TraktAuthToken,
|
||||
TraktRefreshToken = model.TraktRefreshToken,
|
||||
TraktTokenExpiry = model.TraktTokenExpiry,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||
|
||||
private void DeleteEpisodeFile(int id)
|
||||
{
|
||||
var episodeFile = _mediaFileService.Get(id);
|
||||
var episodeFile = _mediaFileService.Get(id);
|
||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||
|
||||
|
||||
@@ -66,13 +66,9 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
||||
private Response LogError(NancyContext context, Exception exception)
|
||||
{
|
||||
var response = _errorPipeline.HandleException(context, exception);
|
||||
|
||||
context.Response = response;
|
||||
|
||||
LogEnd(context);
|
||||
|
||||
context.Response = null;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -80,12 +76,9 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
||||
{
|
||||
if (request.Url.Query.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return string.Concat(request.Url.Path, "?", request.Url.Query);
|
||||
}
|
||||
else
|
||||
{
|
||||
return request.Url.Path;
|
||||
return string.Concat(request.Url.Path, request.Url.Query);
|
||||
}
|
||||
return request.Url.Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Series;
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
@@ -32,16 +30,8 @@ namespace NzbDrone.Api.History
|
||||
protected HistoryResource MapToResource(Core.History.History model)
|
||||
{
|
||||
var resource = model.ToResource();
|
||||
|
||||
resource.Series = model.Series.ToResource();
|
||||
resource.Episode = model.Episode.ToResource();
|
||||
resource.Movie = model.Movie.ToResource();
|
||||
|
||||
if (model.Series != null)
|
||||
{
|
||||
resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(model.Series.Profile.Value, model.Quality);
|
||||
}
|
||||
|
||||
if (model.Movie != null)
|
||||
{
|
||||
resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(model.Movie.Profile.Value, model.Quality);
|
||||
@@ -52,8 +42,6 @@ namespace NzbDrone.Api.History
|
||||
|
||||
private PagingResource<HistoryResource> GetHistory(PagingResource<HistoryResource> pagingResource)
|
||||
{
|
||||
var episodeId = Request.Query.EpisodeId;
|
||||
|
||||
var movieId = Request.Query.MovieId;
|
||||
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, Core.History.History>("date", SortDirection.Descending);
|
||||
@@ -64,12 +52,6 @@ namespace NzbDrone.Api.History
|
||||
pagingSpec.FilterExpression = v => v.EventType == filterValue;
|
||||
}
|
||||
|
||||
if (episodeId.HasValue)
|
||||
{
|
||||
int i = (int)episodeId;
|
||||
pagingSpec.FilterExpression = h => h.EpisodeId == i;
|
||||
}
|
||||
|
||||
if (movieId.HasValue)
|
||||
{
|
||||
int i = (int)movieId;
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace NzbDrone.Api.Indexers
|
||||
|
||||
release.ReleaseWeight = initialWeight;
|
||||
|
||||
if (decision.RemoteEpisode.Series != null)
|
||||
if (decision.RemoteMovie.Movie != null)
|
||||
{
|
||||
release.QualityWeight = decision.RemoteEpisode.Series
|
||||
release.QualityWeight = decision.RemoteMovie.Movie
|
||||
.Profile.Value
|
||||
.Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace NzbDrone.Api.Indexers
|
||||
public bool DownloadAllowed { get; set; }
|
||||
public int ReleaseWeight { get; set; }
|
||||
|
||||
public IEnumerable<string> IndexerFlags { get; set; }
|
||||
|
||||
public string MagnetUrl { get; set; }
|
||||
public string InfoHash { get; set; }
|
||||
@@ -132,7 +133,7 @@ namespace NzbDrone.Api.Indexers
|
||||
Seeders = torrentInfo.Seeders,
|
||||
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
|
||||
Protocol = releaseInfo.DownloadProtocol,
|
||||
|
||||
IndexerFlags = torrentInfo.IndexerFlags.ToString().Split(new string[] { ", " }, StringSplitOptions.None),
|
||||
Edition = parsedMovieInfo.Edition,
|
||||
|
||||
IsDaily = false,
|
||||
|
||||
175
src/NzbDrone.Api/Movies/MovieBulkImportModule.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using NzbDrone.Core.Parser;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using Marr.Data;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||
using NzbDrone.Core.RootFolders;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.Movie
|
||||
{
|
||||
|
||||
public class UnmappedComparer : IComparer<UnmappedFolder>
|
||||
{
|
||||
public int Compare(UnmappedFolder a, UnmappedFolder b)
|
||||
{
|
||||
return a.Name.CompareTo(b.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public class MovieBulkImportModule : NzbDroneRestModule<MovieResource>
|
||||
{
|
||||
private readonly ISearchForNewMovie _searchProxy;
|
||||
private readonly IRootFolderService _rootFolderService;
|
||||
private readonly IMakeImportDecision _importDecisionMaker;
|
||||
private readonly IDiskScanService _diskScanService;
|
||||
private readonly ICached<Core.Tv.Movie> _mappedMovies;
|
||||
private readonly IMovieService _movieService;
|
||||
|
||||
public MovieBulkImportModule(ISearchForNewMovie searchProxy, IRootFolderService rootFolderService, IMakeImportDecision importDecisionMaker,
|
||||
IDiskScanService diskScanService, ICacheManager cacheManager, IMovieService movieService)
|
||||
: base("/movies/bulkimport")
|
||||
{
|
||||
_searchProxy = searchProxy;
|
||||
_rootFolderService = rootFolderService;
|
||||
_importDecisionMaker = importDecisionMaker;
|
||||
_diskScanService = diskScanService;
|
||||
_mappedMovies = cacheManager.GetCache<Core.Tv.Movie>(GetType(), "mappedMoviesCache");
|
||||
_movieService = movieService;
|
||||
Get["/"] = x => Search();
|
||||
}
|
||||
|
||||
|
||||
private Response Search()
|
||||
{
|
||||
if (Request.Query.Id == 0)
|
||||
{
|
||||
//Todo error handling
|
||||
}
|
||||
|
||||
RootFolder rootFolder = _rootFolderService.Get(Request.Query.Id);
|
||||
|
||||
int page = Request.Query.page;
|
||||
int per_page = Request.Query.per_page;
|
||||
|
||||
int min = (page - 1) * per_page;
|
||||
|
||||
int max = page * per_page;
|
||||
|
||||
var unmapped = rootFolder.UnmappedFolders.OrderBy(f => f.Name).ToList();
|
||||
|
||||
int total_count = unmapped.Count;
|
||||
|
||||
if (Request.Query.total_entries.HasValue)
|
||||
{
|
||||
total_count = Request.Query.total_entries;
|
||||
}
|
||||
|
||||
max = total_count >= max ? max : total_count;
|
||||
|
||||
var paged = unmapped.GetRange(min, max-min);
|
||||
|
||||
var mapped = paged.Select(f =>
|
||||
{
|
||||
Core.Tv.Movie m = null;
|
||||
|
||||
var mappedMovie = _mappedMovies.Find(f.Name);
|
||||
|
||||
if (mappedMovie != null)
|
||||
{
|
||||
return mappedMovie;
|
||||
}
|
||||
|
||||
var parsedTitle = Parser.ParseMoviePath(f.Name);
|
||||
if (parsedTitle == null)
|
||||
{
|
||||
m = new Core.Tv.Movie
|
||||
{
|
||||
Title = f.Name.Replace(".", " ").Replace("-", " "),
|
||||
Path = f.Path,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
m = new Core.Tv.Movie
|
||||
{
|
||||
Title = parsedTitle.MovieTitle,
|
||||
Year = parsedTitle.Year,
|
||||
ImdbId = parsedTitle.ImdbId,
|
||||
Path = f.Path
|
||||
};
|
||||
}
|
||||
|
||||
var files = _diskScanService.GetVideoFiles(f.Path);
|
||||
|
||||
var decisions = _importDecisionMaker.GetImportDecisions(files.ToList(), m, true);
|
||||
|
||||
var decision = decisions.Where(d => d.Approved && !d.Rejections.Any()).FirstOrDefault();
|
||||
|
||||
if (decision != null)
|
||||
{
|
||||
var local = decision.LocalMovie;
|
||||
|
||||
m.MovieFile = new LazyLoaded<MovieFile>(new MovieFile
|
||||
{
|
||||
Path = local.Path,
|
||||
Edition = local.ParsedMovieInfo.Edition,
|
||||
Quality = local.Quality,
|
||||
MediaInfo = local.MediaInfo,
|
||||
ReleaseGroup = local.ParsedMovieInfo.ReleaseGroup,
|
||||
RelativePath = f.Path.GetRelativePath(local.Path)
|
||||
});
|
||||
}
|
||||
|
||||
mappedMovie = _searchProxy.MapMovieToTmdbMovie(m);
|
||||
|
||||
if (mappedMovie != null)
|
||||
{
|
||||
mappedMovie.Monitored = true;
|
||||
|
||||
_mappedMovies.Set(f.Name, mappedMovie, TimeSpan.FromDays(2));
|
||||
|
||||
return mappedMovie;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
return new PagingResource<MovieResource>
|
||||
{
|
||||
Page = page,
|
||||
PageSize = per_page,
|
||||
SortDirection = SortDirection.Ascending,
|
||||
SortKey = Request.Query.sort_by,
|
||||
TotalRecords = total_count - mapped.Where(m => m == null).Count(),
|
||||
Records = MapToResource(mapped.Where(m => m != null)).ToList()
|
||||
}.AsResponse();
|
||||
}
|
||||
|
||||
|
||||
private static IEnumerable<MovieResource> MapToResource(IEnumerable<Core.Tv.Movie> movies)
|
||||
{
|
||||
foreach (var currentMovie in movies)
|
||||
{
|
||||
var resource = currentMovie.ToResource();
|
||||
var poster = currentMovie.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster);
|
||||
if (poster != null)
|
||||
{
|
||||
resource.RemotePoster = poster.Url;
|
||||
}
|
||||
|
||||
yield return resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,77 +13,60 @@ using NzbDrone.SignalR;
|
||||
|
||||
namespace NzbDrone.Api.EpisodeFiles
|
||||
{
|
||||
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>
|
||||
//IHandle<EpisodeFileAddedEvent>
|
||||
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>, IHandle<MovieFileAddedEvent>
|
||||
{
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||
private readonly IMovieService _seriesService;
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MovieFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IMediaFileService mediaFileService,
|
||||
IRecycleBinProvider recycleBinProvider,
|
||||
IMovieService seriesService,
|
||||
IMovieService movieService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
Logger logger)
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_mediaFileService = mediaFileService;
|
||||
_recycleBinProvider = recycleBinProvider;
|
||||
_seriesService = seriesService;
|
||||
_movieService = movieService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
_logger = logger;
|
||||
/*GetResourceById = GetEpisodeFile;
|
||||
GetResourceAll = GetEpisodeFiles;
|
||||
UpdateResource = SetQuality;*/
|
||||
DeleteResource = DeleteEpisodeFile;
|
||||
GetResourceById = GetMovieFile;
|
||||
UpdateResource = SetQuality;
|
||||
DeleteResource = DeleteMovieFile;
|
||||
}
|
||||
|
||||
/*private EpisodeFileResource GetEpisodeFile(int id)
|
||||
private MovieFileResource GetMovieFile(int id)
|
||||
{
|
||||
var episodeFile = _mediaFileService.Get(id);
|
||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||
var movie = _mediaFileService.GetMovie(id);
|
||||
|
||||
return episodeFile.ToResource(series, _qualityUpgradableSpecification);
|
||||
return movie.ToResource();
|
||||
}
|
||||
|
||||
private List<EpisodeFileResource> GetEpisodeFiles()
|
||||
private void SetQuality(MovieFileResource movieFileResource)
|
||||
{
|
||||
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));
|
||||
var movieFile = _mediaFileService.GetMovie(movieFileResource.Id);
|
||||
movieFile.Quality = movieFileResource.Quality;
|
||||
_mediaFileService.Update(movieFile);
|
||||
}
|
||||
|
||||
private void SetQuality(EpisodeFileResource episodeFileResource)
|
||||
private void DeleteMovieFile(int id)
|
||||
{
|
||||
var episodeFile = _mediaFileService.Get(episodeFileResource.Id);
|
||||
episodeFile.Quality = episodeFileResource.Quality;
|
||||
_mediaFileService.Update(episodeFile);
|
||||
}*/
|
||||
var movieFile = _mediaFileService.GetMovie(id);
|
||||
var movie = _movieService.GetMovie(movieFile.MovieId);
|
||||
var fullPath = Path.Combine(movie.Path, movieFile.RelativePath);
|
||||
|
||||
private void DeleteEpisodeFile(int id)
|
||||
{
|
||||
var episodeFile = _mediaFileService.GetMovie(id);
|
||||
var series = _seriesService.GetMovie(episodeFile.MovieId);
|
||||
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||
|
||||
_logger.Info("Deleting episode file: {0}", fullPath);
|
||||
_logger.Info("Deleting movie file: {0}", fullPath);
|
||||
_recycleBinProvider.DeleteFile(fullPath);
|
||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
||||
_mediaFileService.Delete(movieFile, DeleteMediaFileReason.Manual);
|
||||
}
|
||||
|
||||
public void Handle(EpisodeFileAddedEvent message)
|
||||
public void Handle(MovieFileAddedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
||||
BroadcastResourceChange(ModelAction.Updated, message.MovieFile.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
src/NzbDrone.Api/Movies/MovieModuleWithSignalR.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using NzbDrone.Api.Movie;
|
||||
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.Movies
|
||||
{
|
||||
public abstract class MovieModuleWithSignalR : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
|
||||
IHandle<MovieGrabbedEvent>,
|
||||
IHandle<MovieDownloadedEvent>
|
||||
{
|
||||
protected readonly IMovieService _movieService;
|
||||
protected readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
|
||||
protected MovieModuleWithSignalR(IMovieService movieService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_movieService = movieService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
|
||||
GetResourceById = GetMovie;
|
||||
}
|
||||
|
||||
protected MovieModuleWithSignalR(IMovieService movieService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster,
|
||||
string resource)
|
||||
: base(signalRBroadcaster, resource)
|
||||
{
|
||||
_movieService = movieService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
|
||||
GetResourceById = GetMovie;
|
||||
}
|
||||
|
||||
protected MovieResource GetMovie(int id)
|
||||
{
|
||||
var movie = _movieService.GetMovie(id);
|
||||
var resource = MapToResource(movie, true);
|
||||
return resource;
|
||||
}
|
||||
|
||||
protected MovieResource MapToResource(Core.Tv.Movie episode, bool includeSeries)
|
||||
{
|
||||
var resource = episode.ToResource();
|
||||
|
||||
if (includeSeries)
|
||||
{
|
||||
var series = episode ?? _movieService.GetMovie(episode.Id);
|
||||
resource = series.ToResource();
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void Handle(MovieGrabbedEvent message)
|
||||
{
|
||||
var resource = message.Movie.Movie.ToResource();
|
||||
|
||||
//add a grabbed field in MovieResource?
|
||||
//resource.Grabbed = true;
|
||||
|
||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||
}
|
||||
|
||||
public void Handle(MovieDownloadedEvent message)
|
||||
{
|
||||
var resource = message.Movie.Movie.ToResource();
|
||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
src/NzbDrone.Api/NetImport/ListImportModule.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using Nancy.Extensions;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.NetImport
|
||||
{
|
||||
public class ListImportModule : NzbDroneApiModule
|
||||
{
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly ISearchForNewMovie _movieSearch;
|
||||
|
||||
public ListImportModule(IMovieService movieService, ISearchForNewMovie movieSearch)
|
||||
: base("/movie/import")
|
||||
{
|
||||
_movieService = movieService;
|
||||
_movieSearch = movieSearch;
|
||||
Put["/"] = Movie => SaveAll();
|
||||
}
|
||||
|
||||
private Response SaveAll()
|
||||
{
|
||||
var resources = Request.Body.FromJson<List<MovieResource>>();
|
||||
|
||||
var Movies = resources.Select(MovieResource => _movieSearch.MapMovieToTmdbMovie(MovieResource.ToModel())).Where(m => m != null).DistinctBy(m => m.TmdbId).ToList();
|
||||
|
||||
return _movieService.AddMovies(Movies).ToResource().AsResponse(HttpStatusCode.Accepted);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/NzbDrone.Api/NetImport/NetImportModule.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using FluentValidation;
|
||||
using NzbDrone.Api.ClientSchema;
|
||||
using NzbDrone.Core.NetImport;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
|
||||
namespace NzbDrone.Api.NetImport
|
||||
{
|
||||
public class NetImportModule : ProviderModuleBase<NetImportResource, INetImport, NetImportDefinition>
|
||||
{
|
||||
public NetImportModule(NetImportFactory netImportFactory) : base(netImportFactory, "netimport")
|
||||
{
|
||||
PostValidator.RuleFor(c => c.RootFolderPath).NotNull();
|
||||
PostValidator.RuleFor(c => c.MinimumAvailability).NotNull();
|
||||
PostValidator.RuleFor(c => c.ProfileId).NotNull();
|
||||
}
|
||||
|
||||
protected override void MapToResource(NetImportResource resource, NetImportDefinition definition)
|
||||
{
|
||||
base.MapToResource(resource, definition);
|
||||
|
||||
resource.Enabled = definition.Enabled;
|
||||
resource.EnableAuto = definition.EnableAuto;
|
||||
resource.ProfileId = definition.ProfileId;
|
||||
resource.RootFolderPath = definition.RootFolderPath;
|
||||
resource.ShouldMonitor = definition.ShouldMonitor;
|
||||
resource.MinimumAvailability = definition.MinimumAvailability;
|
||||
}
|
||||
|
||||
protected override void MapToModel(NetImportDefinition definition, NetImportResource resource)
|
||||
{
|
||||
base.MapToModel(definition, resource);
|
||||
|
||||
definition.Enabled = resource.Enabled;
|
||||
definition.EnableAuto = resource.EnableAuto;
|
||||
definition.ProfileId = resource.ProfileId;
|
||||
definition.RootFolderPath = resource.RootFolderPath;
|
||||
definition.ShouldMonitor = resource.ShouldMonitor;
|
||||
definition.MinimumAvailability = resource.MinimumAvailability;
|
||||
}
|
||||
|
||||
protected override void Validate(NetImportDefinition definition, bool includeWarnings)
|
||||
{
|
||||
if (!definition.Enable) return;
|
||||
base.Validate(definition, includeWarnings);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/NzbDrone.Api/NetImport/NetImportResource.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using NzbDrone.Core.NetImport;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.NetImport
|
||||
{
|
||||
public class NetImportResource : ProviderResource
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public bool EnableAuto { get; set; }
|
||||
public bool ShouldMonitor { get; set; }
|
||||
public string RootFolderPath { get; set; }
|
||||
public int ProfileId { get; set; }
|
||||
public MovieStatusType MinimumAvailability { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,8 @@
|
||||
<Compile Include="ClientSchema\SelectOption.cs" />
|
||||
<Compile Include="Commands\CommandModule.cs" />
|
||||
<Compile Include="Commands\CommandResource.cs" />
|
||||
<Compile Include="Config\NetImportConfigModule.cs" />
|
||||
<Compile Include="Config\NetImportConfigResource.cs" />
|
||||
<Compile Include="Extensions\AccessControlHeaders.cs" />
|
||||
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
|
||||
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
|
||||
@@ -116,11 +118,16 @@
|
||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
||||
<Compile Include="Indexers\ReleasePushModule.cs" />
|
||||
<Compile Include="Movies\MovieModuleWithSignalR.cs" />
|
||||
<Compile Include="Movies\MovieBulkImportModule.cs" />
|
||||
<Compile Include="Movies\MovieFileModule.cs" />
|
||||
<Compile Include="Movies\MovieModule.cs" />
|
||||
<Compile Include="Series\MovieModule.cs" />
|
||||
<Compile Include="Movies\RenameMovieModule.cs" />
|
||||
<Compile Include="Movies\RenameMovieResource.cs" />
|
||||
<Compile Include="Movies\MovieEditorModule.cs" />
|
||||
<Compile Include="NetImport\ListImportModule.cs" />
|
||||
<Compile Include="NetImport\NetImportModule.cs" />
|
||||
<Compile Include="NetImport\NetImportResource.cs" />
|
||||
<Compile Include="Parse\ParseModule.cs" />
|
||||
<Compile Include="Parse\ParseResource.cs" />
|
||||
<Compile Include="ManualImport\ManualImportModule.cs" />
|
||||
@@ -234,12 +241,12 @@
|
||||
<Compile Include="SeasonPass\SeasonPassResource.cs" />
|
||||
<Compile Include="Series\AlternateTitleResource.cs" />
|
||||
<Compile Include="Series\MovieFileResource.cs" />
|
||||
<Compile Include="Series\FetchMovieListModule.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\MovieModule.cs" />
|
||||
<Compile Include="Series\SeriesModule.cs" />
|
||||
<Compile Include="Series\MovieResource.cs" />
|
||||
<Compile Include="Series\SeriesResource.cs" />
|
||||
@@ -254,12 +261,14 @@
|
||||
<Compile Include="TinyIoCNancyBootstrapper.cs" />
|
||||
<Compile Include="Update\UpdateModule.cs" />
|
||||
<Compile Include="Update\UpdateResource.cs" />
|
||||
<Compile Include="Validation\NetImportSyncIntervalValidator.cs" />
|
||||
<Compile Include="Validation\RssSyncIntervalValidator.cs" />
|
||||
<Compile Include="Validation\EmptyCollectionValidator.cs" />
|
||||
<Compile Include="Validation\RuleBuilderExtensions.cs" />
|
||||
<Compile Include="Wanted\CutoffModule.cs" />
|
||||
<Compile Include="Wanted\LegacyMissingModule.cs" />
|
||||
<Compile Include="Wanted\MissingModule.cs" />
|
||||
<Compile Include="Wanted\MovieCutoffModule.cs" />
|
||||
<Compile Include="Wanted\MovieMissingModule.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -288,11 +297,11 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Api
|
||||
@@ -11,6 +13,7 @@ namespace NzbDrone.Api
|
||||
public SortDirection SortDirection { get; set; }
|
||||
public string FilterKey { get; set; }
|
||||
public string FilterValue { get; set; }
|
||||
public string FilterType { get; set; }
|
||||
public int TotalRecords { get; set; }
|
||||
public List<TResource> Records { get; set; }
|
||||
}
|
||||
@@ -38,5 +41,14 @@ namespace NzbDrone.Api
|
||||
|
||||
return pagingSpec;
|
||||
}
|
||||
|
||||
/*public static Expression<Func<TModel, object>> CreateFilterExpression<TModel>(string filterKey, string filterValue)
|
||||
{
|
||||
Type type = typeof(TModel);
|
||||
ParameterExpression parameterExpression = Expression.Parameter(type, "x");
|
||||
Expression expressionBody = parameterExpression;
|
||||
|
||||
return expressionBody;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace NzbDrone.Api.Profiles
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public Quality Cutoff { get; set; }
|
||||
public string PreferredTags { get; set; }
|
||||
public List<ProfileQualityItemResource> Items { get; set; }
|
||||
public Language Language { get; set; }
|
||||
}
|
||||
@@ -33,6 +34,7 @@ namespace NzbDrone.Api.Profiles
|
||||
|
||||
Name = model.Name,
|
||||
Cutoff = model.Cutoff,
|
||||
PreferredTags = model.PreferredTags != null ? string.Join(",", model.PreferredTags) : "",
|
||||
Items = model.Items.ConvertAll(ToResource),
|
||||
Language = model.Language
|
||||
};
|
||||
@@ -59,6 +61,7 @@ namespace NzbDrone.Api.Profiles
|
||||
|
||||
Name = resource.Name,
|
||||
Cutoff = (Quality)resource.Cutoff.Id,
|
||||
PreferredTags = resource.PreferredTags.Split(',').ToList(),
|
||||
Items = resource.Items.ConvertAll(ToModel),
|
||||
Language = resource.Language
|
||||
};
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Api
|
||||
|
||||
resource.Fields = SchemaBuilder.ToSchema(definition.Settings);
|
||||
|
||||
resource.InfoLink = string.Format("https://github.com/Sonarr/Sonarr/wiki/Supported-{0}#{1}",
|
||||
resource.InfoLink = string.Format("https://github.com/Radarr/Radarr/wiki/Supported-{0}#{1}",
|
||||
typeof(TProviderResource).Name.Replace("Resource", "s"),
|
||||
definition.Implementation.ToLower());
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace NzbDrone.Api.Queue
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
_downloadService.DownloadReport(pendingRelease.RemoteEpisode);
|
||||
_downloadService.DownloadReport(pendingRelease.RemoteMovie);
|
||||
|
||||
return resource.AsResponse();
|
||||
}
|
||||
|
||||
@@ -123,7 +123,13 @@ namespace NzbDrone.Api.REST
|
||||
|
||||
Get[ROOT_ROUTE] = options =>
|
||||
{
|
||||
var resource = GetResourcePaged(ReadPagingResourceFromRequest());
|
||||
var pagingSpec = ReadPagingResourceFromRequest();
|
||||
if (pagingSpec.Page == 0 && pagingSpec.PageSize == 0)
|
||||
{
|
||||
var all = GetResourceAll();
|
||||
return all.AsResponse();
|
||||
}
|
||||
var resource = GetResourcePaged(pagingSpec);
|
||||
return resource.AsResponse();
|
||||
};
|
||||
}
|
||||
@@ -214,12 +220,10 @@ namespace NzbDrone.Api.REST
|
||||
private PagingResource<TResource> ReadPagingResourceFromRequest()
|
||||
{
|
||||
int pageSize;
|
||||
int.TryParse(Request.Query.PageSize.ToString(), out pageSize);
|
||||
if (pageSize == 0) pageSize = 10;
|
||||
int.TryParse(Request.Query.PageSize.ToString(), out pageSize);
|
||||
|
||||
int page;
|
||||
int.TryParse(Request.Query.Page.ToString(), out page);
|
||||
if (page == 0) page = 1;
|
||||
|
||||
|
||||
var pagingResource = new PagingResource<TResource>
|
||||
@@ -249,9 +253,16 @@ namespace NzbDrone.Api.REST
|
||||
{
|
||||
pagingResource.FilterValue = Request.Query.FilterValue.ToString();
|
||||
}
|
||||
|
||||
if (Request.Query.FilterType != null)
|
||||
{
|
||||
pagingResource.FilterType = Request.Query.FilterType.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return pagingResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ namespace NzbDrone.Api.RootFolders
|
||||
Id = resource.Id,
|
||||
|
||||
Path = resource.Path,
|
||||
//FreeSpace
|
||||
//UnmappedFolders
|
||||
FreeSpace = resource.FreeSpace,
|
||||
UnmappedFolders = resource.UnmappedFolders
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
60
src/NzbDrone.Api/Series/FetchMovieListModule.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.NetImport;
|
||||
|
||||
namespace NzbDrone.Api.Movie
|
||||
{
|
||||
public class FetchMovieListModule : NzbDroneRestModule<MovieResource>
|
||||
{
|
||||
private readonly IFetchNetImport _fetchNetImport;
|
||||
private readonly ISearchForNewMovie _movieSearch;
|
||||
|
||||
public FetchMovieListModule(IFetchNetImport netImport, ISearchForNewMovie movieSearch)
|
||||
: base("/netimport/movies")
|
||||
{
|
||||
_fetchNetImport = netImport;
|
||||
_movieSearch = movieSearch;
|
||||
Get["/"] = x => Search();
|
||||
}
|
||||
|
||||
|
||||
private Response Search()
|
||||
{
|
||||
var results = _fetchNetImport.FetchAndFilter((int) Request.Query.listId, false);
|
||||
|
||||
List<Core.Tv.Movie> realResults = new List<Core.Tv.Movie>();
|
||||
|
||||
/*foreach (var movie in results)
|
||||
{
|
||||
var mapped = _movieSearch.MapMovieToTmdbMovie(movie);
|
||||
|
||||
if (mapped != null)
|
||||
{
|
||||
realResults.Add(mapped);
|
||||
}
|
||||
}*/
|
||||
|
||||
return MapToResource(results).AsResponse();
|
||||
}
|
||||
|
||||
|
||||
private static IEnumerable<MovieResource> MapToResource(IEnumerable<Core.Tv.Movie> movies)
|
||||
{
|
||||
foreach (var currentSeries in movies)
|
||||
{
|
||||
var resource = currentSeries.ToResource();
|
||||
var poster = currentSeries.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster);
|
||||
if (poster != null)
|
||||
{
|
||||
resource.RemotePoster = poster.Url;
|
||||
}
|
||||
|
||||
yield return resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,44 @@ using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using NzbDrone.Api.REST;
|
||||
|
||||
namespace NzbDrone.Api.Movie
|
||||
{
|
||||
public class MovieLookupModule : NzbDroneRestModule<MovieResource>
|
||||
{
|
||||
private readonly ISearchForNewMovie _searchProxy;
|
||||
private readonly IProvideMovieInfo _movieInfo;
|
||||
|
||||
public MovieLookupModule(ISearchForNewMovie searchProxy)
|
||||
public MovieLookupModule(ISearchForNewMovie searchProxy, IProvideMovieInfo movieInfo)
|
||||
: base("/movies/lookup")
|
||||
{
|
||||
_movieInfo = movieInfo;
|
||||
_searchProxy = searchProxy;
|
||||
Get["/"] = x => Search();
|
||||
Get["/tmdb"] = x => SearchByTmdbId();
|
||||
Get["/imdb"] = x => SearchByImdbId();
|
||||
}
|
||||
|
||||
private Response SearchByTmdbId()
|
||||
{
|
||||
int tmdbId = -1;
|
||||
if(Int32.TryParse(Request.Query.tmdbId, out tmdbId))
|
||||
{
|
||||
var result = _movieInfo.GetMovieInfo(tmdbId, null, true);
|
||||
return result.ToResource().AsResponse();
|
||||
}
|
||||
|
||||
throw new BadRequestException("Tmdb Id was not valid");
|
||||
}
|
||||
|
||||
private Response SearchByImdbId()
|
||||
{
|
||||
string imdbId = Request.Query.imdbId;
|
||||
var result = _movieInfo.GetMovieInfo(imdbId);
|
||||
return result.ToResource().AsResponse();
|
||||
}
|
||||
|
||||
private Response Search()
|
||||
{
|
||||
@@ -25,7 +49,6 @@ namespace NzbDrone.Api.Movie
|
||||
return MapToResource(imdbResults).AsResponse();
|
||||
}
|
||||
|
||||
|
||||
private static IEnumerable<MovieResource> MapToResource(IEnumerable<Core.Tv.Movie> movies)
|
||||
{
|
||||
foreach (var currentSeries in movies)
|
||||
|
||||
@@ -3,6 +3,7 @@ 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;
|
||||
@@ -15,6 +16,7 @@ using NzbDrone.Core.Validation.Paths;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.SignalR;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Api.Movie
|
||||
{
|
||||
@@ -32,6 +34,8 @@ namespace NzbDrone.Api.Movie
|
||||
private readonly IMovieStatisticsService _moviesStatisticsService;
|
||||
private readonly IMapCoversToLocal _coverMapper;
|
||||
|
||||
private const string TITLE_SLUG_ROUTE = "/titleslug/(?<slug>[^/]+)";
|
||||
|
||||
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IMovieService moviesService,
|
||||
IMovieStatisticsService moviesStatisticsService,
|
||||
@@ -52,7 +56,11 @@ namespace NzbDrone.Api.Movie
|
||||
_coverMapper = coverMapper;
|
||||
|
||||
GetResourceAll = AllMovie;
|
||||
GetResourcePaged = GetMoviePaged;
|
||||
GetResourceById = GetMovie;
|
||||
Get[TITLE_SLUG_ROUTE] = (options) => {
|
||||
return ReqResExtensions.AsResponse(GetByTitleSlug(options.slug));
|
||||
};
|
||||
CreateResource = AddMovie;
|
||||
UpdateResource = UpdateMovie;
|
||||
DeleteResource = DeleteMovie;
|
||||
@@ -104,6 +112,15 @@ namespace NzbDrone.Api.Movie
|
||||
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;
|
||||
@@ -128,6 +145,11 @@ namespace NzbDrone.Api.Movie
|
||||
return moviesResources;
|
||||
}
|
||||
|
||||
private MovieResource GetByTitleSlug(string slug)
|
||||
{
|
||||
return MapToResource(_moviesService.FindByTitleSlug(slug));
|
||||
}
|
||||
|
||||
private int AddMovie(MovieResource moviesResource)
|
||||
{
|
||||
var model = moviesResource.ToModel();
|
||||
@@ -147,14 +169,20 @@ namespace NzbDrone.Api.Movie
|
||||
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);
|
||||
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
|
||||
}
|
||||
|
||||
private void MapCoversToLocal(params MovieResource[] movies)
|
||||
@@ -185,7 +213,7 @@ namespace NzbDrone.Api.Movie
|
||||
|
||||
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
|
||||
{
|
||||
resource.SizeOnDisk = moviesStatistics.SizeOnDisk;
|
||||
//resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk;
|
||||
}
|
||||
|
||||
private void PopulateAlternateTitles(List<MovieResource> resources)
|
||||
|
||||
@@ -43,6 +43,10 @@ namespace NzbDrone.Api.Movie
|
||||
|
||||
//Editing Only
|
||||
public bool Monitored { get; set; }
|
||||
public MovieStatusType MinimumAvailability { get; set; }
|
||||
public bool IsAvailable { get; set; }
|
||||
public string FolderName { get; set; }
|
||||
|
||||
public int Runtime { get; set; }
|
||||
public DateTime? LastInfoSync { get; set; }
|
||||
public string CleanTitle { get; set; }
|
||||
@@ -116,7 +120,7 @@ namespace NzbDrone.Api.Movie
|
||||
//TotalEpisodeCount
|
||||
//EpisodeCount
|
||||
//EpisodeFileCount
|
||||
//SizeOnDisk
|
||||
SizeOnDisk = size,
|
||||
Status = model.Status,
|
||||
Overview = model.Overview,
|
||||
//NextAiring
|
||||
@@ -129,8 +133,12 @@ namespace NzbDrone.Api.Movie
|
||||
ProfileId = model.ProfileId,
|
||||
|
||||
Monitored = model.Monitored,
|
||||
MinimumAvailability = model.MinimumAvailability,
|
||||
|
||||
IsAvailable = model.IsAvailable(),
|
||||
FolderName = model.FolderName(),
|
||||
|
||||
SizeOnDisk = size,
|
||||
//SizeOnDisk = size,
|
||||
|
||||
Runtime = model.Runtime,
|
||||
LastInfoSync = model.LastInfoSync,
|
||||
@@ -181,7 +189,8 @@ namespace NzbDrone.Api.Movie
|
||||
ProfileId = resource.ProfileId,
|
||||
|
||||
Monitored = resource.Monitored,
|
||||
|
||||
MinimumAvailability = resource.MinimumAvailability,
|
||||
|
||||
Runtime = resource.Runtime,
|
||||
LastInfoSync = resource.LastInfoSync,
|
||||
CleanTitle = resource.CleanTitle,
|
||||
@@ -210,7 +219,8 @@ namespace NzbDrone.Api.Movie
|
||||
movie.ProfileId = resource.ProfileId;
|
||||
|
||||
movie.Monitored = resource.Monitored;
|
||||
|
||||
movie.MinimumAvailability = resource.MinimumAvailability;
|
||||
|
||||
movie.RootFolderPath = resource.RootFolderPath;
|
||||
movie.Tags = resource.Tags;
|
||||
movie.AddOptions = resource.AddOptions;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using FluentValidation.Validators;
|
||||
|
||||
namespace NzbDrone.Api.Validation
|
||||
{
|
||||
public class NetImportSyncIntervalValidator : PropertyValidator
|
||||
{
|
||||
public NetImportSyncIntervalValidator()
|
||||
: base("Must be between 10 and 1440 or 0 to disable")
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool IsValid(PropertyValidatorContext context)
|
||||
{
|
||||
if (context.PropertyValue == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var value = (int)context.PropertyValue;
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value >= 10 && value <= 1440)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace NzbDrone.Api.Validation
|
||||
public class RssSyncIntervalValidator : PropertyValidator
|
||||
{
|
||||
public RssSyncIntervalValidator()
|
||||
: base("Must be between 10 and 120 or 0 to disable")
|
||||
: base("Must be between 10 and 720 or 0 to disable")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace NzbDrone.Api.Validation
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value >= 10 && value <= 120)
|
||||
if (value >= 10 && value <= 720)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,5 +36,10 @@ namespace NzbDrone.Api.Validation
|
||||
{
|
||||
return ruleBuilder.SetValidator(new RssSyncIntervalValidator());
|
||||
}
|
||||
|
||||
public static IRuleBuilderOptions<T, int> IsValidNetImportSyncInterval<T>(this IRuleBuilder<T, int> ruleBuilder)
|
||||
{
|
||||
return ruleBuilder.SetValidator(new NetImportSyncIntervalValidator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Api.Wanted
|
||||
ISeriesService seriesService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff")
|
||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff-old")
|
||||
{
|
||||
_episodeCutoffService = episodeCutoffService;
|
||||
GetResourcePaged = GetCutoffUnmetEpisodes;
|
||||
|
||||
35
src/NzbDrone.Api/Wanted/MovieCutoffModule.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Api.Movies;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.SignalR;
|
||||
|
||||
namespace NzbDrone.Api.Wanted
|
||||
{
|
||||
public class MovieCutoffModule : MovieModuleWithSignalR
|
||||
{
|
||||
private readonly IMovieCutoffService _movieCutoffService;
|
||||
|
||||
public MovieCutoffModule(IMovieCutoffService movieCutoffService,
|
||||
IMovieService movieService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(movieService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff")
|
||||
{
|
||||
_movieCutoffService = movieCutoffService;
|
||||
GetResourcePaged = GetCutoffUnmetMovies;
|
||||
}
|
||||
|
||||
private PagingResource<MovieResource> GetCutoffUnmetMovies(PagingResource<MovieResource> pagingResource)
|
||||
{
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("title", SortDirection.Ascending);
|
||||
|
||||
pagingSpec.FilterExpression = _movieService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue);
|
||||
|
||||
var resource = ApplyToPage(_movieCutoffService.MoviesWhereCutoffUnmet, pagingSpec, v => MapToResource(v, true));
|
||||
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,14 @@ using NzbDrone.Core.Datastore.Events;
|
||||
|
||||
namespace NzbDrone.Api.Wanted
|
||||
{
|
||||
class MovieMissingModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
|
||||
IHandle<MovieGrabbedEvent>,
|
||||
IHandle<MovieDownloadedEvent>
|
||||
class MovieMissingModule : MovieModuleWithSignalR
|
||||
{
|
||||
protected readonly IMovieService _movieService;
|
||||
|
||||
public MovieMissingModule(IMovieService movieService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(signalRBroadcaster, "wanted/missing")
|
||||
: base(movieService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing")
|
||||
{
|
||||
|
||||
_movieService = movieService;
|
||||
@@ -30,48 +28,13 @@ namespace NzbDrone.Api.Wanted
|
||||
|
||||
private PagingResource<MovieResource> GetMissingMovies(PagingResource<MovieResource> pagingResource)
|
||||
{
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("physicalRelease", SortDirection.Descending);
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("title", SortDirection.Descending);
|
||||
|
||||
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
|
||||
{
|
||||
pagingSpec.FilterExpression = v => v.Monitored == false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pagingSpec.FilterExpression = v => v.Monitored == true;
|
||||
}
|
||||
pagingSpec.FilterExpression = _movieService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue);
|
||||
|
||||
var resource = ApplyToPage(_movieService.MoviesWithoutFiles, pagingSpec, v => MapToResource(v, false));
|
||||
var resource = ApplyToPage(_movieService.MoviesWithoutFiles, pagingSpec, v => MapToResource(v, true));
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
private MovieResource GetMovie(int id)
|
||||
{
|
||||
var movie = _movieService.GetMovie(id);
|
||||
var resource = MapToResource(movie, true);
|
||||
return resource;
|
||||
}
|
||||
|
||||
private MovieResource MapToResource(Core.Tv.Movie movie, bool includeMovieFile)
|
||||
{
|
||||
var resource = movie.ToResource();
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void Handle(MovieGrabbedEvent message)
|
||||
{
|
||||
var resource = message.Movie.Movie.ToResource();
|
||||
|
||||
//add a grabbed field in MovieResource?
|
||||
//resource.Grabbed = true;
|
||||
|
||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||
}
|
||||
|
||||
public void Handle(MovieDownloadedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Movie.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace NzbDrone.App.Test
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Shit appveyor")]
|
||||
public void should_return_same_instance_of_singletons()
|
||||
{
|
||||
var first = _container.ResolveAll<IHandle<ApplicationShutdownRequested>>().OfType<Scheduler>().Single();
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
public void should_be_able_to_check_space_on_ramdrive()
|
||||
{
|
||||
MonoOnly();
|
||||
Subject.GetAvailableSpace("/run/").Should().NotBe(0);
|
||||
Subject.GetAvailableSpace("/").Should().NotBe(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace NzbDrone.Common.Test.Http
|
||||
|
||||
var userAgent = response.Resource.Headers["User-Agent"].ToString();
|
||||
|
||||
userAgent.Should().Contain("Sonarr");
|
||||
userAgent.Should().Contain("Radarr");
|
||||
}
|
||||
|
||||
[TestCase("Accept", "text/xml, text/rss+xml, application/rss+xml")]
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.Http;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
@@ -36,5 +37,17 @@ namespace NzbDrone.Common.Test.Http
|
||||
Action action = () => httpheader.GetEncodingFromContentType();
|
||||
action.ShouldThrow<ArgumentException>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_cookie_with_trailing_semi_colon()
|
||||
{
|
||||
var cookies = HttpHeader.ParseCookies("uid=123456; pass=123456b2f3abcde42ac3a123f3f1fc9f;");
|
||||
|
||||
cookies.Count.Should().Be(2);
|
||||
cookies.First().Key.Should().Be("uid");
|
||||
cookies.First().Value.Should().Be("123456");
|
||||
cookies.Last().Key.Should().Be("pass");
|
||||
cookies.Last().Value.Should().Be("123456b2f3abcde42ac3a123f3f1fc9f");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace NzbDrone.Common.Test
|
||||
{
|
||||
var fakeEnvironment = new Mock<IAppFolderInfo>();
|
||||
|
||||
fakeEnvironment.SetupGet(c => c.AppDataFolder).Returns(@"C:\NzbDrone\".AsOsAgnostic());
|
||||
fakeEnvironment.SetupGet(c => c.AppDataFolder).Returns(@"C:\Radarr\".AsOsAgnostic());
|
||||
|
||||
fakeEnvironment.SetupGet(c => c.TempFolder).Returns(@"C:\Temp\".AsOsAgnostic());
|
||||
|
||||
@@ -233,43 +233,43 @@ namespace NzbDrone.Common.Test
|
||||
[Test]
|
||||
public void AppDataDirectory_path_test()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetAppDataPath().Should().BeEquivalentTo(@"C:\NzbDrone\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetAppDataPath().Should().BeEquivalentTo(@"C:\Radarr\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Config_path_test()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetConfigPath().Should().BeEquivalentTo(@"C:\NzbDrone\Config.xml".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetConfigPath().Should().BeEquivalentTo(@"C:\Radarr\Config.xml".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Sandbox()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdateSandboxFolder().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdateSandboxFolder().Should().BeEquivalentTo(@"C:\Temp\radarr_update\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUpdatePackageFolder()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdatePackageFolder().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\NzbDrone\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdatePackageFolder().Should().BeEquivalentTo(@"C:\Temp\radarr_update\Radarr\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUpdateClientFolder()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdateClientFolder().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\NzbDrone\NzbDrone.Update\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdateClientFolder().Should().BeEquivalentTo(@"C:\Temp\radarr_update\Radarr\NzbDrone.Update\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUpdateClientExePath()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdateClientExePath().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\Radarr.Update.exe".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdateClientExePath().Should().BeEquivalentTo(@"C:\Temp\radarr_update\Radarr.Update.exe".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUpdateLogFolder()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdateLogFolder().Should().BeEquivalentTo(@"C:\NzbDrone\UpdateLogs\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdateLogFolder().Should().BeEquivalentTo(@"C:\Radarr\UpdateLogs\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -9,6 +9,7 @@ using NzbDrone.Common.Model;
|
||||
using NzbDrone.Common.Processes;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Test.Dummy;
|
||||
using System.Reflection;
|
||||
|
||||
namespace NzbDrone.Common.Test
|
||||
{
|
||||
@@ -64,9 +65,18 @@ namespace NzbDrone.Common.Test
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Shit appveyor")]
|
||||
public void Should_be_able_to_start_process()
|
||||
{
|
||||
var process = Subject.Start(Path.Combine(Directory.GetCurrentDirectory(), DummyApp.DUMMY_PROCCESS_NAME + ".exe"));
|
||||
{
|
||||
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
UriBuilder uri = new UriBuilder(codeBase);
|
||||
string path = Uri.UnescapeDataString(uri.Path);
|
||||
var rPath = Path.GetDirectoryName(path);
|
||||
|
||||
var root = Directory.GetParent(rPath).Parent.Parent.Parent;
|
||||
var DummyAppDir = Path.Combine(root.FullName, "NzbDrone.Test.Dummy", "bin", "Release");
|
||||
|
||||
var process = Subject.Start(Path.Combine(DummyAppDir, DummyApp.DUMMY_PROCCESS_NAME + ".exe"));
|
||||
|
||||
Subject.Exists(DummyApp.DUMMY_PROCCESS_NAME).Should()
|
||||
.BeTrue("excepted one dummy process to be already running");
|
||||
@@ -79,6 +89,7 @@ namespace NzbDrone.Common.Test
|
||||
|
||||
|
||||
[Test]
|
||||
[Ignore("Shit appveyor")]
|
||||
public void kill_all_should_kill_all_process_with_name()
|
||||
{
|
||||
var dummy1 = StartDummyProcess();
|
||||
|
||||
@@ -100,6 +100,7 @@ namespace NzbDrone.Common.Test
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Shit appveyor")]
|
||||
public void should_throw_if_starting_a_running_serivce()
|
||||
{
|
||||
Subject.GetService(ALWAYS_INSTALLED_SERVICE).Status
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace NzbDrone.Common.Test
|
||||
}
|
||||
|
||||
[TestCase("")]
|
||||
[TestCase("http://")]
|
||||
public void DownloadString_should_throw_on_error(string url)
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => Subject.DownloadString(url));
|
||||
|
||||
@@ -9,6 +9,7 @@ using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using System.Drawing;
|
||||
|
||||
namespace NzbDrone.Common.Disk
|
||||
{
|
||||
@@ -107,6 +108,41 @@ namespace NzbDrone.Common.Disk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanUseGDIPlus()
|
||||
{
|
||||
try
|
||||
{
|
||||
GdiPlusInterop.CheckGdiPlus();
|
||||
return true;
|
||||
}
|
||||
catch (DllNotFoundException ex)
|
||||
{
|
||||
Logger.Trace(ex, "System does not have libgdiplus.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValidGDIPlusImage(string filename)
|
||||
{
|
||||
if (!CanUseGDIPlus())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (var bmp = new Bitmap(filename))
|
||||
{
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Debug(ex, "Corrupted image found at: {0}.", filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool FolderWritable(string path)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Drawing;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Core.MediaCover
|
||||
namespace NzbDrone.Common.Disk
|
||||
{
|
||||
public static class GdiPlusInterop
|
||||
{
|
||||
@@ -19,6 +19,8 @@ namespace NzbDrone.Common.Disk
|
||||
bool FolderExists(string path);
|
||||
bool FileExists(string path);
|
||||
bool FileExists(string path, StringComparison stringComparison);
|
||||
bool CanUseGDIPlus();
|
||||
bool IsValidGDIPlusImage(string path);
|
||||
bool FolderWritable(string path);
|
||||
string[] GetDirectories(string path);
|
||||
string[] GetFiles(string path, SearchOption searchOption);
|
||||
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class Base64Extentions
|
||||
public static class Base64Extensions
|
||||
{
|
||||
public static string ToBase64(this byte[] bytes)
|
||||
{
|
||||
@@ -14,4 +14,4 @@ namespace NzbDrone.Common.Extensions
|
||||
return BitConverter.GetBytes(input).ToBase64();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,11 @@ using System.Xml.Linq;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class XmlExtentions
|
||||
public static class XmlExtensions
|
||||
{
|
||||
public static IEnumerable<XElement> FindDecendants(this XContainer container, string localName)
|
||||
{
|
||||
return container.Descendants().Where(c => c.Name.LocalName.Equals(localName, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
{
|
||||
public static readonly HttpAccept Rss = new HttpAccept("application/rss+xml, text/rss+xml, application/xml, text/xml");
|
||||
public static readonly HttpAccept Json = new HttpAccept("application/json");
|
||||
public static readonly HttpAccept JsonCharset = new HttpAccept("application/json;charset=utf-8");
|
||||
public static readonly HttpAccept Html = new HttpAccept("text/html");
|
||||
|
||||
public string Value { get; private set; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
@@ -169,7 +169,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public static List<KeyValuePair<string, string>> ParseCookies(string cookies)
|
||||
{
|
||||
return cookies.Split(';')
|
||||
return cookies.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(v => v.Trim().Split('='))
|
||||
.Select(v => new KeyValuePair<string, string>(v[0], v[1]))
|
||||
.ToList();
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace NzbDrone.Common.Http
|
||||
public class JsonRpcRequestBuilder : HttpRequestBuilder
|
||||
{
|
||||
public static HttpAccept JsonRpcHttpAccept = new HttpAccept("application/json-rpc, application/json");
|
||||
public static string JsonRpcContentType = "application/json-rpc";
|
||||
public static string JsonRpcContentType = "application/json";
|
||||
|
||||
public string JsonMethod { get; private set; }
|
||||
public List<object> JsonParameters { get; private set; }
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="ICSharpCode.SharpZipLib">
|
||||
@@ -89,6 +90,7 @@
|
||||
<Compile Include="Disk\FileSystemModel.cs" />
|
||||
<Compile Include="Disk\FileSystemResult.cs" />
|
||||
<Compile Include="Extensions\DictionaryExtensions.cs" />
|
||||
<Compile Include="Disk\GdiPlusInterop.cs" />
|
||||
<Compile Include="Disk\OsPath.cs" />
|
||||
<Compile Include="Disk\DiskProviderBase.cs" />
|
||||
<Compile Include="Disk\IDiskProvider.cs" />
|
||||
@@ -145,14 +147,14 @@
|
||||
<Compile Include="Expansive\Tree.cs" />
|
||||
<Compile Include="Expansive\TreeNode.cs" />
|
||||
<Compile Include="Expansive\TreeNodeList.cs" />
|
||||
<Compile Include="Extensions\Base64Extentions.cs" />
|
||||
<Compile Include="Extensions\Base64Extensions.cs" />
|
||||
<Compile Include="Extensions\DateTimeExtensions.cs" />
|
||||
<Compile Include="Crypto\HashConverter.cs" />
|
||||
<Compile Include="Extensions\Int64Extensions.cs" />
|
||||
<Compile Include="Extensions\ObjectExtensions.cs" />
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="Extensions\UrlExtensions.cs" />
|
||||
<Compile Include="Extensions\XmlExtentions.cs" />
|
||||
<Compile Include="Extensions\XmlExtensions.cs" />
|
||||
<Compile Include="HashUtil.cs" />
|
||||
<Compile Include="Http\Dispatchers\CurlHttpDispatcher.cs" />
|
||||
<Compile Include="Http\Dispatchers\FallbackHttpDispatcher.cs" />
|
||||
@@ -257,4 +259,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -315,6 +315,7 @@ namespace NzbDrone.Common.Processes
|
||||
|
||||
var monoProcesses = Process.GetProcessesByName("mono")
|
||||
.Union(Process.GetProcessesByName("mono-sgen"))
|
||||
.Union(Process.GetProcessesByName("mono-sgen32"))
|
||||
.Where(process =>
|
||||
process.Modules.Cast<ProcessModule>()
|
||||
.Any(module =>
|
||||
|
||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 81 KiB |
@@ -20,6 +20,7 @@ namespace NzbDrone.Core.Test.Blacklisting
|
||||
_blacklist = new Blacklist
|
||||
{
|
||||
SeriesId = 12345,
|
||||
MovieId = 1234,
|
||||
EpisodeIds = new List<int> { 1 },
|
||||
Quality = new QualityModel(Quality.Bluray720p),
|
||||
SourceTitle = "series.title.s01e01",
|
||||
@@ -47,7 +48,7 @@ namespace NzbDrone.Core.Test.Blacklisting
|
||||
{
|
||||
Subject.Insert(_blacklist);
|
||||
|
||||
Subject.BlacklistedByTitle(_blacklist.SeriesId, _blacklist.SourceTitle.ToUpperInvariant()).Should().HaveCount(1);
|
||||
Subject.BlacklistedByTitle(_blacklist.MovieId, _blacklist.SourceTitle.ToUpperInvariant()).Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ namespace NzbDrone.Core.Test.Blacklisting
|
||||
{
|
||||
_event = new DownloadFailedEvent
|
||||
{
|
||||
SeriesId = 12345,
|
||||
EpisodeIds = new List<int> {1},
|
||||
SeriesId = 0,
|
||||
MovieId = 69,
|
||||
EpisodeIds = null,
|
||||
Quality = new QualityModel(Quality.Bluray720p),
|
||||
SourceTitle = "series.title.s01e01",
|
||||
DownloadClient = "SabnzbdClient",
|
||||
@@ -40,7 +41,7 @@ namespace NzbDrone.Core.Test.Blacklisting
|
||||
Subject.Handle(_event);
|
||||
|
||||
Mocker.GetMock<IBlacklistRepository>()
|
||||
.Verify(v => v.Insert(It.Is<Blacklist>(b => b.EpisodeIds == _event.EpisodeIds)), Times.Once());
|
||||
.Verify(v => v.Insert(It.Is<Blacklist>(b => b.MovieId == _event.MovieId)), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -52,7 +53,7 @@ namespace NzbDrone.Core.Test.Blacklisting
|
||||
_event.Data.Remove("protocol");
|
||||
|
||||
Mocker.GetMock<IBlacklistRepository>()
|
||||
.Verify(v => v.Insert(It.Is<Blacklist>(b => b.EpisodeIds == _event.EpisodeIds)), Times.Once());
|
||||
.Verify(v => v.Insert(It.Is<Blacklist>(b => b.MovieId == _event.MovieId)), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
75
src/NzbDrone.Core.Test/BulkImport/AddMultiMoviesFixture.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using Moq;
|
||||
using NzbDrone.Core.Organizer;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.Test.BulkImport
|
||||
{
|
||||
[TestFixture]
|
||||
public class AddMultiMoviesFixture : CoreTest<MovieService>
|
||||
{
|
||||
private List<Movie> fakeMovies;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
fakeMovies = Builder<Movie>.CreateListOfSize(3).BuildList();
|
||||
fakeMovies.ForEach(m =>
|
||||
{
|
||||
m.Path = null;
|
||||
m.RootFolderPath = @"C:\Test\TV";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void movies_added_event_should_have_proper_path()
|
||||
{
|
||||
Mocker.GetMock<IBuildFileNames>()
|
||||
.Setup(s => s.GetMovieFolder(It.IsAny<Movie>(), null))
|
||||
.Returns((Movie m, NamingConfig n) => m.Title);
|
||||
|
||||
var movies = Subject.AddMovies(fakeMovies);
|
||||
|
||||
foreach (Movie movie in movies)
|
||||
{
|
||||
movie.Path.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
//Subject.GetAllMovies().Should().HaveCount(3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void movies_added_should_ignore_already_added()
|
||||
{
|
||||
Mocker.GetMock<IBuildFileNames>()
|
||||
.Setup(s => s.GetMovieFolder(It.IsAny<Movie>(), null))
|
||||
.Returns((Movie m, NamingConfig n) => m.Title);
|
||||
|
||||
Mocker.GetMock<IMovieRepository>().Setup(s => s.All()).Returns(new List<Movie> { fakeMovies[0] });
|
||||
|
||||
var movies = Subject.AddMovies(fakeMovies);
|
||||
|
||||
Mocker.GetMock<IMovieRepository>().Verify(v => v.InsertMany(It.Is<List<Movie>>(l => l.Count == 2)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void movies_added_should_ignore_duplicates()
|
||||
{
|
||||
Mocker.GetMock<IBuildFileNames>()
|
||||
.Setup(s => s.GetMovieFolder(It.IsAny<Movie>(), null))
|
||||
.Returns((Movie m, NamingConfig n) => m.Title);
|
||||
|
||||
fakeMovies[2].TmdbId = fakeMovies[0].TmdbId;
|
||||
|
||||
var movies = Subject.AddMovies(fakeMovies);
|
||||
|
||||
Mocker.GetMock<IMovieRepository>().Verify(v => v.InsertMany(It.Is<List<Movie>>(l => l.Count == 2)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.Configuration
|
||||
[Test]
|
||||
public void Get_value_should_return_default_when_no_value()
|
||||
{
|
||||
Subject.RssSyncInterval.Should().Be(15);
|
||||
Subject.RssSyncInterval.Should().Be(60);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.Configuration
|
||||
public void get_value_with_out_persist_should_not_store_default_value()
|
||||
{
|
||||
var interval = Subject.RssSyncInterval;
|
||||
interval.Should().Be(15);
|
||||
interval.Should().Be(60);
|
||||
Mocker.GetMock<IConfigRepository>().Verify(c => c.Insert(It.IsAny<Config>()), Times.Never());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace NzbDrone.Core.Test.DataAugmentation.DailySeries
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Series")]
|
||||
public void should_get_list_of_daily_series()
|
||||
{
|
||||
var list = Subject.GetDailySeriesIds();
|
||||
|
||||
@@ -8,6 +8,7 @@ using NzbDrone.Test.Common.Categories;
|
||||
namespace NzbDrone.Core.Test.DataAugmentation.Scene
|
||||
{
|
||||
[TestFixture]
|
||||
[Ignore("Series")]
|
||||
[IntegrationTest]
|
||||
public class SceneMappingProxyFixture : CoreTest<SceneMappingProxy>
|
||||
{
|
||||
@@ -18,6 +19,7 @@ namespace NzbDrone.Core.Test.DataAugmentation.Scene
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
public void fetch_should_return_list_of_mappings()
|
||||
{
|
||||
var mappings = Subject.Fetch();
|
||||
|
||||
@@ -1,312 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DataAugmentation.Xem;
|
||||
using NzbDrone.Core.DataAugmentation.Xem.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.DataAugmentation.SceneNumbering
|
||||
{
|
||||
[TestFixture]
|
||||
public class XemServiceFixture : CoreTest<XemService>
|
||||
{
|
||||
private Series _series;
|
||||
private List<int> _theXemSeriesIds;
|
||||
private List<XemSceneTvdbMapping> _theXemTvdbMappings;
|
||||
private List<Episode> _episodes;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(v => v.TvdbId = 10)
|
||||
.With(v => v.UseSceneNumbering = false)
|
||||
.BuildNew();
|
||||
|
||||
_theXemSeriesIds = new List<int> { 120 };
|
||||
Mocker.GetMock<IXemProxy>()
|
||||
.Setup(v => v.GetXemSeriesIds())
|
||||
.Returns(_theXemSeriesIds);
|
||||
|
||||
_theXemTvdbMappings = new List<XemSceneTvdbMapping>();
|
||||
Mocker.GetMock<IXemProxy>()
|
||||
.Setup(v => v.GetSceneTvdbMappings(10))
|
||||
.Returns(_theXemTvdbMappings);
|
||||
|
||||
_episodes = new List<Episode>();
|
||||
_episodes.Add(new Episode { SeasonNumber = 1, EpisodeNumber = 1 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 1, EpisodeNumber = 2 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 1 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 2 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 3 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 4 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 5 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 3, EpisodeNumber = 1 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 3, EpisodeNumber = 2 });
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
.Setup(v => v.GetEpisodeBySeries(It.IsAny<int>()))
|
||||
.Returns(_episodes);
|
||||
}
|
||||
|
||||
private void GivenTvdbMappings()
|
||||
{
|
||||
_theXemSeriesIds.Add(10);
|
||||
|
||||
AddTvdbMapping(1, 1, 1, 1, 1, 1); // 1x01 -> 1x01
|
||||
AddTvdbMapping(2, 1, 2, 2, 1, 2); // 1x02 -> 1x02
|
||||
AddTvdbMapping(3, 2, 1, 3, 2, 1); // 2x01 -> 2x01
|
||||
AddTvdbMapping(4, 2, 2, 4, 2, 2); // 2x02 -> 2x02
|
||||
AddTvdbMapping(5, 2, 3, 5, 2, 3); // 2x03 -> 2x03
|
||||
AddTvdbMapping(6, 3, 1, 6, 2, 4); // 3x01 -> 2x04
|
||||
AddTvdbMapping(7, 3, 2, 7, 2, 5); // 3x02 -> 2x05
|
||||
}
|
||||
|
||||
private void GivenExistingMapping()
|
||||
{
|
||||
_series.UseSceneNumbering = true;
|
||||
|
||||
_episodes[0].SceneSeasonNumber = 1;
|
||||
_episodes[0].SceneEpisodeNumber = 1;
|
||||
_episodes[1].SceneSeasonNumber = 1;
|
||||
_episodes[1].SceneEpisodeNumber = 2;
|
||||
_episodes[2].SceneSeasonNumber = 2;
|
||||
_episodes[2].SceneEpisodeNumber = 1;
|
||||
_episodes[3].SceneSeasonNumber = 2;
|
||||
_episodes[3].SceneEpisodeNumber = 2;
|
||||
_episodes[4].SceneSeasonNumber = 2;
|
||||
_episodes[4].SceneEpisodeNumber = 3;
|
||||
_episodes[5].SceneSeasonNumber = 3;
|
||||
_episodes[5].SceneEpisodeNumber = 1;
|
||||
_episodes[6].SceneSeasonNumber = 3;
|
||||
_episodes[6].SceneEpisodeNumber = 1;
|
||||
}
|
||||
|
||||
private void AddTvdbMapping(int sceneAbsolute, int sceneSeason, int sceneEpisode, int tvdbAbsolute, int tvdbSeason, int tvdbEpisode)
|
||||
{
|
||||
_theXemTvdbMappings.Add(new XemSceneTvdbMapping
|
||||
{
|
||||
Scene = new XemValues { Absolute = sceneAbsolute, Season = sceneSeason, Episode = sceneEpisode },
|
||||
Tvdb = new XemValues { Absolute = tvdbAbsolute, Season = tvdbSeason, Episode = tvdbEpisode },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_not_fetch_scenenumbering_if_not_listed()
|
||||
{
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<IXemProxy>()
|
||||
.Verify(v => v.GetSceneTvdbMappings(10), Times.Never());
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fetch_scenenumbering()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.UseSceneNumbering == true)), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_clear_scenenumbering_if_removed_from_thexem()
|
||||
{
|
||||
GivenExistingMapping();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_clear_scenenumbering_if_no_results_at_all_from_thexem()
|
||||
{
|
||||
GivenExistingMapping();
|
||||
|
||||
_theXemSeriesIds.Clear();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_clear_scenenumbering_if_thexem_throws()
|
||||
{
|
||||
GivenExistingMapping();
|
||||
|
||||
Mocker.GetMock<IXemProxy>()
|
||||
.Setup(v => v.GetXemSeriesIds())
|
||||
.Throws(new InvalidOperationException());
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_flag_unknown_future_episodes_if_existing_season_is_mapped()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
_theXemTvdbMappings.RemoveAll(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_flag_unknown_future_season_if_future_season_is_shifted()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 1);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_flag_unknown_future_season_if_future_season_is_not_shifted()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season == 3);
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 1);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_flag_past_episodes_if_not_causing_overlaps()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season == 2);
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 1);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_flag_past_episodes_if_causing_overlap()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season == 2 && v.Tvdb.Episode <= 1);
|
||||
_theXemTvdbMappings.First(v => v.Scene.Season == 2 && v.Scene.Episode == 2).Scene.Episode = 1;
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 1);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_extrapolate_season_with_specials()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
var specialMapping = _theXemTvdbMappings.First(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
||||
specialMapping.Tvdb.Season = 0;
|
||||
specialMapping.Tvdb.Episode = 1;
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
||||
episode.SceneSeasonNumber.Should().NotHaveValue();
|
||||
episode.SceneEpisodeNumber.Should().NotHaveValue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_extrapolate_season_with_future_episodes()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
_theXemTvdbMappings.RemoveAll(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
||||
episode.SceneSeasonNumber.Should().Be(3);
|
||||
episode.SceneEpisodeNumber.Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_extrapolate_season_with_shifted_episodes()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
_theXemTvdbMappings.RemoveAll(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
||||
var dualMapping = _theXemTvdbMappings.First(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 4);
|
||||
dualMapping.Scene.Season = 2;
|
||||
dualMapping.Scene.Episode = 3;
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
||||
episode.SceneSeasonNumber.Should().Be(2);
|
||||
episode.SceneEpisodeNumber.Should().Be(4);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_extrapolate_shifted_future_seasons()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 2);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
||||
episode.SceneSeasonNumber.Should().Be(4);
|
||||
episode.SceneEpisodeNumber.Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_extrapolate_matching_future_seasons()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season != 1);
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 2);
|
||||
|
||||
episode.UnverifiedSceneNumbering.Should().BeFalse();
|
||||
episode.SceneSeasonNumber.Should().NotHaveValue();
|
||||
episode.SceneEpisodeNumber.Should().NotHaveValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
private RemoteEpisode parseResultMulti;
|
||||
private RemoteEpisode parseResultSingle;
|
||||
private Series series;
|
||||
private Movie movie;
|
||||
private RemoteMovie remoteMovie;
|
||||
private QualityDefinition qualityType;
|
||||
|
||||
[SetUp]
|
||||
@@ -28,6 +30,16 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
series = Builder<Series>.CreateNew()
|
||||
.Build();
|
||||
|
||||
movie = Builder<Movie>.CreateNew().Build();
|
||||
|
||||
remoteMovie = new RemoteMovie
|
||||
{
|
||||
Movie = movie,
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedMovieInfo = new ParsedMovieInfo { Quality = new QualityModel(Quality.SDTV, new Revision(version: 2)) },
|
||||
|
||||
};
|
||||
|
||||
parseResultMultiSet = new RemoteEpisode
|
||||
{
|
||||
Series = series,
|
||||
@@ -196,18 +208,18 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_RAWHD()
|
||||
{
|
||||
parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.RAWHD);
|
||||
//[Test]
|
||||
//public void should_return_true_if_RAWHD()
|
||||
//{
|
||||
// parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.RAWHD);
|
||||
|
||||
series.Runtime = 45;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
|
||||
parseResultSingle.Release.Size = 8000.Megabytes();
|
||||
// series.Runtime = 45;
|
||||
// parseResultSingle.Series = series;
|
||||
// parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
|
||||
// parseResultSingle.Release.Size = 8000.Megabytes();
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
// Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
//}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_for_special()
|
||||
@@ -216,5 +228,17 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_110_minutes_if_runtime_is_0()
|
||||
{
|
||||
movie.Runtime = 0;
|
||||
remoteMovie.Movie = movie;
|
||||
remoteMovie.Release.Size = 1095.Megabytes();
|
||||
|
||||
Subject.IsSatisfiedBy(remoteMovie, null).Accepted.Should().Be(true);
|
||||
remoteMovie.Release.Size = 1105.Megabytes();
|
||||
Subject.IsSatisfiedBy(remoteMovie, null).Accepted.Should().Be(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
public class DownloadDecisionMakerFixture : CoreTest<DownloadDecisionMaker>
|
||||
{
|
||||
private List<ReleaseInfo> _reports;
|
||||
private RemoteEpisode _remoteEpisode;
|
||||
private RemoteMovie _remoteEpisode;
|
||||
|
||||
private Mock<IDecisionEngineSpecification> _pass1;
|
||||
private Mock<IDecisionEngineSpecification> _pass2;
|
||||
@@ -39,22 +39,21 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
_fail2 = new Mock<IDecisionEngineSpecification>();
|
||||
_fail3 = new Mock<IDecisionEngineSpecification>();
|
||||
|
||||
_pass1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Accept);
|
||||
_pass2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Accept);
|
||||
_pass3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Accept);
|
||||
_pass1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null)).Returns(Decision.Accept);
|
||||
_pass2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null)).Returns(Decision.Accept);
|
||||
_pass3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null)).Returns(Decision.Accept);
|
||||
|
||||
_fail1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Reject("fail1"));
|
||||
_fail2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Reject("fail2"));
|
||||
_fail3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Reject("fail3"));
|
||||
_fail1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null)).Returns(Decision.Reject("fail1"));
|
||||
_fail2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null)).Returns(Decision.Reject("fail2"));
|
||||
_fail3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null)).Returns(Decision.Reject("fail3"));
|
||||
|
||||
_reports = new List<ReleaseInfo> { new ReleaseInfo { Title = "The.Office.S03E115.DVDRip.XviD-OSiTV" } };
|
||||
_remoteEpisode = new RemoteEpisode {
|
||||
Series = new Series(),
|
||||
Episodes = new List<Episode> { new Episode() }
|
||||
_reports = new List<ReleaseInfo> { new ReleaseInfo { Title = "Trolls.2016.720p.WEB-DL.DD5.1.H264-FGT" } };
|
||||
_remoteEpisode = new RemoteMovie {
|
||||
Movie = new Movie(),
|
||||
};
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
|
||||
.Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
|
||||
.Returns(_remoteEpisode);
|
||||
}
|
||||
|
||||
@@ -125,11 +124,11 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
|
||||
var results = Subject.GetRssDecision(_reports).ToList();
|
||||
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
|
||||
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
@@ -142,11 +141,11 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
|
||||
var results = Subject.GetRssDecision(_reports).ToList();
|
||||
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
|
||||
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
@@ -156,13 +155,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||
|
||||
_remoteEpisode.Series = null;
|
||||
_remoteEpisode.Movie = null;
|
||||
|
||||
Subject.GetRssDecision(_reports);
|
||||
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -170,19 +169,19 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
GivenSpecifications(_pass1);
|
||||
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
|
||||
.Throws<TestException>();
|
||||
|
||||
_reports = new List<ReleaseInfo>
|
||||
{
|
||||
new ReleaseInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"},
|
||||
new ReleaseInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"},
|
||||
new ReleaseInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"}
|
||||
new ReleaseInfo{Title = "Trolls.2016.720p.WEB-DL.DD5.1.H264-FGT"},
|
||||
new ReleaseInfo{Title = "Trolls.2016.720p.WEB-DL.DD5.1.H264-FGT"},
|
||||
new ReleaseInfo{Title = "Trolls.2016.720p.WEB-DL.DD5.1.H264-FGT"}
|
||||
};
|
||||
|
||||
Subject.GetRssDecision(_reports);
|
||||
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Exactly(_reports.Count));
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Exactly(_reports.Count));
|
||||
|
||||
ExceptionVerification.ExpectedErrors(3);
|
||||
}
|
||||
@@ -192,7 +191,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||
|
||||
_remoteEpisode.Series = null;
|
||||
_remoteEpisode.Movie = null;
|
||||
|
||||
var result = Subject.GetRssDecision(_reports);
|
||||
|
||||
@@ -200,6 +199,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore( "Series")]
|
||||
public void should_only_include_reports_for_requested_episodes()
|
||||
{
|
||||
var series = Builder<Series>.CreateNew().Build();
|
||||
@@ -248,27 +248,28 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||
|
||||
_remoteEpisode.Series = null;
|
||||
_remoteEpisode.Movie = null;
|
||||
|
||||
var result = Subject.GetRssDecision(_reports);
|
||||
|
||||
result.Should().HaveCount(1);
|
||||
|
||||
result.First().RemoteEpisode.DownloadAllowed.Should().BeFalse();
|
||||
result.First().RemoteMovie.DownloadAllowed.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Series")]
|
||||
public void should_not_allow_download_if_no_episodes_found()
|
||||
{
|
||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||
|
||||
_remoteEpisode.Episodes = new List<Episode>();
|
||||
_remoteEpisode.Movie = null;
|
||||
|
||||
var result = Subject.GetRssDecision(_reports);
|
||||
|
||||
result.Should().HaveCount(1);
|
||||
|
||||
result.First().RemoteEpisode.DownloadAllowed.Should().BeFalse();
|
||||
result.First().RemoteMovie.DownloadAllowed.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -276,12 +277,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
GivenSpecifications(_pass1);
|
||||
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
|
||||
.Throws<TestException>();
|
||||
|
||||
_reports = new List<ReleaseInfo>
|
||||
{
|
||||
new ReleaseInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"},
|
||||
new ReleaseInfo{Title = "Trolls.2016.720p.WEB-DL.DD5.1.H264-FGT"},
|
||||
};
|
||||
|
||||
Subject.GetRssDecision(_reports).Should().HaveCount(1);
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Collections.Generic;
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
[TestFixture]
|
||||
[Ignore("Series")]
|
||||
public class FullSeasonSpecificationFixture : CoreTest<FullSeasonSpecification>
|
||||
{
|
||||
private RemoteEpisode _remoteEpisode;
|
||||
|
||||
@@ -26,34 +26,28 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
GivenPreferredDownloadProtocol(DownloadProtocol.Usenet);
|
||||
}
|
||||
|
||||
private Episode GivenEpisode(int id)
|
||||
{
|
||||
return Builder<Episode>.CreateNew()
|
||||
.With(e => e.Id = id)
|
||||
.With(e => e.EpisodeNumber = id)
|
||||
.Build();
|
||||
}
|
||||
private RemoteMovie GivenRemoteMovie(QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet)
|
||||
{
|
||||
var remoteMovie = new RemoteMovie();
|
||||
remoteMovie.ParsedMovieInfo = new ParsedMovieInfo();
|
||||
remoteMovie.ParsedMovieInfo.MovieTitle = "A Movie";
|
||||
remoteMovie.ParsedMovieInfo.Year = 1998;
|
||||
remoteMovie.ParsedMovieInfo.MovieTitleInfo = new SeriesTitleInfo { Year = 1998};
|
||||
remoteMovie.ParsedMovieInfo.MovieTitleInfo.Year = 1998;
|
||||
remoteMovie.ParsedMovieInfo.Quality = quality;
|
||||
|
||||
private RemoteEpisode GivenRemoteEpisode(List<Episode> episodes, QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet)
|
||||
{
|
||||
var remoteEpisode = new RemoteEpisode();
|
||||
remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
||||
remoteEpisode.ParsedEpisodeInfo.Quality = quality;
|
||||
remoteMovie.Movie = Builder<Movie>.CreateNew().With(m => m.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
PreferredTags = new List<string> { "DTS-HD", "SPARKS"} })
|
||||
.With(m => m.Title = "A Movie").Build();
|
||||
|
||||
remoteEpisode.Episodes = new List<Episode>();
|
||||
remoteEpisode.Episodes.AddRange(episodes);
|
||||
remoteMovie.Release = new ReleaseInfo();
|
||||
remoteMovie.Release.PublishDate = DateTime.Now.AddDays(-age);
|
||||
remoteMovie.Release.Size = size;
|
||||
remoteMovie.Release.DownloadProtocol = downloadProtocol;
|
||||
remoteMovie.Release.Title = "A Movie 1998";
|
||||
|
||||
remoteEpisode.Release = new ReleaseInfo();
|
||||
remoteEpisode.Release.PublishDate = DateTime.Now.AddDays(-age);
|
||||
remoteEpisode.Release.Size = size;
|
||||
remoteEpisode.Release.DownloadProtocol = downloadProtocol;
|
||||
|
||||
remoteEpisode.Series = Builder<Series>.CreateNew()
|
||||
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||
.Build();
|
||||
|
||||
return remoteEpisode;
|
||||
}
|
||||
return remoteMovie;
|
||||
}
|
||||
|
||||
private void GivenPreferredDownloadProtocol(DownloadProtocol downloadProtocol)
|
||||
{
|
||||
@@ -68,66 +62,38 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[Test]
|
||||
public void should_put_propers_before_non_propers()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p, new Revision(version: 1)));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p, new Revision(version: 2)));
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 1)));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 2)));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.Should().Be(2);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.ParsedMovieInfo.Quality.Revision.Version.Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_put_higher_quality_before_lower()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.SDTV));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.SDTV));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Quality.Should().Be(Quality.HDTV720p);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_order_by_lowest_number_of_episodes()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(2) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Episodes.First().EpisodeNumber.Should().Be(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_order_by_lowest_number_of_episodes_with_multiple_episodes()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(2), GivenEpisode(3) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Episodes.First().EpisodeNumber.Should().Be(1);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.ParsedMovieInfo.Quality.Quality.Should().Be(Quality.HDTV720p);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_order_by_age_then_largest_rounded_to_200mb()
|
||||
{
|
||||
var remoteEpisodeSd = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.SDTV), size: 100.Megabytes(), age: 1);
|
||||
var remoteEpisodeHdSmallOld = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 1200.Megabytes(), age: 1000);
|
||||
var remoteEpisodeSmallYoung = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 1250.Megabytes(), age: 10);
|
||||
var remoteEpisodeHdLargeYoung = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 3000.Megabytes(), age: 1);
|
||||
var remoteEpisodeSd = GivenRemoteMovie(new QualityModel(Quality.SDTV), size: 100.Megabytes(), age: 1);
|
||||
var remoteEpisodeHdSmallOld = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1200.Megabytes(), age: 1000);
|
||||
var remoteEpisodeSmallYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1250.Megabytes(), age: 10);
|
||||
var remoteEpisodeHdLargeYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 3000.Megabytes(), age: 1);
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisodeSd));
|
||||
@@ -135,38 +101,23 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
decisions.Add(new DownloadDecision(remoteEpisodeSmallYoung));
|
||||
decisions.Add(new DownloadDecision(remoteEpisodeHdLargeYoung));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Should().Be(remoteEpisodeHdLargeYoung);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.Should().Be(remoteEpisodeHdLargeYoung);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_order_by_youngest()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), age: 10);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), age: 5);
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 10);
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 5);
|
||||
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Should().Be(remoteEpisode2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_throw_if_no_episodes_are_found()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 500.Megabytes());
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 500.Megabytes());
|
||||
|
||||
remoteEpisode1.Episodes = new List<Episode>();
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
Subject.PrioritizeDecisions(decisions);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.Should().Be(remoteEpisode2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -174,15 +125,15 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
GivenPreferredDownloadProtocol(DownloadProtocol.Usenet);
|
||||
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Release.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.Release.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -190,38 +141,22 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
GivenPreferredDownloadProtocol(DownloadProtocol.Torrent);
|
||||
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Release.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_season_pack_above_single_episode()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
|
||||
remoteEpisode1.ParsedEpisodeInfo.FullSeason = true;
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.FullSeason.Should().BeTrue();
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.Release.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_releases_with_more_seeders()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var torrentInfo1 = new TorrentInfo();
|
||||
torrentInfo1.PublishDate = DateTime.Now;
|
||||
@@ -233,21 +168,23 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
torrentInfo2.Seeders = 100;
|
||||
|
||||
remoteEpisode1.Release = torrentInfo1;
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
remoteEpisode1.Release.Title = "A Movie 1998";
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
remoteEpisode2.Release.Title = "A Movie 1998";
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
((TorrentInfo) qualifiedReports.First().RemoteEpisode.Release).Seeders.Should().Be(torrentInfo2.Seeders);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
((TorrentInfo) qualifiedReports.First().RemoteMovie.Release).Seeders.Should().Be(torrentInfo2.Seeders);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_releases_with_more_peers_given_equal_number_of_seeds()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var torrentInfo1 = new TorrentInfo();
|
||||
torrentInfo1.PublishDate = DateTime.Now;
|
||||
@@ -261,21 +198,23 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
torrentInfo2.Peers = 100;
|
||||
|
||||
remoteEpisode1.Release = torrentInfo1;
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
remoteEpisode1.Release.Title = "A Movie 1998";
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
remoteEpisode2.Release.Title = "A Movie 1998";
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
((TorrentInfo)qualifiedReports.First().RemoteEpisode.Release).Peers.Should().Be(torrentInfo2.Peers);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Peers.Should().Be(torrentInfo2.Peers);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_releases_with_more_peers_no_seeds()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var torrentInfo1 = new TorrentInfo();
|
||||
torrentInfo1.PublishDate = DateTime.Now;
|
||||
@@ -290,21 +229,23 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
torrentInfo2.Peers = 100;
|
||||
|
||||
remoteEpisode1.Release = torrentInfo1;
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
remoteEpisode1.Release.Title = "A Movie 1998";
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
remoteEpisode2.Release.Title = "A Movie 1998";
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
((TorrentInfo)qualifiedReports.First().RemoteEpisode.Release).Peers.Should().Be(torrentInfo2.Peers);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Peers.Should().Be(torrentInfo2.Peers);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_first_release_if_peers_and_size_are_too_similar()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var torrentInfo1 = new TorrentInfo();
|
||||
torrentInfo1.PublishDate = DateTime.Now;
|
||||
@@ -319,21 +260,23 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
torrentInfo1.Size = 250.Megabytes();
|
||||
|
||||
remoteEpisode1.Release = torrentInfo1;
|
||||
remoteEpisode1.Release.Title = "A Movie 1998";
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
remoteEpisode2.Release.Title = "A Movie 1998";
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
((TorrentInfo) qualifiedReports.First().RemoteEpisode.Release).Should().Be(torrentInfo1);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
((TorrentInfo) qualifiedReports.First().RemoteMovie.Release).Should().Be(torrentInfo1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_first_release_if_age_and_size_are_too_similar()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
remoteEpisode1.Release.PublishDate = DateTime.UtcNow.AddDays(-100);
|
||||
remoteEpisode1.Release.Size = 200.Megabytes();
|
||||
@@ -345,8 +288,25 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Release.Should().Be(remoteEpisode1.Release);
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteEpisode1.Release);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_more_prioritized_words()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
remoteEpisode1.Release.Title += " DTS-HD";
|
||||
remoteEpisode2.Release.Title += " DTS-HD SPARKS";
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
|
||||
qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteEpisode2.Release);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
{
|
||||
private Profile _profile;
|
||||
private DelayProfile _delayProfile;
|
||||
private RemoteEpisode _remoteEpisode;
|
||||
private RemoteMovie _remoteEpisode;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
@@ -38,12 +38,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
.With(d => d.PreferredProtocol = DownloadProtocol.Usenet)
|
||||
.Build();
|
||||
|
||||
var series = Builder<Series>.CreateNew()
|
||||
var series = Builder<Movie>.CreateNew()
|
||||
.With(s => s.Profile = _profile)
|
||||
.Build();
|
||||
|
||||
_remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||
.With(r => r.Series = series)
|
||||
_remoteEpisode = Builder<RemoteMovie>.CreateNew()
|
||||
.With(r => r.Movie = series)
|
||||
.Build();
|
||||
|
||||
_profile.Items = new List<ProfileQualityItem>();
|
||||
@@ -53,30 +53,32 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
|
||||
_profile.Cutoff = Quality.WEBDL720p;
|
||||
|
||||
_remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
||||
_remoteEpisode.ParsedMovieInfo = new ParsedMovieInfo();
|
||||
_remoteEpisode.Release = new ReleaseInfo();
|
||||
_remoteEpisode.Release.DownloadProtocol = DownloadProtocol.Usenet;
|
||||
|
||||
_remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1).Build().ToList();
|
||||
_remoteEpisode.Episodes.First().EpisodeFileId = 0;
|
||||
//_remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1).Build().ToList();
|
||||
//_remoteEpisode.Episodes.First().EpisodeFileId = 0;
|
||||
|
||||
Mocker.GetMock<IDelayProfileService>()
|
||||
.Setup(s => s.BestForTags(It.IsAny<HashSet<int>>()))
|
||||
.Returns(_delayProfile);
|
||||
|
||||
Mocker.GetMock<IPendingReleaseService>()
|
||||
.Setup(s => s.GetPendingRemoteEpisodes(It.IsAny<int>()))
|
||||
.Returns(new List<RemoteEpisode>());
|
||||
.Setup(s => s.GetPendingRemoteMovies(It.IsAny<int>()))
|
||||
.Returns(new List<RemoteMovie>());
|
||||
}
|
||||
|
||||
private void GivenExistingFile(QualityModel quality)
|
||||
{
|
||||
_remoteEpisode.Episodes.First().EpisodeFileId = 1;
|
||||
//_remoteEpisode.Episodes.First().EpisodeFileId = 1;
|
||||
|
||||
_remoteEpisode.Episodes.First().EpisodeFile = new LazyLoaded<EpisodeFile>(new EpisodeFile
|
||||
{
|
||||
Quality = quality
|
||||
});
|
||||
//_remoteEpisode.Episodes.First().EpisodeFile = new LazyLoaded<EpisodeFile>(new EpisodeFile
|
||||
// {
|
||||
// Quality = quality
|
||||
// });
|
||||
|
||||
_remoteEpisode.Movie.MovieFile = new LazyLoaded<MovieFile>(new MovieFile { Quality = quality });
|
||||
}
|
||||
|
||||
private void GivenUpgradeForExistingFile()
|
||||
@@ -95,7 +97,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
[Test]
|
||||
public void should_be_false_when_system_invoked_search_and_release_is_younger_than_delay()
|
||||
{
|
||||
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.SDTV);
|
||||
_remoteEpisode.ParsedMovieInfo.Quality = new QualityModel(Quality.SDTV);
|
||||
_remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||
|
||||
_delayProfile.UsenetDelay = 720;
|
||||
@@ -114,7 +116,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
[Test]
|
||||
public void should_be_true_when_quality_is_last_allowed_in_profile()
|
||||
{
|
||||
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.Bluray720p);
|
||||
_remoteEpisode.ParsedMovieInfo.Quality = new QualityModel(Quality.Bluray720p);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
@@ -122,7 +124,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
[Test]
|
||||
public void should_be_true_when_release_is_older_than_delay()
|
||||
{
|
||||
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.HDTV720p);
|
||||
_remoteEpisode.ParsedMovieInfo.Quality = new QualityModel(Quality.HDTV720p);
|
||||
_remoteEpisode.Release.PublishDate = DateTime.UtcNow.AddHours(-10);
|
||||
|
||||
_delayProfile.UsenetDelay = 60;
|
||||
@@ -133,7 +135,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
[Test]
|
||||
public void should_be_false_when_release_is_younger_than_delay()
|
||||
{
|
||||
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.SDTV);
|
||||
_remoteEpisode.ParsedMovieInfo.Quality = new QualityModel(Quality.SDTV);
|
||||
_remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||
|
||||
_delayProfile.UsenetDelay = 720;
|
||||
@@ -144,7 +146,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
[Test]
|
||||
public void should_be_true_when_release_is_a_proper_for_existing_episode()
|
||||
{
|
||||
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.HDTV720p, new Revision(version: 2));
|
||||
_remoteEpisode.ParsedMovieInfo.Quality = new QualityModel(Quality.HDTV720p, new Revision(version: 2));
|
||||
_remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||
|
||||
GivenExistingFile(new QualityModel(Quality.HDTV720p));
|
||||
@@ -162,7 +164,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
[Test]
|
||||
public void should_be_true_when_release_is_a_real_for_existing_episode()
|
||||
{
|
||||
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.HDTV720p, new Revision(real: 1));
|
||||
_remoteEpisode.ParsedMovieInfo.Quality = new QualityModel(Quality.HDTV720p, new Revision(real: 1));
|
||||
_remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||
|
||||
GivenExistingFile(new QualityModel(Quality.HDTV720p));
|
||||
@@ -180,7 +182,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
[Test]
|
||||
public void should_be_false_when_release_is_proper_for_existing_episode_of_different_quality()
|
||||
{
|
||||
_remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.HDTV720p, new Revision(version: 2));
|
||||
_remoteEpisode.ParsedMovieInfo.Quality = new QualityModel(Quality.HDTV720p, new Revision(version: 2));
|
||||
_remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||
|
||||
GivenExistingFile(new QualityModel(Quality.SDTV));
|
||||
|
||||
@@ -31,15 +31,15 @@ namespace NzbDrone.Core.Test.Download
|
||||
var completed = Builder<DownloadClientItem>.CreateNew()
|
||||
.With(h => h.Status = DownloadItemStatus.Completed)
|
||||
.With(h => h.OutputPath = new OsPath(@"C:\DropFolder\MyDownload".AsOsAgnostic()))
|
||||
.With(h => h.Title = "Drone.S01E01.HDTV")
|
||||
.With(h => h.Title = "Drone.1998")
|
||||
.Build();
|
||||
|
||||
var remoteEpisode = BuildRemoteEpisode();
|
||||
var remoteEpisode = BuildRemoteMovie();
|
||||
|
||||
_trackedDownload = Builder<TrackedDownload>.CreateNew()
|
||||
.With(c => c.State = TrackedDownloadStage.Downloading)
|
||||
.With(c => c.DownloadItem = completed)
|
||||
.With(c => c.RemoteEpisode = remoteEpisode)
|
||||
.With(c => c.RemoteMovie = remoteEpisode)
|
||||
.Build();
|
||||
|
||||
|
||||
@@ -56,17 +56,16 @@ namespace NzbDrone.Core.Test.Download
|
||||
.Returns(new History.History());
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetSeries("Drone.S01E01.HDTV"))
|
||||
.Returns(remoteEpisode.Series);
|
||||
.Setup(s => s.GetMovie("Drone.1998"))
|
||||
.Returns(remoteEpisode.Movie);
|
||||
|
||||
}
|
||||
|
||||
private RemoteEpisode BuildRemoteEpisode()
|
||||
private RemoteMovie BuildRemoteMovie()
|
||||
{
|
||||
return new RemoteEpisode
|
||||
{
|
||||
Series = new Series(),
|
||||
Episodes = new List<Episode> { new Episode { Id = 1 } }
|
||||
return new RemoteMovie
|
||||
{
|
||||
Movie = new Movie()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -80,11 +79,11 @@ namespace NzbDrone.Core.Test.Download
|
||||
|
||||
private void GivenSuccessfulImport()
|
||||
{
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode() { Path = @"C:\TestPath\Droned.S01E01.mkv" }))
|
||||
new ImportResult(new ImportDecision(new LocalEpisode() { Path = @"C:\TestPath\Droned.1998.mkv" }))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -95,22 +94,22 @@ namespace NzbDrone.Core.Test.Download
|
||||
_trackedDownload.DownloadItem.Title = "Droned Pilot"; // Set a badly named download
|
||||
Mocker.GetMock<IHistoryService>()
|
||||
.Setup(s => s.MostRecentForDownloadId(It.Is<string>(i => i == "1234")))
|
||||
.Returns(new History.History() { SourceTitle = "Droned S01E01" });
|
||||
.Returns(new History.History() { SourceTitle = "Droned 1998" });
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetSeries(It.IsAny<string>()))
|
||||
.Returns((Series)null);
|
||||
.Setup(s => s.GetMovie(It.IsAny<string>()))
|
||||
.Returns((Movie)null);
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetSeries("Droned S01E01"))
|
||||
.Returns(BuildRemoteEpisode().Series);
|
||||
.Setup(s => s.GetMovie("Droned 1998"))
|
||||
.Returns(BuildRemoteMovie().Movie);
|
||||
}
|
||||
|
||||
private void GivenSeriesMatch()
|
||||
{
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetSeries(It.IsAny<string>()))
|
||||
.Returns(_trackedDownload.RemoteEpisode.Series);
|
||||
.Setup(s => s.GetMovie(It.IsAny<string>()))
|
||||
.Returns(_trackedDownload.RemoteMovie.Movie);
|
||||
}
|
||||
|
||||
[TestCase(DownloadItemStatus.Downloading)]
|
||||
@@ -155,7 +154,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
public void should_not_process_if_storage_directory_in_drone_factory()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.SetupGet(v => v.DownloadedEpisodesFolder)
|
||||
.SetupGet(v => v.DownloadedMoviesFolder)
|
||||
.Returns(@"C:\DropFolder".AsOsAgnostic());
|
||||
|
||||
_trackedDownload.DownloadItem.OutputPath = new OsPath(@"C:\DropFolder\SomeOtherFolder".AsOsAgnostic());
|
||||
@@ -178,17 +177,17 @@ namespace NzbDrone.Core.Test.Download
|
||||
[Test]
|
||||
public void should_mark_as_imported_if_all_episodes_were_imported()
|
||||
{
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(
|
||||
new ImportDecision(
|
||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
||||
new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"})),
|
||||
|
||||
new ImportResult(
|
||||
new ImportDecision(
|
||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"}))
|
||||
new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"}))
|
||||
});
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
@@ -199,17 +198,17 @@ namespace NzbDrone.Core.Test.Download
|
||||
[Test]
|
||||
public void should_not_mark_as_imported_if_all_files_were_rejected()
|
||||
{
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(
|
||||
new ImportDecision(
|
||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
||||
new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
||||
|
||||
new ImportResult(
|
||||
new ImportDecision(
|
||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"},new Rejection("Rejected!")), "Test Failure")
|
||||
new LocalMovie {Path = @"C:\TestPath\Droned.1999.mkv"},new Rejection("Rejected!")), "Test Failure")
|
||||
});
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
@@ -223,20 +222,20 @@ namespace NzbDrone.Core.Test.Download
|
||||
[Test]
|
||||
public void should_not_mark_as_imported_if_no_episodes_were_parsed()
|
||||
{
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(
|
||||
new ImportDecision(
|
||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
||||
new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
||||
|
||||
new ImportResult(
|
||||
new ImportDecision(
|
||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"},new Rejection("Rejected!")), "Test Failure")
|
||||
new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"},new Rejection("Rejected!")), "Test Failure")
|
||||
});
|
||||
|
||||
_trackedDownload.RemoteEpisode.Episodes.Clear();
|
||||
_trackedDownload.RemoteMovie.Movie = null;
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
|
||||
@@ -246,12 +245,12 @@ namespace NzbDrone.Core.Test.Download
|
||||
[Test]
|
||||
public void should_not_mark_as_imported_if_all_files_were_skipped()
|
||||
{
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}),"Test Failure"),
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}),"Test Failure")
|
||||
new ImportResult(new ImportDecision(new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"}),"Test Failure"),
|
||||
new ImportResult(new ImportDecision(new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"}),"Test Failure")
|
||||
});
|
||||
|
||||
|
||||
@@ -265,17 +264,12 @@ namespace NzbDrone.Core.Test.Download
|
||||
{
|
||||
GivenSeriesMatch();
|
||||
|
||||
_trackedDownload.RemoteEpisode.Episodes = new List<Episode>
|
||||
{
|
||||
new Episode()
|
||||
};
|
||||
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
||||
new ImportResult(new ImportDecision(new LocalEpisode{Path = @"C:\TestPath\Droned.S01E01.mkv"}),"Test Failure")
|
||||
new ImportResult(new ImportDecision(new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"})),
|
||||
new ImportResult(new ImportDecision(new LocalMovie{Path = @"C:\TestPath\Droned.1998.mkv"}),"Test Failure")
|
||||
});
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
@@ -283,46 +277,21 @@ namespace NzbDrone.Core.Test.Download
|
||||
AssertCompletedDownload();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_mark_as_failed_if_some_of_episodes_were_not_imported()
|
||||
{
|
||||
_trackedDownload.RemoteEpisode.Episodes = new List<Episode>
|
||||
{
|
||||
new Episode(),
|
||||
new Episode(),
|
||||
new Episode()
|
||||
};
|
||||
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
||||
new ImportResult(new ImportDecision(new LocalEpisode{Path = @"C:\TestPath\Droned.S01E01.mkv"}),"Test Failure"),
|
||||
new ImportResult(new ImportDecision(new LocalEpisode{Path = @"C:\TestPath\Droned.S01E01.mkv"}),"Test Failure")
|
||||
});
|
||||
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
|
||||
AssertNoCompletedDownload();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_mark_as_imported_if_the_download_can_be_tracked_using_the_source_seriesid()
|
||||
{
|
||||
GivenABadlyNamedDownload();
|
||||
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||
new ImportResult(new ImportDecision(new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"}))
|
||||
});
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Setup(v => v.GetSeries(It.IsAny<int>()))
|
||||
.Returns(BuildRemoteEpisode().Series);
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Setup(v => v.GetMovie(It.IsAny<int>()))
|
||||
.Returns(BuildRemoteMovie().Movie);
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
|
||||
@@ -334,11 +303,11 @@ namespace NzbDrone.Core.Test.Download
|
||||
{
|
||||
GivenABadlyNamedDownload();
|
||||
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.1998.mkv"}))
|
||||
});
|
||||
|
||||
Mocker.GetMock<IHistoryService>()
|
||||
@@ -353,8 +322,8 @@ namespace NzbDrone.Core.Test.Download
|
||||
public void should_not_import_when_there_is_a_title_mismatch()
|
||||
{
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetSeries("Drone.S01E01.HDTV"))
|
||||
.Returns((Series)null);
|
||||
.Setup(s => s.GetMovie("Drone.1998"))
|
||||
.Returns((Movie)null);
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
|
||||
@@ -363,17 +332,13 @@ namespace NzbDrone.Core.Test.Download
|
||||
|
||||
[Test]
|
||||
public void should_mark_as_import_title_mismatch_if_ignore_warnings_is_true()
|
||||
{
|
||||
_trackedDownload.RemoteEpisode.Episodes = new List<Episode>
|
||||
{
|
||||
new Episode()
|
||||
};
|
||||
{
|
||||
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||
new ImportResult(new ImportDecision(new LocalMovie {Path = @"C:\TestPath\Droned.1998.mkv"}))
|
||||
});
|
||||
|
||||
Subject.Process(_trackedDownload, true);
|
||||
@@ -407,8 +372,8 @@ namespace NzbDrone.Core.Test.Download
|
||||
|
||||
private void AssertNoAttemptedImport()
|
||||
{
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Verify(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()), Times.Never());
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Verify(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>()), Times.Never());
|
||||
|
||||
AssertNoCompletedDownload();
|
||||
}
|
||||
@@ -423,8 +388,8 @@ namespace NzbDrone.Core.Test.Download
|
||||
|
||||
private void AssertCompletedDownload()
|
||||
{
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Verify(v => v.ProcessPath(_trackedDownload.DownloadItem.OutputPath.FullPath, ImportMode.Auto, _trackedDownload.RemoteEpisode.Series, _trackedDownload.DownloadItem), Times.Once());
|
||||
Mocker.GetMock<IDownloadedMovieImportService>()
|
||||
.Verify(v => v.ProcessPath(_trackedDownload.DownloadItem.OutputPath.FullPath, ImportMode.Auto, _trackedDownload.RemoteMovie.Movie, _trackedDownload.DownloadItem), Times.Once());
|
||||
|
||||
Mocker.GetMock<IEventAggregator>()
|
||||
.Verify(v => v.PublishEvent(It.IsAny<DownloadCompletedEvent>()), Times.Once());
|
||||
|
||||
@@ -23,93 +23,82 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
public void SetUp()
|
||||
{
|
||||
Mocker.GetMock<IPrioritizeDownloadDecision>()
|
||||
.Setup(v => v.PrioritizeDecisions(It.IsAny<List<DownloadDecision>>()))
|
||||
.Setup(v => v.PrioritizeDecisionsForMovies(It.IsAny<List<DownloadDecision>>()))
|
||||
.Returns<List<DownloadDecision>>(v => v);
|
||||
}
|
||||
|
||||
private Episode GetEpisode(int id)
|
||||
private Movie GetMovie(int id)
|
||||
{
|
||||
return Builder<Episode>.CreateNew()
|
||||
return Builder<Movie>.CreateNew()
|
||||
.With(e => e.Id = id)
|
||||
.With(e => e.EpisodeNumber = id)
|
||||
.With(m => m.Tags = new HashSet<int>())
|
||||
|
||||
.Build();
|
||||
}
|
||||
|
||||
private RemoteEpisode GetRemoteEpisode(List<Episode> episodes, QualityModel quality)
|
||||
private RemoteMovie GetRemoteMovie(QualityModel quality, Movie movie = null)
|
||||
{
|
||||
if (movie == null)
|
||||
{
|
||||
movie = GetMovie(1);
|
||||
}
|
||||
|
||||
movie.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities(), PreferredTags = new List<string>() };
|
||||
|
||||
var remoteMovie = new RemoteMovie()
|
||||
{
|
||||
ParsedMovieInfo = new ParsedMovieInfo()
|
||||
{
|
||||
Quality = quality,
|
||||
Year = 1998,
|
||||
MovieTitle = "A Movie",
|
||||
MovieTitleInfo = new SeriesTitleInfo()
|
||||
},
|
||||
Movie = movie,
|
||||
|
||||
Release = new ReleaseInfo()
|
||||
{
|
||||
PublishDate = DateTime.UtcNow,
|
||||
Title = "A.Movie.1998",
|
||||
Size = 200
|
||||
}
|
||||
};
|
||||
|
||||
return remoteMovie;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_download_report_if_movie_was_not_already_downloaded()
|
||||
{
|
||||
var remoteEpisode = new RemoteEpisode();
|
||||
remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
||||
remoteEpisode.ParsedEpisodeInfo.Quality = quality;
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
remoteEpisode.Episodes = new List<Episode>();
|
||||
remoteEpisode.Episodes.AddRange(episodes);
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
remoteEpisode.Release = new ReleaseInfo();
|
||||
remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||
|
||||
remoteEpisode.Series = Builder<Series>.CreateNew()
|
||||
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||
.Build();
|
||||
|
||||
return remoteEpisode;
|
||||
Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_download_report_if_epsiode_was_not_already_downloaded()
|
||||
public void should_only_download_movie_once()
|
||||
{
|
||||
var episodes = new List<Episode> { GetEpisode(1) };
|
||||
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.HDTV720p));
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode));
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteEpisode>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_only_download_episode_once()
|
||||
{
|
||||
var episodes = new List<Episode> { GetEpisode(1) };
|
||||
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteEpisode>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_download_if_any_episode_was_already_downloaded()
|
||||
{
|
||||
var remoteEpisode1 = GetRemoteEpisode(
|
||||
new List<Episode> { GetEpisode(1) },
|
||||
new QualityModel(Quality.HDTV720p)
|
||||
);
|
||||
|
||||
var remoteEpisode2 = GetRemoteEpisode(
|
||||
new List<Episode> { GetEpisode(1), GetEpisode(2) },
|
||||
new QualityModel(Quality.HDTV720p)
|
||||
);
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteEpisode>()), Times.Once());
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_downloaded_reports()
|
||||
{
|
||||
var episodes = new List<Episode> { GetEpisode(1) };
|
||||
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.HDTV720p));
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode));
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(1);
|
||||
}
|
||||
@@ -117,19 +106,19 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
[Test]
|
||||
public void should_return_all_downloaded_reports()
|
||||
{
|
||||
var remoteEpisode1 = GetRemoteEpisode(
|
||||
new List<Episode> { GetEpisode(1) },
|
||||
new QualityModel(Quality.HDTV720p)
|
||||
);
|
||||
var remoteMovie1 = GetRemoteMovie(
|
||||
new QualityModel(Quality.HDTV720p),
|
||||
GetMovie(1)
|
||||
);
|
||||
|
||||
var remoteEpisode2 = GetRemoteEpisode(
|
||||
new List<Episode> { GetEpisode(2) },
|
||||
new QualityModel(Quality.HDTV720p)
|
||||
);
|
||||
var remoteMovie2 = GetRemoteMovie(
|
||||
new QualityModel(Quality.HDTV720p),
|
||||
GetMovie(2)
|
||||
);
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
decisions.Add(new DownloadDecision(remoteMovie1));
|
||||
decisions.Add(new DownloadDecision(remoteMovie2));
|
||||
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(2);
|
||||
}
|
||||
@@ -137,25 +126,25 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
[Test]
|
||||
public void should_only_return_downloaded_reports()
|
||||
{
|
||||
var remoteEpisode1 = GetRemoteEpisode(
|
||||
new List<Episode> { GetEpisode(1) },
|
||||
new QualityModel(Quality.HDTV720p)
|
||||
);
|
||||
var remoteMovie1 = GetRemoteMovie(
|
||||
new QualityModel(Quality.HDTV720p),
|
||||
GetMovie(1)
|
||||
);
|
||||
|
||||
var remoteEpisode2 = GetRemoteEpisode(
|
||||
new List<Episode> { GetEpisode(2) },
|
||||
new QualityModel(Quality.HDTV720p)
|
||||
);
|
||||
var remoteMovie2 = GetRemoteMovie(
|
||||
new QualityModel(Quality.HDTV720p),
|
||||
GetMovie(2)
|
||||
);
|
||||
|
||||
var remoteEpisode3 = GetRemoteEpisode(
|
||||
new List<Episode> { GetEpisode(2) },
|
||||
new QualityModel(Quality.HDTV720p)
|
||||
var remoteMovie3 = GetRemoteMovie(
|
||||
new QualityModel(Quality.HDTV720p),
|
||||
GetMovie(2)
|
||||
);
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode3));
|
||||
decisions.Add(new DownloadDecision(remoteMovie1));
|
||||
decisions.Add(new DownloadDecision(remoteMovie2));
|
||||
decisions.Add(new DownloadDecision(remoteMovie3));
|
||||
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(2);
|
||||
}
|
||||
@@ -163,13 +152,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
[Test]
|
||||
public void should_not_add_to_downloaded_list_when_download_fails()
|
||||
{
|
||||
var episodes = new List<Episode> { GetEpisode(1) };
|
||||
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.HDTV720p));
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode));
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Mocker.GetMock<IDownloadService>().Setup(s => s.DownloadReport(It.IsAny<RemoteEpisode>())).Throws(new Exception());
|
||||
Mocker.GetMock<IDownloadService>().Setup(s => s.DownloadReport(It.IsAny<RemoteMovie>())).Throws(new Exception());
|
||||
Subject.ProcessDecisions(decisions).Grabbed.Should().BeEmpty();
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
@@ -178,9 +166,9 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
public void should_return_an_empty_list_when_none_are_appproved()
|
||||
{
|
||||
var decisions = new List<DownloadDecision>();
|
||||
RemoteEpisode ep = null;
|
||||
decisions.Add(new DownloadDecision(ep, new Rejection("Failure!")));
|
||||
decisions.Add(new DownloadDecision(ep, new Rejection("Failure!")));
|
||||
RemoteMovie remoteMovie = null;
|
||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!")));
|
||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!")));
|
||||
|
||||
Subject.GetQualifiedReports(decisions).Should().BeEmpty();
|
||||
}
|
||||
@@ -188,26 +176,24 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
[Test]
|
||||
public void should_not_grab_if_pending()
|
||||
{
|
||||
var episodes = new List<Episode> { GetEpisode(1) };
|
||||
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.HDTV720p));
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode));
|
||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
decisions.Add(new DownloadDecision(remoteMovie));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteEpisode>()), Times.Never());
|
||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_add_to_pending_if_episode_was_grabbed()
|
||||
public void should_not_add_to_pending_if_movie_was_grabbed()
|
||||
{
|
||||
var episodes = new List<Episode> { GetEpisode(1) };
|
||||
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.HDTV720p));
|
||||
var removeMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
decisions.Add(new DownloadDecision(removeMovie));
|
||||
decisions.Add(new DownloadDecision(removeMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IPendingReleaseService>().Verify(v => v.Add(It.IsAny<DownloadDecision>()), Times.Never());
|
||||
@@ -216,12 +202,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
[Test]
|
||||
public void should_add_to_pending_even_if_already_added_to_pending()
|
||||
{
|
||||
var episodes = new List<Episode> { GetEpisode(1) };
|
||||
var remoteEpisode = GetRemoteEpisode(episodes, new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
||||
|
||||
Subject.ProcessDecisions(decisions);
|
||||
Mocker.GetMock<IPendingReleaseService>().Verify(v => v.Add(It.IsAny<DownloadDecision>()), Times.Exactly(2));
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[TestFixture]
|
||||
public class ScanWatchFolderFixture : CoreTest<ScanWatchFolder>
|
||||
{
|
||||
protected readonly string _title = "Droned.S01E01.Pilot.1080p.WEB-DL-DRONE";
|
||||
protected readonly string _title = "Droned.1998.1080p.WEB-DL-DRONE";
|
||||
protected string _completedDownloadFolder = @"c:\blackhole\completed".AsOsAgnostic();
|
||||
|
||||
protected void GivenCompletedItem()
|
||||
|
||||
@@ -74,19 +74,19 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
.Returns(1000000);
|
||||
}
|
||||
|
||||
protected override RemoteEpisode CreateRemoteEpisode()
|
||||
protected override RemoteMovie CreateRemoteMovie()
|
||||
{
|
||||
var remoteEpisode = base.CreateRemoteEpisode();
|
||||
var remoteMovie = base.CreateRemoteMovie();
|
||||
var torrentInfo = new TorrentInfo();
|
||||
|
||||
torrentInfo.Title = remoteEpisode.Release.Title;
|
||||
torrentInfo.DownloadUrl = remoteEpisode.Release.DownloadUrl;
|
||||
torrentInfo.DownloadProtocol = remoteEpisode.Release.DownloadProtocol;
|
||||
torrentInfo.Title = remoteMovie.Release.Title;
|
||||
torrentInfo.DownloadUrl = remoteMovie.Release.DownloadUrl;
|
||||
torrentInfo.DownloadProtocol = remoteMovie.Release.DownloadProtocol;
|
||||
torrentInfo.MagnetUrl = "magnet:?xt=urn:btih:755248817d32b00cc853e633ecdc48e4c21bff15&dn=Series.S05E10.PROPER.HDTV.x264-DEFiNE%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710";
|
||||
|
||||
remoteEpisode.Release = torrentInfo;
|
||||
remoteMovie.Release = torrentInfo;
|
||||
|
||||
return remoteEpisode;
|
||||
return remoteMovie;
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -125,9 +125,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[Test]
|
||||
public void Download_should_download_file_if_it_doesnt_exist()
|
||||
{
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
Subject.Download(remoteMovie);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
|
||||
@@ -139,10 +139,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
{
|
||||
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
remoteEpisode.Release.DownloadUrl = null;
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = null;
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
Subject.Download(remoteMovie);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Never());
|
||||
@@ -153,10 +153,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[Test]
|
||||
public void Download_should_not_save_magnet_if_disabled()
|
||||
{
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
remoteEpisode.Release.DownloadUrl = null;
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = null;
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteEpisode));
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteMovie));
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Never());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Never());
|
||||
@@ -169,9 +169,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
{
|
||||
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
Subject.Download(remoteMovie);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
|
||||
@@ -185,10 +185,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
remoteEpisode.Release.Title = illegalTitle;
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.Title = illegalTitle;
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
Subject.Download(remoteMovie);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once());
|
||||
@@ -198,10 +198,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[Test]
|
||||
public void Download_should_throw_if_magnet_and_torrent_url_does_not_exist()
|
||||
{
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
remoteEpisode.Release.DownloadUrl = null;
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = null;
|
||||
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteEpisode));
|
||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteMovie));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -213,7 +213,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
.Setup(c => c.FileExists(It.IsAny<string>()))
|
||||
.Returns(true);
|
||||
|
||||
Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true);
|
||||
Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFile(It.IsAny<string>()), Times.Once());
|
||||
@@ -228,7 +228,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
.Setup(c => c.FolderExists(It.IsAny<string>()))
|
||||
.Returns(true);
|
||||
|
||||
Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true);
|
||||
Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFolder(It.IsAny<string>(), true), Times.Once());
|
||||
@@ -237,7 +237,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[Test]
|
||||
public void RemoveItem_should_ignore_if_unknown_item()
|
||||
{
|
||||
Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true);
|
||||
Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||
@@ -251,7 +251,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
{
|
||||
GivenCompletedItem();
|
||||
|
||||
Assert.Throws<NotSupportedException>(() => Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", false));
|
||||
Assert.Throws<NotSupportedException>(() => Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", false));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||
@@ -273,9 +273,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[Test]
|
||||
public void should_return_null_hash()
|
||||
{
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteEpisode).Should().BeNull();
|
||||
Subject.Download(remoteMovie).Should().BeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[Test]
|
||||
public void Download_should_download_file_if_it_doesnt_exist()
|
||||
{
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
Subject.Download(remoteMovie);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(_filePath), Times.Once());
|
||||
@@ -119,10 +119,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
remoteEpisode.Release.Title = illegalTitle;
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.Title = illegalTitle;
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
Subject.Download(remoteMovie);
|
||||
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.Get(It.Is<HttpRequest>(v => v.Url.FullUri == _downloadUrl)), Times.Once());
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once());
|
||||
@@ -138,7 +138,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
.Setup(c => c.FileExists(It.IsAny<string>()))
|
||||
.Returns(true);
|
||||
|
||||
Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true);
|
||||
Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFile(It.IsAny<string>()), Times.Once());
|
||||
@@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
.Setup(c => c.FolderExists(It.IsAny<string>()))
|
||||
.Returns(true);
|
||||
|
||||
Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true);
|
||||
Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFolder(It.IsAny<string>(), true), Times.Once());
|
||||
@@ -162,7 +162,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
[Test]
|
||||
public void RemoveItem_should_ignore_if_unknown_item()
|
||||
{
|
||||
Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", true);
|
||||
Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||
@@ -176,7 +176,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
{
|
||||
GivenCompletedItem();
|
||||
|
||||
Assert.Throws<NotSupportedException>(() => Subject.RemoveItem("_Droned.S01E01.Pilot.1080p.WEB-DL-DRONE_0", false));
|
||||
Assert.Throws<NotSupportedException>(() => Subject.RemoveItem("_Droned.1998.1080p.WEB-DL-DRONE_0", false));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||
|
||||
@@ -196,9 +196,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
var id = Subject.Download(remoteMovie);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
@@ -208,10 +208,10 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
||||
var remoteMovie = CreateRemoteMovie();
|
||||
remoteMovie.Release.DownloadUrl = magnetUrl;
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
var id = Subject.Download(remoteMovie);
|
||||
|
||||
id.Should().Be(expectedHash);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
public abstract class DownloadClientFixtureBase<TSubject> : CoreTest<TSubject>
|
||||
where TSubject : class, IDownloadClient
|
||||
{
|
||||
protected readonly string _title = "Droned.S01E01.Pilot.1080p.WEB-DL-DRONE";
|
||||
protected readonly string _downloadUrl = "http://somewhere.com/Droned.S01E01.Pilot.1080p.WEB-DL-DRONE.ext";
|
||||
protected readonly string _title = "Droned.1998.1080p.WEB-DL-DRONE";
|
||||
protected readonly string _downloadUrl = "http://somewhere.com/Droned.1998.1080p.WEB-DL-DRONE.ext";
|
||||
|
||||
[SetUp]
|
||||
public void SetupBase()
|
||||
@@ -30,8 +30,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
.Returns(30);
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), (SearchCriteriaBase)null))
|
||||
.Returns(() => CreateRemoteEpisode());
|
||||
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), (SearchCriteriaBase)null))
|
||||
.Returns(() => CreateRemoteMovie());
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||
@@ -42,22 +42,19 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
.Returns<string, OsPath>((h, r) => r);
|
||||
}
|
||||
|
||||
protected virtual RemoteEpisode CreateRemoteEpisode()
|
||||
protected virtual RemoteMovie CreateRemoteMovie()
|
||||
{
|
||||
var remoteEpisode = new RemoteEpisode();
|
||||
remoteEpisode.Release = new ReleaseInfo();
|
||||
remoteEpisode.Release.Title = _title;
|
||||
remoteEpisode.Release.DownloadUrl = _downloadUrl;
|
||||
remoteEpisode.Release.DownloadProtocol = Subject.Protocol;
|
||||
var remoteMovie = new RemoteMovie();
|
||||
remoteMovie.Release = new ReleaseInfo();
|
||||
remoteMovie.Release.Title = _title;
|
||||
remoteMovie.Release.DownloadUrl = _downloadUrl;
|
||||
remoteMovie.Release.DownloadProtocol = Subject.Protocol;
|
||||
|
||||
remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
||||
remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
|
||||
remoteMovie.ParsedMovieInfo = new ParsedMovieInfo();
|
||||
|
||||
remoteEpisode.Episodes = new List<Episode>();
|
||||
remoteMovie.Movie = new Movie();
|
||||
|
||||
remoteEpisode.Series = new Series();
|
||||
|
||||
return remoteEpisode;
|
||||
return remoteMovie;
|
||||
}
|
||||
|
||||
protected void VerifyIdentifiable(DownloadClientItem downloadClientItem)
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Download.Clients.DownloadStation;
|
||||
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class SerialNumberProviderFixture : CoreTest<SerialNumberProvider>
|
||||
{
|
||||
protected DownloadStationSettings _settings;
|
||||
|
||||
[SetUp]
|
||||
protected void Setup()
|
||||
{
|
||||
_settings = new DownloadStationSettings();
|
||||
}
|
||||
|
||||
private void GivenValidResponse()
|
||||
{
|
||||
Mocker.GetMock<IDSMInfoProxy>()
|
||||
.Setup(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
|
||||
.Returns("serial");
|
||||
}
|
||||
|
||||
private void GivenInvalidResponse()
|
||||
{
|
||||
Mocker.GetMock<IDSMInfoProxy>()
|
||||
.Setup(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
|
||||
.Throws(new DownloadClientException("Serial response invalid"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_hashedserialnumber()
|
||||
{
|
||||
GivenValidResponse();
|
||||
|
||||
var serial = Subject.GetSerialNumber(_settings);
|
||||
|
||||
// This hash should remain the same for 'serial', so don't update the test if you change HashConverter, fix the code instead.
|
||||
serial.Should().Be("50DE66B735D30738618568294742FCF1DFA52A47");
|
||||
|
||||
Mocker.GetMock<IDSMInfoProxy>()
|
||||
.Verify(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_cache_serialnumber()
|
||||
{
|
||||
GivenValidResponse();
|
||||
|
||||
var serial1 = Subject.GetSerialNumber(_settings);
|
||||
var serial2 = Subject.GetSerialNumber(_settings);
|
||||
|
||||
serial2.Should().Be(serial1);
|
||||
|
||||
Mocker.GetMock<IDSMInfoProxy>()
|
||||
.Verify(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_serial_number_unavailable()
|
||||
{
|
||||
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.GetSerialNumber(_settings));
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
}
|
||||
}
|
||||