public static async Task DeleteTaxonAsync(this SQLiteDatabase database, ITaxon taxon) { string tableName = GetTableNameForRank(taxon.GetRank()); string subtaxaCommonName = GetTableNameForRank(taxon.GetChildRank()); string subtaxaColumnName = GetFieldNameForRank(taxon.GetRank()); // Set to NULL any references subtaxa have to this taxon. // Note that this can also happen automatically if the foreign key is set up correctly when creating the database. if (!string.IsNullOrEmpty(tableName) && !string.IsNullOrEmpty(subtaxaColumnName)) { using (SQLiteCommand cmd = new SQLiteCommand(string.Format("UPDATE {0} SET {1} = NULL WHERE {1} = $id", subtaxaCommonName, subtaxaColumnName))) { cmd.Parameters.AddWithValue("$id", taxon.Id); await database.ExecuteNonQueryAsync(cmd); } } // Delete the taxon. if (!string.IsNullOrEmpty(tableName)) { using (SQLiteCommand cmd = new SQLiteCommand(string.Format("DELETE FROM {0} WHERE id = $id", tableName))) { cmd.Parameters.AddWithValue("$id", taxon.Id); await database.ExecuteNonQueryAsync(cmd); } } }
private async Task ReplyDeleteTaxonAsync(ITaxon taxon) { if (taxon.IsValid()) { if (taxon.GetRank() != TaxonRankType.Species && (await Db.GetSpeciesAsync(taxon)).Count() > 0) { // If the taxon still has species underneath of it, don't allow it to be deleted. await ReplyErrorAsync("Taxa containing species cannot be deleted."); } else if (taxon.GetRank() != TaxonRankType.Species) { // The taxon is empty, so delete the taxon. await Db.DeleteTaxonAsync(taxon); string name = (taxon is ISpecies species) ? species.GetShortName() : taxon.GetName(); await ReplySuccessAsync($"{taxon.GetRank().GetName().ToSentence()} **{name}** was successfully deleted."); } else { // Species cannot currently be deleted through the bot. await ReplyErrorAsync("Species cannot currently be deleted."); } } }
public async Task SetCommonName(string taxonName, string commonName) { IEnumerable <ITaxon> taxa = await Db.GetTaxaAsync(taxonName); if (taxa.Count() <= 0) { // We did not get any matching taxa. ISpecies species = await ReplySpeciesSuggestionAsync(string.Empty, taxonName); if (species.IsValid()) { await SetSpeciesCommonName(string.Empty, taxonName); } } else { // We got at least one matching taxon. ITaxon taxon = await ReplyValidateTaxaAsync(taxa); if (taxon.IsValid()) { if (taxon.GetRank() == TaxonRankType.Species) { await SetSpeciesCommonName(taxonName, commonName); // species are handled differently } else { await ReplySetTaxonCommonNameAsync(taxon, commonName); } } } }
public async Task SetTaxonDescription(string taxonName) { IEnumerable <ITaxon> taxa = await Db.GetTaxaAsync(taxonName); if (taxa.Count() <= 0) { // We did not get any matching taxa. // In this case, show species suggestions. // If there is no such taxon, default to showing species suggestions. ISpecies species = await ReplySpeciesSuggestionAsync(string.Empty, taxonName); if (species.IsValid()) { await ReplySetTaxonDescriptionAsync(species); } } else { // We got one or more matching taxa. ITaxon taxon = await ReplyValidateTaxaAsync(taxa); if (taxon.GetRank() == TaxonRankType.Species) { taxon = await Db.GetSpeciesAsync(taxon.Id); } if (taxon.IsValid()) { await ReplySetTaxonDescriptionAsync(taxon); } } }
public static async Task <IEnumerable <ITaxon> > GetSubtaxaAsync(this SQLiteDatabase database, ITaxon taxon) { List <ITaxon> result = new List <ITaxon>(); string tableName = GetTableNameForRank(taxon.GetChildRank()); string parentColumnName = GetFieldNameForRank(taxon.GetRank()); if (string.IsNullOrEmpty(tableName) || string.IsNullOrEmpty(parentColumnName) || !taxon.Id.HasValue) { return(Enumerable.Empty <ITaxon>()); } string query = "SELECT * FROM {0} WHERE {1} = $parent_id"; using (SQLiteCommand cmd = new SQLiteCommand(string.Format(query, tableName, parentColumnName))) { cmd.Parameters.AddWithValue("$parent_id", taxon.Id); foreach (DataRow row in await database.GetRowsAsync(cmd)) { result.Add(await database.CreateTaxonFromDataRowAsync(row, taxon.GetChildRank())); } } // Sort taxa alphabetically by name. result.Sort((lhs, rhs) => lhs.Name.CompareTo(rhs.Name)); return(result); }
public async Task <ITaxon> ReplyNoSuchTaxonExistsAsync(string input, ITaxon suggestion, TaxonRankType rank = TaxonRankType.None) { string taxonName = rank == TaxonRankType.None ? "taxon" : rank.GetName(); if (suggestion != null) { taxonName = suggestion.GetRank().GetName(); } StringBuilder sb = new StringBuilder(); if (string.IsNullOrWhiteSpace(input)) { sb.Append($"No such {taxonName} exists."); } else { sb.Append($"No {taxonName} named \"{input}\" exists."); } if (suggestion != null) { string suggestionText = (suggestion is ISpecies species) ? species.GetFullName() : suggestion.GetName().ToTitle(); sb.Append($" Did you mean **{suggestionText}**?"); } IPaginatedMessage message = new PaginatedMessage(sb.ToString()) { Restricted = true }; if (suggestion != null) { bool confirmed = false; message.AddReaction(PaginatedMessageReactionType.Yes, async(args) => { confirmed = true; await Task.CompletedTask; }); await ReplyAndWaitAsync(message); if (!confirmed) { suggestion = null; } } else { await ReplyAsync(message); } return(suggestion); }
private async Task ReplySetTaxonDescriptionAsync(ITaxon taxon) { if (taxon.IsValid()) { IMessage message = new Message($"Reply with the description for {taxon.GetRank().GetName()} **{TaxonFormatter.GetString(taxon, false)}**."); IResponsiveMessageResponse response = await ResponsiveMessageService.GetResponseAsync(Context, message); if (!response.Canceled) { await ReplySetTaxonDescriptionAsync(taxon, await GetDescriptionFromMessageAsync(response.Message)); } } }
private async Task ReplySetTaxonDescriptionAsync(ITaxon taxon, string description) { if (taxon.IsValid()) { taxon.Description = description; await Db.UpdateTaxonAsync(taxon); string name = (taxon is ISpecies species) ? species.GetShortName() : taxon.GetName(); await ReplySuccessAsync($"Successfully updated description for {taxon.GetRank().GetName()} **{name}**."); } }
private async Task ReplySetTaxonPictureAsync(TaxonRankType rank, string taxonName, string imageUrl) { ITaxon taxon = await GetTaxonOrReplyAsync(rank, taxonName); if (taxon.IsValid() && await ReplyValidateImageUrlAsync(imageUrl)) { taxon.Pictures.Clear(); taxon.Pictures.Add(new Picture(imageUrl)); await Db.UpdateTaxonAsync(taxon); await ReplySuccessAsync($"Successfully set the picture for for {taxon.GetRank().GetName()} **{taxon.GetName().ToTitle()}**."); } }
private async Task ReplySetTaxonParentAsync(TaxonRankType rank, string childTaxonName, string parentTaxonName) { ITaxon child = await GetTaxonOrReplyAsync(rank.GetChildRank(), childTaxonName); ITaxon parent = child.IsValid() ? await GetTaxonOrReplyAsync(rank, parentTaxonName) : null; if (child.IsValid() && parent.IsValid()) { child.ParentId = parent.Id; await Db.UpdateTaxonAsync(child); await ReplySuccessAsync($"{child.GetRank().GetName().ToSentence()} **{child.GetName().ToTitle()}** has sucessfully been placed under the {parent.GetRank().GetName()} **{parent.GetName().ToTitle()}**."); } }
private async Task ReplySetTaxonCommonNameAsync(ITaxon taxon, string commonName) { if (taxon.IsValid()) { taxon.CommonNames.Clear(); taxon.CommonNames.Add(commonName); await Db.UpdateTaxonAsync(taxon); if (taxon is ISpecies species) { await ReplySuccessAsync($"{species.GetShortName().ToBold()} is now commonly known as the {species.GetCommonName().ToTitle().ToBold()}."); } else { await ReplySuccessAsync($"Members of the {taxon.GetRank().GetName()} {taxon.GetName().ToTitle().ToBold()} are now commonly known as {taxon.GetCommonName().ToTitle().ToBold()}."); } } }
public static async Task <IEnumerable <ISpecies> > GetSpeciesAsync(this SQLiteDatabase database, ITaxon taxon) { List <ISpecies> species = new List <ISpecies>(); if (taxon.GetRank() == TaxonRankType.Species) { // Return the species corresponding to this taxon. species.Add(await database.GetSpeciesAsync(taxon.Id)); } else { // Get all subtaxa and call this function recursively to get the species from each of them. foreach (ITaxon subtaxon in await database.GetSubtaxaAsync(taxon)) { species.AddRange(await database.GetSpeciesAsync(subtaxon)); } } return(species); }
public static async Task UpdateTaxonAsync(this SQLiteDatabase database, ITaxon taxon) { string tableName = GetTableNameForRank(taxon.GetRank()); if (!string.IsNullOrEmpty(tableName)) { string parentColumnName = GetFieldNameForRank(taxon.GetParentRank()); string updateParentColumnStr = string.Empty; if (!string.IsNullOrEmpty(parentColumnName) && taxon.ParentId.HasValue) { updateParentColumnStr = string.Format(", {0}=$parent_id", parentColumnName); } using (SQLiteCommand cmd = new SQLiteCommand(string.Format("UPDATE {0} SET name = $name, description = $description, pics = $pics{1}, common_name = $common_name WHERE id = $id", tableName, updateParentColumnStr))) { cmd.Parameters.AddWithValue("$id", taxon.Id); cmd.Parameters.AddWithValue("$name", taxon.Name.ToLowerInvariant()); cmd.Parameters.AddWithValue("$description", taxon.Description); cmd.Parameters.AddWithValue("$pics", taxon.GetPictureUrl()); // Because this field was added in a database update, it's possible for it to be null rather than the empty string. cmd.Parameters.AddWithValue("$common_name", string.IsNullOrEmpty(taxon.GetCommonName()) ? "" : taxon.GetCommonName().ToLowerInvariant()); if (!string.IsNullOrEmpty(parentColumnName) && taxon.ParentId.HasValue) { cmd.Parameters.AddWithValue("$parent_column_name", parentColumnName); cmd.Parameters.AddWithValue("$parent_id", taxon.ParentId); } await database.ExecuteNonQueryAsync(cmd); } } }
public async Task <IPaginatedMessage> BuildTaxonMessageAsync(ITaxon taxon) { if (!taxon.IsValid()) { return(null); } List <string> subItems = new List <string>(); if (taxon.Rank.Type == TaxonRankType.Species) { ISpecies species = await Db.GetSpeciesAsync(taxon.Id); return(await BuildSpeciesMessageAsync(species)); } else if (taxon.Rank.Type == TaxonRankType.Genus) { // For genera, get all species underneath it. // This will let us check if the species is extinct, and cross it out if that's the case. List <ISpecies> speciesList = new List <ISpecies>(); foreach (ITaxon subtaxon in await Db.GetSubtaxaAsync(taxon)) { speciesList.Add(await Db.GetSpeciesAsync(subtaxon.Id)); } speciesList.Sort((lhs, rhs) => TaxonFormatter.GetString(lhs, false).CompareTo(TaxonFormatter.GetString(rhs, false))); foreach (ISpecies species in speciesList.Where(s => s.IsValid())) { subItems.Add(TaxonFormatter.GetString(species)); } } else { // Get all subtaxa under this taxon. IEnumerable <ITaxon> subtaxa = await Db.GetSubtaxaAsync(taxon); // Add all subtaxa to the list. foreach (ITaxon subtaxon in subtaxa) { if (subtaxon.Rank.Type == TaxonRankType.Species) { // Do not attempt to count sub-taxa for species. subItems.Add(subtaxon.GetName()); } else { // Count the number of species under this taxon. // Taxa with no species under them will not be displayed. long speciesCount = await Db.GetSpeciesCountAsync(subtaxon); if (speciesCount > 0) { // Count the sub-taxa under this taxon. long subtaxaCount = (await Db.GetSubtaxaAsync(subtaxon)).Count(); // Add the taxon to the list. if (subtaxaCount > 0) { subItems.Add(string.Format("{0} ({1})", subtaxon.GetName(), subtaxaCount)); } } } } } // Generate embed pages. string title = taxon.CommonNames.Count() <= 0 ? taxon.GetName() : string.Format("{0} ({1})", taxon.GetName(), taxon.GetCommonName()); string fieldTitle = string.Format("{0} in this {1} ({2}):", taxon.GetChildRank().GetName(true).ToTitle(), taxon.GetRank().GetName().ToLowerInvariant(), subItems.Count()); string thumbnailUrl = taxon.GetPictureUrl(); StringBuilder description = new StringBuilder(); description.AppendLine(taxon.GetDescriptionOrDefault()); if (subItems.Count() <= 0) { description.AppendLine(); description.AppendLine(string.Format("This {0} contains no {1}.", taxon.GetRank().GetName(), taxon.GetChildRank().GetName(true))); } List <Discord.Messaging.IEmbed> pages = new List <Discord.Messaging.IEmbed>(EmbedUtilities.CreateEmbedPages(fieldTitle, subItems, options: EmbedPaginationOptions.AddPageNumbers)); if (!pages.Any()) { pages.Add(new Discord.Messaging.Embed()); } IPaginatedMessage paginatedMessage = new PaginatedMessage(pages); foreach (Discord.Messaging.IEmbed page in paginatedMessage.Select(m => m.Embed)) { page.Title = title; page.ThumbnailUrl = thumbnailUrl; page.Description = description.ToString(); if (subItems.Count() > 0 && taxon.GetRank() != TaxonRankType.Genus) { page.Footer += string.Format(" — Empty {0} are not listed.", taxon.GetChildRank().GetName(true)); } } return(paginatedMessage); }
public static TaxonRankType GetParentRank(this ITaxon taxon) { return(TaxonUtilities.GetParentRank(taxon.GetRank())); }