コード例 #1
0
ファイル: RaidService.cs プロジェクト: BenneMe/RaidBattlesBot
        public async Task UpdatePoll(Poll poll, IUrlHelper urlHelper, CancellationToken cancellationToken = default)
        {
            var content = poll.GetMessageText(urlHelper, disableWebPreview: poll.DisableWebPreview());

            foreach (var message in poll.Messages)
            {
                try
                {
                    if (message.InlineMesssageId is string inlineMessageId)
                    {
                        await myBot.EditMessageTextAsync(inlineMessageId, content.MessageText, content.ParseMode, content.DisableWebPagePreview,
                                                         await message.GetReplyMarkup(myChatInfo, cancellationToken), cancellationToken);
                    }
                    else if (message.ChatId is long chatId && message.MesssageId is int messageId)
                    {
                        await myBot.EditMessageTextAsync(chatId, messageId, content.MessageText, content.ParseMode, content.DisableWebPagePreview,
                                                         await message.GetReplyMarkup(myChatInfo, cancellationToken), cancellationToken);
                    }
                }
                catch (Exception ex)
                {
                    myTelemetryClient.TrackExceptionEx(ex, message.GetTrackingProperties());
                }
            }
        }
コード例 #2
0
ファイル: RaidService.cs プロジェクト: BenneMe/RaidBattlesBot
        public async Task <int> GetPollId(Poll poll, CancellationToken cancellationToken = default)
        {
            var nextId = poll.Id = await myContext.GetNextPollId(cancellationToken);

            using (var entry = myMemoryCache.CreateEntry(this[nextId]))
            {
                entry.Value = poll;
                entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(3);
            }

            return(nextId);
        }
コード例 #3
0
        public async Task <InlineQueryResult> GetResult(Poll poll, CancellationToken cancellationToken)
        {
            var inviteMessage = await poll.GetInviteMessage(myDB, cancellationToken);

            if (inviteMessage != null)
            {
                return(new InlineQueryResultArticle(PREFIX + poll.GetInlineId(), "Invite", inviteMessage)
                {
                    Description = "Generate invitation query",
                    ThumbUrl = myUrlHelper.AssetsContent("static_assets/png/btn_new_party.png").ToString()
                });
            }

            return(null);
        }
