private void StartObservingRooms() { StopObserving(); RealtimeService.ObserveAllChatRooms(room => { if (string.IsNullOrEmpty(room.Id) || string.IsNullOrEmpty(room.Name)) { return; } ChatRoomItemViewModel existingRoom = Rooms.FirstOrDefault(r => r.Id == room.Id); if (existingRoom == null) { Rooms.Add(new ChatRoomItemViewModel() { Name = room.Name, Id = room.Id, ParticipantCount = room.Users == null ? 0 : room.Users.Count }); } else { existingRoom.Name = room.Name; existingRoom.ParticipantCount = room.Users == null ? 0 : room.Users.Count; } IsBusy = false; }); }
/// <summary> Check that a share link is valid for a project and add the user to the project. </summary> public async Task CheckLinkSharingAsync(string curUserId, string projectId, string shareKey) { using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <SFProject> projectDoc = await GetProjectDocAsync(projectId, conn); if (projectDoc.Data.UserRoles.ContainsKey(curUserId)) { return; } IDocument <User> userDoc = await conn.FetchAsync <User>(curUserId); string projectRole; // Attempt to get the role for the user from the Paratext registry Attempt <string> attempt = await TryGetProjectRoleAsync(projectDoc.Data, curUserId); if (!attempt.TryResult(out projectRole)) { // Get the project role that is specified in the sharekey Attempt <SFProjectSecret> psAttempt = await ProjectSecrets.TryGetAsync(projectId); if (psAttempt.TryResult(out SFProjectSecret ps)) { projectRole = ps.ShareKeys.SingleOrDefault(sk => sk.Key == shareKey)?.ProjectRole; } } // The share key was invalid if (projectRole == null) { throw new ForbiddenException(); } bool linkSharing = projectDoc.Data.CheckingConfig.ShareEnabled && projectDoc.Data.CheckingConfig.ShareLevel == CheckingShareLevel.Anyone; if (linkSharing) { // Add the user and remove the specific user share key if it exists. Link sharing keys // have Email set to null and will not be removed. await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole, true); return; } // Look for a valid specific user share key. SFProjectSecret projectSecret = await ProjectSecrets.UpdateAsync( p => p.Id == projectId && p.ShareKeys.Any( sk => sk.Email != null && sk.Key == shareKey && sk.ExpirationTime > DateTime.UtcNow), update => update.RemoveAll(p => p.ShareKeys, sk => sk.Key == shareKey) ); if (projectSecret != null) { await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole, false); return; } throw new ForbiddenException(); } }
public void AddData(string answerSyncUserId1, string answerSyncUserId2, string commentSyncUserId1, string commentSyncUserId2, bool useAudioResponses = false) { RealtimeService.AddRepository("questions", OTType.Json0, new MemoryRepository <Question>(new[] { new Question { Id = "project01:question01", DataId = "question01", VerseRef = new VerseRefData(40, 1, 1), Text = useAudioResponses ? "" : "Test question?", Answers = { new Answer { DataId = "answer01", OwnerRef = "user02", SyncUserRef = answerSyncUserId1, DateCreated = new DateTime(2019, 1, 1, 8, 0, 0, DateTimeKind.Utc), Text = useAudioResponses ? "" : "Test answer 1.", Comments = { new Comment { DataId = "comment01", OwnerRef = "user03", SyncUserRef = commentSyncUserId1, DateCreated = new DateTime(2019, 1, 1, 9, 0, 0, DateTimeKind.Utc), Text = "Test comment 1." } } }, new Answer { DataId = "answer02", OwnerRef = "user04", SyncUserRef = answerSyncUserId2, DateCreated = new DateTime(2019, 1, 2, 8, 0, 0, DateTimeKind.Utc), Text = "Test answer 2.", VerseRef = new VerseRefData(40, 1, "2-3"), ScriptureText = "This is some scripture.", Comments = { new Comment { DataId = "comment02", OwnerRef = "user02", SyncUserRef = commentSyncUserId2, DateCreated = new DateTime(2019, 1, 2, 9, 0, 0, DateTimeKind.Utc), Text = "Test comment 2." } } } } } })); }
public async Task DeleteProjectAsync(string curUserId, string projectId) { string ptProjectId; using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <SFProject> projectDoc = await conn.FetchAsync <SFProject>(projectId); if (!projectDoc.IsLoaded) { throw new DataNotFoundException("The project does not exist."); } if (!IsProjectAdmin(projectDoc.Data, curUserId)) { throw new ForbiddenException(); } ptProjectId = projectDoc.Data.ParatextId; // delete the project first, so that users get notified about the deletion string[] projectUserIds = projectDoc.Data.UserRoles.Keys.ToArray(); await projectDoc.DeleteAsync(); async Task removeUser(string projectUserId) { IDocument <User> userDoc = await conn.FetchAsync <User>(projectUserId); await RemoveUserFromProjectAsync(conn, projectDoc, userDoc); } var tasks = new List <Task>(); foreach (string projectUserId in projectUserIds) { tasks.Add(removeUser(projectUserId)); } await Task.WhenAll(tasks); } await ProjectSecrets.DeleteAsync(projectId); await RealtimeService.DeleteProjectAsync(projectId); await _engineService.RemoveProjectAsync(projectId); string projectDir = Path.Combine(SiteOptions.Value.SiteDir, "sync", ptProjectId); if (FileSystemService.DirectoryExists(projectDir)) { FileSystemService.DeleteDirectory(projectDir); } string audioDir = GetAudioDir(projectId); if (FileSystemService.DirectoryExists(audioDir)) { FileSystemService.DeleteDirectory(audioDir); } }
protected async Task <TModel> GetProjectAsync(string projectId) { Attempt <TModel> projectAttempt = await RealtimeService.TryGetSnapshotAsync <TModel>(projectId); if (!projectAttempt.TryResult(out TModel project)) { throw new DataNotFoundException("The project does not exist."); } return(project); }
/// <summary> Determine if the specified project is an active source project. </summary> public bool IsSourceProject(string projectId) { IQueryable <SFProject> projectQuery = RealtimeService.QuerySnapshots <SFProject>(); return(projectQuery.Any(p => p.TranslateConfig.Source != null && p.TranslateConfig.Source.ProjectRef == projectId && p.TranslateConfig.TranslationSuggestionsEnabled )); }
public async Task <IEnumerable <SFProject> > GetSFProjects(string[] sfProjectIds) { List <SFProject> projectsResults = new List <SFProject>(); foreach (string id in sfProjectIds) { SFProject proj = await RealtimeService.GetSnapshotAsync <SFProject>(id); projectsResults.Add(proj); } return(projectsResults); }
public async Task SetSyncDisabledAsync(string curUserId, string systemRole, string projectId, bool isDisabled) { if (systemRole != SystemRole.SystemAdmin) { throw new ForbiddenException(); } using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <TModel> projectDoc = await GetProjectDocAsync(projectId, conn); await projectDoc.SubmitJson0OpAsync(op => op.Set(p => p.SyncDisabled, isDisabled)); } }
public async Task SyncAsync(string curUserId, string projectId) { Attempt <SFProject> attempt = await RealtimeService.TryGetSnapshotAsync <SFProject>(projectId); if (!attempt.TryResult(out SFProject project)) { throw new DataNotFoundException("The project does not exist."); } if (!IsProjectAdmin(project, curUserId)) { throw new ForbiddenException(); } await _syncService.SyncAsync(curUserId, projectId, false); }
public async Task <bool> InviteAsync(string curUserId, string projectId, string email) { SFProject project = await GetProjectAsync(projectId); if (await RealtimeService.QuerySnapshots <User>() .AnyAsync(u => project.UserRoles.Keys.Contains(u.Id) && u.Email == email)) { return(false); } SiteOptions siteOptions = SiteOptions.Value; if (!project.CheckingConfig.ShareEnabled && !IsProjectAdmin(project, curUserId)) { throw new ForbiddenException(); } // Invite a specific person. Reuse prior code, if any. SFProjectSecret projectSecret = await ProjectSecrets.UpdateAsync( p => p.Id == projectId && !p.ShareKeys.Any(sk => sk.Email == email), update => update.Add(p => p.ShareKeys, new ShareKey { Email = email, Key = _securityService.GenerateKey() })); if (projectSecret == null) { projectSecret = await ProjectSecrets.GetAsync(projectId); } string key = projectSecret.ShareKeys.Single(sk => sk.Email == email).Key; string url = $"{siteOptions.Origin}projects/{projectId}?sharing=true&shareKey={key}"; string emailSpecificLinkMessage = _localizer[SharedResource.Keys.InviteLinkSharingOff]; User inviter = await RealtimeService.GetSnapshotAsync <User>(curUserId); string subject = _localizer[SharedResource.Keys.InviteSubject, project.Name, siteOptions.Name]; var greeting = $"<p>{_localizer[SharedResource.Keys.InviteGreeting, "<p>", inviter.Name, project.Name, siteOptions.Name, $"<a href=\"{url}\">{url}</a><p>"]}"; var instructions = $"<p>{_localizer[SharedResource.Keys.InviteInstructions, siteOptions.Name, "<b>", "</b>"]}"; var pt = $"<ul><li>{_localizer[SharedResource.Keys.InvitePTOption, "<b>", "</b>", siteOptions.Name]}</li>"; var google = $"<li>{_localizer[SharedResource.Keys.InviteGoogleOption, "<b>", "</b>", siteOptions.Name]}</li>"; var facebook = $"<li>{_localizer[SharedResource.Keys.InviteFacebookOption, "<b>", "</b>", siteOptions.Name]}</li>"; var withemail = $"<li>{_localizer[SharedResource.Keys.InviteEmailOption, siteOptions.Name]}</li></ul></p><p></p>"; var signoff = $"<p>{_localizer[SharedResource.Keys.InviteSignature, "<p>", siteOptions.Name]}</p>"; var emailBody = $"{greeting}{emailSpecificLinkMessage}{instructions}{pt}{google}{facebook}{withemail}{signoff}"; await _emailService.SendEmailAsync(email, subject, emailBody); return(true); }
/// <summary> /// Disassociate user projectUserId from project projectId, if curUserId is allowed to cause that. /// </summary> public async Task RemoveUserAsync(string curUserId, string projectId, string projectUserId) { if (curUserId == null || projectId == null || projectUserId == null) { throw new ArgumentNullException(); } using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <TModel> projectDoc = await GetProjectDocAsync(projectId, conn); if (curUserId != projectUserId && !IsProjectAdmin(projectDoc.Data, curUserId)) { throw new ForbiddenException(); } await RemoveUserCoreAsync(conn, curUserId, projectId, projectUserId); } }
public async Task <bool> HasTransceleratorQuestions(string curUserId, string projectId) { using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <SFProject> projectDoc = await conn.FetchAsync <SFProject>(projectId); if (!projectDoc.IsLoaded) { throw new DataNotFoundException("The project does not exist."); } if (!IsProjectAdmin(projectDoc.Data, curUserId)) { throw new ForbiddenException(); } return(_transceleratorService.HasQuestions(projectDoc.Data.ParatextId)); } }
public async Task AddTranslateMetricsAsync(string curUserId, string projectId, TranslateMetrics metrics) { Attempt <SFProject> attempt = await RealtimeService.TryGetSnapshotAsync <SFProject>(projectId); if (!attempt.TryResult(out SFProject project)) { throw new DataNotFoundException("The project does not exist."); } if (!project.UserRoles.ContainsKey(curUserId)) { throw new ForbiddenException(); } metrics.UserRef = curUserId; metrics.ProjectRef = projectId; metrics.Timestamp = DateTime.UtcNow; await _translateMetrics.ReplaceAsync(metrics, true); }
public async Task CheckLinkSharingAsync(string curUserId, string projectId, string shareKey = null) { using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <SFProject> projectDoc = await GetProjectDocAsync(projectId, conn); if (projectDoc.Data.UserRoles.ContainsKey(curUserId)) { return; } IDocument <User> userDoc = await conn.FetchAsync <User>(curUserId); Attempt <string> attempt = await TryGetProjectRoleAsync(projectDoc.Data, curUserId); string projectRole = attempt.Result; if (shareKey != null) { string currentUserEmail = userDoc.Data.Email; SFProjectSecret projectSecret = await ProjectSecrets.UpdateAsync( p => p.Id == projectId && p.ShareKeys.Any(sk => sk.Email == currentUserEmail && sk.Key == shareKey), update => update.RemoveAll(p => p.ShareKeys, sk => sk.Email == currentUserEmail)); if (projectSecret != null) { await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole, false); return; } } if (projectDoc.Data.CheckingConfig.ShareEnabled == true && projectDoc.Data.CheckingConfig.ShareLevel == CheckingShareLevel.Anyone) { // Users with the project link get added to the project. This also covers the case where // a user was emailed a share key and the invite was cancelled, but link sharing is enabled await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole); return; } throw new ForbiddenException(); } }
/// <summary> /// Disassociate user projectUserId from all projects on the site that this ProjectService is operating on. /// As requested by curUserId. Permissions to do so are not checked. /// </summary> public async Task RemoveUserFromAllProjectsAsync(string curUserId, string projectUserId) { if (curUserId == null || projectUserId == null) { throw new ArgumentNullException(); } using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <User> userDoc = await GetUserDocAsync(projectUserId, conn); IEnumerable <Task> removalTasks = userDoc.Data.Sites[SiteOptions.Value.Id].Projects.Select( (string projectId) => RemoveUserCoreAsync(conn, curUserId, projectId, projectUserId)); // The removals can be processed in parallel in production, but for unit tests, MemoryRealtimeService // does not fully implement concurrent editing of docs, so run them in a sequence. foreach (Task task in removalTasks) { await task; } } }
private void SendMessage() { ChatMessageViewModel newMessage = new ChatMessageViewModel() { Content = _newMessage, IsBusy = true, UserName = _userName }; Messages.Add(newMessage); ChatMessage message = new ChatMessage() { Content = _newMessage, UserName = _userName, }; NewMessage = null; newMessage.Key = RealtimeService.SendMessage(message); }
public async Task AddUserAsync(string curUserId, string projectId, string projectRole) { using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <TModel> projectDoc = await GetProjectDocAsync(projectId, conn); IDocument <User> userDoc = await GetUserDocAsync(curUserId, conn); if (userDoc.Data.Role == SystemRole.User || projectRole == null) { Attempt <string> attempt = await TryGetProjectRoleAsync(projectDoc.Data, curUserId); if (!attempt.TryResult(out projectRole)) { throw new ForbiddenException(); } } await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole); } }
private void StartObservingMessages() { RealtimeService.ObserveMessages((message, key) => { _dispatcher.RequestMainThreadAction(() => { ChatMessageViewModel existingMessage = Messages.FirstOrDefault(m => m.Key == key); if (existingMessage == null) { Debug.WriteLine(key); Messages.Add(new ChatMessageViewModel() { Key = key, Content = message.Content, UserName = message.UserName }); } else { existingMessage.IsBusy = false; } }); }); }
/// <summary> /// Returns SF project id of created project. /// </summary> public async Task <string> CreateProjectAsync(string curUserId, SFProjectCreateSettings settings) { Attempt <UserSecret> userSecretAttempt = await _userSecrets.TryGetAsync(curUserId); if (!userSecretAttempt.TryResult(out UserSecret userSecret)) { throw new DataNotFoundException("The user does not exist."); } IReadOnlyList <ParatextProject> ptProjects = await _paratextService.GetProjectsAsync(userSecret); ParatextProject ptProject = ptProjects.SingleOrDefault(p => p.ParatextId == settings.ParatextId); if (ptProject == null) { throw new DataNotFoundException("The paratext project does not exist."); } var project = new SFProject { ParatextId = settings.ParatextId, Name = ptProject.Name, ShortName = ptProject.ShortName, WritingSystem = new WritingSystem { Tag = ptProject.LanguageTag }, TranslateConfig = new TranslateConfig { TranslationSuggestionsEnabled = settings.TranslationSuggestionsEnabled }, CheckingConfig = new CheckingConfig { CheckingEnabled = settings.CheckingEnabled } }; Attempt <string> attempt = await TryGetProjectRoleAsync(project, curUserId); if (!attempt.TryResult(out string projectRole) || projectRole != SFProjectRole.Administrator) { throw new ForbiddenException(); } string projectId = ObjectId.GenerateNewId().ToString(); using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { if (this.RealtimeService.QuerySnapshots <SFProject>().Any( (SFProject sfProject) => sfProject.ParatextId == project.ParatextId)) { throw new InvalidOperationException(ErrorAlreadyConnectedKey); } IDocument <SFProject> projectDoc = await conn.CreateAsync <SFProject>(projectId, project); await ProjectSecrets.InsertAsync(new SFProjectSecret { Id = projectDoc.Id }); IDocument <User> userDoc = await conn.FetchAsync <User>(curUserId); await AddUserToProjectAsync(conn, projectDoc, userDoc, SFProjectRole.Administrator, false); // Add the source after the project has been created // This will make the source project appear after the target, if it needs to be created if (settings.SourceParatextId != null && settings.SourceParatextId != settings.ParatextId) { TranslateSource source = await this.GetTranslateSourceAsync( curUserId, userSecret, settings.SourceParatextId, ptProjects); await projectDoc.SubmitJson0OpAsync(op => { UpdateSetting(op, p => p.TranslateConfig.Source, source); }); } if (projectDoc.Data.TranslateConfig.TranslationSuggestionsEnabled) { var machineProject = new MachineProject { Id = projectDoc.Id, SourceLanguageTag = projectDoc.Data.TranslateConfig.Source.WritingSystem.Tag, TargetLanguageTag = projectDoc.Data.WritingSystem.Tag }; await _engineService.AddProjectAsync(machineProject); } } await _syncService.SyncAsync(curUserId, projectId, true); return(projectId); }
public EngagementHub() { _connectionService = new ConnectionService(); _engagementService = new EngagementService(); _realtimeService = new RealtimeService(); }
public bool ContainsProject(string id) { return(RealtimeService.GetRepository <SFProject>().Contains(id)); }
public async Task <bool> InviteAsync(string curUserId, string projectId, string email, string locale, string role) { SFProject project = await GetProjectAsync(projectId); if (await RealtimeService.QuerySnapshots <User>() .AnyAsync(u => project.UserRoles.Keys.Contains(u.Id) && u.Email == email)) { return(false); } SiteOptions siteOptions = SiteOptions.Value; if (!project.CheckingConfig.ShareEnabled && !IsProjectAdmin(project, curUserId)) { throw new ForbiddenException(); } CultureInfo.CurrentUICulture = new CultureInfo(locale); // Remove the user sharekey if expired await ProjectSecrets.UpdateAsync( p => p.Id == projectId, update => update.RemoveAll(p => p.ShareKeys, sk => sk.Email == email && sk.ExpirationTime < DateTime.UtcNow) ); DateTime expTime = DateTime.UtcNow.AddDays(14); // Invite a specific person. Reuse prior code, if any. SFProjectSecret projectSecret = await ProjectSecrets.UpdateAsync( p => p.Id == projectId && !p.ShareKeys.Any(sk => sk.Email == email), update => update.Add(p => p.ShareKeys, new ShareKey { Email = email, Key = _securityService.GenerateKey(), ExpirationTime = expTime, ProjectRole = role } ) ); if (projectSecret == null) { projectSecret = await ProjectSecrets.GetAsync(projectId); int index = projectSecret.ShareKeys.FindIndex(sk => sk.Email == email); // Renew the expiration time of the valid key await ProjectSecrets.UpdateAsync( p => p.Id == projectId && p.ShareKeys.Any(sk => sk.Email == email), update => update.Set(p => p.ShareKeys[index].ExpirationTime, expTime) ); } string key = projectSecret.ShareKeys.Single(sk => sk.Email == email).Key; string url = $"{siteOptions.Origin}projects/{projectId}?sharing=true&shareKey={key}&locale={locale}"; string linkExpires = _localizer[SharedResource.Keys.InviteLinkExpires]; User inviter = await RealtimeService.GetSnapshotAsync <User>(curUserId); string subject = _localizer[SharedResource.Keys.InviteSubject, project.Name, siteOptions.Name]; var greeting = $"<p>{_localizer[SharedResource.Keys.InviteGreeting, "<p>", inviter.Name, project.Name, siteOptions.Name, $"<a href=\"{url}\">{url}</a><p>"]}"; var instructions = $"<p>{_localizer[SharedResource.Keys.InviteInstructions, siteOptions.Name, "<b>", "</b>"]}"; var pt = $"<ul><li>{_localizer[SharedResource.Keys.InvitePTOption, "<b>", "</b>", siteOptions.Name]}</li>"; var google = $"<li>{_localizer[SharedResource.Keys.InviteGoogleOption, "<b>", "</b>", siteOptions.Name]}</li>"; var facebook = $"<li>{_localizer[SharedResource.Keys.InviteFacebookOption, "<b>", "</b>", siteOptions.Name]}</li>"; var withemail = $"<li>{_localizer[SharedResource.Keys.InviteEmailOption, siteOptions.Name]}</li></ul></p><p></p>"; var signoff = $"<p>{_localizer[SharedResource.Keys.InviteSignature, "<p>", siteOptions.Name]}</p>"; var emailBody = $"{greeting}{linkExpires}{instructions}{pt}{google}{facebook}{withemail}{signoff}"; await _emailService.SendEmailAsync(email, subject, emailBody); return(true); }
// The SetupSFData method was copied from ParatextSyncRunnerTests.cs, trimmed, and modified. public void SetupSFData(bool translationSuggestionsEnabled, bool checkingEnabled) { RealtimeService.AddRepository("users", OTType.Json0, new MemoryRepository <User>(new[] { new User { Id = "user01", ParatextId = "pt01" }, new User { Id = "user02", ParatextId = "pt02" }, new User { Id = "user03", ParatextId = "pt03" } })); RealtimeService.AddRepository("sf_projects", OTType.Json0, new MemoryRepository <SFProject>( new[] { new SFProject { Id = "project01", Name = "project01", ShortName = "P01", UserRoles = new Dictionary <string, string> { { "user01", SFProjectRole.Administrator }, { "user02", SFProjectRole.Translator }, { "user03", SFProjectRole.Administrator } }, ParatextId = "target01", TranslateConfig = new TranslateConfig { TranslationSuggestionsEnabled = translationSuggestionsEnabled, Source = new TranslateSource { ParatextId = "source01", Name = "Source", ShortName = "SRC", WritingSystem = new WritingSystem { Tag = "en" } } }, CheckingConfig = new CheckingConfig { CheckingEnabled = checkingEnabled }, Sync = new Sync { QueuedCount = 1 } }, new SFProject { Id = "project02", Name = "project02", ShortName = "P02", UserRoles = new Dictionary <string, string> { { "user01", SFProjectRole.Administrator }, { "user02", SFProjectRole.Translator }, { "user03", SFProjectRole.Administrator } }, ParatextId = "target02", TranslateConfig = new TranslateConfig { TranslationSuggestionsEnabled = translationSuggestionsEnabled, Source = new TranslateSource { ParatextId = "source02", Name = "Source", ShortName = "SR2", WritingSystem = new WritingSystem { Tag = "en" } } }, CheckingConfig = new CheckingConfig { CheckingEnabled = checkingEnabled }, Sync = new Sync { QueuedCount = 1 } } })); RealtimeService.AddRepository("texts", OTType.RichText, new MemoryRepository <TextData>()); RealtimeService.AddRepository("questions", OTType.Json0, new MemoryRepository <Question>()); }
public RealtimeController() { service = new RealtimeService(); }
public TestProject GetProject(string id) { return(RealtimeService.GetRepository <TestProject>().Get(id)); }
public async Task UpdateSettingsAsync(string curUserId, string projectId, SFProjectSettings settings) { using (IConnection conn = await RealtimeService.ConnectAsync(curUserId)) { IDocument <SFProject> projectDoc = await conn.FetchAsync <SFProject>(projectId); if (!projectDoc.IsLoaded) { throw new DataNotFoundException("The project does not exist."); } if (!IsProjectAdmin(projectDoc.Data, curUserId)) { throw new ForbiddenException(); } // Get the source - any creation or permission updates are handled in GetTranslateSourceAsync TranslateSource source = null; if (settings.SourceParatextId != null) { Attempt <UserSecret> userSecretAttempt = await _userSecrets.TryGetAsync(curUserId); if (!userSecretAttempt.TryResult(out UserSecret userSecret)) { throw new DataNotFoundException("The user does not exist."); } IReadOnlyList <ParatextProject> ptProjects = await _paratextService.GetProjectsAsync(userSecret); source = await GetTranslateSourceAsync(curUserId, userSecret, settings.SourceParatextId, ptProjects, projectDoc.Data.UserRoles); if (source.ProjectRef == projectId) { // A project cannot reference itself source = null; } } await projectDoc.SubmitJson0OpAsync(op => { UpdateSetting(op, p => p.TranslateConfig.TranslationSuggestionsEnabled, settings.TranslationSuggestionsEnabled); UpdateSetting(op, p => p.TranslateConfig.Source, source); UpdateSetting(op, p => p.CheckingConfig.CheckingEnabled, settings.CheckingEnabled); UpdateSetting(op, p => p.CheckingConfig.UsersSeeEachOthersResponses, settings.UsersSeeEachOthersResponses); UpdateSetting(op, p => p.CheckingConfig.ShareEnabled, settings.ShareEnabled); UpdateSetting(op, p => p.CheckingConfig.ShareLevel, settings.ShareLevel); }); bool suggestionsEnabledSet = settings.TranslationSuggestionsEnabled != null; bool sourceParatextIdSet = settings.SourceParatextId != null; bool checkingEnabledSet = settings.CheckingEnabled != null; // check if a sync needs to be run if (suggestionsEnabledSet || sourceParatextIdSet || checkingEnabledSet) { bool trainEngine = false; if (suggestionsEnabledSet || sourceParatextIdSet) { if (projectDoc.Data.TranslateConfig.TranslationSuggestionsEnabled && projectDoc.Data.TranslateConfig.Source != null) { // translate task was enabled or source project changed // recreate Machine project only if source project changed if (!suggestionsEnabledSet && sourceParatextIdSet) { await _engineService.RemoveProjectAsync(projectId); } var machineProject = new MachineProject { Id = projectId, SourceLanguageTag = projectDoc.Data.TranslateConfig.Source.WritingSystem.Tag, TargetLanguageTag = projectDoc.Data.WritingSystem.Tag }; await _engineService.AddProjectAsync(machineProject); trainEngine = true; } else { // translate task was disabled or source project set to null await _engineService.RemoveProjectAsync(projectId); } } await _syncService.SyncAsync(curUserId, projectId, trainEngine); } } }
public AgentChatController() { _realtimeService = new RealtimeService(); }
public User GetUser(string id) { return(RealtimeService.GetRepository <User>().Get(id)); }