/// <summary> /// remove user data /// </summary> /// <param name="userId"></param> /// <returns></returns> public override async Task <RServiceResult <bool> > RemoveUserData(Guid userId) { RMuseumDbContext context = _context as RMuseumDbContext; string systemEmail = $"{Configuration.GetSection("Ganjoor")["SystemEmail"]}"; var systemUserId = (Guid)(await FindUserByEmail(systemEmail)).Result.Id; if (systemUserId == userId) { return(new RServiceResult <bool>(false, "تلاش برای حذف کاربر سیستمی")); } string deletedUserEmail = $"{Configuration.GetSection("Ganjoor")["DeleteUserEmail"]}"; var deletedUserId = (Guid)(await FindUserByEmail(deletedUserEmail)).Result.Id; if (deletedUserId == userId) { return(new RServiceResult <bool>(false, "تلاش برای حذف کاربر سیستمی کاربر حذف شده")); } var reviewedRecitations = await context.Recitations.Where(r => r.ReviewerId == userId).ToListAsync(); foreach (var reviewedRecitation in reviewedRecitations) { reviewedRecitation.ReviewerId = deletedUserId; } context.UpdateRange(reviewedRecitations); await context.SaveChangesAsync(); //some tracking data related bugs makes it necessary to call this especially for same table data processing var suggestedCorrections = await context.GanjoorPoemCorrections.Where(c => c.UserId == userId).ToListAsync(); foreach (var suggestedCorrection in suggestedCorrections) { suggestedCorrection.UserId = deletedUserId; } context.UpdateRange(suggestedCorrections); await context.SaveChangesAsync(); var reviewedCorrections = await context.GanjoorPoemCorrections.Where(c => c.ReviewerUserId == userId).ToListAsync(); foreach (var reviewedCorrection in reviewedCorrections) { reviewedCorrection.ReviewerUserId = deletedUserId; } context.UpdateRange(reviewedCorrections); await context.SaveChangesAsync(); var reportedComments = await context.GanjoorReportedComments.Where(r => r.ReportedById == userId).ToListAsync(); foreach (var reportedComment in reportedComments) { reportedComment.ReportedById = deletedUserId; } context.UpdateRange(reportedComments); await context.SaveChangesAsync(); var ganjoorLinks = await context.GanjoorLinks.Where(l => l.SuggestedById == userId).ToListAsync(); foreach (var ganjoorLink in ganjoorLinks) { ganjoorLink.SuggestedById = deletedUserId; } context.UpdateRange(ganjoorLinks); await context.SaveChangesAsync(); var reviewedGanjoorLinks = await context.GanjoorLinks.Where(l => l.ReviewerId == userId).ToListAsync(); foreach (var reviewedGanjoorLink in reviewedGanjoorLinks) { reviewedGanjoorLink.ReviewerId = deletedUserId; } context.UpdateRange(reviewedGanjoorLinks); await context.SaveChangesAsync(); var pinLinks = await context.PinterestLinks.Where(l => l.SuggestedById == userId).ToListAsync(); foreach (var pinLink in pinLinks) { pinLink.SuggestedById = deletedUserId; } context.UpdateRange(pinLinks); await context.SaveChangesAsync(); var reviewedPinLinks = await context.PinterestLinks.Where(l => l.ReviewerId == userId).ToListAsync(); foreach (var reviewedPinLink in reviewedPinLinks) { reviewedPinLink.ReviewerId = deletedUserId; } context.UpdateRange(reviewedPinLinks); await context.SaveChangesAsync(); var poemMusicTracks = await context.GanjoorPoemMusicTracks.Where(m => m.SuggestedById == userId).ToListAsync(); foreach (var poemMusicTrack in poemMusicTracks) { poemMusicTrack.SuggestedById = deletedUserId; } context.UpdateRange(poemMusicTracks); await context.SaveChangesAsync(); var snapshots = await context.GanjoorPageSnapshots.Where(s => s.MadeObsoleteByUserId == userId).ToListAsync(); foreach (var snapshot in snapshots) { snapshot.MadeObsoleteByUserId = deletedUserId; } context.UpdateRange(snapshots); await context.SaveChangesAsync(); var translations = await context.GanjoorPoemTranslations.Where(t => t.UserId == userId).ToListAsync(); foreach (var translation in translations) { translation.UserId = deletedUserId; } context.UpdateRange(translations); await context.SaveChangesAsync(); var suggestedPoetNotes = await context.GanjoorPoetSuggestedSpecLines.Where(s => s.SuggestedById == userId).ToListAsync(); foreach (var suggestedPoetNote in suggestedPoetNotes) { suggestedPoetNote.SuggestedById = deletedUserId; } context.UpdateRange(suggestedPoetNotes); await context.SaveChangesAsync(); var suggestedPoetPhotos = await context.GanjoorPoetSuggestedPictures.Where(s => s.SuggestedById == userId).ToListAsync(); foreach (var suggestedPoetPhoto in suggestedPoetPhotos) { suggestedPoetPhoto.SuggestedById = deletedUserId; } context.UpdateRange(suggestedPoetPhotos); await context.SaveChangesAsync(); var visits = await context.GanjoorUserPoemVisits.Where(v => v.UserId == userId).ToListAsync(); context.RemoveRange(visits); await context.SaveChangesAsync(); var bookmarks = await context.UserBookmarks.Where(b => b.RAppUserId == userId).ToListAsync(); context.RemoveRange(bookmarks); await context.SaveChangesAsync(); var uploadSessions = await context.UploadSessions.Where(s => s.UseId == userId).ToListAsync(); context.RemoveRange(uploadSessions); await context.SaveChangesAsync(); var recitations = await context.Recitations.Where(r => r.OwnerId == userId).ToListAsync(); context.RemoveRange(recitations); await context.SaveChangesAsync(); var ganjoorBookmarks = await context.GanjoorUserBookmarks.Where(b => b.UserId == userId).ToListAsync(); context.RemoveRange(ganjoorBookmarks); await context.SaveChangesAsync(); var reportedRecitaions = await context.RecitationErrorReports.Where(r => r.ReporterId == userId).ToListAsync(); context.RemoveRange(reportedRecitaions); await context.SaveChangesAsync(); var comments = await context.GanjoorComments.Where(c => c.UserId == userId).ToListAsync(); foreach (var comment in comments) { //await _ganjoorService.DeleteMyComment(userId, comment.Id);/*had error in service initializtion, so done it in the dirty way*/ await _DeleteComment(context, comment.Id); } var recitationsVotes = await context.RecitationUserUpVotes.Where(c => c.UserId == userId).ToListAsync(); foreach (var vote in recitationsVotes) { int poemId = await context.Recitations.AsNoTracking().Where(r => r.Id == vote.RecitationId).Select(r => r.GanjoorPostId).SingleAsync(); context.Remove(vote); await context.SaveChangesAsync(); await _ReOrderPoemRecitationsAsync(context, poemId); } return(await base.RemoveUserData(userId));//notifications are deleted here, some of these operations might produce new notifications }
/// <summary> /// examine site pages for broken links /// </summary> /// <returns></returns> public RServiceResult <bool> HealthCheckContents() { _backgroundTaskQueue.QueueBackgroundWorkItem ( async token => { using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions <RMuseumDbContext>())) //this is long running job, so _context might be already been freed/collected by GC { LongRunningJobProgressServiceEF jobProgressServiceEF = new LongRunningJobProgressServiceEF(context); var job = (await jobProgressServiceEF.NewJob("HealthCheckContents", "Query data")).Result; try { var pages = await context.GanjoorPages.ToArrayAsync(); await jobProgressServiceEF.UpdateJob(job.Id, 0, $"Examining Pages"); var previousErrors = await context.GanjoorHealthCheckErrors.ToArrayAsync(); context.RemoveRange(previousErrors); await context.SaveChangesAsync(); int percent = 0; for (int i = 0; i < pages.Length; i++) { if (i * 100 / pages.Length > percent) { percent++; await jobProgressServiceEF.UpdateJob(job.Id, percent); } var hrefs = pages[i].HtmlText.Split(new[] { "href=\"" }, StringSplitOptions.RemoveEmptyEntries).Where(o => o.StartsWith("http")).Select(o => o.Substring(0, o.IndexOf("\""))); foreach (string url in hrefs) { if (url == "https://ganjoor.net" || url == "https://ganjoor.net/" || url.IndexOf("https://ganjoor.net/vazn/?") == 0 || url.IndexOf("https://ganjoor.net/simi/?v") == 0) { continue; } if (url.IndexOf("http://ganjoor.net") == 0) { context.GanjoorHealthCheckErrors.Add ( new GanjoorHealthCheckError() { ReferrerPageUrl = pages[i].FullUrl, TargetUrl = url, BrokenLink = false, MulipleTargets = false } ); await context.SaveChangesAsync(); } else if (url.IndexOf("https://ganjoor.net") == 0) { var testUrl = url.Substring("https://ganjoor.net".Length); if (testUrl[testUrl.Length - 1] == '/') { testUrl = testUrl.Substring(0, testUrl.Length - 1); } var pageCount = await context.GanjoorPages.Where(p => p.FullUrl == testUrl).CountAsync(); if (pageCount != 1) { context.GanjoorHealthCheckErrors.Add ( new GanjoorHealthCheckError() { ReferrerPageUrl = pages[i].FullUrl, TargetUrl = url, BrokenLink = pageCount == 0, MulipleTargets = pageCount != 0 } ); await context.SaveChangesAsync(); } } } } await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true); } catch (Exception exp) { await jobProgressServiceEF.UpdateJob(job.Id, 100, "", false, exp.ToString()); } } } ); return(new RServiceResult <bool>(true)); }