コード例 #4
0
        public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default)
        {
            var location   = data.Location;
            var queryParts = data.Query.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            var poll        = default(Poll);
            var pollQuery   = new List <string>(queryParts.Length);
            var searchQuery = new List <string>(queryParts.Length);
            var query       = pollQuery;

            foreach (var queryPart in queryParts)
            {
                switch (queryPart)
                {
                case string locationPart when OpenLocationCode.IsValid(locationPart):
                    location = OpenLocationCode.Decode(locationPart) is var code
              ? new Location
                    {
                        Longitude = (float)code.CenterLongitude, Latitude = (float)code.CenterLatitude
                    }

              : location;
                    break;

                case string part when Regex.Match(part, PATTERN) is Match match && match.Success:
                    if (int.TryParse(match.Groups["pollId"].Value, out var pollId))
                    {
                        poll = myRaidService.GetTemporaryPoll(pollId);
                    }

                    query = searchQuery;

                    break;

                default:
                    query.Add(queryPart);
                    break;
                }
            }

            Portal[] portals;
            if (searchQuery.Count == 0)
            {
                portals = await myIngressClient.GetPortals(0.200, location, cancellationToken);
            }
            else
            {
                portals = await myIngressClient.Search(searchQuery, location, cancellationToken);
            }

            var results = new List <InlineQueryResultBase>(Math.Min(portals.Length, MAX_PORTALS_PER_RESPONSE) + 2);

            if ((poll == null) && (pollQuery.Count != 0))
            {
                var voteFormat = await myDb.Set <Settings>().GetFormat(data.From.Id, cancellationToken);

                for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++)
                {
                    poll = new Poll(data)
                    {
                        Title        = string.Join("  ", pollQuery),
                        AllowedVotes = voteFormat,
                        Portal       = portals[i],
                        ExRaidGym    = false
                    };
                    await myRaidService.GetPollId(poll, cancellationToken);

                    results.Add(new InlineQueryResultArticle(poll.GetInlineId(), poll.GetTitle(myUrlHelper),
                                                             poll.GetMessageText(myUrlHelper, disableWebPreview: poll.DisableWebPreview()))
                    {
                        Description = poll.AllowedVotes?.Format(new StringBuilder("Create a poll ")).ToString(),
                        HideUrl     = true,
                        ThumbUrl    = poll.GetThumbUrl(myUrlHelper).ToString(),
                        ReplyMarkup = poll.GetReplyMarkup()
                    });

                    if (i == 0)
                    {
                        poll.Id        = -poll.Id;
                        poll.ExRaidGym = true;
                        results.Add(new InlineQueryResultArticle(poll.GetInlineId(), poll.GetTitle(myUrlHelper) + " (EX Raid Gym)",
                                                                 poll.GetMessageText(myUrlHelper, disableWebPreview: poll.DisableWebPreview()))
                        {
                            Description = poll.AllowedVotes?.Format(new StringBuilder("Create a poll ")).ToString(),
                            HideUrl     = true,
                            ThumbUrl    = poll.GetThumbUrl(myUrlHelper).ToString(),
                            ReplyMarkup = poll.GetReplyMarkup()
                        });
                    }
                }
            }
            else
            {
                for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++)
                {
                    var portal = portals[i];
                    var title  = portal.Name is string name && !string.IsNullOrWhiteSpace(name) ? name : portal.Guid;
                    if (portal.EncodeGuid() is string portalGuid)
                    {
                        InlineQueryResultArticle Init(InlineQueryResultArticle article, InlineKeyboardButton createButton)
                        {
                            const int thumbnailSize = 64;

                            article.Description = portal.Address;
                            article.ReplyMarkup = new InlineKeyboardMarkup(createButton);
                            article.ThumbUrl    = portal.GetImage(myUrlHelper, thumbnailSize)?.AbsoluteUri;
                            article.ThumbHeight = thumbnailSize;
                            article.ThumbWidth  = thumbnailSize;
                            return(article);
                        }

                        var portalContent = new StringBuilder()
                                            .Bold((builder, mode) => builder.Sanitize(portal.Name)).NewLine()
                                            .Sanitize(portal.Address)
                                            .Link("\u200B", portal.Image)
                                            .ToTextMessageContent();
                        results.Add(Init(
                                        new InlineQueryResultArticle($"portal:{portal.Guid}", title, portalContent),
                                        InlineKeyboardButton.WithSwitchInlineQuery("Create a poll", $"{PREFIX}{portalGuid} {poll?.Title}")));

                        if (i == 0)
                        {
                            var exRaidPortalContent = new StringBuilder()
                                                      .Sanitize("☆ ")
                                                      .Bold((builder, mode) => builder.Sanitize(portal.Name))
                                                      .Sanitize(" (EX Raid Gym)").NewLine()
                                                      .Sanitize(portal.Address)
                                                      .Link("\u200B", portal.Image)
                                                      .ToTextMessageContent();
                            results.Add(Init(
                                            new InlineQueryResultArticle($"portal:{portal.Guid}+", $"☆ {title} (EX Raid Gym)", exRaidPortalContent),
                                            InlineKeyboardButton.WithSwitchInlineQuery("Create a poll ☆ (EX Raid Gym)", $"{PREFIX}{portalGuid}+ {poll?.Title}")));
                        }
                    }
                }
            }

            if (searchQuery.Count == 0)
            {
                results.Add(
                    new InlineQueryResultArticle("EnterGymName", "Enter a Gym's Title", new InputTextMessageContent("Enter a Gym's Title to search"))
                {
                    Description = "to search",
                    ThumbUrl    = default(Portal).GetImage(myUrlHelper)?.AbsoluteUri
                });
            }

            if (results.Count == 0)
            {
                var search = string.Join(" ", searchQuery);
                results.Add(new InlineQueryResultArticle("NothingFound", "Nothing found",
                                                         new StringBuilder($"Nothing found by request ").Code((builder, mode) => builder.Sanitize(search, mode)).ToTextMessageContent())
                {
                    Description = $"Request {search}",
                    ThumbUrl    = myUrlHelper.AssetsContent(@"static_assets/png/btn_close_normal.png").AbsoluteUri
                });
            }

            await myBot.AnswerInlineQueryWithValidationAsync(data.Id, results, cacheTime : 0, isPersonal : true, cancellationToken : cancellationToken);

            await myDb.SaveChangesAsync(cancellationToken);

            return(true);
        }
