diff --git a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs index 86e2cfaf71..b5546683b5 100644 --- a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs +++ b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs @@ -65,7 +65,7 @@ namespace MediaBrowser.Providers.People Person = itemName }).Items.Cast() - .Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) + .Where(i => TvdbSeriesProvider.IsValidSeries(i.ProviderIds)) .ToList(); var infos = seriesWithPerson.Select(i => GetImageFromSeriesData(i, item.Name, cancellationToken)) @@ -77,7 +77,7 @@ namespace MediaBrowser.Providers.People private RemoteImageInfo GetImageFromSeriesData(Series series, string personName, CancellationToken cancellationToken) { - var tvdbPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.GetProviderId(MetadataProviders.Tvdb)); + var tvdbPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds); var actorXmlPath = Path.Combine(tvdbPath, "actors.xml"); diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 7dd4f13e4d..19eda49051 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -66,7 +66,11 @@ namespace MediaBrowser.Providers.TV { var tvdbId = group.Key; - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, tvdbId); + // Todo: Support series by imdb id + var seriesProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); + seriesProviderIds[MetadataProviders.Tvdb.ToString()] = tvdbId; + + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); var episodeFiles = Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.TopDirectoryOnly) .Select(Path.GetFileNameWithoutExtension) diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs index 10ceba94c8..1a6327d00f 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs @@ -57,12 +57,10 @@ namespace MediaBrowser.Providers.TV var episode = (Episode)item; var series = episode.Series; - var seriesId = series != null ? series.GetProviderId(MetadataProviders.Tvdb) : null; - - if (!string.IsNullOrEmpty(seriesId)) + if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds)) { // Process images - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesId); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds); var indexOffset = TvdbSeriesProvider.GetSeriesOffset(series.ProviderIds) ?? 0; var files = TvdbEpisodeProvider.Current.GetEpisodeXmlFiles(episode.ParentIndexNumber + indexOffset, episode.IndexNumber, episode.IndexNumberEnd, seriesDataPath); @@ -204,12 +202,10 @@ namespace MediaBrowser.Providers.TV { var series = episode.Series; - var seriesId = series != null ? series.GetProviderId(MetadataProviders.Tvdb) : null; - - if (!string.IsNullOrEmpty(seriesId)) + if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds)) { // Process images - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesId); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds); var files = TvdbEpisodeProvider.Current.GetEpisodeXmlFiles(episode.ParentIndexNumber, episode.IndexNumber, episode.IndexNumberEnd, seriesDataPath); diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index 42cf493490..ae247c9311 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; @@ -27,7 +26,6 @@ namespace MediaBrowser.Providers.TV /// class TvdbEpisodeProvider : IRemoteMetadataProvider, IItemIdentityProvider, IHasChangeMonitor { - private const string FullIdFormat = "{0}:{1}:{2}"; // seriesId:seasonIndex:episodeNumbers private static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; internal static TvdbEpisodeProvider Current; @@ -47,31 +45,20 @@ namespace MediaBrowser.Providers.TV public async Task> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken) { - var seriesProviderIds = searchInfo.SeriesProviderIds; - var list = new List(); - var identity = Identity.ParseIdentity(searchInfo.GetProviderId(FullIdKey)); - - if (identity == null) - { - await Identify(searchInfo).ConfigureAwait(false); - identity = Identity.ParseIdentity(searchInfo.GetProviderId(FullIdKey)); - } - - if (identity != null) + if (TvdbSeriesProvider.IsValidSeries(searchInfo.SeriesProviderIds) && searchInfo.IndexNumber.HasValue) { - seriesProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); - seriesProviderIds[MetadataProviders.Tvdb.ToString()] = identity.Value.SeriesId; - } + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, searchInfo.SeriesProviderIds); - if (TvdbSeriesProvider.IsValidSeries(seriesProviderIds)) - { - var seriesDataPath = await TvdbSeriesProvider.Current.EnsureSeriesInfo(seriesProviderIds, searchInfo.MetadataLanguage, cancellationToken).ConfigureAwait(false); + var searchNumbers = new EpisodeNumbers(); + searchNumbers.EpisodeNumber = searchInfo.IndexNumber.Value; + searchNumbers.SeasonNumber = searchInfo.ParentIndexNumber; + searchNumbers.EpisodeNumberEnd = searchInfo.IndexNumberEnd ?? searchNumbers.EpisodeNumber; try { - var metadataResult = FetchEpisodeData(searchInfo, identity, seriesDataPath, searchInfo.SeriesProviderIds, cancellationToken); + var metadataResult = FetchEpisodeData(searchInfo, searchNumbers, seriesDataPath, cancellationToken); if (metadataResult.HasMetadata) { @@ -122,11 +109,41 @@ namespace MediaBrowser.Providers.TV if (identity != null) { - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, identity.Value.SeriesId); + var seriesProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); + seriesProviderIds[MetadataProviders.Tvdb.ToString()] = identity.Value.SeriesId; + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + + var searchNumbers = new EpisodeNumbers(); + searchNumbers.EpisodeNumber = identity.Value.EpisodeNumber; + var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(searchInfo.SeriesProviderIds) ?? 0; + searchNumbers.SeasonNumber = identity.Value.SeasonIndex + seasonOffset; + searchNumbers.EpisodeNumberEnd = identity.Value.EpisodeNumberEnd ?? searchNumbers.EpisodeNumber; + + try + { + result = FetchEpisodeData(searchInfo, searchNumbers, seriesDataPath, cancellationToken); + } + catch (FileNotFoundException) + { + // Don't fail the provider because this will just keep on going and going. + } + catch (DirectoryNotFoundException) + { + // Don't fail the provider because this will just keep on going and going. + } + } + else if (TvdbSeriesProvider.IsValidSeries(searchInfo.SeriesProviderIds) && searchInfo.IndexNumber.HasValue) + { + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, searchInfo.SeriesProviderIds); + + var searchNumbers = new EpisodeNumbers(); + searchNumbers.EpisodeNumber = searchInfo.IndexNumber.Value; + searchNumbers.SeasonNumber = searchInfo.ParentIndexNumber; + searchNumbers.EpisodeNumberEnd = searchInfo.IndexNumberEnd ?? searchNumbers.EpisodeNumber; try { - result = FetchEpisodeData(searchInfo, identity.Value, seriesDataPath, searchInfo.SeriesProviderIds, cancellationToken); + result = FetchEpisodeData(searchInfo, searchNumbers, seriesDataPath, cancellationToken); } catch (FileNotFoundException) { @@ -156,12 +173,10 @@ namespace MediaBrowser.Providers.TV var episode = (Episode)item; var series = episode.Series; - var seriesId = series != null ? series.GetProviderId(MetadataProviders.Tvdb) : null; - - if (!string.IsNullOrEmpty(seriesId)) + if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds)) { // Process images - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesId); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds); var files = GetEpisodeXmlFiles(episode.ParentIndexNumber, episode.IndexNumber, episode.IndexNumberEnd, seriesDataPath); @@ -243,20 +258,25 @@ namespace MediaBrowser.Providers.TV return files; } + private class EpisodeNumbers + { + public int EpisodeNumber; + public int? SeasonNumber; + public int EpisodeNumberEnd; + } + /// /// Fetches the episode data. /// /// The identifier. - /// The identity. + /// The search numbers. /// The series data path. - /// The series provider ids. /// The cancellation token. /// Task{System.Boolean}. - private MetadataResult FetchEpisodeData(EpisodeInfo id, Identity? identity, string seriesDataPath, Dictionary seriesProviderIds, CancellationToken cancellationToken) + private MetadataResult FetchEpisodeData(EpisodeInfo id, EpisodeNumbers searchNumbers, string seriesDataPath, CancellationToken cancellationToken) { - var episodeNumber = identity.HasValue ? (identity.Value.EpisodeNumber) : id.IndexNumber.Value; - var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(seriesProviderIds) ?? 0; - var seasonNumber = identity.HasValue ? (identity.Value.SeasonIndex + seasonOffset) : id.ParentIndexNumber; + var episodeNumber = searchNumbers.EpisodeNumber; + var seasonNumber = searchNumbers.SeasonNumber; string file; var usingAbsoluteData = false; @@ -299,7 +319,7 @@ namespace MediaBrowser.Providers.TV usingAbsoluteData = true; } - var end = identity.HasValue ? (identity.Value.EpisodeNumberEnd ?? episodeNumber) : (id.IndexNumberEnd ?? episodeNumber); + var end = searchNumbers.EpisodeNumberEnd; episodeNumber++; while (episodeNumber <= end) diff --git a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs index 6ebbb7c397..d362ca722d 100644 --- a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs +++ b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs @@ -360,7 +360,7 @@ namespace MediaBrowser.Providers.TV _fileSystem.CreateDirectory(seriesDataPath); - return TvdbSeriesProvider.Current.DownloadSeriesZip(id, seriesDataPath, lastTvDbUpdateTime, preferredMetadataLanguage, cancellationToken); + return TvdbSeriesProvider.Current.DownloadSeriesZip(id, MetadataProviders.Tvdb.ToString(), seriesDataPath, lastTvDbUpdateTime, preferredMetadataLanguage, cancellationToken); } } } diff --git a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs index d88b39e106..7af85ecc93 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs @@ -375,17 +375,10 @@ namespace MediaBrowser.Providers.TV var season = (Season)item; var series = season.Series; - if (series == null) - { - return false; - } - - var tvdbId = series.GetProviderId(MetadataProviders.Tvdb); - - if (!String.IsNullOrEmpty(tvdbId)) + if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds)) { // Process images - var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, tvdbId), "banners.xml"); + var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds), "banners.xml"); var fileInfo = _fileSystem.GetFileInfo(imagesXmlPath); diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs index 40b647ceeb..eae389dfb0 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs @@ -340,12 +340,10 @@ namespace MediaBrowser.Providers.TV return false; } - var tvdbId = item.GetProviderId(MetadataProviders.Tvdb); - - if (!String.IsNullOrEmpty(tvdbId)) + if (TvdbSeriesProvider.IsValidSeries(item.ProviderIds)) { // Process images - var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, tvdbId), "banners.xml"); + var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, item.ProviderIds), "banners.xml"); var fileInfo = _fileSystem.GetFileInfo(imagesXmlPath); diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 22e3c59509..16c0098127 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -56,6 +56,7 @@ namespace MediaBrowser.Providers.TV private const string SeriesSearchUrl = "http://www.thetvdb.com/api/GetSeries.php?seriesname={0}&language={1}"; private const string SeriesGetZip = "http://www.thetvdb.com/api/{0}/series/{1}/all/{2}.zip"; + private const string SeriesGetZipByImdbId = "http://www.thetvdb.com/api/{0}/GetSeriesByRemoteID.php?imdbid={1}&language={2}"; public async Task> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) { @@ -100,7 +101,7 @@ namespace MediaBrowser.Providers.TV result.Item = new Series(); result.HasMetadata = true; - FetchSeriesData(result, itemId.GetProviderId(MetadataProviders.Tvdb), cancellationToken); + FetchSeriesData(result, itemId.ProviderIds, cancellationToken); await FindAnimeSeriesIndex(result.Item, itemId).ConfigureAwait(false); } @@ -139,16 +140,25 @@ namespace MediaBrowser.Providers.TV /// Fetches the series data. /// /// The result. - /// The series id. + /// The series provider ids. /// The cancellation token. /// Task{System.Boolean}. - private void FetchSeriesData(MetadataResult result, string seriesId, CancellationToken cancellationToken) + private void FetchSeriesData(MetadataResult result, Dictionary seriesProviderIds, CancellationToken cancellationToken) { var series = result.Item; - series.SetProviderId(MetadataProviders.Tvdb, seriesId); + string id; + if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out id)) + { + series.SetProviderId(MetadataProviders.Tvdb, id); + } + + if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out id)) + { + series.SetProviderId(MetadataProviders.Imdb, id); + } - var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesId); + var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); var seriesXmlFilename = series.GetPreferredMetadataLanguage().ToLower() + ".xml"; @@ -168,21 +178,23 @@ namespace MediaBrowser.Providers.TV /// Downloads the series zip. /// /// The series id. + /// Type of the identifier. /// The series data path. /// The last tv database update time. /// The preferred metadata language. /// The cancellation token. /// Task. - internal async Task DownloadSeriesZip(string seriesId, string seriesDataPath, long? lastTvDbUpdateTime, string preferredMetadataLanguage, CancellationToken cancellationToken) + /// seriesId + internal async Task DownloadSeriesZip(string seriesId, string idType, string seriesDataPath, long? lastTvDbUpdateTime, string preferredMetadataLanguage, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(seriesId)) { throw new ArgumentNullException("seriesId"); } - + try { - await DownloadSeriesZip(seriesId, seriesDataPath, lastTvDbUpdateTime, preferredMetadataLanguage, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + await DownloadSeriesZip(seriesId, idType, seriesDataPath, lastTvDbUpdateTime, preferredMetadataLanguage, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); return; } catch (HttpException ex) @@ -195,18 +207,20 @@ namespace MediaBrowser.Providers.TV if (!string.Equals(preferredMetadataLanguage, "en", StringComparison.OrdinalIgnoreCase)) { - await DownloadSeriesZip(seriesId, seriesDataPath, lastTvDbUpdateTime, "en", preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + await DownloadSeriesZip(seriesId, idType, seriesDataPath, lastTvDbUpdateTime, "en", preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); } } - private async Task DownloadSeriesZip(string seriesId, string seriesDataPath, long? lastTvDbUpdateTime, string preferredMetadataLanguage, string saveAsMetadataLanguage, CancellationToken cancellationToken) + private async Task DownloadSeriesZip(string seriesId, string idType, string seriesDataPath, long? lastTvDbUpdateTime, string preferredMetadataLanguage, string saveAsMetadataLanguage, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(seriesId)) { throw new ArgumentNullException("seriesId"); } - var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, preferredMetadataLanguage); + var url = string.Equals(idType, "tvdb", StringComparison.OrdinalIgnoreCase) ? + string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, preferredMetadataLanguage) : + string.Format(SeriesGetZipByImdbId, TVUtils.TvdbApiKey, seriesId, preferredMetadataLanguage); using (var zipStream = await _httpClient.Get(new HttpRequestOptions { @@ -263,25 +277,44 @@ namespace MediaBrowser.Providers.TV return true; } } - //if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out id)) - //{ - // return true; - //} + + if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out id)) + { + // This check should ideally never be necessary but we're seeing some cases of this and haven't tracked them down yet. + if (!string.IsNullOrWhiteSpace(id)) + { + return true; + } + } return false; } - internal async Task EnsureSeriesInfo(Dictionary seriesProviderIds, string preferredMetadataLanguage, CancellationToken cancellationToken) + internal async Task EnsureSeriesInfo(Dictionary seriesProviderIds, string preferredMetadataLanguage, CancellationToken cancellationToken) { string seriesId; if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesId)) { - var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesId); + var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); // Only download if not already there // The post-scan task will take care of updates so we don't need to re-download here if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) { - await DownloadSeriesZip(seriesId, seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + await DownloadSeriesZip(seriesId, MetadataProviders.Tvdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + } + + return seriesDataPath; + } + + if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesId)) + { + var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + + // Only download if not already there + // The post-scan task will take care of updates so we don't need to re-download here + if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + { + await DownloadSeriesZip(seriesId, MetadataProviders.Imdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); } return seriesDataPath; @@ -839,16 +872,12 @@ namespace MediaBrowser.Providers.TV if (!string.IsNullOrWhiteSpace(val)) { - // Only fill this if it doesn't already have a value, since we get it from imdb which has better data - if (!item.CommunityRating.HasValue || string.IsNullOrWhiteSpace(item.GetProviderId(MetadataProviders.Imdb))) - { - float rval; + float rval; - // float.TryParse is local aware, so it can be probamatic, force us culture - if (float.TryParse(val, NumberStyles.AllowDecimalPoint, _usCulture, out rval)) - { - item.CommunityRating = rval; - } + // float.TryParse is local aware, so it can be probamatic, force us culture + if (float.TryParse(val, NumberStyles.AllowDecimalPoint, _usCulture, out rval)) + { + item.CommunityRating = rval; } } break; @@ -1190,13 +1219,26 @@ namespace MediaBrowser.Providers.TV /// Gets the series data path. /// /// The app paths. - /// The series id. + /// The series provider ids. /// System.String. - internal static string GetSeriesDataPath(IApplicationPaths appPaths, string seriesId) + internal static string GetSeriesDataPath(IApplicationPaths appPaths, Dictionary seriesProviderIds) { - var seriesDataPath = Path.Combine(GetSeriesDataPath(appPaths), seriesId); + string seriesId; + if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesId)) + { + var seriesDataPath = Path.Combine(GetSeriesDataPath(appPaths), seriesId); + + return seriesDataPath; + } - return seriesDataPath; + if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesId)) + { + var seriesDataPath = Path.Combine(GetSeriesDataPath(appPaths), seriesId); + + return seriesDataPath; + } + + return null; } ///