private async Task PurgeBackups(SourceFolder sf) { var numberToKeep = 5; if (sf.Backups.Count() > numberToKeep) { var toDelete = sf.Backups.OrderByDescending(x => x.ScheduledOn).Skip(numberToKeep).ToArray(); foreach (var b in toDelete) { try { if (File.Exists(b.FullPath)) { db.Backups.Remove(b); await db.SaveChangesAsync(); File.Delete(b.FullPath); log.LogInformation($"Backup {b.FullPath} purged"); } } catch (Exception xe) { log.LogError(xe, $"File purge failed: {b.FullPath}"); } } } }
private async Task AddFolderSource(DateTimeOffset configuredOn, FolderSource fs) { var folder = fs.Folder.ToLower(); var sf = await db.SourceFolders.SingleOrDefaultAsync(x => x.FullPath == folder); if (sf != null && sf.DisplayName != fs.DisplayName) { log.LogError($"Source folder {folder} already exists in the database: display name {sf.DisplayName}"); } else { sf = await db.SourceFolders.SingleOrDefaultAsync(x => string.Compare(x.DisplayName, fs.DisplayName, true) == 0); if (sf == null) { sf = new SourceFolder { BackupEnabled = false, DisplayName = fs.DisplayName, //Path = String.Empty, FullPath = folder, ScheduledTime = 3, Type = fs.Type }; await db.SourceFolders.AddAsync(sf); } else { sf.FullPath = fs.Folder.ToLower(); sf.Type = fs.Type; } sf.ConfiguredOn = configuredOn; await db.SaveChangesAsync(); } }
private async Task <ITaskState> DoTask(ITaskState taskState, ScheduleMode mode, CancellationToken cancellationToken) { var configuredOn = DateTimeOffset.Now; using (db = dbf.GetWebDbContext <ServiceDb>()) { await db.Database.EnsureCreatedAsync(); //var sm = new ServerManager(); //foreach (var site in sm.Sites) //{ // await AddSiteFolder(configuredOn, site); //} foreach (var fs in options.FolderSources) { await AddFolderSource(configuredOn, fs); } var staleList = await db.SourceFolders .Include(x => x.Backups) .Where(x => x.ConfiguredOn < configuredOn).ToArrayAsync(); foreach (var sf in staleList) { var backups = sf.Backups.ToArray(); db.Backups.RemoveRange(backups); db.SourceFolders.Remove(sf); log.LogInformation($"{sf.DisplayName} {sf.FullPath} (with {backups.Count()} backups) removed"); } await db.SaveChangesAsync(); var count = db.SourceFolders.Count(); log.LogInformation($"found {count} source folders in database"); return(null);// Task.FromResult<ITaskState>(null); } }
public async Task <StandardResponse> UpdateAnswerMetadata(ClaimsPrincipal identity, AnswerMetadataUpdateViewModel model, ModelStateDictionary modelState) { if (!modelState.IsValid) { return(modelState.StandardError()); } using (var db = new ServiceDb()) { using (var user = await _userService.Become(db, identity, null)) { var metadata = await _answerService.UpdateAnswerMetadata(db, user, new UpdateAnswerMeta() { AnswerId = model.AnswerId, RowVersion = model.RowVersion, Votes = model.Votes, }); await db.SaveChangesAsync(); return(StandardResponse.For(AnswerMetaViewModel.From(metadata))); } } }
public async Task <StandardResponse> AskQuestion(ClaimsPrincipal identity, QuestionAddViewModel model, ModelStateDictionary modelState) { if (!modelState.IsValid) { return(modelState.StandardError()); } using (var db = new ServiceDb()) { using (var user = await _userService.Become(db, identity, null)) { var question = await _questionService.CreateQuestion(db, user, new CreateNewQuestion() { Title = model.Title, Body = model.Body, Tags = model.Tags, Topic = model.Topic ?? Topic.DefaultTopic }); await db.SaveChangesAsync(); return(StandardResponse.For(new { question.QuestionId })); } } }
public async Task <StandardResponse> UpdateQuestion(ClaimsPrincipal identity, QuestionUpdateViewModel model, ModelStateDictionary modelState) { if (!modelState.IsValid) { return(modelState.StandardError()); } using (var db = new ServiceDb()) { using (var user = await _userService.Become(db, identity)) { await _questionService.UpdateQuestion(db, user, new UpdateQuestion() { QuestionId = model.QuestionId, RowVersion = model.RowVersion, Body = model.Body, Tags = model.Tags ?? new string[] { }, Title = model.Title, Topic = model.Topic }); await db.SaveChangesAsync(); var question = await _questionService.GetQuestion(db, user, model.QuestionId); return(StandardResponse.For(QuestionViewModel.From(question))); } } }
public async Task <StandardResponse> UpdateTopic(ClaimsPrincipal identity, TopicUpdateViewModel model, ModelStateDictionary modelState) { if (!modelState.IsValid) { return(modelState.StandardError()); } using (var db = new ServiceDb()) { using (var user = await _userService.Become(db, identity)) { var result = await _topicService.UpdateTopic(db, user, new UpdateTopic() { TopicId = model.TopicId, Description = model.Description, Icon = PangulStringEncoding.GetBytesFromDataUrl(model.Icon), IconType = PangulStringEncoding.GetTypeFromDataUrl(model.Icon), RowVersion = model.RowVersion }); await db.SaveChangesAsync(); return(StandardResponse.For(new { result.TopicId })); } } }
public async Task <IActionResult> SetSourceBackup(int id, bool enabled) { var sf = await serviceDb.SourceFolders.FindAsync(id); sf.BackupEnabled = enabled; await serviceDb.SaveChangesAsync(); return(SuccessDataResult(null)); }
private async Task RequireUserRecordForUser(string username) { using (var db = new ServiceDb()) { try { await _userService.Become(db, username, null); } catch (Exception) { await _userService.Create(db, username); await db.SaveChangesAsync(); } } }
public async Task <StandardResponse> DeleteTopic(ClaimsPrincipal identity, TopicDeleteViewModel model, ModelStateDictionary modelState) { if (!modelState.IsValid) { return(modelState.StandardError()); } using (var db = new ServiceDb()) { using (var user = await _userService.Become(db, identity)) { await _topicService.DeleteTopic(db, user, model.TopicId, model.RowVersion); await db.SaveChangesAsync(); return(StandardResponse.ForSuccess()); } } }
public async Task <StandardResponse> AddAnswerToQuestion(ClaimsPrincipal identity, AddAnswerViewModel model, ModelStateDictionary modelState) { if (!modelState.IsValid) { return(modelState.StandardError()); } using (var db = new ServiceDb()) { using (var user = await _userService.Become(db, identity, null)) { var answer = await _answerService.CreateAnswer(db, user, model.QuestionId, model.Body); await db.SaveChangesAsync(); return(StandardResponse.For(new { answer.AnswerId })); } } }
public async Task <StandardResponse> UpdateAnswer(ClaimsPrincipal identity, UpdateAnswerViewModel model, ModelStateDictionary modelState) { if (!modelState.IsValid) { return(modelState.StandardError()); } using (var db = new ServiceDb()) { using (var user = await _userService.Become(db, identity, null)) { await _answerService.UpdateExistingAnswer(db, user, new UpdateAnswer() { AnswerId = model.AnswerId, NewBody = model.Body, RowVersion = model.RowVersion }); await db.SaveChangesAsync(); return(StandardResponse.ForSuccess()); } } }
private async Task <ITaskState> DoTask(ITaskState taskState, ScheduleMode mode, CancellationToken cancellationToken) { if (options.IsBackupDestinationAvailable()) { using (db = dbf.GetWebDbContext <ServiceDb>()) { var sf = await db.SourceFolders .Include(x => x.Backups) .SingleAsync(x => x.Id == sourceFolderId); //log.LogInformation($"Backup task for source {sf.DisplayName}"); var destinationFolder = Path.Combine(options.GetBackupDestination(), sf.DisplayName); if (!Directory.Exists(destinationFolder)) { Directory.CreateDirectory(destinationFolder); log.LogInformation($"{destinationFolder} created"); } var isPending = await IsBackupPending(sf); if (isPending.result) { //log.LogInformation($"Backup of {sf.GetFullname()} to {destinationFolder} is required"); var backup = isPending.backup; var namePart = sf.DisplayName; var datePart = $"{(backup.ScheduledOn.ToString("yyyy.MM.dd"))}"; var backupFileName = $"{namePart}.{datePart}.zip"; backup.FullPath = Path.Combine(destinationFolder, backupFileName); backup.State = BackupState.Started; var now = DateTimeOffset.Now; var todaysScheduledTime = new DateTimeOffset(now.Year, now.Month, now.Day, sf.ScheduledTime, 0, 0, now.Offset); log.LogInformation($"Backup of {sf.DisplayName} to {destinationFolder} started ({(todaysScheduledTime.ToString("ddMMMyyyy HH:mm:ss"))})"); if (sf.Type == SourceType.Website) { TakeSiteOffline(sf); } await db.SaveChangesAsync(); try { if (File.Exists(backup.FullPath)) { File.Delete(backup.FullPath); log.LogWarning($"{backup.FullPath} deleted"); } zip(sf.FullPath, backup.FullPath); backup.State = BackupState.Finished; backup.BackedUpOn = DateTimeOffset.Now; await db.SaveChangesAsync(); log.LogInformation($"Backup of {sf.DisplayName} to {backup.FullPath} completed"); } catch (Exception xe) { log.LogError(xe, $"backup failed {sf.DisplayName} to {backup.FullPath}"); backup.State = BackupState.Failed; backup.BackedUpOn = DateTimeOffset.Now; await db.SaveChangesAsync(); //throw; } finally { if (sf.Type == SourceType.Website) { BringSiteOnline(sf); } } await PurgeBackups(sf); } else { log.LogInformation($"Backup of {sf.DisplayName} is not pending"); } } } else { foreach (var d in DriveInfo.GetDrives()) { log.LogInformation($"Found drive {d.Name}, label {d.VolumeLabel}, ready = {d.IsReady}"); } log.LogWarning($"Backup destination not available - no disk with volume label {options.BackupDriveLabel} found"); } return(null); }