use music brainz values from audio files with bottom up refresh

This commit is contained in:
Luke Pulverenti 2014-02-07 17:40:03 -05:00
parent 76658f0797
commit 12757d094b
37 changed files with 544 additions and 132 deletions

View File

@ -789,12 +789,7 @@ namespace MediaBrowser.Api.Images
await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false); await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
await entity.RefreshMetadata(new MetadataRefreshOptions await entity.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
{
ImageRefreshMode = ImageRefreshMode.ValidationOnly,
ForceSave = true
}, CancellationToken.None).ConfigureAwait(false);
} }
} }
} }

View File

@ -281,13 +281,7 @@ namespace MediaBrowser.Api.Images
{ {
await _providerManager.SaveImage(item, request.ImageUrl, null, request.Type, null, CancellationToken.None).ConfigureAwait(false); await _providerManager.SaveImage(item, request.ImageUrl, null, request.Type, null, CancellationToken.None).ConfigureAwait(false);
await item.RefreshMetadata(new MetadataRefreshOptions await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
{
ForceSave = true,
ImageRefreshMode = ImageRefreshMode.ValidationOnly,
MetadataRefreshMode = MetadataRefreshMode.None
}, CancellationToken.None).ConfigureAwait(false);
} }
/// <summary> /// <summary>

View File

@ -22,6 +22,15 @@ namespace MediaBrowser.Controller.Entities.Audio
Tags = new List<string>(); Tags = new List<string>();
} }
[IgnoreDataMember]
public MusicArtist MusicArtist
{
get
{
return Parents.OfType<MusicArtist>().FirstOrDefault();
}
}
/// <summary> /// <summary>
/// Gets or sets the tags. /// Gets or sets the tags.
/// </summary> /// </summary>
@ -99,7 +108,7 @@ namespace MediaBrowser.Controller.Entities.Audio
return "MusicAlbum-MusicBrainzReleaseGroup-" + id; return "MusicAlbum-MusicBrainzReleaseGroup-" + id;
} }
id = this.GetProviderId(MetadataProviders.Musicbrainz); id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
if (!string.IsNullOrEmpty(id)) if (!string.IsNullOrEmpty(id))
{ {

View File

@ -89,6 +89,31 @@ namespace MediaBrowser.Controller.Entities.Audio
return GetUserDataKey(this); return GetUserDataKey(this);
} }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
/// <summary> /// <summary>
/// Gets the user data key. /// Gets the user data key.
/// </summary> /// </summary>
@ -96,7 +121,7 @@ namespace MediaBrowser.Controller.Entities.Audio
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
private static string GetUserDataKey(MusicArtist item) private static string GetUserDataKey(MusicArtist item)
{ {
var id = item.GetProviderId(MetadataProviders.Musicbrainz); var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!string.IsNullOrEmpty(id)) if (!string.IsNullOrEmpty(id))
{ {

View File

@ -26,5 +26,30 @@ namespace MediaBrowser.Controller.Entities.Audio
[IgnoreDataMember] [IgnoreDataMember]
public List<ItemByNameCounts> UserItemCountList { get; set; } public List<ItemByNameCounts> UserItemCountList { get; set; }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
} }
} }

View File

@ -124,7 +124,7 @@ namespace MediaBrowser.Controller.Entities
} }
[IgnoreDataMember] [IgnoreDataMember]
public bool IsOwnedItem public virtual bool IsOwnedItem
{ {
get get
{ {
@ -1215,7 +1215,12 @@ namespace MediaBrowser.Controller.Entities
currentFile.Delete(); currentFile.Delete();
} }
return LibraryManager.UpdateItem(this, ItemUpdateType.ImageUpdate, CancellationToken.None); return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
}
public virtual Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
{
return LibraryManager.UpdateItem(this, ItemUpdateType.ImageUpdate, cancellationToken);
} }
/// <summary> /// <summary>
@ -1370,7 +1375,7 @@ namespace MediaBrowser.Controller.Entities
info1.DateModified = FileSystem.GetLastWriteTimeUtc(info1.Path); info1.DateModified = FileSystem.GetLastWriteTimeUtc(info1.Path);
info2.DateModified = FileSystem.GetLastWriteTimeUtc(info2.Path); info2.DateModified = FileSystem.GetLastWriteTimeUtc(info2.Path);
return LibraryManager.UpdateItem(this, ItemUpdateType.ImageUpdate, CancellationToken.None); return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
} }
public virtual bool IsPlayed(User user) public virtual bool IsPlayed(User user)

View File

@ -1,5 +1,4 @@
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization; using System.Runtime.Serialization;
@ -23,5 +22,30 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public List<ItemByNameCounts> UserItemCountList { get; set; } public List<ItemByNameCounts> UserItemCountList { get; set; }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
} }
} }

View File

