public void WithUnrecordedEnglishCulture_FallbackToEnglishOthersCulture()
        {
            var recognizer  = new DateTimeRecognizer(OtherEnglishCulture);
            var testedModel = recognizer.GetDateTimeModel(OtherEnglishCulture);

            TestDateTime(testedModel, otherEnglishControlModel, TestInput);
        }
        public void WithInvalidCulture_AlwaysUseEnglish()
        {
            var recognizer  = new DateTimeRecognizer();
            var testedModel = recognizer.GetDateTimeModel(InvalidCulture);

            TestDateTime(testedModel, defaultEnglishControlModel, TestInput);
        }
        public void WithoutTargetCultureAndWithoutCulture_FallbackToEnglishCulture()
        {
            var recognizer  = new DateTimeRecognizer();
            var testedModel = recognizer.GetDateTimeModel();

            TestDateTime(testedModel, defaultEnglishControlModel, TestInput);
        }
Beispiel #4
0
        public override ValidatorResult <DateTime> Validate(IBotContext context)
        {
            // Recognize Date
            DateTimeRecognizer dateRecognizer = DateTimeRecognizer.GetInstance(DateTimeOptions.None);
            DateTimeModel      dateModel      = dateRecognizer.GetDateTimeModel("en-US");
            var result = dateModel.Parse(context.Request.AsMessageActivity().Text);

            if (result.Count > 0 && !string.IsNullOrEmpty(result[0].Text))
            {
                try
                {
                    return(new ValidatorResult <DateTime>
                    {
                        Value = DateTime.ParseExact(result[0].Text, "yyyy-MM-dd", CultureInfo.CurrentCulture)
                    });
                }
                catch (Exception e)
                {
                    return(new ValidatorResult <DateTime>
                    {
                        Reason = Constants.DATE_ERROR
                    });
                }
            }
            else
            {
                return(new ValidatorResult <DateTime>
                {
                    Reason = Constants.DATE_ERROR
                });
            }
        }
        public void WithOtherCulture_NotUseTargetCulture()
        {
            var recognizer  = new DateTimeRecognizer(SpanishCulture);
            var testedModel = recognizer.GetDateTimeModel(DefaultEnglishCulture);

            TestDateTime(testedModel, defaultEnglishControlModel, TestInput);
        }
        public void WithInvalidCulture_UseTargetCulture()
        {
            var recognizer  = new DateTimeRecognizer(EnglishCulture);
            var testedModel = recognizer.GetDateTimeModel(InvalidCulture);

            TestDateTime(testedModel, controlModel, TestInput);
        }
        private DisambiguateDateDialog() : base(Id)
        {
            var recognizer = new DateTimeRecognizer(Culture.English);
            var model      = recognizer.GetDateTimeModel();

            Dialogs.Add(Id, new WaterfallStep[]
            {
                async(dc, args, next) => {
                    await dc.Context.SendActivity("What date?");
                },
                async(dc, args, next) =>
                {
                    var stateWrapper = new DisambiguateDateDialogStateWrapper(dc.ActiveDialog.State);

                    var value = model.Parse(dc.Context.Activity.Text).ParseRecognizer();

                    stateWrapper.Resolutions = value;

                    if (value.ResolutionType != Resolution.ResolutionTypes.DateTime && value.ResolutionType != Resolution.ResolutionTypes.DateTimeRange)
                    {
                        await dc.Context.SendActivity("I don't understand. Please provide a date");
                        await dc.Replace(Id);
                    }
                    else if (value.NeedsDisambiguation)
                    {
                        var amOrPmChoices = new List <Choice>(new [] { new Choice()
                                                                       {
                                                                           Value = "AM"
                                                                       }, new Choice()
                                                                       {
                                                                           Value = "PM"
                                                                       } });
                        await dc.Prompt("choicePrompt", "Is that AM or PM?", new ChoicePromptOptions
                        {
                            Choices = amOrPmChoices
                        }).ConfigureAwait(false);
                    }
                    else
                    {
                        stateWrapper.Date = value.FirstOrDefault().Date1.Value;
                        await dc.End(dc.ActiveDialog.State);
                    }
                },
                async(dc, args, next) =>
                {
                    var stateWrapper   = new DisambiguateDateDialogStateWrapper(dc.ActiveDialog.State);
                    var amOrPmChoice   = ((FoundChoice)args["Value"]).Value;
                    var availableTimes = stateWrapper.Resolutions.Select(x => x.Date1.Value);
                    stateWrapper.Date  = amOrPmChoice == "AM" ? availableTimes.Min() : availableTimes.Max();
                    await dc.End(dc.ActiveDialog.State);
                }
            });

            Dialogs.Add("textPrompt", new TextPrompt());
            Dialogs.Add("choicePrompt", new ChoicePrompt("en"));
        }
        private DisambiguateRoomDialog() : base(Id)
        {
            var recognizer = new DateTimeRecognizer(Culture.English);
            var model      = recognizer.GetDateTimeModel();

            Dialogs.Add(Id, new WaterfallStep[]
            {
                async(dc, args, next) =>
                {
                    var stateWrapper = new DisambiguateRoomDialogStateWrapper(dc.ActiveDialog.State)
                    {
                        Booking = (BookingRequest)args["bookingRequest"]
                    };
                    var bookingRequest = stateWrapper.Booking;

                    bookingRequest.AvailableRooms = (await MicrosoftGraphExtensions.GetMicrosoftGraphFindMeetingRooms(
                                                         dc.Context.Services.Get <ConversationAuthToken>(AzureAdAuthMiddleware.AUTH_TOKEN_KEY).AccessToken)).ToArray();

                    if (string.IsNullOrEmpty(bookingRequest.Room))
                    {
                        var roomChoices = new List <Choice> {
                            new Choice {
                                Value = "No preference"
                            }
                        };
                        roomChoices.AddRange(from room in bookingRequest.AvailableRooms select new Choice {
                            Value = room.DisplayName
                        });

                        await dc.Prompt("choicePrompt", "Do you have a preference which room?", new ChoicePromptOptions
                        {
                            Choices = roomChoices
                        }).ConfigureAwait(false);
                    }
                    else
                    {
                        await dc.End();
                    }
                },
                async(dc, args, next) =>
                {
                    await dc.End(new Dictionary <string, object>
                    {
                        ["Value"] = ((FoundChoice)args["Value"]).Value
                    });
                }
            });

            Dialogs.Add("choicePrompt", new ChoicePrompt("en"));
        }
        public void WithInvalidCultureAsTargetAndWithoutFallback_ThrowError()
        {
            var recognizer = new DateTimeRecognizer(InvalidCulture);

            Assert.ThrowsException <ArgumentException>(() => recognizer.GetDateTimeModel(fallbackToDefaultCulture: false));
        }
        protected override async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> activity)
        {
            try
            {
                var message       = await activity;
                var quitCondition = message.Text.ToLower().Contains("cancel");

                if (quitCondition)
                {
                    request.ResetDateTime();
                    context.Done(request);
                }
                else
                {
                    var recognizer    = new DateTimeRecognizer(message.Locale, DateTimeOptions.None, false);
                    var dateTimeModel = recognizer.GetDateTimeModel();
                    var results       = dateTimeModel.Parse(message.Text, PSTDateTime);

                    if (!results.Any())
                    {
                        request.ResetDateTime();
                        await context.PostAsync("Sorry, I didn't understand you, can you try again with a date and time?", message.Locale);

                        context.Wait(MessageReceivedAsync);
                        return;
                    }

                    List <Dictionary <string, string> > modelValuesDictionary = (List <Dictionary <string, string> >)results[0].Resolution["values"];
                    var modelResult = modelValuesDictionary.First();
                    if (modelResult["type"] == "time")
                    {
                        var parsedTime = DateTime.Parse(modelResult["value"]);
                        request.StartDateTime = parsedTime;
                        timeValue             = parsedTime.ToShortTimeString();
                        var response = await request.IsAvailableAsync();

                        if (response.IsAvailable)
                        {
                            var promptTodayConfirmation = new PromptDialog.PromptConfirm(
                                $"I assumed today and found {timeValue}, everything looks available at the moment but can confirm you that's what you meant?",
                                "Sorry I didn't understand you. Can you choose an option below?",
                                2);
                            context.Call(promptTodayConfirmation, this.AfterTodayConfirmation);
                        }
                        else
                        {
                            if (response.SuggestedRequest == null)
                            {
                                await context.PostAsync($"I looked at {request.ToSuggestionString()}, I couldn't give you a suggested appointment. {response.FormattedValidationMessage()} Can you suggest both date and time which would work for you?", context.Activity.AsMessageActivity().Locale);
                            }
                            else
                            {
                                suggestedAppointmentRequest = response.SuggestedRequest;
                                var promptSuggestionConfirmation = new PromptDialog.PromptConfirm(
                                    response.FormattedValidationMessage(),
                                    "Sorry I didn't understand you. Can you choose an option below?",
                                    2);
                                context.Call(promptSuggestionConfirmation, this.AfterSuggestionConfirmation);
                            }
                        }
                    }
                    else if (modelResult["type"] == "datetime")
                    {
                        var parsedTime = DateTime.Parse(modelResult["value"]);
                        parsedTime = DateTime.SpecifyKind(parsedTime, DateTimeKind.Local);
                        if (parsedTime.Date.Year < PSTDate.Year)
                        {
                            parsedTime = new DateTime(PSTDate.Year, parsedTime.Month, parsedTime.Day, parsedTime.Hour, parsedTime.Minute, 0);
                        }

                        if (parsedTime.Date < PSTDate)
                        {
                            // fix bias for past days of the week
                            var fix = parsedTime.Next(parsedTime.DayOfWeek);
                            parsedTime = new DateTime(PSTDate.Year, fix.Month, fix.Day, parsedTime.Hour, parsedTime.Minute, 0);
                        }

                        if (parsedTime.Date == PSTDate && parsedTime.Hour < PSTDateTime.Hour &&
                            (parsedTime.Hour >= 1 || parsedTime.Hour <= 9))
                        {
                            // fix bias for time of the day
                            parsedTime = parsedTime.AddHours(12);
                        }

                        timeValue             = parsedTime.ToShortTimeString();
                        request.StartDateTime = parsedTime;
                        var response = await request.IsAvailableAsync();

                        if (response.IsAvailable)
                        {
                            await context.PostAsync("Great, that will work.", message.Locale);

                            context.Done(request);
                        }
                        else
                        {
                            if (response.SuggestedRequest == null)
                            {
                                await context.PostAsync($"I looked at {request.ToSuggestionString()}, I couldn't give you a suggested appointment. {response.FormattedValidationMessage()} Can you suggest both date and time which would work for you?", context.Activity.AsMessageActivity().Locale);
                            }
                            else
                            {
                                suggestedAppointmentRequest = response.SuggestedRequest;
                                var promptSuggestionConfirmation = new PromptDialog.PromptConfirm(
                                    response.FormattedValidationMessage(),
                                    "Sorry I didn't understand you. Can you choose an option below?",
                                    2);
                                context.Call(promptSuggestionConfirmation, this.AfterSuggestionConfirmation);
                            }
                        }
                    }
                    else if (modelResult["type"] == "date")
                    {
                        var parsedDate = DateTime.Parse(modelResult["value"]);
                        if (parsedDate.Year < PSTDate.Year)
                        {
                            parsedDate = parsedDate.SafeCreateFromValue(PSTDate.Year, parsedDate.Month, parsedDate.Day);
                        }

                        if (parsedDate < PSTDate)
                        {
                            // fix bias for past Saturday/Sunday
                            var fix = parsedDate.Next(parsedDate.DayOfWeek);
                            parsedDate = fix.SafeCreateFromValue(PSTDate.Year, fix.Month, fix.Day);
                        }

                        request.StartDateTime = new DateTime(parsedDate.Year, parsedDate.Month, parsedDate.Day, PSTDateTime.Hour, PSTDateTime.Minute, 0, DateTimeKind.Local);
                        var response = await request.IsAvailableAsync();

                        if (response.IsAvailable)
                        {
                            var promptTodayConfirmation = new PromptDialog.PromptConfirm(
                                $"I found {request.ToSuggestionString()}, everything looks available at the moment but can you confirm that's what you meant?",
                                "Sorry I didn't understand you. Can you choose an option below?",
                                2);
                            context.Call(promptTodayConfirmation, this.AfterTimeConfirmation);
                        }
                        else
                        {
                            if (response.SuggestedRequest == null)
                            {
                                await context.PostAsync($"I looked at {request.ToSuggestionString()}, I couldn't give you a suggested appointment. Can you suggest both date and time which would work for you?", context.Activity.AsMessageActivity().Locale);
                            }
                            else
                            {
                                suggestedAppointmentRequest = response.SuggestedRequest;
                                await context.PostAsync($"I looked at {request.ToSuggestionString()}", context.Activity.AsMessageActivity().Locale);

                                var promptSuggestionConfirmation = new PromptDialog.PromptConfirm(
                                    response.FormattedValidationMessage().Replace("Sorry", "But sorry"),
                                    "Sorry I didn't understand you. Can you choose an option below?",
                                    2);
                                context.Call(promptSuggestionConfirmation, this.AfterSuggestionConfirmation);
                            }
                        }
                    }
                    else
                    {
                        request.ResetDateTime();
                        context.Done(request);
                    }
                }
            }
            catch (TooManyAttemptsException)
            {
                request.ResetDateTime();
                context.Done(request);
            }
        }
        private DisambiguateTimeDialog() : base(Id)
        {
            var recognizer = new DateTimeRecognizer(Culture.English);
            var model      = recognizer.GetDateTimeModel();

            AddDialog(new WaterfallDialog(Id, new WaterfallStep[]
            {
                async(dc, cancellationToken) =>
                {
                    await dc.Context.SendActivityAsync("What time?");
                    return(EndOfTurn);
                },
                async(dc, cancellationToken) =>
                {
                    var stateWrapper = new DisambiguateTimeDialogStateWrapper(dc.ActiveDialog.State);

                    var value = model.Parse(dc.Context.Activity.Text).ParseRecognizer();

                    stateWrapper.Resolutions = value;

                    if (value.ResolutionType != Resolution.ResolutionTypes.Time &&
                        value.ResolutionType != Resolution.ResolutionTypes.TimeRange)
                    {
                        await dc.Context.SendActivityAsync("I don't understand. Please provide a time");
                        return(await dc.ReplaceDialogAsync(Id));
                    }

                    if (value.NeedsDisambiguation)
                    {
                        var amOrPmChoices = new List <Choice>(new[]
                                                              { new Choice()
                                                                {
                                                                    Value = "AM"
                                                                }, new Choice()
                                                                {
                                                                    Value = "PM"
                                                                } });
                        return(await dc.PromptAsync("choicePrompt", new PromptOptions
                        {
                            Prompt = new Activity
                            {
                                Type = ActivityTypes.Message,
                                Text = "Is that AM or PM?"
                            },
                            Choices = amOrPmChoices
                        }).ConfigureAwait(false));
                    }

                    stateWrapper.Time = value.FirstOrDefault().Time1.Value;
                    return(await dc.EndDialogAsync(dc.ActiveDialog.State));
                },
                async(dc, cancellationToken) =>
                {
                    var stateWrapper   = new DisambiguateTimeDialogStateWrapper(dc.ActiveDialog.State);
                    var amOrPmChoice   = ((FoundChoice)dc.Result).Value;
                    var availableTimes = stateWrapper.Resolutions.Select(x => x.Time1.Value);
                    stateWrapper.Time  = amOrPmChoice == "AM" ? availableTimes.Min() : availableTimes.Max();
                    return(await dc.EndDialogAsync(dc.ActiveDialog.State));
                }
            }));

            AddDialog(new TextPrompt("textPrompt"));
            AddDialog(new ChoicePrompt("choicePrompt", defaultLocale: "en"));
        }
        public void InitializationNonLazy_CanGetModel()
        {
            var recognizer = new DateTimeRecognizer(EnglishCulture, DateTimeOptions.None, lazyInitialization: false);

            Assert.AreEqual(recognizer.GetDateTimeModel(), recognizer.GetDateTimeModel(EnglishCulture));
        }
        public void WithoutTargetCultureAndWithoutCulture_FallbackToEnglishCulture()
        {
            var recognizer = new DateTimeRecognizer();

            Assert.AreEqual(recognizer.GetDateTimeModel(), recognizer.GetDateTimeModel(EnglishCulture));
        }
        public void WithInvalidCulture_UseTargetCulture()
        {
            var recognizer = new DateTimeRecognizer(EnglishCulture);

            Assert.AreEqual(recognizer.GetDateTimeModel(InvalidCulture), recognizer.GetDateTimeModel());
        }
        public void WithOtherCulture_NotUseTargetCulture()
        {
            var recognizer = new DateTimeRecognizer(EnglishCulture);

            Assert.AreNotEqual(recognizer.GetDateTimeModel(SpanishCulture), recognizer.GetDateTimeModel());
        }