fix double path concatenation
This commit is contained in:
parent
a09d449c00
commit
146c7ac4bf
|
@ -859,6 +859,14 @@ namespace MediaBrowser.Model.ApiClient
|
|||
/// <returns>System.String.</returns>
|
||||
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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -271,6 +285,67 @@ namespace MediaBrowser.Providers.TV
|
|||
return hasChanges;
|
||||
}
|
||||
|
||||
/// <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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -513,6 +513,7 @@ namespace MediaBrowser.WebDashboard.Api
|
|||
"tvrecommended.js",
|
||||
"tvshows.js",
|
||||
"tvstudios.js",
|
||||
"tvupcoming.js",
|
||||
"updatepasswordpage.js",
|
||||
"userimagepage.js",
|
||||
"userprofilespage.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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue
Block a user