diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-10-24 13:49:24 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-10-24 13:49:24 -0400 |
| commit | 146c7ac4bf58059771d1da24ab3a60a76d35ba2d (patch) | |
| tree | 906ed3e777b0dd62f629f20c9bce7d51c7bfa40e | |
| parent | a09d449c003c0c828a877fd75eceaefc66e835b5 (diff) | |
fix double path concatenation
| -rw-r--r-- | MediaBrowser.Model/ApiClient/IApiClient.cs | 8 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dto/BaseItemDto.cs | 24 | ||||
| -rw-r--r-- | MediaBrowser.Model/Querying/ItemSortBy.cs | 1 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Movies/MovieDbProvider.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/RemoteSeriesProvider.cs | 20 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/SeriesPostScanTask.cs | 135 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Dto/DtoService.cs | 22 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj | 1 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Sorting/AirTimeComparer.cs | 48 | ||||
| -rw-r--r-- | MediaBrowser.WebDashboard/Api/DashboardService.cs | 1 | ||||
| -rw-r--r-- | MediaBrowser.WebDashboard/ApiClient.js | 19 | ||||
| -rw-r--r-- | MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 | ||||
| -rw-r--r-- | MediaBrowser.WebDashboard/packages.config | 2 |
13 files changed, 247 insertions, 42 deletions
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 21894819d..3f66f195e 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -860,6 +860,14 @@ namespace MediaBrowser.Model.ApiClient string GetArtImageUrl(BaseItemDto item, ImageOptions options); /// <summary> + /// Gets the thumb image URL. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="options">The options.</param> + /// <returns>System.String.</returns> + string GetThumbImageUrl(BaseItemDto item, ImageOptions options); + + /// <summary> /// Gets the url needed to stream an audio file /// </summary> /// <param name="options">The options.</param> diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 22280f6ba..501095f24 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -468,6 +468,30 @@ namespace MediaBrowser.Model.Dto /// </summary> /// <value>The parent art image tag.</value> public Guid? ParentArtImageTag { get; set; } + + /// <summary> + /// Gets or sets the series thumb image tag. + /// </summary> + /// <value>The series thumb image tag.</value> + public Guid? SeriesThumbImageTag { get; set; } + + /// <summary> + /// Gets or sets the series studio. + /// </summary> + /// <value>The series studio.</value> + public string SeriesStudio { get; set; } + + /// <summary> + /// Gets or sets the parent thumb item id. + /// </summary> + /// <value>The parent thumb item id.</value> + public string ParentThumbItemId { get; set; } + + /// <summary> + /// Gets or sets the parent thumb image tag. + /// </summary> + /// <value>The parent thumb image tag.</value> + public Guid? ParentThumbImageTag { get; set; } /// <summary> /// Gets or sets the chapters. diff --git a/MediaBrowser.Model/Querying/ItemSortBy.cs b/MediaBrowser.Model/Querying/ItemSortBy.cs index f2c9ece32..12dfa9626 100644 --- a/MediaBrowser.Model/Querying/ItemSortBy.cs +++ b/MediaBrowser.Model/Querying/ItemSortBy.cs @@ -83,5 +83,6 @@ namespace MediaBrowser.Model.Querying public const string MusicVideoCount = "MusicVideoCount"; public const string SeriesSortName = "SeriesSortName"; public const string VideoBitRate = "VideoBitRate"; + public const string AirTime = "AirTime"; } } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 92759e013..9ed0860b2 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -386,7 +386,7 @@ namespace MediaBrowser.Providers.Movies name = name.Replace(",", " "); name = name.Replace(".", " "); name = name.Replace("_", " "); - name = name.Replace("-", ""); + name = name.Replace("-", " "); // Search again if the new name is different if (!string.Equals(name, originalName)) diff --git a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs index d639c6743..322fcd228 100644 --- a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs @@ -295,6 +295,9 @@ namespace MediaBrowser.Providers.TV }).ConfigureAwait(false)) { + // Delete existing files + DeleteXmlFiles(seriesDataPath); + // Copy to memory stream because we need a seekable stream using (var ms = new MemoryStream()) { @@ -315,6 +318,23 @@ namespace MediaBrowser.Providers.TV await ExtractEpisodes(seriesDataPath, Path.Combine(seriesDataPath, ConfigurationManager.Configuration.PreferredMetadataLanguage + ".xml"), lastTvDbUpdateTime).ConfigureAwait(false); } + private void DeleteXmlFiles(string path) + { + try + { + foreach (var file in new DirectoryInfo(path) + .EnumerateFiles("*.xml", SearchOption.AllDirectories) + .ToList()) + { + file.Delete(); + } + } + catch (DirectoryNotFoundException) + { + // No biggie + } + } + /// <summary> /// Sanitizes the XML file. /// </summary> diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index 51b38f4cb..d35e5e9d8 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; @@ -25,13 +24,11 @@ namespace MediaBrowser.Providers.TV private readonly ILibraryManager _libraryManager; private readonly IServerConfigurationManager _config; private readonly ILogger _logger; - private readonly IDirectoryWatchers _directoryWatchers; - public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IDirectoryWatchers directoryWatchers, IServerConfigurationManager config) + public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config) { _libraryManager = libraryManager; _logger = logger; - _directoryWatchers = directoryWatchers; _config = config; } @@ -53,7 +50,7 @@ namespace MediaBrowser.Providers.TV { cancellationToken.ThrowIfCancellationRequested(); - await new MissingEpisodeProvider(_logger, _directoryWatchers, _config).Run(series, cancellationToken).ConfigureAwait(false); + await new MissingEpisodeProvider(_logger, _config).Run(series, cancellationToken).ConfigureAwait(false); var episodes = series.RecursiveChildren .OfType<Episode>() @@ -88,14 +85,12 @@ namespace MediaBrowser.Providers.TV { private readonly IServerConfigurationManager _config; private readonly ILogger _logger; - private readonly IDirectoryWatchers _directoryWatchers; private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public MissingEpisodeProvider(ILogger logger, IDirectoryWatchers directoryWatchers, IServerConfigurationManager config) + public MissingEpisodeProvider(ILogger logger, IServerConfigurationManager config) { _logger = logger; - _directoryWatchers = directoryWatchers; _config = config; } @@ -141,19 +136,21 @@ namespace MediaBrowser.Providers.TV .Where(i => i.Item1 != -1 && i.Item2 != -1) .ToList(); - var hasChanges = false; + var anySeasonsRemoved = await RemoveObsoleteOrMissingSeasons(series, episodeLookup, cancellationToken).ConfigureAwait(false); + + var anyEpisodesRemoved = await RemoveObsoleteOrMissingEpisodes(series, episodeLookup, cancellationToken).ConfigureAwait(false); + + var hasNewEpisodes = false; if (_config.Configuration.CreateVirtualMissingEpisodes || _config.Configuration.CreateVirtualFutureEpisodes) { if (_config.Configuration.EnableInternetProviders) { - hasChanges = await AddMissingEpisodes(series, seriesDataPath, episodeLookup, cancellationToken).ConfigureAwait(false); + hasNewEpisodes = await AddMissingEpisodes(series, seriesDataPath, episodeLookup, cancellationToken).ConfigureAwait(false); } } - var anyRemoved = await RemoveObsoleteMissingEpisodes(series, cancellationToken).ConfigureAwait(false); - - if (hasChanges || anyRemoved) + if (hasNewEpisodes || anySeasonsRemoved || anyEpisodesRemoved) { await series.RefreshMetadata(cancellationToken, true).ConfigureAwait(false); await series.ValidateChildren(new Progress<double>(), cancellationToken, true).ConfigureAwait(false); @@ -231,7 +228,7 @@ namespace MediaBrowser.Providers.TV /// <summary> /// Removes the virtual entry after a corresponding physical version has been added /// </summary> - private async Task<bool> RemoveObsoleteMissingEpisodes(Series series, CancellationToken cancellationToken) + private async Task<bool> RemoveObsoleteOrMissingEpisodes(Series series, IEnumerable<Tuple<int, int>> episodeLookup, CancellationToken cancellationToken) { var existingEpisodes = series.RecursiveChildren .OfType<Episode>() @@ -250,10 +247,27 @@ namespace MediaBrowser.Providers.TV { if (i.IndexNumber.HasValue && i.ParentIndexNumber.HasValue) { - return physicalEpisodes.Any(p => p.ParentIndexNumber.HasValue && p.ParentIndexNumber.Value == i.ParentIndexNumber.Value && p.ContainsEpisodeNumber(i.IndexNumber.Value)); + var seasonNumber = i.ParentIndexNumber.Value; + var episodeNumber = i.IndexNumber.Value; + + // If there's a physical episode with the same season and episode number, delete it + if (physicalEpisodes.Any(p => + p.ParentIndexNumber.HasValue && p.ParentIndexNumber.Value == seasonNumber && + p.ContainsEpisodeNumber(episodeNumber))) + { + return true; + } + + // If the episode no longer exists in the remote lookup, delete it + if (!episodeLookup.Any(e => e.Item1 == seasonNumber && e.Item2 == episodeNumber)) + { + return true; + } + + return false; } - return false; + return true; }) .ToList(); @@ -261,7 +275,7 @@ namespace MediaBrowser.Providers.TV foreach (var episodeToRemove in episodesToRemove) { - _logger.Info("Removing {0} {1}x{2}", series.Name, episodeToRemove.ParentIndexNumber, episodeToRemove.IndexNumber); + _logger.Info("Removing missing/unaired episode {0} {1}x{2}", series.Name, episodeToRemove.ParentIndexNumber, episodeToRemove.IndexNumber); await episodeToRemove.Parent.RemoveChild(episodeToRemove, cancellationToken).ConfigureAwait(false); @@ -272,6 +286,67 @@ namespace MediaBrowser.Providers.TV } /// <summary> + /// Removes the obsolete or missing seasons. + /// </summary> + /// <param name="series">The series.</param> + /// <param name="episodeLookup">The episode lookup.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{System.Boolean}.</returns> + private async Task<bool> RemoveObsoleteOrMissingSeasons(Series series, IEnumerable<Tuple<int, int>> episodeLookup, CancellationToken cancellationToken) + { + var existingSeasons = series.Children + .OfType<Season>() + .ToList(); + + var physicalSeasons = existingSeasons + .Where(i => i.LocationType != LocationType.Virtual) + .ToList(); + + var virtualSeasons = existingSeasons + .Where(i => i.LocationType == LocationType.Virtual) + .ToList(); + + var seasonsToRemove = virtualSeasons + .Where(i => + { + if (i.IndexNumber.HasValue) + { + var seasonNumber = i.IndexNumber.Value; + + // If there's a physical season with the same number, delete it + if (physicalSeasons.Any(p => p.IndexNumber.HasValue && p.IndexNumber.Value == seasonNumber)) + { + return true; + } + + // If the season no longer exists in the remote lookup, delete it + if (episodeLookup.All(e => e.Item1 != seasonNumber)) + { + return true; + } + + return false; + } + + return true; + }) + .ToList(); + + var hasChanges = false; + + foreach (var seasonToRemove in seasonsToRemove) + { + _logger.Info("Removing virtual season {0} {1}", series.Name, seasonToRemove.IndexNumber); + + await seasonToRemove.Parent.RemoveChild(seasonToRemove, cancellationToken).ConfigureAwait(false); + + hasChanges = true; + } + + return hasChanges; + } + + /// <summary> /// Adds the episode. /// </summary> /// <param name="series">The series.</param> @@ -319,35 +394,17 @@ namespace MediaBrowser.Providers.TV var name = string.Format("Season {0}", seasonNumber.ToString(UsCulture)); - var path = Path.Combine(series.Path, name); - var season = new Season { Name = name, IndexNumber = seasonNumber, - Path = path, Parent = series, - DisplayMediaType = typeof(Season).Name + DisplayMediaType = typeof(Season).Name, + Id = (series.Id + seasonNumber.ToString(UsCulture) + name).GetMBId(typeof(Season)) }; - _directoryWatchers.TemporarilyIgnore(path); - - try - { - var info = Directory.CreateDirectory(path); - - season.DateCreated = info.CreationTimeUtc; - season.DateModified = info.LastWriteTimeUtc; - - await series.AddChild(season, cancellationToken).ConfigureAwait(false); - - await season.RefreshMetadata(cancellationToken).ConfigureAwait(false); - } - finally - { - _directoryWatchers.RemoveTempIgnore(path); - } - + await series.AddChild(season, cancellationToken).ConfigureAwait(false); + await season.RefreshMetadata(cancellationToken).ConfigureAwait(false); return season; } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index fea49880e..5f4a6a52f 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -868,6 +868,19 @@ namespace MediaBrowser.Server.Implementations.Dto } } + // If there is no thumb, indicate what parent has one in case the Ui wants to allow inheritance + if (!dto.HasThumb) + { + var parentWithImage = GetParentImageItem(item, ImageType.Thumb, owner); + + if (parentWithImage != null) + { + dto.ParentThumbItemId = GetDtoId(parentWithImage); + + dto.ParentThumbImageTag = GetImageCacheTag(parentWithImage, ImageType.Thumb, parentWithImage.GetImage(ImageType.Thumb)); + } + } + if (fields.Contains(ItemFields.Path)) { dto.Path = item.Path; @@ -1022,6 +1035,13 @@ namespace MediaBrowser.Server.Implementations.Dto dto.SeriesId = GetDtoId(series); dto.SeriesName = series.Name; + dto.AirTime = series.AirTime; + dto.SeriesStudio = series.Studios.FirstOrDefault(); + + if (series.HasImage(ImageType.Thumb)) + { + dto.SeriesThumbImageTag = GetImageCacheTag(series, ImageType.Thumb, series.GetImage(ImageType.Thumb)); + } } // Add SeasonInfo @@ -1033,6 +1053,8 @@ namespace MediaBrowser.Server.Implementations.Dto dto.SeriesId = GetDtoId(series); dto.SeriesName = series.Name; + dto.AirTime = series.AirTime; + dto.SeriesStudio = series.Studios.FirstOrDefault(); } var game = item as Game; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 385712700..05c5f5a82 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -186,6 +186,7 @@ </Compile> <Compile Include="Session\SessionWebSocketListener.cs" /> <Compile Include="Session\WebSocketController.cs" /> + <Compile Include="Sorting\AirTimeComparer.cs" /> <Compile Include="Sorting\AlbumArtistComparer.cs" /> <Compile Include="Sorting\AlbumComparer.cs" /> <Compile Include="Sorting\AlbumCountComparer.cs" /> diff --git a/MediaBrowser.Server.Implementations/Sorting/AirTimeComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AirTimeComparer.cs new file mode 100644 index 000000000..46c3df07b --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/AirTimeComparer.cs @@ -0,0 +1,48 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +using System; + +namespace MediaBrowser.Server.Implementations.Sorting +{ + public class AirTimeComparer : IBaseItemComparer + { + /// <summary> + /// Compares the specified x. + /// </summary> + /// <param name="x">The x.</param> + /// <param name="y">The y.</param> + /// <returns>System.Int32.</returns> + public int Compare(BaseItem x, BaseItem y) + { + return DateTime.Compare(GetValue(x), GetValue(y)); + } + + /// <summary> + /// Gets the value. + /// </summary> + /// <param name="x">The x.</param> + /// <returns>System.String.</returns> + private DateTime GetValue(BaseItem x) + { + var series = (x as Series) ?? x.FindParent<Series>(); + + DateTime result; + if (series != null && DateTime.TryParse(series.AirTime, out result)) + { + return result; + } + return DateTime.MinValue; + } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name + { + get { return ItemSortBy.AirTime; } + } + } +} diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 264eaeeeb..126b8d5ca 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -513,6 +513,7 @@ namespace MediaBrowser.WebDashboard.Api "tvrecommended.js", "tvshows.js", "tvstudios.js", + "tvupcoming.js", "updatepasswordpage.js", "userimagepage.js", "userprofilespage.js", diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 8c2dfc720..97a443e84 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -2018,11 +2018,28 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi options.imageType = "logo"; - var logoItemId = item.HasLogo ? item.Id : item.ParentLogoItemId; + var logoItemId = item.ImageTags && item.ImageTags.Logo ? item.Id : item.ParentLogoItemId; return logoItemId ? self.getImageUrl(logoItemId, options) : null; }; + self.getThumbImageUrl = function (item, options) { + + if (!item) { + throw new Error("null item"); + } + + options = options || { + + }; + + options.imageType = "thumb"; + + var itemId = item.ImageTags && item.ImageTags.Thumb ? item.Id : item.ParentThumbItemId; + + return itemId ? self.getImageUrl(itemId, options) : null; + }; + /** * Constructs an array of backdrop image url's for an item * If the item doesn't have any backdrops, it will inherit them from a parent diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 5ed3544c6..b2d9a0945 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -341,12 +341,18 @@ <Content Include="dashboard-ui\scripts\metadatatv.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\tvupcoming.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\wizardservice.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\wizardsettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\tvupcoming.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\wizardservice.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index f0ac36bc5..9c48b3809 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.180" targetFramework="net45" /> + <package id="MediaBrowser.ApiClient.Javascript" version="3.0.181" 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 |
