public void Reply(EmailMessageItem message, SalesEstimator salesEstimator) { var emailMessage = EmailMessage.Bind(_exchangeService, message.MessageId); var body = GetReplyBody(message, salesEstimator); emailMessage.Forward(body, emailMessage.From); }
private void SetAbbyInFile(SalesEstimator model, AttachmentUnit unit, String fullAbbyInPath) { String fileName = Path.GetFileNameWithoutExtension(unit.PhisicalName); String extension = Path.GetExtension(unit.PhisicalName); if (!String.IsNullOrWhiteSpace(fileName)) { unit.AbbyFilePath = String.Format("{0}\\{1}{2}{3}", fullAbbyInPath, fileName, DateTime.UtcNow.Ticks, extension); File.Move(unit.PhisicalName, unit.AbbyFilePath); } else { model.AddError(String.Format("Incorect file name: {0}\n file:{1}", fileName, unit.PhisicalName)); } }
private String GetReplyBody(EmailMessageItem message, SalesEstimator salesEstimator) { var totalTat = 0.0; var totalCost = 0m; var totalWordCount = 0; var body = new StringBuilder(); body.AppendFormat("Message <strong>'{0}'</strong> processing completed successfully!", message.Subject); body.AppendFormat("<br> Source Language - {0}", salesEstimator.SourceLanguage.Language); body.AppendFormat("<br> Target Language - {0}", salesEstimator.DestinationLanguage.Language); body.AppendFormat("<br> Rush - {0}", salesEstimator.Rush.Description()); body.AppendFormat("<br> Tier - {0}", salesEstimator.Tier.Description()); body.AppendFormat("<br>"); foreach (var wordCounter in salesEstimator.WordCounterList) { var result = salesEstimator.GetCost(wordCounter); body.AppendFormat("<br> File {0} - ${1} ({2} word(s))", wordCounter.FullFilePath, result.ToString("0.00", CultureInfo.InvariantCulture), wordCounter.WordCount); totalCost += result; totalWordCount += wordCounter.WordCount; totalTat += salesEstimator.GetTurnaroundTime(wordCounter); } body.AppendFormat("<br><br> <strong>Overall word count - {0}</strong>", totalWordCount); body.AppendFormat("<br><strong>Overall cost - ${0}</strong> {1}", Math.Max(totalCost, 150).ToString("0.00", CultureInfo.InvariantCulture), totalCost < 150 ? "<i>(there is a minimum charge of $150 associated with this request)</i>" : string.Empty); body.AppendFormat("<br><strong>Turnaround time: {0} day(s)</strong>", Math.Ceiling(totalTat)); if (salesEstimator.NotSupportedFileList.Any()) { body.Append("<br><br> Files not processed:"); foreach (var wordCounter in salesEstimator.NotSupportedFileList) { body.AppendFormat("<br> 	 {0}", wordCounter.FullFilePath); } } body.Append("<br><br>NOTE:"); body.Append("<br>This quote is for <strong>estimation purposes</strong> and is not a guarantee of cost for services. " + "Quote is based on current information from client about the project requirements. " + "<strong>Actual cost may change</strong> once project elements are finalized or negotiated. " + "Client will be notified of any changes in cost prior to them being incurred."); return(body.ToString()); }
public void AbbyProcessed(SalesEstimator model, IList <AttachmentUnit> units, String tempPath, IProgress <EstimatorBaseProgress> progress) { String abbyInPath = _settingsService.AbbyHotFolderInPath; String abbyOutPath = _settingsService.AbbyHotFolderOutPath; Boolean abbyInExists = Directory.Exists(abbyInPath); Boolean abbyOutExists = Directory.Exists(abbyOutPath); String fullAbbyInPath = abbyInPath + model.SourceLanguage.Language; String fullAbbyOutPath = abbyOutPath + model.SourceLanguage.Language; Boolean fullAbbyInExists = Directory.Exists(fullAbbyInPath); Boolean fullAbbyOutExists = Directory.Exists(fullAbbyOutPath); if (!abbyInExists || !abbyOutExists || !fullAbbyInExists || !fullAbbyOutExists) { if (!abbyInExists) { String error = String.Format("Folder {0} not found ", abbyInPath); throw new Exception(error); } if (!abbyOutExists) { String error = String.Format("Folder {0} not found ", abbyOutPath); throw new Exception(error); } if (!fullAbbyInExists) { String error = String.Format("Folder {0} not found ", fullAbbyInPath); throw new Exception(error); } else { String error = String.Format("Folder {0} not found ", fullAbbyOutPath); throw new Exception(error); } } else { foreach (AttachmentUnit unit in units.Where(u => u.CurrentType == FileType.Abby)) { SetAbbyInFile(model, unit, fullAbbyInPath); } foreach (AttachmentUnit unit in units.Where(u => u.CurrentType == FileType.Abby)) { GetAbbyOutFile(tempPath, unit, fullAbbyOutPath); } } }
private SalesEstimator EmailMessageItemProcessed(EmailMessageItem message, IEnumerable <LanguageMapping> fromEnglishMappings, IEnumerable <LanguageMapping> toEnglishMappings, IProgress <EstimatorBaseProgress> progress) { String tempFolder = _settingsService.TempAttachmentFilePath; Boolean exists = Directory.Exists(tempFolder); if (!exists) { Directory.CreateDirectory(tempFolder); } String tempPath = String.Format("{0}{1}\\", tempFolder, DateTime.UtcNow.Ticks); exists = Directory.Exists(tempPath); if (!exists) { Directory.CreateDirectory(tempPath); } SalesEstimator model = new SalesEstimator(); String body = _emailExchangeService.GetEmailBody(message); ProgressLogTask(progress, String.Format("Parsing email {0}.", message.Subject)); WaitTask(); InputInformation inputInformation = _parsingService.ParseEmailBody(body, fromEnglishMappings, toEnglishMappings, model); String status = inputInformation.NonCorrectStatus; if (!String.IsNullOrWhiteSpace(status)) { String error = String.Format("Incorrect parsing email with Body: '{0}' <br>Error: {1}", body, status); throw new ApplicationException(error); } IList <Attachment> attach = _emailExchangeService.GetEmailAttachments(message); _fileService.FileProcessed(attach, progress, tempPath); ProgressLogTask(progress, String.Format("Sorting attachments {0}.", message.Subject)); IList <AttachmentUnit> units = _fileService.GetAttachmentUnits(tempPath); try { _zipService.UnzipProcessed(units, tempPath, progress); } catch (Exception exception) { model.AddError(exception.Message); } try { _imageService.AbbyProcessed(model, units, tempPath, progress); } catch (Exception exception) { model.AddError(exception.Message); } //convert all Xlsx and xls files to docx try { foreach (var unit in units.Where(u => u.CurrentType == FileType.Xlsx)) { ConvertExcelToText(unit, progress); } } catch (Exception ex) { model.AddError(ex.Message); } //convert all Pptx and Ppt files to docx try { foreach (var unit in units.Where(u => u.CurrentType == FileType.Pptx)) { ConvertPresentToText(unit, progress); } } catch (Exception ex) { model.AddError(ex.Message); } try { foreach (AttachmentUnit unit in units.Where(u => u.CurrentType == FileType.Docx)) { var statistic = GetStatistic(unit.PhisicalName, progress); String fileName = Path.GetFileName(unit.PhisicalName); model.WordCounterList.Add(new WordCounter { FileName = fileName, WordCount = statistic.Words, CharWithSpaceCount = statistic.CharsWithSpaces, CharWithoutSpaceCount = statistic.CharsWithoutSpaces, FullFilePath = unit.ZipFileName }); } } catch (Exception exception) { model.AddError(exception.Message); } foreach (AttachmentUnit unit in units.Where(u => u.CurrentType == FileType.None)) { String fileName = Path.GetFileName(unit.PhisicalName); model.NotSupportedFileList.Add(new WordCounter { FileName = fileName, WordCount = 0, FullFilePath = unit.ZipFileName }); } Directory.Delete(tempPath, true); return(model); }
private void RunTask(IProgress <EstimatorBaseProgress> progress) { ProgressLogTask(progress, "Task is started."); while (true) { ProgressStatusTask(progress, ProgressTaskStatus.Working); ProgressIterationTask(progress, true); ProgressLogTask(progress, "Iteration is started."); WaitTask(); IList <LanguageMapping> fromeEnglishMappings = _excelService.GetFromEnglishMappings().ToList(); IList <LanguageMapping> toEnglishMappings = _excelService.GetToEnglishMappings().ToList(); ProgressLogTask(progress, "Excel settings are read correctly."); WaitTask(); IList <EmailMessageItem> messages = _emailExchangeService.GetUnreadMessages().ToList(); ProgressInfoTask(progress, null, messages.Count, null, null); ProgressLogTask(progress, String.Format("Found {0} emails.", messages.Count)); WaitTask(); foreach (EmailMessageItem message in messages) { try { SalesEstimator model = EmailMessageItemProcessed(message, fromeEnglishMappings, toEnglishMappings, progress); _emailExchangeService.Reply(message, model); _emailExchangeService.MarkAsRead(message); ProgressInfoTask(progress, 1, null, message.Subject, null); ProgressLogTask(progress, String.Format("Emails with Subject: '{0}' processed success.", message.Subject)); WaitTask(); } catch (OperationCanceledException) { throw; } catch (ApplicationException ex) { ProgressLogTask(progress, ex.Message, ProgressType.Error); _emailExchangeService.ReplyWithException(message, ex); } catch (Exception exception) { ProgressLogTask(progress, exception.Message, ProgressType.Error); _emailExchangeService.ResendExceptionToAdmin(message, exception); } } if (messages.Any()) { ProgressLogTask(progress, "All emails processed."); WaitTask(); } ProgressStatusTask(progress, ProgressTaskStatus.Ended); ProgressIterationTask(progress, false); Int32 seconds = _settingsService.TaskPauseSeconds; ProgressLogTask(progress, String.Format("Waiting {0} seconds to next iteration.", seconds)); WaitTask(seconds * 1000); } }
public InputInformation ParseEmailBody(String body, IEnumerable <LanguageMapping> fromEnglishMappings, IEnumerable <LanguageMapping> toEnglishMappings, SalesEstimator model) { var result = new InputInformation(); var hasEngLang = false; if (body == null) { result.NonCorrectStatus += @"Body has to contains information about Source and Target Languages (Tier and Rush are optional)."; return(result); } //Regex will parse strings likes "Rush: 3", but not "Rush - 3" body = body.Replace(" -", ":"); var regex = new Regex(@"Source Language:(?<SourceLanguage>.+)\s"); var @group = regex.Match(body).Groups["SourceLanguage"]; if (group.Success) { var language = group.Value.Trim(); if (language != "English") { result.SourceLanguage = toEnglishMappings.SingleOrDefault(n => language == n.Language); if (result.SourceLanguage != null) { model.SourceLanguage = result.SourceLanguage; } else { result.NonCorrectStatus += string.Format("<br>Unknown Source Language - {0}", language); } } else { hasEngLang = true; result.SourceLanguage = new LanguageMapping { Language = language }; model.SourceLanguage = result.SourceLanguage; model.IsSourceLanguageEnglish = true; } } else { result.NonCorrectStatus += @"<br> There is no Source Language. This information is required."; } regex = new Regex(@"Target Language:(?<TargetLanguage>.+)\s"); @group = regex.Match(body).Groups["TargetLanguage"]; if (group.Success) { var language = group.Value.Trim(); if (language != "English") { result.TargetLanguage = fromEnglishMappings.SingleOrDefault(n => language == n.Language); if (result.TargetLanguage != null) { model.DestinationLanguage = result.TargetLanguage; } else { result.NonCorrectStatus += string.Format("<br>Unknown Target Language - {0}", language); } } else { hasEngLang = true; result.TargetLanguage = new LanguageMapping { Language = language }; model.DestinationLanguage = result.TargetLanguage; model.IsSourceLanguageEnglish = false; } } else { result.NonCorrectStatus += @"<br>There is no Target Language. This information is required."; } //Either Source Language or Target Language has to be English if (!hasEngLang) { result.NonCorrectStatus += @"<br>Either Source Language or Target Language has to be English."; } regex = new Regex(@"Tier:(?<Tier>.+)\s"); @group = regex.Match(body).Groups["Tier"]; if (group.Success) { var tier = group.Value.Trim(); switch (tier) { case "3": model.Tier = Tier.Tier3; break; case "3.5": model.Tier = Tier.Tier35; break; case "4": model.Tier = Tier.Tier4; break; default: result.NonCorrectStatus += string.Format("<br>Unknown Tier - {0}. Please select from next options: 3, 3.5, 4", tier); break; } } else { model.Tier = Tier.Tier4; } regex = new Regex(@"Rush:(?<Rush>.+)\s"); @group = regex.Match(body).Groups["Rush"]; if (group.Success) { string rush = group.Value.Trim().ToLower(); switch (rush) { case "1": model.Rush = Rush.Rush1; break; case "3": model.Rush = Rush.Rush3; break; case "6": model.Rush = Rush.Rush6; break; case "no": model.Rush = Rush.No; break; default: result.NonCorrectStatus += string.Format("<br>Unknown Rush - {0}. Please select from next options: No, 1, 3, 6", rush); break; } } else { model.Rush = Rush.No; } return(result); }