示例#1
0
        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()}**.");
            }
        }
示例#2
0
        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.");
                }
            }
        }
示例#3
0
        public static async Task <long> GetSpeciesCountAsync(this SQLiteDatabase database, ITaxon taxon)
        {
            if (!taxon.IsValid())
            {
                return(0);
            }

            long speciesCount = 0;

            if (taxon.Rank.Type == TaxonRankType.Species)
            {
                // If a species was passed in, count it as a single species.
                speciesCount += 1;
            }
            else
            {
                // Get all subtaxa and call this function recursively to get the species from each of them.

                IEnumerable <ITaxon> subtaxa = await database.GetSubtaxaAsync(taxon);

                foreach (ITaxon subtaxon in subtaxa)
                {
                    speciesCount += await database.GetSpeciesCountAsync(subtaxon);
                }
            }

            return(speciesCount);
        }
示例#4
0
        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);
                    }
                }
            }
        }
示例#5
0
        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);
                }
            }
        }
示例#6
0
        public async Task Gallery([Remainder] string arg0)
        {
            arg0 = StringUtilities.StripOuterQuotes(arg0);

            // Possible cases:
            // 1. <species>
            // 2. <taxon>

            // Prioritize species galleries first.

            IEnumerable <ISpecies> matchingSpecies = await Db.GetSpeciesAsync(arg0);

            if (matchingSpecies.Count() <= 0)
            {
                // No such species exists, so check if a taxon exists.

                ITaxon taxon = (await Db.GetTaxaAsync(arg0)).FirstOrDefault();

                if (!taxon.IsValid())
                {
                    // If no such taxon exists, show species recommendations to the user.

                    ISpecies species = await ReplySpeciesSuggestionAsync(string.Empty, arg0);

                    if (species.IsValid())
                    {
                        await ShowGalleryAsync(species);
                    }
                }
                else
                {
                    // The taxon does exist, so we'll generate a gallery from this taxon.
                    // First, images for this taxon will be added, followed by the galleries for all species under it.

                    List <IPicture> pictures = new List <IPicture>();

                    pictures.AddRange(taxon.Pictures);

                    foreach (ISpecies species in await Db.GetSpeciesAsync(taxon))
                    {
                        pictures.AddRange(await Db.GetPicturesAsync(species));
                    }

                    await ReplyGalleryAsync(taxon.GetName(), pictures);
                }
            }
            else
            {
                // We got one or more matching species.

                ISpecies species = await ReplyValidateSpeciesAsync(matchingSpecies);

                if (species.IsValid())
                {
                    await ShowGalleryAsync(species);
                }
            }
        }
示例#7
0
        private async Task ReplyDeleteTaxonAsync(string taxonName)
        {
            ITaxon taxon = await GetTaxonOrReplyAsync(taxonName);

            if (taxon.IsValid())
            {
                await ReplyDeleteTaxonAsync(taxon);
            }
        }
示例#8
0
        private async Task ReplySetTaxonCommonNameAsync(TaxonRankType rank, string taxonName, string commonName)
        {
            ITaxon taxon = await GetTaxonOrReplyAsync(rank, taxonName);

            if (taxon.IsValid())
            {
                await ReplySetTaxonCommonNameAsync(taxon, commonName);
            }
        }
示例#9
0
        private async Task ReplySetTaxonDescriptionAsync(TaxonRankType rank, string taxonName)
        {
            ITaxon taxon = await GetTaxonOrReplyAsync(rank, taxonName);

            if (taxon.IsValid())
            {
                await ReplySetTaxonDescriptionAsync(taxon);
            }
        }
示例#10
0
        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}**.");
            }
        }
示例#11
0
        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));
                }
            }
        }
示例#12
0
        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()}**.");
            }
        }
示例#13
0
        public async Task SetTaxonDescription(string arg0, string arg1)
        {
            // Possible cases:
            // 1. <taxon> <description>
            // 2. <genus> <species>

            IEnumerable <ISpecies> matchingSpecies = await Db.GetSpeciesAsync(arg0, arg1);

            if (matchingSpecies.Count() <= 0)
            {
                // No such species exists, so we have case (1). Note that this might still be a species (<species> <description>).

                IEnumerable <ITaxon> taxa = await Db.GetTaxaAsync(arg0);

                if (taxa.Count() <= 0)
                {
                    // If there are no matching taxa, show species suggestions.

                    ISpecies species = await ReplySpeciesSuggestionAsync(string.Empty, arg0);

                    if (species.IsValid())
                    {
                        await ReplySetTaxonDescriptionAsync(species, arg1);
                    }
                }
                else
                {
                    // There is at least one matching taxon.

                    ITaxon taxon = await ReplyValidateTaxaAsync(taxa);

                    if (taxon.IsValid())
                    {
                        await ReplySetTaxonDescriptionAsync(taxon, arg1);
                    }
                }
            }
            else
            {
                // There is at least one matching species.

                ISpecies species = await ReplyValidateSpeciesAsync(matchingSpecies);

                if (species.IsValid())
                {
                    await ReplySetTaxonDescriptionAsync(species);
                }
            }
        }
示例#14
0
        // Private members

        private async Task ReplyTaxonOrTypeAsync(TaxonRankType rank, string taxonName)
        {
            if (string.IsNullOrWhiteSpace(taxonName))
            {
                await ReplyTaxonAsync(rank);
            }
            else
            {
                ITaxon taxon = await GetTaxonOrReplyAsync(rank, taxonName);

                if (taxon.IsValid())
                {
                    await ReplyTaxonAsync(taxon);
                }
            }
        }
示例#15
0
        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()}.");
                }
            }
        }
示例#16
0
        private async Task ReplyAddTaxonAsync(TaxonRankType rank, string taxonName, string description)
        {
            // Make sure that the taxon does not already exist before trying to add it.

            ITaxon taxon = (await Db.GetTaxaAsync(taxonName, rank)).FirstOrDefault();

            if (taxon.IsValid())
            {
                await ReplyWarningAsync($"The {rank.GetName()} **{taxon.GetName()}** already exists.");
            }
            else
            {
                taxon = new Common.Taxa.Taxon(rank, taxonName)
                {
                    Name        = taxonName,
                    Description = description
                };

                await Db.AddTaxonAsync(taxon);

                await ReplySuccessAsync($"Successfully created new {rank.GetName()}, **{taxon.GetName()}**.");
            }
        }
示例#17
0
        public async Task SetGenus(string genusName, string speciesName, string newGenusName)
        {
            // Get the specified species.

            ISpecies species = await GetSpeciesOrReplyAsync(genusName, speciesName);

            if (species.IsValid())
            {
                // Get the specified genus.

                ITaxon genus = await GetTaxonOrReplyAsync(TaxonRankType.Genus, newGenusName);

                if (genus.IsValid())
                {
                    // Update the species.

                    species.Genus = genus;

                    await Db.UpdateSpeciesAsync(species);

                    await ReplySuccessAsync($"**{species.GetShortName()}** has successfully been assigned to the genus **{genus.GetName().ToTitle()}**.");
                }
            }
        }
示例#18
0
        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);
        }