fixes #715 - Support creating/editing collections (boxsets) in web client #715

pull/702/head
Luke Pulverenti 10 years ago
parent e00985d07c
commit 546acf0ebb

@ -134,7 +134,7 @@ namespace MediaBrowser.Api
IncludeStudios = request.IncludeStudios,
StartIndex = request.StartIndex,
UserId = request.UserId,
IncludeItemTypes = (request.IncludeItemTypes ?? string.Empty).Split(',')
IncludeItemTypes = (request.IncludeItemTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray()
}).ConfigureAwait(false);

@ -745,9 +745,9 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
AddChildrenToList(user, includeLinkedChildren, list, false, null);
var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false, null);
return list;
return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list;
}
/// <summary>

@ -22,8 +22,8 @@ namespace MediaBrowser.Controller.Entities
public enum LinkedChildType
{
Manual = 1,
Shortcut = 2
Manual = 0,
Shortcut = 1
}
public class LinkedChildComparer : IEqualityComparer<LinkedChild>
@ -39,7 +39,7 @@ namespace MediaBrowser.Controller.Entities
public int GetHashCode(LinkedChild obj)
{
return (obj.Path + obj.Type.ToString()).GetHashCode();
return (obj.Path + obj.Type).GetHashCode();
}
}
}

@ -51,9 +51,8 @@ namespace MediaBrowser.Controller.Library
/// Refreshes metadata for each user
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="force">if set to <c>true</c> [force].</param>
/// <returns>Task.</returns>
Task RefreshUsersMetadata(CancellationToken cancellationToken, bool force = false);
Task RefreshUsersMetadata(CancellationToken cancellationToken);
/// <summary>
/// Renames the user.

@ -1,5 +1,6 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
@ -37,6 +38,15 @@ namespace MediaBrowser.Providers.BoxSets
protected override void MergeData(BoxSet source, BoxSet target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
if (mergeMetadataSettings)
{
var list = source.LinkedChildren.ToList();
list.AddRange(target.LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut));
target.LinkedChildren = list;
}
}
protected override ItemUpdateType BeforeSave(BoxSet item)

@ -0,0 +1,129 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System.Collections.Generic;
using System.Globalization;
using System.Xml;
namespace MediaBrowser.Providers.BoxSets
{
public class BoxSetXmlParser : BaseItemXmlParser<BoxSet>
{
private readonly CultureInfo UsCulture = new CultureInfo("en-US");
public BoxSetXmlParser(ILogger logger)
: base(logger)
{
}
protected override void FetchDataFromXmlNode(XmlReader reader, BoxSet item)
{
switch (reader.Name)
{
case "CollectionItems":
using (var subReader = reader.ReadSubtree())
{
FetchFromCollectionItemsNode(subReader, item);
}
break;
default:
base.FetchDataFromXmlNode(reader, item);
break;
}
}
private void FetchFromCollectionItemsNode(XmlReader reader, BoxSet item)
{
reader.MoveToContent();
var list = new List<LinkedChild>();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "CollectionItem":
{
using (var subReader = reader.ReadSubtree())
{
var child = GetLinkedChild(subReader);
if (child != null)
{
list.Add(child);
}
}
break;
}
default:
reader.Skip();
break;
}
}
}
item.LinkedChildren = list;
}
private LinkedChild GetLinkedChild(XmlReader reader)
{
reader.MoveToContent();
var linkedItem = new LinkedChild
{
Type = LinkedChildType.Manual
};
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "Name":
{
linkedItem.ItemName = reader.ReadElementContentAsString();
break;
}
case "Type":
{
linkedItem.ItemType = reader.ReadElementContentAsString();
break;
}
case "Year":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
linkedItem.ItemYear = rval;
}
}
break;
}
default:
reader.Skip();
break;
}
}
}
return string.IsNullOrWhiteSpace(linkedItem.ItemName) || string.IsNullOrWhiteSpace(linkedItem.ItemType) ? null : linkedItem;
}
}
}

@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.BoxSets
protected override void Fetch(LocalMetadataResult<BoxSet> result, string path, CancellationToken cancellationToken)
{
new BaseItemXmlParser<BoxSet>(_logger).Fetch(result.Item, path, cancellationToken);
new BoxSetXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
}
protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)

@ -75,6 +75,7 @@
<Compile Include="All\LocalImageProvider.cs" />
<Compile Include="Books\BookMetadataService.cs" />
<Compile Include="BoxSets\BoxSetMetadataService.cs" />
<Compile Include="BoxSets\BoxSetXmlParser.cs" />
<Compile Include="BoxSets\MovieDbBoxSetImageProvider.cs" />
<Compile Include="BoxSets\MovieDbBoxSetProvider.cs" />
<Compile Include="Folders\CollectionFolderImageProvider.cs" />

@ -148,9 +148,39 @@ namespace MediaBrowser.Server.Implementations.Collections
list.Add(child);
}
foreach (var child in list)
var shortcutFiles = Directory
.EnumerateFiles(collection.Path, "*", SearchOption.TopDirectoryOnly)
.Where(i => _fileSystem.IsShortcut(i))
.ToList();
var shortcutFilesToDelete = list.Where(child => !string.IsNullOrWhiteSpace(child.Path) && child.Type == LinkedChildType.Shortcut)
.Select(child => shortcutFiles.FirstOrDefault(i => string.Equals(child.Path, _fileSystem.ResolveShortcut(i), StringComparison.OrdinalIgnoreCase)))
.Where(i => !string.IsNullOrWhiteSpace(i))
.ToList();
foreach (var file in shortcutFilesToDelete)
{
_iLibraryMonitor.ReportFileSystemChangeBeginning(file);
}
try
{
collection.LinkedChildren.Remove(child);
foreach (var file in shortcutFilesToDelete)
{
File.Delete(file);
}
foreach (var child in list)
{
collection.LinkedChildren.Remove(child);
}
}
finally
{
foreach (var file in shortcutFilesToDelete)
{
_iLibraryMonitor.ReportFileSystemChangeComplete(file, false);
}
}
await collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);

@ -189,15 +189,10 @@ namespace MediaBrowser.Server.Implementations.Library
/// Refreshes metadata for each user
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="force">if set to <c>true</c> [force].</param>
/// <returns>Task.</returns>
public Task RefreshUsersMetadata(CancellationToken cancellationToken, bool force = false)
public Task RefreshUsersMetadata(CancellationToken cancellationToken)
{
var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions
{
ReplaceAllMetadata = force
}, cancellationToken)).ToList();
var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions(), cancellationToken)).ToList();
return Task.WhenAll(tasks);
}

@ -582,8 +582,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
.Select(i => _libraryManager.GetGenre(i))
.ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
programs = programList.OrderByDescending(i => GetRecommendationScore(i, user.Id, serviceName, genres))
.ThenBy(i => i.HasImage(ImageType.Primary) ? 0 : 1)
programs = programList.OrderBy(i => i.HasImage(ImageType.Primary) ? 0 : 1)
.ThenByDescending(i => GetRecommendationScore(i, user.Id, serviceName, genres))
.ThenBy(i => i.StartDate);
if (query.Limit.HasValue)

Loading…
Cancel
Save