aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Van den brande <sven.vandenbrande@outlook.com>2013-11-10 22:47:45 +0100
committerSven Van den brande <sven.vandenbrande@outlook.com>2013-11-10 22:47:45 +0100
commit09d7bc00c2f21b0686bb08051bf20ba7aebccfcd (patch)
tree923bcb092565d4a2f0466b532044c84ca7e0f8ee
parente4564ac8607e45534bfb8132ccb410eab04f5528 (diff)
parent0bf016d0ff500a2a2ffc51a22f90748b79d6dbbc (diff)
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
-rw-r--r--MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs146
-rw-r--r--MediaBrowser.Api/DefaultTheme/Models.cs5
-rw-r--r--MediaBrowser.Api/PackageReviewService.cs85
-rw-r--r--MediaBrowser.Common.Implementations/Archiving/ZipClient.cs39
-rw-r--r--MediaBrowser.Controller/Drawing/IImageProcessor.cs2
-rw-r--r--MediaBrowser.Model/Dto/BaseItemDto.cs6
-rw-r--r--MediaBrowser.Model/Entities/PackageReviewInfo.cs5
-rw-r--r--MediaBrowser.Model/IO/IZipClient.cs16
-rw-r--r--MediaBrowser.Model/Updates/PackageInfo.cs6
-rw-r--r--MediaBrowser.Providers/Music/LastfmHelper.cs19
-rw-r--r--MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs14
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs17
-rw-r--r--MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Ratings/dk.txt (renamed from MediaBrowser.Server.Implementations/Localization/Ratings/da.txt)0
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj2
-rw-r--r--MediaBrowser.Server.Implementations/Providers/ImageSaver.cs11
-rw-r--r--MediaBrowser.Server.Implementations/Providers/ProviderManager.cs2
-rw-r--r--MediaBrowser.WebDashboard/ApiClient.js167
-rw-r--r--MediaBrowser.WebDashboard/packages.config2
-rw-r--r--MediaBrowser.sln3
21 files changed, 282 insertions, 271 deletions
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<ItemFields>();
var seriesWithBestBackdrops = FilterItemsForBackdropDisplay(seriesWithBackdrops).ToList();
@@ -401,146 +398,6 @@ namespace MediaBrowser.Api.DefaultTheme
return ToOptimizedResult(view);
}
- private void SetFavoriteGenres(TvView view, IEnumerable<BaseItem> 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<BaseItem> 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<BaseItem> 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<BaseItem> 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<Movie>()
.ToList();
- SetFavoriteGenres(view, movies, user);
- SetFavoriteStudios(view, movies, user);
-
var trailers = items.OfType<Trailer>()
.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<BaseItemDto> LatestTrailers { get; set; }
public List<BaseItemDto> LatestMovies { get; set; }
-
- public List<ItemByNameInfo> FavoriteGenres { get; set; }
- public List<ItemByNameInfo> FavoriteStudios { get; set; }
}
public class TvView : BaseView
@@ -47,8 +44,6 @@ namespace MediaBrowser.Api.DefaultTheme
public List<ItemStub> RomanceItems { get; set; }
public List<ItemStub> ComedyItems { get; set; }
- public List<ItemByNameInfo> FavoriteGenres { get; set; }
- public List<ItemByNameInfo> FavoriteStudios { get; set; }
public List<string> SeriesIdsInProgress { get; set; }
public List<BaseItemDto> 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; }
}
+ /// <summary>
+ /// Class InstallPackage
+ /// </summary>
+ [Route("/PackageReviews/{Id}", "GET")]
+ [Api(("Retrieve reviews for a package"))]
+ public class ReviewRequest : IReturn<List<PackageReviewInfo>>
+ {
+ /// <summary>
+ /// Gets or sets the Id.
+ /// </summary>
+ /// <value>The Id.</value>
+ [ApiMember(Name = "Id", Description = "Package Id", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")]
+ public int Id { get; set; }
+
+ /// <summary>
+ /// Gets or sets the max rating.
+ /// </summary>
+ /// <value>The max rating.</value>
+ [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; }
+
+ /// <summary>
+ /// Gets or sets the min rating.
+ /// </summary>
+ /// <value>The max rating.</value>
+ [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; }
+
+ /// <summary>
+ /// Only retrieve reviews with at least a short review.
+ /// </summary>
+ /// <value>True if should only get reviews with a title.</value>
+ [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; }
+
+ /// <summary>
+ /// Gets or sets the limit for the query.
+ /// </summary>
+ /// <value>The max rating.</value>
+ [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<List<PackageReviewInfo>>(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<string, string>
{ { "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
}
}
}
+
+ /// <summary>
+ /// Extracts all from rar.
+ /// </summary>
+ /// <param name="sourceFile">The source file.</param>
+ /// <param name="targetPath">The target path.</param>
+ /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
+ public void ExtractAllFromRar(string sourceFile, string targetPath, bool overwriteExistingFiles)
+ {
+ using (var fileStream = File.OpenRead(sourceFile))
+ {
+ ExtractAllFromRar(fileStream, targetPath, overwriteExistingFiles);
+ }
+ }
+
+ /// <summary>
+ /// Extracts all from rar.
+ /// </summary>
+ /// <param name="source">The source.</param>
+ /// <param name="targetPath">The target path.</param>
+ /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
+ 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
/// <param name="imageEnhancers">The image enhancers.</param>
/// <returns>Guid.</returns>
Guid GetImageCacheTag(BaseItem item, ImageType imageType, string originalImagePath, DateTime dateModified,
- IEnumerable<IImageEnhancer> imageEnhancers);
+ List<IImageEnhancer> imageEnhancers);
/// <summary>
/// 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
@@ -384,6 +384,12 @@ namespace MediaBrowser.Model.Dto
public Guid? AlbumPrimaryImageTag { get; set; }
/// <summary>
+ /// Gets or sets the series primary image tag.
+ /// </summary>
+ /// <value>The series primary image tag.</value>
+ public Guid? SeriesPrimaryImageTag { get; set; }
+
+ /// <summary>
/// Gets or sets the album artist.
/// </summary>
/// <value>The album artist.</value>
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
/// </summary>
public string review { get; set; }
+ /// <summary>
+ /// Time of review
+ /// </summary>
+ 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
/// <param name="targetPath">The target path.</param>
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
void ExtractAllFromTar(Stream source, string targetPath, bool overwriteExistingFiles);
+
+ /// <summary>
+ /// Extracts all from rar.
+ /// </summary>
+ /// <param name="sourceFile">The source file.</param>
+ /// <param name="targetPath">The target path.</param>
+ /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
+ void ExtractAllFromRar(string sourceFile, string targetPath, bool overwriteExistingFiles);
+
+ /// <summary>
+ /// Extracts all from rar.
+ /// </summary>
+ /// <param name="source">The source.</param>
+ /// <param name="targetPath">The target path.</param>
+ /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
+ 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
@@ -118,12 +118,6 @@ namespace MediaBrowser.Model.Updates
public string guid { get; set; }
/// <summary>
- /// Gets or sets the total number of machines who have checked registration for this package (if premium).
- /// </summary>
- /// <value>The total hits.</value>
- public int totalHits { get; set; }
-
- /// <summary>
/// Gets or sets the total number of ratings for this package.
/// </summary>
/// <value>The total ratings.</value>
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());
}
/// <summary>
@@ -602,7 +602,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <param name="imageEnhancers">The image enhancers.</param>
/// <returns>Guid.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
- public Guid GetImageCacheTag(BaseItem item, ImageType imageType, string originalImagePath, DateTime dateModified, IEnumerable<IImageEnhancer> imageEnhancers)
+ public Guid GetImageCacheTag(BaseItem item, ImageType imageType, string originalImagePath, DateTime dateModified, List<IImageEnhancer> 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
index b9a085e01..b9a085e01 100644
--- a/MediaBrowser.Server.Implementations/Localization/Ratings/da.txt
+++ b/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 @@
<EmbeddedResource Include="Localization\Ratings\gb.txt" />
<EmbeddedResource Include="Localization\Ratings\nl.txt" />
<EmbeddedResource Include="Localization\Ratings\br.txt" />
- <EmbeddedResource Include="Localization\Ratings\da.txt" />
+ <EmbeddedResource Include="Localization\Ratings\dk.txt" />
<EmbeddedResource Include="Localization\Ratings\de.txt" />
<EmbeddedResource Include="Localization\Ratings\mx.txt" />
<EmbeddedResource Include="Localization\Ratings\co.txt" />
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
/// </summary>
private readonly IDirectoryWatchers _directoryWatchers;
private readonly IFileSystem _fileSystem;
+ private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="ImageSaver"/> class.
/// </summary>
/// <param name="config">The config.</param>
/// <param name="directoryWatchers">The directory watchers.</param>
- 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
/// <returns>Task.</returns>
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
/// <returns>Task.</returns>
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);
}
/// <summary>
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 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="MediaBrowser.ApiClient.Javascript" version="3.0.191" targetFramework="net45" />
+ <package id="MediaBrowser.ApiClient.Javascript" version="3.0.192" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
</packages> \ 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