Example #1
0
        public static async Task <bool> Run([ActivityTrigger] string contestScreenName, ILogger log)
        {
            var startTime = DateTime.Now;

            log.LogInformation("start updating {0}", contestScreenName);
            var ghClient = GitHubUtil.Client;
            var acClient = new AtCoderClient();

            var session = Secrets.GetSecret("AtCoderCSRFToken");
            await acClient.LoginAsync(session);

            var standings = await acClient.GetStandingsAsync(contestScreenName);

            var jsonPath = $"aperfs/{contestScreenName}.json";

            bool found;
            RepositoryContent content;

            try
            {
                content = (await ghClient.Repository.Content.GetAllContents(GitHubUtil.Owner, GitHubUtil.Repo, jsonPath)).First();
                found   = true;
            }
            catch (NotFoundException)
            {
                content = null;
                found   = false;
            }
            var dic = content is null ? new Dictionary <string, double>() : JsonSerializer.Deserialize <Dictionary <string, double> >(content.Content);

            log.LogInformation("start crawling.");
            bool abort = false;

            foreach (var standingData in standings.StandingsData)
            {
                if ((DateTime.Now - startTime).TotalMinutes >= 8)
                {
                    log.LogWarning("time limit is nearing. abort.");
                    abort = true;
                    break;
                }
                if (standingData.UserIsDeleted ||
                    standingData.Competitions == 0 ||
                    !standingData.IsRated ||
                    dic.ContainsKey(standingData.UserScreenName))
                {
                    continue;
                }
                var history = await acClient.GetCompetitionHistoryAsync(standingData.UserScreenName);

                var beforeContestPerfs = history?.TakeWhile(x => x.ContestScreenName.Split('.', 2).First() != contestScreenName)?.Where(x => x.IsRated)?.Select(x => x.InnerPerformance)?.ToArray();
                var aperf = Rating.CalcAPerf(beforeContestPerfs);
                if (aperf is null)
                {
                    log.LogWarning($"aperf is null. screenName: {standingData.UserScreenName}");
                    continue;
                }
                dic.Add(standingData.UserScreenName, aperf.Value);
                await Task.Delay(100);
            }
            log.LogInformation("end crawling.");

            var options = new JsonSerializerOptions();

            options.Converters.Add(new TruncateDoubleConverter());
            var json = JsonSerializer.Serialize(dic, options);

            if (!found)
            {
                var request = new CreateFileRequest($"add aperfs data of {contestScreenName}", json)
                {
                    Committer = GitHubUtil.Comitter
                };
                await ghClient.Repository.Content.CreateFile(GitHubUtil.Owner, GitHubUtil.Repo, jsonPath, request);
            }
            else
            {
                var request = new UpdateFileRequest($"update aperfs data of {contestScreenName}", json, content.Sha)
                {
                    Committer = GitHubUtil.Comitter
                };
                await ghClient.Repository.Content.UpdateFile(GitHubUtil.Owner, GitHubUtil.Repo, jsonPath, request);
            }

            return(abort || !standings.Fixed);
        }