@ -25,5 +25,30 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public List<ItemByNameCounts> UserItemCountList { get; set; } public List<ItemByNameCounts> UserItemCountList { get; set; }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
} }
} }

View File

@ -8,7 +8,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary> /// <summary>
/// This is the full Person object that can be retrieved with all of it's data. /// This is the full Person object that can be retrieved with all of it's data.
/// </summary> /// </summary>
public class Person : BaseItem, IItemByName, IHasLookupInfo<Providers.PersonLookupInfo> public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo>
{ {
public Person() public Person()
{ {
@ -33,9 +33,34 @@ namespace MediaBrowser.Controller.Entities
return "Person-" + Name; return "Person-" + Name;
} }
public Providers.PersonLookupInfo GetLookupInfo() public PersonLookupInfo GetLookupInfo()
{ {
return GetItemLookupInfo<Providers.PersonLookupInfo>(); return GetItemLookupInfo<PersonLookupInfo>();
}
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
} }
} }

View File

@ -26,5 +26,30 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public List<ItemByNameCounts> UserItemCountList { get; set; } public List<ItemByNameCounts> UserItemCountList { get; set; }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
} }
} }

View File

@ -72,6 +72,31 @@ namespace MediaBrowser.Controller.Entities
} }
} }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
/// <summary> /// <summary>
/// The _root folder /// The _root folder
/// </summary> /// </summary>
@ -222,6 +247,11 @@ namespace MediaBrowser.Controller.Entities
}, CancellationToken.None); }, CancellationToken.None);
} }
public override Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
{
return UserManager.UpdateUser(this);
}
/// <summary> /// <summary>
/// Gets the path to the user's configuration directory /// Gets the path to the user's configuration directory
/// </summary> /// </summary>

View File

@ -26,5 +26,30 @@ namespace MediaBrowser.Controller.Entities
{ {
return "Year-" + Name; return "Year-" + Name;
} }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
} }
} }

View File

@ -25,6 +25,31 @@ namespace MediaBrowser.Controller.LiveTv
public string ServiceName { get; set; } public string ServiceName { get; set; }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
public override string MediaType public override string MediaType
{ {
get get

View File

@ -25,6 +25,31 @@ namespace MediaBrowser.Controller.LiveTv
[IgnoreDataMember] [IgnoreDataMember]
public List<ItemByNameCounts> UserItemCountList { get; set; } public List<ItemByNameCounts> UserItemCountList { get; set; }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
/// <summary> /// <summary>
/// Gets or sets the number. /// Gets or sets the number.
/// </summary> /// </summary>

View File

@ -127,6 +127,31 @@ namespace MediaBrowser.Controller.LiveTv
/// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value>
public bool IsPremiere { get; set; } public bool IsPremiere { get; set; }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
public override string MediaType public override string MediaType
{ {
get get

View File

@ -46,6 +46,31 @@ namespace MediaBrowser.Controller.LiveTv
} }
} }
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
/// </summary>
/// <value>The containing folder path.</value>
public override string ContainingFolderPath
{
get
{
return Path;
}
}
/// <summary>
/// Gets a value indicating whether this instance is owned item.
/// </summary>
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
public override bool IsOwnedItem
{
get
{
return false;
}
}
public override string GetClientTypeName() public override string GetClientTypeName()
{ {
return "Recording"; return "Recording";

View File

@ -680,12 +680,30 @@ namespace MediaBrowser.Controller.Providers
} }
break; break;
} }
case "MusicbrainzId": case "MusicBrainzAlbumId":
{ {
var mbz = reader.ReadElementContentAsString(); var mbz = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(mbz)) if (!string.IsNullOrWhiteSpace(mbz))
{ {
item.SetProviderId(MetadataProviders.Musicbrainz, mbz); item.SetProviderId(MetadataProviders.MusicBrainzAlbum, mbz);
}
break;
}
case "MusicBrainzAlbumArtistId":
{
var mbz = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(mbz))
{
item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, mbz);
}
break;
}
case "MusicBrainzArtistId":
{
var mbz = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(mbz))
{
item.SetProviderId(MetadataProviders.MusicBrainzArtist, mbz);
} }
break; break;
} }

View File

@ -22,7 +22,7 @@ namespace MediaBrowser.Controller.Providers
public class LocalImageInfo public class LocalImageInfo
{ {
public string Path { get; set; } public FileInfo FileInfo { get; set; }
public ImageType Type { get; set; } public ImageType Type { get; set; }
} }

View File

@ -24,10 +24,6 @@ namespace MediaBrowser.Model.Entities
/// </summary> /// </summary>
Tvcom, Tvcom,
/// <summary> /// <summary>
/// MusicBrainz
/// </summary>
Musicbrainz,
/// <summary>
/// The rotten tomatoes /// The rotten tomatoes
/// </summary> /// </summary>
RottenTomatoes, RottenTomatoes,
@ -35,6 +31,9 @@ namespace MediaBrowser.Model.Entities
/// Tmdb Collection Id /// Tmdb Collection Id
/// </summary> /// </summary>
TmdbCollection, TmdbCollection,
MusicBrainzAlbum,
MusicBrainzAlbumArtist,
MusicBrainzArtist,
MusicBrainzReleaseGroup, MusicBrainzReleaseGroup,
Zap2It, Zap2It,
NesBox, NesBox,