コード例 #5
0
        public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default)
        {
            var location = await myDb.Set <UserSettings>().GetLocation(data, cancellationToken);

            var queryParts = data.Query.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            var poll = default(Poll);
            List <VoteLimit> limits = default;
            var pollQuery           = new List <string>(queryParts.Length);
            var searchQuery         = new List <string>(queryParts.Length);
            var query = pollQuery;

            foreach (var queryPart in queryParts)
            {
                switch (queryPart)
                {
                case { } locationPart when OpenLocationCode.IsValid(locationPart):
                    location = OpenLocationCode.Decode(locationPart) is var code
              ? new Location
                    {
                        Longitude = (float)code.CenterLongitude, Latitude = (float)code.CenterLatitude
                    }

              : location;
                    break;

                case { } part when Regex.Match(part, PATTERN) is
                    {
                        Success: true
                    }

match:
                    if (int.TryParse(match.Groups["pollId"].ValueSpan, out var pollId))
                    {
                        poll = myRaidService
                               .GetTemporaryPoll(pollId)
                               .InitImplicitVotes(data.From, myBot.BotId);
                    }
                    query = searchQuery;
                    break;

                case { } part when myGeneralInlineQueryHandler.ProcessLimitQueryString(ref limits, part):
                    break;

                default:
                    query.Add(queryPart);
                    break;
                }
            }

            Portal[] portals;
            if (searchQuery.Count == 0)
            {
                portals = await myIngressClient.GetPortals(0.200, location, cancellationToken);
            }
            else
            {
                portals = await myIngressClient.Search(searchQuery, location, near : true, cancellationToken);
            }

            var results = new List <InlineQueryResult>(Math.Min(portals.Length, MAX_PORTALS_PER_RESPONSE) + 2);

            if (poll == null && pollQuery.Count != 0)
            {
                var voteFormat = await myDb.Set <Settings>().GetFormat(data.From.Id, cancellationToken);

                poll = await new Poll(data)
                {
                    Title        = string.Join("  ", pollQuery),
                    AllowedVotes = voteFormat,
                    ExRaidGym    = false,
                    Limits       = limits
                }.DetectRaidTime(myTimeZoneService, () => Task.FromResult(location), async ct => myClock.GetCurrentInstant().InZone(await myGeoCoder.GetTimeZone(data, ct)), cancellationToken);

                for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++)
                {
                    var portalPoll = new Poll(poll)
                    {
                        Portal = portals[i],
                        Limits = poll.Limits ?? limits
                    }.InitImplicitVotes(data.From, myBot.BotId);
                    await myRaidService.GetPollId(portalPoll, data.From, cancellationToken);

                    results.Add(myGeneralInlineQueryHandler.GetInlineResult(portalPoll));

                    if (i == 0)
                    {
                        portalPoll.Id        = -portalPoll.Id;
                        portalPoll.ExRaidGym = true;
                        results.Add(myGeneralInlineQueryHandler.GetInlineResult(portalPoll));
                    }
                }
            }
            else
            {
                for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++)
                {
                    var portal = portals[i];
                    var title  = portal.Name is { } name&& !string.IsNullOrWhiteSpace(name) ? name : portal.Guid;
                    if (portal.EncodeGuid() is { } portalGuid)
                    {
                        InlineQueryResultArticle Init(InlineQueryResultArticle article, InlineKeyboardButton createButton)
                        {
                            const int thumbnailSize = 64;

                            article.Description = portal.Address;
                            article.ReplyMarkup = new InlineKeyboardMarkup(createButton);
                            article.ThumbUrl    = portal.GetImage(myUrlHelper, thumbnailSize)?.AbsoluteUri;
                            article.ThumbHeight = thumbnailSize;
                            article.ThumbWidth  = thumbnailSize;
                            return(article);
                        }

                        var portalContent = new TextBuilder()
                                            .Bold(builder => builder.Sanitize(portal.Name)).NewLine()
                                            .Sanitize(portal.Address)
                                            .Link("\u200B", portal.Image)
                                            .ToTextMessageContent();
                        results.Add(Init(
                                        new InlineQueryResultArticle($"portal:{portal.Guid}", title, portalContent),
                                        InlineKeyboardButton.WithSwitchInlineQuery("Create a poll", $"{PREFIX}{portalGuid} {poll?.Title}")));

                        if (i == 0)
                        {
                            var exRaidPortalContent = new TextBuilder()
                                                      .Sanitize("☆ ")
                                                      .Bold(builder => builder.Sanitize(portal.Name))
                                                      .Sanitize(" (EX Raid Gym)").NewLine()
                                                      .Sanitize(portal.Address)
                                                      .Link("\u200B", portal.Image)
                                                      .ToTextMessageContent();
                            results.Add(Init(
                                            new InlineQueryResultArticle($"portal:{portal.Guid}+", $"☆ {title} (EX Raid Gym)", exRaidPortalContent),
                                            InlineKeyboardButton.WithSwitchInlineQuery("Create a poll ☆ (EX Raid Gym)", $"{PREFIX}{portalGuid}+ {poll?.Title}")));
                        }
                    }
                }
            }

            if (searchQuery.Count == 0)
            {
                results.Add(
                    new InlineQueryResultArticle("EnterGymName", "Enter a Gym's Title", new InputTextMessageContent("Enter a Gym's Title to search"))
                {
                    Description = "to search",
                    ThumbUrl    = default(Portal).GetImage(myUrlHelper)?.AbsoluteUri
                });
            }

            if (results.Count == 0)
            {
                var search = string.Join(" ", searchQuery);
                results.Add(new InlineQueryResultArticle("NothingFound", "Nothing found",
                                                         new TextBuilder($"Nothing found by request ").Code(builder => builder.Sanitize(search)).ToTextMessageContent())
                {
                    Description = $"Request {search}",
                    ThumbUrl    = myUrlHelper.AssetsContent(@"static_assets/png/btn_close_normal.png").AbsoluteUri
                });
            }

            await myBot.AnswerInlineQueryWithValidationAsync(data.Id, results, cacheTime : 0, isPersonal : true, cancellationToken : cancellationToken);

            await myDb.SaveChangesAsync(cancellationToken);

            return(true);
        }
コード例 #6
0
 public static string AutoApprove(Poll poll) => $"{ID}:{AutoApproveId}:{poll.Id}";
コード例 #7
0
ファイル: PollEx.cs プロジェクト: BenneMe/RaidBattlesBot
 public static string GetInlineId(this Poll poll, object suffix = null) =>
 $"{InlineIdPrefix}:{poll.GetId()}:{(poll.Portal?.Guid ?? poll.PortalId)}:{suffix}";
コード例 #8
0
 public InlineQueryResultArticle GetInlineResult(Poll poll, int?suffixNumber = null) =>
コード例 #9
0
ファイル: PollEx.cs プロジェクト: BenneMe/RaidBattlesBot
 public static PollId GetId(this Poll poll) =>
 new PollId
 {
     Id = poll.Id, Format = poll.AllowedVotes ?? VoteEnum.Standard
 };
コード例 #10
0
ファイル: PollEx.cs プロジェクト: BenneMe/RaidBattlesBot
 public static Raid Raid(this Poll poll)
 {
     return(poll.Raid?.PostEggRaid ?? poll.Raid);
 }
コード例 #11
0
ファイル: PollEx.cs プロジェクト: BenneMe/RaidBattlesBot
 public static bool DisableWebPreview([CanBeNull] this Poll poll)
 {
     return(GetRaidId(poll) == null);
 }
