diff --git a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs index bb23f7f7e..df69f68f8 100644 --- a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs +++ b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs @@ -288,9 +288,6 @@ namespace MediaBrowser.Api.DefaultTheme var view = new TvView(); - SetFavoriteGenres(view, series, user); - SetFavoriteStudios(view, series, user); - var fields = new List(); var seriesWithBestBackdrops = FilterItemsForBackdropDisplay(seriesWithBackdrops).ToList(); @@ -401,146 +398,6 @@ namespace MediaBrowser.Api.DefaultTheme return ToOptimizedResult(view); } - private void SetFavoriteGenres(TvView view, IEnumerable inputItems, User user) - { - var all = inputItems.SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase); - - view.FavoriteGenres = all.Select(i => - { - try - { - var itemByName = _libraryManager.GetGenre(i); - - var counts = itemByName.GetItemByNameCounts(user); - - var count = counts == null ? 0 : counts.SeriesCount; - - if (count > 0 && _userDataManager.GetUserData(user.Id, itemByName.GetUserDataKey()).IsFavorite) - { - return new ItemByNameInfo - { - Name = itemByName.Name, - ItemCount = count - }; - } - } - catch (Exception ex) - { - _logger.ErrorException("Error getting genre {0}", ex, i); - - } - - return null; - - }).Where(i => i != null).ToList(); - } - - private void SetFavoriteStudios(TvView view, IEnumerable inputItems, User user) - { - var all = inputItems.SelectMany(i => i.Studios) - .Distinct(StringComparer.OrdinalIgnoreCase); - - view.FavoriteStudios = all.Select(i => - { - try - { - var itemByName = _libraryManager.GetStudio(i); - - var counts = itemByName.GetItemByNameCounts(user); - - var count = counts == null ? 0 : counts.SeriesCount; - - if (count > 0 && _userDataManager.GetUserData(user.Id, itemByName.GetUserDataKey()).IsFavorite) - { - return new ItemByNameInfo - { - Name = itemByName.Name, - ItemCount = count - }; - } - } - catch (Exception ex) - { - _logger.ErrorException("Error getting studio {0}", ex, i); - - } - - return null; - - }).Where(i => i != null).ToList(); - } - - private void SetFavoriteGenres(MoviesView view, IEnumerable inputItems, User user) - { - var all = inputItems.SelectMany(i => i.Genres) - .Distinct(StringComparer.OrdinalIgnoreCase); - - view.FavoriteGenres = all.Select(i => - { - try - { - var itemByName = _libraryManager.GetGenre(i); - - var counts = itemByName.GetItemByNameCounts(user); - - var count = counts == null ? 0 : counts.MovieCount; - - if (count > 0 && _userDataManager.GetUserData(user.Id, itemByName.GetUserDataKey()).IsFavorite) - { - return new ItemByNameInfo - { - Name = itemByName.Name, - ItemCount = count - }; - } - } - catch (Exception ex) - { - _logger.ErrorException("Error getting genre {0}", ex, i); - - } - - return null; - - }).Where(i => i != null).ToList(); - } - - private void SetFavoriteStudios(MoviesView view, IEnumerable inputItems, User user) - { - var all = inputItems.SelectMany(i => i.Studios) - .Distinct(StringComparer.OrdinalIgnoreCase); - - view.FavoriteStudios = all.Select(i => - { - try - { - var itemByName = _libraryManager.GetStudio(i); - - var counts = itemByName.GetItemByNameCounts(user); - - var count = counts == null ? 0 : counts.MovieCount; - - if (count > 0 && _userDataManager.GetUserData(user.Id, itemByName.GetUserDataKey()).IsFavorite) - { - return new ItemByNameInfo - { - Name = itemByName.Name, - ItemCount = count - }; - } - } - catch (Exception ex) - { - _logger.ErrorException("Error getting studio {0}", ex, i); - - } - - return null; - - }).Where(i => i != null).ToList(); - } - public object Get(GetMovieView request) { var user = _userManager.GetUserById(request.UserId); @@ -557,9 +414,6 @@ namespace MediaBrowser.Api.DefaultTheme var movies = items.OfType() .ToList(); - SetFavoriteGenres(view, movies, user); - SetFavoriteStudios(view, movies, user); - var trailers = items.OfType() .ToList(); diff --git a/MediaBrowser.Api/DefaultTheme/Models.cs b/MediaBrowser.Api/DefaultTheme/Models.cs index bdff82de2..5219c44f9 100644 --- a/MediaBrowser.Api/DefaultTheme/Models.cs +++ b/MediaBrowser.Api/DefaultTheme/Models.cs @@ -34,9 +34,6 @@ namespace MediaBrowser.Api.DefaultTheme public List LatestTrailers { get; set; } public List LatestMovies { get; set; } - - public List FavoriteGenres { get; set; } - public List FavoriteStudios { get; set; } } public class TvView : BaseView @@ -47,8 +44,6 @@ namespace MediaBrowser.Api.DefaultTheme public List RomanceItems { get; set; } public List ComedyItems { get; set; } - public List FavoriteGenres { get; set; } - public List FavoriteStudios { get; set; } public List SeriesIdsInProgress { get; set; } public List LatestEpisodes { get; set; } diff --git a/MediaBrowser.Api/PackageReviewService.cs b/MediaBrowser.Api/PackageReviewService.cs index 1aca596c0..e0d52ee8a 100644 --- a/MediaBrowser.Api/PackageReviewService.cs +++ b/MediaBrowser.Api/PackageReviewService.cs @@ -1,9 +1,12 @@ using System.Collections.Generic; using System.Globalization; +using System.Net; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Constants; using MediaBrowser.Common.Net; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Serialization; using ServiceStack.ServiceHost; namespace MediaBrowser.Api @@ -51,27 +54,103 @@ namespace MediaBrowser.Api public string Review { get; set; } } + /// + /// Class InstallPackage + /// + [Route("/PackageReviews/{Id}", "GET")] + [Api(("Retrieve reviews for a package"))] + public class ReviewRequest : IReturn> + { + /// + /// Gets or sets the Id. + /// + /// The Id. + [ApiMember(Name = "Id", Description = "Package Id", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")] + public int Id { get; set; } + + /// + /// Gets or sets the max rating. + /// + /// The max rating. + [ApiMember(Name = "MaxRating", Description = "Retrieve only reviews less than or equal to this", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int MaxRating { get; set; } + + /// + /// Gets or sets the min rating. + /// + /// The max rating. + [ApiMember(Name = "MinRating", Description = "Retrieve only reviews greator than or equal to this", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int MinRating { get; set; } + + /// + /// Only retrieve reviews with at least a short review. + /// + /// True if should only get reviews with a title. + [ApiMember(Name = "ForceTitle", Description = "Whether or not to restrict results to those with a title", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool ForceTitle { get; set; } + + /// + /// Gets or sets the limit for the query. + /// + /// The max rating. + [ApiMember(Name = "Limit", Description = "Limit the result to this many reviews (ordered by latest)", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int Limit { get; set; } + + } public class PackageReviewService : BaseApiService { private readonly IHttpClient _httpClient; private readonly INetworkManager _netManager; + private readonly IJsonSerializer _serializer; - public PackageReviewService(IHttpClient client, INetworkManager net) + public PackageReviewService(IHttpClient client, INetworkManager net, IJsonSerializer serializer) { _httpClient = client; _netManager = net; + _serializer = serializer; + } + + public object Get(ReviewRequest request) + { + var parms = "?id=" + request.Id; + + if (request.MaxRating > 0) + { + parms += "&max=" + request.MaxRating; + } + if (request.MinRating > 0) + { + parms += "&min=" + request.MinRating; + } + if (request.MinRating > 0) + { + parms += "&limit=" + request.Limit; + } + if (request.ForceTitle) + { + parms += "&title=true"; + } + + var result = _httpClient.Get(Constants.MbAdminUrl + "/service/packageReview/retrieve"+parms, CancellationToken.None).Result; + + var reviews = _serializer.DeserializeFromStream>(result); + + return ToOptimizedResult(reviews); } public void Post(CreateReviewRequest request) { + var reviewText = WebUtility.HtmlEncode(request.Review ?? string.Empty); + var title = WebUtility.HtmlEncode(request.Title ?? string.Empty); + var review = new Dictionary { { "id", request.Id.ToString(CultureInfo.InvariantCulture) }, { "mac", _netManager.GetMacAddress() }, { "rating", request.Rating.ToString(CultureInfo.InvariantCulture) }, { "recommend", request.Recommend.ToString() }, - { "title", request.Title }, - { "review", request.Review }, + { "title", title }, + { "review", reviewText }, }; Task.WaitAll(_httpClient.Post(Constants.MbAdminUrl + "/service/packageReview/update", review, CancellationToken.None)); diff --git a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs index 2b66617af..23d40cf67 100644 --- a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs +++ b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs @@ -1,4 +1,5 @@ using MediaBrowser.Model.IO; +using SharpCompress.Archive.Rar; using SharpCompress.Archive.SevenZip; using SharpCompress.Archive.Tar; using SharpCompress.Common; @@ -123,5 +124,43 @@ namespace MediaBrowser.Common.Implementations.Archiving } } } + + /// + /// Extracts all from rar. + /// + /// The source file. + /// The target path. + /// if set to true [overwrite existing files]. + public void ExtractAllFromRar(string sourceFile, string targetPath, bool overwriteExistingFiles) + { + using (var fileStream = File.OpenRead(sourceFile)) + { + ExtractAllFromRar(fileStream, targetPath, overwriteExistingFiles); + } + } + + /// + /// Extracts all from rar. + /// + /// The source. + /// The target path. + /// if set to true [overwrite existing files]. + public void ExtractAllFromRar(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var archive = RarArchive.Open(source)) + { + using (var reader = archive.ExtractAllEntries()) + { + var options = ExtractOptions.ExtractFullPath; + + if (overwriteExistingFiles) + { + options = options | ExtractOptions.Overwrite; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + } } } diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index e4c68a8ab..1a8583489 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -68,7 +68,7 @@ namespace MediaBrowser.Controller.Drawing /// The image enhancers. /// Guid. Guid GetImageCacheTag(BaseItem item, ImageType imageType, string originalImagePath, DateTime dateModified, - IEnumerable imageEnhancers); + List imageEnhancers); /// /// Processes the image. diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 501095f24..1d50a5933 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -383,6 +383,12 @@ namespace MediaBrowser.Model.Dto /// The album image tag. public Guid? AlbumPrimaryImageTag { get; set; } + /// + /// Gets or sets the series primary image tag. + /// + /// The series primary image tag. + public Guid? SeriesPrimaryImageTag { get; set; } + /// /// Gets or sets the album artist. /// diff --git a/MediaBrowser.Model/Entities/PackageReviewInfo.cs b/MediaBrowser.Model/Entities/PackageReviewInfo.cs index 9d71622c3..c350935f4 100644 --- a/MediaBrowser.Model/Entities/PackageReviewInfo.cs +++ b/MediaBrowser.Model/Entities/PackageReviewInfo.cs @@ -33,5 +33,10 @@ namespace MediaBrowser.Model.Entities /// public string review { get; set; } + /// + /// Time of review + /// + public DateTime timestamp { get; set; } + } } diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs index 1fa3e0271..ba0725da5 100644 --- a/MediaBrowser.Model/IO/IZipClient.cs +++ b/MediaBrowser.Model/IO/IZipClient.cs @@ -54,5 +54,21 @@ namespace MediaBrowser.Model.IO /// The target path. /// if set to true [overwrite existing files]. void ExtractAllFromTar(Stream source, string targetPath, bool overwriteExistingFiles); + + /// + /// Extracts all from rar. + /// + /// The source file. + /// The target path. + /// if set to true [overwrite existing files]. + void ExtractAllFromRar(string sourceFile, string targetPath, bool overwriteExistingFiles); + + /// + /// Extracts all from rar. + /// + /// The source. + /// The target path. + /// if set to true [overwrite existing files]. + void ExtractAllFromRar(Stream source, string targetPath, bool overwriteExistingFiles); } } diff --git a/MediaBrowser.Model/Updates/PackageInfo.cs b/MediaBrowser.Model/Updates/PackageInfo.cs index 13c4d6194..2263f29fd 100644 --- a/MediaBrowser.Model/Updates/PackageInfo.cs +++ b/MediaBrowser.Model/Updates/PackageInfo.cs @@ -117,12 +117,6 @@ namespace MediaBrowser.Model.Updates /// The name. public string guid { get; set; } - /// - /// Gets or sets the total number of machines who have checked registration for this package (if premium). - /// - /// The total hits. - public int totalHits { get; set; } - /// /// Gets or sets the total number of ratings for this package. /// diff --git a/MediaBrowser.Providers/Music/LastfmHelper.cs b/MediaBrowser.Providers/Music/LastfmHelper.cs index f529fd44a..d58aa714b 100644 --- a/MediaBrowser.Providers/Music/LastfmHelper.cs +++ b/MediaBrowser.Providers/Music/LastfmHelper.cs @@ -25,8 +25,13 @@ namespace MediaBrowser.Providers.Music } } - artist.PremiereDate = yearFormed > 0 ? new DateTime(yearFormed, 1, 1, 0, 0, 0, DateTimeKind.Utc) : (DateTime?)null; - artist.ProductionYear = yearFormed; + if (yearFormed > 0) + { + artist.PremiereDate = new DateTime(yearFormed, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + artist.ProductionYear = yearFormed; + } + if (data.tags != null && !artist.LockedFields.Contains(MetadataFields.Tags)) { AddTags(artist, data.tags); @@ -102,10 +107,14 @@ namespace MediaBrowser.Providers.Music DateTime release; - if (DateTime.TryParse(data.releasedate, out release) && release.Year != 1901) + if (DateTime.TryParse(data.releasedate, out release)) { - item.PremiereDate = release; - item.ProductionYear = release.Year; + // Lastfm sends back null as sometimes 1901, other times 0 + if (release.Year > 1901) + { + item.PremiereDate = release; + item.ProductionYear = release.Year; + } } if (data.toptags != null && !item.LockedFields.Contains(MetadataFields.Tags)) diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index 78dcf6fd0..fd980abc8 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -589,7 +589,7 @@ namespace MediaBrowser.Server.Implementations.Drawing var supportedEnhancers = GetSupportedEnhancers(item, imageType); - return GetImageCacheTag(item, imageType, imagePath, dateModified, supportedEnhancers); + return GetImageCacheTag(item, imageType, imagePath, dateModified, supportedEnhancers.ToList()); } /// @@ -602,7 +602,7 @@ namespace MediaBrowser.Server.Implementations.Drawing /// The image enhancers. /// Guid. /// item - public Guid GetImageCacheTag(BaseItem item, ImageType imageType, string originalImagePath, DateTime dateModified, IEnumerable imageEnhancers) + public Guid GetImageCacheTag(BaseItem item, ImageType imageType, string originalImagePath, DateTime dateModified, List imageEnhancers) { if (item == null) { @@ -619,6 +619,12 @@ namespace MediaBrowser.Server.Implementations.Drawing throw new ArgumentNullException("originalImagePath"); } + // Optimization + if (imageEnhancers.Count == 0) + { + return (originalImagePath + dateModified.Ticks).GetMD5(); + } + // Cache name is created with supported enhancers combined with the last config change so we pick up new config changes var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList(); cacheKeys.Add(originalImagePath + dateModified.Ticks); @@ -879,7 +885,7 @@ namespace MediaBrowser.Server.Implementations.Drawing { try { - return i.Supports(item as BaseItem, imageType); + return i.Supports(item, imageType); } catch (Exception ex) { @@ -888,7 +894,7 @@ namespace MediaBrowser.Server.Implementations.Drawing return false; } - }).ToList(); + }); } public void Dispose() diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 0104196e0..d327796f9 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -165,7 +165,8 @@ namespace MediaBrowser.Server.Implementations.Dto { var folder = (Folder)item; - dto.ChildCount = folder.GetChildren(user, true).Count(); + dto.ChildCount = folder.GetChildren(user, true) + .Count(); if (!(folder is UserRootFolder)) { @@ -1051,6 +1052,13 @@ namespace MediaBrowser.Server.Implementations.Dto { dto.SeriesThumbImageTag = GetImageCacheTag(series, ImageType.Thumb, series.GetImage(ImageType.Thumb)); } + + var imagePath = series.PrimaryImagePath; + + if (!string.IsNullOrEmpty(imagePath)) + { + dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary, imagePath); + } } // Add SeasonInfo @@ -1064,6 +1072,13 @@ namespace MediaBrowser.Server.Implementations.Dto dto.SeriesName = series.Name; dto.AirTime = series.AirTime; dto.SeriesStudio = series.Studios.FirstOrDefault(); + + var imagePath = series.PrimaryImagePath; + + if (!string.IsNullOrEmpty(imagePath)) + { + dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary, imagePath); + } } var game = item as Game; diff --git a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs index 03739cc8f..ffb351222 100644 --- a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs @@ -67,7 +67,8 @@ namespace MediaBrowser.Server.Implementations.IO public async void RemoveTempIgnore(string path) { // This is an arbitraty amount of time, but delay it because file system writes often trigger events after RemoveTempIgnore has been called. - await Task.Delay(2000).ConfigureAwait(false); + // Seeing long delays in some situations, especially over the network. + await Task.Delay(40000).ConfigureAwait(false); string val; _tempIgnoredPaths.TryRemove(path, out val); diff --git a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs index ae4ae2fa9..95ec416b6 100644 --- a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs +++ b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs @@ -25,7 +25,8 @@ namespace MediaBrowser.Server.Implementations.Library "ps3_vprm", "adv_obj", "extrafanart", - "extrathumbs" + "extrathumbs", + ".actors" }.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Server.Implementations/Localization/Ratings/da.txt b/MediaBrowser.Server.Implementations/Localization/Ratings/dk.txt similarity index 100% rename from MediaBrowser.Server.Implementations/Localization/Ratings/da.txt rename to MediaBrowser.Server.Implementations/Localization/Ratings/dk.txt diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 017dc2b54..ac451e1eb 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -250,7 +250,7 @@ - + diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs index b8686800f..ff11b9a2b 100644 --- a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs +++ b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs @@ -13,6 +13,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.Providers { @@ -37,17 +38,19 @@ namespace MediaBrowser.Server.Implementations.Providers /// private readonly IDirectoryWatchers _directoryWatchers; private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The config. /// The directory watchers. - public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem) + public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem, ILogger logger) { _config = config; _directoryWatchers = directoryWatchers; _fileSystem = fileSystem; + _logger = logger; _remoteImageCache = new FileSystemRepository(config.ApplicationPaths.DownloadedImagesDataPath); } @@ -170,7 +173,12 @@ namespace MediaBrowser.Server.Implementations.Providers /// Task. private async Task SaveImageToLocation(Stream source, string path, CancellationToken cancellationToken) { + _logger.Debug("Saving image to {0}", path); + + var parentFolder = Path.GetDirectoryName(path); + _directoryWatchers.TemporarilyIgnore(path); + _directoryWatchers.TemporarilyIgnore(parentFolder); try { @@ -196,6 +204,7 @@ namespace MediaBrowser.Server.Implementations.Providers finally { _directoryWatchers.RemoveTempIgnore(path); + _directoryWatchers.RemoveTempIgnore(parentFolder); } } diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs index 0252373f0..7b2a038f4 100644 --- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs +++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs @@ -349,7 +349,7 @@ namespace MediaBrowser.Server.Implementations.Providers /// Task. public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken) { - return new ImageSaver(ConfigurationManager, _directoryWatchers, _fileSystem).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken); + return new ImageSaver(ConfigurationManager, _directoryWatchers, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken); } /// diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index e72d48e3e..a5621ff4d 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -53,20 +53,15 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if ($.browser.chrome) { name = "Chrome"; - } - else if ($.browser.safari) { + } else if ($.browser.safari) { name = "Safari"; - } - else if ($.browser.webkit) { + } else if ($.browser.webkit) { name = "WebKit"; - } - else if ($.browser.msie) { + } else if ($.browser.msie) { name = "Internet Explorer"; - } - else if ($.browser.opera) { + } else if ($.browser.opera) { name = "Opera"; - } - else if ($.browser.firefox || $.browser.mozilla) { + } else if ($.browser.firefox || $.browser.mozilla) { name = "Firefox"; } @@ -74,18 +69,15 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if ($.browser.version) { name += " " + $.browser.version; } - } - else { + } else { name = "Web Browser"; } if ($.browser.ipad) { name += " Ipad"; - } - else if ($.browser.iphone) { + } else if ($.browser.iphone) { name += " Iphone"; - } - else if ($.browser.android) { + } else if ($.browser.android) { name += " Android"; } return name; @@ -313,28 +305,22 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if (options.artist) { urlPrefix = "Artists/" + self.encodeName(options.artist); delete options.artist; - } - else if (options.person) { + } else if (options.person) { urlPrefix = "Persons/" + self.encodeName(options.person); delete options.person; - } - else if (options.genre) { + } else if (options.genre) { urlPrefix = "Genres/" + self.encodeName(options.genre); delete options.genre; - } - else if (options.musicGenre) { + } else if (options.musicGenre) { urlPrefix = "MusicGenres/" + self.encodeName(options.musicGenre); delete options.musicGenre; - } - else if (options.gameGenre) { + } else if (options.gameGenre) { urlPrefix = "GameGenres/" + self.encodeName(options.gameGenre); delete options.gameGenre; - } - else if (options.studio) { + } else if (options.studio) { urlPrefix = "Studios/" + self.encodeName(options.studio); delete options.studio; - } - else { + } else { urlPrefix = "Items/" + options.itemId; delete options.itemId; } @@ -624,10 +610,8 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("Items/" + itemId + "/Refresh", { - forced: force || false, recursive: recursive || false - }); return self.ajax({ @@ -643,9 +627,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("Artists/" + self.encodeName(name) + "/Refresh", { - forced: force || false - }); return self.ajax({ @@ -661,9 +643,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("Genres/" + self.encodeName(name) + "/Refresh", { - forced: force || false - }); return self.ajax({ @@ -679,9 +659,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("MusicGenres/" + self.encodeName(name) + "/Refresh", { - forced: force || false - }); return self.ajax({ @@ -697,9 +675,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("GameGenres/" + self.encodeName(name) + "/Refresh", { - forced: force || false - }); return self.ajax({ @@ -715,9 +691,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("Persons/" + self.encodeName(name) + "/Refresh", { - forced: force || false - }); return self.ajax({ @@ -733,9 +707,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("Studios/" + self.encodeName(name) + "/Refresh", { - forced: force || false - }); return self.ajax({ @@ -1122,7 +1094,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi url += "/" + virtualFolderName + "/Paths"; url = self.getUrl(url, { - refreshLibrary: refreshLibrary ? true : false, path: mediaPath }); @@ -1152,7 +1123,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi url += "/" + virtualFolderName + "/Paths"; url = self.getUrl(url, { - refreshLibrary: refreshLibrary ? true : false, path: mediaPath }); @@ -1222,23 +1192,17 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if (itemType == "Artist") { url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Genre") { + } else if (itemType == "Genre") { url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "GameGenre") { + } else if (itemType == "GameGenre") { url = self.getUrl("GameGenres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "MusicGenre") { + } else if (itemType == "MusicGenre") { url = self.getUrl("MusicGenres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Person") { + } else if (itemType == "Person") { url = self.getUrl("Persons/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Studio") { + } else if (itemType == "Studio") { url = self.getUrl("Studios/" + self.encodeName(itemName) + "/Images"); - } - else { + } else { url = self.getUrl("Items/" + itemId + "/Images"); } @@ -1284,23 +1248,17 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if (itemType == "Artist") { url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options); - } - else if (itemType == "Genre") { + } else if (itemType == "Genre") { url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options); - } - else if (itemType == "GameGenre") { + } else if (itemType == "GameGenre") { url = self.getUrl("GameGenres/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options); - } - else if (itemType == "MusicGenre") { + } else if (itemType == "MusicGenre") { url = self.getUrl("MusicGenres/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options); - } - else if (itemType == "Person") { + } else if (itemType == "Person") { url = self.getUrl("Persons/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options); - } - else if (itemType == "Studio") { + } else if (itemType == "Studio") { url = self.getUrl("Studios/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options); - } - else { + } else { url = self.getUrl("Items/" + itemId + "/Images/" + imageType + "/" + imageIndex + "/Index", options); } @@ -1320,23 +1278,17 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if (itemType == "Artist") { url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Genre") { + } else if (itemType == "Genre") { url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "GameGenre") { + } else if (itemType == "GameGenre") { url = self.getUrl("GameGenres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "MusicGenre") { + } else if (itemType == "MusicGenre") { url = self.getUrl("MusicGenres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Person") { + } else if (itemType == "Person") { url = self.getUrl("Persons/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Studio") { + } else if (itemType == "Studio") { url = self.getUrl("Studios/" + self.encodeName(itemName) + "/Images"); - } - else { + } else { url = self.getUrl("Items/" + itemId + "/Images"); } @@ -1459,23 +1411,17 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if (itemType == "Artist") { url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Genre") { + } else if (itemType == "Genre") { url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "GameGenre") { + } else if (itemType == "GameGenre") { url = self.getUrl("GameGenres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "MusicGenre") { + } else if (itemType == "MusicGenre") { url = self.getUrl("MusicGenres/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Person") { + } else if (itemType == "Person") { url = self.getUrl("Persons/" + self.encodeName(itemName) + "/Images"); - } - else if (itemType == "Studio") { + } else if (itemType == "Studio") { url = self.getUrl("Studios/" + self.encodeName(itemName) + "/Images"); - } - else { + } else { url = self.getUrl("Items/" + itemId + "/Images"); } @@ -2823,6 +2769,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }; self.getDateParamValue = function (date) { + function formatDigit(i) { return i < 10 ? "0" + i : i; } @@ -3385,7 +3332,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, { - CanSeek: canSeek, QueueableMediaTypes: queueableMediaTypes }); @@ -3466,6 +3412,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi } var params = { + }; if (positionTicks) { @@ -3579,7 +3526,39 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi url: url, }); }; - } + + self.getPackageReviews = function (packageId, minRating, maxRating, limit, forceTitle) { + + if (!packageId) { + throw new Error("null packageId"); + } + + var options = {}; + + if (minRating) { + options.MinRating = minRating; + } + if (maxRating) { + options.MaxRating = maxRating; + } + if (limit) { + options.Limit = limit; + } + if (forceTitle) { + options.ForceTitle = true; + } + + var url = self.getUrl("PackageReviews/" + packageId, options); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + + + }; }(jQuery, navigator, window.JSON, window.WebSocket, setTimeout, window); diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 5ab968880..846153190 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 744debbcd..0c5360b49 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -237,4 +237,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection EndGlobal