Browse Source

support plot keywords

Luke Pulverenti 11 years ago
parent
commit
ce13ff95ad

+ 6 - 0
MediaBrowser.Api/ItemUpdateService.cs

@@ -288,6 +288,12 @@ namespace MediaBrowser.Api
                 hasTags.Tags = request.Tags;
             }
 
+            var hasKeywords = item as IHasKeywords;
+            if (hasKeywords != null)
+            {
+                hasKeywords.Keywords = request.Keywords;
+            }
+
             if (request.Studios != null)
             {
                 item.Studios = request.Studios.Select(x => x.Name).ToList();

+ 14 - 0
MediaBrowser.Api/SimilarItemsHelper.cs

@@ -130,6 +130,17 @@ namespace MediaBrowser.Api
             return new List<string>();
         }
 
+        private static IEnumerable<string> GetKeywords(BaseItem item)
+        {
+            var hasTags = item as IHasKeywords;
+            if (hasTags != null)
+            {
+                return hasTags.Keywords;
+            }
+
+            return new List<string>();
+        }
+
         /// <summary>
         /// Gets the similiarity score.
         /// </summary>
@@ -151,6 +162,9 @@ namespace MediaBrowser.Api
             // Find common tags
             points += GetTags(item1).Where(i => GetTags(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10);
 
+            // Find common keywords
+            points += GetKeywords(item1).Where(i => GetKeywords(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10);
+            
             // Find common studios
             points += item1.Studios.Where(i => item2.Studios.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 3);
 

+ 31 - 0
MediaBrowser.Controller/Entities/IHasKeywords.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Controller.Entities
+{
+    public interface IHasKeywords
+    {
+        /// <summary>
+        /// Gets or sets the keywords.
+        /// </summary>
+        /// <value>The keywords.</value>
+        List<string> Keywords { get; set; }
+    }
+
+    public static class KeywordExtensions
+    {
+        public static void AddKeyword(this IHasKeywords item, string name)
+        {
+            if (string.IsNullOrWhiteSpace(name))
+            {
+                throw new ArgumentNullException("name");
+            }
+
+            if (!item.Keywords.Contains(name, StringComparer.OrdinalIgnoreCase))
+            {
+                item.Keywords.Add(name);
+            }
+        }
+    }
+}

+ 3 - 1
MediaBrowser.Controller/Entities/Movies/BoxSet.cs

@@ -9,7 +9,7 @@ namespace MediaBrowser.Controller.Entities.Movies
     /// <summary>
     /// Class BoxSet
     /// </summary>
-    public class BoxSet : Folder, IHasTrailers, IHasTags, IHasPreferredMetadataLanguage, IHasDisplayOrder
+    public class BoxSet : Folder, IHasTrailers, IHasTags, IHasKeywords, IHasPreferredMetadataLanguage, IHasDisplayOrder
     {
         public BoxSet()
         {
@@ -18,6 +18,7 @@ namespace MediaBrowser.Controller.Entities.Movies
             Tags = new List<string>();
 
             DisplayOrder = ItemSortBy.PremiereDate;
+            Keywords = new List<string>();
         }
 
         public List<Guid> LocalTrailerIds { get; set; }
@@ -33,6 +34,7 @@ namespace MediaBrowser.Controller.Entities.Movies
         /// </summary>
         /// <value>The tags.</value>
         public List<string> Tags { get; set; }
+        public List<string> Keywords { get; set; }
 
         public string PreferredMetadataLanguage { get; set; }
 

+ 4 - 2
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.Entities.Movies
     /// <summary>
     /// Class Movie
     /// </summary>
-    public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasTags, IHasPreferredMetadataLanguage
+    public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasTags, IHasPreferredMetadataLanguage
     {
         public List<Guid> SpecialFeatureIds { get; set; }
 
@@ -39,10 +39,12 @@ namespace MediaBrowser.Controller.Entities.Movies
             ThemeVideoIds = new List<Guid>();
             Taglines = new List<string>();
             Tags = new List<string>();
+            Keywords = new List<string>();
         }
 
         public List<Guid> LocalTrailerIds { get; set; }
-        
+        public List<string> Keywords { get; set; }
+    
         public List<MediaUrl> RemoteTrailers { get; set; }
 
         /// <summary>

+ 4 - 1
MediaBrowser.Controller/Entities/Trailer.cs

@@ -9,7 +9,7 @@ namespace MediaBrowser.Controller.Entities
     /// <summary>
     /// Class Trailer
     /// </summary>
-    public class Trailer : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasTrailers, IHasTaglines, IHasTags, IHasPreferredMetadataLanguage
+    public class Trailer : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasTrailers, IHasKeywords, IHasTaglines, IHasTags, IHasPreferredMetadataLanguage
     {
         public List<Guid> SoundtrackIds { get; set; }
 
@@ -28,12 +28,15 @@ namespace MediaBrowser.Controller.Entities
             SoundtrackIds = new List<Guid>();
             LocalTrailerIds = new List<Guid>();
             Tags = new List<string>();
+            Keywords = new List<string>();
         }
 
         public List<Guid> LocalTrailerIds { get; set; }
         
         public List<MediaUrl> RemoteTrailers { get; set; }
 
+        public List<string> Keywords { get; set; }
+        
         /// <summary>
         /// Gets or sets the tags.
         /// </summary>

+ 11 - 1
MediaBrowser.Controller/Library/ItemResolveArgs.cs

@@ -35,7 +35,17 @@ namespace MediaBrowser.Controller.Library
         /// <value>The file system children.</value>
         public IEnumerable<FileSystemInfo> FileSystemChildren
         {
-            get { return FileSystemDictionary.Values; }
+            get
+            {
+                var dict = FileSystemDictionary;
+
+                if (dict == null)
+                {
+                    return new List<FileSystemInfo>();
+                }
+
+                return dict.Values;
+            }
         }
 
         /// <summary>

+ 1 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -87,6 +87,7 @@
     <Compile Include="Entities\IHasCriticRating.cs" />
     <Compile Include="Entities\IHasDisplayOrder.cs" />
     <Compile Include="Entities\IHasImages.cs" />
+    <Compile Include="Entities\IHasKeywords.cs" />
     <Compile Include="Entities\IHasMediaStreams.cs" />
     <Compile Include="Entities\IHasPreferredMetadataLanguage.cs" />
     <Compile Include="Entities\IHasProductionLocations.cs" />

+ 47 - 0
MediaBrowser.Controller/Providers/BaseItemXmlParser.cs

@@ -79,6 +79,11 @@ namespace MediaBrowser.Controller.Providers
                 hasTags.Tags.Clear();
             }
 
+            var hasKeywords = item as IHasKeywords;
+            if (hasKeywords != null)
+            {
+                hasKeywords.Keywords.Clear();
+            }
 
             var hasTrailers = item as IHasTrailers;
             if (hasTrailers != null)
@@ -747,6 +752,19 @@ namespace MediaBrowser.Controller.Providers
                         break;
                     }
 
+                case "PlotKeywords":
+                    {
+                        using (var subtree = reader.ReadSubtree())
+                        {
+                            var hasTags = item as IHasKeywords;
+                            if (hasTags != null)
+                            {
+                                FetchFromKeywordsNode(subtree, hasTags);
+                            }
+                        }
+                        break;
+                    }
+
                 case "Persons":
                     {
                         using (var subtree = reader.ReadSubtree())
@@ -912,6 +930,35 @@ namespace MediaBrowser.Controller.Providers
             }
         }
 
