/// <summary> /// Gets the next kink in its category by its predecessor's F-List ID. /// </summary> /// <param name="db">The database.</param> /// <param name="precedingFListID">The F-List ID of the preceding kink.</param> /// <returns>A retrieval result which may or may not have succeeded.</returns> public async Task <RetrieveEntityResult <Kink> > GetNextKinkByCurrentFListIDAsync([NotNull] GlobalInfoContext db, int precedingFListID) { var getKinkResult = await GetKinkByFListIDAsync(db, precedingFListID); if (!getKinkResult.IsSuccess) { return(getKinkResult); } var currentKink = getKinkResult.Entity; var getKinksResult = await GetKinksByCategoryAsync(db, currentKink.Category); if (!getKinksResult.IsSuccess) { return(RetrieveEntityResult <Kink> .FromError(getKinksResult)); } var group = getKinksResult.Entity; var nextKink = group.SkipUntil(k => k.FListID == precedingFListID).FirstOrDefault(); if (nextKink is null) { return(RetrieveEntityResult <Kink> .FromError(CommandError.ObjectNotFound, "The current kink was the last one in the category.")); } return(RetrieveEntityResult <Kink> .FromSuccess(nextKink)); }
/// <summary> /// Gets a user's kink preferences by the F-List kink ID. /// </summary> /// <param name="db">The database.</param> /// <param name="discordUser">The discord user.</param> /// <param name="onlineKinkID">The F-List kink ID.</param> /// <returns>The user's kink preference.</returns> public async Task <RetrieveEntityResult <UserKink> > GetUserKinkByFListIDAsync([NotNull] GlobalInfoContext db, IUser discordUser, int onlineKinkID) { var getKinkResult = await GetKinkByFListIDAsync(db, onlineKinkID); if (!getKinkResult.IsSuccess) { return(RetrieveEntityResult <UserKink> .FromError(getKinkResult)); } var user = await db.GetOrRegisterUserAsync(discordUser); var userKink = user.Kinks.FirstOrDefault(k => k.Kink.FListID == onlineKinkID); if (!(userKink is null)) { return(RetrieveEntityResult <UserKink> .FromSuccess(userKink)); } var kink = getKinkResult.Entity; var addKinkResult = await AddUserKinkAsync(db, discordUser, kink); if (!addKinkResult.IsSuccess) { return(RetrieveEntityResult <UserKink> .FromError(addKinkResult)); } return(RetrieveEntityResult <UserKink> .FromSuccess(addKinkResult.Entity)); }
public RetrieveEntityResult <FileStream> OpenLocalStream([PathReference][NotNull] string path, [CanBeNull] string subdirectory = null, FileMode fileMode = FileMode.Open) { var absolutePath = Path.GetFullPath(path); if (!absolutePath.StartsWith(this.BaseContentPath)) { return(RetrieveEntityResult <FileStream> .FromError ( CommandError.Unsuccessful, "The path pointed to something that wasn't in the content folder." )); } if (!(subdirectory is null)) { var subdirectoryParentDir = Path.Combine(this.BaseContentPath, subdirectory); if (!absolutePath.StartsWith(subdirectoryParentDir)) { return(RetrieveEntityResult <FileStream> .FromError ( CommandError.Unsuccessful, "The path pointed to something that wasn't in the specified subdirectory." )); } } // Make sure that the directory chain is created Directory.CreateDirectory(Directory.GetParent(absolutePath).FullName); return(RetrieveEntityResult <FileStream> .FromSuccess(File.Open(absolutePath, fileMode))); }
public async Task <RetrieveEntityResult <Roleplay> > GetNamedRoleplayAsync ( [NotNull] GlobalInfoContext db, [NotNull] string roleplayName, [NotNull] IGuild guild ) { if (await db.Roleplays.CountAsync(rp => string.Equals(rp.Name, roleplayName, StringComparison.OrdinalIgnoreCase)) > 1) { return(RetrieveEntityResult <Roleplay> .FromError ( CommandError.MultipleMatches, "There's more than one roleplay with that name. Please specify which user it belongs to." )); } var roleplay = GetRoleplays(db, guild) .FirstOrDefault(rp => string.Equals(rp.Name, roleplayName, StringComparison.OrdinalIgnoreCase)); if (roleplay is null) { return(RetrieveEntityResult <Roleplay> .FromError(CommandError.ObjectNotFound, "No roleplay with that name found.")); } return(RetrieveEntityResult <Roleplay> .FromSuccess(roleplay)); }
public async Task <RetrieveEntityResult <Character> > GetUserCharacterByNameAsync ( [NotNull] GlobalInfoContext db, [NotNull] ICommandContext context, [NotNull] IUser characterOwner, [NotNull] string characterName ) { var character = await GetUserCharacters(db, characterOwner, context.Guild) .FirstOrDefaultAsync ( ch => string.Equals(ch.Name, characterName, StringComparison.OrdinalIgnoreCase) ); if (character is null) { var isCurrentUser = context.Message.Author.Id == characterOwner.Id; var errorMessage = isCurrentUser ? "You don't own a character with that name." : "The user doesn't own a character with that name."; return(RetrieveEntityResult <Character> .FromError(CommandError.ObjectNotFound, errorMessage)); } return(RetrieveEntityResult <Character> .FromSuccess(character)); }
public async Task <RetrieveEntityResult <Character> > GetNamedCharacterAsync ( [NotNull] GlobalInfoContext db, [NotNull] string characterName, [NotNull] IGuild guild ) { var guildCharacters = db.Characters.Where(ch => ch.ServerID == (long)guild.Id); if (await guildCharacters.CountAsync(ch => string.Equals(ch.Name, characterName, StringComparison.OrdinalIgnoreCase)) > 1) { return(RetrieveEntityResult <Character> .FromError ( CommandError.MultipleMatches, "There's more than one character with that name. Please specify which user it belongs to." )); } var character = GetCharacters(db, guild).FirstOrDefault(ch => string.Equals(ch.Name, characterName, StringComparison.OrdinalIgnoreCase)); if (character is null) { return(RetrieveEntityResult <Character> .FromError(CommandError.ObjectNotFound, "No character with that name found.")); } return(RetrieveEntityResult <Character> .FromSuccess(character)); }
public async Task <RetrieveEntityResult <Character> > GetCurrentCharacterAsync ( [NotNull] GlobalInfoContext db, [NotNull] ICommandContext context, [NotNull] IUser discordUser ) { if (!await HasActiveCharacterOnServerAsync(db, discordUser, context.Guild)) { var isCurrentUser = context.Message.Author.Id == discordUser.Id; var errorMessage = isCurrentUser ? "You haven't assumed a character." : "The user hasn't assumed a character."; return(RetrieveEntityResult <Character> .FromError(CommandError.ObjectNotFound, errorMessage)); } var currentCharacter = await GetUserCharacters(db, discordUser, context.Guild) .FirstOrDefaultAsync ( ch => ch.IsCurrent ); if (currentCharacter is null) { return(RetrieveEntityResult <Character> .FromError(CommandError.Unsuccessful, "Failed to retrieve a current character.")); } return(RetrieveEntityResult <Character> .FromSuccess(currentCharacter)); }
public async Task <RetrieveEntityResult <Roleplay> > GetUserRoleplayByNameAsync ( [NotNull] GlobalInfoContext db, [NotNull] ICommandContext context, [NotNull] IUser roleplayOwner, [NotNull] string roleplayName ) { var roleplay = await GetRoleplays(db, context.Guild) .FirstOrDefaultAsync ( rp => rp.Name.Equals(roleplayName, StringComparison.OrdinalIgnoreCase) && rp.Owner.DiscordID == (long)roleplayOwner.Id ); if (roleplay is null) { var isCurrentUser = context.Message.Author.Id == roleplayOwner.Id; var errorMessage = isCurrentUser ? "You don't own a roleplay with that name." : "The user doesn't own a roleplay with that name."; return(RetrieveEntityResult <Roleplay> .FromError(CommandError.ObjectNotFound, errorMessage)); } return(RetrieveEntityResult <Roleplay> .FromSuccess(roleplay)); }
public RetrieveEntityResult <FileStream> GetDossierStream([NotNull] Dossier dossier) { if (!File.Exists(dossier.Path) || dossier.Path.IsNullOrWhitespace()) { return(RetrieveEntityResult <FileStream> .FromError(CommandError.ObjectNotFound, "No file data set.")); } return(OpenLocalStream(dossier.Path, "Dossiers")); }
/// <summary> /// Gets a kink by its F-list ID. /// </summary> /// <param name="db">The database.</param> /// <param name="onlineKinkID">The F-List kink ID.</param> /// <returns>A retrieval result which may or may not have succeeded.</returns> public async Task <RetrieveEntityResult <Kink> > GetKinkByFListIDAsync([NotNull] GlobalInfoContext db, int onlineKinkID) { var kink = await db.Kinks.FirstOrDefaultAsync(k => k.FListID == onlineKinkID); if (kink is null) { return(RetrieveEntityResult <Kink> .FromError(CommandError.ObjectNotFound, "No kink with that ID found.")); } return(RetrieveEntityResult <Kink> .FromSuccess(kink)); }
/// <summary> /// Gets the first kink in the given category. /// </summary> /// <param name="db">The database.</param> /// <param name="category">The category.</param> /// <returns>A retrieval result which may or may not have succeeded.</returns> public async Task <RetrieveEntityResult <Kink> > GetFirstKinkInCategoryAsync([NotNull] GlobalInfoContext db, KinkCategory category) { var getKinksResult = await GetKinksByCategoryAsync(db, category); if (!getKinksResult.IsSuccess) { return(RetrieveEntityResult <Kink> .FromError(getKinksResult)); } return(RetrieveEntityResult <Kink> .FromSuccess(getKinksResult.Entity.First())); }
public async Task <RetrieveEntityResult <Dossier> > GetDossierByTitleAsync ( [NotNull] GlobalInfoContext db, [NotNull] string title ) { var dossier = await db.Dossiers.FirstOrDefaultAsync(d => string.Equals(d.Title, title, StringComparison.OrdinalIgnoreCase)); if (dossier is null) { return(RetrieveEntityResult <Dossier> .FromError(CommandError.ObjectNotFound, "No dossier with that title found.")); } return(RetrieveEntityResult <Dossier> .FromSuccess(dossier)); }
/// <summary> /// Gets a list of all kinks in a given category. /// </summary> /// <param name="db">The database.</param> /// <param name="category">The category.</param> /// <returns>A retrieval result which may or may not have succeeded.</returns> public async Task <RetrieveEntityResult <IEnumerable <Kink> > > GetKinksByCategoryAsync([NotNull] GlobalInfoContext db, KinkCategory category) { var group = await db.Kinks.GroupBy(k => k.Category).FirstOrDefaultAsync(g => g.Key == category); if (group is null) { return(RetrieveEntityResult <IEnumerable <Kink> > .FromError ( CommandError.ObjectNotFound, "There are no kinks in that category." )); } return(RetrieveEntityResult <IEnumerable <Kink> > .FromSuccess(group)); }
public async Task <RetrieveEntityResult <Stream> > GetAttachmentStreamAsync([NotNull] Attachment attachment) { try { var stream = await Client.GetStreamAsync(attachment.Url); return(RetrieveEntityResult <Stream> .FromSuccess(stream)); } catch (HttpRequestException hex) { return(RetrieveEntityResult <Stream> .FromError(CommandError.Exception, hex.ToString())); } catch (TaskCanceledException) { return(RetrieveEntityResult <Stream> .FromError(CommandError.Unsuccessful, "The download operation timed out.")); } }
public async Task <RetrieveEntityResult <IReadOnlyList <Transformation> > > DiscoverBundledTransformationsAsync ( [NotNull] GlobalInfoContext db, [NotNull] TransformationService transformation, [NotNull] Species species ) { const string speciesFilename = "Species.yml"; var speciesDir = GetSpeciesDirectory(species); var transformationFiles = Directory.EnumerateFiles(speciesDir).Where(p => !p.EndsWith(speciesFilename)); var transformations = new List <Transformation>(); var deser = new DeserializerBuilder() .WithTypeConverter(new ColourYamlConverter()) .WithTypeConverter(new SpeciesYamlConverter(db, transformation)) .WithNodeDeserializer(i => new ValidatingNodeDeserializer(i), s => s.InsteadOf <ObjectNodeDeserializer>()) .WithNamingConvention(new UnderscoredNamingConvention()) .Build(); foreach (var transformationFile in transformationFiles) { string content = await FileAsync.ReadAllTextAsync(transformationFile); try { transformations.Add(deser.Deserialize <Transformation>(content)); } catch (YamlException yex) { if (yex.InnerException is SerializationException sex) { return(RetrieveEntityResult <IReadOnlyList <Transformation> > .FromError(sex)); } return(RetrieveEntityResult <IReadOnlyList <Transformation> > .FromError(yex)); } } return(RetrieveEntityResult <IReadOnlyList <Transformation> > .FromSuccess(transformations)); }
public async Task <RetrieveEntityResult <Roleplay> > GetActiveRoleplayAsync ( [NotNull] GlobalInfoContext db, [NotNull] ICommandContext context ) { if (context.Guild is null) { return(RetrieveEntityResult <Roleplay> .FromError(CommandError.ObjectNotFound, "You're not in a server.")); } var roleplay = await GetRoleplays(db, context.Guild) .FirstOrDefaultAsync(rp => rp.IsActive && rp.ActiveChannelID == (long)context.Channel.Id); if (roleplay is null) { return(RetrieveEntityResult <Roleplay> .FromError(CommandError.ObjectNotFound, "There is no roleplay that is currently active in this channel.")); } return(RetrieveEntityResult <Roleplay> .FromSuccess(roleplay)); }
public async Task <RetrieveEntityResult <IReadOnlyList <Species> > > DiscoverBundledSpeciesAsync() { const string speciesFilename = "Species.yml"; var deser = new DeserializerBuilder() .WithNodeDeserializer(i => new ValidatingNodeDeserializer(i), s => s.InsteadOf <ObjectNodeDeserializer>()) .WithNamingConvention(new UnderscoredNamingConvention()) .Build(); var species = new List <Species>(); var speciesFolders = Directory.EnumerateDirectories(this.BaseTransformationSpeciesPath); foreach (string directory in speciesFolders) { string speciesFilePath = Path.Combine(directory, speciesFilename); if (!File.Exists(speciesFilePath)) { continue; } string content = await FileAsync.ReadAllTextAsync(speciesFilePath, Encoding.UTF8); try { species.Add(deser.Deserialize <Species>(content)); } catch (YamlException yex) { if (yex.InnerException is SerializationException sex) { return(RetrieveEntityResult <IReadOnlyList <Species> > .FromError(sex)); } return(RetrieveEntityResult <IReadOnlyList <Species> > .FromError(yex)); } } return(RetrieveEntityResult <IReadOnlyList <Species> > .FromSuccess(species)); }
/// <summary> /// Gets the first kink that the given uses does not have a set preference for in the given category. /// </summary> /// <param name="db">The database.</param> /// <param name="user">The user.</param> /// <param name="category">The category.</param> /// <returns>A retrieval result which may or may not have succeeded.</returns> public async Task <RetrieveEntityResult <Kink> > GetFirstKinkWithoutPreferenceInCategoryAsync([NotNull] GlobalInfoContext db, IUser user, KinkCategory category) { var getKinksResult = await GetKinksByCategoryAsync(db, category); if (!getKinksResult.IsSuccess) { return(RetrieveEntityResult <Kink> .FromError(getKinksResult)); } var kinks = getKinksResult.Entity; var userKinks = (await GetUserKinksByCategoryAsync(db, user, category)).ToList(); // Find the first kink that the user either has in their list with no preference, or does not exist // in their list var kinkWithoutPreference = kinks.FirstOrDefault ( k => userKinks.Any ( uk => k.FListID == uk.Kink.FListID && uk.Preference == KinkPreference.NoPreference ) || userKinks.All ( uk => k.FListID != uk.Kink.FListID ) ); if (kinkWithoutPreference is null) { return(RetrieveEntityResult <Kink> .FromError(CommandError.ObjectNotFound, "No kink without a set preference found.")); } return(RetrieveEntityResult <Kink> .FromSuccess(kinkWithoutPreference)); }