diff --git a/NzbDrone.Core.Test/Files/Feed.nzbmatrix.com.xml b/NzbDrone.Core.Test/Files/Feed.nzbmatrix.com.xml
new file mode 100644
index 000000000..4a13c31cc
--- /dev/null
+++ b/NzbDrone.Core.Test/Files/Feed.nzbmatrix.com.xml
@@ -0,0 +1,112 @@
+
+
+
+ NZBMatrix.com RSS 2.0
+ en
+ NZBMatrix
+ NZBMatrix.com RSS Feed - Usenet
+ http://nzbmatrix.com
+ Copyright 2010 NZBMatrix
+ Fri, 23 Apr 2010 01:28:23 -0400
+
+ 24.S08E19.HDTV.XviD-LOL
+ http://nzbmatrix.com/api-nzb-download.php?id=625437
+ http://nzbmatrix.com/api-nzb-download.php?id=625437
+ Name: Craig Ferguson 2010 04 22 Jeffrey Dean Morgan HDTV XviD LMAO Category: TV: Divx/Xvid Size: 424.85MB Added: 2010-04-23 06:22:45]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ CSI.S10E20.HDTV.XviD-LOL
+ http://nzbmatrix.com/api-nzb-download.php?id=625436
+ http://nzbmatrix.com/api-nzb-download.php?id=625436
+ Name: Little People Big World S08E24 Brothers in Bavaria REPACK HDTV XviD MOMENTUM Category: TV: Divx/Xvid Size: 208.22MB Added: 2010-04-23 06:21:44]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ The.Daily.Show.2010.04.29.Michael.Caine.HDTV.XviD-FQM.nzb
+ http://nzbmatrix.com/api-nzb-download.php?id=625435
+ http://nzbmatrix.com/api-nzb-download.php?id=625435
+ Name: Lopez Tonight 2010 04 21 Zoe Saldana HDTV XviD MOMENTUM Category: TV: Divx/Xvid Size: 424.31MB Added: 2010-04-23 06:04:48]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ The Mentalist S02E20 720p HDTV x264 CTU
+ http://nzbmatrix.com/api-nzb-download.php?id=625434
+ http://nzbmatrix.com/api-nzb-download.php?id=625434
+ Name: The Mentalist S02E20 720p HDTV x264 CTU Category: TV: HD Size: 219.79MB Added: 2010-04-23 05:57:50]]>
+ TV: HD
+ tv.hd
+ 41
+
+
+
+ 24.S06E01.HDTV.XviD-LOL
+ http://nzbmatrix.com/api-nzb-download.php?id=625433
+ http://nzbmatrix.com/api-nzb-download.php?id=625433
+ Name: Jimmy Kimmel 2010 04 22 Chace Crawford HDTV XviD 2HD Category: TV: Divx/Xvid Size: 433.32MB Added: 2010-04-23 05:46:31]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ Bones.S05E19.HDTV.XviD-LOL
+ http://nzbmatrix.com/api-nzb-download.php?id=625430
+ http://nzbmatrix.com/api-nzb-download.php?id=625430
+ Name: Project Runway S07E14 WS DSR XviD MOMENTUM Category: TV: Divx/Xvid Size: 430.59MB Added: 2010-04-23 05:34:44]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ David Letterman 2010 04 22 David Spade HDTV XviD LMAO
+ http://nzbmatrix.com/api-nzb-download.php?id=625402
+ http://nzbmatrix.com/api-nzb-download.php?id=625402
+ Name: David Letterman 2010 04 22 David Spade HDTV XviD LMAO Category: TV: Divx/Xvid Size: 416.25MB Added: 2010-04-23 05:20:07]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ Jay Leno 2010 04 22 Jeff Corwin HDTV XviD LMAO
+ http://nzbmatrix.com/api-nzb-download.php?id=625389
+ http://nzbmatrix.com/api-nzb-download.php?id=625389
+ Name: Jay Leno 2010 04 22 Jeff Corwin HDTV XviD LMAO Category: TV: Divx/Xvid Size: 417.51MB Added: 2010-04-23 05:06:07]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ The Colbert Report 2010 04 22 Gorillaz HDTV XviD FQM
+ http://nzbmatrix.com/api-nzb-download.php?id=625387
+ http://nzbmatrix.com/api-nzb-download.php?id=625387
+ Name: The Colbert Report 2010 04 22 Gorillaz HDTV XviD FQM Category: TV: Divx/Xvid Size: 216.94MB Added: 2010-04-23 04:13:02]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+ The Marriage Ref S01E08 HDTV XviD 2HD
+ http://nzbmatrix.com/api-nzb-download.php?id=625386
+ http://nzbmatrix.com/api-nzb-download.php?id=625386
+ Name: The Marriage Ref S01E08 HDTV XviD 2HD Category: TV: Divx/Xvid Size: 431.06MB Added: 2010-04-23 04:11:08]]>
+ TV: Divx/Xvid
+ tv.divx/xvid
+ 6
+
+
+
+
\ No newline at end of file
diff --git a/NzbDrone.Core.Test/HistoryProviderTest.cs b/NzbDrone.Core.Test/HistoryProviderTest.cs
new file mode 100644
index 000000000..3ba755152
--- /dev/null
+++ b/NzbDrone.Core.Test/HistoryProviderTest.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Gallio.Framework;
+using MbUnit.Framework;
+using MbUnit.Framework.ContractVerifiers;
+using Moq;
+using NzbDrone.Core.Providers;
+using NzbDrone.Core.Repository;
+using SubSonic.Repository;
+
+namespace NzbDrone.Core.Test
+{
+ [TestFixture]
+ public class HistoryProviderTest
+ {
+ [Test]
+ public void AllItems()
+ {
+ //Setup
+ var indexer = new Indexer {Enabled = true, Name = "NzbMatrix", Order = 1, RssUrl = "http://www.nzbmatrix.com"};
+ var series = new Series
+ {
+ SeriesId = 5656,
+ CleanTitle = "rock",
+ Monitored = true,
+ Overview = "Series Overview",
+ Quality = 1,
+ Title = "30 Rock",
+ Path = @"C:\Test\TV\30 Rock"
+ };
+ var season = new Season{SeasonId = 4321, SeasonNumber = 1, SeriesId = 5656, Monitored = true};
+ var episode = new Episode
+ {
+ AirDate = DateTime.Today.AddDays(-1),
+ EpisodeId = 1234,
+ EpisodeNumber = 5,
+ Language = "English",
+ Overview = "This is an Overview",
+ SeasonNumber = 1,
+ SeasonId = 4321,
+ Season = season,
+ SeriesId = 5656
+ };
+
+ var list = new List();
+ list.Add(new History
+ {
+ Id = new int(),
+ Date = DateTime.Now,
+ IsProper = false,
+ Quality = 1,
+ Indexer = indexer,
+ Episode = episode,
+ EpisodeId = 1234
+ });
+
+ var repo = new Mock();
+ repo.Setup(r => r.All()).Returns(list.AsQueryable());
+
+ var target = new HistoryProvider(repo.Object);
+
+ //Act
+ var result = target.AllItems();
+
+ //Assert
+ Assert.AreEqual(result.Count(), 1);
+ }
+
+ [Test]
+ public void Exists_True()
+ {
+ //Todo: This test fails... Moq Setup doesn't return the expected value
+ //Setup
+ var indexer = new Indexer { Enabled = true, Name = "NzbMatrix", Order = 1, RssUrl = "http://www.nzbmatrix.com" };
+ var series = new Series
+ {
+ SeriesId = 5656,
+ CleanTitle = "rock",
+ Monitored = true,
+ Overview = "Series Overview",
+ Quality = 1,
+ Title = "30 Rock",
+ Path = @"C:\Test\TV\30 Rock"
+ };
+ var season = new Season { SeasonId = 4321, SeasonNumber = 1, SeriesId = 5656, Monitored = true };
+ var episode = new Episode
+ {
+ AirDate = DateTime.Today.AddDays(-1),
+ EpisodeId = 1234,
+ EpisodeNumber = 5,
+ Language = "English",
+ Overview = "This is an Overview",
+ SeasonNumber = 1,
+ SeasonId = 4321,
+ Season = season,
+ SeriesId = 5656
+ };
+
+ var list = new List();
+ list.Add(new History
+ {
+ Id = new int(),
+ Date = DateTime.Now,
+ IsProper = false,
+ Quality = 1,
+ Indexer = indexer,
+ Episode = episode,
+ EpisodeId = 1234
+ });
+
+ var proper = false;
+
+ var repo = new Mock();
+ repo.Setup(r => r.Exists(h => h.EpisodeId == episode.EpisodeId && h.IsProper == proper)).Returns(true);
+
+ var target = new HistoryProvider(repo.Object);
+
+ //Act
+ var result = target.Exists(episode, false);
+
+ //Assert
+ Assert.AreEqual(result, true);
+ }
+
+ [Test]
+ public void Exists_False()
+ {
+ //Todo: This test fails... Moq Setup doesn't return the expected value
+
+ //Setup
+ var indexer = new Indexer { Enabled = true, Name = "NzbMatrix", Order = 1, RssUrl = "http://www.nzbmatrix.com" };
+ var series = new Series
+ {
+ SeriesId = 5656,
+ CleanTitle = "rock",
+ Monitored = true,
+ Overview = "Series Overview",
+ Quality = 1,
+ Title = "30 Rock",
+ Path = @"C:\Test\TV\30 Rock"
+ };
+ var season = new Season { SeasonId = 4321, SeasonNumber = 1, SeriesId = 5656, Monitored = true };
+ var episode = new Episode
+ {
+ AirDate = DateTime.Today.AddDays(-1),
+ EpisodeId = 1234,
+ EpisodeNumber = 5,
+ Language = "English",
+ Overview = "This is an Overview",
+ SeasonNumber = 1,
+ SeasonId = 4321,
+ Season = season,
+ SeriesId = 5656
+ };
+
+ var list = new List();
+ list.Add(new History
+ {
+ Id = new int(),
+ Date = DateTime.Now,
+ IsProper = false,
+ Quality = 1,
+ Indexer = indexer,
+ Episode = episode,
+ EpisodeId = 1234
+ });
+
+ var repo = new Mock();
+ repo.Setup(r => r.Exists(h => h.Episode == episode && h.IsProper == list[0].IsProper)).Returns(false);
+
+ var target = new HistoryProvider(repo.Object);
+
+ //Act
+ var result = target.Exists(episode, true);
+
+ //Assert
+ Assert.AreEqual(result, false);
+ }
+ }
+}
diff --git a/NzbDrone.Core.Test/IndexerProviderTest.cs b/NzbDrone.Core.Test/IndexerProviderTest.cs
new file mode 100644
index 000000000..6b4640e45
--- /dev/null
+++ b/NzbDrone.Core.Test/IndexerProviderTest.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Gallio.Framework;
+using MbUnit.Framework;
+using MbUnit.Framework.ContractVerifiers;
+using Moq;
+using NzbDrone.Core.Providers;
+using NzbDrone.Core.Repository;
+using SubSonic.Repository;
+
+namespace NzbDrone.Core.Test
+{
+ [TestFixture]
+ public class IndexerProviderTest
+ {
+ [Test]
+ public void AllIndexers()
+ {
+ //
+ // TODO: Add test logic here
+ //
+
+ //Setup
+ var list = new List();
+ list.Add(new Indexer{Name = "Test1", RssUrl = "http://www.test1.com/rss.php", Enabled = true, Order = 1});
+ list.Add(new Indexer{Name = "Test2", RssUrl = "http://www.test2.com/rss.php", Enabled = false, Order = 4});
+ list.Add(new Indexer{Name = "Test3", RssUrl = "http://www.test3.com/rss.php", Enabled = true, Order = 3});
+ list.Add(new Indexer{Name = "Test4", RssUrl = "http://www.test4.com/rss.php", Enabled = false, Order = 2});
+
+ var repo = new Mock();
+ repo.Setup(r => r.All()).Returns(list.AsQueryable());
+
+ var target = new IndexerProvider(repo.Object);
+
+ //Act
+ var result = target.AllIndexers();
+
+ //Assert
+
+ Assert.AreEqual(result.Last().Name, "Test2");
+ }
+
+ [Test]
+ public void EnabledIndexers()
+ {
+ //
+ // TODO: Add test logic here
+ //
+
+ //Setup
+ var list = new List();
+ list.Add(new Indexer { Name = "Test1", RssUrl = "http://www.test1.com/rss.php", Enabled = true, Order = 1 });
+ list.Add(new Indexer { Name = "Test2", RssUrl = "http://www.test2.com/rss.php", Enabled = false, Order = 4 });
+ list.Add(new Indexer { Name = "Test3", RssUrl = "http://www.test3.com/rss.php", Enabled = true, Order = 3 });
+ list.Add(new Indexer { Name = "Test4", RssUrl = "http://www.test4.com/rss.php", Enabled = false, Order = 2 });
+
+ var repo = new Mock();
+ repo.Setup(r => r.All()).Returns(list.AsQueryable());
+
+ var target = new IndexerProvider(repo.Object);
+
+ //Act
+ var result = target.EnabledIndexers();
+
+ //Assert
+ Assert.AreEqual(result.First().Name, "Test1");
+ Assert.AreEqual(result.Last().Name, "Test3");
+ }
+ }
+}
diff --git a/NzbDrone.Core.Test/Libs/Moq.pdb b/NzbDrone.Core.Test/Libs/Moq.pdb
deleted file mode 100644
index 8ec9d72f8..000000000
Binary files a/NzbDrone.Core.Test/Libs/Moq.pdb and /dev/null differ
diff --git a/NzbDrone.Core.Test/Libs/RSS.NET.XML b/NzbDrone.Core.Test/Libs/RSS.NET.XML
new file mode 100644
index 000000000..e60b7797a
--- /dev/null
+++ b/NzbDrone.Core.Test/Libs/RSS.NET.XML
@@ -0,0 +1,1388 @@
+
+
+
+ RSS.NET
+
+
+
+ The contents of a RssFeed
+
+
+ Initialize a new instance of the RssFeed class.
+
+
+ Initialize a new instance of the RssFeed class with a specified encoding.
+
+
+ Returns a string representation of the current Object.
+ The Url of the feed
+
+
+ Reads the specified RSS feed
+ The url or filename of the RSS feed
+ The contents of the feed
+
+
+ Reads the specified RSS feed
+ The specified way to connect to the web server
+ The contents of the feed
+
+
+ Reads the specified RSS feed
+ The cached version of the feed
+ The current contents of the feed
+ Will not download the feed if it has not been modified
+
+
+ Reads the specified RSS feed
+ The specified way to connect to the web server
+ The cached version of the feed
+ The current contents of the feed
+ Will not download the feed if it has not been modified
+
+
+ Writes the RSS feed to the specified stream.
+ specified Stream
+ The Stream cannot be written to.
+ Feed must contain at least one channel.
+ Channel must contain at least one item.
+
+
+ Writes the RSS feed to the specified file.
+ The encoding is ISO-8859-1.
+ The filename is empty, contains only white space, or contains one or more invalid characters.
+ Access is denied.
+ The filename is a (null c#, Nothing vb) reference.
+ The directory to write to is not found.
+ The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
+ The caller does not have the required permission.
+ specified file (including path) If the file exists, it will be truncated with the new content.
+ Feed must contain at least one channel.
+ Channel must contain at least one item.
+
+
+ The channels that are contained in the feed.
+
+
+ The modules that the feed adhears to.
+
+
+ A collection of all exceptions encountered during the reading of the feed.
+
+
+ The Version of the feed.
+
+
+ The server generated hash of the feed.
+
+
+ The server generated last modfified date and time of the feed.
+
+
+ Indicates this feed has not been changed on the server, and the local copy was returned.
+
+
+ Location of the feed
+
+
+ Encoding of the feed
+
+
+ Provide information regarding the location of the subject matter of the channel in a taxonomy
+
+
+ Base class for all RSS elements
+
+
+ Initialize a new instance of the RssElement class
+
+
+ Initialize a new instance of the RssCategory class
+
+
+ Actual categorization given for this item, within the chosen taxonomy
+
+
+ URL of external taxonomy
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified channel to this collection.
+ The channel to add.
+ The zero-based index of the added channel.
+
+
+ Determines whether the RssChannelCollection contains a specific element.
+ The RssChannel to locate in the RssChannelCollection.
+ true if the RssChannelCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssChannelCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssChannel Array that is the destination of the elements copied from RssChannelCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssChannelCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssChannel and returns the zero-based index of the first occurrence within the entire RssChannelCollection.
+ The RssChannel to locate in the RssChannelCollection.
+ The zero-based index of the first occurrence of RssChannel within the entire RssChannelCollection, if found; otherwise, -1.
+
+
+ Inserts a channel into this collection at a specified index.
+ The zero-based index of the collection at which to insert the channel.
+ The channel to insert into this collection.
+
+
+ Removes a specified channel from this collection.
+ The channel to remove.
+
+
+ Gets or sets the channel at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A channel at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ A reference to an attachment to the item
+
+
+ Initialize a new instance of the RssEnclosure class.
+
+
+ Where the enclosure is located
+
+
+ The size of the enclosure, in bytes
+ -1 represents a null.
+
+
+ A standard Multipurpose Internet Mail Extensions (MIME) type
+
+
+ Grouping of related content items on a site
+
+
+ Initialize a new instance of the RssChannel class.
+
+
+ Returns a string representation of the current Object.
+ The channel's title, description, or "RssChannel" if the title and description are blank.
+
+
+ The name of the channel
+ Maximum length is 100 characters (For RSS 0.91)
+
+
+ URL of the website named in the title
+ Maximum length is 500 characters (For RSS 0.91)
+
+
+ Description of the channel
+ Maximum length is 500 characters (For RSS 0.91)
+
+
+ Language the channel is written in
+
+
+ A link and description for a graphic icon that represent a channel
+
+
+ Copyright notice for content in the channel
+ Maximum length is 100 (For RSS 0.91)
+
+
+ The email address of the managing editor of the channel, the person to contact for editorial inquiries
+
+ Maximum length is 100 (For RSS 0.91)
+ The suggested format for email addresses in RSS elements is
+ bull@mancuso.com (Bull Mancuso)
+
+
+
+ The email address of the webmaster for the channel
+
+ Person to contact if there are technical problems
+ Maximum length is 100 (For RSS 0.91)
+ The suggested format for email addresses in RSS elements is
+ bull@mancuso.com (Bull Mancuso)
+
+
+
+ The PICS rating for the channel
+ Maximum length is 500 (For RSS 0.91)
+
+
+ The publication date for the content in the channel, expressed as the coordinated universal time (UTC)
+
+
+ The date-time the last time the content of the channel changed, expressed as the coordinated universal time (UTC)
+
+
+ One or more categories the channel belongs to.
+
+
+ A string indicating the program used to generate the channel
+
+
+ A URL, points to the documentation for the format used in the RSS file
+ Maximum length is 500 (For RSS 0.91).
+
+
+ Provides information about an HTTP GET feature, typically for a search or subscription
+
+
+ Readers should not read the channel during days listed. (UTC)
+ Days are listed in the array in the following order:
+ Monday
+ Tuesday
+ Wednesday
+ Thursday
+ Friday
+ Saturday
+ Sunday
+ Monday
+
+
+
+ Readers should not read the channel during hours listed (UTC)
+ Represents a time in UTC - 1.
+
+
+ Allow processes to register with a cloud to be notified of updates to the channel
+
+
+ The number of minutes that a channel can be cached.
+
+
+ All items within the channel
+
+
+ People in a photo
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssModuleItemCollection contains a specific element.
+ The RssModuleItem to locate in the RssModuleItemCollection.
+ true if the RssModuleItemCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssModuleItemCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssModuleItem Array that is the destination of the elements copied from RssModuleItemCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleItemCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssModuleItem and returns the zero-based index of the first occurrence within the entire RssModuleItemCollection.
+ The RssModuleItem to locate in the RssModuleItemCollection.
+ The zero-based index of the first occurrence of RssModuleItem within the entire RssModuleItemCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ Bind a particular item to this module
+ Hash code of the item
+
+
+ Check if a particular item is bound to this module
+ Hash code of the item
+ true if this item is bound to this module, otherwise false
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhotoPeople class
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhotoPeople class
+ Name of person
+
+
+ Add a person to the photo
+ Name of person
+ The zero-based index of the added item
+
+
+ A collection of photos in a category
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssModuleItemCollectionCollection contains a specific element.
+ The RssModuleItemCollection to locate in the RssModuleItemCollectionCollection.
+ true if the RssModuleItemCollectionCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssModuleItemCollectionCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssModuleItemCollection Array that is the destination of the elements copied from RssModuleItemCollectionCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleItemCollectionCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssModuleItemCollection and returns the zero-based index of the first occurrence within the entire RssModuleItemCollectionCollection.
+ The RssModuleItemCollection to locate in the RssModuleItemCollectionCollection.
+ The zero-based index of the first occurrence of RssModuleItemCollection within the entire RssModuleItemCollectionCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+
+
+ Adds a sepecified photo to this collection.
+ The photo to add.
+ The zero-based index of the added item.
+
+
+ A photo in the category
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ A collection of categories in a photo album
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+
+
+ Adds a sepecified category to this collection.
+ The category to add.
+ The zero-based index of the added item.
+
+
+ A Photo Album category
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ RSS syndication for Robert A. Wlodarczyk's Photo Album application (to be sold by Inno Thinx LLC)
+
+
+ Base class for all RSS modules
+
+
+ Initialize a new instance of the RssModule class
+
+
+ Bind a particular channel to this module
+ Hash code of the channel
+
+
+ Check if a particular channel is bound to this module
+ Hash code of the channel
+ true if this channel is bound to this module, otherwise false
+
+
+ Collection of RSSModuleItem that are to be placed in the channel
+
+
+ Collection of RSSModuleItemCollection that are to be placed in the channel item
+
+
+ Prefix for the given module namespace
+
+
+ URL for the given module namespace
+
+
+ Initialize a new instance of the RssPhotoAlbum class
+ Link to the Photo Album
+ The category of the Photo Album to add
+
+
+ Initialize a new instance of the RssPhotoAlbum class
+ Link to the Photo Album
+ A collection of categories in the Photo Album to add
+
+
+ Link element for channel
+
+
+ Contains default values and methods for maintaining data consistency
+
+
+ Default value for a string in all RSS classes
+ empty string
+ If an element in the RSS class library has the value of RssDefault.String, consider the element as "not entered", "null", or empty.
+
+
+ Default value for an int in all RSS classes
+ -1
+ If an element in the RSS class library has the value of RssDefault.Int, consider the element as "not entered", "null", or empty.
+
+
+ Default value for a DateTime in all RSS classes
+ DateTime.MinValue
+ If an element in the RSS class library has the value of RssDefault.DateTime, consider the element as "not entered", "null", or empty.
+
+
+ Default value for a Uri in all RSS classes
+ gopher://rss-net.sf.net
+ If an element in the RSS class library has the value of RssDefault.Uri, consider the element as "not entered", "null", or empty.
+
+
+ Verifies the string passed is not null
+ string to verify
+ RssDefault.String if input is null, otherwise input
+ Method is used in properties to prevent a null value
+
+
+ Verifies the int passed is greater than or equal to -1
+ int to verify
+ RssDefault.Int if int is less than -1, else input
+ Method is used in properties to prevent values less than -1
+
+
+ Verifies the Uri passed is not null
+ Uri to verify
+ RssDefault.Uri if input is null, otherwise input
+ Method is used in all properties to prevent a null value
+
+
+ Represents Null, False, and True
+ Source: Microsoft c# example
+
+
+ A DBBool containing 'Null'.
+ One of three possible DBBool values.
+
+
+ A DBBool containing 'False'.
+ One of three possible DBBool values.
+
+
+ A DBBool containing 'True'.
+ One of three possible DBBool values.
+
+
+ Private field that stores –1, 0, 1 for False, Null, True.
+
+
+ Private instance constructor. The value parameter must be –1, 0, or 1.
+
+
+ Implicit conversion from bool to DBBool. Maps true to DBBool.True and false to DBBool.False.
+ a DBBool
+
+
+ Explicit conversion from DBBool to bool.
+ The given DBBool is Null
+ a DBBool
+ true or false
+
+
+ Equality operator.
+ a DBBool
+ a DBBool
+ Returns Null if either operand is Null, otherwise returns True or False.
+
+
+ Inequality operator.
+ a DBBool
+ a DBBool
+ Returns Null if either operand is Null, otherwise returns True or False.
+
+
+ Logical negation operator.
+ a DBBool
+ Returns True if the operand is False, Null if the operand is Null, or False if the operand is True.
+
+
+ Logical AND operator.
+ a DBBool
+ a DBBool
+ Returns False if either operand is False, otherwise Null if either operand is Null, otherwise True.
+
+
+ Logical OR operator.
+ a DBBool
+ a DBBool
+ Returns True if either operand is True, otherwise Null if either operand is Null, otherwise False.
+
+
+ Definitely true operator.
+ a DBBool
+ Returns true if the operand is True, false otherwise.
+
+
+ Definitely false operator.
+ a DBBool
+ Returns true if the operand is False, false otherwise.
+
+
+ Determines whether two DBBool instances are equal.
+ The object to check.
+ True if the two DBBools are equal.
+
+
+ Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table.
+ A hash code for the current DBBool.
+
+
+ Returns a string representation of the current Object.
+ Object has not been initialized.
+ A string containing DBBool.False, DBBool.Null, or DBBool.True
+
+
+ Properties to examine the value of a DBBool.
+ Return true if this DBBool has the given value, false otherwise.
+
+
+ Properties to examine the value of a DBBool.
+ Return true if this DBBool has the given value, false otherwise.
+
+
+ Properties to examine the value of a DBBool.
+ Return true if this DBBool has the given value, false otherwise.
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssModuleCollection contains a specific element.
+ The RssModule to locate in the RssModuleCollection.
+ true if the RssModuleCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssModuleCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssModule Array that is the destination of the elements copied from RssModuleCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssModule and returns the zero-based index of the first occurrence within the entire RssModuleCollection.
+ The RssModule to locate in the RssModuleCollection.
+ The zero-based index of the first occurrence of RssModule within the entire RssModuleCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssItemCollection contains a specific element.
+ The RssItem to locate in the RssItemCollection.
+ true if the RssItemCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssItemCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssItem Array that is the destination of the elements copied from RssItemCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssItemCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssItem and returns the zero-based index of the first occurrence within the entire RssItemCollection.
+ The RssItem to locate in the RssItemCollection.
+ The zero-based index of the first occurrence of RssItem within the entire RssItemCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ The latest pubDate in the items collection
+ The latest pubDate -or- RssDefault.DateTime if all item pubDates are not defined
+
+
+ The oldest pubDate in the items collection
+ The oldest pubDate -or- RssDefault.DateTime if all item pubDates are not defined
+
+
+ Calculates the oldest and latest pubdates
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Allow processes to register with a cloud to be notified of updates to the channel.
+
+
+ Initialize a new instance of the RssCloud class.
+
+
+ Domain name or IP address of the cloud
+
+
+ TCP port that the cloud is running on
+
+
+ Location of its responder
+
+
+ Name of the procedure to call to request notification
+
+
+ Protocol used
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified feed to this collection.
+ The feed to add.
+ The zero-based index of the added feed.
+
+
+ Determines whether the RssFeedCollection contains a specific element.
+ The RssFeed to locate in the RssFeedCollection.
+ true if the RssFeedCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssFeedCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssFeed Array that is the destination of the elements copied from RssFeedCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssFeedCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssFeed and returns the zero-based index of the first occurrence within the entire RssFeedCollection.
+ The RssFeed to locate in the RssFeedCollection.
+ The zero-based index of the first occurrence of RssFeed within the entire RssFeedCollection, if found; otherwise, -1.
+
+
+ Inserts a feed into this collection at a specified index.
+ The zero-based index of the collection at which to insert the feed.
+ The feed to insert into this collection.
+
+
+ Removes a specified category from this collection.
+ The category to remove.
+
+
+ Gets or sets the feed at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A feed at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Gets or sets the feed with the given name.In C#, this property is the indexer for the class.
+ The url of the feed to access.
+ A feed at each valid url. If the feed does not exist, null.
+ This method is an indexer that can be used to access the collection.
+
+
+ A RSS module that adds elements at the channel level that are common to weblogs.
+
+
+ Initialize a new instance of the
+ The URL of an OPML file containing the blogroll for the site.
+ The URL of an OPML file containing the author's RSS subscriptions.
+
+ The URL of a weblog that the author of the weblog is promoting per Mark Pilgrim's description.
+ "http://diveintomark.org/archives/2002/09/17.html#blink_and_youll_miss_it"
+
+
+ The URL of a changes.xml file. When the feed that contains this element updates, it pings a server that updates this file. The presence of this element says to aggregators that they only have to read the changes file to see if this feed has updated. If several feeds point to the same changes file, the aggregator has to do less polling, resulting in better use of server bandwidth, and the Internet as a whole; and resulting in faster scans. Everyone wins. For more technical information, see the howto on the XML-RPC site.
+ "http://www.xmlrpc.com/weblogsComForRss"
+
+
+
+ All valid Rss Cloud protocols, including Null
+
+
+ Not defined
+
+
+ Protocol is not supported
+
+
+ xml-rpc
+
+
+ soap
+
+
+ http-post
+
+
+ All RSS versions
+
+
+ Not defined
+
+
+ Version is not directly supported
+
+
+ RDF Site Summary (RSS) 0.9
+
+
+ Rich Site Summary (RSS) 0.91
+
+
+ Rich Site Summary (RSS) 0.92
+
+
+ RDF Site Summary (RSS) 1.0
+
+
+ Really Simple Syndication (RSS) 2.0
+
+
+ Writes an RSS XML file.
+ Represents a writer that provides a fast, non-cached, forward-only way of generating streams or files containing RSS XML data that conforms to the W3C Extensible Markup Language (XML) 1.0 and the Namespaces in XML recommendations.
+
+
+ Creates an instance of the RssWriter class using the specified TextWriter.
+ specified TextWriter
+
+
+ Creates an instance of the RssWriter class using the specified Stream and Encoding.
+ The encoding is not supported or the stream cannot be written to.
+ Stream to output to
+ The encoding to use. If encoding is (null c#, Nothing vb) it writes out the stream as UTF-8.
+
+
+ Creates an instance of the RssWriter class using the specified Stream.
+ The encoding is ISO-8859-1.
+ The Stream cannot be written to.
+ specified Stream
+
+
+ Creates an instance of the RssWriter class using the specified file and Encoding.
+ The encoding is not supported; the filename is empty, contains only white space, or contains one or more invalid characters.
+ Access is denied.
+ The filename is a (null c#, Nothing vb) reference.
+ The directory to write to is not found.
+ The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
+ The caller does not have the required permission.
+ specified file (including path) If the file exists, it will be truncated with the new content.
+ specified Encoding
+
+
+ Creates an instance of the RssWriter class using the specified file.
+ The encoding is ISO-8859-1.
+ The filename is empty, contains only white space, or contains one or more invalid characters.
+ Access is denied.
+ The filename is a (null c#, Nothing vb) reference.
+ The directory to write to is not found.
+ The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
+ The caller does not have the required permission.
+ specified file (including path) If the file exists, it will be truncated with the new content.
+
+
+ Writes the begining data to the RSS file
+ This routine is called from the WriteChannel and WriteItem subs
+ RDF Site Summary (RSS) 1.0 is not currently supported.
+
+
+ Closes instance of RssWriter.
+ Writes end elements, and releases connections
+ Occurs if the RssWriter is already closed or the caller is attempting to close before writing a channel.
+
+
+ Writes an RSS channel
+ RssWriter has been closed, and can not be written to.
+ Channel must be instanciated with data, before calling Write.
+ RSS channel to write
+
+
+ Writes an RSS item
+ Either the RssWriter has already been closed, or the caller is attempting to write an RSS item before an RSS channel.
+ Item must be instanciated with data, before calling Write.
+ RSS item to write
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Gets or sets the RSS version to write.
+ Can't change version number after data has been written.
+
+
+ Gets or sets the of the XML output.
+ Can't change XML formatting after data has been written.
+
+
+ Gets or sets how indentation to write for each level in the hierarchy when XmlFormat is set to
+ Can't change XML formatting after data has been written.
+ Setting this property to a negative value.
+
+
+ RSS modules
+
+
+ Reads an RSS file.
+ Provides fast, non-cached, forward-only access to RSS data.
+
+
+ Initializes a new instance of the RssReader class with the specified URL or filename.
+ The URL or filename for the file containing the RSS data.
+ Occures when unable to retrieve file containing the RSS data.
+
+
+ Creates an instance of the RssReader class using the specified TextReader.
+ specified TextReader
+ Occures when unable to retrieve file containing the RSS data.
+
+
+ Creates an instance of the RssReader class using the specified Stream.
+ Occures when unable to retrieve file containing the RSS data.
+ Stream to read from
+
+
+ Reads the next RssElement from the stream.
+ An RSS Element
+ RssReader has been closed, and can not be read.
+ RSS file not found.
+ Invalid XML syntax in RSS file.
+ Unable to read an RssElement. Reached the end of the stream.
+
+
+ Closes connection to file.
+ This method also releases any resources held while reading.
+
+
+ A collection of all exceptions the RssReader class has encountered.
+
+
+ Gets the RSS version of the stream.
+ One of the values.
+
+
+ Globally unique identifier
+
+
+ Initialize a new instance of the RssGuid class.
+
+
+ If true, a url that can be opened in a web browser that points to the item
+
+
+ Globally unique identifier value
+
+
+ A link and description for a graphic that represent a channel
+
+
+ Initialize a new instance of the RssImage class.
+
+
+ The URL of a GIF, JPEG or PNG image that represents the channel.
+ Maximum length is 500 (For RSS 0.91).
+
+
+ Describes the image, it's used in the ALT attribute of the HTML img tag when the channel is rendered in HTML.
+ Maximum length is 100 (For RSS 0.91).
+
+
+ The URL of the site, when the channel is rendered, the image is a link to the site.
+ Maximum length is 500 (For RSS 0.91).
+
+
+ Contains text that is included in the TITLE attribute of the link formed around the image in the HTML rendering.
+
+
+ Width of image in pixels
+ Maximum value for height is 400 (For RSS 0.91)
+
+
+ Height of image in pixels
+ Maximum value for width is 144 (For RSS 0.91)
+
+
+ A module may contain any number of items (either channel-based or item-based).
+
+
+ Initialize a new instance of the RssModuleItem class
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ Is text required for this RssModuleItem?
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ The text contained within this RssModuleItem.
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ Is text required for this RssModuleItem?
+ The text contained within this RssModuleItem.
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ The text contained within this RssModuleItem.
+ The sub-elements of this RssModuleItem (if any exist).
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ Is text required for this RssModuleItem?
+ The text contained within this RssModuleItem.
+ The sub-elements of this RssModuleItem (if any exist).
+
+
+ Returns a string representation of the current Object.
+ The item's title, description, or "RssModuleItem" if the title and description are blank.
+
+
+
+ The name of this RssModuleItem.
+
+
+
+
+ The text contained within this RssModuleItem.
+
+
+
+
+ The sub-elements of this RssModuleItem (if any exist).
+
+
+
+
+ Is text for this element required?
+
+
+
+ Describes an items source
+
+
+ Initialize a new instance of the RssSource class
+
+
+ Name of the RSS channel that the item came from
+
+
+ URL of the original RSS feed from which the item was republished
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified exception to this collection.
+ The exception to add.
+ The zero-based index of the added exception -or- -1 if the exception already exists.
+
+
+ Determines whether the ExceptionCollection contains a specific element.
+ The Exception to locate in the ExceptionCollection.
+ true if the ExceptionCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire ExceptionCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional Exception Array that is the destination of the elements copied from ExceptionCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source ExceptionCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified Exception and returns the zero-based index of the first occurrence within the entire ExceptionCollection.
+ The Exception to locate in the ExceptionCollection.
+ The zero-based index of the first occurrence of RssChannel within the entire ExceptionCollection, if found; otherwise, -1.
+
+
+ Inserts an Exception into this collection at a specified index.
+ The zero-based index of the collection at which to insert the Exception.
+ The Exception to insert into this collection.
+
+
+ Removes a specified Exception from this collection.
+ The Exception to remove.
+
+
+ Gets or sets the exception at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A exception at each valid index.
+ This method is an indexer that can be used to access the collection.
+
+
+ Returns the last exception added through the Add method.
+ The last exception -or- null if no exceptions exist
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified category to this collection.
+ The category to add.
+ The zero-based index of the added category.
+
+
+ Determines whether the RssCategoryCollection contains a specific element.
+ The RssCategory to locate in the RssCategoryCollection.
+ true if the RssCategoryCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssCategoryCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssCategory Array that is the destination of the elements copied from RssCategoryCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssCategoryCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssCategory and returns the zero-based index of the first occurrence within the entire RssCategoryCollection.
+ The RssCategory to locate in the RssCategoryCollection.
+ The zero-based index of the first occurrence of RssCategory within the entire RssCategoryCollection, if found; otherwise, -1.
+
+
+ Inserts an category into this collection at a specified index.
+ The zero-based index of the collection at which to insert the category.
+ The category to insert into this collection.
+
+
+ Removes a specified category from this collection.
+ The category to remove.
+
+
+ Gets or sets the category at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A category at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ A RSS module that adds elements at the channel or item level that specifies which Creative Commons license applies.
+
+
+ Initialize a new instance of the
+
+ If present as a sub-element of channel, indicates that the content of the RSS file is available under a license, indicated by a URL, which is the value of the license element. A list of some licenses that may be used in this context is on the Creative Commons website on this page, however the license element may point to licenses not authored by Creative Commons.
+ You may also use the license element as a sub-element of item. When used this way it applies only to the content of that item. If an item has a license, and the channel does too, the license on the item applies, i.e. the inner license overrides the outer one.
+ Multiple license elements are allowed, in either context, indicating that the content is available under multiple licenses.
+ "http://www.creativecommons.org/licenses/"
+
+ If present as a sub-element of channel then true, otherwise false
+
+
+ A channel may contain any number of items, each of which links to more information about the item, with an optional description
+
+
+ Initialize a new instance of the RssItem class
+
+
+ Returns a string representation of the current Object.
+ The item's title, description, or "RssItem" if the title and description are blank.
+
+
+ Title of the item
+ Maximum length is 100 (For RSS 0.91)
+
+
+ URL of the item
+ Maximum length is 500 (For RSS 0.91)
+
+
+ Item synopsis
+ Maximum length is 500 (For RSS 0.91)
+
+
+ Email address of the author of the item
+
+
+ Provide information regarding the location of the subject matter of the channel in a taxonomy
+
+
+ URL of a page for comments relating to the item
+
+
+ Describes an items source
+
+
+ A reference to an attachment to the item
+
+
+ A string that uniquely identifies the item
+
+
+ Indicates when the item was published
+
+
+ Multi-purpose channel element for the purpose of allowing users to submit queries back to the publisher's site
+ Typically for a search or subscription
+
+
+ Initialize a new instance of the RssTextInput class
+
+
+ The label of the submit button in the text input area
+ Maximum length is 100 (For RSS 0.91)
+
+
+ Explains the text input area
+ Maximum length is 500 (For RSS 0.91)
+
+
+ The name of the text object in the text input area
+ Maximum length is 20 (For RSS 0.91).
+
+
+ The URL of the script that processes text input requests
+ Maximum length is 500 (For RSS 0.91)
+
+
+
diff --git a/NzbDrone.Core.Test/Libs/RSS.NET.dll b/NzbDrone.Core.Test/Libs/RSS.NET.dll
new file mode 100644
index 000000000..10dd1f774
Binary files /dev/null and b/NzbDrone.Core.Test/Libs/RSS.NET.dll differ
diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
index 4eb6565e2..8f6aa0b11 100644
--- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
+++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
@@ -21,6 +21,7 @@
DEBUG;TRACEprompt4
+ AnyCPUpdbonly
@@ -52,6 +53,10 @@
..\NzbDrone.Core\Libraries\NLog.dll
+
+ False
+ Libs\RSS.NET.dll
+ False..\NzbDrone.Core\Libraries\SubSonic.Core.dll
@@ -68,6 +73,7 @@
+
@@ -80,8 +86,10 @@
+
+
@@ -91,6 +99,9 @@
+
+ Always
+ PreserveNewest
@@ -102,8 +113,9 @@
PreserveNewest
-
+
+ Always
diff --git a/NzbDrone.Core.Test/RssProviderTest.cs b/NzbDrone.Core.Test/RssProviderTest.cs
new file mode 100644
index 000000000..bf95ed775
--- /dev/null
+++ b/NzbDrone.Core.Test/RssProviderTest.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Security.Policy;
+using System.Text;
+using Gallio.Framework;
+using MbUnit.Framework;
+using MbUnit.Framework.ContractVerifiers;
+using Moq;
+using NzbDrone.Core.Model;
+using NzbDrone.Core.Providers;
+using Rss;
+
+namespace NzbDrone.Core.Test
+{
+ [TestFixture]
+ public class RssProviderTest
+ {
+ [Test]
+ public void GetFeed()
+ {
+ //Setup
+ var feedInfo = new FeedInfoModel("NzbMatrix", @"Files\Feed.nzbmatrix.com.xml");
+ var target = new RssProvider();
+
+ //Act
+ var enumerable = target.GetFeed(feedInfo);
+ var result = new List();
+ result.AddRange(enumerable);
+
+ //Assert
+ Assert.GreaterThan(result.Count, 1); //Assert that the number of Items in the feed is greater than 1
+ }
+ }
+}
diff --git a/NzbDrone.Core/CentralDispatch.cs b/NzbDrone.Core/CentralDispatch.cs
index 288539101..a19096bef 100644
--- a/NzbDrone.Core/CentralDispatch.cs
+++ b/NzbDrone.Core/CentralDispatch.cs
@@ -30,11 +30,21 @@ namespace NzbDrone.Core
Logger.Debug("Binding Ninject's Kernel");
_kernel = new StandardKernel();
+ //Sqlite
string connectionString = String.Format("Data Source={0};Version=3;", Path.Combine(AppPath, "nzbdrone.db"));
var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
+ //SQLExpress
+ //string connectionString = String.Format(@"server=.\SQLExpress; database=NzbDrone; Trusted_Connection=True;");
+ //var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SqlClient");
+
+ //Sqlite
string logConnectionString = String.Format("Data Source={0};Version=3;", Path.Combine(AppPath, "log.db"));
var logDbProvider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SQLite");
+
+ //SQLExpress
+ //string logConnectionString = String.Format(@"server=.\SQLExpress; database=NzbDroneLogs; Trusted_Connection=True;");
+ //var logDbProvider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SqlClient");
var logRepository = new SimpleRepository(logDbProvider, SimpleRepositoryOptions.RunMigrations);
//dbProvider.ExecuteQuery(new QueryCommand("VACUUM", dbProvider));
@@ -46,8 +56,12 @@ namespace NzbDrone.Core
_kernel.Bind().To();
_kernel.Bind().To();
_kernel.Bind().To();
+ _kernel.Bind().To();
_kernel.Bind().To().InSingletonScope();
_kernel.Bind().To().InSingletonScope();
+ _kernel.Bind().To().InSingletonScope();
+ _kernel.Bind().To().InSingletonScope();
+ _kernel.Bind().To().InSingletonScope();;
_kernel.Bind().To().InSingletonScope();
_kernel.Bind().To().InSingletonScope();
_kernel.Bind().To().InSingletonScope();
@@ -58,6 +72,7 @@ namespace NzbDrone.Core
ForceMigration(_kernel.Get());
+ SetupIndexers(_kernel.Get()); //Setup the default set of indexers on start-up
}
}
@@ -73,6 +88,16 @@ namespace NzbDrone.Core
}
}
+ public static string ExecutablePath
+ {
+ get
+ {
+ //var uri = new Uri(Assembly.EscapedCodeBase);
+ //return Path.GetDirectoryName(uri.LocalPath);
+ return Directory.GetCurrentDirectory();
+ }
+ }
+
public static IKernel NinjectKernel
{
get
@@ -90,9 +115,9 @@ namespace NzbDrone.Core
repository.GetPaged(0, 1);
repository.GetPaged(0, 1);
repository.GetPaged(0, 1);
+ repository.GetPaged(0, 1);
}
-
///
/// This method forces IISExpress process to exit with the host application
///
@@ -125,5 +150,83 @@ namespace NzbDrone.Core
Logger.Info("Shutting down application.");
Process.GetCurrentProcess().Kill();
}
+
+ private static void SetupIndexers(IRepository repository)
+ {
+ //Setup the default providers in the Providers table
+
+ string nzbMatrixRss = "http://rss.nzbmatrix.com/rss.php?page=download&username=USERNAME&apikey=APIKEY&subcat=6&english=1";
+ string nzbsOrgRss = "http://nzbs.org/rss.php?type=1&dl=1&num=100&i=UID&h=HASH";
+ string nzbsrusRss = "http://www.nzbsrus.com/rssfeed.php?cat=91,75&i=UID&h=HASH";
+
+ var nzbMatrixIndexer = new Indexer
+ {
+ IndexerName = "NzbMatrix",
+ RssUrl = nzbMatrixRss,
+ ApiUrl = String.Empty,
+ Enabled = false,
+ Order = 1
+ };
+
+ var nzbsOrgIndexer = new Indexer
+ {
+ IndexerName = "NzbsOrg",
+ RssUrl = nzbsOrgRss,
+ ApiUrl = String.Empty,
+ Enabled = false,
+ Order = 2
+ };
+
+ var nzbsrusIndexer = new Indexer
+ {
+ IndexerName = "Nzbsrus",
+ RssUrl = nzbsrusRss,
+ ApiUrl = String.Empty,
+ Enabled = false,
+ Order = 3
+ };
+
+ //NzbMatrix
+ Logger.Debug("Checking for NzbMatrix Indexer");
+ if (!repository.Exists(i => i.IndexerName == "NzbMatrix"))
+ {
+ Logger.Debug("Adding new Indexer: NzbMatrix");
+ repository.Add(nzbMatrixIndexer);
+ }
+
+ else
+ {
+ Logger.Debug("Updating Indexer: NzbMatrix");
+ repository.Update(nzbMatrixIndexer);
+ }
+
+ //Nzbs.org
+ Logger.Debug("Checking for Nzbs.org");
+ if (!repository.Exists(i => i.IndexerName == "NzbsOrg"))
+ {
+ Logger.Debug("Adding new Indexer: Nzbs.org");
+ repository.Add(nzbsOrgIndexer);
+ }
+
+ else
+ {
+ Logger.Debug("Updating Indexer: Nzbs.org");
+ repository.Update(nzbsOrgIndexer);
+ }
+
+ //Nzbsrus
+ Logger.Debug("Checking for Nzbsrus");
+ if (!repository.Exists(i => i.IndexerName == "Nzbsrus"))
+ {
+ Logger.Debug("Adding new Indexer: Nzbsrus");
+ repository.Add(nzbsrusIndexer);
+ }
+
+ else
+ {
+ Logger.Debug("Updating Indexer: Nzbsrus");
+ repository.Update(nzbsrusIndexer);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/Instrumentation/Log.cs b/NzbDrone.Core/Instrumentation/Log.cs
index 95883a59c..c6341dc00 100644
--- a/NzbDrone.Core/Instrumentation/Log.cs
+++ b/NzbDrone.Core/Instrumentation/Log.cs
@@ -6,6 +6,7 @@ namespace NzbDrone.Core.Instrumentation
public class Log
{
public int LogId { get; set; }
+ [SubSonicLongString]
public string Message { get; set; }
public DateTime Time { get; set; }
public string Logger { get; set; }
@@ -13,8 +14,10 @@ namespace NzbDrone.Core.Instrumentation
[SubSonicNullString]
public string Stack { get; set; }
[SubSonicNullString]
+ [SubSonicLongString]
public string ExceptionMessage { get; set; }
[SubSonicNullString]
+ [SubSonicLongString]
public string ExceptionString { get; set; }
[SubSonicNullString]
public string ExceptionType { get; set; }
diff --git a/NzbDrone.Core/Libraries/Castle.Core.pdb b/NzbDrone.Core/Libraries/Castle.Core.pdb
deleted file mode 100644
index 1f8f1d471..000000000
Binary files a/NzbDrone.Core/Libraries/Castle.Core.pdb and /dev/null differ
diff --git a/NzbDrone.Core/Libraries/NLog.pdb b/NzbDrone.Core/Libraries/NLog.pdb
deleted file mode 100644
index a9996beef..000000000
Binary files a/NzbDrone.Core/Libraries/NLog.pdb and /dev/null differ
diff --git a/NzbDrone.Core/Libraries/RSS.NET.XML b/NzbDrone.Core/Libraries/RSS.NET.XML
new file mode 100644
index 000000000..e60b7797a
--- /dev/null
+++ b/NzbDrone.Core/Libraries/RSS.NET.XML
@@ -0,0 +1,1388 @@
+
+
+
+ RSS.NET
+
+
+
+ The contents of a RssFeed
+
+
+ Initialize a new instance of the RssFeed class.
+
+
+ Initialize a new instance of the RssFeed class with a specified encoding.
+
+
+ Returns a string representation of the current Object.
+ The Url of the feed
+
+
+ Reads the specified RSS feed
+ The url or filename of the RSS feed
+ The contents of the feed
+
+
+ Reads the specified RSS feed
+ The specified way to connect to the web server
+ The contents of the feed
+
+
+ Reads the specified RSS feed
+ The cached version of the feed
+ The current contents of the feed
+ Will not download the feed if it has not been modified
+
+
+ Reads the specified RSS feed
+ The specified way to connect to the web server
+ The cached version of the feed
+ The current contents of the feed
+ Will not download the feed if it has not been modified
+
+
+ Writes the RSS feed to the specified stream.
+ specified Stream
+ The Stream cannot be written to.
+ Feed must contain at least one channel.
+ Channel must contain at least one item.
+
+
+ Writes the RSS feed to the specified file.
+ The encoding is ISO-8859-1.
+ The filename is empty, contains only white space, or contains one or more invalid characters.
+ Access is denied.
+ The filename is a (null c#, Nothing vb) reference.
+ The directory to write to is not found.
+ The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
+ The caller does not have the required permission.
+ specified file (including path) If the file exists, it will be truncated with the new content.
+ Feed must contain at least one channel.
+ Channel must contain at least one item.
+
+
+ The channels that are contained in the feed.
+
+
+ The modules that the feed adhears to.
+
+
+ A collection of all exceptions encountered during the reading of the feed.
+
+
+ The Version of the feed.
+
+
+ The server generated hash of the feed.
+
+
+ The server generated last modfified date and time of the feed.
+
+
+ Indicates this feed has not been changed on the server, and the local copy was returned.
+
+
+ Location of the feed
+
+
+ Encoding of the feed
+
+
+ Provide information regarding the location of the subject matter of the channel in a taxonomy
+
+
+ Base class for all RSS elements
+
+
+ Initialize a new instance of the RssElement class
+
+
+ Initialize a new instance of the RssCategory class
+
+
+ Actual categorization given for this item, within the chosen taxonomy
+
+
+ URL of external taxonomy
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified channel to this collection.
+ The channel to add.
+ The zero-based index of the added channel.
+
+
+ Determines whether the RssChannelCollection contains a specific element.
+ The RssChannel to locate in the RssChannelCollection.
+ true if the RssChannelCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssChannelCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssChannel Array that is the destination of the elements copied from RssChannelCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssChannelCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssChannel and returns the zero-based index of the first occurrence within the entire RssChannelCollection.
+ The RssChannel to locate in the RssChannelCollection.
+ The zero-based index of the first occurrence of RssChannel within the entire RssChannelCollection, if found; otherwise, -1.
+
+
+ Inserts a channel into this collection at a specified index.
+ The zero-based index of the collection at which to insert the channel.
+ The channel to insert into this collection.
+
+
+ Removes a specified channel from this collection.
+ The channel to remove.
+
+
+ Gets or sets the channel at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A channel at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ A reference to an attachment to the item
+
+
+ Initialize a new instance of the RssEnclosure class.
+
+
+ Where the enclosure is located
+
+
+ The size of the enclosure, in bytes
+ -1 represents a null.
+
+
+ A standard Multipurpose Internet Mail Extensions (MIME) type
+
+
+ Grouping of related content items on a site
+
+
+ Initialize a new instance of the RssChannel class.
+
+
+ Returns a string representation of the current Object.
+ The channel's title, description, or "RssChannel" if the title and description are blank.
+
+
+ The name of the channel
+ Maximum length is 100 characters (For RSS 0.91)
+
+
+ URL of the website named in the title
+ Maximum length is 500 characters (For RSS 0.91)
+
+
+ Description of the channel
+ Maximum length is 500 characters (For RSS 0.91)
+
+
+ Language the channel is written in
+
+
+ A link and description for a graphic icon that represent a channel
+
+
+ Copyright notice for content in the channel
+ Maximum length is 100 (For RSS 0.91)
+
+
+ The email address of the managing editor of the channel, the person to contact for editorial inquiries
+
+ Maximum length is 100 (For RSS 0.91)
+ The suggested format for email addresses in RSS elements is
+ bull@mancuso.com (Bull Mancuso)
+
+
+
+ The email address of the webmaster for the channel
+
+ Person to contact if there are technical problems
+ Maximum length is 100 (For RSS 0.91)
+ The suggested format for email addresses in RSS elements is
+ bull@mancuso.com (Bull Mancuso)
+
+
+
+ The PICS rating for the channel
+ Maximum length is 500 (For RSS 0.91)
+
+
+ The publication date for the content in the channel, expressed as the coordinated universal time (UTC)
+
+
+ The date-time the last time the content of the channel changed, expressed as the coordinated universal time (UTC)
+
+
+ One or more categories the channel belongs to.
+
+
+ A string indicating the program used to generate the channel
+
+
+ A URL, points to the documentation for the format used in the RSS file
+ Maximum length is 500 (For RSS 0.91).
+
+
+ Provides information about an HTTP GET feature, typically for a search or subscription
+
+
+ Readers should not read the channel during days listed. (UTC)
+ Days are listed in the array in the following order:
+ Monday
+ Tuesday
+ Wednesday
+ Thursday
+ Friday
+ Saturday
+ Sunday
+ Monday
+
+
+
+ Readers should not read the channel during hours listed (UTC)
+ Represents a time in UTC - 1.
+
+
+ Allow processes to register with a cloud to be notified of updates to the channel
+
+
+ The number of minutes that a channel can be cached.
+
+
+ All items within the channel
+
+
+ People in a photo
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssModuleItemCollection contains a specific element.
+ The RssModuleItem to locate in the RssModuleItemCollection.
+ true if the RssModuleItemCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssModuleItemCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssModuleItem Array that is the destination of the elements copied from RssModuleItemCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleItemCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssModuleItem and returns the zero-based index of the first occurrence within the entire RssModuleItemCollection.
+ The RssModuleItem to locate in the RssModuleItemCollection.
+ The zero-based index of the first occurrence of RssModuleItem within the entire RssModuleItemCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ Bind a particular item to this module
+ Hash code of the item
+
+
+ Check if a particular item is bound to this module
+ Hash code of the item
+ true if this item is bound to this module, otherwise false
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhotoPeople class
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhotoPeople class
+ Name of person
+
+
+ Add a person to the photo
+ Name of person
+ The zero-based index of the added item
+
+
+ A collection of photos in a category
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssModuleItemCollectionCollection contains a specific element.
+ The RssModuleItemCollection to locate in the RssModuleItemCollectionCollection.
+ true if the RssModuleItemCollectionCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssModuleItemCollectionCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssModuleItemCollection Array that is the destination of the elements copied from RssModuleItemCollectionCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleItemCollectionCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssModuleItemCollection and returns the zero-based index of the first occurrence within the entire RssModuleItemCollectionCollection.
+ The RssModuleItemCollection to locate in the RssModuleItemCollectionCollection.
+ The zero-based index of the first occurrence of RssModuleItemCollection within the entire RssModuleItemCollectionCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+
+
+ Adds a sepecified photo to this collection.
+ The photo to add.
+ The zero-based index of the added item.
+
+
+ A photo in the category
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ People to add to the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ Adds a specified item to this collection.
+ Date of the Photo
+ Description of the photo.
+ Direct link of the photo.
+ The zero-based index of the added item.
+
+
+ A collection of categories in a photo album
+
+
+ Initialize a new instance of the RssPhotoAlbumItemPhoto class
+
+
+ Adds a sepecified category to this collection.
+ The category to add.
+ The zero-based index of the added item.
+
+
+ A Photo Album category
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ Initialize a new instance of the RssPhotoAlbumItem class
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+
+
+ Adds a specified category to this collection.
+ Name of the category.
+ Description of the category.
+ From date of the category.
+ To date of the category.
+ Photos of the category.
+ The zero-based index of the added item.
+
+
+ RSS syndication for Robert A. Wlodarczyk's Photo Album application (to be sold by Inno Thinx LLC)
+
+
+ Base class for all RSS modules
+
+
+ Initialize a new instance of the RssModule class
+
+
+ Bind a particular channel to this module
+ Hash code of the channel
+
+
+ Check if a particular channel is bound to this module
+ Hash code of the channel
+ true if this channel is bound to this module, otherwise false
+
+
+ Collection of RSSModuleItem that are to be placed in the channel
+
+
+ Collection of RSSModuleItemCollection that are to be placed in the channel item
+
+
+ Prefix for the given module namespace
+
+
+ URL for the given module namespace
+
+
+ Initialize a new instance of the RssPhotoAlbum class
+ Link to the Photo Album
+ The category of the Photo Album to add
+
+
+ Initialize a new instance of the RssPhotoAlbum class
+ Link to the Photo Album
+ A collection of categories in the Photo Album to add
+
+
+ Link element for channel
+
+
+ Contains default values and methods for maintaining data consistency
+
+
+ Default value for a string in all RSS classes
+ empty string
+ If an element in the RSS class library has the value of RssDefault.String, consider the element as "not entered", "null", or empty.
+
+
+ Default value for an int in all RSS classes
+ -1
+ If an element in the RSS class library has the value of RssDefault.Int, consider the element as "not entered", "null", or empty.
+
+
+ Default value for a DateTime in all RSS classes
+ DateTime.MinValue
+ If an element in the RSS class library has the value of RssDefault.DateTime, consider the element as "not entered", "null", or empty.
+
+
+ Default value for a Uri in all RSS classes
+ gopher://rss-net.sf.net
+ If an element in the RSS class library has the value of RssDefault.Uri, consider the element as "not entered", "null", or empty.
+
+
+ Verifies the string passed is not null
+ string to verify
+ RssDefault.String if input is null, otherwise input
+ Method is used in properties to prevent a null value
+
+
+ Verifies the int passed is greater than or equal to -1
+ int to verify
+ RssDefault.Int if int is less than -1, else input
+ Method is used in properties to prevent values less than -1
+
+
+ Verifies the Uri passed is not null
+ Uri to verify
+ RssDefault.Uri if input is null, otherwise input
+ Method is used in all properties to prevent a null value
+
+
+ Represents Null, False, and True
+ Source: Microsoft c# example
+
+
+ A DBBool containing 'Null'.
+ One of three possible DBBool values.
+
+
+ A DBBool containing 'False'.
+ One of three possible DBBool values.
+
+
+ A DBBool containing 'True'.
+ One of three possible DBBool values.
+
+
+ Private field that stores –1, 0, 1 for False, Null, True.
+
+
+ Private instance constructor. The value parameter must be –1, 0, or 1.
+
+
+ Implicit conversion from bool to DBBool. Maps true to DBBool.True and false to DBBool.False.
+ a DBBool
+
+
+ Explicit conversion from DBBool to bool.
+ The given DBBool is Null
+ a DBBool
+ true or false
+
+
+ Equality operator.
+ a DBBool
+ a DBBool
+ Returns Null if either operand is Null, otherwise returns True or False.
+
+
+ Inequality operator.
+ a DBBool
+ a DBBool
+ Returns Null if either operand is Null, otherwise returns True or False.
+
+
+ Logical negation operator.
+ a DBBool
+ Returns True if the operand is False, Null if the operand is Null, or False if the operand is True.
+
+
+ Logical AND operator.
+ a DBBool
+ a DBBool
+ Returns False if either operand is False, otherwise Null if either operand is Null, otherwise True.
+
+
+ Logical OR operator.
+ a DBBool
+ a DBBool
+ Returns True if either operand is True, otherwise Null if either operand is Null, otherwise False.
+
+
+ Definitely true operator.
+ a DBBool
+ Returns true if the operand is True, false otherwise.
+
+
+ Definitely false operator.
+ a DBBool
+ Returns true if the operand is False, false otherwise.
+
+
+ Determines whether two DBBool instances are equal.
+ The object to check.
+ True if the two DBBools are equal.
+
+
+ Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table.
+ A hash code for the current DBBool.
+
+
+ Returns a string representation of the current Object.
+ Object has not been initialized.
+ A string containing DBBool.False, DBBool.Null, or DBBool.True
+
+
+ Properties to examine the value of a DBBool.
+ Return true if this DBBool has the given value, false otherwise.
+
+
+ Properties to examine the value of a DBBool.
+ Return true if this DBBool has the given value, false otherwise.
+
+
+ Properties to examine the value of a DBBool.
+ Return true if this DBBool has the given value, false otherwise.
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssModuleCollection contains a specific element.
+ The RssModule to locate in the RssModuleCollection.
+ true if the RssModuleCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssModuleCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssModule Array that is the destination of the elements copied from RssModuleCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssModule and returns the zero-based index of the first occurrence within the entire RssModuleCollection.
+ The RssModule to locate in the RssModuleCollection.
+ The zero-based index of the first occurrence of RssModule within the entire RssModuleCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified item to this collection.
+ The item to add.
+ The zero-based index of the added item.
+
+
+ Determines whether the RssItemCollection contains a specific element.
+ The RssItem to locate in the RssItemCollection.
+ true if the RssItemCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssItemCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssItem Array that is the destination of the elements copied from RssItemCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssItemCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssItem and returns the zero-based index of the first occurrence within the entire RssItemCollection.
+ The RssItem to locate in the RssItemCollection.
+ The zero-based index of the first occurrence of RssItem within the entire RssItemCollection, if found; otherwise, -1.
+
+
+ Inserts an item into this collection at a specified index.
+ The zero-based index of the collection at which to insert the item.
+ The item to insert into this collection.
+
+
+ Removes a specified item from this collection.
+ The item to remove.
+
+
+ The latest pubDate in the items collection
+ The latest pubDate -or- RssDefault.DateTime if all item pubDates are not defined
+
+
+ The oldest pubDate in the items collection
+ The oldest pubDate -or- RssDefault.DateTime if all item pubDates are not defined
+
+
+ Calculates the oldest and latest pubdates
+
+
+ Gets or sets the item at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ An item at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Allow processes to register with a cloud to be notified of updates to the channel.
+
+
+ Initialize a new instance of the RssCloud class.
+
+
+ Domain name or IP address of the cloud
+
+
+ TCP port that the cloud is running on
+
+
+ Location of its responder
+
+
+ Name of the procedure to call to request notification
+
+
+ Protocol used
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified feed to this collection.
+ The feed to add.
+ The zero-based index of the added feed.
+
+
+ Determines whether the RssFeedCollection contains a specific element.
+ The RssFeed to locate in the RssFeedCollection.
+ true if the RssFeedCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssFeedCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssFeed Array that is the destination of the elements copied from RssFeedCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssFeedCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssFeed and returns the zero-based index of the first occurrence within the entire RssFeedCollection.
+ The RssFeed to locate in the RssFeedCollection.
+ The zero-based index of the first occurrence of RssFeed within the entire RssFeedCollection, if found; otherwise, -1.
+
+
+ Inserts a feed into this collection at a specified index.
+ The zero-based index of the collection at which to insert the feed.
+ The feed to insert into this collection.
+
+
+ Removes a specified category from this collection.
+ The category to remove.
+
+
+ Gets or sets the feed at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A feed at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ Gets or sets the feed with the given name.In C#, this property is the indexer for the class.
+ The url of the feed to access.
+ A feed at each valid url. If the feed does not exist, null.
+ This method is an indexer that can be used to access the collection.
+
+
+ A RSS module that adds elements at the channel level that are common to weblogs.
+
+
+ Initialize a new instance of the
+ The URL of an OPML file containing the blogroll for the site.
+ The URL of an OPML file containing the author's RSS subscriptions.
+
+ The URL of a weblog that the author of the weblog is promoting per Mark Pilgrim's description.
+ "http://diveintomark.org/archives/2002/09/17.html#blink_and_youll_miss_it"
+
+
+ The URL of a changes.xml file. When the feed that contains this element updates, it pings a server that updates this file. The presence of this element says to aggregators that they only have to read the changes file to see if this feed has updated. If several feeds point to the same changes file, the aggregator has to do less polling, resulting in better use of server bandwidth, and the Internet as a whole; and resulting in faster scans. Everyone wins. For more technical information, see the howto on the XML-RPC site.
+ "http://www.xmlrpc.com/weblogsComForRss"
+
+
+
+ All valid Rss Cloud protocols, including Null
+
+
+ Not defined
+
+
+ Protocol is not supported
+
+
+ xml-rpc
+
+
+ soap
+
+
+ http-post
+
+
+ All RSS versions
+
+
+ Not defined
+
+
+ Version is not directly supported
+
+
+ RDF Site Summary (RSS) 0.9
+
+
+ Rich Site Summary (RSS) 0.91
+
+
+ Rich Site Summary (RSS) 0.92
+
+
+ RDF Site Summary (RSS) 1.0
+
+
+ Really Simple Syndication (RSS) 2.0
+
+
+ Writes an RSS XML file.
+ Represents a writer that provides a fast, non-cached, forward-only way of generating streams or files containing RSS XML data that conforms to the W3C Extensible Markup Language (XML) 1.0 and the Namespaces in XML recommendations.
+
+
+ Creates an instance of the RssWriter class using the specified TextWriter.
+ specified TextWriter
+
+
+ Creates an instance of the RssWriter class using the specified Stream and Encoding.
+ The encoding is not supported or the stream cannot be written to.
+ Stream to output to
+ The encoding to use. If encoding is (null c#, Nothing vb) it writes out the stream as UTF-8.
+
+
+ Creates an instance of the RssWriter class using the specified Stream.
+ The encoding is ISO-8859-1.
+ The Stream cannot be written to.
+ specified Stream
+
+
+ Creates an instance of the RssWriter class using the specified file and Encoding.
+ The encoding is not supported; the filename is empty, contains only white space, or contains one or more invalid characters.
+ Access is denied.
+ The filename is a (null c#, Nothing vb) reference.
+ The directory to write to is not found.
+ The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
+ The caller does not have the required permission.
+ specified file (including path) If the file exists, it will be truncated with the new content.
+ specified Encoding
+
+
+ Creates an instance of the RssWriter class using the specified file.
+ The encoding is ISO-8859-1.
+ The filename is empty, contains only white space, or contains one or more invalid characters.
+ Access is denied.
+ The filename is a (null c#, Nothing vb) reference.
+ The directory to write to is not found.
+ The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
+ The caller does not have the required permission.
+ specified file (including path) If the file exists, it will be truncated with the new content.
+
+
+ Writes the begining data to the RSS file
+ This routine is called from the WriteChannel and WriteItem subs
+ RDF Site Summary (RSS) 1.0 is not currently supported.
+
+
+ Closes instance of RssWriter.
+ Writes end elements, and releases connections
+ Occurs if the RssWriter is already closed or the caller is attempting to close before writing a channel.
+
+
+ Writes an RSS channel
+ RssWriter has been closed, and can not be written to.
+ Channel must be instanciated with data, before calling Write.
+ RSS channel to write
+
+
+ Writes an RSS item
+ Either the RssWriter has already been closed, or the caller is attempting to write an RSS item before an RSS channel.
+ Item must be instanciated with data, before calling Write.
+ RSS item to write
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an element with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Writes an attribute with the specified local name and value
+ the localname of the element
+ the value of the element
+ boolean that determines if input cannot be null
+
+
+ Gets or sets the RSS version to write.
+ Can't change version number after data has been written.
+
+
+ Gets or sets the of the XML output.
+ Can't change XML formatting after data has been written.
+
+
+ Gets or sets how indentation to write for each level in the hierarchy when XmlFormat is set to
+ Can't change XML formatting after data has been written.
+ Setting this property to a negative value.
+
+
+ RSS modules
+
+
+ Reads an RSS file.
+ Provides fast, non-cached, forward-only access to RSS data.
+
+
+ Initializes a new instance of the RssReader class with the specified URL or filename.
+ The URL or filename for the file containing the RSS data.
+ Occures when unable to retrieve file containing the RSS data.
+
+
+ Creates an instance of the RssReader class using the specified TextReader.
+ specified TextReader
+ Occures when unable to retrieve file containing the RSS data.
+
+
+ Creates an instance of the RssReader class using the specified Stream.
+ Occures when unable to retrieve file containing the RSS data.
+ Stream to read from
+
+
+ Reads the next RssElement from the stream.
+ An RSS Element
+ RssReader has been closed, and can not be read.
+ RSS file not found.
+ Invalid XML syntax in RSS file.
+ Unable to read an RssElement. Reached the end of the stream.
+
+
+ Closes connection to file.
+ This method also releases any resources held while reading.
+
+
+ A collection of all exceptions the RssReader class has encountered.
+
+
+ Gets the RSS version of the stream.
+ One of the values.
+
+
+ Globally unique identifier
+
+
+ Initialize a new instance of the RssGuid class.
+
+
+ If true, a url that can be opened in a web browser that points to the item
+
+
+ Globally unique identifier value
+
+
+ A link and description for a graphic that represent a channel
+
+
+ Initialize a new instance of the RssImage class.
+
+
+ The URL of a GIF, JPEG or PNG image that represents the channel.
+ Maximum length is 500 (For RSS 0.91).
+
+
+ Describes the image, it's used in the ALT attribute of the HTML img tag when the channel is rendered in HTML.
+ Maximum length is 100 (For RSS 0.91).
+
+
+ The URL of the site, when the channel is rendered, the image is a link to the site.
+ Maximum length is 500 (For RSS 0.91).
+
+
+ Contains text that is included in the TITLE attribute of the link formed around the image in the HTML rendering.
+
+
+ Width of image in pixels
+ Maximum value for height is 400 (For RSS 0.91)
+
+
+ Height of image in pixels
+ Maximum value for width is 144 (For RSS 0.91)
+
+
+ A module may contain any number of items (either channel-based or item-based).
+
+
+ Initialize a new instance of the RssModuleItem class
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ Is text required for this RssModuleItem?
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ The text contained within this RssModuleItem.
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ Is text required for this RssModuleItem?
+ The text contained within this RssModuleItem.
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ The text contained within this RssModuleItem.
+ The sub-elements of this RssModuleItem (if any exist).
+
+
+ Initialize a new instance of the RssModuleItem class
+ The name of this RssModuleItem.
+ Is text required for this RssModuleItem?
+ The text contained within this RssModuleItem.
+ The sub-elements of this RssModuleItem (if any exist).
+
+
+ Returns a string representation of the current Object.
+ The item's title, description, or "RssModuleItem" if the title and description are blank.
+
+
+
+ The name of this RssModuleItem.
+
+
+
+
+ The text contained within this RssModuleItem.
+
+
+
+
+ The sub-elements of this RssModuleItem (if any exist).
+
+
+
+
+ Is text for this element required?
+
+
+
+ Describes an items source
+
+
+ Initialize a new instance of the RssSource class
+
+
+ Name of the RSS channel that the item came from
+
+
+ URL of the original RSS feed from which the item was republished
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified exception to this collection.
+ The exception to add.
+ The zero-based index of the added exception -or- -1 if the exception already exists.
+
+
+ Determines whether the ExceptionCollection contains a specific element.
+ The Exception to locate in the ExceptionCollection.
+ true if the ExceptionCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire ExceptionCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional Exception Array that is the destination of the elements copied from ExceptionCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source ExceptionCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified Exception and returns the zero-based index of the first occurrence within the entire ExceptionCollection.
+ The Exception to locate in the ExceptionCollection.
+ The zero-based index of the first occurrence of RssChannel within the entire ExceptionCollection, if found; otherwise, -1.
+
+
+ Inserts an Exception into this collection at a specified index.
+ The zero-based index of the collection at which to insert the Exception.
+ The Exception to insert into this collection.
+
+
+ Removes a specified Exception from this collection.
+ The Exception to remove.
+
+
+ Gets or sets the exception at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A exception at each valid index.
+ This method is an indexer that can be used to access the collection.
+
+
+ Returns the last exception added through the Add method.
+ The last exception -or- null if no exceptions exist
+
+
+ A strongly typed collection of objects
+
+
+ Adds a specified category to this collection.
+ The category to add.
+ The zero-based index of the added category.
+
+
+ Determines whether the RssCategoryCollection contains a specific element.
+ The RssCategory to locate in the RssCategoryCollection.
+ true if the RssCategoryCollection contains the specified value; otherwise, false.
+
+
+ Copies the entire RssCategoryCollection to a compatible one-dimensional , starting at the specified index of the target array.
+ The one-dimensional RssCategory Array that is the destination of the elements copied from RssCategoryCollection. The Array must have zero-based indexing.
+ The zero-based index in array at which copying begins.
+ array is a null reference (Nothing in Visual Basic).
+ index is less than zero.
+ array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssCategoryCollection is greater than the available space from index to the end of the destination array.
+
+
+ Searches for the specified RssCategory and returns the zero-based index of the first occurrence within the entire RssCategoryCollection.
+ The RssCategory to locate in the RssCategoryCollection.
+ The zero-based index of the first occurrence of RssCategory within the entire RssCategoryCollection, if found; otherwise, -1.
+
+
+ Inserts an category into this collection at a specified index.
+ The zero-based index of the collection at which to insert the category.
+ The category to insert into this collection.
+
+
+ Removes a specified category from this collection.
+ The category to remove.
+
+
+ Gets or sets the category at a specified index.In C#, this property is the indexer for the class.
+ The index of the collection to access.
+ A category at each valid index.
+ This method is an indexer that can be used to access the collection.
+ index is not a valid index.
+
+
+ A RSS module that adds elements at the channel or item level that specifies which Creative Commons license applies.
+
+
+ Initialize a new instance of the
+
+ If present as a sub-element of channel, indicates that the content of the RSS file is available under a license, indicated by a URL, which is the value of the license element. A list of some licenses that may be used in this context is on the Creative Commons website on this page, however the license element may point to licenses not authored by Creative Commons.
+ You may also use the license element as a sub-element of item. When used this way it applies only to the content of that item. If an item has a license, and the channel does too, the license on the item applies, i.e. the inner license overrides the outer one.
+ Multiple license elements are allowed, in either context, indicating that the content is available under multiple licenses.
+ "http://www.creativecommons.org/licenses/"
+
+ If present as a sub-element of channel then true, otherwise false
+
+
+ A channel may contain any number of items, each of which links to more information about the item, with an optional description
+
+
+ Initialize a new instance of the RssItem class
+
+
+ Returns a string representation of the current Object.
+ The item's title, description, or "RssItem" if the title and description are blank.
+
+
+ Title of the item
+ Maximum length is 100 (For RSS 0.91)
+
+
+ URL of the item
+ Maximum length is 500 (For RSS 0.91)
+
+
+ Item synopsis
+ Maximum length is 500 (For RSS 0.91)
+
+
+ Email address of the author of the item
+
+
+ Provide information regarding the location of the subject matter of the channel in a taxonomy
+
+
+ URL of a page for comments relating to the item
+
+
+ Describes an items source
+
+
+ A reference to an attachment to the item
+
+
+ A string that uniquely identifies the item
+
+
+ Indicates when the item was published
+
+
+ Multi-purpose channel element for the purpose of allowing users to submit queries back to the publisher's site
+ Typically for a search or subscription
+
+
+ Initialize a new instance of the RssTextInput class
+
+
+ The label of the submit button in the text input area
+ Maximum length is 100 (For RSS 0.91)
+
+
+ Explains the text input area
+ Maximum length is 500 (For RSS 0.91)
+
+
+ The name of the text object in the text input area
+ Maximum length is 20 (For RSS 0.91).
+
+
+ The URL of the script that processes text input requests
+ Maximum length is 500 (For RSS 0.91)
+
+
+
diff --git a/NzbDrone.Core/Libraries/RSS.NET.dll b/NzbDrone.Core/Libraries/RSS.NET.dll
new file mode 100644
index 000000000..10dd1f774
Binary files /dev/null and b/NzbDrone.Core/Libraries/RSS.NET.dll differ
diff --git a/NzbDrone.Core/Libraries/SubSonic.Core.pdb b/NzbDrone.Core/Libraries/SubSonic.Core.pdb
deleted file mode 100644
index 14f65566b..000000000
Binary files a/NzbDrone.Core/Libraries/SubSonic.Core.pdb and /dev/null differ
diff --git a/NzbDrone.Core/Libraries/TvdbLib.pdb b/NzbDrone.Core/Libraries/TvdbLib.pdb
deleted file mode 100644
index 2d006a5a1..000000000
Binary files a/NzbDrone.Core/Libraries/TvdbLib.pdb and /dev/null differ
diff --git a/NzbDrone.Core/Model/EpisodeModel.cs b/NzbDrone.Core/Model/EpisodeModel.cs
index caa4ed596..2d0d16826 100644
--- a/NzbDrone.Core/Model/EpisodeModel.cs
+++ b/NzbDrone.Core/Model/EpisodeModel.cs
@@ -6,7 +6,9 @@ namespace NzbDrone.Core.Model
public class EpisodeModel
{
public string SeriesTitle { get; set; }
+ public int SeriesId { get; set; }
public string EpisodeTitle { get; set; }
+ public int EpisodeId { get; set; }
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
public QualityTypes Quality { get; set; }
diff --git a/NzbDrone.Core/Model/FeedInfoModel.cs b/NzbDrone.Core/Model/FeedInfoModel.cs
new file mode 100644
index 000000000..98c979b6d
--- /dev/null
+++ b/NzbDrone.Core/Model/FeedInfoModel.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace NzbDrone.Core.Model
+{
+ public class FeedInfoModel
+ {
+ public FeedInfoModel(string name, string url)
+ {
+ Name = name ?? "UN-NAMED";
+ Url = ParseUrl(url);
+ }
+
+ public string Name { get; private set; }
+ public string Url { get; private set; }
+
+ private static string ParseUrl(string url)
+ {
+ Uri uri;
+ if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
+ {
+ uri = new Uri(new Uri(CentralDispatch.ExecutablePath + Path.DirectorySeparatorChar), url);
+ }
+ return uri.IsFile ? uri.AbsolutePath.Replace("%20", " ") : uri.AbsoluteUri;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != typeof(FeedInfoModel)) return false;
+ return Equals((FeedInfoModel) obj);
+ }
+
+ public bool Equals(FeedInfoModel other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Equals(other.Name, Name) && Equals(other.Url, Url);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return ((Name != null ? Name.GetHashCode() : 0)*397) ^ (Url != null ? Url.GetHashCode() : 0);
+ }
+ }
+ }
+}
diff --git a/NzbDrone.Core/Model/NzbInfoModel.cs b/NzbDrone.Core/Model/NzbInfoModel.cs
new file mode 100644
index 000000000..0ed6d31ec
--- /dev/null
+++ b/NzbDrone.Core/Model/NzbInfoModel.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NzbDrone.Core.Repository;
+
+namespace NzbDrone.Core.Model
+{
+ public class NzbInfoModel
+ {
+ public string Id { get; set; }
+ public string Title { get; set; }
+ public string TitleFix { get; set; }
+ public NzbSiteModel Site { get; set; }
+ public Uri Link { get; set; }
+ public string Description { get; set; }
+ public bool Proper { get; set; }
+
+ public bool IsPassworded()
+ {
+ return Title.EndsWith("(Passworded)", StringComparison.InvariantCultureIgnoreCase);
+ }
+ }
+}
diff --git a/NzbDrone.Core/Model/NzbSiteModel.cs b/NzbDrone.Core/Model/NzbSiteModel.cs
new file mode 100644
index 000000000..c7b70b6ce
--- /dev/null
+++ b/NzbDrone.Core/Model/NzbSiteModel.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace NzbDrone.Core.Model
+{
+ public class NzbSiteModel
+ {
+ private static readonly IList Sites = new List
+ {
+ new NzbSiteModel {Name = "nzbmatrix", Url = "nzbmatrix.com", Pattern = @"\d{6,10}"},
+ new NzbSiteModel {Name = "nzbsDotOrg", Url = "nzbs.org", Pattern = @"\d{5,10}"},
+ new NzbSiteModel {Name = "nzbsrus", Url = "nzbsrus.com", Pattern = @"\d{6,10}"},
+ new NzbSiteModel {Name = "lilx", Url = "lilx.net", Pattern = @"\d{6,10}"},
+ };
+
+ public string Name { get; set; }
+ public string Pattern { get; set; }
+ public string Url { get; set; }
+
+ // TODO: use HttpUtility.ParseQueryString();
+ // https://nzbmatrix.com/api-nzb-download.php?id=626526
+ public string ParseId(string url)
+ {
+ return Regex.Match(url, Pattern).Value;
+ }
+
+ public static NzbSiteModel Parse(string url)
+ {
+ return Sites.Where(site => url.Contains(site.Url)).SingleOrDefault() ??
+ new NzbSiteModel { Name = "unknown", Pattern = @"\d{6,10}" };
+ }
+ }
+}
diff --git a/NzbDrone.Core/Model/SabnzbdPriorityType.cs b/NzbDrone.Core/Model/SabnzbdPriorityType.cs
new file mode 100644
index 000000000..bd6ea272c
--- /dev/null
+++ b/NzbDrone.Core/Model/SabnzbdPriorityType.cs
@@ -0,0 +1,9 @@
+namespace NzbDrone.Core.Model
+{
+ public enum SabnzbdPriorityType
+ {
+ Low = -1,
+ Normal = 0,
+ High = 1
+ }
+}
diff --git a/NzbDrone.Core/Model/Season.cs b/NzbDrone.Core/Model/Season.cs
new file mode 100644
index 000000000..42e5ad1fd
--- /dev/null
+++ b/NzbDrone.Core/Model/Season.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using SubSonic.SqlGeneration.Schema;
+
+namespace NzbDrone.Core.Repository
+{
+ public class Season
+ {
+ [SubSonicPrimaryKey(false)]
+ public virtual long SeasonId { get; set; }
+ public long SeriesId { get; set; }
+ public int SeasonNumber { get; set; }
+ public bool Monitored { get; set; }
+ public string Folder { get; set; }
+
+ [SubSonicToManyRelation]
+ public virtual List Episodes { get; private set; }
+
+ [SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
+ public virtual Series Series { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index 8a3dca65d..fcd5a170e 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -31,7 +31,7 @@
true
- x86
+ AnyCPUtruefullfalse
@@ -91,7 +91,7 @@
bin\Debug\DEBUG;TRACEfull
- x86
+ AnyCPUbin\Debug\SABSync.exe.CodeAnalysisLog.xmltrueGlobalSuppressions.cs
@@ -134,6 +134,10 @@
FalseLibraries\NLog.Extended.dll
+
+ False
+ Libraries\RSS.NET.dll
+ D:\OpenSource\sabscripts\SABSync\References\SubSonic.Core.dll
@@ -159,6 +163,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -190,6 +206,8 @@
+
+
@@ -228,7 +246,6 @@
-
@@ -236,14 +253,14 @@
-
+
+
-
diff --git a/NzbDrone.Core/Parser.cs b/NzbDrone.Core/Parser.cs
index 661898e36..d55506e60 100644
--- a/NzbDrone.Core/Parser.cs
+++ b/NzbDrone.Core/Parser.cs
@@ -8,6 +8,7 @@ using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository.Quality;
+using Rss;
namespace NzbDrone.Core
{
@@ -145,5 +146,18 @@ namespace NzbDrone.Core
return info.FullName.ToLower().Trim('/', '\\', ' ');
}
+
+ public static NzbInfoModel ParseNzbInfo(FeedInfoModel feed, RssItem item)
+ {
+ NzbSiteModel site = NzbSiteModel.Parse(feed.Url.ToLower());
+ return new NzbInfoModel
+ {
+ Id = site.ParseId(item.Link.ToString()),
+ Title = item.Title,
+ Site = site,
+ Link = item.Link,
+ Description = item.Description
+ };
+ }
}
}
diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs
index 7bbd808d3..e33400335 100644
--- a/NzbDrone.Core/Providers/EpisodeProvider.cs
+++ b/NzbDrone.Core/Providers/EpisodeProvider.cs
@@ -17,15 +17,17 @@ namespace NzbDrone.Core.Providers
private readonly ISeriesProvider _series;
private readonly ISeasonProvider _seasons;
private readonly ITvDbProvider _tvDb;
+ private readonly IHistoryProvider _history;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
- public EpisodeProvider(IRepository sonicRepo, ISeriesProvider seriesProvider, ISeasonProvider seasonProvider, ITvDbProvider tvDbProvider)
+ public EpisodeProvider(IRepository sonicRepo, ISeriesProvider seriesProvider, ISeasonProvider seasonProvider, ITvDbProvider tvDbProvider, IHistoryProvider history)
{
_sonicRepo = sonicRepo;
_series = seriesProvider;
_tvDb = tvDbProvider;
_seasons = seasonProvider;
+ _history = history;
}
public Episode GetEpisode(long id)
@@ -64,6 +66,44 @@ namespace NzbDrone.Core.Providers
///
public bool IsNeeded(EpisodeModel episode)
{
+ //IsSeasonIgnored
+ //IsQualityWanted
+ //EpisodeFileExists
+ //IsInHistory
+ //IsOnDisk? (How to handle episodes that are downloaded manually?)
+
+ if (IsSeasonIgnored(episode))
+ return false;
+
+ if (!_series.QualityWanted(episode.SeriesId, episode.Quality))
+ {
+ Logger.Debug("Quality [{0}] is not wanted for: {1}", episode.Quality, episode.SeriesTitle);
+ return false;
+ }
+
+ //Check to see if there is an episode file for this episode
+ var dbEpisode = GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber);
+ episode.EpisodeId = dbEpisode.EpisodeId;
+
+ var epWithFiles = _sonicRepo.Single(c => c.EpisodeId == episode.EpisodeId && c.Files.Count > 0);
+
+ if (epWithFiles != null)
+ {
+ //If not null we need to see if this episode has the quality as the download (or if it is better)
+ foreach (var file in epWithFiles.Files)
+ {
+ if (file.Quality == episode.Quality)
+ return false;
+ }
+ }
+
+ //IsInHistory? (NZBDrone)
+ if (_history.Exists(dbEpisode.EpisodeId, episode.Quality, episode.Proper))
+ {
+ Logger.Debug("Episode in history: {0}", episode.ToString());
+ return false;
+ }
+
throw new NotImplementedException();
}
@@ -86,6 +126,13 @@ namespace NzbDrone.Core.Providers
{
try
{
+ //DateTime throws an error in SQLServer per message below:
+ //SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
+ //So lets hack it so it works for SQLServer (as well as SQLite), perhaps we can find a better solution
+ //Todo: Fix this hack
+ if (episode.FirstAired < new DateTime(1753, 1, 1))
+ episode.FirstAired = new DateTime(1753, 1, 1);
+
Logger.Trace("Updating info for series:{0} - episode:{1}", targetSeries.SeriesName, episode.EpisodeNumber);
var newEpisode = new Episode()
{
@@ -123,5 +170,18 @@ namespace NzbDrone.Core.Providers
Logger.Debug("Finished episode refresh for series:{0}. Successful:{1} - Failed:{2} ", targetSeries.SeriesName, successCount, failCount);
}
+
+ private bool IsSeasonIgnored(EpisodeModel episode)
+ {
+ //Check if this Season is ignored
+ if (_seasons.IsIgnored(episode.SeriesId, episode.SeasonNumber))
+ {
+ Logger.Debug("Season {0} is ignored for: {1}", episode.SeasonNumber, episode.SeriesTitle);
+ return true;
+ }
+
+ Logger.Debug("Season {0} is wanted for: {1}", episode.SeasonNumber, episode.SeriesTitle);
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/Providers/HistoryProvider.cs b/NzbDrone.Core/Providers/HistoryProvider.cs
new file mode 100644
index 000000000..3ff35aaf1
--- /dev/null
+++ b/NzbDrone.Core/Providers/HistoryProvider.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NLog;
+using NzbDrone.Core.Repository;
+using NzbDrone.Core.Repository.Quality;
+using SubSonic.Repository;
+
+namespace NzbDrone.Core.Providers
+{
+ public class HistoryProvider : IHistoryProvider
+ {
+ private readonly IRepository _sonicRepo;
+
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ public HistoryProvider(IRepository sonicRepo)
+ {
+ _sonicRepo = sonicRepo;
+ }
+
+ #region IHistoryProvider Members
+
+ public List AllItems()
+ {
+ return _sonicRepo.All().ToList();
+ }
+
+ public void Purge()
+ {
+ var all = _sonicRepo.All();
+ _sonicRepo.DeleteMany(all);
+ Logger.Info("History has been Purged");
+ }
+
+ public void Trim()
+ {
+ var old = _sonicRepo.All().Where(h => h.Date < DateTime.Now.AddDays(-30));
+ _sonicRepo.DeleteMany(old);
+ Logger.Info("History has been trimmed, items older than 30 days have been removed");
+ }
+
+ public void Insert(History item)
+ {
+ _sonicRepo.Add(item);
+ Logger.Info("Item added to history: {0} - {1}x{2:00}", item.Episode.Series.Title, item.Episode.SeasonNumber, item.Episode.EpisodeNumber);
+ }
+
+ public bool Exists(int episodeId, QualityTypes quality, bool proper)
+ {
+ //Looks for the existance of this episode in History
+ if (_sonicRepo.Exists(h => h.EpisodeId == episodeId && (QualityTypes)h.Quality == quality && h.IsProper == proper))
+ return true;
+
+ Logger.Debug("Episode not in History: {0}", episodeId);
+ return false;
+ }
+
+ #endregion
+ }
+}
diff --git a/NzbDrone.Core/Providers/IHistoryProvider.cs b/NzbDrone.Core/Providers/IHistoryProvider.cs
new file mode 100644
index 000000000..6eb9aed3d
--- /dev/null
+++ b/NzbDrone.Core/Providers/IHistoryProvider.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NzbDrone.Core.Model;
+using NzbDrone.Core.Repository;
+using NzbDrone.Core.Repository.Quality;
+
+namespace NzbDrone.Core.Providers
+{
+ public interface IHistoryProvider
+ {
+ List AllItems();
+ void Purge();
+ void Trim();
+ void Insert(History item);
+ bool Exists(int episodeId, QualityTypes quality, bool proper);
+ }
+}
diff --git a/NzbDrone.Core/Providers/IIndexerProvider.cs b/NzbDrone.Core/Providers/IIndexerProvider.cs
new file mode 100644
index 000000000..8c7c5e971
--- /dev/null
+++ b/NzbDrone.Core/Providers/IIndexerProvider.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NzbDrone.Core.Model;
+using NzbDrone.Core.Repository;
+
+namespace NzbDrone.Core.Providers
+{
+ public interface IIndexerProvider
+ {
+ List AllIndexers();
+ List EnabledIndexers();
+ void Update(Indexer indexer);
+ }
+}
diff --git a/NzbDrone.Core/Providers/IRssProvider.cs b/NzbDrone.Core/Providers/IRssProvider.cs
new file mode 100644
index 000000000..85e52f952
--- /dev/null
+++ b/NzbDrone.Core/Providers/IRssProvider.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NzbDrone.Core.Model;
+using Rss;
+
+namespace NzbDrone.Core.Providers
+{
+ public interface IRssProvider
+ {
+ IEnumerable GetFeed(FeedInfoModel feedInfo);
+ }
+}
diff --git a/NzbDrone.Core/Providers/IRssSyncProvider.cs b/NzbDrone.Core/Providers/IRssSyncProvider.cs
new file mode 100644
index 000000000..aa033924f
--- /dev/null
+++ b/NzbDrone.Core/Providers/IRssSyncProvider.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace NzbDrone.Core.Providers
+{
+ public interface IRssSyncProvider
+ {
+ void Begin();
+ }
+}
diff --git a/NzbDrone.Core/Providers/ISeasonProvider.cs b/NzbDrone.Core/Providers/ISeasonProvider.cs
index 3a8f79854..d43104749 100644
--- a/NzbDrone.Core/Providers/ISeasonProvider.cs
+++ b/NzbDrone.Core/Providers/ISeasonProvider.cs
@@ -9,5 +9,7 @@ namespace NzbDrone.Core.Providers
List GetSeasons(int seriesId);
void EnsureSeason(int seriesId, int seasonId, int seasonNumber);
int SaveSeason(Season season);
+ bool IsIgnored(int seasonId);
+ bool IsIgnored(int seriesId, int seasonNumber);
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/Providers/ISeriesProvider.cs b/NzbDrone.Core/Providers/ISeriesProvider.cs
index 53310ff75..c7568e33a 100644
--- a/NzbDrone.Core/Providers/ISeriesProvider.cs
+++ b/NzbDrone.Core/Providers/ISeriesProvider.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Repository;
-using NzbDrone.Core.Repository;
+using NzbDrone.Core.Repository.Quality;
using TvdbLib.Data;
namespace NzbDrone.Core.Providers
@@ -22,5 +22,7 @@ namespace NzbDrone.Core.Providers
TvdbSeries MapPathToSeries(string path);
void AddSeries(string path, TvdbSeries series);
List GetUnmappedFolders();
+ Series FindSeries(string cleanTitle);
+ bool QualityWanted(int seriesId, QualityTypes quality);
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/Providers/IndexerProvider.cs b/NzbDrone.Core/Providers/IndexerProvider.cs
new file mode 100644
index 000000000..1af472693
--- /dev/null
+++ b/NzbDrone.Core/Providers/IndexerProvider.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NLog;
+using NzbDrone.Core.Model;
+using SubSonic.Repository;
+using NzbDrone.Core.Repository;
+
+namespace NzbDrone.Core.Providers
+{
+ public class IndexerProvider : IIndexerProvider
+ {
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+ private readonly IRepository _sonicRepo;
+
+ public IndexerProvider(IRepository sonicRepo)
+ {
+ _sonicRepo = sonicRepo;
+ }
+
+ #region IIndexerProvider
+
+ public List AllIndexers()
+ {
+ return _sonicRepo.All().OrderBy(i => i.Order).ToList();
+ }
+
+ public List EnabledIndexers()
+ {
+ return _sonicRepo.All().Where(i => i.Enabled).OrderBy(i => i.Order).ToList();
+ }
+
+ public void Update(Indexer indexer)
+ {
+ _sonicRepo.Update(indexer);
+ }
+
+ #endregion
+ }
+}
diff --git a/NzbDrone.Core/Providers/RssProvider.cs b/NzbDrone.Core/Providers/RssProvider.cs
new file mode 100644
index 000000000..495ccf109
--- /dev/null
+++ b/NzbDrone.Core/Providers/RssProvider.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NLog;
+using NzbDrone.Core.Model;
+using Rss;
+
+namespace NzbDrone.Core.Providers
+{
+ public class RssProvider : IRssProvider
+ {
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ #region IRssProvider Members
+ public IEnumerable GetFeed(FeedInfoModel feedInfo)
+ {
+ RssFeed feed = null;
+ try
+ {
+ Logger.Info("INFO: Downloading feed {0} from {1}", feedInfo.Name, feedInfo.Url);
+ feed = RssFeed.Read(feedInfo.Url);
+ }
+ catch (Exception e)
+ {
+ Logger.ErrorException(String.Format("ERROR: Could not download feed {0} from {1}", feedInfo.Name, feedInfo.Url), e);
+ }
+ if (feed == null || feed.Channels == null || feed.Channels.Count == 0)
+ return Enumerable.Empty();
+ return feed.Channels[0].Items.Cast();
+ }
+ #endregion
+ }
+}
diff --git a/NzbDrone.Core/Providers/RssSyncProvider.cs b/NzbDrone.Core/Providers/RssSyncProvider.cs
new file mode 100644
index 000000000..df9c3bd3f
--- /dev/null
+++ b/NzbDrone.Core/Providers/RssSyncProvider.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using NLog;
+using NzbDrone.Core.Model;
+using NzbDrone.Core.Repository.Quality;
+using Rss;
+
+namespace NzbDrone.Core.Providers
+{
+ public class RssSyncProvider : IRssSyncProvider
+ {
+ //Sync with RSS feeds to download files as needed
+
+ private Thread _rssSyncThread;
+ private IIndexerProvider _indexerProvider;
+ private IRssProvider _rss;
+ private ISeriesProvider _series;
+ private ISeasonProvider _season;
+ private IEpisodeProvider _episode;
+ private IHistoryProvider _history;
+ private IDownloadProvider _sab;
+
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ public RssSyncProvider(IIndexerProvider indexerProvider, IRssProvider rss, ISeriesProvider series,
+ ISeasonProvider season, IEpisodeProvider episode, IHistoryProvider history, IDownloadProvider sab)
+ {
+ _indexerProvider = indexerProvider;
+ _rss = rss;
+ _series = series;
+ _season = season;
+ _episode = episode;
+ _history = history;
+ _sab = sab;
+ }
+
+ #region IRssSyncProvider Members
+
+ public void Begin()
+ {
+ Logger.Debug("RSS Sync Starting");
+ if (_rssSyncThread == null || !_rssSyncThread.IsAlive)
+ {
+ Logger.Debug("Initializing background sync of RSS Feeds.");
+ _rssSyncThread = new Thread(SyncWithRss)
+ {
+ Name = "SyncUnmappedFolders",
+ Priority = ThreadPriority.Lowest
+ };
+
+ _rssSyncThread.Start();
+ }
+ else
+ {
+ Logger.Warn("RSS Sync already in progress. Ignoring request.");
+ }
+
+ }
+
+ #endregion
+
+ private void SyncWithRss()
+ {
+ //Get all enabled RSS providers
+ //Download Feeds
+
+ var indexers = _indexerProvider.EnabledIndexers();
+
+ foreach (var i in indexers)
+ {
+ var indexer = new FeedInfoModel(i.IndexerName, i.RssUrl);
+
+ foreach(RssItem item in _rss.GetFeed(indexer))
+ {
+ NzbInfoModel nzb = Parser.ParseNzbInfo(indexer, item);
+ QueueIfWanted(nzb);
+ }
+ }
+ }
+
+ private void QueueIfWanted(NzbInfoModel nzb)
+ {
+ //Do we want this item?
+
+ try
+ {
+ if (nzb.IsPassworded())
+ {
+ Logger.Debug("Skipping Passworded Report {0}", nzb.Title);
+ return;
+ }
+
+ var episodeParseResults = Parser.ParseEpisodeInfo(nzb.Title);
+
+ if (episodeParseResults.Count() < 1)
+ {
+ Logger.Debug("Unsupported Title: {0}", nzb.Title);
+ return;
+ }
+
+ if (episodeParseResults.Count() > 0)
+ {
+ //Todo: How to determine if we want the show if the FeedTitle is drastically different from the TitleOnDisk (CSI is one that comes to mind)
+ var series = _series.FindSeries(episodeParseResults[0].SeriesTitle);
+
+ if (series == null)
+ {
+ Logger.Debug("Show is not being watched: {0}", episodeParseResults[0].SeriesTitle);
+ return;
+ }
+
+ Logger.Debug("Show is being watched: {0}", series.Title);
+
+ nzb.TitleFix = GetTitleFix(episodeParseResults, series.SeriesId); //Get the TitleFix so we can use it later
+ nzb.Proper = Parser.ParseProper(nzb.Title);
+
+ //Loop through the list of the episodeParseResults to ensure that all the episodes are needed)
+ foreach (var episode in episodeParseResults)
+ {
+ //IsEpisodeWanted?
+ var episodeModel = new EpisodeModel();
+ episodeModel.Proper = nzb.Proper;
+ episodeModel.SeriesId = series.SeriesId;
+ episodeModel.SeriesTitle = series.Title;
+ episodeModel.Quality = Parser.ParseQuality(nzb.Title);
+ episodeModel.SeasonNumber = episode.SeasonNumber;
+ episodeModel.EpisodeNumber = episode.EpisodeNumber;
+
+ if (!_episode.IsNeeded(episodeModel))
+ return;
+
+ var titleFix = GetTitleFix(new List { episode }, episodeModel.SeriesId);
+ _sab.IsInQueue(titleFix);
+ }
+ }
+ }
+
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error Parsing NZB: " + ex.Message, ex);
+ }
+ }
+
+ private string GetTitleFix(List episodes, int seriesId)
+ {
+ var series = _series.GetSeries(seriesId);
+
+ int seasonNumber = 0;
+ string episodeNumbers = String.Empty;
+ string episodeTitles = String.Empty;
+
+ foreach (var episode in episodes)
+ {
+ var episodeInDb = _episode.GetEpisode(seriesId, episode.SeasonNumber, episode.EpisodeNumber);
+ seasonNumber = episodeInDb.SeasonNumber;
+ episodeNumbers = String.Format("{0}x{1:00}", episodeNumbers, episodeInDb.EpisodeNumber);
+ episodeTitles = String.Format("{0} + {1}", episodeTitles, episodeInDb.Title);
+ }
+
+ return String.Format("{0} - {1}{2} - {3}", series.Title, seasonNumber, episodeNumbers, episodeTitles);
+ }
+ }
+}
diff --git a/NzbDrone.Core/Providers/SeasonProvider.cs b/NzbDrone.Core/Providers/SeasonProvider.cs
index 85a22d85e..686ba0050 100644
--- a/NzbDrone.Core/Providers/SeasonProvider.cs
+++ b/NzbDrone.Core/Providers/SeasonProvider.cs
@@ -3,13 +3,14 @@ using System.Collections.Generic;
using NLog;
using NzbDrone.Core.Repository;
using SubSonic.Repository;
+using System.Linq;
namespace NzbDrone.Core.Providers
{
class SeasonProvider : ISeasonProvider
{
private readonly IRepository _sonicRepo;
- private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger();
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public SeasonProvider(IRepository dataRepository)
{
@@ -18,12 +19,12 @@ namespace NzbDrone.Core.Providers
public Season GetSeason(int seasonId)
{
- throw new NotImplementedException();
+ return _sonicRepo.Single(seasonId);
}
public List GetSeasons(int seriesId)
{
- throw new NotImplementedException();
+ return _sonicRepo.All().Where(s => s.SeriesId == seriesId).ToList();
}
public void EnsureSeason(int seriesId, int seasonId, int seasonNumber)
@@ -43,11 +44,27 @@ namespace NzbDrone.Core.Providers
_sonicRepo.Add(newSeason);
}
-
-
public int SaveSeason(Season season)
{
throw new NotImplementedException();
}
+
+ public bool IsIgnored(int seasonId)
+ {
+ if (_sonicRepo.Single(seasonId).Monitored)
+ return true;
+
+ Logger.Debug("Season {0} is not wanted.");
+ return false;
+ }
+
+ public bool IsIgnored(int seriesId, int seasonNumber)
+ {
+ if (_sonicRepo.Single(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber).Monitored)
+ return true;
+
+ Logger.Debug("Season: {0} is not wanted for Series: {1}", seasonNumber, seriesId);
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs
index 4a393cd5d..361d0723b 100644
--- a/NzbDrone.Core/Providers/SeriesProvider.cs
+++ b/NzbDrone.Core/Providers/SeriesProvider.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Core.Repository;
+using NzbDrone.Core.Repository.Quality;
using SubSonic.Repository;
using TvdbLib.Data;
@@ -52,6 +53,11 @@ namespace NzbDrone.Core.Providers
return _sonioRepo.Exists(c => c.SeriesId == id && c.Monitored);
}
+ public bool QualityWanted(int seriesId, QualityTypes quality)
+ {
+ return _sonioRepo.Exists(s => s.SeriesId == seriesId && (QualityTypes)s.Quality == quality);
+ }
+
public List GetUnmappedFolders()
{
Logger.Debug("Generating list of unmapped folders");
@@ -83,7 +89,6 @@ namespace NzbDrone.Core.Providers
return _tvDb.GetSeries(searchResults.Id, false);
}
-
public void AddSeries(string path, TvdbSeries series)
{
Logger.Info("Adding Series [{0}]:{1} Path: {2}", series.Id, series.SeriesName, path);
@@ -100,6 +105,11 @@ namespace NzbDrone.Core.Providers
_sonioRepo.Add(repoSeries);
}
+ public Series FindSeries(string cleanTitle)
+ {
+ return _sonioRepo.Single(s => s.CleanTitle == cleanTitle);
+ }
+
#endregion
#region Static Helpers
diff --git a/NzbDrone.Core/Providers/TvDbProvider.cs b/NzbDrone.Core/Providers/TvDbProvider.cs
index a9a1c079e..84ebfd98d 100644
--- a/NzbDrone.Core/Providers/TvDbProvider.cs
+++ b/NzbDrone.Core/Providers/TvDbProvider.cs
@@ -11,7 +11,7 @@ namespace NzbDrone.Core.Providers
{
public class TvDbProvider : ITvDbProvider
{
- private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger();
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly Regex CleanUpRegex = new Regex(@"((\s|^)the(\s|$))|((\s|^)and(\s|$))|[^a-z]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private const string TVDB_APIKEY = "5D2D188E86E07F4F";
diff --git a/NzbDrone.Core/Repository/Episode.cs b/NzbDrone.Core/Repository/Episode.cs
index 27a58e713..6e20c4098 100644
--- a/NzbDrone.Core/Repository/Episode.cs
+++ b/NzbDrone.Core/Repository/Episode.cs
@@ -15,6 +15,7 @@ namespace NzbDrone.Core.Repository
public int SeasonId { get; set; }
public string Title { get; set; }
public DateTime AirDate { get; set; }
+ [SubSonicLongString]
public string Overview { get; set; }
public string Language { get; set; }
@@ -26,5 +27,8 @@ namespace NzbDrone.Core.Repository
[SubSonicToManyRelation]
public virtual List Files { get; private set; }
+
+ [SubSonicToManyRelation]
+ public virtual List Histories { get; private set; }
}
}
diff --git a/NzbDrone.Core/Repository/History.cs b/NzbDrone.Core/Repository/History.cs
new file mode 100644
index 000000000..b6a4b6b04
--- /dev/null
+++ b/NzbDrone.Core/Repository/History.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using SubSonic.SqlGeneration.Schema;
+
+namespace NzbDrone.Core.Repository
+{
+ public class History
+ {
+ public int HistoryId { get; set; }
+ public virtual int EpisodeId { get; set; }
+ public virtual string IndexerName { get; set; }
+ public int Quality { get; set; }
+ public DateTime Date { get; set; }
+ public bool IsProper { get; set; }
+
+ [SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
+ public virtual Episode Episode { get; set; }
+
+ [SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
+ public virtual Indexer Indexer { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/Repository/Indexer.cs b/NzbDrone.Core/Repository/Indexer.cs
new file mode 100644
index 000000000..b8730ce07
--- /dev/null
+++ b/NzbDrone.Core/Repository/Indexer.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using SubSonic.SqlGeneration.Schema;
+
+namespace NzbDrone.Core.Repository
+{
+ public class Indexer
+ {
+ [SubSonicPrimaryKey (true)]
+ public string IndexerName { get; set; }
+ public string RssUrl { get; set; }
+
+ [SubSonicNullStringAttribute]
+ public string ApiUrl { get; set; }
+ public bool Enabled { get; set; }
+ public int Order { get; set; }
+
+ [SubSonicToManyRelation]
+ public virtual List Histories { get; private set; }
+ }
+}
diff --git a/NzbDrone.Core/Repository/Season.cs b/NzbDrone.Core/Repository/Season.cs
index aaeb11a90..b0f5a5a3a 100644
--- a/NzbDrone.Core/Repository/Season.cs
+++ b/NzbDrone.Core/Repository/Season.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using SubSonic.SqlGeneration.Schema;
namespace NzbDrone.Core.Repository
@@ -6,8 +7,8 @@ namespace NzbDrone.Core.Repository
public class Season
{
[SubSonicPrimaryKey(false)]
- public virtual long SeasonId { get; set; }
- public long SeriesId { get; set; }
+ public virtual int SeasonId { get; set; }
+ public int SeriesId { get; set; }
public int SeasonNumber { get; set; }
public bool Monitored { get; set; }
diff --git a/NzbDrone.Core/Repository/Series.cs b/NzbDrone.Core/Repository/Series.cs
index e9c03b929..78c6ae624 100644
--- a/NzbDrone.Core/Repository/Series.cs
+++ b/NzbDrone.Core/Repository/Series.cs
@@ -29,6 +29,8 @@ namespace NzbDrone.Core.Repository
public bool Monitored { get; set; }
+ public int Quality { get; set; }
+
[SubSonicToManyRelation]
public virtual List Seasons { get; private set; }
diff --git a/NzbDrone.Web.Test/App.config b/NzbDrone.Web.Test/App.config
index f00e873ec..64ee57c34 100644
--- a/NzbDrone.Web.Test/App.config
+++ b/NzbDrone.Web.Test/App.config
@@ -1,14 +1,24 @@
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NzbDrone.Web.Test/NzbDrone.Web.Tests.csproj b/NzbDrone.Web.Test/NzbDrone.Web.Tests.csproj
index 52baaa9f2..4315eadbe 100644
--- a/NzbDrone.Web.Test/NzbDrone.Web.Tests.csproj
+++ b/NzbDrone.Web.Test/NzbDrone.Web.Tests.csproj
@@ -23,6 +23,7 @@
DEBUG;TRACEprompt4
+ x86pdbonly
diff --git a/NzbDrone.Web/Content/Images/.svn/all-wcprops b/NzbDrone.Web/Content/Images/.svn/all-wcprops
new file mode 100644
index 000000000..805301755
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/all-wcprops
@@ -0,0 +1,101 @@
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images
+END
+ui-icons_ffffff_256x240.png
+K 25
+svn:wc:ra_dav:version-url
+V 98
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-icons_ffffff_256x240.png
+END
+ui-icons_cd0a0a_256x240.png
+K 25
+svn:wc:ra_dav:version-url
+V 98
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-icons_cd0a0a_256x240.png
+END
+ui-icons_72a7cf_256x240.png
+K 25
+svn:wc:ra_dav:version-url
+V 98
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-icons_72a7cf_256x240.png
+END
+ui-bg_glass_100_f0f0f0_1x400.png
+K 25
+svn:wc:ra_dav:version-url
+V 103
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_glass_100_f0f0f0_1x400.png
+END
+ui-bg_highlight-soft_100_e7eef3_1x100.png
+K 25
+svn:wc:ra_dav:version-url
+V 112
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_highlight-soft_100_e7eef3_1x100.png
+END
+ui-icons_222222_256x240.png
+K 25
+svn:wc:ra_dav:version-url
+V 98
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-icons_222222_256x240.png
+END
+ui-bg_highlight-hard_100_f9f9f9_1x100.png
+K 25
+svn:wc:ra_dav:version-url
+V 112
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png
+END
+ui-icons_2e83ff_256x240.png
+K 25
+svn:wc:ra_dav:version-url
+V 98
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-icons_2e83ff_256x240.png
+END
+ui-bg_diagonals-small_0_aaaaaa_40x40.png
+K 25
+svn:wc:ra_dav:version-url
+V 111
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png
+END
+ui-bg_glass_95_fef1ec_1x400.png
+K 25
+svn:wc:ra_dav:version-url
+V 102
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_glass_95_fef1ec_1x400.png
+END
+ui-bg_glass_50_99c2ff_1x400.png
+K 25
+svn:wc:ra_dav:version-url
+V 102
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_glass_50_99c2ff_1x400.png
+END
+ui-icons_888888_256x240.png
+K 25
+svn:wc:ra_dav:version-url
+V 98
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-icons_888888_256x240.png
+END
+ui-bg_glass_80_e6e6e6_1x400.png
+K 25
+svn:wc:ra_dav:version-url
+V 102
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_glass_80_e6e6e6_1x400.png
+END
+ui-bg_diagonals-thick_15_444444_40x40.png
+K 25
+svn:wc:ra_dav:version-url
+V 112
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_diagonals-thick_15_444444_40x40.png
+END
+ui-icons_2694e8_256x240.png
+K 25
+svn:wc:ra_dav:version-url
+V 98
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-icons_2694e8_256x240.png
+END
+ui-bg_glass_55_fbf5d0_1x400.png
+K 25
+svn:wc:ra_dav:version-url
+V 102
+/svn/WebWinkel/!svn/ver/21/trunk/Bestel/Content/Theme_Cupertino/images/ui-bg_glass_55_fbf5d0_1x400.png
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/entries b/NzbDrone.Web/Content/Images/.svn/entries
new file mode 100644
index 000000000..4fcc4e9df
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/entries
@@ -0,0 +1,579 @@
+9
+
+dir
+21
+https://server2003:8443/svn/WebWinkel/trunk/Bestel/Content/Theme_Cupertino/images
+https://server2003:8443/svn/WebWinkel
+
+
+
+2009-03-06T14:15:55.199272Z
+21
+ers
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+3df9b5ea-419e-9541-a5e1-220ca4e478c2
+
+
+
+
+
+
+0
+
+ui-icons_ffffff_256x240.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+4de00da1c8312a0402eb34ef1a727227
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4379
+
+ui-icons_cd0a0a_256x240.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+85eb7d511838b9bc089b7d6efd4ded92
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4379
+
+ui-icons_72a7cf_256x240.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+80f2c70881fca0c579f48b792d97e904
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5399
+
+ui-bg_glass_100_f0f0f0_1x400.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+e9d6692a317729586e10e9c9ebbe0efe
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+106
+
+ui-bg_highlight-soft_100_e7eef3_1x100.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+9b5c95a4d5c087377add1f43621ced45
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+149
+
+ui-icons_222222_256x240.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+89a6553a4bba879b4944ba11cf061e04
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4379
+
+ui-bg_highlight-hard_100_f9f9f9_1x100.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+0df7f895481fe8e47e7114399f644583
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+117
+
+ui-icons_2e83ff_256x240.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+a4127cef04012ee8681adef24d8e2a0f
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4379
+
+ui-bg_diagonals-small_0_aaaaaa_40x40.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+1fa4d379c6be86d335082c92b767cd23
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+128
+
+ui-bg_glass_95_fef1ec_1x400.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+5a3be2d8fff8324d59aec3df7b0a0c83
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+119
+
+ui-bg_glass_50_99c2ff_1x400.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+343a57f7e2ce3eec88824047180db85c
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+159
+
+ui-icons_888888_256x240.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+4ec07344d71ee10034427088ec6f3ca3
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4379
+
+ui-bg_glass_80_e6e6e6_1x400.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+4835b082c0a5bccfe84c671ec559d805
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+113
+
+ui-bg_diagonals-thick_15_444444_40x40.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+8d91ecb66ca58a9a787b7cf567fe317c
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+373
+
+ui-icons_2694e8_256x240.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+fa3a8f67fa343d6afc810e061c522b72
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4379
+
+ui-bg_glass_55_fbf5d0_1x400.png
+file
+
+
+
+
+2009-03-06T03:20:14.000000Z
+9871dd318a7253034b93f19f87a9ed5b
+2009-03-06T14:15:55.199272Z
+21
+ers
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+123
+
diff --git a/NzbDrone.Web/Content/Images/.svn/format b/NzbDrone.Web/Content/Images/.svn/format
new file mode 100644
index 000000000..ec635144f
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/format
@@ -0,0 +1 @@
+9
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_diagonals-small_0_aaaaaa_40x40.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_diagonals-small_0_aaaaaa_40x40.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_diagonals-small_0_aaaaaa_40x40.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_diagonals-thick_15_444444_40x40.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_diagonals-thick_15_444444_40x40.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_diagonals-thick_15_444444_40x40.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_100_f0f0f0_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_100_f0f0f0_1x400.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_100_f0f0f0_1x400.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_50_99c2ff_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_50_99c2ff_1x400.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_50_99c2ff_1x400.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_55_fbf5d0_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_55_fbf5d0_1x400.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_55_fbf5d0_1x400.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_80_e6e6e6_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_80_e6e6e6_1x400.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_80_e6e6e6_1x400.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_95_fef1ec_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_95_fef1ec_1x400.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_glass_95_fef1ec_1x400.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_highlight-hard_100_f9f9f9_1x100.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_highlight-hard_100_f9f9f9_1x100.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_highlight-hard_100_f9f9f9_1x100.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_highlight-soft_100_e7eef3_1x100.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_highlight-soft_100_e7eef3_1x100.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-bg_highlight-soft_100_e7eef3_1x100.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_222222_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_222222_256x240.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_222222_256x240.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_2694e8_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_2694e8_256x240.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_2694e8_256x240.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_2e83ff_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_2e83ff_256x240.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_2e83ff_256x240.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_72a7cf_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_72a7cf_256x240.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_72a7cf_256x240.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_888888_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_888888_256x240.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_888888_256x240.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_cd0a0a_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_cd0a0a_256x240.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_cd0a0a_256x240.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_ffffff_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_ffffff_256x240.png.svn-base
new file mode 100644
index 000000000..5e9587e65
--- /dev/null
+++ b/NzbDrone.Web/Content/Images/.svn/prop-base/ui-icons_ffffff_256x240.png.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_diagonals-small_0_aaaaaa_40x40.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_diagonals-small_0_aaaaaa_40x40.png.svn-base
new file mode 100644
index 000000000..d5359734a
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_diagonals-small_0_aaaaaa_40x40.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_diagonals-thick_15_444444_40x40.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_diagonals-thick_15_444444_40x40.png.svn-base
new file mode 100644
index 000000000..a24c5aab6
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_diagonals-thick_15_444444_40x40.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_100_f0f0f0_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_100_f0f0f0_1x400.png.svn-base
new file mode 100644
index 000000000..33896e710
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_100_f0f0f0_1x400.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_50_99c2ff_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_50_99c2ff_1x400.png.svn-base
new file mode 100644
index 000000000..a717a043d
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_50_99c2ff_1x400.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_55_fbf5d0_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_55_fbf5d0_1x400.png.svn-base
new file mode 100644
index 000000000..0f45be78c
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_55_fbf5d0_1x400.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_80_e6e6e6_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_80_e6e6e6_1x400.png.svn-base
new file mode 100644
index 000000000..abaa23f00
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_80_e6e6e6_1x400.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_95_fef1ec_1x400.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_95_fef1ec_1x400.png.svn-base
new file mode 100644
index 000000000..4443fdc1a
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_glass_95_fef1ec_1x400.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_highlight-hard_100_f9f9f9_1x100.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_highlight-hard_100_f9f9f9_1x100.png.svn-base
new file mode 100644
index 000000000..4812b8676
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_highlight-hard_100_f9f9f9_1x100.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_highlight-soft_100_e7eef3_1x100.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_highlight-soft_100_e7eef3_1x100.png.svn-base
new file mode 100644
index 000000000..d39c18227
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-bg_highlight-soft_100_e7eef3_1x100.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_222222_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_222222_256x240.png.svn-base
new file mode 100644
index 000000000..67560da9b
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_222222_256x240.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_2694e8_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_2694e8_256x240.png.svn-base
new file mode 100644
index 000000000..dbd78b68a
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_2694e8_256x240.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_2e83ff_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_2e83ff_256x240.png.svn-base
new file mode 100644
index 000000000..b425c446d
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_2e83ff_256x240.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_72a7cf_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_72a7cf_256x240.png.svn-base
new file mode 100644
index 000000000..6183ac205
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_72a7cf_256x240.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_888888_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_888888_256x240.png.svn-base
new file mode 100644
index 000000000..2e5180e47
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_888888_256x240.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_cd0a0a_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_cd0a0a_256x240.png.svn-base
new file mode 100644
index 000000000..2db88b796
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_cd0a0a_256x240.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_ffffff_256x240.png.svn-base b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_ffffff_256x240.png.svn-base
new file mode 100644
index 000000000..746e6fa25
Binary files /dev/null and b/NzbDrone.Web/Content/Images/.svn/text-base/ui-icons_ffffff_256x240.png.svn-base differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_diagonals-small_0_aaaaaa_40x40.png b/NzbDrone.Web/Content/Images/ui-bg_diagonals-small_0_aaaaaa_40x40.png
new file mode 100644
index 000000000..d5359734a
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_diagonals-small_0_aaaaaa_40x40.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_diagonals-thick_15_444444_40x40.png b/NzbDrone.Web/Content/Images/ui-bg_diagonals-thick_15_444444_40x40.png
new file mode 100644
index 000000000..a24c5aab6
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_diagonals-thick_15_444444_40x40.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_glass_100_f0f0f0_1x400.png b/NzbDrone.Web/Content/Images/ui-bg_glass_100_f0f0f0_1x400.png
new file mode 100644
index 000000000..33896e710
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_glass_100_f0f0f0_1x400.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_glass_50_99c2ff_1x400.png b/NzbDrone.Web/Content/Images/ui-bg_glass_50_99c2ff_1x400.png
new file mode 100644
index 000000000..a717a043d
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_glass_50_99c2ff_1x400.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_glass_55_fbf5d0_1x400.png b/NzbDrone.Web/Content/Images/ui-bg_glass_55_fbf5d0_1x400.png
new file mode 100644
index 000000000..0f45be78c
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_glass_55_fbf5d0_1x400.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_glass_80_e6e6e6_1x400.png b/NzbDrone.Web/Content/Images/ui-bg_glass_80_e6e6e6_1x400.png
new file mode 100644
index 000000000..abaa23f00
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_glass_80_e6e6e6_1x400.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_glass_95_fef1ec_1x400.png b/NzbDrone.Web/Content/Images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 000000000..4443fdc1a
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_glass_95_fef1ec_1x400.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_highlight-hard_100_f9f9f9_1x100.png b/NzbDrone.Web/Content/Images/ui-bg_highlight-hard_100_f9f9f9_1x100.png
new file mode 100644
index 000000000..4812b8676
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_highlight-hard_100_f9f9f9_1x100.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-bg_highlight-soft_100_e7eef3_1x100.png b/NzbDrone.Web/Content/Images/ui-bg_highlight-soft_100_e7eef3_1x100.png
new file mode 100644
index 000000000..d39c18227
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-bg_highlight-soft_100_e7eef3_1x100.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-icons_222222_256x240.png b/NzbDrone.Web/Content/Images/ui-icons_222222_256x240.png
new file mode 100644
index 000000000..67560da9b
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-icons_222222_256x240.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-icons_2694e8_256x240.png b/NzbDrone.Web/Content/Images/ui-icons_2694e8_256x240.png
new file mode 100644
index 000000000..dbd78b68a
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-icons_2694e8_256x240.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-icons_2e83ff_256x240.png b/NzbDrone.Web/Content/Images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 000000000..b425c446d
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-icons_2e83ff_256x240.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-icons_72a7cf_256x240.png b/NzbDrone.Web/Content/Images/ui-icons_72a7cf_256x240.png
new file mode 100644
index 000000000..6183ac205
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-icons_72a7cf_256x240.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-icons_888888_256x240.png b/NzbDrone.Web/Content/Images/ui-icons_888888_256x240.png
new file mode 100644
index 000000000..2e5180e47
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-icons_888888_256x240.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-icons_cd0a0a_256x240.png b/NzbDrone.Web/Content/Images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 000000000..2db88b796
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-icons_cd0a0a_256x240.png differ
diff --git a/NzbDrone.Web/Content/Images/ui-icons_ffffff_256x240.png b/NzbDrone.Web/Content/Images/ui-icons_ffffff_256x240.png
new file mode 100644
index 000000000..746e6fa25
Binary files /dev/null and b/NzbDrone.Web/Content/Images/ui-icons_ffffff_256x240.png differ
diff --git a/NzbDrone.Web/Content/ajax-loader.gif b/NzbDrone.Web/Content/ajax-loader.gif
new file mode 100644
index 000000000..2e9d85eed
Binary files /dev/null and b/NzbDrone.Web/Content/ajax-loader.gif differ
diff --git a/NzbDrone.Web/Content/jquery-ui-1.8.8.custom.css b/NzbDrone.Web/Content/jquery-ui-1.8.8.custom.css
new file mode 100644
index 000000000..ef0d93dbc
--- /dev/null
+++ b/NzbDrone.Web/Content/jquery-ui-1.8.8.custom.css
@@ -0,0 +1,572 @@
+/*
+ * jQuery UI CSS Framework 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
+.ui-widget-content a { color: #333333; }
+.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+.ui-widget-header a { color: #ffffff; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
+.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
+ * jQuery UI Resizable 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
+ * jQuery UI Selectable 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*
+ * jQuery UI Accordion 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }/*
+ * jQuery UI Autocomplete 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+ list-style:none;
+ padding: 2px;
+ margin: 0;
+ display:block;
+ float: left;
+}
+.ui-menu .ui-menu {
+ margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+ margin:0;
+ padding: 0;
+ zoom: 1;
+ float: left;
+ clear: left;
+ width: 100%;
+}
+.ui-menu .ui-menu-item a {
+ text-decoration:none;
+ display:block;
+ padding:.2em .4em;
+ line-height:1.5;
+ zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+ font-weight: normal;
+ margin: -1px;
+}
+/*
+ * jQuery UI Button 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4; }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*
+ * jQuery UI Dialog 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*
+ * jQuery UI Slider 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
+ * jQuery UI Tabs 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*
+ * jQuery UI Datepicker 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}/*
+ * jQuery UI Progressbar 1.8.8
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file
diff --git a/NzbDrone.Web/Content/jquery-ui.css b/NzbDrone.Web/Content/jquery-ui.css
new file mode 100644
index 000000000..ccbf186f0
--- /dev/null
+++ b/NzbDrone.Web/Content/jquery-ui.css
@@ -0,0 +1,405 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=3px&bgColorHeader=e7eef3&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=100&borderColorHeader=b2c7d7&fcHeader=222222&iconColorHeader=72a7cf&bgColorContent=f9f9f9&bgTextureContent=04_highlight_hard.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=362b36&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=80&borderColorDefault=cccccc&fcDefault=444444&iconColorDefault=888888&bgColorHover=f0f0f0&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=b2c7d7&fcHover=0b5b98&iconColorHover=2694e8&bgColorActive=99c2ff&bgTextureActive=02_glass.png&bgImgOpacityActive=50&borderColorActive=2694e8&fcActive=000000&iconColorActive=ffffff&bgColorHighlight=fbf5d0&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=f9dd34&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=444444&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=15&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=07_diagonals_small.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=0px&offsetTopShadow=4px&offsetLeftShadow=4px&cornerRadiusShadow=4px
+*/
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #dddddd; background: #f9f9f9 url(images/ui-bg_highlight-hard_100_f9f9f9_1x100.png) 50% top repeat-x; color: #362b36; }
+.ui-widget-content a { color: #362b36; }
+.ui-widget-header { border: 1px solid #b2c7d7; background: #e7eef3 url(images/ui-bg_highlight-soft_100_e7eef3_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #cccccc; background: #e6e6e6 url(images/ui-bg_glass_80_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #444444; outline: none; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #444444; text-decoration: none; outline: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #b2c7d7; background: #f0f0f0 url(images/ui-bg_glass_100_f0f0f0_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #0b5b98; outline: none; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #0b5b98; text-decoration: none; outline: none; }
+.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #2694e8; background: #99c2ff url(images/ui-bg_glass_50_99c2ff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #000000; outline: none; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #000000; outline: none; text-decoration: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #f9dd34; background: #fbf5d0 url(images/ui-bg_glass_55_fbf5d0_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_72a7cf_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_2694e8_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; }
+.ui-corner-tr { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; }
+.ui-corner-br { -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; }
+.ui-corner-top { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; }
+.ui-corner-right { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; }
+.ui-corner-left { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; }
+.ui-corner-all { -moz-border-radius: 3px; -webkit-border-radius: 3px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #444444 url(images/ui-bg_diagonals-thick_15_444444_40x40.png) 50% 50% repeat; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: 4px 0 0 4px; padding: 0px; background: #aaaaaa url(images/ui-bg_diagonals-small_0_aaaaaa_40x40.png) 50% 50% repeat; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 4px; -webkit-border-radius: 4px; }/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Accordion
+----------------------------------*/
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
+.ui-accordion .ui-accordion-content-active { display: block; }/* Dialog
+----------------------------------*/
+.ui-dialog { position: relative; padding: .2em; width: 300px; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/* Slider
+----------------------------------*/
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
+----------------------------------*/
+.ui-tabs { padding: .2em; zoom: 1; }
+.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
+.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/* Datepicker
+----------------------------------*/
+.ui-datepicker { width: 17em; padding: .2em .2em 0; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}/* Progressbar
+----------------------------------*/
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file
diff --git a/NzbDrone.Web/Content/jquery-ui.custom.css b/NzbDrone.Web/Content/jquery-ui.custom.css
new file mode 100644
index 000000000..ab1742531
--- /dev/null
+++ b/NzbDrone.Web/Content/jquery-ui.custom.css
@@ -0,0 +1,17 @@
+/* Customisation of jQuery-ui classes */
+
+.ui-state-error
+{
+ padding: 3px;
+ padding-left : 10px;
+}
+
+.ui-state-highlight {
+ padding: 3px;
+ padding-left : 10px;
+}
+
+.ui-icon
+{
+ margin-top: 2px;
+}
diff --git a/NzbDrone.Web/Content/style.css b/NzbDrone.Web/Content/style.css
index 8aa87cc9f..58f4bb84d 100644
--- a/NzbDrone.Web/Content/style.css
+++ b/NzbDrone.Web/Content/style.css
@@ -119,7 +119,7 @@ hr
#page
{
- margin: 0 auto 60px;
+ margin: 0 auto 10px;
overflow: hidden;
background-color: White;
padding: 10px 20px 20px 20px;
@@ -153,9 +153,22 @@ hr
font-family: Consolas, Monospace;
}
-/*fix telerik grid missing boarder*/
+/*fix telerik grid missing border*/
.t-grid .t-last
{
border-bottom: 1px solid #EEEEEE;
border-color: #EEEEEE;
}
+
+/* Footer */
+.timer
+{
+ text-align: center;
+ color: #065EFE;
+}
+
+#footer
+{
+ padding: 1px, 1px, 1px, 1px;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/NzbDrone.Web/Controllers/Copy of SettingsController.cs b/NzbDrone.Web/Controllers/Copy of SettingsController.cs
new file mode 100644
index 000000000..8f8f229ba
--- /dev/null
+++ b/NzbDrone.Web/Controllers/Copy of SettingsController.cs
@@ -0,0 +1,41 @@
+//using System;
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Threading;
+//using System.Web;
+//using System.Web.Mvc;
+//using NzbDrone.Core.Providers;
+//using NzbDrone.Web.Models;
+
+//namespace NzbDrone.Web.Controllers
+//{
+// [HandleError]
+// public class SettingsController : Controller
+// {
+// //
+// // GET: /Settings/
+// private IConfigProvider _configProvider;
+
+// public SettingsController(IConfigProvider configProvider)
+// {
+// _configProvider = configProvider;
+// }
+
+// public ActionResult Index()
+// {
+// return View(new SettingsModel() { TvFolder = _configProvider.SeriesRoot });
+// }
+
+// [HttpPost]
+// public ActionResult Index(SettingsModel model)
+// {
+// if (ModelState.IsValid)
+// {
+// _configProvider.SeriesRoot = model.TvFolder;
+// //return RedirectToAction("index");
+// }
+// return RedirectToAction("index", "series");
+// }
+
+// }
+//}
diff --git a/NzbDrone.Web/Controllers/SettingsController.cs b/NzbDrone.Web/Controllers/SettingsController.cs
index 2add481f3..9aeb4c78d 100644
--- a/NzbDrone.Web/Controllers/SettingsController.cs
+++ b/NzbDrone.Web/Controllers/SettingsController.cs
@@ -4,7 +4,8 @@ using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
-using NzbDrone.Core.Providers;
+using NLog;
+using NzbDrone.Core.Providers;
using NzbDrone.Web.Models;
namespace NzbDrone.Web.Controllers
@@ -12,30 +13,222 @@ namespace NzbDrone.Web.Controllers
[HandleError]
public class SettingsController : Controller
{
- //
- // GET: /Settings/
private IConfigProvider _configProvider;
+ private IIndexerProvider _indexerProvider;
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
- public SettingsController(IConfigProvider configProvider)
+ public SettingsController(IConfigProvider configProvider, IIndexerProvider indexerProvider)
{
_configProvider = configProvider;
+ _indexerProvider = indexerProvider;
}
- public ActionResult Index()
+ public ActionResult Index(string viewName)
{
- return View(new SettingsModel() { TvFolder = _configProvider.SeriesRoot });
+ if (viewName != null)
+ ViewData["viewName"] = viewName;
+
+ else
+ ViewData["viewName"] = "General";
+
+ return View("Index", new SettingsModel
+ {
+ TvFolder = _configProvider.SeriesRoot
+ });
+ }
+
+ public ActionResult General()
+ {
+ ViewData["viewName"] = "General";
+ return View("Index", new SettingsModel
+ {
+ TvFolder = _configProvider.SeriesRoot
+ });
+ }
+
+ public ActionResult Indexers()
+ {
+ ViewData["viewName"] = "Indexers";
+ return View("Index", new SettingsModel
+ {
+ NzbMatrixUsername = _configProvider.GetValue("NzbMatrixUsername", String.Empty, false),
+ NzbMatrixApiKey = _configProvider.GetValue("NzbMatrixApiKey", String.Empty, false),
+ NzbsOrgUId = _configProvider.GetValue("NzbsOrgUId", String.Empty, false),
+ NzbsOrgHash = _configProvider.GetValue("NzbsOrgHash", String.Empty, false),
+ NzbsrusUId = _configProvider.GetValue("NzbsrusUId", String.Empty, false),
+ NzbsrusHash = _configProvider.GetValue("NzbsrusHash", String.Empty, false),
+ Indexers = _indexerProvider.AllIndexers()
+ });
+ }
+
+ public ActionResult Downloads()
+ {
+ ViewData["viewName"] = "Downloads";
+ return View("Index", new SettingsModel
+ {
+ //Sync Frequency
+ //Download Propers?
+ //Retention
+ //SAB Host/IP
+ //SAB Port
+ //SAB APIKey
+ //SAB Username
+ //SAB Password
+ //SAB Category
+ //SAB Priority
+
+ SyncFrequency = Convert.ToInt32(_configProvider.GetValue("SyncFrequency", "15", true)),
+ DownloadPropers = Convert.ToBoolean(_configProvider.GetValue("DownloadPropers", "false", true)),
+ Rentention = Convert.ToInt32(_configProvider.GetValue("Rentention", "500", true)),
+ SabHost = _configProvider.GetValue("SabHost", "localhost", false),
+ SabPort = Convert.ToInt32(_configProvider.GetValue("SabPort", "8080", true)),
+ SabApiKey = _configProvider.GetValue("SabApiKey", String.Empty, false),
+ SabUsername = _configProvider.GetValue("SabUsername", String.Empty, false),
+ SabPassword = _configProvider.GetValue("SabPassword", String.Empty, false),
+ SabCategory = _configProvider.GetValue("SabCategory", String.Empty, false),
+ //SabPriority = _configProvider.GetValue("SabPriority", String.Empty, false)
+ });
+ }
+
+ public ActionResult SubMenu()
+ {
+ return PartialView();
}
[HttpPost]
- public ActionResult Index(SettingsModel model)
+ public ActionResult Index(SettingsModel data)
{
- if (ModelState.IsValid)
+ try
{
- _configProvider.SeriesRoot = model.TvFolder;
- //return RedirectToAction("index");
+ _configProvider.SeriesRoot = data.TvFolder;
+ _configProvider.SetValue("NzbMatrixUsername", data.NzbMatrixUsername);
+ _configProvider.SetValue("NzbMatrixApiKey", data.NzbMatrixApiKey);
+ _configProvider.SetValue("NzbsOrgUId", data.NzbsOrgUId);
+ _configProvider.SetValue("NzbsOrgHash", data.NzbsOrgHash);
}
- return RedirectToAction("index", "series");
+ catch (Exception)
+ {
+ if (Request.IsAjaxRequest())
+ return Content("Settings Saved.");
+
+ return Content("Settings Saved.");
+ Logger.Error("");
+ }
+
+
+ if (Request.IsAjaxRequest())
+ return Content("Settings Saved.");
+
+ return Content("Settings Saved.");
}
+ [HttpPost]
+ public ActionResult SaveGeneral(SettingsModel data)
+ {
+ try
+ {
+ _configProvider.SeriesRoot = data.TvFolder;
+ }
+ catch (Exception e)
+ {
+ Logger.ErrorException(e.Message, e);
+ if (Request.IsAjaxRequest())
+ return Content("Error Saving Settings, please fix any errors");
+
+ return Content("Error Saving Settings, please fix any errors");
+ }
+
+ if (Request.IsAjaxRequest())
+ return Content("Settings Saved.");
+
+ return Content("Settings Saved.");
+ }
+
+ [HttpPost]
+ public ActionResult SaveIndexers(SettingsModel data)
+ {
+ try
+ {
+ foreach (var indexer in data.Indexers)
+ {
+ _indexerProvider.Update(indexer);
+ }
+
+ _configProvider.SetValue("NzbMatrixUsername", data.NzbMatrixUsername);
+ _configProvider.SetValue("NzbMatrixApiKey", data.NzbMatrixApiKey);
+ _configProvider.SetValue("NzbsOrgUId", data.NzbsOrgUId);
+ _configProvider.SetValue("NzbsOrgHash", data.NzbsOrgHash);
+ _configProvider.SetValue("NzbsrusUId", data.NzbsrusUId);
+ _configProvider.SetValue("NzbsrusHash", data.NzbsrusHash);
+ }
+ catch (Exception e)
+ {
+ Logger.ErrorException(e.Message, e);
+ if (Request.IsAjaxRequest())
+ return Content("Error Saving Settings, please fix any errors");
+
+ return Content("Error Saving Settings, please fix any errors");
+ }
+
+ if (Request.IsAjaxRequest())
+ return Content("Settings Saved.");
+
+ return Content("Settings Saved.");
+ }
+
+ [HttpPost]
+ public ActionResult SaveDownloads(SettingsModel data)
+ {
+ try
+ {
+ if (data.SyncFrequency > 15)
+ _configProvider.SetValue("SyncFrequency", data.SyncFrequency.ToString());
+
+ _configProvider.SetValue("DownloadPropers", data.DownloadPropers.ToString());
+
+ if (data.Rentention > 0)
+ _configProvider.SetValue("Retention", data.Rentention.ToString());
+
+ if (data.SabHost != null)
+ _configProvider.SetValue("SabHost", data.SabHost);
+
+ if (data.SabPort > 0)
+ _configProvider.SetValue("SabPort", data.SabPort.ToString());
+
+ if (data.SabApiKey != null)
+ _configProvider.SetValue("SabApiKey", data.SabApiKey);
+
+ if (data.SabUsername != null)
+ _configProvider.SetValue("SabUsername", data.SabUsername);
+
+ if (data.SabPassword != null)
+ _configProvider.SetValue("SabPassword", data.SabPassword);
+
+ if (data.SabCategory != null)
+ _configProvider.SetValue("SabCategory", data.SabCategory);
+
+ //if (data.SabPriority != null)
+ // _configProvider.SetValue("SabPriority", data.SabPriority.ToString());
+ }
+ catch (Exception e)
+ {
+ Logger.ErrorException(e.Message, e);
+ if (Request.IsAjaxRequest())
+ return Content("Error Saving Settings, please fix any errors");
+
+ return Content("Error Saving Settings, please fix any errors");
+ }
+
+ if (Request.IsAjaxRequest())
+ return Content("Settings Saved.");
+
+ return Content("Settings Saved.");
+ }
+
+ [HttpPost]
+ public ActionResult SortedList(List