You've already forked Sonarr
							
							
				mirror of
				https://github.com/Sonarr/Sonarr.git
				synced 2025-10-31 00:07:55 +02:00 
			
		
		
		
	Merge branch 'master' into backbone
Conflicts: .gitignore
This commit is contained in:
		
							
								
								
									
										159
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										159
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -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)); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|   | ||||
							
								
								
									
										3
									
								
								NzbDrone.Core.Test/Files/TvRage/SearchResults_empty.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								NzbDrone.Core.Test/Files/TvRage/SearchResults_empty.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" ?> | ||||
|  | ||||
| <Results>0</Results> | ||||
							
								
								
									
										420
									
								
								NzbDrone.Core.Test/Files/TvRage/SearchResults_many.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										420
									
								
								NzbDrone.Core.Test/Files/TvRage/SearchResults_many.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -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> | ||||
							
								
								
									
										26
									
								
								NzbDrone.Core.Test/Files/TvRage/SearchResults_one.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								NzbDrone.Core.Test/Files/TvRage/SearchResults_one.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -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> | ||||
							
								
								
									
										3
									
								
								NzbDrone.Core.Test/Files/TvRage/SeriesInfo_empty.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								NzbDrone.Core.Test/Files/TvRage/SeriesInfo_empty.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" ?> | ||||
|  | ||||
| <Showinfo></Showinfo> | ||||
							
								
								
									
										22
									
								
								NzbDrone.Core.Test/Files/TvRage/SeriesInfo_one.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								NzbDrone.Core.Test/Files/TvRage/SeriesInfo_one.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||
|   | ||||
							
								
								
									
										93
									
								
								NzbDrone.Core.Test/JobTests/RenameSeasonJobFixture.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								NzbDrone.Core.Test/JobTests/RenameSeasonJobFixture.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										18
									
								
								NzbDrone.Core/Datastore/Migrations/Migration20121218.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								NzbDrone.Core/Datastore/Migrations/Migration20121218.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
|   | ||||
							
								
								
									
										51
									
								
								NzbDrone.Core/Helpers/XElementHelper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								NzbDrone.Core/Helpers/XElementHelper.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
|   | ||||
							
								
								
									
										17
									
								
								NzbDrone.Core/Model/TvRage/TvRageEpisode.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								NzbDrone.Core/Model/TvRage/TvRageEpisode.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								NzbDrone.Core/Model/TvRage/TvRageSearchResult.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								NzbDrone.Core/Model/TvRage/TvRageSearchResult.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										25
									
								
								NzbDrone.Core/Model/TvRage/TvRageSeries.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								NzbDrone.Core/Model/TvRage/TvRageSeries.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||
|   | ||||
							
								
								
									
										69
									
								
								NzbDrone.Core/Providers/TvRageMappingProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								NzbDrone.Core/Providers/TvRageMappingProvider.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										169
									
								
								NzbDrone.Core/Providers/TvRageProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								NzbDrone.Core/Providers/TvRageProvider.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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> | ||||
|          | ||||
|   | ||||
							
								
								
									
										15
									
								
								NzbDrone.Web/Views/Shared/FreeSpace.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								NzbDrone.Web/Views/Shared/FreeSpace.cshtml
									
									
									
									
									
										Normal file
									
								
							| @@ -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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user