public static async Task <IGeneration> AdvanceGenerationAsync(this SQLiteDatabase database) { IGeneration generation = await database.GetCurrentGenerationOrNullAsync(); if (generation != null) { // Update the end date of the current generation. generation.EndDate = DateUtilities.GetCurrentDateUtc(); await database.UpdateGenerationAsync(generation); } // Create and add the next generation. generation = new Generation { Number = generation is null ? 1 : generation.Number + 1, StartDate = generation is null ? DateTimeOffset.MinValue : DateUtilities.GetCurrentDateUtc(), EndDate = DateTimeOffset.MaxValue }; await database.AddGenerationAsync(generation); return(generation); }
private async Task <IPaginatedMessage> BuildGenerationEmbedAsync(IGeneration generation) { IPaginatedMessage message = await this.BuildRecentEventsMessageAsync(generation.StartDate, generation.EndDate); TimeSpan span = DateUtilities.GetCurrentDateUtc() - generation.EndDate; string timeSpanString = DateUtilities.GetTimestampFromDate(generation.EndDate) == DateUtilities.GetMaxTimestamp() ? "Current" : DateUtilities.GetTimeSpanString(span) + " ago"; message.SetTitle(string.Format("{0} ({1})", generation.Name, timeSpanString)); return(message); }
public async Task Recent(string timespanStr) { if (DateUtilities.TryParseTimeSpan(timespanStr, out TimeSpan timespan)) { DateTimeOffset start = DateUtilities.GetCurrentDateUtc() - timespan; DateTimeOffset end = DateUtilities.GetCurrentDateUtc(); await this.ReplyRecentEventsAsync(start, end); } else { await ReplyErrorAsync("Unrecognized timespan."); } }
public async Task Profile(IUser user) { // Begin building the embed (add default parameters). EmbedBuilder embed = new EmbedBuilder(); embed.WithTitle(string.Format("{0}'s profile", user.Username)); embed.WithThumbnailUrl(user.GetAvatarUrl(size: 64)); // Get basic information about the user. // This will return null if the user hasn't been seen before. ICreator userInfo = await Db.GetCreatorAsync(user.ToCreator(), UserInfoQueryFlags.MatchEither); if (userInfo is null) { embed.WithDescription(string.Format("{0} has not submitted any species.", user.Username)); } else { long daysSinceFirstSubmission = (DateUtilities.GetCurrentDateUtc() - userInfo.FirstSpeciesDate).Value.Days; UserRank userRank = await Db.GetRankAsync(userInfo, UserInfoQueryFlags.MatchEither); // Get the user's most active genus. IEnumerable <ISpecies> userSpecies = await Db.GetSpeciesAsync(userInfo, UserInfoQueryFlags.MatchEither); IGrouping <string, string> favoriteGenusGrouping = userSpecies .Select(x => x.Genus.GetName()) .GroupBy(x => x) .OrderByDescending(x => x.Count()) .FirstOrDefault(); string favoriteGenus = favoriteGenusGrouping is null ? "N/A" : favoriteGenusGrouping.First(); int favoriteGenusCount = favoriteGenusGrouping is null ? 0 : favoriteGenusGrouping.Count(); int userSpeciesCount = userSpecies.Count(); int speciesCount = (int)await Db.GetSpeciesCountAsync(); // Get the user's rarest trophy. string rarest_trophy = "N/A"; IUnlockedTrophyInfo[] unlocked = (await Db.GetUnlockedTrophiesAsync(new Creator(user.Id, user.Username), TrophyService.GetTrophies())).ToArray(); if (unlocked.Count() > 0) { Array.Sort(unlocked, (lhs, rhs) => lhs.TimesUnlocked.CompareTo(rhs.TimesUnlocked)); ITrophy trophy = TrophyService.GetTrophies() .Where(t => t.Identifier.Equals(unlocked[0].Trophy.Identifier)) .FirstOrDefault(); rarest_trophy = trophy.Name; } // Put together the user's profile. if (Config.GenerationsEnabled) { int generationsSinceFirstSubmission = (await Db.GetGenerationsAsync()).Where(x => x.EndDate > userInfo.FirstSpeciesDate).Count(); double speciesPerGeneration = generationsSinceFirstSubmission <= 0 ? userSpeciesCount : (double)userSpeciesCount / generationsSinceFirstSubmission; embed.WithDescription(string.Format("{0} made their first species during **{1}**.\nSince then, they have submitted **{2:0.0}** species per generation.\n\nTheir submissions make up **{3:0.0}%** of all species.", user.Username, await GetDateStringAsync(userInfo.FirstSpeciesDate), speciesPerGeneration, (double)userSpeciesCount / speciesCount * 100.0)); } else { embed.WithDescription(string.Format("{0} made their first species on **{1}**.\nSince then, they have submitted **{2:0.0}** species per day.\n\nTheir submissions make up **{3:0.0}%** of all species.", user.Username, await GetDateStringAsync(userInfo.FirstSpeciesDate), daysSinceFirstSubmission == 0 ? userSpeciesCount : (double)userSpeciesCount / daysSinceFirstSubmission, (double)userSpeciesCount / speciesCount * 100.0)); } embed.AddField("Species", string.Format("{0} (Rank **#{1}**)", userSpeciesCount, userRank.Rank), inline: true); embed.AddField("Favorite genus", string.Format("{0} ({1} spp.)", StringUtilities.ToTitleCase(favoriteGenus), favoriteGenusCount), inline: true); if (Config.TrophiesEnabled) { embed.AddField("Trophies", string.Format("{0} ({1:0.0}%)", (await Db.GetUnlockedTrophiesAsync(new Creator(user.Id, user.Username), TrophyService.GetTrophies())).Count(), await Db.GetTrophyCompletionRateAsync(new Creator(user.Id, user.Username), TrophyService.GetTrophies())), inline: true); embed.AddField("Rarest trophy", rarest_trophy, inline: true); } } await ReplyAsync("", false, embed.Build()); }
protected async Task UploadDatabaseBackupAsync(IMessageChannel channel, string databaseFilePath) { bool backupInProgress = GetDatabaseStatus(databaseFilePath).BackupInProgress; if (backupInProgress) { await DiscordUtilities.ReplyErrorAsync(channel, "A backup is already in progress. Please wait until it has completed."); } else { GetDatabaseStatus(databaseFilePath).BackupInProgress = true; if (System.IO.File.Exists(databaseFilePath)) { try { await DiscordUtilities.ReplyInfoAsync(channel, string.Format("Uploading database backup ({0:0.##} MB).\nThe backup will be posted in this channel when it is complete.", new System.IO.FileInfo(databaseFilePath).Length / 1024000.0)); await channel.SendFileAsync(databaseFilePath, string.Format("`Database backup ({0})`", DateUtilities.GetCurrentDateUtc())); } catch (Exception) { await DiscordUtilities.ReplyErrorAsync(channel, "Database file cannot be accessed."); } } else { await DiscordUtilities.ReplyErrorAsync(channel, "Database file does not exist at the specified path."); } GetDatabaseStatus(databaseFilePath).BackupInProgress = false; } }