From e55ab989d2077d70568965198139793ca7c116b4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Dec 2014 23:20:07 -0500 Subject: add more sync buttons --- .../Library/LibraryManager.cs | 73 ++++++++++++++++++---- 1 file changed, 60 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library/LibraryManager.cs') diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 4cb39778c..d61a00ac3 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -18,8 +18,8 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Naming.Audio; using MediaBrowser.Naming.Common; using MediaBrowser.Naming.IO; +using MediaBrowser.Naming.TV; using MediaBrowser.Naming.Video; -using MediaBrowser.Server.Implementations.Library.Resolvers.TV; using MediaBrowser.Server.Implementations.Library.Validators; using MediaBrowser.Server.Implementations.ScheduledTasks; using System; @@ -862,7 +862,7 @@ namespace MediaBrowser.Server.Implementations.Library var type = typeof(T); - if (type == typeof(Person) && ConfigurationManager.Configuration.EnablePeoplePrefixSubFolders) + if (type == typeof(Person)) { subFolderPrefix = validFilename.Substring(0, 1); } @@ -1708,22 +1708,69 @@ namespace MediaBrowser.Server.Implementations.Library public int? GetSeasonNumberFromPath(string path) { - return SeriesResolver.GetSeasonNumberFromPath(path, CollectionType.TvShows); + return new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, true).SeasonNumber; } - public int? GetSeasonNumberFromEpisodeFile(string path) + public bool FillMissingEpisodeNumbersFromPath(Episode episode) { - return SeriesResolver.GetSeasonNumberFromEpisodeFile(path); - } + var resolver = new EpisodeResolver(new ExtendedNamingOptions(), + new Naming.Logging.NullLogger()); - public int? GetEndingEpisodeNumberFromFile(string path) - { - return SeriesResolver.GetEndingEpisodeNumberFromFile(path); - } + var locationType = episode.LocationType; + + var fileType = /*args.IsDirectory ? FileInfoType.Directory :*/ FileInfoType.File; + var episodeInfo = locationType == LocationType.FileSystem || locationType == LocationType.Offline ? + resolver.Resolve(episode.Path, fileType) : + new Naming.TV.EpisodeInfo(); - public int? GetEpisodeNumberFromFile(string path, bool considerSeasonless) - { - return SeriesResolver.GetEpisodeNumberFromFile(path, considerSeasonless); + if (episodeInfo == null) + { + episodeInfo = new Naming.TV.EpisodeInfo(); + } + + var changed = false; + + if (!episode.IndexNumber.HasValue) + { + episode.IndexNumber = episodeInfo.EpisodeNumber; + + if (episode.IndexNumber.HasValue) + { + changed = true; + } + } + + if (!episode.IndexNumberEnd.HasValue) + { + episode.IndexNumberEnd = episodeInfo.EndingEpsiodeNumber; + + if (episode.IndexNumberEnd.HasValue) + { + changed = true; + } + } + + if (!episode.ParentIndexNumber.HasValue) + { + episode.ParentIndexNumber = episodeInfo.SeasonNumber; + + if (!episode.ParentIndexNumber.HasValue) + { + var season = episode.Season; + + if (season != null) + { + episode.ParentIndexNumber = season.IndexNumber; + } + } + + if (episode.ParentIndexNumber.HasValue) + { + changed = true; + } + } + + return changed; } public ItemLookupInfo ParseName(string name) -- cgit v1.2.3 From 7b0306dce771abbe141e178330f2566bc0e21be6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 Dec 2014 20:23:56 -0500 Subject: update to jstree 3.0.8 --- .../Entities/Audio/MusicArtist.cs | 34 +- MediaBrowser.Controller/Entities/Folder.cs | 2 +- MediaBrowser.Model/Dto/DtoOptions.cs | 1 + MediaBrowser.Model/Querying/ItemFields.cs | 5 - .../Dto/DtoService.cs | 7 +- .../Library/LibraryManager.cs | 11 +- .../Localization/JavaScript/javascript.json | 1 + MediaBrowser.WebDashboard/Api/PackageCreator.cs | 3 +- .../MediaBrowser.WebDashboard.csproj | 732 +-------------------- 9 files changed, 59 insertions(+), 737 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library/LibraryManager.cs') diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index e9cc13c66..a60258d1a 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -136,7 +136,7 @@ namespace MediaBrowser.Controller.Entities.Audio // Refresh songs foreach (var item in songs) { - if (tasks.Count >= 3) + if (tasks.Count >= 2) { await Task.WhenAll(tasks).ConfigureAwait(false); tasks.Clear(); @@ -173,37 +173,23 @@ namespace MediaBrowser.Controller.Entities.Audio // Refresh all non-songs foreach (var item in others) { - if (tasks.Count >= 3) - { - await Task.WhenAll(tasks).ConfigureAwait(false); - tasks.Clear(); - } - cancellationToken.ThrowIfCancellationRequested(); - var innerProgress = new ActionableProgress(); // Avoid implicitly captured closure var currentChild = item; - innerProgress.RegisterAction(p => - { - lock (percentages) - { - percentages[currentChild.Id] = p / 100; - var percent = percentages.Values.Sum(); - percent /= totalItems; - percent *= 100; - progress.Report(percent); - } - }); + await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); + lock (percentages) + { + percentages[currentChild.Id] = 1; - // Avoid implicitly captured closure - var taskChild = item; - tasks.Add(Task.Run(async () => await RefreshItem(taskChild, refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false), cancellationToken)); + var percent = percentages.Values.Sum(); + percent /= totalItems; + percent *= 100; + progress.Report(percent); + } } - await Task.WhenAll(tasks).ConfigureAwait(false); - progress.Report(100); } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index fba5d082d..e8582a52a 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -545,7 +545,7 @@ namespace MediaBrowser.Controller.Entities foreach (var child in children) { - if (tasks.Count >= 3) + if (tasks.Count >= 2) { await Task.WhenAll(tasks).ConfigureAwait(false); tasks.Clear(); diff --git a/MediaBrowser.Model/Dto/DtoOptions.cs b/MediaBrowser.Model/Dto/DtoOptions.cs index 069d71fce..6a61c7ef2 100644 --- a/MediaBrowser.Model/Dto/DtoOptions.cs +++ b/MediaBrowser.Model/Dto/DtoOptions.cs @@ -10,6 +10,7 @@ namespace MediaBrowser.Model.Dto public List ImageTypes { get; set; } public int ImageTypeLimit { get; set; } public bool EnableImages { get; set; } + public bool EnableSettings { get; set; } public DtoOptions() { diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 875894c07..0bbb29742 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -106,11 +106,6 @@ namespace MediaBrowser.Model.Querying /// Metascore, - /// - /// The metadata settings - /// - Settings, - /// /// The item overview /// diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index a14a8ad08..bbf1d8e3a 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -71,7 +71,8 @@ namespace MediaBrowser.Server.Implementations.Dto { var options = new DtoOptions { - Fields = fields + Fields = fields, + EnableSettings = true }; // Get everything @@ -676,7 +677,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.IsUnidentified = item.IsUnidentified; } - if (fields.Contains(ItemFields.Settings)) + if (options.EnableSettings) { dto.LockedFields = item.LockedFields; dto.LockData = item.IsLocked; @@ -1169,7 +1170,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.SeasonCount = series.SeasonCount; - if (fields.Contains(ItemFields.Settings)) + if (options.EnableSettings) { dto.DisplaySpecialsWithSeasons = series.DisplaySpecialsWithSeasons; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d61a00ac3..9647461bf 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1563,14 +1563,11 @@ namespace MediaBrowser.Server.Implementations.Library return null; } - var collectionTypes = GetUserRootFolder().Children + return GetUserRootFolder().Children .OfType() - .Where(i => !string.IsNullOrEmpty(i.CollectionType) && (string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path))) + .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path)) .Select(i => i.CollectionType) - .Distinct() - .ToList(); - - return collectionTypes.Count == 1 ? collectionTypes[0] : null; + .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); } public async Task GetNamedView(string name, @@ -1717,7 +1714,7 @@ namespace MediaBrowser.Server.Implementations.Library new Naming.Logging.NullLogger()); var locationType = episode.LocationType; - + var fileType = /*args.IsDirectory ? FileInfoType.Directory :*/ FileInfoType.File; var episodeInfo = locationType == LocationType.FileSystem || locationType == LocationType.Offline ? resolver.Resolve(episode.Path, fileType) : diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 7072f2406..695200239 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -402,6 +402,7 @@ "LabelYear": "Year:", "LabelDateOfBirth": "Date of birth:", "LabelBirthYear": "Birth year:", + "LabelBirthDate": "Birth date:", "LabelDeathDate": "Death date:", "HeaderRemoveMediaLocation": "Remove Media Location", "MessageConfirmRemoveMediaLocation": "Are you sure you wish to remove this location?", diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 6dd44fb5a..d727dda6e 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -198,6 +198,7 @@ namespace MediaBrowser.WebDashboard.Api "thirdparty/jquerymobile-1.4.5/jquery.mobile-1.4.5.min.css", "thirdparty/swipebox-master/css/swipebox.min.css" + versionString, "thirdparty/fontawesome/css/font-awesome.min.css" + versionString, + "thirdparty/jstree3.0.8/themes/default/style.min.css", "css/all.css" + versionString }; @@ -220,7 +221,7 @@ namespace MediaBrowser.WebDashboard.Api var files = new[] { "scripts/all.js" + versionString, - "thirdparty/jstree1.0/jquery.jstree.min.js", + "thirdparty/jstree3.0.8/jstree.min.js", "thirdparty/swipebox-master/js/jquery.swipebox.min.js" + versionString }; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 50ce47b36..dc552c518 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -969,621 +969,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -2193,15 +1578,48 @@ PreserveNewest - - PreserveNewest - PreserveNewest PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -2438,78 +1856,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -2929,12 +2275,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 74520804f80974ec018a6c45f4e221276ded4cd3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Dec 2014 13:58:17 -0500 Subject: start on content type setting --- MediaBrowser.Api/ItemUpdateService.cs | 104 +++++++++++++++++++++ .../Configuration/BaseConfigurationManager.cs | 20 +++- .../Serialization/XmlSerializer.cs | 17 +++- MediaBrowser.Controller/Entities/Folder.cs | 2 +- MediaBrowser.Controller/Library/ILibraryManager.cs | 9 +- .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + MediaBrowser.Model/Dto/MetadataEditorInfo.cs | 4 + MediaBrowser.Model/Dto/NameValuePair.cs | 17 ++++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + .../Library/LibraryManager.cs | 17 ++-- .../Localization/Server/server.json | 12 +++ 12 files changed, 197 insertions(+), 12 deletions(-) create mode 100644 MediaBrowser.Model/Dto/NameValuePair.cs (limited to 'MediaBrowser.Server.Implementations/Library/LibraryManager.cs') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 601feabd5..953f7b3bb 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -6,6 +6,7 @@ using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using ServiceStack; using System; using System.Collections.Generic; @@ -28,6 +29,16 @@ namespace MediaBrowser.Api [ApiMember(Name = "ItemId", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string ItemId { get; set; } } + + [Route("/Items/{ItemId}/ContentType", "POST", Summary = "Updates an item's content type")] + public class UpdateItemContentType : IReturnVoid + { + [ApiMember(Name = "ItemId", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string ItemId { get; set; } + + [ApiMember(Name = "ContentType", Description = "The content type of the item", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] + public string ContentType { get; set; } + } [Authenticated] public class ItemUpdateService : BaseApiService @@ -55,9 +66,102 @@ namespace MediaBrowser.Api Cultures = _localizationManager.GetCultures().ToList() }; + var locationType = item.LocationType; + if (locationType == LocationType.FileSystem || + locationType == LocationType.Offline) + { + var collectionType = _libraryManager.GetInheritedContentType(item); + if (string.IsNullOrWhiteSpace(collectionType)) + { + info.ContentTypeOptions = GetContentTypeOptions(true); + info.ContentType = _libraryManager.GetContentType(item); + } + } + return ToOptimizedResult(info); } + public void Post(UpdateItemContentType request) + { + + } + + private List GetContentTypeOptions(bool isForItem) + { + var list = new List(); + + if (isForItem) + { + list.Add(new NameValuePair + { + Name = "FolderTypeInherit", + Value = "" + }); + } + + list.Add(new NameValuePair + { + Name = "FolderTypeMovies", + Value = "movies" + }); + list.Add(new NameValuePair + { + Name = "FolderTypeMusic", + Value = "music" + }); + list.Add(new NameValuePair + { + Name = "FolderTypeTvShows", + Value = "tvshows" + }); + + if (!isForItem) + { + list.Add(new NameValuePair + { + Name = "FolderTypeBooks", + Value = "books" + }); + list.Add(new NameValuePair + { + Name = "FolderTypeGames", + Value = "games" + }); + } + + list.Add(new NameValuePair + { + Name = "FolderTypeHomeVideos", + Value = "homevideos" + }); + list.Add(new NameValuePair + { + Name = "FolderTypeMusicVideos", + Value = "musicvideos" + }); + list.Add(new NameValuePair + { + Name = "FolderTypePhotos", + Value = "photos" + }); + + if (!isForItem) + { + list.Add(new NameValuePair + { + Name = "FolderTypeMixed", + Value = "" + }); + } + + foreach (var val in list) + { + val.Name = _localizationManager.GetLocalizedString(val.Name); + } + + return list; + } + public void Post(UpdateItem request) { var task = UpdateItem(request); diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs index 4a70697fa..a061420d7 100644 --- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs +++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs @@ -208,11 +208,29 @@ namespace MediaBrowser.Common.Implementations.Configuration lock (_configurationSyncLock) { - return ConfigurationHelper.GetXmlConfiguration(configurationType, file, XmlSerializer); + return LoadConfiguration(file, configurationType); } }); } + private object LoadConfiguration(string path, Type configurationType) + { + try + { + return XmlSerializer.DeserializeFromFile(configurationType, path); + } + catch (FileNotFoundException) + { + return Activator.CreateInstance(configurationType); + } + catch (Exception ex) + { + Logger.ErrorException("Error loading configuration file: {0}", ex, path); + + return Activator.CreateInstance(configurationType); + } + } + public void SaveConfiguration(string key, object configuration) { var configurationType = GetConfigurationType(key); diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs index cef744753..04030522f 100644 --- a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs +++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs @@ -1,5 +1,6 @@ using MediaBrowser.Model.Serialization; using System; +using System.Collections.Concurrent; using System.IO; using System.Xml; @@ -10,6 +11,17 @@ namespace MediaBrowser.Common.Implementations.Serialization /// public class XmlSerializer : IXmlSerializer { + // Need to cache these + // http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html + private readonly ConcurrentDictionary _serializers = + new ConcurrentDictionary(); + + private System.Xml.Serialization.XmlSerializer GetSerializer(Type type) + { + var key = type.FullName; + return _serializers.GetOrAdd(key, k => new System.Xml.Serialization.XmlSerializer(type)); + } + /// /// Serializes to writer. /// @@ -18,7 +30,7 @@ namespace MediaBrowser.Common.Implementations.Serialization private void SerializeToWriter(object obj, XmlTextWriter writer) { writer.Formatting = Formatting.Indented; - var netSerializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); + var netSerializer = GetSerializer(obj.GetType()); netSerializer.Serialize(writer, obj); } @@ -32,8 +44,7 @@ namespace MediaBrowser.Common.Implementations.Serialization { using (var reader = new XmlTextReader(stream)) { - var netSerializer = new System.Xml.Serialization.XmlSerializer(type); - + var netSerializer = GetSerializer(type); return netSerializer.Deserialize(reader); } } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e8582a52a..2761aa5d7 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -708,7 +708,7 @@ namespace MediaBrowser.Controller.Entities /// IEnumerable{BaseItem}. protected virtual IEnumerable GetNonCachedChildren(IDirectoryService directoryService) { - var collectionType = LibraryManager.FindCollectionType(this); + var collectionType = LibraryManager.GetContentType(this); return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, collectionType); } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 6d8f89226..7cdfb7788 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -259,8 +259,15 @@ namespace MediaBrowser.Controller.Library /// /// The item. /// System.String. - string FindCollectionType(BaseItem item); + string GetContentType(BaseItem item); + /// + /// Gets the type of the inherited content. + /// + /// The item. + /// System.String. + string GetInheritedContentType(BaseItem item); + /// /// Normalizes the root path list. /// diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index ec41ffe0b..f18c53cd3 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -464,6 +464,9 @@ Dto\MetadataEditorInfo.cs + + Dto\NameValuePair.cs + Dto\RatingType.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 01aaad2ac..f17215988 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -429,6 +429,9 @@ Dto\MetadataEditorInfo.cs + + Dto\NameValuePair.cs + Dto\RatingType.cs diff --git a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs index 66bdb8ce3..9bd15fc8f 100644 --- a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs +++ b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs @@ -12,12 +12,16 @@ namespace MediaBrowser.Model.Dto public List Cultures { get; set; } public List ExternalIdInfos { get; set; } + public string ContentType { get; set; } + public List ContentTypeOptions { get; set; } + public MetadataEditorInfo() { ParentalRatingOptions = new List(); Countries = new List(); Cultures = new List(); ExternalIdInfos = new List(); + ContentTypeOptions = new List(); } } } diff --git a/MediaBrowser.Model/Dto/NameValuePair.cs b/MediaBrowser.Model/Dto/NameValuePair.cs new file mode 100644 index 000000000..2d55e8f2a --- /dev/null +++ b/MediaBrowser.Model/Dto/NameValuePair.cs @@ -0,0 +1,17 @@ + +namespace MediaBrowser.Model.Dto +{ + public class NameValuePair + { + /// + /// Gets or sets the name. + /// + /// The name. + public string Name { get; set; } + /// + /// Gets or sets the value. + /// + /// The value. + public string Value { get; set; } + } +} diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 0dd5442ed..759c671e9 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -129,6 +129,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 9647461bf..ab50c30fb 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1546,12 +1546,17 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.RetrieveItem(id); } - /// - /// Finds the type of the collection. - /// - /// The item. - /// System.String. - public string FindCollectionType(BaseItem item) + public string GetContentType(BaseItem item) + { + return GetInheritedContentType(item); + } + + public string GetInheritedContentType(BaseItem item) + { + return GetTopFolderContentType(item); + } + + private string GetTopFolderContentType(BaseItem item) { while (!(item.Parent is AggregateFolder) && item.Parent != null) { diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 9bf06c50b..9a515d492 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -37,6 +37,18 @@ "ButtonOk": "Ok", "ButtonCancel": "Cancel", "ButtonNew": "New", + "FolderTypeMixed": "Mixed videos", + "FolderTypeMovies": "Movies", + "FolderTypeMusic": "Music", + "FolderTypeAdultVideos": "Adult videos", + "FolderTypePhotos": "Photos", + "FolderTypeMusicVideos": "Music videos", + "FolderTypeHomeVideos": "Home videos", + "FolderTypeGames": "Games", + "FolderTypeBooks": "Books", + "FolderTypeTvShows": "TV", + "FolderTypeInherit": "Inherit", + "LabelContentType": "Content type:", "HeaderSetupLibrary": "Setup your media library", "ButtonAddMediaFolder": "Add media folder", "LabelFolderType": "Folder type:", -- cgit v1.2.3 From 498b58aad0b2df17b3caf34b04dbf3f1438742c5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 22 Dec 2014 01:50:29 -0500 Subject: added content type selection --- MediaBrowser.Api/ItemUpdateService.cs | 37 ++++++++++++---- MediaBrowser.Controller/Library/ILibraryManager.cs | 4 +- .../Configuration/CinemaModeConfiguration.cs | 1 + .../Configuration/ServerConfiguration.cs | 6 ++- .../Library/LibraryManager.cs | 49 +++++++++++++++++++--- .../Library/Resolvers/Movies/MovieResolver.cs | 4 +- 6 files changed, 82 insertions(+), 19 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library/LibraryManager.cs') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 953f7b3bb..020908ddd 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; @@ -46,12 +47,14 @@ namespace MediaBrowser.Api private readonly ILibraryManager _libraryManager; private readonly IProviderManager _providerManager; private readonly ILocalizationManager _localizationManager; + private readonly IServerConfigurationManager _config; - public ItemUpdateService(ILibraryManager libraryManager, IProviderManager providerManager, ILocalizationManager localizationManager) + public ItemUpdateService(ILibraryManager libraryManager, IProviderManager providerManager, ILocalizationManager localizationManager, IServerConfigurationManager config) { _libraryManager = libraryManager; _providerManager = providerManager; _localizationManager = localizationManager; + _config = config; } public object Get(GetMetadataEditorInfo request) @@ -70,11 +73,14 @@ namespace MediaBrowser.Api if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) { - var collectionType = _libraryManager.GetInheritedContentType(item); - if (string.IsNullOrWhiteSpace(collectionType)) + if (!(item is ICollectionFolder) && !(item is UserView) && !(item is AggregateFolder)) { - info.ContentTypeOptions = GetContentTypeOptions(true); - info.ContentType = _libraryManager.GetContentType(item); + var collectionType = _libraryManager.GetInheritedContentType(item); + if (string.IsNullOrWhiteSpace(collectionType)) + { + info.ContentTypeOptions = GetContentTypeOptions(true); + info.ContentType = _libraryManager.GetContentType(item); + } } } @@ -83,7 +89,24 @@ namespace MediaBrowser.Api public void Post(UpdateItemContentType request) { - + var item = _libraryManager.GetItemById(request.ItemId); + var path = item.ContainingFolderPath; + + var types = _config.Configuration.ContentTypes + .Where(i => !string.Equals(i.Name, path, StringComparison.OrdinalIgnoreCase)) + .ToList(); + + if (!string.IsNullOrWhiteSpace(request.ContentType)) + { + types.Add(new NameValuePair + { + Name = path, + Value = request.ContentType + }); + } + + _config.Configuration.ContentTypes = types.ToArray(); + _config.SaveConfiguration(); } private List GetContentTypeOptions(bool isForItem) diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 7cdfb7788..8573f32e0 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -23,11 +23,9 @@ namespace MediaBrowser.Controller.Library /// /// The file information. /// The parent. - /// Type of the collection. /// BaseItem. BaseItem ResolvePath(FileSystemInfo fileInfo, - Folder parent = null, - string collectionType = null); + Folder parent = null); /// /// Resolves a set of files into a list of BaseItem diff --git a/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs b/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs index bd20713de..764a7222f 100644 --- a/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs +++ b/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs @@ -19,6 +19,7 @@ namespace MediaBrowser.Model.Configuration public CinemaModeConfiguration() { EnableIntrosParentalControl = true; + EnableIntrosFromSimilarMovies = true; TrailerLimit = 2; } } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 0852e0a5c..730735499 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Model.Configuration { @@ -165,6 +166,8 @@ namespace MediaBrowser.Model.Configuration public bool SaveMetadataHidden { get; set; } + public NameValuePair[] ContentTypes { get; set; } + /// /// Initializes a new instance of the class. /// @@ -192,6 +195,7 @@ namespace MediaBrowser.Model.Configuration FindInternetTrailers = true; PathSubstitutions = new PathSubstitution[] { }; + ContentTypes = new NameValuePair[] { }; PreferredMetadataLanguage = "en"; MetadataCountryCode = "US"; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index ab50c30fb..d52288f87 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -560,10 +560,9 @@ namespace MediaBrowser.Server.Implementations.Library } public BaseItem ResolvePath(FileSystemInfo fileInfo, - Folder parent = null, - string collectionType = null) + Folder parent = null) { - return ResolvePath(fileInfo, new DirectoryService(_logger), parent, collectionType); + return ResolvePath(fileInfo, new DirectoryService(_logger), parent); } private BaseItem ResolvePath(FileSystemInfo fileInfo, IDirectoryService directoryService, Folder parent = null, string collectionType = null) @@ -573,10 +572,17 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("fileInfo"); } + var fullPath = fileInfo.FullName; + + if (string.IsNullOrWhiteSpace(collectionType)) + { + collectionType = GetConfiguredContentType(fullPath); + } + var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, this, directoryService) { Parent = parent, - Path = fileInfo.FullName, + Path = fullPath, FileInfo = fileInfo, CollectionType = collectionType }; @@ -1548,12 +1554,43 @@ namespace MediaBrowser.Server.Implementations.Library public string GetContentType(BaseItem item) { - return GetInheritedContentType(item); + // Types cannot be overridden, so go from the top down until we find a configured content type + + var type = GetTopFolderContentType(item); + + if (!string.IsNullOrWhiteSpace(type)) + { + return type; + } + + type = GetInheritedContentType(item); + + if (!string.IsNullOrWhiteSpace(type)) + { + return type; + } + + return GetConfiguredContentType(item); } public string GetInheritedContentType(BaseItem item) { - return GetTopFolderContentType(item); + return item.Parents + .Select(GetConfiguredContentType) + .LastOrDefault(i => !string.IsNullOrWhiteSpace(i)); + } + + private string GetConfiguredContentType(BaseItem item) + { + return GetConfiguredContentType(item.ContainingFolderPath); + } + + private string GetConfiguredContentType(string path) + { + var type = ConfigurationManager.Configuration.ContentTypes + .FirstOrDefault(i => string.Equals(i.Name, path, StringComparison.OrdinalIgnoreCase) || _fileSystem.ContainsSubPath(i.Name, path)); + + return type == null ? null : type.Value; } private string GetTopFolderContentType(BaseItem item) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 58b5dbc6a..01dc4db8a 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return ResolveVideos /// The series. /// The episode lookup. - /// if set to true [force remove all]. /// Task{System.Boolean}. private async Task RemoveObsoleteOrMissingSeasons(IEnumerable series, - IEnumerable> episodeLookup, - bool forceRemoveAll) + IEnumerable> episodeLookup) { var existingSeasons = (from s in series let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) @@ -385,11 +395,6 @@ namespace MediaBrowser.Providers.TV var seasonsToRemove = virtualSeasons .Where(i => { - if (forceRemoveAll) - { - return true; - } - if (i.Season.IndexNumber.HasValue) { var seasonNumber = i.Season.IndexNumber.Value + i.SeasonOffset; @@ -409,7 +414,9 @@ namespace MediaBrowser.Providers.TV return false; } - return true; + // Season does not have a number + // Remove if there are no episodes directly in series without a season number + return i.Season.Series.RecursiveChildren.OfType().All(s => s.ParentIndexNumber.HasValue || s.IsInSeasonFolder); }) .ToList(); @@ -472,20 +479,22 @@ namespace MediaBrowser.Providers.TV /// The cancellation token. /// Task{Season}. private async Task AddSeason(Series series, - int seasonNumber, + int? seasonNumber, CancellationToken cancellationToken) { - _logger.Info("Creating Season {0} entry for {1}", seasonNumber, series.Name); + var seasonName = seasonNumber == 0 ? + _config.Configuration.SeasonZeroDisplayName : + (seasonNumber.HasValue ? string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.Value.ToString(UsCulture)) : _localization.GetLocalizedString("NameSeasonUnknown")); - var name = seasonNumber == 0 ? _config.Configuration.SeasonZeroDisplayName : string.Format("Season {0}", seasonNumber.ToString(UsCulture)); + _logger.Info("Creating Season {0} entry for {1}", seasonName, series.Name); var season = new Season { - Name = name, + Name = seasonName, IndexNumber = seasonNumber, Parent = series, DisplayMediaType = typeof(Season).Name, - Id = (series.Id + seasonNumber.ToString(UsCulture) + name).GetMBId(typeof(Season)) + Id = (series.Id + (seasonNumber ?? -1).ToString(UsCulture) + seasonName).GetMBId(typeof(Season)) }; await series.AddChild(season, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index d350d2fe4..e1986a7c1 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -1,11 +1,12 @@ -using System.Collections.Generic; -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -25,12 +26,14 @@ namespace MediaBrowser.Providers.TV private readonly ILibraryManager _libraryManager; private readonly IServerConfigurationManager _config; private readonly ILogger _logger; + private readonly ILocalizationManager _localization; - public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config) + public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, ILocalizationManager localization) { _libraryManager = libraryManager; _logger = logger; _config = config; + _localization = localization; } public Task Run(IProgress progress, CancellationToken cancellationToken) @@ -47,7 +50,7 @@ namespace MediaBrowser.Providers.TV var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList(); - await new MissingEpisodeProvider(_logger, _config, _libraryManager).Run(seriesGroups, cancellationToken).ConfigureAwait(false); + await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization).Run(seriesGroups, cancellationToken).ConfigureAwait(false); var numComplete = 0; diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index ef9f5427c..52c1ab7dd 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -72,6 +72,10 @@ namespace MediaBrowser.Providers.TV { // Don't fail the provider because this will just keep on going and going. } + catch (DirectoryNotFoundException) + { + // Don't fail the provider because this will just keep on going and going. + } } return list; @@ -101,6 +105,10 @@ namespace MediaBrowser.Providers.TV { // Don't fail the provider because this will just keep on going and going. } + catch (DirectoryNotFoundException) + { + // Don't fail the provider because this will just keep on going and going. + } } return result; @@ -208,8 +216,9 @@ namespace MediaBrowser.Providers.TV /// Fetches the episode data. /// /// The identifier. + /// The identity. /// The series data path. - /// + /// The series provider ids. /// The cancellation token. /// Task{System.Boolean}. private Episode FetchEpisodeData(EpisodeInfo id, EpisodeIdentity identity, string seriesDataPath, Dictionary seriesProviderIds, CancellationToken cancellationToken) @@ -279,6 +288,10 @@ namespace MediaBrowser.Providers.TV { break; } + catch (DirectoryNotFoundException) + { + break; + } episodeNumber++; } diff --git a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs index efafeae96..1ebd7bed5 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs @@ -94,6 +94,10 @@ namespace MediaBrowser.Providers.TV { // No tvdb data yet. Don't blow up } + catch (DirectoryNotFoundException) + { + // No tvdb data yet. Don't blow up + } } return new RemoteImageInfo[] { }; diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs index 9cc09c40c..08913d3b4 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs @@ -87,6 +87,10 @@ namespace MediaBrowser.Providers.TV { // No tvdb data yet. Don't blow up } + catch (DirectoryNotFoundException) + { + // No tvdb data yet. Don't blow up + } } return new RemoteImageInfo[] { }; diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 376dc3548..67d844543 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; @@ -789,7 +790,7 @@ namespace MediaBrowser.Server.Implementations.Connect if (user == null) { // Add user - user = await _userManager.CreateUser(connectEntry.UserName).ConfigureAwait(false); + user = await _userManager.CreateUser(_userManager.MakeValidUsername(connectEntry.UserName)).ConfigureAwait(false); user.ConnectUserName = connectEntry.UserName; user.ConnectUserId = connectEntry.UserId; diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index b141fea1e..967c78c50 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -78,6 +78,11 @@ namespace MediaBrowser.Server.Implementations.Drawing // No biggie sizeDictionary = new Dictionary(); } + catch (DirectoryNotFoundException) + { + // No biggie + sizeDictionary = new Dictionary(); + } catch (Exception ex) { logger.ErrorException("Error parsing image size cache file", ex); diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 3b5e34520..432ea1f69 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -459,11 +459,11 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private bool IsSameEpisode(string sourcePath, string newPath) { - var sourceFileInfo = new FileInfo(sourcePath); - var destinationFileInfo = new FileInfo(newPath); - try { + var sourceFileInfo = new FileInfo(sourcePath); + var destinationFileInfo = new FileInfo(newPath); + if (sourceFileInfo.Length == destinationFileInfo.Length) { return true; @@ -473,6 +473,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { return false; } + catch (DirectoryNotFoundException) + { + return false; + } return false; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d52288f87..66125784c 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1755,9 +1755,12 @@ namespace MediaBrowser.Server.Implementations.Library var resolver = new EpisodeResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var fileType = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd || episode.VideoType == VideoType.HdDvd ? + FileInfoType.Directory : + FileInfoType.File; + var locationType = episode.LocationType; - var fileType = /*args.IsDirectory ? FileInfoType.Directory :*/ FileInfoType.File; var episodeInfo = locationType == LocationType.FileSystem || locationType == LocationType.Offline ? resolver.Resolve(episode.Path, fileType) : new Naming.TV.EpisodeInfo(); @@ -1769,29 +1772,42 @@ namespace MediaBrowser.Server.Implementations.Library var changed = false; - if (!episode.IndexNumber.HasValue) + if (episodeInfo.IsByDate) { - episode.IndexNumber = episodeInfo.EpisodeNumber; - if (episode.IndexNumber.HasValue) { + episode.IndexNumber = null; changed = true; } - } - - if (!episode.IndexNumberEnd.HasValue) - { - episode.IndexNumberEnd = episodeInfo.EndingEpsiodeNumber; if (episode.IndexNumberEnd.HasValue) { + episode.IndexNumberEnd = null; changed = true; } - } - if (!episode.ParentIndexNumber.HasValue) - { - episode.ParentIndexNumber = episodeInfo.SeasonNumber; + if (!episode.PremiereDate.HasValue) + { + if (episodeInfo.Year.HasValue && episodeInfo.Month.HasValue && episodeInfo.Day.HasValue) + { + episode.PremiereDate = new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value).ToUniversalTime(); + } + + if (episode.PremiereDate.HasValue) + { + changed = true; + } + } + + if (!episode.ProductionYear.HasValue) + { + episode.ProductionYear = episodeInfo.Year; + + if (episode.ProductionYear.HasValue) + { + changed = true; + } + } if (!episode.ParentIndexNumber.HasValue) { @@ -1801,11 +1817,53 @@ namespace MediaBrowser.Server.Implementations.Library { episode.ParentIndexNumber = season.IndexNumber; } + + if (episode.ParentIndexNumber.HasValue) + { + changed = true; + } + } + } + else + { + if (!episode.IndexNumber.HasValue) + { + episode.IndexNumber = episodeInfo.EpisodeNumber; + + if (episode.IndexNumber.HasValue) + { + changed = true; + } } - if (episode.ParentIndexNumber.HasValue) + if (!episode.IndexNumberEnd.HasValue) { - changed = true; + episode.IndexNumberEnd = episodeInfo.EndingEpsiodeNumber; + + if (episode.IndexNumberEnd.HasValue) + { + changed = true; + } + } + + if (!episode.ParentIndexNumber.HasValue) + { + episode.ParentIndexNumber = episodeInfo.SeasonNumber; + + if (!episode.ParentIndexNumber.HasValue) + { + var season = episode.Season; + + if (season != null) + { + episode.ParentIndexNumber = season.IndexNumber; + } + } + + if (episode.ParentIndexNumber.HasValue) + { + changed = true; + } } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index 39b0a93cc..1a873f01e 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -1,7 +1,5 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Naming.Common; -using MediaBrowser.Naming.IO; using System.Linq; namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 1d58ad074..02d7c1be1 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -171,6 +171,38 @@ namespace MediaBrowser.Server.Implementations.Library return AuthenticateUser(username, passwordSha1, null, remoteEndPoint); } + public bool IsValidUsername(string username) + { + // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) + return username.All(IsValidCharacter); + } + + private bool IsValidCharacter(char i) + { + return char.IsLetterOrDigit(i) || char.Equals(i, '-') || char.Equals(i, '_') || char.Equals(i, '\'') || + char.Equals(i, '.'); + } + + public string MakeValidUsername(string username) + { + if (IsValidUsername(username)) + { + return username; + } + + // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) + var builder = new StringBuilder(); + + foreach (var c in username) + { + if (IsValidCharacter(c)) + { + builder.Append(c); + } + } + return builder.ToString(); + } + public async Task AuthenticateUser(string username, string passwordSha1, string passwordMd5, string remoteEndPoint) { if (string.IsNullOrWhiteSpace(username)) @@ -178,7 +210,8 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("username"); } - var user = Users.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase)); + var user = Users + .FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase)); if (user == null) { @@ -203,20 +236,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - // Maybe user accidently entered connect credentials. let's be flexible - if (!success && user.ConnectLinkType.HasValue && !string.IsNullOrWhiteSpace(passwordMd5)) - { - try - { - await _connectFactory().Authenticate(user.ConnectUserName, passwordMd5).ConfigureAwait(false); - success = true; - } - catch - { - - } - } - // Update LastActivityDate and LastLoginDate, then save if (success) { @@ -273,7 +292,7 @@ namespace MediaBrowser.Server.Implementations.Library // There always has to be at least one user. if (users.Count == 0) { - var name = Environment.UserName; + var name = MakeValidUsername(Environment.UserName); var user = InstantiateNewUser(name, false); @@ -477,6 +496,11 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("name"); } + if (!IsValidUsername(name)) + { + throw new ArgumentException("Only alphanumeric characters are allowed."); + } + if (Users.Any(u => u.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name)); @@ -803,6 +827,10 @@ namespace MediaBrowser.Server.Implementations.Library return (UserPolicy)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), path); } } + catch (DirectoryNotFoundException) + { + return GetDefaultPolicy(user); + } catch (FileNotFoundException) { return GetDefaultPolicy(user); @@ -840,6 +868,8 @@ namespace MediaBrowser.Server.Implementations.Library var path = GetPolifyFilePath(user); + Directory.CreateDirectory(Path.GetDirectoryName(path)); + lock (_policySyncLock) { _xmlSerializer.SerializeToFile(userPolicy, path); @@ -900,6 +930,10 @@ namespace MediaBrowser.Server.Implementations.Library return (UserConfiguration)_xmlSerializer.DeserializeFromFile(typeof(UserConfiguration), path); } } + catch (DirectoryNotFoundException) + { + return new UserConfiguration(); + } catch (FileNotFoundException) { return new UserConfiguration(); @@ -930,6 +964,8 @@ namespace MediaBrowser.Server.Implementations.Library config = _jsonSerializer.DeserializeFromString(json); } + Directory.CreateDirectory(Path.GetDirectoryName(path)); + lock (_configSyncLock) { _xmlSerializer.SerializeToFile(config, path); diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 695200239..827a2388d 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -419,7 +419,7 @@ "HeaderMediaLocations": "Media Locations", "LabelFolderTypeValue": "Folder type: {0}", "LabelPathSubstitutionHelp": "Optional: Path substitution can map server paths to network shares that clients can access for direct playback.", - "FolderTypeMixed": "Mixed videos", + "FolderTypeMixed": "Mixed content", "FolderTypeMovies": "Movies", "FolderTypeMusic": "Music", "FolderTypeAdultVideos": "Adult videos", @@ -658,5 +658,5 @@ "LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.", "MessageBookPluginRequired": "Requires installation of the Bookshelf plugin", "MessageGamePluginRequired": "Requires installation of the GameBrowser plugin", - "MessageMixedContentHelp": "Content will be displayed with as a plain folder structure" + "MessageMixedContentHelp": "Content will be displayed as a plain folder structure" } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 9a515d492..c0af13950 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -37,7 +37,7 @@ "ButtonOk": "Ok", "ButtonCancel": "Cancel", "ButtonNew": "New", - "FolderTypeMixed": "Mixed videos", + "FolderTypeMixed": "Mixed content", "FolderTypeMovies": "Movies", "FolderTypeMusic": "Music", "FolderTypeAdultVideos": "Adult videos", @@ -48,7 +48,7 @@ "FolderTypeBooks": "Books", "FolderTypeTvShows": "TV", "FolderTypeInherit": "Inherit", - "LabelContentType": "Content type:", + "LabelContentType": "Content type:", "HeaderSetupLibrary": "Setup your media library", "ButtonAddMediaFolder": "Add media folder", "LabelFolderType": "Folder type:", @@ -1307,5 +1307,8 @@ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", "TitleSync": "Sync", - "OptionAllowSyncContent": "Allow syncing media to devices" + "OptionAllowSyncContent": "Allow syncing media to devices", + "NameSeasonUnknown": "Season Unknown", + "NameSeasonNumber": "Season {0}", + "LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)" } diff --git a/MediaBrowser.Server.Implementations/News/NewsService.cs b/MediaBrowser.Server.Implementations/News/NewsService.cs index 9eeadfab7..684363d01 100644 --- a/MediaBrowser.Server.Implementations/News/NewsService.cs +++ b/MediaBrowser.Server.Implementations/News/NewsService.cs @@ -26,6 +26,14 @@ namespace MediaBrowser.Server.Implementations.News { return GetProductNewsInternal(query); } + catch (DirectoryNotFoundException) + { + // No biggie + return new QueryResult + { + Items = new NewsItem[] { } + }; + } catch (FileNotFoundException) { // No biggie diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index 86e92530f..0f1d53ea6 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -256,6 +256,10 @@ namespace MediaBrowser.XbmcMetadata.Savers catch (FileNotFoundException) { + } + catch (DirectoryNotFoundException) + { + } writer.WriteEndElement(); -- cgit v1.2.3 From 5278959edef763bdf0b4d72ace75efd151ab5024 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 28 Dec 2014 01:21:39 -0500 Subject: sync fixes --- MediaBrowser.Api/VideosService.cs | 8 +- .../Archiving/ZipClient.cs | 16 +++ MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 11 +- .../Savers/FolderXmlSaver.cs | 2 +- MediaBrowser.Model/IO/IZipClient.cs | 8 ++ .../BoxSets/BoxSetMetadataService.cs | 2 +- .../Music/AlbumMetadataService.cs | 20 ++-- .../Music/ArtistMetadataService.cs | 21 ++-- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 2 +- .../Library/LibraryManager.cs | 10 +- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 45 ++++---- .../Library/Resolvers/Movies/BoxSetResolver.cs | 17 +++ .../Library/Resolvers/Movies/MovieResolver.cs | 39 +------ .../Library/Resolvers/PhotoResolver.cs | 4 +- .../Library/Resolvers/TV/SeriesResolver.cs | 124 ++------------------- .../Library/UserManager.cs | 7 ++ .../Localization/JavaScript/javascript.json | 4 +- .../Localization/Server/server.json | 4 +- .../MediaBrowser.Server.Implementations.csproj | 2 +- .../Session/WebSocketController.cs | 11 -- .../Sync/SyncJobProcessor.cs | 76 +++++++------ .../Sync/SyncManager.cs | 23 +++- .../Sync/SyncRepository.cs | 7 +- .../packages.config | 2 +- .../MediaBrowser.Server.Mono.csproj | 4 - 25 files changed, 190 insertions(+), 279 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library/LibraryManager.cs') diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs index 91b02089c..28db46b98 100644 --- a/MediaBrowser.Api/VideosService.cs +++ b/MediaBrowser.Api/VideosService.cs @@ -112,11 +112,11 @@ namespace MediaBrowser.Api { link.PrimaryVersionId = null; - await link.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await link.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); } video.LinkedAlternateVersions.Clear(); - await video.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await video.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); } public void Post(MergeVersions request) @@ -184,7 +184,7 @@ namespace MediaBrowser.Api { item.PrimaryVersionId = primaryVersion.Id; - await item.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); primaryVersion.LinkedAlternateVersions.Add(new LinkedChild { @@ -193,7 +193,7 @@ namespace MediaBrowser.Api }); } - await primaryVersion.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await primaryVersion.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs index 23d40cf67..c32134d4f 100644 --- a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs +++ b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs @@ -4,6 +4,7 @@ using SharpCompress.Archive.SevenZip; using SharpCompress.Archive.Tar; using SharpCompress.Common; using SharpCompress.Reader; +using SharpCompress.Reader.Zip; using System.IO; namespace MediaBrowser.Common.Implementations.Archiving @@ -48,6 +49,21 @@ namespace MediaBrowser.Common.Implementations.Archiving } } + public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var reader = ZipReader.Open(source)) + { + var options = ExtractOptions.ExtractFullPath; + + if (overwriteExistingFiles) + { + options = options | ExtractOptions.Overwrite; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + /// /// Extracts all from7z. /// diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 6563da8de..8d3cf9bad 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Controller.Entities.Movies public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasPreferredMetadataLanguage, IHasDisplayOrder, IHasLookupInfo, IMetadataContainer, IHasShares { public List Shares { get; set; } - + public BoxSet() { RemoteTrailers = new List(); @@ -171,10 +171,13 @@ namespace MediaBrowser.Controller.Entities.Movies { var userId = user.Id.ToString("N"); - return Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)) || + // Need to check Count > 0 for boxsets created prior to the introduction of Shares + if (Shares.Count > 0 && !Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase))) + { + return false; + } - // Need to support this for boxsets created prior to the creation of Shares - Shares.Count == 0; + return true; } return false; diff --git a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs index fa3d7d87d..67fa12b55 100644 --- a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs @@ -49,7 +49,7 @@ namespace MediaBrowser.LocalMetadata.Savers !(item is GameSystem) && !(item is Playlist)) { - return updateType >= ItemUpdateType.MetadataDownload; + return updateType >= ItemUpdateType.MetadataEdit; } } diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs index ba0725da5..13b31c201 100644 --- a/MediaBrowser.Model/IO/IZipClient.cs +++ b/MediaBrowser.Model/IO/IZipClient.cs @@ -23,6 +23,14 @@ namespace MediaBrowser.Model.IO /// if set to true [overwrite existing files]. void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles); + /// + /// Extracts all from zip. + /// + /// The source. + /// The target path. + /// if set to true [overwrite existing files]. + void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles); + /// /// Extracts all from7z. /// diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index 062519f9d..5afaaa875 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -75,7 +75,7 @@ namespace MediaBrowser.Providers.BoxSets if (!string.Equals(currentOfficialRating ?? string.Empty, item.OfficialRating ?? string.Empty, StringComparison.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index 79fab2f70..6e3a5bf06 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -54,7 +54,7 @@ namespace MediaBrowser.Providers.Music if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } @@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.Music if (currentList.Count != item.Studios.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Studios.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } @@ -81,15 +81,15 @@ namespace MediaBrowser.Providers.Music if (!string.Equals(item.Name, name, StringComparison.Ordinal)) { item.Name = name; - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } } - } - updateType = updateType | SetAlbumArtistFromSongs(item, songs); - updateType = updateType | SetArtistsFromSongs(item, songs); - updateType = updateType | SetDateFromSongs(item, songs); + updateType = updateType | SetAlbumArtistFromSongs(item, songs); + updateType = updateType | SetArtistsFromSongs(item, songs); + updateType = updateType | SetDateFromSongs(item, songs); + } return updateType; } @@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.Music if (!item.AlbumArtists.SequenceEqual(albumArtists, StringComparer.OrdinalIgnoreCase)) { item.AlbumArtists = albumArtists; - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } return updateType; @@ -124,7 +124,7 @@ namespace MediaBrowser.Providers.Music if (currentList.Count != item.Artists.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Artists.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } return updateType; @@ -158,7 +158,7 @@ namespace MediaBrowser.Providers.Music if ((originalPremiereDate ?? DateTime.MinValue) != (item.PremiereDate ?? DateTime.MinValue) || (originalProductionYear ?? -1) != (item.ProductionYear ?? -1)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } return updateType; diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index 939bd2b3b..a73d82992 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -35,19 +35,22 @@ namespace MediaBrowser.Providers.Music { var updateType = base.BeforeSave(item); - if (!item.IsAccessedByName && !item.LockedFields.Contains(MetadataFields.Genres)) + if (!item.IsAccessedByName && !item.IsLocked) { - var songs = item.RecursiveChildren.OfType