+        private void FetchFromKeywordsNode(XmlReader reader, IHasKeywords item)
+        {
+            reader.MoveToContent();
+
+            while (reader.Read())
+            {
+                if (reader.NodeType == XmlNodeType.Element)
+                {
+                    switch (reader.Name)
+                    {
+                        case "PlotKeyword":
+                            {
+                                var tag = reader.ReadElementContentAsString();
+
+                                if (!string.IsNullOrWhiteSpace(tag))
+                                {
+                                    item.AddKeyword(tag);
+                                }
+                                break;
+                            }
+
+                        default:
+                            reader.Skip();
+                            break;
+                    }
+                }
+            }
+        }
+
         /// <summary>
         /// Fetches the data from persons node.
         /// </summary>

+ 6 - 0
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -370,6 +370,12 @@ namespace MediaBrowser.Model.Dto
         /// <value>The tags.</value>
         public List<string> Tags { get; set; }
 
+        /// <summary>
+        /// Gets or sets the keywords.
+        /// </summary>
+        /// <value>The keywords.</value>
+        public List<string> Keywords { get; set; }
+        
         /// <summary>
         /// Gets or sets the primary image aspect ratio, after image enhancements.
         /// </summary>

+ 5 - 0
MediaBrowser.Model/Querying/ItemFields.cs

