Merge branch 'master' into backbone
Conflicts: .gitignore
This commit is contained in:
commit
0bfc6cfe71
|
@ -1,54 +1,127 @@
|
|||
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
#ignore thumbnails created by windows
|
||||
Thumbs.db
|
||||
#Ignore files build by Visual Studio
|
||||
*.obj
|
||||
# mstest test results
|
||||
TestResults
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.aps
|
||||
*.pch
|
||||
*.vspscc
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ncb
|
||||
*.suo
|
||||
*.tlb
|
||||
*.tlh
|
||||
*.bak
|
||||
*.cache
|
||||
*.ilk
|
||||
*.log
|
||||
[Bb]in
|
||||
[Dd]ebug*/
|
||||
[Rr]elease]*/
|
||||
*.lib
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.nzb
|
||||
obj/
|
||||
_ReSharper*/
|
||||
[Tt]est
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
[Rr]esult[s]
|
||||
[Nn]zbs
|
||||
[Bb]uild/
|
||||
[Ll]ogs/
|
||||
[Aa]pp_Data/
|
||||
packages/
|
||||
/FakesAssemblies/
|
||||
#NZBDrone specific
|
||||
*.db
|
||||
*Web.Publish.xml
|
||||
NzbDrone.Web/NzbDrone.Web.Publish.xml
|
||||
*.sdf
|
||||
[Bb]anners
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Mindbench SASS cache
|
||||
.sass-cache/
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
|
||||
# NuGet Packages Directory
|
||||
packages
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql
|
||||
TestResults
|
||||
[Tt]est[Rr]esult*
|
||||
*.Cache
|
||||
ClientBin
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
# Git Files
|
||||
*.orig
|
||||
_rawPackage/
|
||||
NzbDrone.zip
|
||||
NzbDrone.sln.DotSettings.user*
|
||||
config.xml
|
||||
UpdateLogs/
|
||||
NzbDrone.Web/MediaCover
|
||||
NzbDrone.fpr
|
||||
nzbdrone.log*txt
|
||||
_rawPackage_service/
|
||||
|
||||
# Tools
|
||||
_NCrunch_*
|
||||
_TeamCity*
|
||||
NCrunch_*
|
||||
|
||||
# NzbDrone
|
||||
config.xml
|
||||
nzbdrone.log*txt
|
||||
NzbDrone.Web/MediaCover
|
||||
UpdateLogs/
|
|
@ -1,6 +1,7 @@
|
|||
// ReSharper disable InconsistentNaming
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
|
@ -88,6 +89,7 @@ namespace NzbDrone.Common.Test
|
|||
public void ToString_on_new_processInfo()
|
||||
{
|
||||
Console.WriteLine(new ProcessInfo().ToString());
|
||||
ExceptionVerification.MarkInconclusive(typeof(Win32Exception));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Results>0</Results>
|
|
@ -0,0 +1,420 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Results>
|
||||
<show>
|
||||
<showid>6753</showid>
|
||||
<name>Top Gear</name>
|
||||
<link>http://www.tvrage.com/Top_Gear</link>
|
||||
<country>UK</country>
|
||||
<started>Oct/20/2002</started>
|
||||
<ended></ended>
|
||||
<seasons>18</seasons>
|
||||
<status>Returning Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre></genre>
|
||||
<genre>Automobiles</genre>
|
||||
<genre>Comedy</genre>
|
||||
</genres>
|
||||
<network country="UK">BBC TWO</network>
|
||||
<airtime>20:00</airtime>
|
||||
<airday>Sunday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>19321</showid>
|
||||
<name>Top Gear (1978)</name>
|
||||
<link>http://www.tvrage.com/shows/id-19321</link>
|
||||
<country>UK</country>
|
||||
<started>Jul/13/1978</started>
|
||||
<ended>Dec/17/2001</ended>
|
||||
<seasons>24</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>30</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Automobiles</genre>
|
||||
</genres>
|
||||
<network country="UK">BBC TWO</network>
|
||||
<airtime>12:00</airtime>
|
||||
<airday>Sunday</airday>
|
||||
<akas>
|
||||
<aka country="UK">Top Gear Xtra</aka>
|
||||
</akas>
|
||||
</show>
|
||||
<show>
|
||||
<showid>20568</showid>
|
||||
<name>Top Gear (US)</name>
|
||||
<link>http://www.tvrage.com/Top_Gear_US</link>
|
||||
<country>US</country>
|
||||
<started>Nov/21/2010</started>
|
||||
<ended></ended>
|
||||
<seasons>3</seasons>
|
||||
<status>Returning Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Documentary</classification>
|
||||
<genres>
|
||||
<genre>Automobiles</genre>
|
||||
<genre>Comedy</genre>
|
||||
</genres>
|
||||
<network country="US">History Channel</network>
|
||||
<airtime>21:00</airtime>
|
||||
<airday>Tuesday</airday>
|
||||
<akas>
|
||||
<aka attr="Unofficial Working Title">Top Gear USA</aka>
|
||||
</akas>
|
||||
</show>
|
||||
<show>
|
||||
<showid>20324</showid>
|
||||
<name>Top Gear Australia</name>
|
||||
<link>http://www.tvrage.com/shows/id-20324</link>
|
||||
<country>AU</country>
|
||||
<started>Sep/29/2008</started>
|
||||
<ended></ended>
|
||||
<seasons>4</seasons>
|
||||
<status>Returning Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Documentary</classification>
|
||||
<genres>
|
||||
<genre>Automobiles</genre>
|
||||
<genre>Comedy</genre>
|
||||
</genres>
|
||||
<network country="AU">GEM</network>
|
||||
<airtime>18:30</airtime>
|
||||
<airday>Saturday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>20569</showid>
|
||||
<name>Top Gear Motorsport</name>
|
||||
<link>http://www.tvrage.com/shows/id-20569</link>
|
||||
<country>UK</country>
|
||||
<started>Mar/24/1995</started>
|
||||
<ended>1998</ended>
|
||||
<seasons>3</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>30</runtime>
|
||||
<classification>Sports</classification>
|
||||
<genres>
|
||||
<genre>Educational</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>How To/Do It Yourself</genre>
|
||||
</genres>
|
||||
<network country="UK">BBC TWO</network>
|
||||
<airtime>12:00</airtime>
|
||||
<airday>Wednesday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>6249</showid>
|
||||
<name>Top Secret Life of Edgar Briggs</name>
|
||||
<link>http://www.tvrage.com/shows/id-6249</link>
|
||||
<country>UK</country>
|
||||
<started>Sep/15/1974</started>
|
||||
<ended>Dec/20/1974</ended>
|
||||
<seasons>1</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>30</runtime>
|
||||
<classification>Scripted</classification>
|
||||
<genres>
|
||||
<genre>Comedy</genre>
|
||||
</genres>
|
||||
<network country="UK">ITV</network>
|
||||
<airtime>19:00</airtime>
|
||||
<airday>Friday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>25253</showid>
|
||||
<name>Popstar Wesley: Op weg naar de Top</name>
|
||||
<link>http://www.tvrage.com/shows/id-25253</link>
|
||||
<country>NL</country>
|
||||
<started>Feb/06/2010</started>
|
||||
<ended>Feb/27/2010</ended>
|
||||
<seasons>1</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>15</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>How To/Do It Yourself</genre>
|
||||
<genre>Music</genre>
|
||||
<genre>Talent</genre>
|
||||
</genres>
|
||||
<network country="NL">SBS 6</network>
|
||||
<airtime>23:15</airtime>
|
||||
<airday>Saturday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>19649</showid>
|
||||
<name>Top Chef: Masters</name>
|
||||
<link>http://www.tvrage.com/Top_Chef-Masters</link>
|
||||
<country>US</country>
|
||||
<started>Jun/10/2009</started>
|
||||
<ended></ended>
|
||||
<seasons>4</seasons>
|
||||
<status>Returning Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Cooking/Food</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>Talent</genre>
|
||||
</genres>
|
||||
<network country="US">Bravo</network>
|
||||
<airtime>22:00</airtime>
|
||||
<airday>Wednesday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>26212</showid>
|
||||
<name>Top Chef: Just Desserts</name>
|
||||
<link>http://www.tvrage.com/Top_Chef-Just_Desserts</link>
|
||||
<country>US</country>
|
||||
<started>Sep/15/2010</started>
|
||||
<ended></ended>
|
||||
<seasons>2</seasons>
|
||||
<status>New Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Celebrities</genre>
|
||||
<genre>Cooking/Food</genre>
|
||||
<genre>Educational</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>How To/Do It Yourself</genre>
|
||||
<genre>Talent</genre>
|
||||
</genres>
|
||||
<network country="US">Bravo</network>
|
||||
<airtime>22:00</airtime>
|
||||
<airday>Wednesday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>11210</showid>
|
||||
<name>Top Design</name>
|
||||
<link>http://www.tvrage.com/shows/id-11210</link>
|
||||
<country>US</country>
|
||||
<started>Jan/31/2007</started>
|
||||
<ended>Nov/05/2008</ended>
|
||||
<seasons>2</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Celebrities</genre>
|
||||
<genre>Educational</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>Housing/Building</genre>
|
||||
<genre>How To/Do It Yourself</genre>
|
||||
</genres>
|
||||
<network country="US">Bravo</network>
|
||||
<airtime>22:00</airtime>
|
||||
<airday>Wednesday</airday>
|
||||
<akas>
|
||||
<aka attr="Working Title">Top Decorator</aka>
|
||||
<aka attr="Working Title">Top Designer</aka>
|
||||
</akas>
|
||||
</show>
|
||||
<show>
|
||||
<showid>15390</showid>
|
||||
<name>Air Gear</name>
|
||||
<link>http://www.tvrage.com/shows/id-15390</link>
|
||||
<country>AJ</country>
|
||||
<started>Apr/04/2006</started>
|
||||
<ended>Sep/26/2006</ended>
|
||||
<seasons>1</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>30</runtime>
|
||||
<classification>Animation</classification>
|
||||
<genres>
|
||||
<genre>Anime</genre>
|
||||
<genre>Adventure</genre>
|
||||
<genre>Sci-Fi</genre>
|
||||
<genre>Tech/Gaming</genre>
|
||||
</genres>
|
||||
<network country="JP">TV Tokyo</network>
|
||||
<airtime>12:00</airtime>
|
||||
<airday>Wednesday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>30933</showid>
|
||||
<name>Top Guns</name>
|
||||
<link>http://www.tvrage.com/shows/id-30933</link>
|
||||
<country>US</country>
|
||||
<started>Feb/15/2012</started>
|
||||
<ended></ended>
|
||||
<seasons>1</seasons>
|
||||
<status>New Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Action</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>How To/Do It Yourself</genre>
|
||||
<genre>Talent</genre>
|
||||
</genres>
|
||||
<network country="US">H2 TV</network>
|
||||
<airtime>22:00</airtime>
|
||||
<airday>Wednesday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>28150</showid>
|
||||
<name>Top Chef Canada</name>
|
||||
<link>http://www.tvrage.com/shows/id-28150</link>
|
||||
<country>CA</country>
|
||||
<started>Apr/11/2011</started>
|
||||
<ended></ended>
|
||||
<seasons>2</seasons>
|
||||
<status>New Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Cooking/Food</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>Talent</genre>
|
||||
</genres>
|
||||
<network country="CA">Food Network Canada</network>
|
||||
<airtime>21:00</airtime>
|
||||
<airday>Monday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>6386</showid>
|
||||
<name>Top of the Pops Saturday</name>
|
||||
<link>http://www.tvrage.com/shows/id-6386</link>
|
||||
<country>UK</country>
|
||||
<started>Sep/20/2003</started>
|
||||
<ended>Mar/26/2005</ended>
|
||||
<seasons>2</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Variety</classification>
|
||||
<genres>
|
||||
<genre>Children</genre>
|
||||
</genres>
|
||||
<network country="UK">BBC One</network>
|
||||
<airtime>23:00</airtime>
|
||||
<airday>Saturday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>29633</showid>
|
||||
<name>Top Secret Recipe</name>
|
||||
<link>http://www.tvrage.com/shows/id-29633</link>
|
||||
<country>US</country>
|
||||
<started>Oct/07/2011</started>
|
||||
<ended></ended>
|
||||
<seasons>1</seasons>
|
||||
<status>New Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Cooking/Food</genre>
|
||||
<genre>How To/Do It Yourself</genre>
|
||||
</genres>
|
||||
<network country="US">CMT</network>
|
||||
<airtime>21:00</airtime>
|
||||
<airday>Thursday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>26650</showid>
|
||||
<name>The Top 100: NFL's Greatest Players</name>
|
||||
<link>http://www.tvrage.com/shows/id-26650</link>
|
||||
<country>US</country>
|
||||
<started>Sep/03/2010</started>
|
||||
<ended>Nov/04/2010</ended>
|
||||
<seasons>1</seasons>
|
||||
<status>New Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Sports</classification>
|
||||
<genres>
|
||||
<genre>Sports</genre>
|
||||
</genres>
|
||||
<network country="US">NFL Network</network>
|
||||
<airtime>21:00</airtime>
|
||||
<airday>Thursday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>7047</showid>
|
||||
<name>Top of the Pops Reloaded</name>
|
||||
<link>http://www.tvrage.com/shows/id-7047</link>
|
||||
<country>UK</country>
|
||||
<started>Sep/2005</started>
|
||||
<ended>Mar/2006</ended>
|
||||
<seasons>2</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>45</runtime>
|
||||
<classification>Variety</classification>
|
||||
<genres>
|
||||
<genre>Children</genre>
|
||||
<genre>Music</genre>
|
||||
<genre>Sketch/Improv</genre>
|
||||
</genres>
|
||||
<network country="UK">CBBC</network>
|
||||
<airtime>11:00</airtime>
|
||||
<airday>Saturday</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>19475</showid>
|
||||
<name>Top Model Ghana</name>
|
||||
<link>http://www.tvrage.com/shows/id-19475</link>
|
||||
<country>GH</country>
|
||||
<started>Aug/26/2006</started>
|
||||
<ended>Oct/16/2006</ended>
|
||||
<seasons>1</seasons>
|
||||
<status>Canceled/Ended</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Celebrities</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>Fashion/Make-up</genre>
|
||||
<genre>Talent</genre>
|
||||
<genre>Travel</genre>
|
||||
</genres>
|
||||
<network country="GH">GTV</network>
|
||||
<airtime>21:00</airtime>
|
||||
<airday>Monday</airday>
|
||||
<akas>
|
||||
<aka attr="Alternate title" country="US">Ghana's Next Top Model</aka>
|
||||
<aka attr="Abbreviated title" country="GH">TMG</aka>
|
||||
<aka attr="1st Season title" country="GH">Top Model Ghana, Cycle</aka>
|
||||
</akas>
|
||||
</show>
|
||||
<show>
|
||||
<showid>31823</showid>
|
||||
<name>Top 100 Video Games of All Time</name>
|
||||
<link>http://www.tvrage.com/shows/id-31823</link>
|
||||
<country>US</country>
|
||||
<started>Jun/11/2012</started>
|
||||
<ended></ended>
|
||||
<seasons>1</seasons>
|
||||
<status>New Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Mini-Series</classification>
|
||||
<genres>
|
||||
<genre>Family</genre>
|
||||
<genre>Teens</genre>
|
||||
</genres>
|
||||
<network country="US">G4</network>
|
||||
<airtime>20:00</airtime>
|
||||
<airday>Weekdays</airday>
|
||||
</show>
|
||||
<show>
|
||||
<showid>25003</showid>
|
||||
<name>Cantore Stories: On Top of the World</name>
|
||||
<link>http://www.tvrage.com/Cantore_Stories-On_Top_of_the_World</link>
|
||||
<country>US</country>
|
||||
<started>Jan/24/2010</started>
|
||||
<ended></ended>
|
||||
<seasons>1</seasons>
|
||||
<status>New Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Reality</classification>
|
||||
<genres>
|
||||
<genre>Adventure</genre>
|
||||
<genre>Educational</genre>
|
||||
<genre>Family</genre>
|
||||
<genre>Travel</genre>
|
||||
</genres>
|
||||
<network country="US">The Weather Channel</network>
|
||||
<airtime>22:00</airtime>
|
||||
<airday>Sunday</airday>
|
||||
<akas>
|
||||
<aka attr="Short title" country="US">Cantore Stories</aka>
|
||||
</akas>
|
||||
</show>
|
||||
</Results>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Results>
|
||||
<show>
|
||||
<showid>27518</showid>
|
||||
<name>Suits</name>
|
||||
<link>http://www.tvrage.com/Suits</link>
|
||||
<country>US</country>
|
||||
<started>Jun/23/2011</started>
|
||||
<ended></ended>
|
||||
<seasons>2</seasons>
|
||||
<status>Returning Series</status>
|
||||
<runtime>60</runtime>
|
||||
<classification>Scripted</classification>
|
||||
<genres>
|
||||
<genre>Drama</genre>
|
||||
<genre>Financial/Business</genre>
|
||||
</genres>
|
||||
<network country="US">USA</network>
|
||||
<airtime>22:00</airtime>
|
||||
<airday>Thursday</airday>
|
||||
<akas>
|
||||
<aka attr="Working title" country="US">A Legal Mind</aka>
|
||||
</akas>
|
||||
</show>
|
||||
</Results>
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Showinfo></Showinfo>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Showinfo>
|
||||
<showid>29999</showid>
|
||||
<showname>Anger Management</showname>
|
||||
<showlink>http://tvrage.com/shows/id-29999</showlink>
|
||||
<seasons>2</seasons>
|
||||
<started>2012</started>
|
||||
<startdate>Jun/28/2012</startdate>
|
||||
<ended></ended>
|
||||
<origin_country>US</origin_country>
|
||||
<status>Returning Series</status>
|
||||
<classification>Scripted</classification>
|
||||
<genres>
|
||||
<genre>Comedy</genre>
|
||||
</genres>
|
||||
<runtime>30</runtime>
|
||||
<network country="US">FX</network>
|
||||
<airtime>21:30</airtime>
|
||||
<airday>Thursday</airday>
|
||||
<timezone>GMT-5 -DST</timezone>
|
||||
</Showinfo>
|
|
@ -12,16 +12,12 @@ using NzbDrone.Core.Providers;
|
|||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
namespace NzbDrone.Core.Test.HelperTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class SortHelperTest : CoreTest
|
||||
{
|
||||
//American Gladiators
|
||||
//Ancient Apocalypse
|
||||
//There Will Be Brawl
|
||||
|
||||
[TestCase("The Office (US)", "Office (US)")]
|
||||
[TestCase("A Man in Anger", "Man in Anger")]
|
||||
[TestCase("An Idiot Abroad", "Idiot Abroad")]
|
||||
|
@ -32,7 +28,7 @@ namespace NzbDrone.Core.Test
|
|||
[TestCase(null, "")]
|
||||
public void SkipArticles(string title, string expected)
|
||||
{
|
||||
var result = SortHelper.SkipArticles(title);
|
||||
var result = title.IgnoreArticles();
|
||||
result.Should().Be(expected);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// ReSharper disable RedundantUsingDirective
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using Ninject;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using TvdbLib.Data;
|
||||
using TvdbLib.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.Test.HelperTests.XElementHelperTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class ParseDayOfWeekFixture : CoreTest
|
||||
{
|
||||
[Test]
|
||||
public void should_return_null_if_xelement_is_null()
|
||||
{
|
||||
XElement test = null;
|
||||
test.ConvertToDayOfWeek().Should().Be(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_value_is_null()
|
||||
{
|
||||
new XElement("airday", null).ConvertToDayOfWeek().Should().Be(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_value_is_empty()
|
||||
{
|
||||
new XElement("airday", "").ConvertToDayOfWeek().Should().Be(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_value_is_daily()
|
||||
{
|
||||
new XElement("airday", "Daily").ConvertToDayOfWeek().Should().Be(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_value_is_weekdays()
|
||||
{
|
||||
new XElement("airday", "Weekdays").ConvertToDayOfWeek().Should().Be(null);
|
||||
}
|
||||
|
||||
[TestCase("Sunday", DayOfWeek.Sunday)]
|
||||
[TestCase("Monday", DayOfWeek.Monday)]
|
||||
[TestCase("Tuesday", DayOfWeek.Tuesday)]
|
||||
[TestCase("Wednesday", DayOfWeek.Wednesday)]
|
||||
[TestCase("Thursday", DayOfWeek.Thursday)]
|
||||
[TestCase("Friday", DayOfWeek.Friday)]
|
||||
[TestCase("Saturday", DayOfWeek.Saturday)]
|
||||
public void should_return_dayOfWeek_when_it_is_valid(string value, DayOfWeek expected)
|
||||
{
|
||||
new XElement("airday", value).ConvertToDayOfWeek().Should().Be(expected);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// ReSharper disable RedundantUsingDirective
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Model.Notification;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.HelperTests.XElementHelperTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class XElementHelperTest : CoreTest
|
||||
{
|
||||
[Test]
|
||||
public void Int32_should_return_zero_when_xelement_is_null()
|
||||
{
|
||||
XElement test = null;
|
||||
|
||||
test.ConvertTo<Int32>().Should().Be(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Int32_should_return_zero_when_value_is_null()
|
||||
{
|
||||
new XElement("test", null).ConvertTo<Int32>().Should().Be(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Int32_should_return_value_when_value_is_an_int()
|
||||
{
|
||||
new XElement("test", 10).ConvertTo<Int32>().Should().Be(10);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Nullable_Int32_should_return_null_when_xelement_is_null()
|
||||
{
|
||||
XElement test = null;
|
||||
|
||||
test.ConvertTo<Nullable<Int32>>().Should().Be(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DateTime_should_return_zero_when_xelement_is_null()
|
||||
{
|
||||
XElement test = null;
|
||||
|
||||
test.ConvertTo<DateTime>().Should().Be(DateTime.MinValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DateTime_should_return_zero_when_value_is_null()
|
||||
{
|
||||
new XElement("test", null).ConvertTo<DateTime>().Should().Be(DateTime.MinValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DateTime_should_return_value_when_value_is_a_date()
|
||||
{
|
||||
var date = DateTime.Today;
|
||||
new XElement("test", date.ToString()).ConvertTo<DateTime>().Should().Be(date);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,8 +27,6 @@ namespace NzbDrone.Core.Test.JobTests
|
|||
.With(s => s.SeriesId = 12)
|
||||
.Build();
|
||||
|
||||
WithStrictMocker();
|
||||
|
||||
Mocker.GetMock<SeriesProvider>()
|
||||
.Setup(p => p.GetSeries(series.SeriesId))
|
||||
.Returns(series);
|
||||
|
@ -54,8 +52,6 @@ namespace NzbDrone.Core.Test.JobTests
|
|||
.TheNext(1).With(s => s.SeriesId = 15)
|
||||
.Build();
|
||||
|
||||
WithStrictMocker();
|
||||
|
||||
Mocker.GetMock<SeriesProvider>()
|
||||
.Setup(p => p.GetAllSeries())
|
||||
.Returns(series);
|
||||
|
@ -82,8 +78,6 @@ namespace NzbDrone.Core.Test.JobTests
|
|||
.TheNext(1).With(s => s.SeriesId = 15)
|
||||
.Build();
|
||||
|
||||
WithStrictMocker();
|
||||
|
||||
Mocker.GetMock<SeriesProvider>()
|
||||
.Setup(p => p.GetAllSeries())
|
||||
.Returns(series);
|
||||
|
@ -111,8 +105,6 @@ namespace NzbDrone.Core.Test.JobTests
|
|||
.TheNext(1).With(s => s.SeriesId = 15)
|
||||
.Build();
|
||||
|
||||
WithStrictMocker();
|
||||
|
||||
Mocker.GetMock<SeriesProvider>()
|
||||
.Setup(p => p.GetAllSeries())
|
||||
.Returns(series);
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Jobs;
|
||||
using NzbDrone.Core.Model.Notification;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.JobTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class RenameSeasonJobFixture : TestBase
|
||||
{
|
||||
private ProgressNotification _testNotification;
|
||||
private Series _series;
|
||||
private IList<EpisodeFile> _episodeFiles;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_testNotification = new ProgressNotification("TEST");
|
||||
|
||||
_series = Builder<Series>
|
||||
.CreateNew()
|
||||
.Build();
|
||||
|
||||
_episodeFiles = Builder<EpisodeFile>
|
||||
.CreateListOfSize(5)
|
||||
.All()
|
||||
.With(e => e.SeasonNumber = 5)
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<SeriesProvider>()
|
||||
.Setup(s => s.GetSeries(_series.SeriesId))
|
||||
.Returns(_series);
|
||||
|
||||
Mocker.GetMock<MediaFileProvider>()
|
||||
.Setup(s => s.GetSeasonFiles(_series.SeriesId, 5))
|
||||
.Returns(_episodeFiles);
|
||||
}
|
||||
|
||||
private void WithMovedFiles()
|
||||
{
|
||||
Mocker.GetMock<DiskScanProvider>()
|
||||
.Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), false))
|
||||
.Returns(_episodeFiles.First());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_seriesId_is_zero()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = 0, SeasonNumber = 10 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_seasonId_is_less_than_zero()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = _series.SeriesId, SeasonNumber = -10 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_log_warning_if_no_episode_files_are_found()
|
||||
{
|
||||
Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = _series.SeriesId, SeasonNumber = 10 });
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_if_no_episodes_are_moved()
|
||||
{
|
||||
Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = _series.SeriesId, SeasonNumber = 5 });
|
||||
|
||||
Mocker.GetMock<MetadataProvider>().Verify(v => v.RemoveForEpisodeFiles(It.IsAny<List<EpisodeFile>>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_process_metadata_if_files_are_moved()
|
||||
{
|
||||
WithMovedFiles();
|
||||
Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = _series.SeriesId, SeasonNumber = 5 });
|
||||
|
||||
Mocker.GetMock<MetadataProvider>().Verify(v => v.RemoveForEpisodeFiles(It.IsAny<List<EpisodeFile>>()), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -144,6 +144,15 @@
|
|||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="HelperTests\XElementHelperTests\ConvertToTFixture.cs" />
|
||||
<Compile Include="JobTests\RenameSeasonJobFixture.cs" />
|
||||
<Compile Include="ProviderTests\SearchProviderTests\GetSeriesTitleFixture.cs" />
|
||||
<Compile Include="ProviderTests\TvRageMappingProviderTests\FindMatchingTvRageSeriesFixture.cs" />
|
||||
<Compile Include="ProviderTests\TvRageMappingProviderTests\ProcessResultsFixture.cs" />
|
||||
<Compile Include="ProviderTests\TvRageProviderTests\GetSeriesFixture.cs" />
|
||||
<Compile Include="HelperTests\XElementHelperTests\ConvertToDayOfWeekFixture.cs" />
|
||||
<Compile Include="ProviderTests\TvRageProviderTests\GetUtcOffsetFixture.cs" />
|
||||
<Compile Include="ProviderTests\TvRageProviderTests\SearchSeriesFixture.cs" />
|
||||
<Compile Include="QualityTypesTest.cs" />
|
||||
<Compile Include="EpisodeParseResultTest.cs" />
|
||||
<Compile Include="Integeration\ServiceIntegerationFixture.cs" />
|
||||
|
@ -204,7 +213,7 @@
|
|||
<Compile Include="ProviderTests\XemCommunicationProviderTests\GetSceneTvdbMappingsFixture.cs" />
|
||||
<Compile Include="ProviderTests\XemCommunicationProviderTests\GetXemSeriesIdsFixture.cs" />
|
||||
<Compile Include="Services\ParseErrorServiceFixture.cs" />
|
||||
<Compile Include="SortHelperTest.cs" />
|
||||
<Compile Include="HelperTests\SortHelperFixture.cs" />
|
||||
<Compile Include="ProviderTests\EpisodeProviderTests\EpisodeProviderTest_DeleteInvalidEpisodes.cs" />
|
||||
<Compile Include="ProviderTests\DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
|
||||
<Compile Include="ProviderTests\QualityTypeProviderTest.cs" />
|
||||
|
@ -333,6 +342,21 @@
|
|||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="Files\TvRage\SeriesInfo_empty.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\TvRage\SeriesInfo_one.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\TvRage\SearchResults_one.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\TvRage\SearchResults_many.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\TvRage\SearchResults_empty.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\Xem\Ids.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
|
|
@ -72,6 +72,10 @@ namespace NzbDrone.Core.Test.ParserFixture
|
|||
[TestCase("Top Gear - 07x03 - 2005.11.70", "Top Gear", 7, 3)]
|
||||
[TestCase("Hatfields and McCoys 2012 Part 1 REPACK 720p HDTV x264 2HD", "Hatfields and McCoys 2012", 1, 1)]
|
||||
[TestCase("Glee.S04E09.Swan.Song.1080p.WEB-DL.DD5.1.H.264-ECI", "Glee", 4, 9)]
|
||||
[TestCase("S08E20 50-50 Carla [DVD]", "", 8, 20)]
|
||||
[TestCase("Cheers S08E20 50-50 Carla [DVD]", "Cheers", 8, 20)]
|
||||
[TestCase("S02E10 6-50 to SLC [SDTV]", "", 2, 10)]
|
||||
[TestCase("Franklin & Bash S02E10 6-50 to SLC [SDTV]", "Franklin & Bash", 2, 10)]
|
||||
public void ParseTitle_single(string postTitle, string title, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
var result = Parser.ParseTitle(postTitle);
|
||||
|
@ -396,5 +400,12 @@ namespace NzbDrone.Core.Test.ParserFixture
|
|||
{
|
||||
Parser.ParseHeader(title).Should().Be(expected);
|
||||
}
|
||||
|
||||
[TestCase("password - \"bdc435cb-93c4-4902-97ea-ca00568c3887.337\" yEnc")]
|
||||
public void should_not_parse_encypted_posts(string title)
|
||||
{
|
||||
Parser.ParseTitle(title).Should().BeNull();
|
||||
ExceptionVerification.IgnoreWarns();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.ProviderTests.SearchProviderTests
|
||||
{
|
||||
public class GetSeriesTitleFixture : TestBase
|
||||
{
|
||||
private Series _series;
|
||||
private const string SCENE_NAME = "Scandal";
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_series = Builder<Series>
|
||||
.CreateNew()
|
||||
.With(s => s.Title = "Scandal (2012)")
|
||||
.Build();
|
||||
}
|
||||
|
||||
private void WithSceneName()
|
||||
{
|
||||
Mocker.GetMock<SceneMappingProvider>()
|
||||
.Setup(s => s.GetSceneName(_series.SeriesId))
|
||||
.Returns("Scandal");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_scene_name_when_sceneName_is_available()
|
||||
{
|
||||
WithSceneName();
|
||||
|
||||
Mocker.Resolve<SearchProvider>().GetSeriesTitle(_series).Should().Be(SCENE_NAME);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_seriesTitle_when_sceneName_is_not_available()
|
||||
{
|
||||
Mocker.Resolve<SearchProvider>().GetSeriesTitle(_series).Should().Be(_series.Title);
|
||||
}
|
||||
|
||||
[TestCase("Mike & Molly", "Mike and Molly")]
|
||||
[TestCase("Franklin & Bash", "Franklin and Bash")]
|
||||
[TestCase("Law & Order", "Law and Order")]
|
||||
public void should_replace_ampersand_with_and_when_returning_title(string seriesTitle, string expectedTitle)
|
||||
{
|
||||
_series.Title = seriesTitle;
|
||||
|
||||
Mocker.Resolve<SearchProvider>().GetSeriesTitle(_series).Should().Be(expectedTitle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.ProviderTests.SearchProviderTests
|
|||
.Returns(parseResults);
|
||||
_episodeIndexer1.Setup(c => c.FetchPartialSeason(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(parseResults);
|
||||
|
||||
_episodeIndexer1.Setup(s => s.Name).Returns("Episode Indexer 1");
|
||||
|
||||
_episodeIndexer2 = new Mock<IndexerBase>();
|
||||
_episodeIndexer2.Setup(c => c.FetchEpisode(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()))
|
||||
|
@ -74,14 +74,17 @@ namespace NzbDrone.Core.Test.ProviderTests.SearchProviderTests
|
|||
.Returns(parseResults);
|
||||
_episodeIndexer2.Setup(c => c.FetchPartialSeason(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(parseResults);
|
||||
_episodeIndexer2.Setup(s => s.Name).Returns("Episode Indexer 2");
|
||||
|
||||
_brokenIndexer = new Mock<IndexerBase>();
|
||||
_brokenIndexer.Setup(c => c.FetchEpisode(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Throws(new Exception());
|
||||
_brokenIndexer.Setup(s => s.Name).Returns("Broken Indexer");
|
||||
|
||||
_nullIndexer = new Mock<IndexerBase>();
|
||||
_nullIndexer.Setup(c => c.FetchEpisode(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns<List<EpisodeParseResult>>(null);
|
||||
_nullIndexer.Setup(s => s.Name).Returns("Null Indexer");
|
||||
}
|
||||
|
||||
private void WithTwoGoodOneBrokenIndexer()
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace NzbDrone.Core.Test.ProviderTests
|
|||
[TestCase("The Simpsons")]
|
||||
[TestCase("Family Guy")]
|
||||
[TestCase("South Park")]
|
||||
[TestCase("Franklin & Bash")]
|
||||
public void successful_search(string title)
|
||||
{
|
||||
var result = tvDbProvider.SearchSeries(title);
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Model.TvRage;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.ProviderTests.TvRageMappingProviderTests
|
||||
{
|
||||
public class FindMatchingTvRageSeriesFixture : TestBase
|
||||
{
|
||||
private IList<TvRageSearchResult> _searchResults;
|
||||
private Series _series;
|
||||
private Episode _episode;
|
||||
private TvRageSeries _tvRageSeries;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_searchResults = Builder<TvRageSearchResult>
|
||||
.CreateListOfSize(5)
|
||||
.Build();
|
||||
|
||||
_series = Builder<Series>
|
||||
.CreateNew()
|
||||
.With(s => s.TvRageId = 0)
|
||||
.With(s => s.TvRageTitle = null)
|
||||
.With(s => s.UtcOffset = 0)
|
||||
.Build();
|
||||
|
||||
_episode = Builder<Episode>
|
||||
.CreateNew()
|
||||
.With(e => e.AirDate = DateTime.Today.AddDays(-365))
|
||||
.Build();
|
||||
|
||||
_tvRageSeries = Builder<TvRageSeries>
|
||||
.CreateNew()
|
||||
.With(s => s.UtcOffset = -8)
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<EpisodeProvider>()
|
||||
.Setup(s => s.GetEpisode(_series.SeriesId, 1, 1))
|
||||
.Returns(_episode);
|
||||
|
||||
Mocker.GetMock<SceneMappingProvider>()
|
||||
.Setup(s => s.GetCleanName(_series.SeriesId))
|
||||
.Returns("");
|
||||
|
||||
Mocker.GetMock<TvRageProvider>()
|
||||
.Setup(s => s.SearchSeries(_series.Title))
|
||||
.Returns(_searchResults);
|
||||
|
||||
Mocker.GetMock<TvRageProvider>()
|
||||
.Setup(s => s.GetSeries(_searchResults.First().ShowId))
|
||||
.Returns(_tvRageSeries);
|
||||
}
|
||||
|
||||
private void WithMatchingResult()
|
||||
{
|
||||
_series.CleanTitle = Parser.NormalizeTitle(_searchResults.First().Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_set_tvRage_info_when_result_is_null()
|
||||
{
|
||||
var result = Mocker.Resolve<TvRageMappingProvider>()
|
||||
.FindMatchingTvRageSeries(_series);
|
||||
|
||||
result.TvRageId.Should().Be(0);
|
||||
result.TvRageTitle.Should().Be(null);
|
||||
result.UtcOffset.Should().Be(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_tvRage_info_when_result_is_returned()
|
||||
{
|
||||
WithMatchingResult();
|
||||
|
||||
var result = Mocker.Resolve<TvRageMappingProvider>()
|
||||
.FindMatchingTvRageSeries(_series);
|
||||
|
||||
result.TvRageId.Should().Be(_searchResults.First().ShowId);
|
||||
result.TvRageTitle.Should().Be(_searchResults.First().Name);
|
||||
result.UtcOffset.Should().Be(_tvRageSeries.UtcOffset);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Model.TvRage;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.ProviderTests.TvRageMappingProviderTests
|
||||
{
|
||||
public class ProcessResultsFixture : TestBase
|
||||
{
|
||||
private IList<TvRageSearchResult> _searchResults;
|
||||
private Series _series;
|
||||
private Episode _episode;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_searchResults = Builder<TvRageSearchResult>
|
||||
.CreateListOfSize(5)
|
||||
.Build();
|
||||
|
||||
_series = Builder<Series>.CreateNew().Build();
|
||||
|
||||
_episode = Builder<Episode>
|
||||
.CreateNew()
|
||||
.With(e => e.AirDate = DateTime.Today.AddDays(-365))
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_no_match_is_found()
|
||||
{
|
||||
Mocker.Resolve<TvRageMappingProvider>()
|
||||
.ProcessResults(_searchResults, _series, "nomatchhere", _episode)
|
||||
.Should()
|
||||
.BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_result_if_series_clean_name_matches()
|
||||
{
|
||||
_series.CleanTitle = Parser.NormalizeTitle(_searchResults.First().Name);
|
||||
|
||||
Mocker.Resolve<TvRageMappingProvider>()
|
||||
.ProcessResults(_searchResults, _series, "nomatchhere", _episode)
|
||||
.Should()
|
||||
.Be(_searchResults.First());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_result_if_scene_clean_name_matches()
|
||||
{
|
||||
Mocker.Resolve<TvRageMappingProvider>()
|
||||
.ProcessResults(_searchResults, _series, Parser.NormalizeTitle(_searchResults.First().Name), _episode)
|
||||
.Should()
|
||||
.Be(_searchResults.First());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_result_if_firstAired_matches()
|
||||
{
|
||||
_episode.AirDate = _searchResults.Last().Started;
|
||||
|
||||
Mocker.Resolve<TvRageMappingProvider>()
|
||||
.ProcessResults(_searchResults, _series, "nomatchhere", _episode)
|
||||
.Should()
|
||||
.Be(_searchResults.Last());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// ReSharper disable RedundantUsingDirective
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ninject;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using TvdbLib.Data;
|
||||
using TvdbLib.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class GetSeriesFixture : CoreTest
|
||||
{
|
||||
private const string showinfo = "http://services.tvrage.com/feeds/showinfo.php?key=NW4v0PSmQIoVmpbASLdD&sid=";
|
||||
|
||||
private void WithEmptyResults()
|
||||
{
|
||||
Mocker.GetMock<HttpProvider>()
|
||||
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(showinfo)), null))
|
||||
.Returns(new FileStream(@".\Files\TVRage\SeriesInfo_empty.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||
}
|
||||
|
||||
private void WithOneResult()
|
||||
{
|
||||
Mocker.GetMock<HttpProvider>()
|
||||
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(showinfo)), null))
|
||||
.Returns(new FileStream(@".\Files\TVRage\SeriesInfo_one.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_null_when_no_showinfo_is_returned()
|
||||
{
|
||||
WithEmptyResults();
|
||||
Mocker.Resolve<TvRageProvider>().GetSeries(100).Should().BeNull();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_series_when_showinfo_is_valid()
|
||||
{
|
||||
WithOneResult();
|
||||
var result = Mocker.Resolve<TvRageProvider>().GetSeries(29999);
|
||||
|
||||
result.ShowId.Should().Be(29999);
|
||||
result.Name.Should().Be("Anger Management");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// ReSharper disable RedundantUsingDirective
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using Ninject;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using TvdbLib.Data;
|
||||
using TvdbLib.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class GetUtcOffsetFixture : CoreTest
|
||||
{
|
||||
[Test]
|
||||
public void should_return_zero_if_timeZone_is_empty()
|
||||
{
|
||||
Mocker.Resolve<TvRageProvider>().GetUtcOffset("").Should().Be(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_zero_if_cannot_be_coverted_to_int()
|
||||
{
|
||||
Mocker.Resolve<TvRageProvider>().GetUtcOffset("adfhadfhdjaf").Should().Be(0);
|
||||
}
|
||||
|
||||
[TestCase("GMT-5", -5)]
|
||||
[TestCase("GMT+0", 0)]
|
||||
[TestCase("GMT+8", 8)]
|
||||
public void should_return_offset_when_not_dst(string timezone, int expected)
|
||||
{
|
||||
Mocker.Resolve<TvRageProvider>().GetUtcOffset(timezone).Should().Be(expected);
|
||||
}
|
||||
|
||||
[TestCase("GMT-5 +DST", -4)]
|
||||
[TestCase("GMT+0 +DST", 1)]
|
||||
[TestCase("GMT+8 +DST", 9)]
|
||||
public void should_return_offset_plus_one_when_dst(string timezone, int expected)
|
||||
{
|
||||
Mocker.Resolve<TvRageProvider>().GetUtcOffset(timezone).Should().Be(expected);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
// ReSharper disable RedundantUsingDirective
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ninject;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using TvdbLib.Data;
|
||||
using TvdbLib.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.Test.ProviderTests.TvRageProviderTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class SearchSeriesFixture : CoreTest
|
||||
{
|
||||
private const string search = "http://services.tvrage.com/feeds/full_search.php?show=";
|
||||
|
||||
private void WithEmptyResults()
|
||||
{
|
||||
Mocker.GetMock<HttpProvider>()
|
||||
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
|
||||
.Returns(new FileStream(@".\Files\TVRage\SearchResults_empty.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||
}
|
||||
|
||||
private void WithManyResults()
|
||||
{
|
||||
Mocker.GetMock<HttpProvider>()
|
||||
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
|
||||
.Returns(new FileStream(@".\Files\TVRage\SearchResults_many.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||
}
|
||||
|
||||
private void WithOneResult()
|
||||
{
|
||||
Mocker.GetMock<HttpProvider>()
|
||||
.Setup(s => s.DownloadStream(It.Is<String>(u => u.StartsWith(search)), null))
|
||||
.Returns(new FileStream(@".\Files\TVRage\SearchResults_one.xml", FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_empty_when_no_results_are_found()
|
||||
{
|
||||
WithEmptyResults();
|
||||
Mocker.Resolve<TvRageProvider>().SearchSeries("asdasdasdasdas").Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_have_more_than_one_when_multiple_results_are_returned()
|
||||
{
|
||||
WithManyResults();
|
||||
Mocker.Resolve<TvRageProvider>().SearchSeries("top+gear").Should().NotBeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_have_one_when_only_one_result_is_found()
|
||||
{
|
||||
WithOneResult();
|
||||
Mocker.Resolve<TvRageProvider>().SearchSeries("suits").Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ended_should_not_have_a_value_when_series_has_not_ended()
|
||||
{
|
||||
WithOneResult();
|
||||
Mocker.Resolve<TvRageProvider>().SearchSeries("suits").First().Ended.HasValue.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void started_should_match_series()
|
||||
{
|
||||
WithOneResult();
|
||||
Mocker.Resolve<TvRageProvider>().SearchSeries("suits").First().Started.Should().Be(new DateTime(2011, 6, 23));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using Migrator.Framework;
|
||||
using NzbDrone.Common;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migrations
|
||||
{
|
||||
[Migration(20121218)]
|
||||
public class Migration20121218 : NzbDroneMigration
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Database.AddColumn("Series", new Column("TvRageId", DbType.Int32, ColumnProperty.Null));
|
||||
Database.AddColumn("Series", new Column("TvRageTitle", DbType.String, ColumnProperty.Null));
|
||||
Database.AddColumn("Series", new Column("UtcOffset", DbType.Int32, ColumnProperty.Null));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -112,6 +112,12 @@ namespace NzbDrone.Core
|
|||
private const Decimal ONE_GIGABYTE = ONE_MEGABYTE * 1024M;
|
||||
|
||||
public static string ToBestFileSize(this long bytes, int precision = 0)
|
||||
{
|
||||
var ulongBytes = (ulong)bytes;
|
||||
return ulongBytes.ToBestFileSize(precision);
|
||||
}
|
||||
|
||||
public static string ToBestFileSize(this ulong bytes, int precision = 0)
|
||||
{
|
||||
if (bytes == 0)
|
||||
return "0B";
|
||||
|
|
|
@ -5,9 +5,9 @@ using System.Text;
|
|||
|
||||
namespace NzbDrone.Core.Helpers
|
||||
{
|
||||
public class SortHelper
|
||||
public static class SortHelper
|
||||
{
|
||||
public static string SkipArticles(string input)
|
||||
public static string IgnoreArticles(this string input)
|
||||
{
|
||||
if (String.IsNullOrEmpty(input))
|
||||
return String.Empty;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace NzbDrone.Core.Helpers
|
||||
{
|
||||
public static class XElementHelper
|
||||
{
|
||||
public static T ConvertTo<T>(this XElement element)
|
||||
{
|
||||
if (element == null)
|
||||
return default(T);
|
||||
|
||||
if (String.IsNullOrEmpty(element.Value))
|
||||
return default(T);
|
||||
|
||||
var converter = TypeDescriptor.GetConverter(typeof(T));
|
||||
try
|
||||
{
|
||||
return (T)converter.ConvertFromString(element.Value);
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public static DayOfWeek? ConvertToDayOfWeek(this XElement element)
|
||||
{
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
if (String.IsNullOrWhiteSpace(element.Value))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return (DayOfWeek)Enum.Parse(typeof(DayOfWeek), element.Value);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,13 +15,16 @@ namespace NzbDrone.Core.Jobs
|
|||
{
|
||||
private readonly SeriesProvider _seriesProvider;
|
||||
private readonly DiskScanProvider _diskScanProvider;
|
||||
private readonly ConfigProvider _configProvider;
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Inject]
|
||||
public DiskScanJob(SeriesProvider seriesProvider, DiskScanProvider diskScanProvider)
|
||||
public DiskScanJob(SeriesProvider seriesProvider, DiskScanProvider diskScanProvider,
|
||||
ConfigProvider configProvider)
|
||||
{
|
||||
_seriesProvider = seriesProvider;
|
||||
_diskScanProvider = diskScanProvider;
|
||||
_configProvider = configProvider;
|
||||
}
|
||||
|
||||
public DiskScanJob()
|
||||
|
@ -43,7 +46,11 @@ namespace NzbDrone.Core.Jobs
|
|||
IList<Series> seriesToScan;
|
||||
if (options == null || options.SeriesId == 0)
|
||||
{
|
||||
seriesToScan = _seriesProvider.GetAllSeries().OrderBy(o => SortHelper.SkipArticles(o.Title)).ToList();
|
||||
if (_configProvider.IgnoreArticlesWhenSortingSeries)
|
||||
seriesToScan = _seriesProvider.GetAllSeries().OrderBy(o => o.Title.IgnoreArticles()).ToList();
|
||||
|
||||
else
|
||||
seriesToScan = _seriesProvider.GetAllSeries().OrderBy(o => o.Title).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -85,12 +85,20 @@ namespace NzbDrone.Core.Jobs
|
|||
}
|
||||
}
|
||||
|
||||
if(!oldEpisodeFiles.Any())
|
||||
{
|
||||
logger.Trace("No episodes were renamed for: {0} Season {1}, no changes were made", series.Title,
|
||||
options.SeasonNumber);
|
||||
notification.CurrentMessage = String.Format("Rename completed for: {0} Season {1}, no changes were made", series.Title, options.SeasonNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
//Remove & Create Metadata for episode files
|
||||
//Todo: Add a metadata manager to avoid this hack
|
||||
_metadataProvider.RemoveForEpisodeFiles(oldEpisodeFiles);
|
||||
_metadataProvider.CreateForEpisodeFiles(newEpisodeFiles);
|
||||
|
||||
//Start AfterRename
|
||||
|
||||
var message = String.Format("Renamed: Series {0}, Season: {1}", series.Title, options.SeasonNumber);
|
||||
_externalNotificationProvider.AfterRename(message, series);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ using Ninject;
|
|||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Model.Notification;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Jobs
|
||||
|
@ -15,15 +16,17 @@ namespace NzbDrone.Core.Jobs
|
|||
private readonly SeriesProvider _seriesProvider;
|
||||
private readonly EpisodeProvider _episodeProvider;
|
||||
private readonly ReferenceDataProvider _referenceDataProvider;
|
||||
private readonly ConfigProvider _configProvider;
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Inject]
|
||||
public UpdateInfoJob(SeriesProvider seriesProvider, EpisodeProvider episodeProvider,
|
||||
ReferenceDataProvider referenceDataProvider)
|
||||
ReferenceDataProvider referenceDataProvider, ConfigProvider configProvider)
|
||||
{
|
||||
_seriesProvider = seriesProvider;
|
||||
_episodeProvider = episodeProvider;
|
||||
_referenceDataProvider = referenceDataProvider;
|
||||
_configProvider = configProvider;
|
||||
}
|
||||
|
||||
public UpdateInfoJob()
|
||||
|
@ -46,7 +49,11 @@ namespace NzbDrone.Core.Jobs
|
|||
IList<Series> seriesToUpdate;
|
||||
if (options == null || options.SeriesId == 0)
|
||||
{
|
||||
seriesToUpdate = _seriesProvider.GetAllSeries().OrderBy(o => SortHelper.SkipArticles(o.Title)).ToList();
|
||||
if (_configProvider.IgnoreArticlesWhenSortingSeries)
|
||||
seriesToUpdate = _seriesProvider.GetAllSeries().OrderBy(o => o.Title.IgnoreArticles()).ToList();
|
||||
|
||||
else
|
||||
seriesToUpdate = _seriesProvider.GetAllSeries().OrderBy(o => o.Title).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace NzbDrone.Core.Model
|
|||
public class EpisodeParseResult
|
||||
{
|
||||
public string SeriesTitle { get; set; }
|
||||
|
||||
public string CleanTitle
|
||||
{
|
||||
get
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Core.Model.TvRage
|
||||
{
|
||||
public class TvRageEpisode
|
||||
{
|
||||
public int EpisodeNumber { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public string ProductionCode { get; set; }
|
||||
public DateTime AirDate { get; set; }
|
||||
public string Link { get; set; }
|
||||
public string Title { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Core.Model.TvRage
|
||||
{
|
||||
public class TvRageSearchResult
|
||||
{
|
||||
public int ShowId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Link { get; set; }
|
||||
public string Country { get; set; }
|
||||
public DateTime Started { get; set; }
|
||||
public DateTime? Ended { get; set; }
|
||||
public int Seasons { get; set; }
|
||||
public string Status { get; set; }
|
||||
public int RunTime { get; set; }
|
||||
public DateTime AirTime { get; set; }
|
||||
public DayOfWeek? AirDay { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Core.Model.TvRage
|
||||
{
|
||||
public class TvRageSeries
|
||||
{
|
||||
public int ShowId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Link { get; set; }
|
||||
public int Seasons { get; set; }
|
||||
public int Started { get; set; }
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime Ended { get; set; }
|
||||
public string OriginCountry { get; set; }
|
||||
public string Status { get; set; }
|
||||
public int RunTime { get; set; }
|
||||
public string Network { get; set; }
|
||||
public DateTime AirTime { get; set; }
|
||||
public DayOfWeek? AirDay { get; set; }
|
||||
public int UtcOffset { get; set; }
|
||||
}
|
||||
}
|
|
@ -229,6 +229,7 @@
|
|||
<Compile Include="Datastore\MigrationLogger.cs" />
|
||||
<Compile Include="Datastore\MigrationsHelper.cs" />
|
||||
<Compile Include="Datastore\CustomeMapper.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20121218.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20121209.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20121202.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20121122.cs" />
|
||||
|
@ -262,6 +263,7 @@
|
|||
<Compile Include="Helpers\EpisodeSortingHelper.cs" />
|
||||
<Compile Include="Helpers\SortHelper.cs" />
|
||||
<Compile Include="Helpers\SabnzbdPriorityTypeConverter.cs" />
|
||||
<Compile Include="Helpers\XElementHelper.cs" />
|
||||
<Compile Include="Jobs\CleanupRecycleBinJob.cs" />
|
||||
<Compile Include="Jobs\XemUpdateJob.cs" />
|
||||
<Compile Include="Jobs\EmptyRecycleBinJob.cs" />
|
||||
|
@ -292,6 +294,9 @@
|
|||
<Compile Include="Model\Sabnzbd\SabQueueItem.cs" />
|
||||
<Compile Include="Model\Sabnzbd\SabVersionModel.cs" />
|
||||
<Compile Include="Model\StatsModel.cs" />
|
||||
<Compile Include="Model\TvRage\TvRageEpisode.cs" />
|
||||
<Compile Include="Model\TvRage\TvRageSearchResult.cs" />
|
||||
<Compile Include="Model\TvRage\TvRageSeries.cs" />
|
||||
<Compile Include="Model\Twitter\TwitterAuthorizationModel.cs" />
|
||||
<Compile Include="Model\UpdatePackage.cs" />
|
||||
<Compile Include="Model\Xbmc\ActionType.cs" />
|
||||
|
@ -346,6 +351,8 @@
|
|||
<Compile Include="Jobs\RssSyncJob.cs" />
|
||||
<Compile Include="Jobs\UpdateInfoJob.cs" />
|
||||
<Compile Include="Providers\StatsProvider.cs" />
|
||||
<Compile Include="Providers\TvRageMappingProvider.cs" />
|
||||
<Compile Include="Providers\TvRageProvider.cs" />
|
||||
<Compile Include="Providers\XemCommunicationProvider.cs" />
|
||||
<Compile Include="Providers\XemProvider.cs" />
|
||||
<Compile Include="Repository\MetadataDefinition.cs" />
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace NzbDrone.Core
|
|||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Episodes without a title, Single (S01E05, 1x05) AND Multi (S01E04E05, 1x04x05, etc)
|
||||
new Regex(@"^(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex])(?<episode>\d{2}(?!\d+)))+\W*)+\W?(?!\\)",
|
||||
new Regex(@"^(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)\W?(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Episodes with a title, Single episodes (S01E05, 1x05, etc) & Multi-episode (S01E05E06, S01E05-06, S01E05 E06, etc)
|
||||
|
@ -140,7 +140,8 @@ namespace NzbDrone.Core
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.ErrorException("An error has occurred while trying to parse " + title, e);
|
||||
if (!title.ToLower().Contains("password") && !title.ToLower().Contains("yenc"))
|
||||
Logger.ErrorException("An error has occurred while trying to parse " + title, e);
|
||||
}
|
||||
|
||||
Logger.Trace("Unable to parse {0}", title);
|
||||
|
@ -150,7 +151,7 @@ namespace NzbDrone.Core
|
|||
|
||||
private static EpisodeParseResult ParseMatchCollection(MatchCollection matchCollection)
|
||||
{
|
||||
var seriesName = matchCollection[0].Groups["title"].Value;
|
||||
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ');
|
||||
|
||||
int airyear;
|
||||
Int32.TryParse(matchCollection[0].Groups["airyear"].Value, out airyear);
|
||||
|
|
|
@ -529,6 +529,13 @@ namespace NzbDrone.Core.Providers.Core
|
|||
set { SetValue("OmgwtfnzbsApiKey", value); }
|
||||
}
|
||||
|
||||
public virtual Boolean IgnoreArticlesWhenSortingSeries
|
||||
{
|
||||
get { return GetValueBoolean("IgnoreArticlesWhenSortingSeries", true); }
|
||||
|
||||
set { SetValue("IgnoreArticlesWhenSortingSeries", value); }
|
||||
}
|
||||
|
||||
private string GetValue(string key)
|
||||
{
|
||||
return GetValue(key, String.Empty);
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using Ninject;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Repository;
|
||||
using PetaPoco;
|
||||
|
@ -25,8 +26,6 @@ namespace NzbDrone.Core.Providers
|
|||
_seriesProvider = seriesProvider;
|
||||
}
|
||||
|
||||
#region IRootDirProvider
|
||||
|
||||
public virtual List<RootDir> GetAll()
|
||||
{
|
||||
return _database.Fetch<RootDir>();
|
||||
|
@ -51,7 +50,7 @@ namespace NzbDrone.Core.Providers
|
|||
_database.Delete<RootDir>(rootDirId);
|
||||
}
|
||||
|
||||
public List<String> GetUnmappedFolders(string path)
|
||||
public virtual List<String> GetUnmappedFolders(string path)
|
||||
{
|
||||
Logger.Debug("Generating list of unmapped folders");
|
||||
if (String.IsNullOrEmpty(path))
|
||||
|
@ -77,26 +76,16 @@ namespace NzbDrone.Core.Providers
|
|||
return results;
|
||||
}
|
||||
|
||||
public virtual string GetMostFreeRootDir()
|
||||
public virtual List<RootDir> AllWithFreeSpace()
|
||||
{
|
||||
ulong maxSize = 0;
|
||||
var maxPath = String.Empty;
|
||||
|
||||
var rootDirs = GetAll();
|
||||
|
||||
foreach (var rootDir in rootDirs)
|
||||
{
|
||||
rootDir.FreeSpace = _diskProvider.FreeDiskSpace(new DirectoryInfo(rootDir.Path));
|
||||
if (rootDir.FreeSpace > maxSize)
|
||||
{
|
||||
maxPath = rootDir.Path;
|
||||
maxSize = rootDir.FreeSpace;
|
||||
}
|
||||
}
|
||||
|
||||
return maxPath;
|
||||
return rootDirs;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -101,5 +101,15 @@ namespace NzbDrone.Core.Providers
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual string GetCleanName(int seriesId)
|
||||
{
|
||||
var item = _database.FirstOrDefault<SceneMapping>("WHERE SeriesId = @0", seriesId);
|
||||
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
return item.CleanTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -570,8 +570,11 @@ namespace NzbDrone.Core.Providers
|
|||
{
|
||||
var title = _sceneMappingProvider.GetSceneName(series.SeriesId);
|
||||
|
||||
if (String.IsNullOrWhiteSpace(title))
|
||||
if(String.IsNullOrWhiteSpace(title))
|
||||
{
|
||||
title = series.Title;
|
||||
title = title.Replace("&", "and");
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
|
|
@ -15,19 +15,24 @@ namespace NzbDrone.Core.Providers
|
|||
{
|
||||
public class SeriesProvider
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly ConfigProvider _configProvider;
|
||||
private readonly TvDbProvider _tvDbProvider;
|
||||
private readonly IDatabase _database;
|
||||
private readonly SceneMappingProvider _sceneNameMappingProvider;
|
||||
private readonly BannerProvider _bannerProvider;
|
||||
private readonly MetadataProvider _metadataProvider;
|
||||
private readonly TvRageMappingProvider _tvRageMappingProvider;
|
||||
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static readonly Regex TimeRegex = new Regex(@"^(?<time>\d+:?\d*)\W*(?<meridiem>am|pm)?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
[Inject]
|
||||
public SeriesProvider(IDatabase database, ConfigProvider configProviderProvider,
|
||||
TvDbProvider tvDbProviderProvider, SceneMappingProvider sceneNameMappingProvider,
|
||||
BannerProvider bannerProvider, MetadataProvider metadataProvider)
|
||||
BannerProvider bannerProvider, MetadataProvider metadataProvider,
|
||||
TvRageMappingProvider tvRageMappingProvider)
|
||||
{
|
||||
_database = database;
|
||||
_configProvider = configProviderProvider;
|
||||
|
@ -35,6 +40,7 @@ namespace NzbDrone.Core.Providers
|
|||
_sceneNameMappingProvider = sceneNameMappingProvider;
|
||||
_bannerProvider = bannerProvider;
|
||||
_metadataProvider = metadataProvider;
|
||||
_tvRageMappingProvider = tvRageMappingProvider;
|
||||
}
|
||||
|
||||
public SeriesProvider()
|
||||
|
@ -106,6 +112,17 @@ namespace NzbDrone.Core.Providers
|
|||
series.BannerUrl = tvDbSeries.BannerPath;
|
||||
series.Network = tvDbSeries.Network;
|
||||
|
||||
try
|
||||
{
|
||||
if(series.TvRageId == 0)
|
||||
series = _tvRageMappingProvider.FindMatchingTvRageSeries(series);
|
||||
}
|
||||
|
||||
catch(Exception ex)
|
||||
{
|
||||
logger.ErrorException("Error getting TvRage information for series: " + series.Title, ex);
|
||||
}
|
||||
|
||||
UpdateSeries(series);
|
||||
_metadataProvider.CreateForSeries(series, tvDbSeries);
|
||||
|
||||
|
@ -114,7 +131,7 @@ namespace NzbDrone.Core.Providers
|
|||
|
||||
public virtual void AddSeries(string title, string path, int tvDbSeriesId, int qualityProfileId, DateTime? airedAfter)
|
||||
{
|
||||
Logger.Info("Adding Series [{0}] Path: [{1}]", tvDbSeriesId, path);
|
||||
logger.Info("Adding Series [{0}] Path: [{1}]", tvDbSeriesId, path);
|
||||
|
||||
if (tvDbSeriesId <=0)
|
||||
{
|
||||
|
@ -175,33 +192,33 @@ namespace NzbDrone.Core.Providers
|
|||
public virtual void DeleteSeries(int seriesId)
|
||||
{
|
||||
var series = GetSeries(seriesId);
|
||||
Logger.Warn("Deleting Series [{0}]", series.Title);
|
||||
logger.Warn("Deleting Series [{0}]", series.Title);
|
||||
|
||||
using (var tran = _database.GetTransaction())
|
||||
{
|
||||
//Delete History, Files, Episodes, Seasons then the Series
|
||||
|
||||
Logger.Debug("Deleting History Items from DB for Series: {0}", series.Title);
|
||||
logger.Debug("Deleting History Items from DB for Series: {0}", series.Title);
|
||||
_database.Delete<History>("WHERE SeriesId=@0", seriesId);
|
||||
|
||||
Logger.Debug("Deleting EpisodeFiles from DB for Series: {0}", series.Title);
|
||||
logger.Debug("Deleting EpisodeFiles from DB for Series: {0}", series.Title);
|
||||
_database.Delete<EpisodeFile>("WHERE SeriesId=@0", seriesId);
|
||||
|
||||
Logger.Debug("Deleting Seasons from DB for Series: {0}", series.Title);
|
||||
logger.Debug("Deleting Seasons from DB for Series: {0}", series.Title);
|
||||
_database.Delete<Season>("WHERE SeriesId=@0", seriesId);
|
||||
|
||||
Logger.Debug("Deleting Episodes from DB for Series: {0}", series.Title);
|
||||
logger.Debug("Deleting Episodes from DB for Series: {0}", series.Title);
|
||||
_database.Delete<Episode>("WHERE SeriesId=@0", seriesId);
|
||||
|
||||
Logger.Debug("Deleting Series from DB {0}", series.Title);
|
||||
logger.Debug("Deleting Series from DB {0}", series.Title);
|
||||
_database.Delete<Series>("WHERE SeriesId=@0", seriesId);
|
||||
|
||||
Logger.Info("Successfully deleted Series [{0}]", series.Title);
|
||||
logger.Info("Successfully deleted Series [{0}]", series.Title);
|
||||
|
||||
tran.Complete();
|
||||
}
|
||||
|
||||
Logger.Trace("Beginning deletion of banner for SeriesID: ", seriesId);
|
||||
logger.Trace("Beginning deletion of banner for SeriesID: ", seriesId);
|
||||
_bannerProvider.Delete(seriesId);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,12 @@ namespace NzbDrone.Core.Providers
|
|||
{
|
||||
Logger.Debug("Searching TVDB for '{0}'", title);
|
||||
|
||||
if(title.Contains(" & "))
|
||||
{
|
||||
Logger.Debug("Removing ampersand before searching");
|
||||
title = title.Replace(" & ", " ");
|
||||
}
|
||||
|
||||
var result = _handler.SearchSeries(title);
|
||||
|
||||
Logger.Debug("Search for '{0}' returned {1} possible results", title, result.Count);
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using Ninject;
|
||||
using NzbDrone.Core.Model.TvRage;
|
||||
using NzbDrone.Core.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class TvRageMappingProvider
|
||||
{
|
||||
private readonly SceneMappingProvider _sceneMappingProvider;
|
||||
private readonly TvRageProvider _tvRageProvider;
|
||||
private readonly EpisodeProvider _episodeProvider;
|
||||
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Inject]
|
||||
public TvRageMappingProvider(SceneMappingProvider sceneMappingProvider,
|
||||
TvRageProvider tvRageProvider, EpisodeProvider episodeProvider)
|
||||
{
|
||||
_sceneMappingProvider = sceneMappingProvider;
|
||||
_tvRageProvider = tvRageProvider;
|
||||
_episodeProvider = episodeProvider;
|
||||
}
|
||||
|
||||
public TvRageMappingProvider()
|
||||
{
|
||||
}
|
||||
|
||||
public Series FindMatchingTvRageSeries(Series series)
|
||||
{
|
||||
var firstEpisode = _episodeProvider.GetEpisode(series.SeriesId, 1, 1);
|
||||
|
||||
var cleanName = _sceneMappingProvider.GetCleanName(series.SeriesId);
|
||||
var results = _tvRageProvider.SearchSeries(series.Title);
|
||||
var result = ProcessResults(results, series, cleanName, firstEpisode);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
logger.Trace("TV Rage: {0} matches TVDB: {1}", result.Name, series.Title);
|
||||
series.TvRageId = result.ShowId;
|
||||
series.TvRageTitle = result.Name;
|
||||
series.UtcOffset = _tvRageProvider.GetSeries(result.ShowId).UtcOffset;
|
||||
}
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
public TvRageSearchResult ProcessResults(IList<TvRageSearchResult> searchResults, Series series, string sceneCleanName, Episode firstEpisode)
|
||||
{
|
||||
foreach (var result in searchResults)
|
||||
{
|
||||
if (Parser.NormalizeTitle(result.Name).Equals(series.CleanTitle))
|
||||
return result;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(sceneCleanName) && Parser.NormalizeTitle(result.Name).Equals(sceneCleanName))
|
||||
return result;
|
||||
|
||||
if (firstEpisode.AirDate.HasValue && result.Started == firstEpisode.AirDate.Value)
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using NLog;
|
||||
using Ninject;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Model.TvRage;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class TvRageProvider
|
||||
{
|
||||
private readonly HttpProvider _httpProvider;
|
||||
private const string TVRAGE_APIKEY = "NW4v0PSmQIoVmpbASLdD";
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Inject]
|
||||
public TvRageProvider(HttpProvider httpProvider)
|
||||
{
|
||||
_httpProvider = httpProvider;
|
||||
}
|
||||
|
||||
public TvRageProvider()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual IList<TvRageSearchResult> SearchSeries(string title)
|
||||
{
|
||||
var searchResults = new List<TvRageSearchResult>();
|
||||
|
||||
var xmlStream = _httpProvider.DownloadStream("http://services.tvrage.com/feeds/full_search.php?show=" + title, null);
|
||||
|
||||
var xml = XDocument.Load(xmlStream);
|
||||
var shows = xml.Descendants("Results").Descendants("show");
|
||||
|
||||
foreach (var s in shows)
|
||||
{
|
||||
try
|
||||
{
|
||||
var show = new TvRageSearchResult();
|
||||
show.ShowId = s.Element("showid").ConvertTo<Int32>();
|
||||
show.Name = s.Element("name").Value;
|
||||
show.Link = s.Element("link").Value;
|
||||
show.Country = s.Element("country").Value;
|
||||
|
||||
show.Started = s.Element("started").ConvertTo<DateTime>();
|
||||
show.Ended = s.Element("ended").ConvertTo<DateTime>();
|
||||
|
||||
if (show.Ended < new DateTime(1900, 1, 1))
|
||||
show.Ended = null;
|
||||
|
||||
show.Seasons = s.Element("seasons").ConvertTo<Int32>();
|
||||
show.Status = s.Element("status").Value;
|
||||
show.RunTime = s.Element("seasons").ConvertTo<Int32>();
|
||||
show.AirTime = s.Element("seasons").ConvertTo<DateTime>();
|
||||
show.AirDay = s.Element("airday").ConvertToDayOfWeek();
|
||||
|
||||
searchResults.Add(show);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.DebugException("Failed to parse TvRage Search Result. Search Term : " + title, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return searchResults;
|
||||
}
|
||||
|
||||
public virtual TvRageSeries GetSeries(int id)
|
||||
{
|
||||
var url = string.Format("http://services.tvrage.com/feeds/showinfo.php?key={0}&sid={1}", TVRAGE_APIKEY, id);
|
||||
var xmlStream = _httpProvider.DownloadStream(url, null);
|
||||
var xml = XDocument.Load(xmlStream);
|
||||
var s = xml.Descendants("Showinfo").First();
|
||||
try
|
||||
{
|
||||
if(s.Element("showid") == null)
|
||||
{
|
||||
logger.Warn("TvRage did not return valid series info for id: {0}", id);
|
||||
return null;
|
||||
}
|
||||
|
||||
var show = new TvRageSeries();
|
||||
show.ShowId = s.Element("showid").ConvertTo<Int32>();
|
||||
show.Name = s.Element("showname").Value;
|
||||
show.Link = s.Element("showlink").Value;
|
||||
show.Seasons = s.Element("seasons").ConvertTo<Int32>();
|
||||
show.Started = s.Element("started").ConvertTo<Int32>();
|
||||
|
||||
show.StartDate = s.Element("startdate").ConvertTo<DateTime>();
|
||||
show.Ended = s.Element("ended").ConvertTo<DateTime>();
|
||||
|
||||
show.OriginCountry = s.Element("origin_country").Value;
|
||||
show.Status = s.Element("status").Value;
|
||||
show.RunTime = s.Element("runtime").ConvertTo<Int32>();
|
||||
show.Network = s.Element("network").Value;
|
||||
show.AirTime = s.Element("airtime").ConvertTo<DateTime>();
|
||||
show.AirDay = s.Element("airday").ConvertToDayOfWeek();
|
||||
show.UtcOffset = GetUtcOffset(s.Element("timezone").Value);
|
||||
return show;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.DebugException("Failed to parse ShowInfo for ID: " + id, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual List<TvRageEpisode> GetEpisodes(int id)
|
||||
{
|
||||
var url = String.Format("http://services.tvrage.com/feeds/episode_list.php?key={0}&sid={1}", TVRAGE_APIKEY, id);
|
||||
var xmlStream = _httpProvider.DownloadStream(url, null);
|
||||
var xml = XDocument.Load(xmlStream);
|
||||
var show = xml.Descendants("Show");
|
||||
var seasons = show.Descendants("Season");
|
||||
|
||||
var episodes = new List<TvRageEpisode>();
|
||||
|
||||
foreach (var season in seasons)
|
||||
{
|
||||
var eps = season.Descendants("episode");
|
||||
|
||||
foreach (var e in eps)
|
||||
{
|
||||
try
|
||||
{
|
||||
var episode = new TvRageEpisode();
|
||||
episode.EpisodeNumber = e.Element("epnum").ConvertTo<Int32>();
|
||||
episode.SeasonNumber = e.Element("seasonnum").ConvertTo<Int32>();
|
||||
episode.ProductionCode = e.Element("prodnum").Value;
|
||||
episode.AirDate = e.Element("airdate").ConvertTo<DateTime>();
|
||||
episode.Link = e.Element("link").Value;
|
||||
episode.Title = e.Element("title").Value;
|
||||
episodes.Add(episode);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.DebugException("Failed to parse TV Rage episode", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return episodes;
|
||||
}
|
||||
|
||||
internal int GetUtcOffset(string timeZone)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(timeZone))
|
||||
return 0;
|
||||
|
||||
var offsetString = timeZone.Substring(3, 2);
|
||||
int offset;
|
||||
|
||||
if (!Int32.TryParse(offsetString, out offset))
|
||||
return 0;
|
||||
|
||||
if (timeZone.IndexOf("+DST", StringComparison.CurrentCultureIgnoreCase) > 0)
|
||||
offset++;
|
||||
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,6 +52,12 @@ namespace NzbDrone.Core.Repository
|
|||
|
||||
public bool UseSceneNumbering { get; set; }
|
||||
|
||||
public int TvRageId { get; set; }
|
||||
|
||||
public string TvRageTitle { get; set; }
|
||||
|
||||
public int UtcOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Series"/> is hidden.
|
||||
/// </summary>
|
||||
|
|
|
@ -368,7 +368,7 @@
|
|||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>32122</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>25289</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:62182/</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#menu
|
||||
{
|
||||
height: 60px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#menu ul
|
||||
|
@ -9,6 +10,7 @@
|
|||
padding: 5px 0px 5px 0px;
|
||||
list-style: none;
|
||||
line-height: normal;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#menu li
|
||||
|
|
|
@ -211,19 +211,6 @@ button span, input[type="button"] span, input[type="submit"] span, input[type="r
|
|||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
/* Local Series Search */
|
||||
#localSeriesLookup
|
||||
{
|
||||
width: 220px;
|
||||
float: right;
|
||||
margin-top: 7px;
|
||||
margin-bottom: 0px;
|
||||
border: 0px;
|
||||
background: rgb(75, 75, 75);
|
||||
color: rgb(169, 169, 169);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.ui-dialog-buttonset .ui-delete-button
|
||||
{
|
||||
background: url("jQueryUI/images/ui-bg_flat_30_b40404_40x100.png") repeat-x scroll 50% 50% #B40404;
|
||||
|
@ -261,4 +248,55 @@ button span, input[type="button"] span, input[type="submit"] span, input[type="r
|
|||
/* Font-Awesome */
|
||||
i[class*="icon-"]:not(.gridAction):hover {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Donate */
|
||||
#donate a {
|
||||
background-color: #065EFE;
|
||||
color: #191919;
|
||||
}
|
||||
|
||||
/* Right Menu */
|
||||
#right-menu {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
#right-menu ul {
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#right-menu li
|
||||
{
|
||||
display: block;
|
||||
float: left;
|
||||
padding: 0px 0px 10px 15px;
|
||||
}
|
||||
|
||||
#localSeriesLookup
|
||||
{
|
||||
width: 220px;
|
||||
border: 0px;
|
||||
background: rgb(75, 75, 75);
|
||||
color: rgb(169, 169, 169);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.free-space {
|
||||
display: inline-block;
|
||||
margin-top: 2px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
background-color: #6e6e6e;
|
||||
color: #d0d0d0;
|
||||
/*color: #FFFFFF;*/
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.free-space span {
|
||||
color: #191919;
|
||||
}
|
|
@ -8,6 +8,7 @@ using DataTables.Mvc.Core.Models;
|
|||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Jobs;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Web.Models;
|
||||
|
||||
namespace NzbDrone.Web.Controllers
|
||||
|
@ -16,11 +17,14 @@ namespace NzbDrone.Web.Controllers
|
|||
{
|
||||
private readonly HistoryProvider _historyProvider;
|
||||
private readonly JobProvider _jobProvider;
|
||||
private readonly ConfigProvider _configProvider;
|
||||
|
||||
public HistoryController(HistoryProvider historyProvider, JobProvider jobProvider)
|
||||
public HistoryController(HistoryProvider historyProvider, JobProvider jobProvider,
|
||||
ConfigProvider configProvider)
|
||||
{
|
||||
_historyProvider = historyProvider;
|
||||
_jobProvider = jobProvider;
|
||||
_configProvider = configProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
|
@ -32,6 +36,7 @@ namespace NzbDrone.Web.Controllers
|
|||
{
|
||||
var pageResult = _historyProvider.GetPagedItems(pageRequest);
|
||||
var totalItems = _historyProvider.Count();
|
||||
var ignoreArticles = _configProvider.IgnoreArticlesWhenSortingSeries;
|
||||
|
||||
var items = pageResult.Items.Select(h => new HistoryModel
|
||||
{
|
||||
|
@ -41,7 +46,7 @@ namespace NzbDrone.Web.Controllers
|
|||
EpisodeTitle = h.EpisodeTitle,
|
||||
EpisodeOverview = h.EpisodeOverview,
|
||||
SeriesTitle = h.SeriesTitle,
|
||||
SeriesTitleSorter = SortHelper.SkipArticles(h.SeriesTitle),
|
||||
SeriesTitleSorter = ignoreArticles ? h.SeriesTitle.IgnoreArticles() : h.SeriesTitle,
|
||||
NzbTitle = h.NzbTitle,
|
||||
Quality = h.Quality.ToString(),
|
||||
IsProper = h.IsProper,
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Web.Script.Serialization;
|
|||
using NzbDrone.Core;
|
||||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Web.Models;
|
||||
using ServiceStack.Text;
|
||||
|
||||
|
@ -16,15 +17,18 @@ namespace NzbDrone.Web.Controllers
|
|||
public class MissingController : Controller
|
||||
{
|
||||
private readonly EpisodeProvider _episodeProvider;
|
||||
private readonly ConfigProvider _configProvider;
|
||||
|
||||
public MissingController(EpisodeProvider episodeProvider)
|
||||
public MissingController(EpisodeProvider episodeProvider, ConfigProvider configProvider)
|
||||
{
|
||||
_episodeProvider = episodeProvider;
|
||||
_configProvider = configProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
{
|
||||
var missingEpisodes = _episodeProvider.EpisodesWithoutFiles(false);
|
||||
var ignoreArticles = _configProvider.IgnoreArticlesWhenSortingSeries;
|
||||
|
||||
var missing = missingEpisodes.Select(e => new MissingEpisodeModel
|
||||
{
|
||||
|
@ -34,7 +38,7 @@ namespace NzbDrone.Web.Controllers
|
|||
EpisodeTitle = e.Title,
|
||||
Overview = e.Overview,
|
||||
SeriesTitle = e.Series.Title,
|
||||
SeriesTitleSorter = SortHelper.SkipArticles(e.Series.Title),
|
||||
SeriesTitleSorter = ignoreArticles ? e.Series.Title.IgnoreArticles() : e.Series.Title,
|
||||
AirDateSorter = e.AirDate.Value.ToString("o", CultureInfo.InvariantCulture),
|
||||
AirDate = e.AirDate.Value.ToBestDateString()
|
||||
});
|
||||
|
|
|
@ -11,6 +11,7 @@ using NzbDrone.Core.Helpers;
|
|||
using NzbDrone.Core.Jobs;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
using NzbDrone.Web.Filters;
|
||||
|
@ -25,17 +26,19 @@ namespace NzbDrone.Web.Controllers
|
|||
private readonly SeriesProvider _seriesProvider;
|
||||
private readonly JobProvider _jobProvider;
|
||||
private readonly SeasonProvider _seasonProvider;
|
||||
private readonly ConfigProvider _configProvider;
|
||||
//
|
||||
// GET: /Series/
|
||||
|
||||
public SeriesController(SeriesProvider seriesProvider,
|
||||
QualityProvider qualityProvider, JobProvider jobProvider,
|
||||
SeasonProvider seasonProvider)
|
||||
public SeriesController(SeriesProvider seriesProvider, QualityProvider qualityProvider,
|
||||
JobProvider jobProvider, SeasonProvider seasonProvider,
|
||||
ConfigProvider configProvider)
|
||||
{
|
||||
_seriesProvider = seriesProvider;
|
||||
_qualityProvider = qualityProvider;
|
||||
_jobProvider = jobProvider;
|
||||
_seasonProvider = seasonProvider;
|
||||
_configProvider = configProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
|
@ -177,7 +180,7 @@ namespace NzbDrone.Web.Controllers
|
|||
masterBacklogList.Insert(0, new KeyValuePair<int, string>(-10, "Select..."));
|
||||
ViewData["MasterBacklogSettingSelectList"] = new SelectList(masterBacklogList, "Key", "Value");
|
||||
|
||||
var series = GetSeriesModels(_seriesProvider.GetAllSeries()).OrderBy(o => SortHelper.SkipArticles(o.Title));
|
||||
var series = GetSeriesModels(_seriesProvider.GetAllSeries());
|
||||
|
||||
return View(series);
|
||||
}
|
||||
|
@ -206,11 +209,13 @@ namespace NzbDrone.Web.Controllers
|
|||
|
||||
private List<SeriesModel> GetSeriesModels(IList<Series> seriesInDb)
|
||||
{
|
||||
var ignoreArticles = _configProvider.IgnoreArticlesWhenSortingSeries;
|
||||
|
||||
var series = seriesInDb.Select(s => new SeriesModel
|
||||
{
|
||||
SeriesId = s.SeriesId,
|
||||
Title = s.Title,
|
||||
TitleSorter = SortHelper.SkipArticles(s.Title),
|
||||
TitleSorter = ignoreArticles? s.Title.IgnoreArticles() : s.Title,
|
||||
AirsDayOfWeek = s.AirsDayOfWeek.ToString(),
|
||||
Monitored = s.Monitored,
|
||||
Overview = s.Overview,
|
||||
|
|
|
@ -253,6 +253,7 @@ namespace NzbDrone.Web.Controllers
|
|||
model.EnableBacklogSearching = _configProvider.EnableBacklogSearching;
|
||||
model.AutoIgnorePreviouslyDownloadedEpisodes = _configProvider.AutoIgnorePreviouslyDownloadedEpisodes;
|
||||
model.AllowedReleaseGroups = _configProvider.AllowedReleaseGroups;
|
||||
model.IgnoreArticlesWhenSortingSeries = _configProvider.IgnoreArticlesWhenSortingSeries;
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
@ -662,6 +663,7 @@ namespace NzbDrone.Web.Controllers
|
|||
_configProvider.EnableBacklogSearching = data.EnableBacklogSearching;
|
||||
_configProvider.AutoIgnorePreviouslyDownloadedEpisodes = data.AutoIgnorePreviouslyDownloadedEpisodes;
|
||||
_configProvider.AllowedReleaseGroups = data.AllowedReleaseGroups;
|
||||
_configProvider.IgnoreArticlesWhenSortingSeries = data.IgnoreArticlesWhenSortingSeries;
|
||||
|
||||
return GetSuccessResult();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Web.Mvc;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Web.Models;
|
||||
|
||||
namespace NzbDrone.Web.Controllers
|
||||
|
@ -7,10 +8,12 @@ namespace NzbDrone.Web.Controllers
|
|||
public class SharedController : Controller
|
||||
{
|
||||
private readonly EnvironmentProvider _environmentProvider;
|
||||
private readonly RootDirProvider _rootDirProvider;
|
||||
|
||||
public SharedController(EnvironmentProvider environmentProvider)
|
||||
public SharedController(EnvironmentProvider environmentProvider, RootDirProvider rootDirProvider)
|
||||
{
|
||||
_environmentProvider = environmentProvider;
|
||||
_rootDirProvider = rootDirProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
|
@ -24,5 +27,14 @@ namespace NzbDrone.Web.Controllers
|
|||
{
|
||||
return PartialView(new FooterModel { BuildTime = _environmentProvider.BuildDateTime, Version = _environmentProvider.Version });
|
||||
}
|
||||
|
||||
[ChildActionOnly]
|
||||
[OutputCache(Duration = 600)]
|
||||
public ActionResult FreeSpace()
|
||||
{
|
||||
var rootDirs = _rootDirProvider.AllWithFreeSpace();
|
||||
|
||||
return PartialView(rootDirs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,5 +20,9 @@ namespace NzbDrone.Web.Models
|
|||
[Description("Comma separated list of release groups to download episodes (leave empty for all groups)")]
|
||||
[DisplayFormat(ConvertEmptyStringToNull = false)]
|
||||
public string AllowedReleaseGroups { get; set; }
|
||||
|
||||
[DisplayName("Ignore Articles")]
|
||||
[Description("Ignore articles when sorting by series title?")]
|
||||
public bool IgnoreArticlesWhenSortingSeries { get; set; }
|
||||
}
|
||||
}
|
|
@ -526,6 +526,7 @@
|
|||
<Content Include="Views\System\Indexers.cshtml" />
|
||||
<Content Include="Views\System\Config.cshtml" />
|
||||
<Content Include="Views\Settings\_SettingsLayout.cshtml" />
|
||||
<Content Include="Views\Shared\FreeSpace.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
|
|
|
@ -27,6 +27,11 @@
|
|||
</label>
|
||||
@Html.TextBoxFor(m => m.AllowedReleaseGroups, new { @class = "inputClass" })
|
||||
|
||||
<label class="labelClass">@Html.LabelFor(m => m.IgnoreArticlesWhenSortingSeries)
|
||||
<span class="small">@Html.DescriptionFor(m => m.IgnoreArticlesWhenSortingSeries)</span>
|
||||
</label>
|
||||
@Html.CheckBoxFor(m => m.IgnoreArticlesWhenSortingSeries, new { @class = "inputClass checkClass" })
|
||||
|
||||
<div style="overflow: hidden; height: 50px;">
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
@using NzbDrone.Core
|
||||
@model IEnumerable<NzbDrone.Core.Repository.RootDir>
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
|
||||
|
||||
@{
|
||||
foreach(var rootDir in Model)
|
||||
{
|
||||
<div class="free-space" title="@rootDir.Path">
|
||||
@rootDir.FreeSpace.ToBestFileSize(1) <span>Free</span>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -30,9 +30,16 @@
|
|||
@MvcHtmlString.Create(Html.CurrentControllerLink("Missing", "Index", "Missing"))
|
||||
@MvcHtmlString.Create(Html.CurrentControllerLink("Settings", "Index", "Settings"))
|
||||
@MvcHtmlString.Create(Html.CurrentControllerLink("Logs", "Index", "Log"))
|
||||
<li id="donate" title="Donate to support the development of NzbDrone"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KRTE52U3XJDSQ" target="_blank">Donate</a></li>
|
||||
</ul>
|
||||
<input id="localSeriesLookup" type="text" />
|
||||
</div>
|
||||
<div id="right-menu">
|
||||
<ul>
|
||||
<li>@{ Html.RenderAction("FreeSpace", "Shared"); }</li>
|
||||
<li><input id="localSeriesLookup" type="text" /></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="logo">
|
||||
<span>@ViewBag.Title</span>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue