diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs
index 9fc4bb3d04..a244b71df5 100644
--- a/MediaBrowser.Api/ItemUpdateService.cs
+++ b/MediaBrowser.Api/ItemUpdateService.cs
@@ -271,6 +271,16 @@ namespace MediaBrowser.Api
item.Overview = request.Overview;
item.Genres = request.Genres;
+ var episode = item as Episode;
+ if (episode != null)
+ {
+ episode.DvdSeasonNumber = request.DvdSeasonNumber;
+ episode.DvdEpisodeNumber = request.DvdEpisodeNumber;
+ episode.AirsAfterSeasonNumber = request.AirsAfterSeasonNumber;
+ episode.AirsBeforeEpisodeNumber = request.AirsBeforeEpisodeNumber;
+ episode.AirsBeforeSeasonNumber = request.AirsBeforeSeasonNumber;
+ }
+
var hasTags = item as IHasTags;
if (hasTags != null)
{
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index b1e0339fcb..f33db49790 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -38,14 +38,6 @@
Always
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
-
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Text.dll
-
@@ -56,6 +48,12 @@
..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
+
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Text.dll
+
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index 7d75cfd3db..0d35cb4da0 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -37,14 +37,6 @@
Always
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Text.dll
-
-
- False
- ..\packages\sharpcompress.0.10.2\lib\net40\SharpCompress.dll
-
@@ -58,6 +50,12 @@
..\packages\SimpleInjector.2.3.6\lib\net40-client\SimpleInjector.dll
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Text.dll
+
+
+ ..\packages\sharpcompress.0.10.2\lib\net40\SharpCompress.dll
+
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index e7593b075e..1d38b37281 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -1359,13 +1359,24 @@ namespace MediaBrowser.Controller.Entities
Logger.ErrorException("Error getting ResolveArgs for {0}", ex, Path);
}
- //this should be functionally equivilent to what was here since it is IEnum and works on a thread-safe copy
return RecursiveChildren.Where(i => i.LocationType != LocationType.Virtual).FirstOrDefault(i =>
{
try
{
- return string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase)
- || i.ResolveArgs.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase);
+ if (string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ if (i.LocationType != LocationType.Remote)
+ {
+ if (i.ResolveArgs.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ return false;
}
catch (IOException ex)
{
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index e9f250d2a4..f24d86408e 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -40,6 +40,17 @@ namespace MediaBrowser.Controller.Entities.TV
public int? AirsAfterSeasonNumber { get; set; }
public int? AirsBeforeEpisodeNumber { get; set; }
+ ///
+ /// Gets or sets the DVD season number.
+ ///
+ /// The DVD season number.
+ public int? DvdSeasonNumber { get; set; }
+ ///
+ /// Gets or sets the DVD episode number.
+ ///
+ /// The DVD episode number.
+ public float? DvdEpisodeNumber { get; set; }
+
///
/// We want to group into series not show individually in an index
///
diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
index e296e0f182..c34180eb61 100644
--- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs
+++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
@@ -130,7 +130,7 @@ namespace MediaBrowser.Controller.Library
{
get
{
- return IsDirectory && Path.Equals(_appPaths.RootFolderPath, StringComparison.OrdinalIgnoreCase);
+ return IsDirectory && string.Equals(Path, _appPaths.RootFolderPath, StringComparison.OrdinalIgnoreCase);
}
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index f1f2aaf5ef..8d03f84807 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -58,10 +58,6 @@
4
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
-
@@ -74,6 +70,9 @@
..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
+
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index 20f60586c1..3bdbf2ae67 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -30,11 +30,20 @@ namespace MediaBrowser.Model.Dto
/// The date created.
public DateTime? DateCreated { get; set; }
+ public int? AirsBeforeSeasonNumber { get; set; }
+ public int? AirsAfterSeasonNumber { get; set; }
+ public int? AirsBeforeEpisodeNumber { get; set; }
+
+ ///
+ /// Gets or sets the DVD season number.
+ ///
+ /// The DVD season number.
+ public int? DvdSeasonNumber { get; set; }
///
- /// Gets or sets the special season number.
+ /// Gets or sets the DVD episode number.
///
- /// The special season number.
- public int? SpecialSeasonNumber { get; set; }
+ /// The DVD episode number.
+ public float? DvdEpisodeNumber { get; set; }
///
/// Gets or sets the name of the sort.
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index 6a17ad133a..ade4e96fdf 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -110,6 +110,12 @@ namespace MediaBrowser.Model.System
/// The HTTP server port number.
public int HttpServerPortNumber { get; set; }
+ ///
+ /// Gets or sets the wan address.
+ ///
+ /// The wan address.
+ public string WanAddress { get; set; }
+
///
/// Initializes a new instance of the class.
///
diff --git a/MediaBrowser.Mono.sln b/MediaBrowser.Mono.sln
index 397763489a..bfd30573ec 100644
--- a/MediaBrowser.Mono.sln
+++ b/MediaBrowser.Mono.sln
@@ -36,8 +36,8 @@ Global
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.Build.0 = Debug|x86
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.Build.0 = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|x86
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.Build.0 = Release|x86
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.Build.0 = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -82,6 +82,6 @@ Global
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
- StartupItem = MediaBrowser.Model\MediaBrowser.Model.csproj
+ StartupItem = MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj
EndGlobalSection
EndGlobal
diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs
index 51ba9d804b..d07dfa4cbf 100644
--- a/MediaBrowser.Mono.userprefs
+++ b/MediaBrowser.Mono.userprefs
@@ -1,13 +1,29 @@
-
-
+
+
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -21,6 +37,7 @@
+
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
index e483b1d61e..952d7e218e 100644
--- a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
@@ -325,6 +325,7 @@ namespace MediaBrowser.Providers.Movies
{
continue;
}
+ break;
}
}
}
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPrescanTask.cs b/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPrescanTask.cs
index aff71c6dbb..9bd73bf656 100644
--- a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPrescanTask.cs
+++ b/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPrescanTask.cs
@@ -16,7 +16,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Movies
{
- class FanArtMovieUpdatesPrescanTask : ILibraryPrescanTask
+ class FanArtMovieUpdatesPrescanTask : ILibraryPostScanTask
{
private const string UpdatesUrl = "http://api.fanart.tv/webservice/newmovies/{0}/{1}/";
diff --git a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
index f8fb133c60..46e947c70c 100644
--- a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
+++ b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
@@ -16,7 +16,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Movies
{
- public class MovieUpdatesPreScanTask : ILibraryPrescanTask
+ public class MovieUpdatesPreScanTask : ILibraryPostScanTask
{
///
/// The updates URL
diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
index 161c96a5dd..2e072b0983 100644
--- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
@@ -203,6 +203,7 @@ namespace MediaBrowser.Providers.Music
{
continue;
}
+ break;
}
}
}
diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
index 4830d15b17..57a191ab13 100644
--- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
@@ -328,6 +328,7 @@ namespace MediaBrowser.Providers.Music
{
continue;
}
+ break;
}
}
}
diff --git a/MediaBrowser.Providers/Music/FanArtUpdatesPrescanTask.cs b/MediaBrowser.Providers/Music/FanArtUpdatesPrescanTask.cs
index ddf2121792..a3d0deb0e0 100644
--- a/MediaBrowser.Providers/Music/FanArtUpdatesPrescanTask.cs
+++ b/MediaBrowser.Providers/Music/FanArtUpdatesPrescanTask.cs
@@ -15,7 +15,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Music
{
- class FanArtUpdatesPrescanTask : ILibraryPrescanTask
+ class FanArtUpdatesPrescanTask : ILibraryPostScanTask
{
private const string UpdatesUrl = "http://api.fanart.tv/webservice/newmusic/{0}/{1}/";
diff --git a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
index 35dd551f13..88b3af5be0 100644
--- a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
@@ -92,6 +92,16 @@ namespace MediaBrowser.Providers.Savers
builder.Append("" + SecurityElement.Escape(episode.ParentIndexNumber.Value.ToString(_usCulture)) + "");
}
+ if (episode.DvdEpisodeNumber.HasValue)
+ {
+ builder.Append("" + SecurityElement.Escape(episode.DvdEpisodeNumber.Value.ToString(_usCulture)) + "");
+ }
+
+ if (episode.DvdSeasonNumber.HasValue)
+ {
+ builder.Append("" + SecurityElement.Escape(episode.DvdSeasonNumber.Value.ToString(_usCulture)) + "");
+ }
+
if (episode.PremiereDate.HasValue)
{
builder.Append("" + SecurityElement.Escape(episode.PremiereDate.Value.ToString("yyyy-MM-dd")) + "");
@@ -113,7 +123,9 @@ namespace MediaBrowser.Providers.Savers
"EpisodeNumberEnd",
"airsafter_season",
"airsbefore_episode",
- "airsbefore_season"
+ "airsbefore_season",
+ "DVD_episodenumber",
+ "DVD_season"
});
}
diff --git a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs
index 5d970107e4..a06a3bf23b 100644
--- a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs
+++ b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Entities.TV;
+using System;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
@@ -40,7 +41,7 @@ namespace MediaBrowser.Providers.TV
}
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
+
///
/// Fetches the data from XML node.
///
@@ -142,6 +143,38 @@ namespace MediaBrowser.Providers.TV
break;
}
+ case "DVD_episodenumber":
+ {
+ var number = reader.ReadElementContentAsString();
+
+ if (!string.IsNullOrWhiteSpace(number))
+ {
+ float num;
+
+ if (float.TryParse(number, NumberStyles.Any, UsCulture, out num))
+ {
+ item.DvdEpisodeNumber = num;
+ }
+ }
+ break;
+ }
+
+ case "DVD_season":
+ {
+ var number = reader.ReadElementContentAsString();
+
+ if (!string.IsNullOrWhiteSpace(number))
+ {
+ float num;
+
+ if (float.TryParse(number, NumberStyles.Any, UsCulture, out num))
+ {
+ item.DvdSeasonNumber = Convert.ToInt32(num);
+ }
+ }
+ break;
+ }
+
case "airsbefore_episode":
{
var val = reader.ReadElementContentAsString();
diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
index ed5145bc25..713a95b26c 100644
--- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
@@ -143,6 +143,7 @@ namespace MediaBrowser.Providers.TV
{
continue;
}
+ break;
}
}
}
diff --git a/MediaBrowser.Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
index 251420261c..90af81ec37 100644
--- a/MediaBrowser.Providers/TV/FanArtTVProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
@@ -264,6 +264,7 @@ namespace MediaBrowser.Providers.TV
{
continue;
}
+ break;
}
}
}
diff --git a/MediaBrowser.Providers/TV/FanArtTvUpdatesPrescanTask.cs b/MediaBrowser.Providers/TV/FanArtTvUpdatesPrescanTask.cs
index 8ef04ed118..46137a2110 100644
--- a/MediaBrowser.Providers/TV/FanArtTvUpdatesPrescanTask.cs
+++ b/MediaBrowser.Providers/TV/FanArtTvUpdatesPrescanTask.cs
@@ -16,7 +16,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.TV
{
- class FanArtTvUpdatesPrescanTask : ILibraryPrescanTask
+ class FanArtTvUpdatesPrescanTask : ILibraryPostScanTask
{
private const string UpdatesUrl = "http://api.fanart.tv/webservice/newtv/{0}/{1}/";
diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
index 5d9f387fea..b7709b5d35 100644
--- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
@@ -404,6 +404,40 @@ namespace MediaBrowser.Providers.TV
break;
}
+ case "DVD_episodenumber":
+ {
+ var val = reader.ReadElementContentAsString();
+
+ if (!string.IsNullOrWhiteSpace(val))
+ {
+ float num;
+
+ if (float.TryParse(val, NumberStyles.Any, _usCulture, out num))
+ {
+ item.DvdEpisodeNumber = num;
+ }
+ }
+
+ break;
+ }
+
+ case "DVD_season":
+ {
+ var val = reader.ReadElementContentAsString();
+
+ if (!string.IsNullOrWhiteSpace(val))
+ {
+ float num;
+
+ if (float.TryParse(val, NumberStyles.Any, _usCulture, out num))
+ {
+ item.DvdSeasonNumber = Convert.ToInt32(num);
+ }
+ }
+
+ break;
+ }
+
case "airsbefore_episode":
{
var val = reader.ReadElementContentAsString();
diff --git a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs
index cdfe86dac7..c5e5327c33 100644
--- a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.IO;
+using System.Net;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
@@ -6,6 +7,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic;
@@ -159,24 +161,12 @@ namespace MediaBrowser.Providers.TV
{
if (!item.HasImage(ImageType.Primary))
{
- var image = images.FirstOrDefault(i => i.Type == ImageType.Primary);
-
- if (image != null)
- {
- await _providerManager.SaveImage(item, image.Url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Primary, null, cancellationToken)
- .ConfigureAwait(false);
- }
+ await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
}
if (ConfigurationManager.Configuration.DownloadSeasonImages.Banner && !item.HasImage(ImageType.Banner))
{
- var image = images.FirstOrDefault(i => i.Type == ImageType.Banner);
-
- if (image != null)
- {
- await _providerManager.SaveImage(item, image.Url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Banner, null, cancellationToken)
- .ConfigureAwait(false);
- }
+ await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false);
}
if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
@@ -196,5 +186,26 @@ namespace MediaBrowser.Providers.TV
}
}
}
+
+ private async Task SaveImage(BaseItem item, List images, ImageType type, CancellationToken cancellationToken)
+ {
+ foreach (var image in images.Where(i => i.Type == type))
+ {
+ try
+ {
+ await _providerManager.SaveImage(item, image.Url, TvdbSeriesProvider.Current.TvDbResourcePool, type, null, cancellationToken).ConfigureAwait(false);
+ break;
+ }
+ catch (HttpException ex)
+ {
+ // Sometimes fanart has bad url's in their xml
+ if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
+ {
+ continue;
+ }
+ break;
+ }
+ }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index ba9dd170df..6e8c9d3ebe 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -1061,7 +1061,12 @@ namespace MediaBrowser.Server.Implementations.Dto
if (episode != null)
{
dto.IndexNumberEnd = episode.IndexNumberEnd;
- dto.SpecialSeasonNumber = episode.AirsAfterSeasonNumber ?? episode.AirsBeforeSeasonNumber;
+
+ dto.DvdSeasonNumber = episode.DvdSeasonNumber;
+ dto.DvdEpisodeNumber = episode.DvdEpisodeNumber;
+ dto.AirsAfterSeasonNumber = episode.AirsAfterSeasonNumber;
+ dto.AirsBeforeEpisodeNumber = episode.AirsBeforeEpisodeNumber;
+ dto.AirsBeforeSeasonNumber = episode.AirsBeforeSeasonNumber;
var seasonId = episode.SeasonId;
if (seasonId.HasValue)
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
index 29dce67476..5e4c6f0aaf 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -63,8 +63,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
_logger = logManager.GetLogger("HttpServer");
- LogManager.LogFactory = new ServerLogFactory(logManager);
-
_containerAdapter = new ContainerAdapter(applicationHost);
for (var i = 0; i < 2; i++)
@@ -477,7 +475,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
ServiceController = CreateServiceController();
_logger.Info("Calling ServiceStack AppHost.Init");
- Init();
+
+ base.Init();
}
///
diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs
index 57acddc432..c403c09b44 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Logging;
+using ServiceStack.Logging;
namespace MediaBrowser.Server.Implementations.HttpServer
{
@@ -20,6 +21,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// IHttpServer.
public static IHttpServer CreateServer(IApplicationHost applicationHost, ILogManager logManager, string serverName, string handlerPath, string defaultRedirectpath)
{
+ LogManager.LogFactory = new ServerLogFactory(logManager);
+
return new HttpListenerHost(applicationHost, logManager, serverName, handlerPath, defaultRedirectpath);
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 03e29dd38f..e335f4ad5d 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -116,6 +116,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return null;
}
+ var filename = Path.GetFileName(args.Path);
+ // Don't misidentify xbmc trailers as a movie
+ if (filename.IndexOf(BaseItem.XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ return null;
+ }
+
// Find movies that are mixed in the same folder
if (args.Path.IndexOf("[trailers]", StringComparison.OrdinalIgnoreCase) != -1 ||
string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase))
diff --git a/MediaBrowser.Server.Implementations/Localization/Ratings/de.txt b/MediaBrowser.Server.Implementations/Localization/Ratings/de.txt
index 571b6eba95..e1c3639cb4 100644
--- a/MediaBrowser.Server.Implementations/Localization/Ratings/de.txt
+++ b/MediaBrowser.Server.Implementations/Localization/Ratings/de.txt
@@ -2,4 +2,5 @@ DE-FSK0,1
DE-FSK6+,5
DE-FSK12+,7
DE-FSK16+,8
+DE-16,8
DE-FSK18+,9
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 39966f0d7a..70b173fd9f 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -37,25 +37,8 @@
..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.dll
-
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Client.dll
-
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Common.dll
-
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
-
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Text.dll
+
+ ..\ThirdParty\Mono.Data.Sqlite\Mono.Data.Sqlite.dll
@@ -73,6 +56,21 @@
..\packages\System.Data.SQLite.x86.1.0.89.0\lib\net45\System.Data.SQLite.dll
+
+ ..\ThirdParty\ServiceStack\ServiceStack.dll
+
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Client.dll
+
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Common.dll
+
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
+
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Text.dll
+
@@ -169,6 +167,7 @@
+
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs
index 075ef42398..5842b05a34 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs
@@ -32,6 +32,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
_logger = logManager.GetLogger(GetType().Name);
}
+ private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
+
///
/// Opens the connection to the database
///
@@ -52,6 +54,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.RunQueries(queries, _logger);
PrepareStatements();
+
+ _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
}
///
@@ -282,6 +286,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
lock (_disposeLock)
{
+ if (_shrinkMemoryTimer != null)
+ {
+ _shrinkMemoryTimer.Dispose();
+ _shrinkMemoryTimer = null;
+ }
+
if (_connection != null)
{
if (_connection.IsOpen())
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
index 5d836b090d..9971c74605 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
@@ -25,6 +25,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
_logger = logManager.GetLogger(GetType().Name);
}
+ private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
+
///
/// Opens the connection to the database
///
@@ -50,6 +52,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.RunQueries(queries, _logger);
PrepareStatements();
+
+ _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
}
private static readonly string[] SaveColumns =
@@ -240,6 +244,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
lock (_disposeLock)
{
+ if (_shrinkMemoryTimer != null)
+ {
+ _shrinkMemoryTimer.Dispose();
+ _shrinkMemoryTimer = null;
+ }
+
if (_connection != null)
{
if (_connection.IsOpen())
diff --git a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs
index 76971342a0..d6b78bd84b 100644
--- a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs
@@ -62,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
return CompareEpisodes(x, y);
}
- if (!isXSpecial && isYSpecial)
+ if (!isXSpecial)
{
return CompareEpisodeToSpecial(x, y);
}
@@ -87,8 +87,17 @@ namespace MediaBrowser.Server.Implementations.Sorting
// Add 1 to to non-specials to account for AirsBeforeEpisodeNumber
var xEpisode = x.IndexNumber ?? -1;
xEpisode++;
+
var yEpisode = y.AirsBeforeEpisodeNumber ?? 10000;
+ // Sometimes they'll both have a value.
+ // For example AirsAfterSeasonNumber=1, AirsBeforeSeasonNumber=2, AirsBeforeEpisodeNumber=1
+ // The episode should be displayed at the end of season 1
+ if (y.AirsAfterSeasonNumber.HasValue && y.AirsBeforeSeasonNumber.HasValue && y.AirsBeforeSeasonNumber.Value > y.AirsAfterSeasonNumber.Value)
+ {
+ yEpisode = 10000;
+ }
+
return xEpisode.CompareTo(yEpisode);
}
diff --git a/MediaBrowser.Server.Implementations/Sorting/AlphanumComparator.cs b/MediaBrowser.Server.Implementations/Sorting/AlphanumComparator.cs
new file mode 100644
index 0000000000..3fbb01f779
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Sorting/AlphanumComparator.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.Sorting
+{
+ public class AlphanumComparator : IComparer
+ {
+ private enum ChunkType { Alphanumeric, Numeric };
+
+ private static bool InChunk(char ch, char otherCh)
+ {
+ var type = ChunkType.Alphanumeric;
+
+ if (char.IsDigit(otherCh))
+ {
+ type = ChunkType.Numeric;
+ }
+
+ if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
+ || (type == ChunkType.Numeric && !char.IsDigit(ch)))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static int CompareValues(string s1, string s2)
+ {
+ if (s1 == null || s2 == null)
+ {
+ return 0;
+ }
+
+ int thisMarker = 0, thisNumericChunk = 0;
+ int thatMarker = 0, thatNumericChunk = 0;
+
+ while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
+ {
+ if (thisMarker >= s1.Length)
+ {
+ return -1;
+ }
+ else if (thatMarker >= s2.Length)
+ {
+ return 1;
+ }
+ char thisCh = s1[thisMarker];
+ char thatCh = s2[thatMarker];
+
+ StringBuilder thisChunk = new StringBuilder();
+ StringBuilder thatChunk = new StringBuilder();
+
+ while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || InChunk(thisCh, thisChunk[0])))
+ {
+ thisChunk.Append(thisCh);
+ thisMarker++;
+
+ if (thisMarker < s1.Length)
+ {
+ thisCh = s1[thisMarker];
+ }
+ }
+
+ while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || InChunk(thatCh, thatChunk[0])))
+ {
+ thatChunk.Append(thatCh);
+ thatMarker++;
+
+ if (thatMarker < s2.Length)
+ {
+ thatCh = s2[thatMarker];
+ }
+ }
+
+ int result = 0;
+ // If both chunks contain numeric characters, sort them numerically
+ if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
+ {
+ thisNumericChunk = Convert.ToInt32(thisChunk.ToString());
+ thatNumericChunk = Convert.ToInt32(thatChunk.ToString());
+
+ if (thisNumericChunk < thatNumericChunk)
+ {
+ result = -1;
+ }
+
+ if (thisNumericChunk > thatNumericChunk)
+ {
+ result = 1;
+ }
+ }
+ else
+ {
+ result = thisChunk.ToString().CompareTo(thatChunk.ToString());
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return 0;
+ }
+
+ public int Compare(string x, string y)
+ {
+ return CompareValues(x, y);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Sorting/NameComparer.cs b/MediaBrowser.Server.Implementations/Sorting/NameComparer.cs
index 49f86c485a..83b1b2d16f 100644
--- a/MediaBrowser.Server.Implementations/Sorting/NameComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/NameComparer.cs
@@ -1,7 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Querying;
-using System;
namespace MediaBrowser.Server.Implementations.Sorting
{
@@ -18,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
/// System.Int32.
public int Compare(BaseItem x, BaseItem y)
{
- return string.Compare(x.Name, y.Name, StringComparison.CurrentCultureIgnoreCase);
+ return AlphanumComparator.CompareValues(x.Name, y.Name);
}
///
diff --git a/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs b/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs
index 4efc3218b2..09612a49c9 100644
--- a/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs
@@ -16,7 +16,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
/// System.Int32.
public int Compare(BaseItem x, BaseItem y)
{
- return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
+ return AlphanumComparator.CompareValues(GetValue(x), GetValue(y));
}
private string GetValue(BaseItem item)
diff --git a/MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs b/MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs
index 873753a2b2..e635cfbe52 100644
--- a/MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs
@@ -1,7 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Querying;
-using System;
namespace MediaBrowser.Server.Implementations.Sorting
{
@@ -18,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
/// System.Int32.
public int Compare(BaseItem x, BaseItem y)
{
- return string.Compare(x.SortName, y.SortName, StringComparison.CurrentCultureIgnoreCase);
+ return AlphanumComparator.CompareValues(x.SortName, y.SortName);
}
///
diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
index be7fb7b278..8d59a9a141 100644
--- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
+++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
@@ -39,11 +39,8 @@
-
- ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Common.dll
-
- ..\packages\ServiceStack.Common.3.9.70\lib\net35\ServiceStack.Interfaces.dll
+ ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
@@ -74,6 +71,9 @@
+
+ EntryPoints\WanAddressEntryPoint.cs
+
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 6058c59581..46a7430b02 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -28,7 +28,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
-using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Updates;
using MediaBrowser.Providers;
@@ -49,6 +48,7 @@ using MediaBrowser.Server.Implementations.Providers;
using MediaBrowser.Server.Implementations.ServerManager;
using MediaBrowser.Server.Implementations.Session;
using MediaBrowser.Server.Implementations.WebSocket;
+using MediaBrowser.ServerApplication.EntryPoints;
using MediaBrowser.ServerApplication.FFMpeg;
using MediaBrowser.ServerApplication.IO;
using MediaBrowser.ServerApplication.Native;
@@ -616,7 +616,8 @@ namespace MediaBrowser.ServerApplication
HttpServerPortNumber = ServerConfigurationManager.Configuration.HttpServerPortNumber,
OperatingSystem = Environment.OSVersion.ToString(),
CanSelfRestart = CanSelfRestart,
- CanSelfUpdate = CanSelfUpdate
+ CanSelfUpdate = CanSelfUpdate,
+ WanAddress = WanAddressEntryPoint.WanAddress
};
}
diff --git a/MediaBrowser.ServerApplication/EntryPoints/WanAddressEntryPoint.cs b/MediaBrowser.ServerApplication/EntryPoints/WanAddressEntryPoint.cs
new file mode 100644
index 0000000000..44819b3903
--- /dev/null
+++ b/MediaBrowser.ServerApplication/EntryPoints/WanAddressEntryPoint.cs
@@ -0,0 +1,56 @@
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Plugins;
+using System;
+using System.IO;
+using System.Threading;
+
+namespace MediaBrowser.ServerApplication.EntryPoints
+{
+ public class WanAddressEntryPoint : IServerEntryPoint
+ {
+ public static string WanAddress;
+ private Timer _timer;
+ private readonly IHttpClient _httpClient;
+
+ public WanAddressEntryPoint(IHttpClient httpClient)
+ {
+ _httpClient = httpClient;
+ }
+
+ public void Run()
+ {
+ _timer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(1), TimeSpan.FromHours(24));
+ }
+
+ private async void TimerCallback(object state)
+ {
+ try
+ {
+ using (var stream = await _httpClient.Get(new HttpRequestOptions
+ {
+ Url = "http://bot.whatismyipaddress.com/"
+
+ }).ConfigureAwait(false))
+ {
+ using (var reader = new StreamReader(stream))
+ {
+ WanAddress = await reader.ReadToEndAsync().ConfigureAwait(false);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ var b = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ if (_timer != null)
+ {
+ _timer.Dispose();
+ _timer = null;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs
index a3d4706893..c133e09571 100644
--- a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs
+++ b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs
@@ -88,7 +88,7 @@ namespace MediaBrowser.ServerApplication
Cursor = Cursors.Wait;
await Task.Run(() =>
{
- IEnumerable children = CurrentUser.Name == "Physical" ? _libraryManager.RootFolder.Children : _libraryManager.RootFolder.GetChildren(CurrentUser, true);
+ IEnumerable children = CurrentUser.Name == "Physical" ? new[] { _libraryManager.RootFolder } : _libraryManager.RootFolder.GetChildren(CurrentUser, true);
children = OrderByName(children, CurrentUser);
foreach (Folder folder in children)
@@ -237,9 +237,9 @@ namespace MediaBrowser.ServerApplication
{
previews.Add(new PreviewItem(item.GetImage(ImageType.Thumb), "Thumb"));
}
- previews.AddRange(
- item.BackdropImagePaths.Select(
- image => new PreviewItem(image, "Backdrop")));
+ previews.AddRange(
+ item.BackdropImagePaths.Select(
+ image => new PreviewItem(image, "Backdrop")));
});
lstPreviews.ItemsSource = previews;
lstPreviews.Items.Refresh();
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index e02bb1d69a..38e082f12e 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -162,6 +162,7 @@
+
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 35ed3f1e26..9d2b42c85d 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -37,16 +37,15 @@
Always
-
- False
- ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
-
+
+ ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll
+