@@ -56,6 +56,11 @@ namespace MediaBrowser.Model.Querying
         /// </summary>
         IndexOptions,
 
+        /// <summary>
+        /// The keywords
+        /// </summary>
+        Keywords,
+
         /// <summary>
         /// The metadata settings
         /// </summary>

+ 8 - 8
MediaBrowser.Providers/Movies/MovieDbProvider.cs

@@ -847,14 +847,14 @@ namespace MediaBrowser.Providers.Movies
                 }
             }
 
-            //if (movieData.keywords != null && movieData.keywords.keywords != null && !movie.LockedFields.Contains(MetadataFields.Tags))
-            //{
-            //    var hasTags = movie as IHasTags;
-            //    if (hasTags != null)
-            //    {
-            //        hasTags.Tags = movieData.keywords.keywords.Select(i => i.name).ToList();
-            //    }
-            //}
+            if (movieData.keywords != null && movieData.keywords.keywords != null && !movie.LockedFields.Contains(MetadataFields.Tags))
+            {
+                var hasTags = movie as IHasKeywords;
+                if (hasTags != null)
+                {
+                    hasTags.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList();
+                }
+            }
 
             if (movieData.trailers != null && movieData.trailers.youtube != null &&
                 movieData.trailers.youtube.Count > 0)

+ 16 - 0
MediaBrowser.Providers/Savers/XmlSaverHelpers.cs

@@ -484,6 +484,22 @@ namespace MediaBrowser.Providers.Savers
                 }
             }
 
+            var hasKeywords = item as IHasKeywords;
+            if (hasKeywords != null)
+            {
+                if (hasKeywords.Keywords.Count > 0)
+                {
+                    builder.Append("<PlotKeywords>");
+
+                    foreach (var tag in hasKeywords.Keywords)
+                    {
+                        builder.Append("<PlotKeyword>" + SecurityElement.Escape(tag) + "</PlotKeyword>");
+                    }
+
+                    builder.Append("</PlotKeywords>");
+                }
+            }
+
             if (item.People.Count > 0)
             {
                 builder.Append("<Persons>");

+ 14 - 0
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -698,6 +698,20 @@ namespace MediaBrowser.Server.Implementations.Dto
                 }
             }
 
+            if (fields.Contains(ItemFields.Keywords))
+            {
+                var hasTags = item as  IHasKeywords;
+                if (hasTags != null)
+                {
+                    dto.Keywords = hasTags.Keywords;
+                }
+
+                if (dto.Keywords == null)
+                {
+                    dto.Keywords = new List<string>();
+                }
+            }
+
             if (fields.Contains(ItemFields.ProductionLocations))
             {
                 SetProductionLocations(item, dto);

+ 1 - 0
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -567,6 +567,7 @@ namespace MediaBrowser.WebDashboard.Api
             await AppendResource(memoryStream, "thirdparty/jquerymobile-1.4.0/jquery.mobile-1.4.0.min.js", newLineBytes).ConfigureAwait(false);
 
             //await AppendResource(memoryStream, "thirdparty/jquery.infinite-scroll-helper.min.js", newLineBytes).ConfigureAwait(false);
+            await AppendResource(memoryStream, "thirdparty/jquery.hoverIntent.minified.js", newLineBytes).ConfigureAwait(false);
 
             var versionString = string.Format("window.dashboardVersion='{0}';", _appHost.ApplicationVersion);
             var versionBytes = Encoding.UTF8.GetBytes(versionString);

+ 3 - 0
MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

@@ -496,6 +496,9 @@
     <Content Include="dashboard-ui\thirdparty\jquery-2.0.3.min.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="dashboard-ui\thirdparty\jquery.hoverIntent.minified.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="dashboard-ui\thirdparty\jquery.infinite-scroll-helper.min.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>