예제 #1
0
        private async Task UpdateFeed(DaumCafeFeed feed, ulong serverId, CancellationToken ct)
        {
            var guild = _client.GetGuild(serverId);

            if (guild == null)
            {
                return;
            }

            var channel = guild.GetTextChannel(feed.TargetChannel);

            if (channel == null)
            {
                return;
            }

            var logger = _logger.WithScope(channel);

            // Choose a session
            DaumCafeSession session;

            if (feed.CredentialId != Guid.Empty)
            {
                if (!_sessionCache.TryGetValue(feed.CredentialId, out var dateSession) || DateTime.Now - dateSession.Item1 > SessionLifetime)
                {
                    var credential = await Modules.CafeModule.GetCredential(_credentialsService, feed.CredentialUser, feed.CredentialId, ct);

                    try
                    {
                        session = await DaumCafeSession.Create(credential.Login, credential.Password, ct);

                        _sessionCache[feed.CredentialId] = Tuple.Create(DateTime.Now, session);
                    }
                    catch (Exception ex) when(ex is CountryBlockException || ex is LoginFailedException)
                    {
                        session = DaumCafeSession.Anonymous;
                        _sessionCache[feed.CredentialId] = Tuple.Create(DateTime.Now, session);
                    }
                }
                else
                {
                    session = dateSession.Item2;
                }
            }
            else
            {
                session = DaumCafeSession.Anonymous;
            }

            // Get last post ID
            int lastPostId;

            try
            {
                lastPostId = await session.GetLastPostId(feed.CafeId, feed.BoardId, ct);
            }
            catch (WebException ex) when(ex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.Forbidden)
            {
                logger.LogInformation("Cafe feed {CafeId}/{BoardId} update forbidden", feed.CafeId, feed.BoardId);
                return;
            }

            // If new feed -> just store the last post ID and return
            if (feed.LastPostId < 0)
            {
                await _settings.Modify <MediaSettings>(serverId, s =>
                {
                    var current = s.DaumCafeFeeds.FirstOrDefault(x => x.Id == feed.Id);
                    if (current != null && current.LastPostId < 0)
                    {
                        current.LastPostId = lastPostId;
                    }
                });

                return;
            }

            var currentPostId = feed.LastPostId;

            if (lastPostId <= feed.LastPostId)
            {
                return;
            }

            logger.LogInformation("Updating feed {CafeId}/{BoardId} found {PostCount} new posts ({FirstPostId} to {LastPostId})", feed.CafeId, feed.BoardId, lastPostId - currentPostId, currentPostId + 1, lastPostId, guild.Name, guild.Id);

            while (lastPostId > currentPostId)
            {
                var preview = await CreatePreview(session, feed.CafeId, feed.BoardId, currentPostId + 1, ct);

                if (!guild.CurrentUser.GetPermissions(channel).SendMessages)
                {
                    logger.LogInformation("Can't update Cafe feed because of permissions");
                    currentPostId = lastPostId;
                    break;
                }

                await channel.SendMessageAsync(preview.Item1.Sanitise(), false, preview.Item2);

                currentPostId++;
            }

            await _settings.Modify <MediaSettings>(serverId, settings =>
            {
                var current = settings.DaumCafeFeeds.FirstOrDefault(x => x.Id == feed.Id);
                if (current != null && current.LastPostId < currentPostId)
                {
                    current.LastPostId = currentPostId;
                }
            });
        }
예제 #2
0
        public async Task AddCafeFeed(ICommand command, CancellationToken ct)
        {
            if ((await _settings.Read <MediaSettings>(command.GuildId)).DaumCafeFeeds.Count >= ServerFeedLimit)
            {
                await command.ReplyError("You've reached the maximum amount of Daum Cafe feeds on this server.");

                return;
            }

            if (!(await command.Guild.GetCurrentUserAsync()).GetPermissions(command["Channel"].AsTextChannel).SendMessages)
            {
                await command.ReplyError($"The bot can't send messages in this channel. Please set the correct guild or channel permissions.");

                return;
            }

            var feed = new DaumCafeFeed()
            {
                TargetChannel = command["Channel"].AsTextChannel.Id
            };

            bool postsAccesible;

            try
            {
                DaumCafeSession session;
                if (command["CredentialId"].HasValue)
                {
                    feed.CredentialUser = command.Message.Author.Id;
                    feed.CredentialId   = (Guid)command["CredentialId"];

                    var credential = await GetCredential(_credentialsService, feed.CredentialUser, feed.CredentialId, ct);

                    session = await DaumCafeSession.Create(credential.Login, credential.Password, default);
                }
                else
                {
                    session = DaumCafeSession.Anonymous;
                }

                var info = await session.GetCafeAndBoardId(command["BoardSectionLink"]);

                feed.CafeId  = info.Item1;
                feed.BoardId = info.Item2;

                postsAccesible = await session.ArePostsAccesible(feed.CafeId, feed.BoardId, default);
            }
            catch (InvalidBoardLinkException)
            {
                throw new IncorrectParametersCommandException("Unrecognized board link.");
            }
            catch (InaccessibleBoardException)
            {
                await command.ReplyError("The bot cannot access this board. " + (command.ParametersCount > 2 ? "Check if the provided account can view this board." : "You might need to provide credentials to an account that can view this board."));

                return;
            }
            catch (CountryBlockException)
            {
                await command.ReplyError($"Your account is country blocked.\nUnblock it on <https://member.daum.net/security/country.daum>. Allow either all countries (모든 국가 허용) or just the country where the bot is hosted (허용 국가 지정 (최대 5개) -> 추가). Contact the bot owner to get information about the bot's location.");

                return;
            }
            catch (LoginFailedException)
            {
                await command.ReplyError("Failed to login with the supplied credential.");

                return;
            }

            await _settings.Modify(command.GuildId, (MediaSettings s) =>
            {
                // Remove duplicate feeds
                s.DaumCafeFeeds.RemoveAll(x => x.CafeId == feed.CafeId && x.BoardId == feed.BoardId && x.TargetChannel == feed.TargetChannel);

                s.DaumCafeFeeds.Add(feed);
            });

            await command.ReplySuccess($"Cafe feed has been added!" + (!postsAccesible ? "\n\n**Warning:** The bot cannot view posts on this board and will not create post previews. To get previews you need to provide credentials to an account that can view posts on this board." : ""));
        }