View File

@ -65,25 +65,29 @@ namespace MediaBrowser.Providers.All
return false; return false;
} }
private IEnumerable<string> GetFiles(IHasImages item, bool includeDirectories) private IEnumerable<FileSystemInfo> GetFiles(IHasImages item, bool includeDirectories)
{ {
if (item.LocationType != LocationType.FileSystem) if (item.LocationType != LocationType.FileSystem)
{ {
return new List<string>(); return new List<FileSystemInfo>();
} }
var path = item.ContainingFolderPath; var path = item.ContainingFolderPath;
if (includeDirectories) if (includeDirectories)
{ {
return Directory.EnumerateFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly); return new DirectoryInfo(path).EnumerateFileSystemInfos("*", SearchOption.TopDirectoryOnly)
.Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase) ||
(i.Attributes & FileAttributes.Directory) == FileAttributes.Directory);
} }
return Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
return new DirectoryInfo(path).EnumerateFiles("*", SearchOption.TopDirectoryOnly)
.Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase));
} }
public List<LocalImageInfo> GetImages(IHasImages item) public List<LocalImageInfo> GetImages(IHasImages item)
{ {
var files = GetFileDictionary(GetFiles(item, true)); var files = GetFiles(item, true).ToList();
var list = new List<LocalImageInfo>(); var list = new List<LocalImageInfo>();
@ -92,7 +96,7 @@ namespace MediaBrowser.Providers.All
return list; return list;
} }
private void PopulateImages(IHasImages item, List<LocalImageInfo> images, Dictionary<string, string> files) private void PopulateImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files)
{ {
var imagePrefix = string.Empty; var imagePrefix = string.Empty;
@ -130,7 +134,7 @@ namespace MediaBrowser.Providers.All
} }
} }
private void PopulatePrimaryImages(IHasImages item, List<LocalImageInfo> images, Dictionary<string, string> files, string imagePrefix) private void PopulatePrimaryImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix)
{ {
AddImage(files, images, imagePrefix + "folder", ImageType.Primary); AddImage(files, images, imagePrefix + "folder", ImageType.Primary);
AddImage(files, images, imagePrefix + "cover", ImageType.Primary); AddImage(files, images, imagePrefix + "cover", ImageType.Primary);
@ -161,7 +165,7 @@ namespace MediaBrowser.Providers.All
} }
} }
private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, Dictionary<string, string> files, string imagePrefix) private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix)
{ {
PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", ImageType.Backdrop); PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", ImageType.Backdrop);
@ -179,19 +183,21 @@ namespace MediaBrowser.Providers.All
PopulateBackdrops(images, files, imagePrefix, "background", "background-", ImageType.Backdrop); PopulateBackdrops(images, files, imagePrefix, "background", "background-", ImageType.Backdrop);
PopulateBackdrops(images, files, imagePrefix, "art", "art-", ImageType.Backdrop); PopulateBackdrops(images, files, imagePrefix, "art", "art-", ImageType.Backdrop);
string extraFanartFolder; var extraFanartFolder = files.OfType<DirectoryInfo>()
if (files.TryGetValue("extrafanart", out extraFanartFolder)) .FirstOrDefault(i => string.Equals(i.Name, "extrafanart", StringComparison.OrdinalIgnoreCase));
if (extraFanartFolder != null)
{ {
PopulateBackdropsFromExtraFanart(extraFanartFolder, images); PopulateBackdropsFromExtraFanart(extraFanartFolder.FullName, images);
} }
} }
private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images) private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images)
{ {
var imageFiles = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly) var imageFiles = new DirectoryInfo(path).EnumerateFiles("*", SearchOption.TopDirectoryOnly)
.Where(i => .Where(i =>
{ {
var extension = Path.GetExtension(i); var extension = i.Extension;
if (string.IsNullOrEmpty(extension)) if (string.IsNullOrEmpty(extension))
{ {
@ -203,17 +209,17 @@ namespace MediaBrowser.Providers.All
images.AddRange(imageFiles.Select(i => new LocalImageInfo images.AddRange(imageFiles.Select(i => new LocalImageInfo
{ {
Path = i, FileInfo = i,
Type = ImageType.Backdrop Type = ImageType.Backdrop
})); }));
} }
private void PopulateScreenshots(List<LocalImageInfo> images, Dictionary<string, string> files, string imagePrefix) private void PopulateScreenshots(List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix)
{ {
PopulateBackdrops(images, files, imagePrefix, "screenshot", "screenshot", ImageType.Screenshot); PopulateBackdrops(images, files, imagePrefix, "screenshot", "screenshot", ImageType.Screenshot);
} }
private void PopulateBackdrops(List<LocalImageInfo> images, Dictionary<string, string> files, string imagePrefix, string firstFileName, string subsequentFileNamePrefix, ImageType type) private void PopulateBackdrops(List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, string firstFileName, string subsequentFileNamePrefix, ImageType type)
{ {
AddImage(files, images, imagePrefix + firstFileName, type); AddImage(files, images, imagePrefix + firstFileName, type);
@ -246,7 +252,7 @@ namespace MediaBrowser.Providers.All
return; return;
} }
var files = GetFileDictionary(GetFiles(series, false)); var seriesFiles = GetFiles(series, false).ToList();
// Try using the season name // Try using the season name
var prefix = season.Name.ToLower().Replace(" ", string.Empty); var prefix = season.Name.ToLower().Replace(" ", string.Empty);
@ -265,39 +271,22 @@ namespace MediaBrowser.Providers.All
foreach (var filename in filenamePrefixes) foreach (var filename in filenamePrefixes)
{ {
AddImage(files, images, filename + "-poster", ImageType.Primary); AddImage(seriesFiles, images, filename + "-poster", ImageType.Primary);
AddImage(files, images, filename + "-fanart", ImageType.Backdrop); AddImage(seriesFiles, images, filename + "-fanart", ImageType.Backdrop);
AddImage(files, images, filename + "-banner", ImageType.Banner); AddImage(seriesFiles, images, filename + "-banner", ImageType.Banner);
AddImage(files, images, filename + "-landscape", ImageType.Thumb); AddImage(seriesFiles, images, filename + "-landscape", ImageType.Thumb);
} }
} }
private Dictionary<string, string> GetFileDictionary(IEnumerable<string> paths) private bool AddImage(List<FileSystemInfo> files, List<LocalImageInfo> images, string name, ImageType type)
{ {
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); var image = GetImage(files, name) as FileInfo;
foreach (var path in paths)
{
var filename = Path.GetFileName(path);
if (!string.IsNullOrEmpty(filename))
{
dict[filename] = path;
}
}
return dict;
}
private bool AddImage(Dictionary<string, string> dict, List<LocalImageInfo> images, string name, ImageType type)
{
var image = GetImage(dict, name);
if (image != null) if (image != null)
{ {
images.Add(new LocalImageInfo images.Add(new LocalImageInfo
{ {
Path = image, FileInfo = image,
Type = type Type = type
}); });
@ -307,16 +296,14 @@ namespace MediaBrowser.Providers.All
return false; return false;
} }
private string GetImage(Dictionary<string, string> dict, string name) private FileSystemInfo GetImage(IEnumerable<FileSystemInfo> files, string name)
{ {
return BaseItem.SupportedImageExtensions var candidates = files
.Select(i => .Where(i => string.Equals(name, Path.GetFileNameWithoutExtension(i.Name), StringComparison.OrdinalIgnoreCase))
{ .ToList();
var filename = name + i;
string path;
return dict.TryGetValue(filename, out path) ? path : null; return BaseItem.SupportedImageExtensions
}) .Select(i => candidates.FirstOrDefault(c => string.Equals(c.Extension, i, StringComparison.OrdinalIgnoreCase)))
.FirstOrDefault(i => i != null); .FirstOrDefault(i => i != null);
} }
} }

View File

@ -275,9 +275,9 @@ namespace MediaBrowser.Providers.Manager
{ {
var currentImage = item.GetImageInfo(type, 0); var currentImage = item.GetImageInfo(type, 0);
if (currentImage == null || !string.Equals(currentImage.Path, image.Path, StringComparison.OrdinalIgnoreCase)) if (currentImage == null || !string.Equals(currentImage.Path, image.FileInfo.FullName, StringComparison.OrdinalIgnoreCase))
{ {
item.SetImagePath(type, new FileInfo(image.Path)); item.SetImagePath(type, image.FileInfo);
changed = true; changed = true;
} }
} }
@ -287,7 +287,7 @@ namespace MediaBrowser.Providers.Manager
if (backdrops.Count > 0) if (backdrops.Count > 0)
{ {
var foundImages = images.Where(i => i.Type == ImageType.Backdrop) var foundImages = images.Where(i => i.Type == ImageType.Backdrop)
.Select(i => new FileInfo(i.Path)) .Select(i => i.FileInfo)
.ToList(); .ToList();
if (foundImages.Count > 0) if (foundImages.Count > 0)
@ -303,7 +303,7 @@ namespace MediaBrowser.Providers.Manager
if (hasScreenshots != null) if (hasScreenshots != null)
{ {
var foundImages = images.Where(i => i.Type == ImageType.Screenshot) var foundImages = images.Where(i => i.Type == ImageType.Screenshot)
.Select(i => new FileInfo(i.Path)) .Select(i => i.FileInfo)
.ToList(); .ToList();
if (foundImages.Count > 0) if (foundImages.Count > 0)

View File

@ -197,11 +197,6 @@ namespace MediaBrowser.Providers.Manager
.Where(i => i.HasChanged(currentItem, currentItem.DateLastSaved)) .Where(i => i.HasChanged(currentItem, currentItem.DateLastSaved))
.ToList(); .ToList();
if (providersWithChanges.Count > 0)
{
var b = true;
}
// If local providers are the only ones with changes, then just run those // If local providers are the only ones with changes, then just run those
if (providersWithChanges.All(i => i is ILocalMetadataProvider)) if (providersWithChanges.All(i => i is ILocalMetadataProvider))
{ {

View File

@ -117,6 +117,7 @@
<Compile Include="Music\AlbumMetadataService.cs" /> <Compile Include="Music\AlbumMetadataService.cs" />
<Compile Include="Music\ArtistMetadataService.cs" /> <Compile Include="Music\ArtistMetadataService.cs" />
<Compile Include="Music\AudioMetadataService.cs" /> <Compile Include="Music\AudioMetadataService.cs" />
<Compile Include="Music\Extensions.cs" />
<Compile Include="Music\LastfmArtistProvider.cs" /> <Compile Include="Music\LastfmArtistProvider.cs" />
<Compile Include="Music\MovieDbMusicVideoProvider.cs" /> <Compile Include="Music\MovieDbMusicVideoProvider.cs" />
<Compile Include="Music\MusicBrainzArtistProvider.cs" /> <Compile Include="Music\MusicBrainzArtistProvider.cs" />

View File

@ -178,6 +178,11 @@ namespace MediaBrowser.Providers.MediaInfo
FetchStudios(audio, tags, "ensemble"); FetchStudios(audio, tags, "ensemble");
FetchStudios(audio, tags, "publisher"); FetchStudios(audio, tags, "publisher");
} }
audio.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id"));
audio.SetProviderId(MetadataProviders.MusicBrainzArtist, FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id"));
audio.SetProviderId(MetadataProviders.MusicBrainzAlbum, FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id"));
audio.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id"));
} }
private readonly char[] _nameDelimiters = new[] { '/', '|', ';', '\\' }; private readonly char[] _nameDelimiters = new[] { '/', '|', ';', '\\' };

View File

@ -0,0 +1,67 @@
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using System.Linq;
namespace MediaBrowser.Providers.Music
{
public static class Extensions
{
public static string GetAlbumArtist(this AlbumInfo info)
{
var id = info.AlbumArtist;
if (string.IsNullOrEmpty(id))
{
return info.SongInfos.Select(i => i.AlbumArtist)
.FirstOrDefault(i => !string.IsNullOrEmpty(i));
}
return id;
}
public static string GetReleaseGroupId(this AlbumInfo info)
{
var id = info.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
if (string.IsNullOrEmpty(id))
{
return info.SongInfos.Select(i => i.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup))
.FirstOrDefault(i => !string.IsNullOrEmpty(i));
}
return id;
}
public static string GetReleaseId(this AlbumInfo info)
{
var id = info.GetProviderId(MetadataProviders.MusicBrainzAlbum);
if (string.IsNullOrEmpty(id))
{
return info.SongInfos.Select(i => i.GetProviderId(MetadataProviders.MusicBrainzAlbum))
.FirstOrDefault(i => !string.IsNullOrEmpty(i));
}
return id;
}
public static string GetArtistId(this AlbumInfo info)
{
string id;
info.ProviderIds.TryGetValue(MetadataProviders.MusicBrainzAlbumArtist.ToString(), out id);
if (string.IsNullOrEmpty(id))
{
info.ArtistProviderIds.TryGetValue(MetadataProviders.MusicBrainzArtist.ToString(), out id);
}
if (string.IsNullOrEmpty(id))
{
return info.SongInfos.Select(i => i.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist))
.FirstOrDefault(i => !string.IsNullOrEmpty(i));
}
return id;
}
}
}

View File

@ -70,7 +70,7 @@ namespace MediaBrowser.Providers.Music
var list = new List<RemoteImageInfo>(); var list = new List<RemoteImageInfo>();
var artistMusicBrainzId = album.Parent.GetProviderId(MetadataProviders.Musicbrainz); var artistMusicBrainzId = album.MusicArtist.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!string.IsNullOrEmpty(artistMusicBrainzId)) if (!string.IsNullOrEmpty(artistMusicBrainzId))
{ {
@ -80,7 +80,7 @@ namespace MediaBrowser.Providers.Music
var musicBrainzReleaseGroupId = album.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); var musicBrainzReleaseGroupId = album.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
var musicBrainzId = album.GetProviderId(MetadataProviders.Musicbrainz); var musicBrainzId = album.GetProviderId(MetadataProviders.MusicBrainzAlbum);
try try
{ {
@ -365,17 +365,21 @@ namespace MediaBrowser.Providers.Music
} }
var album = (MusicAlbum)item; var album = (MusicAlbum)item;
var artist = album.MusicArtist;
var artistMusicBrainzId = album.Parent.GetProviderId(MetadataProviders.Musicbrainz); if (artist != null)
if (!String.IsNullOrEmpty(artistMusicBrainzId))
{ {
// Process images var artistMusicBrainzId = artist.GetProviderId(MetadataProviders.MusicBrainzArtist);
var artistXmlPath = FanartArtistProvider.GetArtistXmlPath(_config.CommonApplicationPaths, artistMusicBrainzId);
var fileInfo = new FileInfo(artistXmlPath); if (!String.IsNullOrEmpty(artistMusicBrainzId))
{
// Process images
var artistXmlPath = FanartArtistProvider.GetArtistXmlPath(_config.CommonApplicationPaths, artistMusicBrainzId);
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; var fileInfo = new FileInfo(artistXmlPath);
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
}
} }
return false; return false;

View File

@ -82,7 +82,7 @@ namespace MediaBrowser.Providers.Music
var list = new List<RemoteImageInfo>(); var list = new List<RemoteImageInfo>();
var artistMusicBrainzId = artist.GetProviderId(MetadataProviders.Musicbrainz); var artistMusicBrainzId = artist.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!String.IsNullOrEmpty(artistMusicBrainzId)) if (!String.IsNullOrEmpty(artistMusicBrainzId))
{ {
@ -381,7 +381,7 @@ namespace MediaBrowser.Providers.Music
return false; return false;
} }
var id = item.GetProviderId(MetadataProviders.Musicbrainz); var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!String.IsNullOrEmpty(id)) if (!String.IsNullOrEmpty(id))
{ {

View File

@ -61,7 +61,9 @@ namespace MediaBrowser.Providers.Music
RemoteImageInfo info = null; RemoteImageInfo info = null;
var musicBrainzId = item.GetProviderId(MetadataProviders.Musicbrainz); var musicBrainzId = item is MusicAlbum ?
item.GetProviderId(MetadataProviders.MusicBrainzAlbum) :
item.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!string.IsNullOrEmpty(musicBrainzId)) if (!string.IsNullOrEmpty(musicBrainzId))
{ {

View File

@ -48,9 +48,10 @@ namespace MediaBrowser.Providers.Music
private async Task<LastfmGetAlbumResult> GetAlbumResult(AlbumInfo item, CancellationToken cancellationToken) private async Task<LastfmGetAlbumResult> GetAlbumResult(AlbumInfo item, CancellationToken cancellationToken)
{ {
// Try album release Id // Try album release Id
if (!string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Musicbrainz))) var id = item.GetReleaseId();
if (!string.IsNullOrEmpty(id))
{ {
var result = await GetAlbumResult(item.GetProviderId(MetadataProviders.Musicbrainz), cancellationToken).ConfigureAwait(false); var result = await GetAlbumResult(id, cancellationToken).ConfigureAwait(false);
if (result != null && result.album != null) if (result != null && result.album != null)
{ {
@ -59,9 +60,10 @@ namespace MediaBrowser.Providers.Music
} }
// Try album release group Id // Try album release group Id
if (!string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup))) id = item.GetReleaseGroupId();
if (!string.IsNullOrEmpty(id))
{ {
var result = await GetAlbumResult(item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup), cancellationToken).ConfigureAwait(false); var result = await GetAlbumResult(id, cancellationToken).ConfigureAwait(false);
if (result != null && result.album != null) if (result != null && result.album != null)
{ {
@ -69,6 +71,7 @@ namespace MediaBrowser.Providers.Music
} }
} }
var albumArtist = item.GetAlbumArtist();
//// Get each song, distinct by the combination of AlbumArtist and Album //// Get each song, distinct by the combination of AlbumArtist and Album
//var songs = item.RecursiveChildren.OfType<Audio>().DistinctBy(i => (i.AlbumArtist ?? string.Empty) + (i.Album ?? string.Empty), StringComparer.OrdinalIgnoreCase).ToList(); //var songs = item.RecursiveChildren.OfType<Audio>().DistinctBy(i => (i.AlbumArtist ?? string.Empty) + (i.Album ?? string.Empty), StringComparer.OrdinalIgnoreCase).ToList();
@ -82,12 +85,12 @@ namespace MediaBrowser.Providers.Music
// } // }
//} //}
if (string.IsNullOrEmpty(item.AlbumArtist)) if (string.IsNullOrEmpty(albumArtist))
{ {
return null; return null;
} }
return await GetAlbumResult(item.AlbumArtist, item.Name, cancellationToken); return await GetAlbumResult(albumArtist, item.Name, cancellationToken);
} }
private async Task<LastfmGetAlbumResult> GetAlbumResult(string artist, string album, CancellationToken cancellationToken) private async Task<LastfmGetAlbumResult> GetAlbumResult(string artist, string album, CancellationToken cancellationToken)
@ -166,7 +169,7 @@ namespace MediaBrowser.Providers.Music
string imageSize; string imageSize;
var url = LastfmHelper.GetImageUrl(data, out imageSize); var url = LastfmHelper.GetImageUrl(data, out imageSize);
var musicBrainzId = item.GetProviderId(MetadataProviders.Musicbrainz) ?? var musicBrainzId = item.GetProviderId(MetadataProviders.MusicBrainzAlbum) ??
item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
LastfmHelper.SaveImageInfo(_config.ApplicationPaths, _logger, musicBrainzId, url, imageSize); LastfmHelper.SaveImageInfo(_config.ApplicationPaths, _logger, musicBrainzId, url, imageSize);

View File

@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.Music
{ {
var result = new MetadataResult<MusicArtist>(); var result = new MetadataResult<MusicArtist>();
var musicBrainzId = id.GetProviderId(MetadataProviders.Musicbrainz); var musicBrainzId = id.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!String.IsNullOrWhiteSpace(musicBrainzId)) if (!String.IsNullOrWhiteSpace(musicBrainzId))
{ {
@ -51,8 +51,6 @@ namespace MediaBrowser.Providers.Music
result.Item = new MusicArtist(); result.Item = new MusicArtist();
result.HasMetadata = true; result.HasMetadata = true;
result.Item.SetProviderId(MetadataProviders.Musicbrainz, musicBrainzId);
await FetchLastfmData(result.Item, musicBrainzId, cancellationToken).ConfigureAwait(false); await FetchLastfmData(result.Item, musicBrainzId, cancellationToken).ConfigureAwait(false);
} }

View File

@ -29,26 +29,25 @@ namespace MediaBrowser.Providers.Music
public async Task<MetadataResult<MusicAlbum>> GetMetadata(AlbumInfo id, CancellationToken cancellationToken) public async Task<MetadataResult<MusicAlbum>> GetMetadata(AlbumInfo id, CancellationToken cancellationToken)
{ {
var albumId = id; var releaseId = id.GetReleaseId();
var releaseId = albumId.GetProviderId(MetadataProviders.Musicbrainz); var releaseGroupId = id.GetReleaseGroupId();
var releaseGroupId = albumId.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
var result = new MetadataResult<MusicAlbum>(); var result = new MetadataResult<MusicAlbum>
{
Item = new MusicAlbum()
};
if (string.IsNullOrEmpty(releaseId)) if (string.IsNullOrEmpty(releaseId))
{ {
string artistMusicBrainzId; var artistMusicBrainzId = id.GetArtistId();
albumId.ArtistProviderIds.TryGetValue(MetadataProviders.Musicbrainz.ToString(), out artistMusicBrainzId);
var releaseResult = await GetReleaseResult(artistMusicBrainzId, albumId.AlbumArtist, albumId.Name, cancellationToken).ConfigureAwait(false); var releaseResult = await GetReleaseResult(artistMusicBrainzId, id.GetAlbumArtist(), id.Name, cancellationToken).ConfigureAwait(false);
result.Item = new MusicAlbum();
if (!string.IsNullOrEmpty(releaseResult.ReleaseId)) if (!string.IsNullOrEmpty(releaseResult.ReleaseId))
{ {
releaseId = releaseResult.ReleaseId; releaseId = releaseResult.ReleaseId;
result.HasMetadata = true; result.HasMetadata = true;
result.Item.SetProviderId(MetadataProviders.Musicbrainz, releaseId); result.Item.SetProviderId(MetadataProviders.MusicBrainzAlbum, releaseId);
} }
if (!string.IsNullOrEmpty(releaseResult.ReleaseGroupId)) if (!string.IsNullOrEmpty(releaseResult.ReleaseGroupId))
@ -67,6 +66,19 @@ namespace MediaBrowser.Providers.Music
result.Item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, releaseGroupId); result.Item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, releaseGroupId);
} }
if (result.HasMetadata)
{
if (!string.IsNullOrEmpty(releaseId))
{
result.Item.SetProviderId(MetadataProviders.MusicBrainzAlbum, releaseId);
}
if (!string.IsNullOrEmpty(releaseGroupId))
{
result.Item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, releaseGroupId);
}
}
return result; return result;
} }

