Beispiel #1
0
        public async Task ExportToFileAsync()
        {
            if (!this.Manager.TryGet(this.Context.Channel.Id, out GameState game))
            {
                // This command only works during a game
                return;
            }

            if (!(this.Context.User is IGuildUser guildUser))
            {
                return;
            }

            if (!(this.Context.Channel is IGuildChannel guildChannel))
            {
                return;
            }

            Logger.Information($"User {this.Context.User.Id} attempting to export a scoresheet");

            IGuildUser guildBotUser = await this.Context.Guild.GetCurrentUserAsync();

            ChannelPermissions channelPermissions = guildBotUser.GetPermissions(guildChannel);

            if (!channelPermissions.AttachFiles)
            {
                Logger.Information(
                    $"User {this.Context.User.Id}'s export failed because channel {guildChannel.Id} didn't have the Attach Files permission");
                await this.Context.Channel.SendMessageAsync(
                    "This bot must have \"Attach Files\" permissions to export a scoresheet to a file");

                return;
            }

            int userExportCount;
            int guildExportCount;

            using (DatabaseAction action = this.DatabaseActionFactory.Create())
            {
                int[] exportCounts = await Task.WhenAll(
                    action.GetGuildExportCount(this.Context.Guild.Id),
                    action.GetUserExportCount(this.Context.User.Id));

                userExportCount  = exportCounts[0];
                guildExportCount = exportCounts[1];

                // The count starts at 0, so use >= to make sure we don't go over
                if (userExportCount >= this.Options.CurrentValue.DailyUserExportLimit)
                {
                    Logger.Information($"User {this.Context.User.Id}'s export failed because of a daily user limit");
                    await this.Context.Channel.SendMessageAsync(
                        "Cannot export a scoresheet. The user has already exceeded the number of scoresheets they can " +
                        $"export each day ({this.Options.CurrentValue.DailyUserExportLimit}). The limit resets at midnight GMT.");

                    return;
                }
                else if (guildExportCount >= this.Options.CurrentValue.DailyGuildExportLimit)
                {
                    Logger.Information(
                        $"User {this.Context.User.Id}'s export failed because of a daily server limit on server {this.Context.Guild.Id}");
                    await this.Context.Channel.SendMessageAsync(
                        "Cannot export a scoresheet. The server has already exceeded the number of scoresheets it can " +
                        $"export each day ({this.Options.CurrentValue.DailyGuildExportLimit}). The count resets at midnight GMT.");

                    return;
                }

                await Task.WhenAll(
                    action.IncrementGuildExportCount(this.Context.Guild.Id),
                    action.IncrementUserExportCount(this.Context.User.Id));
            }

            string           readerName        = guildUser.Nickname ?? guildUser.Username;
            IResult <Stream> spreadsheetResult = await this.ScoresheetGenerator.TryCreateScoresheet(
                game, readerName, this.Context.Channel.Name);

            if (!spreadsheetResult.Success)
            {
                Logger.Information($"User {this.Context.User.Id}'s export failed because of this error: {spreadsheetResult.ErrorMessage}");
                await this.Context.Channel.SendMessageAsync($"Export failed. Error: {spreadsheetResult.ErrorMessage}");

                return;
            }

            string readerNameInFilename = readerName.Length > 12 ? readerName.Substring(0, 12) : readerName;
            int    newExportCount       = userExportCount + 1;
            string filename             = $"Scoresheet_{readerNameInFilename}_{newExportCount}.xlsx";

            await this.Context.Channel.SendFileAsync(
                spreadsheetResult.Value,
                filename,
                text : "Scoresheet for this game. This scoresheet is based on NAQT's electronic scoresheet (© National Academic Quiz Tournaments, LLC).");

            Logger.Information($"User {this.Context.User.Id}'s export succeeded");
        }