private async void SaveLink_OnClick(object sender, RoutedEventArgs e) { SshProfileViewModel vm = (SshProfileViewModel)DataContext; var validationResult = await vm.ValidateAsync(); if (validationResult != SshConnectionInfoValidationResult.Valid && // We may ignore empty username for links validationResult != SshConnectionInfoValidationResult.UsernameEmpty) { await new MessageDialog(validationResult.GetErrorString(Environment.NewLine), I18N.Translate("InvalidInput")).ShowAsync(); return; } string content = string.Format(ShortcutFileFormat, await _sshHelperService.ConvertToUriAsync(vm)); string fileName = string.IsNullOrEmpty(vm.Username) ? $"{vm.Host}.url" : $"{vm.Username}@{vm.Host}.url"; FileSavePicker savePicker = new FileSavePicker { SuggestedFileName = fileName, SuggestedStartLocation = PickerLocationId.Desktop }; savePicker.FileTypeChoices.Add("Shortcut", new List <string> { ".url" }); StorageFile file = await savePicker.PickSaveFileAsync(); if (file == null) { return; } try { await _trayProcessCommunicationService.SaveTextFileAsync(file.Path, content); } catch (Exception ex) { await new MessageDialog(ex.Message, I18N.Translate("Error")).ShowAsync(); } }
public SshProfilesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IFileSystemService fileSystemService, IApplicationView applicationView, ITrayProcessCommunicationService trayProcessCommunicationService) { _settingsService = settingsService; _dialogService = dialogService; _fileSystemService = fileSystemService; _applicationView = applicationView; _trayProcessCommunicationService = trayProcessCommunicationService; CreateSshProfileCommand = new RelayCommand(CreateSshProfile); CloneCommand = new RelayCommand <SshProfileViewModel>(Clone); var defaultSshProfileId = _settingsService.GetDefaultSshProfileId(); foreach (var sshProfile in _settingsService.GetSshProfiles()) { var viewModel = new SshProfileViewModel(sshProfile, settingsService, dialogService, fileSystemService, applicationView, _trayProcessCommunicationService, false); viewModel.Deleted += OnSshProfileDeleted; viewModel.SetAsDefault += OnSshProfileSetAsDefault; if (sshProfile.Id == defaultSshProfileId) { viewModel.IsDefault = true; } SshProfiles.Add(viewModel); } if (SshProfiles.Count == 0) { CreateSshProfile(); } SelectedSshProfile = SshProfiles.FirstOrDefault(p => p.IsDefault); if (SelectedSshProfile == null) { SelectedSshProfile = SshProfiles.First(); } }
public ISshConnectionInfo ParseSsh(Uri uri) { SshProfileViewModel vm = new SshProfileViewModel(null, _settingsService, _dialogService, _fileSystemService, _applicationView, _defaultValueProvider, _trayProcessCommunicationService, true) { Host = uri.Host, UseMosh = MoshUriScheme.Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase) }; if (uri.Port >= 0) { vm.SshPort = (ushort)uri.Port; } if (!string.IsNullOrEmpty(uri.UserInfo)) { string[] parts = uri.UserInfo.Split(';'); if (parts.Length > 2) { throw new FormatException($"UserInfo part contains {parts.Length} elements."); } vm.Username = HttpUtility.UrlDecode(parts[0]); if (parts.Length > 1) { // For now we are only interested in IdentityFile option Tuple <string, string> identityFileOption = ParseParams(parts[1], ',').FirstOrDefault(p => string.Equals(p.Item1, IdentityFileOptionName, StringComparison.OrdinalIgnoreCase)); vm.IdentityFile = identityFileOption?.Item2; } } if (string.IsNullOrEmpty(uri.Query)) { return(vm); } string queryString = uri.Query?.Trim(); if (string.IsNullOrEmpty(queryString)) { return(vm); } if (queryString.StartsWith('?')) { queryString = queryString.Substring(1); } foreach (Tuple <string, string> param in ParseParams(queryString, '&')) { string paramName = param.Item1.ToLower(); if (ValidMoshPortsNames.Contains(paramName)) { Match match = MoshRangeRx.Match(param.Item2); if (match.Success) { vm.MoshPortFrom = ushort.Parse(match.Groups["from"].Value); vm.MoshPortTo = ushort.Parse(match.Groups["to"].Value); } continue; } if (param.Item1.Equals(ThemeQueryStringParam, StringComparison.OrdinalIgnoreCase)) { if (Guid.TryParse(param.Item2, out Guid themeId)) { vm.TerminalThemeId = themeId; } continue; } if (param.Item2.Equals(TabQueryStringParam, StringComparison.OrdinalIgnoreCase)) { if (int.TryParse(param.Item2, out int tabThemeId)) { vm.TabThemeId = tabThemeId; } } // For now we are ignoring unknown query string arguments } return(vm); }
public async Task <string> ConvertToUriAsync(ISshConnectionInfo sshConnectionInfo) { var result = await sshConnectionInfo.ValidateAsync(); if (result != SshConnectionInfoValidationResult.Valid && // We can ignore empty username here result != SshConnectionInfoValidationResult.UsernameEmpty) { throw new ArgumentException(result.GetErrorString(), nameof(sshConnectionInfo)); } SshProfileViewModel sshConnectionInfoVm = (SshProfileViewModel)sshConnectionInfo; StringBuilder sb = new StringBuilder(sshConnectionInfoVm.UseMosh ? MoshUriScheme : SshUriScheme); sb.Append("://"); bool containsUserInfo = false; if (!string.IsNullOrEmpty(sshConnectionInfoVm.Username)) { sb.Append(HttpUtility.UrlEncode(sshConnectionInfoVm.Username)); containsUserInfo = true; } if (!string.IsNullOrEmpty(sshConnectionInfoVm.IdentityFile)) { sb.Append(";"); if (!string.IsNullOrEmpty(sshConnectionInfoVm.IdentityFile)) { sb.Append($"{IdentityFileOptionName}={HttpUtility.UrlEncode(sshConnectionInfoVm.IdentityFile)}"); } containsUserInfo = true; } if (containsUserInfo) { sb.Append("@"); } sb.Append(sshConnectionInfoVm.Host); if (sshConnectionInfoVm.SshPort != SshProfile.DefaultSshPort) { sb.Append(":"); sb.Append(sshConnectionInfoVm.SshPort.ToString("#####")); } sb.Append("/"); bool queryStringAdded = false; if (sshConnectionInfoVm.UseMosh) { sb.Append( $"?{ValidMoshPortsNames[0]}={sshConnectionInfo.MoshPortFrom:#####}-{sshConnectionInfo.MoshPortTo:#####}"); queryStringAdded = true; } if (!sshConnectionInfo.TerminalThemeId.Equals(Guid.Empty)) { if (!queryStringAdded) { sb.Append("?"); queryStringAdded = true; } else { sb.Append("&"); } sb.Append($"{ThemeQueryStringParam}={sshConnectionInfo.TerminalThemeId}"); } if (sshConnectionInfo.TabThemeId != 0) { if (!queryStringAdded) { sb.Append("?"); } else { sb.Append("&"); } sb.Append($"{TabQueryStringParam}={sshConnectionInfo.TabThemeId:##########}"); } return(sb.ToString()); }