View File

@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Music
{ {
var result = new MetadataResult<MusicArtist>(); var result = new MetadataResult<MusicArtist>();
var musicBrainzId = id.GetProviderId(MetadataProviders.Musicbrainz) ?? await FindId(id, cancellationToken).ConfigureAwait(false); var musicBrainzId = id.GetProviderId(MetadataProviders.MusicBrainzArtist) ?? await FindId(id, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(musicBrainzId)) if (!string.IsNullOrWhiteSpace(musicBrainzId))
{ {
@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.Music
result.Item = new MusicArtist(); result.Item = new MusicArtist();
result.HasMetadata = true; result.HasMetadata = true;
result.Item.SetProviderId(MetadataProviders.Musicbrainz, musicBrainzId); result.Item.SetProviderId(MetadataProviders.MusicBrainzArtist, musicBrainzId);
} }
return result; return result;

View File

@ -415,11 +415,25 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<Zap2ItId>" + SecurityElement.Escape(zap2It) + "</Zap2ItId>"); builder.Append("<Zap2ItId>" + SecurityElement.Escape(zap2It) + "</Zap2ItId>");
} }
var mbz = item.GetProviderId(MetadataProviders.Musicbrainz); var mbz = item.GetProviderId(MetadataProviders.MusicBrainzAlbum);
if (!string.IsNullOrEmpty(mbz)) if (!string.IsNullOrEmpty(mbz))
{ {
builder.Append("<MusicbrainzId>" + SecurityElement.Escape(mbz) + "</MusicbrainzId>"); builder.Append("<MusicBrainzAlbumId>" + SecurityElement.Escape(mbz) + "</MusicBrainzAlbumId>");
}
mbz = item.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist);
if (!string.IsNullOrEmpty(mbz))
{
builder.Append("<MusicBrainzAlbumArtistId>" + SecurityElement.Escape(mbz) + "</MusicBrainzAlbumArtistId>");
}
mbz = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!string.IsNullOrEmpty(mbz))
{
builder.Append("<MusicBrainzArtistId>" + SecurityElement.Escape(mbz) + "</MusicBrainzArtistId>");
} }
mbz = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); mbz = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);

