Example #1
0
        private async Task LoadState()
        {
            var sw = Stopwatch.StartNew();

            // in case the main save is corrupted, try the backup save
            foreach (var filePath in new[] { GetStateFilePath(), GetStateFilePath() + ".bak" })
            {
                try
                {
                    using var fileStream = File.OpenRead(filePath);
                    using var gzipStream = new GZipStream(fileStream, CompressionMode.Decompress);
                    _state = await JsonSerializer.DeserializeAsync <ScrapeState>(gzipStream);

                    _state.Chatty.SetDictionaries();
                    await _eventProvider.PrePopulate(_state.Chatty, _state.LolCounts, _state.Events);

                    _logger.LogInformation($"Loaded state in {sw.Elapsed}. Last event is #{await _eventProvider.GetLastEventId()}.");
                    return;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"Failed to read state from \"{filePath}\".");
                }
            }
        }
        public async Task Post(string username, string password, int parentId, string body)
        {
            if (body.Length > 0 && body[0] == '@')
            {
                body = " " + body;
            }

            var contentTypeId = 17;
            var contentId     = 17;

            if (parentId != 0)
            {
                try
                {
                    (contentTypeId, contentId) = await _threadParser.GetContentTypeId(parentId);
                }
                catch (ParsingException)
                {
                    throw new Api400Exception(Api400Exception.Codes.INVALID_PARENT, "Invalid parent ID.");
                }
            }

            var query = _downloadService.NewQuery();

            query.Add("parent_id", parentId == 0 ? "" : $"{parentId}");
            query.Add("content_type_id", $"{contentTypeId}");
            query.Add("content_id", $"{contentId}");
            query.Add("page", "");
            query.Add("parent_url", "/chatty");
            query.Add("body", _emojiConverter.ConvertEmojisToEntities(body.Replace("&", "&amp;")));

            var lastEventId = await _eventProvider.GetLastEventId();

            var response = await _downloadService.DownloadWithUserLogin(
                "https://www.shacknews.com/post_chatty.x",
                username, password, query);

            if (response.Contains("You must be logged in to post", StringComparison.Ordinal))
            {
                throw new Api400Exception(Api400Exception.Codes.INVALID_LOGIN,
                                          $"Unable to log into user account [{username}].");
            }
            if (response.Contains("Please wait a few minutes before trying to post again", StringComparison.Ordinal))
            {
                throw new Api400Exception(Api400Exception.Codes.POST_RATE_LIMIT,
                                          "Please wait a few minutes before trying to post again.");
            }
            if (response.Contains("banned", StringComparison.Ordinal))
            {
                throw new Api400Exception(Api400Exception.Codes.BANNED,
                                          "You are banned.");
            }
            if (response.Contains("Trying to post to a nuked thread", StringComparison.Ordinal))
            {
                throw new Api400Exception(Api400Exception.Codes.NUKED,
                                          "You cannot reply to a nuked thread or subthread.");
            }
            if (!response.Contains("fixup_postbox_parent_for_remove(", StringComparison.Ordinal))
            {
                throw new Api500Exception("Unexpected response from server: " + response);
            }

            // wait for the event to appear
            var sw          = Stopwatch.StartNew();
            var maxTimeSpan = TimeSpan.FromSeconds(15);

            while (sw.Elapsed < maxTimeSpan)
            {
                foreach (var ev in await _eventProvider.GetEvents(lastEventId))
                {
                    if (ev.EventType == EventType.NewPost)
                    {
                        var eventData = (NewPostEventDataModel)ev.EventData;
                        if (eventData.Post.Author.Equals(username, StringComparison.InvariantCultureIgnoreCase))
                        {
                            return;
                        }
                    }
                    lastEventId = ev.EventId;
                }
                await Task.Delay(TimeSpan.FromSeconds(1));
            }
        }