public async Task Sync(IApiClient apiClient, ServerInfo serverInfo, IProgress<double> progress, CancellationToken cancellationToken = default(CancellationToken)) { _logger.Debug("Beginning media sync process with server Id: {0}", serverInfo.Id); // First report actions to the server that occurred while offline await ReportOfflineActions(apiClient, serverInfo, cancellationToken).ConfigureAwait(false); progress.Report(1); await SyncData(apiClient, serverInfo, false, cancellationToken).ConfigureAwait(false); progress.Report(3); var innerProgress = new DoubleProgress(); innerProgress.RegisterAction(pct => { var totalProgress = pct * .97; totalProgress += 1; progress.Report(totalProgress); }); await GetNewMedia(apiClient, serverInfo, innerProgress, cancellationToken); progress.Report(100); // Do the data sync twice so the server knows what was removed from the device await SyncData(apiClient, serverInfo, true, cancellationToken).ConfigureAwait(false); }
private async Task SyncInternal(ServerInfo server, IProgress<double> progress, CancellationToken cancellationToken) { _logger.Debug("Beginning ServerSync with server {0}, Id {1}", server.Name, server.Id); if (string.IsNullOrWhiteSpace(server.AccessToken) && string.IsNullOrWhiteSpace(server.ExchangeToken)) { _logger.Info("Skipping sync process for server " + server.Name + ". No server authentication information available."); progress.Report(100); return; } // Don't need these here var result = await _connectionManager.Connect(server, new ConnectionOptions { EnableWebSocket = false, ReportCapabilities = false, UpdateDateLastAccessed = false }, cancellationToken).ConfigureAwait(false); if (result.State == ConnectionState.SignedIn) { await SyncInternal(server, result.ApiClient, progress, cancellationToken).ConfigureAwait(false); progress.Report(100); } else { _logger.Info("Skipping sync process for server " + server.Name + ". ConnectionManager returned a state of {0}", result.State.ToString()); progress.Report(100); } }
private void SetUserUpdateHandler(ServerInfo serverInfo) { var apiClient = _connectionManager.GetApiClient(serverInfo.Id); if (apiClient != null) { apiClient.UserUpdated -= ApiClientOnUserUpdated; apiClient.UserUpdated += ApiClientOnUserUpdated; } }
public async Task RemoveServer(ServerInfo server) { var creds = await GetServerCredentials(); var serverExists = creds.Servers.FirstOrDefault(x => x.Id == server.Id); if (serverExists != null) { creds.Servers.Remove(serverExists); await SaveServerCredentials(creds); } }
public async Task GetItemFileAsync( IApiClient apiClient, ServerInfo server, LocalItem item, string syncJobItemId, IProgress<double> transferProgress, CancellationToken cancellationToken) { var downloadUrl = apiClient.GetSyncJobItemFileUrl(syncJobItemId); await CreateDownload(downloadUrl, apiClient, item); }
public async Task GetItemFileAsync(IApiClient apiClient, ServerInfo server, LocalItem item, string syncJobItemId, IProgress<double> transferProgress, CancellationToken cancellationToken = default(CancellationToken)) { _logger.Debug("Downloading media with Id {0} to local repository", item.Item.Id); using (var stream = await apiClient.GetSyncJobItemFile(syncJobItemId, cancellationToken).ConfigureAwait(false)) { await _localAssetManager.SaveMedia(stream, item, server).ConfigureAwait(false); } transferProgress.Report(100); }
public async Task Sync(ServerInfo server, IProgress<double> progress, CancellationToken cancellationToken = default(CancellationToken)) { var semaphore = GetLock(server.Id); await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { await SyncInternal(server, progress, cancellationToken).ConfigureAwait(false); } finally { semaphore.Release(); } }
public async Task UpdateOfflineUsers(ServerInfo server, IApiClient apiClient, CancellationToken cancellationToken = default(CancellationToken)) { foreach (var user in server.Users.ToList()) { cancellationToken.ThrowIfCancellationRequested(); try { await SaveOfflineUser(user, apiClient, cancellationToken).ConfigureAwait(false); } catch { // Already logged at lower level } } }
private async Task GetNewMedia(IApiClient apiClient, ServerInfo server, IProgress<double> progress, CancellationToken cancellationToken) { var jobItems = await apiClient.GetReadySyncItems(apiClient.DeviceId).ConfigureAwait(false); var numComplete = 0; double startingPercent = 0; double percentPerItem = 1; if (jobItems.Count > 0) { percentPerItem /= jobItems.Count; } foreach (var jobItem in jobItems) { cancellationToken.ThrowIfCancellationRequested(); var currentPercent = startingPercent; var innerProgress = new DoubleProgress(); innerProgress.RegisterAction(pct => { var totalProgress = pct * percentPerItem; totalProgress += currentPercent; progress.Report(totalProgress); }); try { await GetItem(apiClient, server, jobItem, innerProgress, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { _logger.ErrorException("Error syncing new media", ex); } numComplete++; startingPercent = numComplete; startingPercent /= jobItems.Count; startingPercent *= 100; progress.Report(startingPercent); } }
private async Task LoadSettings() { RetryButtonIsVisible = false; App.Settings.ConnectionDetails = new ConnectionDetails { PortNo = 8096 }; var doNotShowFirstRun = _applicationSettings.Get(Constants.Settings.DoNotShowFirstRun, false); if (!doNotShowFirstRun) { NavigationService.NavigateTo(Constants.Pages.FirstRun.WelcomeView); return; } SetProgressBar(AppResources.SysTrayLoadingSettings); #if !DEBUG //try //{ // if (!ApplicationManifest.Current.App.Title.ToLower().Contains("beta")) // { // var marketPlace = new MarketplaceInformationService(); // var appInfo = await marketPlace.GetAppInformationAsync(ApplicationManifest.Current.App.ProductId); // if (new Version(appInfo.Entry.Version) > new Version(ApplicationManifest.Current.App.Version) && // MessageBox.Show("There is a newer version, would you like to install it now?", "Update Available", MessageBoxButton.OKCancel) == MessageBoxResult.OK) // { // new MarketplaceDetailService().Show(); // } // } //} //catch (Exception ex) //{ // Log.ErrorException("GetAppInformationAsync()", ex); //} #endif // Get and set the app specific settings _specificSettings = _applicationSettings.Get<SpecificSettings>(Constants.Settings.SpecificSettings); if (_specificSettings != null) SharedUtils.CopyItem(_specificSettings, App.SpecificSettings); SetRunUnderLock(); _uploadSettings = _applicationSettings.Get<UploadSettings>(Constants.Settings.PhotoUploadSettings); if (_uploadSettings != null) SharedUtils.CopyItem(_uploadSettings, App.UploadSettings); _connectionDetails = _applicationSettings.Get<ConnectionDetails>(Constants.Settings.ConnectionSettings); _savedServer = _applicationSettings.Get<ServerInfo>(Constants.Settings.DefaultServerConnection); if (_savedServer != null) { _serverInfo.SetServerInfo(_savedServer); } else { NavigationService.NavigateTo(Constants.Pages.FirstRun.WelcomeView); return; } await ConnectToServer(); }
private async Task ConnectToServer() { RetryButtonIsVisible = false; ConnectionResult result = null; SetProgressBar(AppResources.SysTrayGettingServerDetails); if (_connectionDetails != null && !string.IsNullOrEmpty(_connectionDetails.ServerId)) { result = await ConnectionManager.Connect(_connectionDetails.ServerAddress); var server = result.Servers.FirstOrDefault(x => string.Equals(x.Id, _connectionDetails.ServerId, StringComparison.CurrentCultureIgnoreCase)); if (server != null) { _serverInfo.SetServerInfo(server); _applicationSettings.Set(Constants.Settings.DefaultServerConnection, server); _savedServer = server; _applicationSettings.Remove(Constants.Settings.ConnectionSettings); _connectionDetails = null; } } if (_savedServer != null) { result = await ConnectionManager.Connect(_savedServer); } if (result != null && result.State == ConnectionState.Unavailable && _savedServer != null) { RetryButtonIsVisible = true; return; } // See if we can find and communicate with the server if (result == null || result.State == ConnectionState.Unavailable) { result = await ConnectionManager.Connect(); } Deployment.Current.Dispatcher.BeginInvoke(async () => { await Utils.HandleConnectedState(result, ApiClient, NavigationService, Log); SetProgressBar(); }); }
private void ServerInfoServiceOnServerInfoChanged(object sender, ServerInfo serverInfo) { SetUserUpdateHandler(serverInfo); }
private void SaveServer(ServerInfo server) { _serverInfo.SetServerInfo(server); _applicationSettings.Set(Constants.Settings.DefaultServerConnection, server); }
public LocalItem CreateLocalItem(BaseItemDto libraryItem, ServerInfo server, string syncJobItemId, string originalFileName) { var path = GetDirectoryPath(libraryItem, server); path.Add(GetLocalFileName(libraryItem, originalFileName)); var localPath = _fileRepository.GetFullLocalPath(path); foreach (var mediaSource in libraryItem.MediaSources) { mediaSource.Path = localPath; mediaSource.Protocol = MediaProtocol.File; } return new LocalItem { Item = libraryItem, ItemId = libraryItem.Id, ServerId = server.Id, LocalPath = localPath, Id = GetLocalId(server.Id, libraryItem.Id), SyncJobItemId = syncJobItemId }; }
public void AddOrUpdateServer(ServerInfo server) { if (server == null) { throw new ArgumentNullException("server"); } var list = Servers.ToList(); var index = FindIndex(list, server.Id); if (index != -1) { var existing = list[index]; // Merge the data existing.DateLastAccessed = new[] { existing.DateLastAccessed, server.DateLastAccessed }.Max(); existing.UserLinkType = server.UserLinkType; if (!string.IsNullOrEmpty(server.AccessToken)) { existing.AccessToken = server.AccessToken; existing.UserId = server.UserId; } if (!string.IsNullOrEmpty(server.ExchangeToken)) { existing.ExchangeToken = server.ExchangeToken; } if (!string.IsNullOrEmpty(server.RemoteAddress)) { existing.RemoteAddress = server.RemoteAddress; } if (!string.IsNullOrEmpty(server.LocalAddress)) { existing.LocalAddress = server.LocalAddress; } if (!string.IsNullOrEmpty(server.ManualAddress)) { existing.LocalAddress = server.ManualAddress; } if (!string.IsNullOrEmpty(server.Name)) { existing.Name = server.Name; } if (server.WakeOnLanInfos != null && server.WakeOnLanInfos.Count > 0) { existing.WakeOnLanInfos = server.WakeOnLanInfos.ToList(); } if (server.LastConnectionMode.HasValue) { existing.LastConnectionMode = server.LastConnectionMode; } } else { list.Add(server); } Servers = list; }
public LocalItem CreateLocalItem(BaseItemDto libraryItem, ServerInfo server, string syncJobItemId, string originalFileName) { throw new NotImplementedException(); }
public Task SaveMedia(Stream stream, LocalItem localItem, ServerInfo server) { return Task.FromResult(true); }
public void AddOrUpdateServer(ServerInfo server) { if (server == null) { throw new ArgumentNullException("server"); } // Clone the existing list of servers var list = new List <ServerInfo>(); foreach (ServerInfo serverInfo in Servers) { list.Add(serverInfo); } var index = FindIndex(list, server.Id); if (index != -1) { var existing = list[index]; // Take the most recent DateLastAccessed if (server.DateLastAccessed > existing.DateLastAccessed) { existing.DateLastAccessed = server.DateLastAccessed; } existing.UserLinkType = server.UserLinkType; if (!string.IsNullOrEmpty(server.AccessToken)) { existing.AccessToken = server.AccessToken; existing.UserId = server.UserId; } if (!string.IsNullOrEmpty(server.ExchangeToken)) { existing.ExchangeToken = server.ExchangeToken; } if (!string.IsNullOrEmpty(server.RemoteAddress)) { existing.RemoteAddress = server.RemoteAddress; } if (!string.IsNullOrEmpty(server.ConnectServerId)) { existing.ConnectServerId = server.ConnectServerId; } if (!string.IsNullOrEmpty(server.LocalAddress)) { existing.LocalAddress = server.LocalAddress; } if (!string.IsNullOrEmpty(server.ManualAddress)) { existing.LocalAddress = server.ManualAddress; } if (!string.IsNullOrEmpty(server.Name)) { existing.Name = server.Name; } if (server.WakeOnLanInfos != null && server.WakeOnLanInfos.Count > 0) { existing.WakeOnLanInfos = new List <WakeOnLanInfo>(); foreach (WakeOnLanInfo info in server.WakeOnLanInfos) { existing.WakeOnLanInfos.Add(info); } } if (server.LastConnectionMode.HasValue) { existing.LastConnectionMode = server.LastConnectionMode; } foreach (ServerUserInfo user in server.Users) { existing.AddOrUpdate(user); } } else { list.Add(server); } Servers = list; }
private void SaveUserInfoIntoCredentials(ServerInfo server, UserDto user) { // Record user info here server.AddOrUpdate(new ServerUserInfo { Id = user.Id, IsSignedInOffline = true }); }
public Task SaveMedia(Stream stream, LocalItem localItem, ServerInfo server) { _logger.Debug("Saving media to " + localItem.LocalPath); return _fileRepository.SaveFile(stream, localItem.LocalPath); }
private List<string> GetDirectoryPath(BaseItemDto item, ServerInfo server) { var parts = new List<string> { server.Name }; if (item.IsType("episode")) { parts.Add("TV"); parts.Add(item.SeriesName); if (!string.IsNullOrWhiteSpace(item.SeasonName)) { parts.Add(item.SeasonName); } } else if (item.IsVideo) { parts.Add("Videos"); parts.Add(item.Name); } else if (item.IsAudio) { parts.Add("Music"); if (!string.IsNullOrWhiteSpace(item.AlbumArtist)) { parts.Add(item.AlbumArtist); } if (!string.IsNullOrWhiteSpace(item.Album)) { parts.Add(item.Album); } } else if (string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase)) { parts.Add("Photos"); if (!string.IsNullOrWhiteSpace(item.Album)) { parts.Add(item.Album); } } return parts.Select(_fileRepository.GetValidFileName).ToList(); }
private async Task GetItem(IApiClient apiClient, ServerInfo server, SyncedItem jobItem, IProgress<double> progress, CancellationToken cancellationToken) { var libraryItem = jobItem.Item; var localItem = _localAssetManager.CreateLocalItem(libraryItem, server, jobItem.SyncJobItemId, jobItem.OriginalFileName); // Create db record await _localAssetManager.AddOrUpdate(localItem).ConfigureAwait(false); var fileTransferProgress = new DoubleProgress(); fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92)); // Download item file await _fileTransferManager.GetItemFileAsync(apiClient, server, localItem, jobItem.SyncJobItemId, fileTransferProgress, cancellationToken).ConfigureAwait(false); progress.Report(92); // Download images await GetItemImages(apiClient, localItem, cancellationToken).ConfigureAwait(false); progress.Report(95); // Download subtitles await GetItemSubtitles(apiClient, jobItem, localItem, cancellationToken).ConfigureAwait(false); progress.Report(99); // Let the server know it was successfully downloaded await apiClient.ReportSyncJobItemTransferred(jobItem.SyncJobItemId).ConfigureAwait(false); progress.Report(100); }
public void ConnectToServer(string address, string port, ServerInfo info) { //Manually connect int intPort; Int32.TryParse(port, out intPort); if (!Kernel.ConnectToServer(address, intPort, 10000, info)) { DisplayDialog(String.Format("Unable to connect to server at {0}:{1}", address, port), "Connect Failed"); } else { Logger.ReportInfo("Connected to server {0} at {1}:{2}", Kernel.ServerInfo.ServerName, address, port); Logger.ReportInfo("Server version: " + Kernel.ServerInfo.Version); Login(); } }
private async Task SyncData(IApiClient apiClient, ServerInfo serverInfo, bool syncUserItemAccess, CancellationToken cancellationToken) { _logger.Debug("Beginning SyncData with server {0}", serverInfo.Name); var localIds = await _localAssetManager.GetServerItemIds(serverInfo.Id).ConfigureAwait(false); var result = await apiClient.SyncData(new SyncDataRequest { TargetId = apiClient.DeviceId, LocalItemIds = localIds, OfflineUserIds = serverInfo.Users.Select(i => i.Id).ToList() }).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); foreach (var itemIdToRemove in result.ItemIdsToRemove) { try { await RemoveItem(serverInfo.Id, itemIdToRemove).ConfigureAwait(false); } catch (Exception ex) { _logger.ErrorException("Error deleting item from device. Id: {0}", ex, itemIdToRemove); } } if (syncUserItemAccess) { foreach (var item in result.ItemUserAccess) { var itemid = item.Key; var localItem = await _localAssetManager.GetLocalItem(serverInfo.Id, itemid).ConfigureAwait(false); if (!localItem.UserIdsWithAccess.SequenceEqual(item.Value, StringComparer.OrdinalIgnoreCase)) { localItem.UserIdsWithAccess = item.Value; await _localAssetManager.AddOrUpdate(localItem).ConfigureAwait(false); } } } }
public void AddOrUpdateServer(ServerInfo server) { if (server == null) { throw new ArgumentNullException("server"); } // Clone the existing list of servers var list = new List<ServerInfo>(); foreach (ServerInfo serverInfo in Servers) { list.Add(serverInfo); } var index = FindIndex(list, server.Id); if (index != -1) { var existing = list[index]; // Take the most recent DateLastAccessed if (server.DateLastAccessed > existing.DateLastAccessed) { existing.DateLastAccessed = server.DateLastAccessed; } existing.UserLinkType = server.UserLinkType; if (!string.IsNullOrEmpty(server.AccessToken)) { existing.AccessToken = server.AccessToken; existing.UserId = server.UserId; } if (!string.IsNullOrEmpty(server.ExchangeToken)) { existing.ExchangeToken = server.ExchangeToken; } if (!string.IsNullOrEmpty(server.RemoteAddress)) { existing.RemoteAddress = server.RemoteAddress; } if (!string.IsNullOrEmpty(server.LocalAddress)) { existing.LocalAddress = server.LocalAddress; } if (!string.IsNullOrEmpty(server.ManualAddress)) { existing.LocalAddress = server.ManualAddress; } if (!string.IsNullOrEmpty(server.Name)) { existing.Name = server.Name; } if (server.WakeOnLanInfos != null && server.WakeOnLanInfos.Count > 0) { existing.WakeOnLanInfos = new List<WakeOnLanInfo>(); foreach (WakeOnLanInfo info in server.WakeOnLanInfos) { existing.WakeOnLanInfos.Add(info); } } if (server.LastConnectionMode.HasValue) { existing.LastConnectionMode = server.LastConnectionMode; } foreach (ServerUserInfo user in server.Users) { existing.AddOrUpdate(user); } } else { list.Add(server); } Servers = list; }
public async Task<ConnectionResult> Connect(string address, CancellationToken cancellationToken = default(CancellationToken)) { address = NormalizeAddress(address); var publicInfo = await TryConnect(address, 15000, cancellationToken).ConfigureAwait(false); if (publicInfo == null) { return new ConnectionResult { State = ConnectionState.Unavailable, ConnectUser = ConnectUser }; } var server = new ServerInfo { ManualAddress = address, LastConnectionMode = ConnectionMode.Manual }; server.ImportInfo(publicInfo); return await Connect(server, cancellationToken).ConfigureAwait(false); }
private async Task SyncInternal(ServerInfo server, IApiClient apiClient, IProgress<double> progress, CancellationToken cancellationToken) { const double cameraUploadTotalPercentage = .25; var uploadProgress = new DoubleProgress(); uploadProgress.RegisterAction(p => progress.Report(p * cameraUploadTotalPercentage)); await new ContentUploader(apiClient, _logger) .UploadImages(uploadProgress, cancellationToken).ConfigureAwait(false); if (_clientCapabilities.SupportsOfflineAccess) { await new OfflineUserSync(_localAssetManager, _logger) .UpdateOfflineUsers(server, apiClient, cancellationToken).ConfigureAwait(false); } var syncProgress = new DoubleProgress(); syncProgress.RegisterAction(p => progress.Report((cameraUploadTotalPercentage * 100) + (p * (1 - cameraUploadTotalPercentage)))); await new MediaSync(_localAssetManager, _logger, _fileTransferManager) .Sync(apiClient, server, uploadProgress, cancellationToken).ConfigureAwait(false); }
public void SetServerInfo(ServerInfo serverInfo) { ServerInfo = serverInfo; SendEvent(); }
private async Task ValidateAuthentication(ServerInfo server, ConnectionMode connectionMode, ConnectionOptions options, CancellationToken cancellationToken) { _logger.Debug("Validating saved authentication"); var url = server.GetAddress(connectionMode); var headers = new HttpHeaders(); headers.SetAccessToken(server.AccessToken); var request = new HttpRequest { CancellationToken = cancellationToken, Method = "GET", RequestHeaders = headers, Url = url + "/emby/system/info?format=json" }; try { using (var stream = await _httpClient.SendAsync(request).ConfigureAwait(false)) { var systemInfo = JsonSerializer.DeserializeFromStream<SystemInfo>(stream); server.ImportInfo(systemInfo); } if (!string.IsNullOrEmpty(server.UserId)) { request.Url = url + "/mediabrowser/users/" + server.UserId + "?format=json"; using (var stream = await _httpClient.SendAsync(request).ConfigureAwait(false)) { var localUser = JsonSerializer.DeserializeFromStream<UserDto>(stream); SaveUserInfoIntoCredentials(server, localUser); OnLocalUserSignIn(options, localUser); } } } catch (OperationCanceledException) { throw; } catch (Exception ex) { // Already logged at a lower level server.UserId = null; server.AccessToken = null; } }
/// <summary> /// Wakes a server /// </summary> private async Task WakeServer(ServerInfo server, CancellationToken cancellationToken) { foreach (var info in server.WakeOnLanInfos) { await WakeServer(info, cancellationToken).ConfigureAwait(false); } }
private async Task ReportOfflineActions(IApiClient apiClient, ServerInfo serverInfo, CancellationToken cancellationToken) { var actions = await _localAssetManager.GetUserActions(serverInfo.Id).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var actionList = actions .OrderBy(i => i.Date) .ToList(); _logger.Debug("Reporting {0} offline actions to server {1}", actionList.Count, serverInfo.Id); if (actionList.Count > 0) { await apiClient.ReportOfflineActions(actionList).ConfigureAwait(false); } foreach (var action in actionList) { await _localAssetManager.Delete(action).ConfigureAwait(false); } }