public bool IsDataSuitable(IPerformanceData performance, IPerformanceFilter filter) { if (filter == null) { return(true); } if (filter.Locations != null && filter.Locations.Any() && !filter.Locations.Contains(performance.Location)) { return(false); } if (filter.PerformanceTypes != null && filter.PerformanceTypes.Any() && filter.PerformanceTypes.All(val => 0 != string.Compare(val, performance.Type, true))) { return(false); } if (filter.DaysOfWeek != null && filter.DaysOfWeek.Any() && !filter.DaysOfWeek.Contains(performance.DateTime.DayOfWeek)) { return(false); } return(true); }
public async Task <IPerformanceData[]> RequestProcess(IPerformanceFilter filter, CancellationToken cancellationToken) { Trace.TraceInformation("PlayBillResolver.RequestProcess started"); DateTime[] months = filter.StartDate.GetMonthsBetween(filter.EndDate); List <IPerformanceData> performances = new List <IPerformanceData>(); foreach (var dateTime in months) { cancellationToken.ThrowIfCancellationRequested(); string content = await Request(dateTime, cancellationToken); performances.AddRange(await _playbillParser.Parse(content, cancellationToken)); } cancellationToken.ThrowIfCancellationRequested(); IEnumerable <IPerformanceData> filtered = performances.Where(item => _filterChecker.IsDataSuitable(item, filter)).ToArray(); Task[] resolvePricesTasks = filtered .Select(item => Task.Run(async() => { item.MinPrice = (await _ticketParser.ParseFromUrl(item.Url, cancellationToken)).GetMinPrice(); }, cancellationToken)).ToArray(); await Task.WhenAll(resolvePricesTasks.ToArray()); Trace.TraceInformation(" PlayBillResolver.RequestProcess finished"); return(filtered.ToArray()); }
public override async Task <string> ExecuteAsync(IChatDataInfo chatInfo) { IPerformanceFilter filter = _filterhelper.GetFilter(chatInfo); IPerformanceData[] data = await _playBillResolver.RequestProcess(chatInfo.When, new DateTime(), filter); return(await PerfomancesMessage(data, filter, chatInfo.When)); }
public PlayBillResolverMock() { _playBillResolverMock.Setup(h => h.RequestProcess(It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <IPerformanceFilter>())) .Callback <DateTime, DateTime, IPerformanceFilter>((dtStart, stEnd, filterResult) => { StartDate = dtStart; Filter = filterResult; }).Returns(() => Task.FromResult(new IPerformanceData[0])); }
// first was coded the simplest merge private void MergeFilters(List <IPerformanceFilter> filters, IPerformanceFilter newFilter) { if (!filters.Any(filter => filter.StartDate.Year == newFilter.StartDate.Year && filter.StartDate.Month == newFilter.StartDate.Month)) { filters.Add(newFilter); } }
private static IPerformanceFilter GetFilter() { IPerformanceFilter filter = Bootstrapper.Resolve <IPerformanceFilter>(); //filter.Locations = new[] { "Мариинский театр", "Мариинский театр 2" }; filter.DaysOfWeek = new[] { DayOfWeek.Saturday, DayOfWeek.Sunday }; filter.PerfomanceTypes = new[] { "Опера", "Балет" }; return(filter); }
public override async Task <ITgOutboundMessage> AscUserAsync(IChatDataInfo chatInfo, CancellationToken cancellationToken) { IPerformanceFilter filter = _filterService.GetFilter(chatInfo); IPerformanceData[] data = await _playBillResolver.RequestProcess(filter, cancellationToken); return(new TgOutboundMessage(await PerformancesMessage(data, filter, chatInfo.When)) { IsEscaped = true }); }
private Task <string> PerformancesMessage(IPerformanceData[] performances, IPerformanceFilter filter, DateTime when) { var cultureRu = CultureInfo.CreateSpecificCulture("ru"); var stringBuilder = new StringBuilder(); string days = filter.DaysOfWeek != null ? filter.DaysOfWeek.Length == 1 ? $"день недели: {cultureRu.DateTimeFormat.GetDayName(filter.DaysOfWeek.First())}" : "дни недели: " + string.Join(" или ", filter.DaysOfWeek.Select(d => cultureRu.DateTimeFormat.GetDayName(d))) : string.Empty; string types = filter.PerformanceTypes == null ? "все представления" : string.Join(", ", filter.PerformanceTypes); stringBuilder.AppendLine( $"Я искал для Вас билеты на {when.ToString("MMMM yyyy", cultureRu)} {days} на {types}.".EscapeMessageForMarkupV2()); foreach (var item in performances.OrderBy(item => item.DateTime)) { string minPrice = item.MinPrice.ToString(); DateTime dt = item.DateTime.Kind == DateTimeKind.Utc ? TimeZoneInfo.ConvertTimeFromUtc(item.DateTime, _timeZoneService.TimeZone) : item.DateTime; string performanceString = $"{dt:ddMMM HH:mm} {item.Location} {item.Type} \"{item.Name}\" от {minPrice}" .EscapeMessageForMarkupV2(); stringBuilder.AppendLine(string.IsNullOrWhiteSpace(item.Url) ? performanceString : $"[{performanceString}]({item.Url.EscapeMessageForMarkupV2()})"); stringBuilder.AppendLine(""); } if (!performances.Any()) { return(Task.FromResult("Увы, я ничего не нашел. Попробуем поискать еще?".EscapeMessageForMarkupV2())); } return(Task.FromResult(stringBuilder.ToString())); }
public async Task DialogTest(long chatId, int month, DayOfWeek[] dayOfWeeks, string performanceType, params string[] commands) { IPerformanceFilter filter = null; var playBillResolverMock = new Mock <IPlayBillDataResolver>(); playBillResolverMock.Setup(h => h.RequestProcess(It.IsAny <IPerformanceFilter>(), It.IsAny <CancellationToken>())) .Callback <IPerformanceFilter, CancellationToken>((filterResult, cToken) => { filter = filterResult; }).Returns(() => Task.FromResult(new IPerformanceData[0])); bool sent = false; var tgBotServiceMock = new Mock <ITgBotService>(); tgBotServiceMock.Setup(x => x.Start(CancellationToken.None)).Verifiable(); tgBotServiceMock.Setup(x => x.SendMessageAsync(It.IsAny <long>(), It.IsAny <ITgOutboundMessage>())) .Callback(() => { sent = true; }); await using ILifetimeScope scope = _fixture.RootScope.BeginLifetimeScope(builder => { builder.RegisterInstance(playBillResolverMock.Object).As <IPlayBillDataResolver>().AsImplementedInterfaces(); builder.RegisterModule <TlBotModule>(); }); var tgProcessor = scope.Resolve <ITgBotProcessor>(); //test tgProcessor.Start(tgBotServiceMock.Object, CancellationToken.None); foreach (var cmd in commands) { tgBotServiceMock.Raise(x => x.OnMessage += null, null, Mock.Of <ITgInboundMessage>(m => m.Message == cmd && m.ChatId == chatId)); while (!sent) { await Task.Delay(10); } sent = false; } playBillResolverMock.Verify(lw => lw.RequestProcess(It.IsAny <IPerformanceFilter>(), It.IsAny <CancellationToken>()), Times.AtLeastOnce()); Assert.NotNull(filter); _output.WriteLine($"{string.Join(" ", filter.DaysOfWeek.OrderBy(d => d))}"); _output.WriteLine($"{string.Join(" ", dayOfWeeks.OrderBy(d => d))}"); Assert.True(filter.DaysOfWeek.OrderBy(d => d).SequenceEqual(dayOfWeeks.OrderBy(d => d))); Assert.Equal(month, filter.StartDate.Month); Assert.Equal(performanceType.ToLower(), filter.PerformanceTypes.First().ToLower()); tgBotServiceMock.Verify(x => x.SendMessageAsync(It.IsAny <long>(), It.IsAny <ITgOutboundMessage>()), Times.AtLeastOnce); //second dialog after first foreach (var cmd in commands) { tgBotServiceMock.Raise(x => x.OnMessage += null, null, Mock.Of <ITgInboundMessage>(m => m.Message == cmd && m.ChatId == 1)); while (!sent) { await Task.Delay(10); } sent = false; } tgProcessor.Stop(); Assert.NotNull(filter); Assert.True(filter.DaysOfWeek.OrderBy(d => d).SequenceEqual(dayOfWeeks.OrderBy(d => d))); Assert.Equal(month, filter.StartDate.Month); Assert.Equal(performanceType.ToLower(), filter.PerformanceTypes.First().ToLower()); }
private async Task <string> PerfomancesMessage(IPerformanceData[] perfomances, IPerformanceFilter filter, DateTime when) { var cultureRu = CultureInfo.CreateSpecificCulture("ru"); var stringBuilder = new StringBuilder(); string days = filter.DaysOfWeek != null ? filter.DaysOfWeek.Length == 1 ? $"день недели: {cultureRu.DateTimeFormat.GetDayName(filter.DaysOfWeek.First())}" : "дни недели: " + string.Join(" или ", filter.DaysOfWeek.Select(d => cultureRu.DateTimeFormat.GetDayName(d))) : string.Empty; string types = filter.PerfomanceTypes == null ? "все представления" : string.Join(", ", filter.PerfomanceTypes); stringBuilder.AppendLine($"Я искал для Вас билеты на {when.ToString("MMMM yyyy", cultureRu)} {days} на {types}."); foreach (var item in perfomances.OrderBy(item => item.DateTime)) { string minPrice = item.Tickets.GetMinPrice().ToString() ?? item.Tickets.Description; if (string.IsNullOrWhiteSpace(item.Url)) { stringBuilder.AppendLine($"{item.DateTime:ddMMM HH:mm} {item.Location} {item.Type} \"{item.Name}\" {minPrice}"); } else { stringBuilder.AppendLine($"[{item.DateTime:ddMMM HH:mm} {item.Location} {item.Type} \"{item.Name}\" от {minPrice}]({item.Url})"); } stringBuilder.AppendLine(""); } if (!perfomances.Any()) { return("Увы, я ничего не нашел. Попробуем поискать еще?"); } return(stringBuilder.ToString()); }
public async Task <IPerformanceData[]> RequestProcess(DateTime startDate, DateTime endDate, IPerformanceFilter filter) { string content = await Request(startDate); IPerformanceData[] perfomances = _playBillParser.Parse(content).GetAwaiter().GetResult(); IList <Task> tasks = new List <Task>(); var filtredList = perfomances.Where(item => _filterChecker.IsDataSuitable(item, filter)); foreach (var item in filtredList) { tasks.Add(Task.Run(async() => item.Tickets = await _ticketParser.ParseFromUrl(item.Url))); } Task.WaitAll(tasks.ToArray()); Trace.TraceInformation("Parsing finished"); Trace.TraceInformation(""); return(filtredList.ToArray()); }