aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2015-01-24 14:03:55 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2015-01-24 14:03:55 -0500
commitee00f8bf726ae5498d64cff0086b9b7e638936ea (patch)
tree710a5b4b715e5fbf1574bc072c4f299e7c9826ff /MediaBrowser.Server.Implementations
parent1af651bc56025935cebe2762d6f36be41530eba1 (diff)
added HasSyncJob
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelManager.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Collections/CollectionManager.cs12
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectManager.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs99
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserViewManager.cs38
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json4
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs5
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncRepository.cs27
-rw-r--r--MediaBrowser.Server.Implementations/Udp/UdpServer.cs14
11 files changed, 168 insertions, 48 deletions
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
index 99ca0b5da..37536a4ee 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
@@ -180,7 +180,7 @@ namespace MediaBrowser.Server.Implementations.Channels
var dtoOptions = new DtoOptions();
- var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
+ var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ToArray();
var result = new QueryResult<BaseItemDto>
@@ -556,7 +556,7 @@ namespace MediaBrowser.Server.Implementations.Channels
var dtoOptions = new DtoOptions();
- var returnItems = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
+ var returnItems = _dtoService.GetBaseItemDtos(items, dtoOptions, user)
.ToArray();
var result = new QueryResult<BaseItemDto>
@@ -823,7 +823,7 @@ namespace MediaBrowser.Server.Implementations.Channels
var dtoOptions = new DtoOptions();
- var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
+ var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ToArray();
var result = new QueryResult<BaseItemDto>
@@ -972,7 +972,7 @@ namespace MediaBrowser.Server.Implementations.Channels
var dtoOptions = new DtoOptions();
- var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
+ var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ToArray();
var result = new QueryResult<BaseItemDto>
diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
index 6100e3f5d..faf73c059 100644
--- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
+++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
@@ -6,7 +6,6 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
-using MoreLinq;
using System;
using System.Collections.Generic;
using System.IO;
@@ -41,6 +40,14 @@ namespace MediaBrowser.Server.Implementations.Collections
.FirstOrDefault();
}
+ public IEnumerable<BoxSet> GetCollections(User user)
+ {
+ var folder = GetCollectionsFolder(user.Id.ToString("N"));
+ return folder == null ?
+ new List<BoxSet>() :
+ folder.GetChildren(user, true).OfType<BoxSet>();
+ }
+
public async Task<BoxSet> CreateCollection(CollectionCreationOptions options)
{
var name = options.Name;
@@ -269,7 +276,8 @@ namespace MediaBrowser.Server.Implementations.Collections
public IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user)
{
var results = new Dictionary<Guid, BaseItem>();
- var allBoxsets = new List<BoxSet>();
+
+ var allBoxsets = GetCollections(user).ToList();
foreach (var item in items)
{
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
index bb89f01fa..e079aaf61 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
@@ -153,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.Connect
try
{
- var localAddress = _appHost.GetSystemInfo().LocalAddress;
+ var localAddress = _appHost.LocalApiUrl;
var hasExistingRecord = !string.IsNullOrWhiteSpace(ConnectServerId) &&
!string.IsNullOrWhiteSpace(ConnectAccessKey);
@@ -195,7 +195,7 @@ namespace MediaBrowser.Server.Implementations.Connect
private string _lastReportedIdentifier;
private string GetConnectReportingIdentifier()
{
- return GetConnectReportingIdentifier(_appHost.GetSystemInfo().LocalAddress, WanApiAddress);
+ return GetConnectReportingIdentifier(_appHost.LocalApiUrl, WanApiAddress);
}
private string GetConnectReportingIdentifier(string localAddress, string remoteAddress)
{
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index e919336b1..85a31337b 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -19,6 +20,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Sync;
using MoreLinq;
using System;
using System.Collections.Generic;
@@ -42,8 +44,9 @@ namespace MediaBrowser.Server.Implementations.Dto
private readonly Func<IChannelManager> _channelManagerFactory;
private readonly ISyncManager _syncManager;
private readonly IApplicationHost _appHost;
+ private readonly Func<IDeviceManager> _deviceManager;
- public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func<IChannelManager> channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost)
+ public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func<IChannelManager> channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func<IDeviceManager> deviceManager)
{
_logger = logger;
_libraryManager = libraryManager;
@@ -56,6 +59,7 @@ namespace MediaBrowser.Server.Implementations.Dto
_channelManagerFactory = channelManagerFactory;
_syncManager = syncManager;
_appHost = appHost;
+ _deviceManager = deviceManager;
}
/// <summary>
@@ -73,10 +77,39 @@ namespace MediaBrowser.Server.Implementations.Dto
{
Fields = fields
};
-
+
return GetBaseItemDto(item, options, user, owner);
}
+ public IEnumerable<BaseItemDto> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
+ {
+ var itemIdsWithSyncJobs = GetItemIdsWithSyncJobs(options).ToList();
+
+ var list = new List<BaseItemDto>();
+
+ foreach (var item in items)
+ {
+ var dto = GetBaseItemDtoInternal(item, options, user, owner);
+
+ var byName = item as IItemByName;
+
+ if (byName != null && !(item is LiveTvChannel))
+ {
+ var libraryItems = user != null ?
+ user.RootFolder.GetRecursiveChildren(user) :
+ _libraryManager.RootFolder.RecursiveChildren;
+
+ SetItemByNameInfo(item, dto, byName.GetTaggedItems(libraryItems).ToList(), user);
+ }
+
+ FillSyncInfo(dto, item, itemIdsWithSyncJobs, options);
+
+ list.Add(dto);
+ }
+
+ return list;
+ }
+
public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
{
var dto = GetBaseItemDtoInternal(item, options, user, owner);
@@ -94,9 +127,64 @@ namespace MediaBrowser.Server.Implementations.Dto
return dto;
}
+ FillSyncInfo(dto, item, options);
+
return dto;
}
+ private IEnumerable<string> GetItemIdsWithSyncJobs(DtoOptions options)
+ {
+ if (!options.Fields.Contains(ItemFields.SyncInfo))
+ {
+ return new List<string>();
+ }
+
+ var deviceId = options.DeviceId;
+ if (string.IsNullOrWhiteSpace(deviceId))
+ {
+ return new List<string>();
+ }
+
+ var caps = _deviceManager().GetCapabilities(deviceId);
+ if (caps == null || !caps.SupportsSync)
+ {
+ return new List<string>();
+ }
+
+ var result = _syncManager.GetLibraryItemIds(new SyncJobItemQuery
+ {
+ TargetId = deviceId
+ });
+
+ return result.Items;
+ }
+
+ private void FillSyncInfo(BaseItemDto dto, BaseItem item, DtoOptions options)
+ {
+ if (options.Fields.Contains(ItemFields.SyncInfo))
+ {
+ dto.SupportsSync = _syncManager.SupportsSync(item);
+ }
+
+ if (dto.SupportsSync ?? false)
+ {
+ dto.HasSyncJob = GetItemIdsWithSyncJobs(options).Contains(dto.Id, StringComparer.OrdinalIgnoreCase);
+ }
+ }
+
+ private void FillSyncInfo(BaseItemDto dto, BaseItem item, IEnumerable<string> itemIdsWithSyncJobs, DtoOptions options)
+ {
+ if (options.Fields.Contains(ItemFields.SyncInfo))
+ {
+ dto.SupportsSync = _syncManager.SupportsSync(item);
+ }
+
+ if (dto.SupportsSync ?? false)
+ {
+ dto.HasSyncJob = itemIdsWithSyncJobs.Contains(dto.Id, StringComparer.OrdinalIgnoreCase);
+ }
+ }
+
private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
{
var fields = options.Fields;
@@ -167,11 +255,6 @@ namespace MediaBrowser.Server.Implementations.Dto
AttachBasicFields(dto, item, owner, options);
- if (fields.Contains(ItemFields.SyncInfo))
- {
- dto.SupportsSync = _syncManager.SupportsSync(item);
- }
-
if (fields.Contains(ItemFields.SoundtrackIds))
{
var hasSoundtracks = item as IHasSoundtracks;
@@ -1029,7 +1112,7 @@ namespace MediaBrowser.Server.Implementations.Dto
//if (fields.Contains(ItemFields.MediaSourceCount))
//{
- // Songs always have one
+ // Songs always have one
//}
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 1306188da..d93705a51 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -1575,7 +1575,7 @@ namespace MediaBrowser.Server.Implementations.Library
CancellationToken cancellationToken)
{
var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath,
- "views");
+ "views");
path = Path.Combine(path, _fileSystem.GetValidFilename(type));
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index c4c0e5395..6b6f5b1b6 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -696,8 +696,7 @@ namespace MediaBrowser.Server.Implementations.Library
var text = new StringBuilder();
- var info = _appHost.GetSystemInfo();
- var localAddress = info.LocalAddress ?? string.Empty;
+ var localAddress = _appHost.LocalApiUrl ?? string.Empty;
text.AppendLine("Use your web browser to visit:");
text.AppendLine(string.Empty);
diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
index 46c32cc56..bd0f44adc 100644
--- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
@@ -1,6 +1,6 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Collections;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
@@ -23,24 +23,24 @@ namespace MediaBrowser.Server.Implementations.Library
{
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localizationManager;
- private readonly IFileSystem _fileSystem;
private readonly IUserManager _userManager;
private readonly IChannelManager _channelManager;
private readonly ILiveTvManager _liveTvManager;
- private readonly IServerApplicationPaths _appPaths;
private readonly IPlaylistManager _playlists;
+ private readonly ICollectionManager _collectionManager;
+ private readonly IServerConfigurationManager _config;
- public UserViewManager(ILibraryManager libraryManager, ILocalizationManager localizationManager, IFileSystem fileSystem, IUserManager userManager, IChannelManager channelManager, ILiveTvManager liveTvManager, IServerApplicationPaths appPaths, IPlaylistManager playlists)
+ public UserViewManager(ILibraryManager libraryManager, ILocalizationManager localizationManager, IUserManager userManager, IChannelManager channelManager, ILiveTvManager liveTvManager, IPlaylistManager playlists, ICollectionManager collectionManager, IServerConfigurationManager config)
{
_libraryManager = libraryManager;
_localizationManager = localizationManager;
- _fileSystem = fileSystem;
_userManager = userManager;
_channelManager = channelManager;
_liveTvManager = liveTvManager;
- _appPaths = appPaths;
_playlists = playlists;
+ _collectionManager = collectionManager;
+ _config = config;
}
public async Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken)
@@ -88,12 +88,24 @@ namespace MediaBrowser.Server.Implementations.Library
list.Add(await GetUserView(CollectionType.Games, string.Empty, cancellationToken).ConfigureAwait(false));
}
- if (user.Configuration.DisplayCollectionsView &&
- folders
- .Except(standaloneFolders)
- .SelectMany(i => i.GetRecursiveChildren(user, false)).OfType<BoxSet>().Any())
+ if (user.Configuration.DisplayCollectionsView)
{
- list.Add(await GetUserView(CollectionType.BoxSets, string.Empty, cancellationToken).ConfigureAwait(false));
+ bool showCollectionView;
+ if (_config.Configuration.EnableLegacyCollections)
+ {
+ showCollectionView = folders
+ .Except(standaloneFolders)
+ .SelectMany(i => i.GetRecursiveChildren(user, false)).OfType<BoxSet>().Any();
+ }
+ else
+ {
+ showCollectionView = _collectionManager.GetCollections(user).Any();
+ }
+
+ if (showCollectionView)
+ {
+ list.Add(await GetUserView(CollectionType.BoxSets, string.Empty, cancellationToken).ConfigureAwait(false));
+ }
}
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)))
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index 576e0493e..34a0b327d 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -56,7 +56,7 @@
"HeaderVideo": "Video",
"HeaderPaths": "Paths",
"LabelSyncTempPath": "Temporary file path:",
- "LabelSyncTempPathHelp": "",
+ "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.",
"LabelCustomCertificatePath": "Custom certificate path:",
"LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.",
"TitleNotifications": "Notifications",
@@ -891,7 +891,7 @@
"OptionCommunityMostWatchedSort": "Most Watched",
"TabNextUp": "Next Up",
"HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter",
- "TextAccessPremiumFeatures": "Enjoy Premium Features",
+ "TextAccessPremiumFeatures": "Enjoy Premium Features",
"MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.",
"MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.",
"MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.",
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index b5e29533b..cdbb0d5e5 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -720,5 +720,10 @@ namespace MediaBrowser.Server.Implementations.Sync
await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
}
+
+ public QueryResult<string> GetLibraryItemIds(SyncJobItemQuery query)
+ {
+ return _repo.GetLibraryItemIds(query);
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
index 0e527ea54..6d77749e0 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
@@ -459,7 +459,7 @@ namespace MediaBrowser.Server.Implementations.Sync
return null;
}
- public QueryResult<SyncJobItem> GetJobItems(SyncJobItemQuery query)
+ private QueryResult<T> GetJobItemReader<T>(SyncJobItemQuery query, string baseSelectText, Func<IDataReader, T> itemFactory)
{
if (query == null)
{
@@ -468,7 +468,7 @@ namespace MediaBrowser.Server.Implementations.Sync
using (var cmd = _connection.CreateCommand())
{
- cmd.CommandText = BaseJobItemSelectText;
+ cmd.CommandText = baseSelectText;
var whereClauses = new List<string>();
@@ -515,14 +515,14 @@ namespace MediaBrowser.Server.Implementations.Sync
cmd.CommandText += "; select count (Id) from SyncJobItems" + whereTextWithoutPaging;
- var list = new List<SyncJobItem>();
+ var list = new List<T>();
var count = 0;
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
- list.Add(GetJobItem(reader));
+ list.Add(itemFactory(reader));
}
if (reader.NextResult() && reader.Read())
@@ -531,7 +531,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- return new QueryResult<SyncJobItem>()
+ return new QueryResult<T>()
{
Items = list.ToArray(),
TotalRecordCount = count
@@ -539,6 +539,16 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
+ public QueryResult<string> GetLibraryItemIds(SyncJobItemQuery query)
+ {
+ return GetJobItemReader(query, "select ItemId from SyncJobItems", GetItemId);
+ }
+
+ public QueryResult<SyncJobItem> GetJobItems(SyncJobItemQuery query)
+ {
+ return GetJobItemReader(query, BaseJobItemSelectText, GetJobItem);
+ }
+
public Task Create(SyncJobItem jobItem)
{
return Update(jobItem);
@@ -679,10 +689,15 @@ namespace MediaBrowser.Server.Implementations.Sync
info.IsMarkedForRemoval = reader.GetBoolean(13);
info.JobItemIndex = reader.GetInt32(14);
-
+
return info;
}
+ private string GetItemId(IDataReader reader)
+ {
+ return reader.GetString(0);
+ }
+
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs
index 91a4940ae..9dbffa922 100644
--- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs
+++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs
@@ -83,9 +83,7 @@ namespace MediaBrowser.Server.Implementations.Udp
private async void RespondToV1Message(string endpoint)
{
- var info = _appHost.GetSystemInfo();
-
- var localAddress = info.LocalAddress;
+ var localAddress = _appHost.LocalApiUrl;
if (!string.IsNullOrEmpty(localAddress))
{
@@ -110,15 +108,15 @@ namespace MediaBrowser.Server.Implementations.Udp
private async void RespondToV2Message(string endpoint)
{
- var info = _appHost.GetSystemInfo();
+ var localUrl = _appHost.LocalApiUrl;
- if (!string.IsNullOrEmpty(info.LocalAddress))
+ if (!string.IsNullOrEmpty(localUrl))
{
var response = new ServerDiscoveryInfo
{
- Address = info.LocalAddress,
- Id = info.Id,
- Name = info.ServerName
+ Address = localUrl,
+ Id = _appHost.SystemId,
+ Name = _appHost.FriendlyName
};
await SendAsync(Encoding.UTF8.GetBytes(_json.SerializeToString(response)), endpoint);