diff --git a/MediaBrowser.Api/ApiService.cs b/MediaBrowser.Api/ApiService.cs
index 3a717b7541..76a93d4bbc 100644
--- a/MediaBrowser.Api/ApiService.cs
+++ b/MediaBrowser.Api/ApiService.cs
@@ -97,7 +97,7 @@ namespace MediaBrowser.Api
dto.SpecialCounts = folder.GetSpecialCounts(user);
dto.IsRoot = folder.IsRoot;
- dto.IsVirtualFolder = folder.IsVirtualFolder;
+ dto.IsVirtualFolder = folder is VirtualFolder;
}
return dto;
diff --git a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs b/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs
index 7c4af71ebc..2fe557dbeb 100644
--- a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs
+++ b/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs
@@ -97,5 +97,32 @@ namespace MediaBrowser.Controller.Events
}
}
+ public VirtualFolder VirtualFolder
+ {
+ get
+ {
+ if (Parent != null)
+ {
+ return Parent.VirtualFolder;
+ }
+
+ return null;
+ }
+ }
+
+ public string VirtualFolderCollectionType
+ {
+ get
+ {
+ VirtualFolder vf = VirtualFolder;
+
+ if (vf == null)
+ {
+ return null;
+ }
+
+ return vf.CollectionType;
+ }
+ }
}
}
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs
index 22ccfecc17..2058f6d611 100644
--- a/MediaBrowser.Controller/Kernel.cs
+++ b/MediaBrowser.Controller/Kernel.cs
@@ -77,6 +77,7 @@ namespace MediaBrowser.Controller
// Add the internal resolvers
resolvers.Add(new VideoResolver());
resolvers.Add(new AudioResolver());
+ resolvers.Add(new VirtualFolderResolver());
resolvers.Add(new FolderResolver());
EntityResolvers = resolvers;
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index ea5944126a..5c60529710 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -60,6 +60,7 @@
+
diff --git a/MediaBrowser.Controller/Resolvers/FolderResolver.cs b/MediaBrowser.Controller/Resolvers/FolderResolver.cs
index bd91ec2bac..09d3cebe49 100644
--- a/MediaBrowser.Controller/Resolvers/FolderResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/FolderResolver.cs
@@ -19,10 +19,10 @@ namespace MediaBrowser.Controller.Resolvers
}
}
- public abstract class BaseFolderResolver : BaseItemResolver
- where T : Folder, new ()
+ public abstract class BaseFolderResolver : BaseItemResolver
+ where TItemType : Folder, new()
{
- protected override void SetItemValues(T item, ItemResolveEventArgs args)
+ protected override void SetItemValues(TItemType item, ItemResolveEventArgs args)
{
base.SetItemValues(item, args);
@@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Resolvers
PopulateFolderMetadata(item, args);
}
- private void PopulateFolderMetadata(Folder folder, ItemResolveEventArgs args)
+ private void PopulateFolderMetadata(TItemType folder, ItemResolveEventArgs args)
{
var metadataFile = args.GetFileByName("folder.xml");
diff --git a/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs b/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs
new file mode 100644
index 0000000000..51478fd02e
--- /dev/null
+++ b/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs
@@ -0,0 +1,41 @@
+using System.ComponentModel.Composition;
+using System.IO;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Controller.Resolvers
+{
+ [Export(typeof(IBaseItemResolver))]
+ public class VirtualFolderResolver : BaseFolderResolver
+ {
+ protected override VirtualFolder Resolve(ItemResolveEventArgs args)
+ {
+ if (args.IsFolder && args.Parent != null && args.Parent.IsRoot)
+ {
+ return new VirtualFolder();
+ }
+
+ return null;
+ }
+
+ protected override void SetItemValues(VirtualFolder item, ItemResolveEventArgs args)
+ {
+ // Set the name initially by stripping off the [CollectionType=...]
+ // The name can always be overridden later by folder.xml
+ string pathName = Path.GetFileNameWithoutExtension(args.Path);
+
+ string srch = "[collectiontype=";
+ int index = pathName.IndexOf(srch, System.StringComparison.OrdinalIgnoreCase);
+
+ if (index != -1)
+ {
+ item.Name = pathName.Substring(0, index).Trim();
+
+ item.CollectionType = pathName.Substring(index + srch.Length).TrimEnd(']');
+ }
+
+ base.SetItemValues(item, args);
+ }
+
+ }
+}
diff --git a/MediaBrowser.Controller/Xml/FolderXmlParser.cs b/MediaBrowser.Controller/Xml/FolderXmlParser.cs
index 94ff97f62a..5ce3a10e5a 100644
--- a/MediaBrowser.Controller/Xml/FolderXmlParser.cs
+++ b/MediaBrowser.Controller/Xml/FolderXmlParser.cs
@@ -3,7 +3,7 @@
namespace MediaBrowser.Controller.Xml
{
///
- /// Fetches metadata fro a folder.
+ /// Fetches metadata for a folder.
/// Since folder.xml contains no folder-specific values, no overrides are needed
///
public class FolderXmlParser : BaseItemXmlParser
diff --git a/MediaBrowser.Model/Entities/BaseItem.cs b/MediaBrowser.Model/Entities/BaseItem.cs
index 506c051c52..7d3663fb23 100644
--- a/MediaBrowser.Model/Entities/BaseItem.cs
+++ b/MediaBrowser.Model/Entities/BaseItem.cs
@@ -6,6 +6,29 @@ namespace MediaBrowser.Model.Entities
{
public abstract class BaseItem : BaseEntity, IHasProviderIds
{
+ ///
+ /// Goes up the tree to find the virtual folder parent
+ ///
+ public VirtualFolder VirtualFolder
+ {
+ get
+ {
+ var vf = this as VirtualFolder;
+
+ if (vf != null)
+ {
+ return vf;
+ }
+
+ if (Parent != null)
+ {
+ return Parent.VirtualFolder;
+ }
+
+ return null;
+ }
+ }
+
public string SortName { get; set; }
///
diff --git a/MediaBrowser.Model/Entities/Folder.cs b/MediaBrowser.Model/Entities/Folder.cs
index 105151f315..50ce9d45ef 100644
--- a/MediaBrowser.Model/Entities/Folder.cs
+++ b/MediaBrowser.Model/Entities/Folder.cs
@@ -8,14 +8,6 @@ namespace MediaBrowser.Model.Entities
{
public bool IsRoot { get; set; }
- public bool IsVirtualFolder
- {
- get
- {
- return Parent != null && Parent.IsRoot;
- }
- }
-
public BaseItem[] Children { get; set; }
///
diff --git a/MediaBrowser.Model/Entities/IHasProviderIds.cs b/MediaBrowser.Model/Entities/IHasProviderIds.cs
index 3406d618bd..8b9852dda3 100644
--- a/MediaBrowser.Model/Entities/IHasProviderIds.cs
+++ b/MediaBrowser.Model/Entities/IHasProviderIds.cs
@@ -3,7 +3,7 @@
namespace MediaBrowser.Model.Entities
{
///
- /// Since BaseItem and DTOBaseItem both have ProviderIds, this interface helps avoid code repition using extension methods
+ /// Since BaseItem and DTOBaseItem both have ProviderIds, this interface helps avoid code repition by using extension methods
///
public interface IHasProviderIds
{
diff --git a/MediaBrowser.Model/Entities/ItemSpecialCounts.cs b/MediaBrowser.Model/Entities/ItemSpecialCounts.cs
index 9add9fe99e..8dd9a2fbd9 100644
--- a/MediaBrowser.Model/Entities/ItemSpecialCounts.cs
+++ b/MediaBrowser.Model/Entities/ItemSpecialCounts.cs
@@ -2,7 +2,7 @@
namespace MediaBrowser.Model.Entities
{
///
- /// Since it can be slow to collect this data. This class helps provide a way to calculate them all at once.
+ /// Since it can be slow to collect this data, this class helps provide a way to calculate them all at once.
///
public class ItemSpecialCounts
{
diff --git a/MediaBrowser.Model/Entities/VirtualFolder.cs b/MediaBrowser.Model/Entities/VirtualFolder.cs
new file mode 100644
index 0000000000..f25db3e41b
--- /dev/null
+++ b/MediaBrowser.Model/Entities/VirtualFolder.cs
@@ -0,0 +1,8 @@
+
+namespace MediaBrowser.Model.Entities
+{
+ public class VirtualFolder : Folder
+ {
+ public string CollectionType { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 77f4403d87..60defff43b 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -46,6 +46,7 @@
+
diff --git a/MediaBrowser.Movies/Resolvers/BoxSetResolver.cs b/MediaBrowser.Movies/Resolvers/BoxSetResolver.cs
index 0689fe0410..8120c979c6 100644
--- a/MediaBrowser.Movies/Resolvers/BoxSetResolver.cs
+++ b/MediaBrowser.Movies/Resolvers/BoxSetResolver.cs
@@ -12,7 +12,7 @@ namespace MediaBrowser.Movies.Resolvers
{
protected override BoxSet Resolve(ItemResolveEventArgs args)
{
- if (args.IsFolder)
+ if (args.IsFolder && (args.VirtualFolderCollectionType ?? string.Empty).Equals("Movies", StringComparison.OrdinalIgnoreCase))
{
if (Path.GetFileName(args.Path).IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1)
{
diff --git a/MediaBrowser.Movies/Resolvers/MovieResolver.cs b/MediaBrowser.Movies/Resolvers/MovieResolver.cs
index 7868652d9e..fae0bdc514 100644
--- a/MediaBrowser.Movies/Resolvers/MovieResolver.cs
+++ b/MediaBrowser.Movies/Resolvers/MovieResolver.cs
@@ -17,7 +17,7 @@ namespace MediaBrowser.Movies.Resolvers
{
protected override Movie Resolve(ItemResolveEventArgs args)
{
- if (args.IsFolder)
+ if (args.IsFolder && (args.VirtualFolderCollectionType ?? string.Empty).Equals("Movies", StringComparison.OrdinalIgnoreCase))
{
// Optimization to avoid running these tests against VF's
if (args.Parent != null && args.Parent.IsRoot)
diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs
index cbcf5186e3..3cc29e7dff 100644
--- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs
+++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Windows;
+using MediaBrowser.Common.Logging;
using MediaBrowser.Controller;
using MediaBrowser.Model.Progress;
@@ -26,11 +27,18 @@ namespace MediaBrowser.ServerApplication
try
{
+ DateTime now = DateTime.Now;
+
new Kernel().Init(progress);
+
+ double seconds = (DateTime.Now - now).TotalSeconds;
+
+ Logger.LogInfo("Kernel.Init completed in {0} seconds.", seconds);
}
catch (Exception ex)
{
MessageBox.Show("There was an error launching Media Browser Server: " + ex.Message);
+ Close();
}
finally
{
diff --git a/MediaBrowser.TV/Resolvers/SeasonResolver.cs b/MediaBrowser.TV/Resolvers/SeasonResolver.cs
index 85c880a3ae..98ebfa2267 100644
--- a/MediaBrowser.TV/Resolvers/SeasonResolver.cs
+++ b/MediaBrowser.TV/Resolvers/SeasonResolver.cs
@@ -3,6 +3,7 @@ using System.IO;
using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.TV.Entities;
+using MediaBrowser.TV.Metadata;
namespace MediaBrowser.TV.Resolvers
{
diff --git a/MediaBrowser.TV/Resolvers/SeriesResolver.cs b/MediaBrowser.TV/Resolvers/SeriesResolver.cs
index 0b63a325c5..3b65796d9e 100644
--- a/MediaBrowser.TV/Resolvers/SeriesResolver.cs
+++ b/MediaBrowser.TV/Resolvers/SeriesResolver.cs
@@ -13,7 +13,7 @@ namespace MediaBrowser.TV.Resolvers
{
protected override Series Resolve(ItemResolveEventArgs args)
{
- if (args.IsFolder)
+ if (args.IsFolder && (args.VirtualFolderCollectionType ?? string.Empty).Equals("TV", StringComparison.OrdinalIgnoreCase))
{
// Optimization to avoid running these tests against VF's
if (args.Parent != null && args.Parent.IsRoot)
@@ -42,6 +42,12 @@ namespace MediaBrowser.TV.Resolvers
{
base.SetItemValues(item, args);
+ // Read data from series.xml, if it exists
+ PopulateFolderMetadata(item, args);
+ }
+
+ private void PopulateFolderMetadata(Series item, ItemResolveEventArgs args)
+ {
var metadataFile = args.GetFileByName("series.xml");
if (metadataFile.HasValue)