コード例 #12
0
ファイル: PollEx.cs プロジェクト: BenneMe/RaidBattlesBot
 public static int?GetRaidId([CanBeNull] this Poll poll)
 {
     return(poll?.Raid?.Id ?? poll?.RaidId);
 }
コード例 #13
0
ファイル: PollEx.cs プロジェクト: BenneMe/RaidBattlesBot
        public static InputTextMessageContent GetMessageText(this Poll poll, IUrlHelper urlHelper, ParseMode mode = Helpers.DefaultParseMode, bool disableWebPreview = false)
        {
            var text = poll.GetDescription(urlHelper, mode).NewLine();

            text.Append(" "); // for better presentation in telegram pins & notifications

            if (poll.Cancelled)
            {
                text
                .NewLine()
                .Bold((builder, m) => builder.Sanitize("Cancellation!", m).NewLine(), mode);
            }

            var compactMode = poll.Votes?.Count > 10;
            var pollVotes   = poll.Votes ?? Enumerable.Empty <Vote>();

            GroupVotes(text, pollVotes, ourVoteGrouping);

            text.Link("\x200B", poll.Raid()?.GetLink(urlHelper), mode);

            return(text.ToTextMessageContent(mode, disableWebPreview));

            int GroupVotes(StringBuilder result, IEnumerable <Vote> enumerable, IEnumerable <VoteGrouping> grouping, string extraPhrase = null)
            {
                int groupsCount = 0;

                foreach (var voteGroup in enumerable
                         .GroupBy(vote => grouping.OrderBy(_ => _.Order).FirstOrDefault(_ => vote.Team?.HasAnyFlags(_.Flag) ?? false))
                         .OrderBy(voteGroup => voteGroup.Key.DisplayOrder))
                {
                    groupsCount++;
                    var votesNumber = voteGroup.Aggregate(0, (i, vote) => i + vote.Team.GetPlusVotesCount() + 1);
                    var countStr    = votesNumber == 1 ? voteGroup.Key.Singular : voteGroup.Key.Plural;
                    StringBuilder FormatCaption(StringBuilder sb)
                    {
                        var captionParts = new[] { votesNumber.ToString(), extraPhrase, countStr }.Where(s => !string.IsNullOrWhiteSpace(s));

                        return(sb
                               .NewLine()
                               .Sanitize(string.Join(" ", captionParts), mode)
                               .NewLine());
                    }

                    if (voteGroup.Key.NestedGrouping is {} nestedGrouping)
                    {
                        var nestedResult = new StringBuilder();
                        if (GroupVotes(nestedResult, voteGroup, nestedGrouping) > 1)
                        {
                            FormatCaption(result).Append(nestedResult);
                        }
                        else
                        {
                            GroupVotes(result, voteGroup, nestedGrouping, countStr);
                        }
                        continue;
                    }

                    FormatCaption(result);

                    foreach (var vote in voteGroup.GroupBy(_ => _.Team?.RemoveFlags(VoteEnum.Modifiers)).OrderBy(_ => _.Key))
                    {
                        var votes = vote.OrderBy(v => v.Modified);
                        if (compactMode)
                        {
                            result
                            .Sanitize(vote.Key?.Description()).Append('\x00A0')
                            .AppendJoin(", ", votes.Select(v => v.GetUserLinkWithPluses(mode)))
                            .NewLine();
                        }
                        else
                        {
                            result
                            .AppendJoin(Helpers.NewLineString,
                                        votes.Select(v => $"{v.Team?.Description().Sanitize(mode)} {v.GetUserLinkWithPluses(mode)}"))
                            .NewLine();
                        }
                    }
                }

                return(groupsCount);
            }
        }