예제 #1
0
        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));
            }
        }
예제 #3
0
        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> &#09; {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);
        }