View File

@ -28,12 +28,12 @@ namespace MediaBrowser.Providers.TV
var nameWithoutExtension = Path.GetFileNameWithoutExtension(item.Path); var nameWithoutExtension = Path.GetFileNameWithoutExtension(item.Path);
var thumbName = nameWithoutExtension + "-thumb"; var thumbName = nameWithoutExtension + "-thumb";
return Directory.EnumerateFiles(parentPath, "*", SearchOption.AllDirectories) return new DirectoryInfo(parentPath).EnumerateFiles("*", SearchOption.AllDirectories)
.Where(i => .Where(i =>
{ {
if (BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i) ?? string.Empty)) if (BaseItem.SupportedImageExtensions.Contains(i.Extension))
{ {
var currentNameWithoutExtension = Path.GetFileNameWithoutExtension(i); var currentNameWithoutExtension = Path.GetFileNameWithoutExtension(i.Name);
if (string.Equals(nameWithoutExtension, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase)) if (string.Equals(nameWithoutExtension, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
{ {
@ -50,7 +50,7 @@ namespace MediaBrowser.Providers.TV
}) })
.Select(i => new LocalImageInfo .Select(i => new LocalImageInfo
{ {
Path = i, FileInfo = i,
Type = ImageType.Primary Type = ImageType.Primary
}) })
.ToList(); .ToList();

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata> <metadata>
<id>MediaBrowser.Common.Internal</id> <id>MediaBrowser.Common.Internal</id>
<version>3.0.320</version> <version>3.0.321</version>
<title>MediaBrowser.Common.Internal</title> <title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors> <authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners> <owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description> <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright> <copyright>Copyright © Media Browser 2013</copyright>
<dependencies> <dependencies>
<dependency id="MediaBrowser.Common" version="3.0.320" /> <dependency id="MediaBrowser.Common" version="3.0.321" />
<dependency id="NLog" version="2.1.0" /> <dependency id="NLog" version="2.1.0" />
<dependency id="SimpleInjector" version="2.4.1" /> <dependency id="SimpleInjector" version="2.4.1" />
<dependency id="sharpcompress" version="0.10.2" /> <dependency id="sharpcompress" version="0.10.2" />

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata> <metadata>
<id>MediaBrowser.Common</id> <id>MediaBrowser.Common</id>
<version>3.0.320</version> <version>3.0.321</version>
<title>MediaBrowser.Common</title> <title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors> <authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners> <owners>ebr,Luke,scottisafool</owners>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata> <metadata>
<id>MediaBrowser.Server.Core</id> <id>MediaBrowser.Server.Core</id>
<version>3.0.320</version> <version>3.0.321</version>
<title>Media Browser.Server.Core</title> <title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors> <authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners> <owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description> <description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright> <copyright>Copyright © Media Browser 2013</copyright>
<dependencies> <dependencies>
<dependency id="MediaBrowser.Common" version="3.0.320" /> <dependency id="MediaBrowser.Common" version="3.0.321" />
</dependencies> </dependencies>
</metadata> </metadata>
<files> <files>