From 2089df52ad38d6517cfdbb711d512943be29e2d6 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Wed, 5 Jan 2022 17:20:27 +0300 Subject: [PATCH 01/11] Add Discrod side --- Bot.sln | 23 +- DiscordBot/DiscordBot.csproj | 14 + DiscordBot/DiscrodBot.cs | 63 ++++ .../LinksPlatformDiscordBor.csproj | 16 + LinksPlatformDiscordBor/Program.cs | 63 ++++ csharp/Platform.Bot/Platform.Bot.csproj | 1 + csharp/Platform.Bot/Program.cs | 2 + csharp/Storage/LocalStorage/File.cs | 36 +- csharp/Storage/LocalStorage/FileStorage.cs | 355 +++++++++--------- 9 files changed, 381 insertions(+), 192 deletions(-) create mode 100644 DiscordBot/DiscordBot.csproj create mode 100644 DiscordBot/DiscrodBot.cs create mode 100644 LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj create mode 100644 LinksPlatformDiscordBor/Program.cs diff --git a/Bot.sln b/Bot.sln index 53dd800f..5213f46b 100644 --- a/Bot.sln +++ b/Bot.sln @@ -1,12 +1,17 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Bot", "csharp\Platform.Bot\Platform.Bot.csproj", "{81D55AD3-9698-4BEC-B7EC-26ED7B8E6E53}" +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Platform.Bot", "csharp\Platform.Bot\Platform.Bot.csproj", "{81D55AD3-9698-4BEC-B7EC-26ED7B8E6E53}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileManager", "csharp\FileManager\FileManager.csproj", "{2F40CB1A-A1FD-4433-B998-BC3AEA2EFEB3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileManager", "csharp\FileManager\FileManager.csproj", "{2F40CB1A-A1FD-4433-B998-BC3AEA2EFEB3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interfaces", "csharp\Interfaces\Interfaces.csproj", "{CF4AF09D-456A-4F85-9879-99AE74839B35}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interfaces", "csharp\Interfaces\Interfaces.csproj", "{CF4AF09D-456A-4F85-9879-99AE74839B35}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Storage", "csharp\Storage\Storage.csproj", "{E81C2E82-9F15-478C-8388-E9BD53686E36}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Storage", "csharp\Storage\Storage.csproj", "{E81C2E82-9F15-478C-8388-E9BD53686E36}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBot", "DiscordBot\DiscordBot.csproj", "{3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -30,5 +35,15 @@ Global {E81C2E82-9F15-478C-8388-E9BD53686E36}.Debug|Any CPU.Build.0 = Debug|Any CPU {E81C2E82-9F15-478C-8388-E9BD53686E36}.Release|Any CPU.ActiveCfg = Release|Any CPU {E81C2E82-9F15-478C-8388-E9BD53686E36}.Release|Any CPU.Build.0 = Release|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F6862B5F-1B9D-4EE5-92DA-19F07B85A78C} EndGlobalSection EndGlobal diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj new file mode 100644 index 00000000..c5f4dd14 --- /dev/null +++ b/DiscordBot/DiscordBot.csproj @@ -0,0 +1,14 @@ + + + + net5.0 + + + + + + + + + + diff --git a/DiscordBot/DiscrodBot.cs b/DiscordBot/DiscrodBot.cs new file mode 100644 index 00000000..6f24c9fa --- /dev/null +++ b/DiscordBot/DiscrodBot.cs @@ -0,0 +1,63 @@ +using Discord; +using Discord.WebSocket; +using System; +using System.Threading.Tasks; + +namespace LinksPlatformDiscordBot +{ + public class BotStartup + { + private Storage.Local.FileStorage LinksStorage { get; set; } + + private string Token { get; set; } + + private DiscordSocketClient Client { get; set; } + + public BotStartup(string token, Storage.Local.FileStorage storage) + { + LinksStorage = storage; + Client = new DiscordSocketClient(); + Token = token; + } + public async Task StartupAsync() + { + Client.Log += Log; + Client.MessageReceived += MessageReceived; + await Client.LoginAsync(TokenType.Bot, Token); + await Client.StartAsync(); + + await Task.Delay(-1); + } + private async Task MessageReceived(SocketMessage message) + { + if (message.Content.Contains("https://github.com")) + { + if (message.Channel.Name == "main") + await message.Channel.SendMessageAsync("@konard look at this dude"); + } + if (message.Content.Contains("accept")) + { + if (message.Author.Username == "FirstAfterGod") + { + await message.Channel.SendMessageAsync("accepted."); + string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; + LinksStorage.AddLinkToIvite(link); + foreach (var a in LinksStorage.GetLinksToInvite()) + { + Console.WriteLine(a); + } + } + } + } + public void CreateInvite(string link) + { + + } + + private Task Log(LogMessage msg) + { + Console.WriteLine(msg.ToString()); + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj b/LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj new file mode 100644 index 00000000..64badeba --- /dev/null +++ b/LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj @@ -0,0 +1,16 @@ + + + + Exe + net5.0 + + + + + + + + + + + diff --git a/LinksPlatformDiscordBor/Program.cs b/LinksPlatformDiscordBor/Program.cs new file mode 100644 index 00000000..4b157cc4 --- /dev/null +++ b/LinksPlatformDiscordBor/Program.cs @@ -0,0 +1,63 @@ +using Discord; +using Discord.WebSocket; +using System; +using System.Threading.Tasks; + +namespace LinksPlatformDiscordBot +{ + public class BotStartup + { + private Storage.Local.FileStorage LinksStorage { get; set; } + + private string Token { get; set; } + + private DiscordSocketClient Client { get; set; } + + public BotStartup(string token, string DBFilename) + { + LinksStorage = new Storage.Local.FileStorage(DBFilename); + Client = new DiscordSocketClient(); + Token = token; + } + public async Task Main() + { + Client.Log += Log; + Client.MessageReceived += MessageReceived; + await Client.LoginAsync(TokenType.Bot, Token); + await Client.StartAsync(); + + await Task.Delay(-1); + } + private async Task MessageReceived(SocketMessage message) + { + if (message.Content.Contains("https://github.com")) + { + if (message.Channel.Name == "#main") + await message.Channel.SendMessageAsync("@konard look at this dude"); + } + if (message.Content.Contains("/accept")) + { + if (message.Author.Username == "Konstantin Dyachenko#8793") + { + await message.Channel.SendMessageAsync("accepted."); + string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; + LinksStorage.AddLinkToIvite(link); + foreach (var a in LinksStorage.GetLinksToInvite()) + { + Console.WriteLine(a); + } + } + } + } + public void CreateInvite(string link) + { + + } + + private Task Log(LogMessage msg) + { + Console.WriteLine(msg.ToString()); + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/csharp/Platform.Bot/Platform.Bot.csproj b/csharp/Platform.Bot/Platform.Bot.csproj index 06fa2c68..7ab7131e 100644 --- a/csharp/Platform.Bot/Platform.Bot.csproj +++ b/csharp/Platform.Bot/Platform.Bot.csproj @@ -13,6 +13,7 @@ + diff --git a/csharp/Platform.Bot/Program.cs b/csharp/Platform.Bot/Program.cs index ccf53106..d79705a8 100644 --- a/csharp/Platform.Bot/Program.cs +++ b/csharp/Platform.Bot/Program.cs @@ -28,8 +28,10 @@ private static void Main(string[] args) var appName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "App Name", args); var databaseFileName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Database file name", args); var fileSetName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "File set name ", args); + var discordToken = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Token for discord bot", args); var dbContext = new FileStorage(databaseFileName); Console.WriteLine($"Bot has been started. {Environment.NewLine}Press CTRL+C to close"); + new LinksPlatformDiscordBot.BotStartup(discordToken, dbContext).StartupAsync(); try { var api = new GitHubStorage(username, token, appName); diff --git a/csharp/Storage/LocalStorage/File.cs b/csharp/Storage/LocalStorage/File.cs index aff476cc..98d7e82e 100644 --- a/csharp/Storage/LocalStorage/File.cs +++ b/csharp/Storage/LocalStorage/File.cs @@ -1,28 +1,28 @@ namespace Storage.Local { - /// - /// - /// Represents the file. - /// - /// - /// + /// + /// + /// Represents the file. + /// + /// + /// public class File { - /// - /// - /// Gets or sets the path value. - /// - /// - /// + /// + /// + /// Gets or sets the path value. + /// + /// + /// public string Path { get; set; } - /// - /// - /// Gets or sets the content value. - /// - /// - /// + /// + /// + /// Gets or sets the content value. + /// + /// + /// public string Content { get; set; } } } diff --git a/csharp/Storage/LocalStorage/FileStorage.cs b/csharp/Storage/LocalStorage/FileStorage.cs index 0758a91d..484844f4 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -18,12 +18,12 @@ namespace Storage.Local { - /// - /// - /// Represents the file storage. - /// - /// - /// + /// + /// + /// Represents the file storage. + /// + /// + /// public class FileStorage { private readonly TLinkAddress _unicodeSequenceMarker; @@ -36,20 +36,21 @@ public class FileStorage private readonly TLinkAddress _unicodeSymbolMarker; private readonly TLinkAddress _setMarker; private readonly TLinkAddress _fileMarker; + private readonly TLinkAddress _linksToInviteToTheOrganizationMarker; private readonly TLinkAddress Any; private TLinkAddress GetOrCreateNextMapping(TLinkAddress currentMappingIndex) => Links.Exists(currentMappingIndex) ? currentMappingIndex : Links.CreateAndUpdate(_meaningRoot, Links.Constants.Itself); private TLinkAddress GetOrCreateMeaningRoot(TLinkAddress meaningRootIndex) => Links.Exists(meaningRootIndex) ? meaningRootIndex : Links.CreatePoint(); - /// - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// A db filename. - /// - /// + /// + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// A db filename. + /// + /// public FileStorage(string DBFilename) { var linksConstants = new LinksConstants(enableExternalReferencesSupport: true); @@ -64,6 +65,7 @@ public FileStorage(string DBFilename) _unicodeSequenceMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); _setMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); _fileMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _linksToInviteToTheOrganizationMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); _addressToNumberConverter = new AddressToRawNumberConverter(); _numberToAddressConverter = new RawNumberToAddressConverter(); var balancedVariantConverter = new BalancedVariantConverter(Links); @@ -76,56 +78,69 @@ public FileStorage(string DBFilename) _unicodeSequenceToStringConverter = new CachingConverterDecorator(new UnicodeSequenceToStringConverter(Links, unicodeSequenceCriterionMatcher, sequenceWalker, unicodeSymbolToCharConverter)); } - /// - /// - /// Converts the str. - /// - /// - /// - /// - /// The str. - /// - /// - /// - /// The link address - /// - /// + public void AddLinkToIvite(string linkToInvite) => Links.GetOrCreate(_linksToInviteToTheOrganizationMarker, _stringToUnicodeSequenceConverter.Convert(linkToInvite)); + + public List GetLinksToInvite() + { + List links = new(); + var list = Links.All(new Link(index: Any, source: _linksToInviteToTheOrganizationMarker, target: Any)); + foreach (var link in list) + { + links.Add(Convert(Links.GetTarget(link))); + } + return links; + } + + /// + /// + /// Converts the str. + /// + /// + /// + /// + /// The str. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress Convert(string str) => _stringToUnicodeSequenceConverter.Convert(str); - /// - /// - /// Converts the address. - /// - /// - /// - /// - /// The address. - /// - /// - /// - /// The string - /// - /// + /// + /// + /// Converts the address. + /// + /// + /// + /// + /// The address. + /// + /// + /// + /// The string + /// + /// public string Convert(TLinkAddress address) => _unicodeSequenceToStringConverter.Convert(address); - /// - /// - /// Gets the file content using the specified address. - /// - /// - /// - /// - /// The address. - /// - /// - /// - /// Link is not a file. - /// - /// - /// - /// The string - /// - /// + /// + /// + /// Gets the file content using the specified address. + /// + /// + /// + /// + /// The address. + /// + /// + /// + /// Link is not a file. + /// + /// + /// + /// The string + /// + /// public string GetFileContent(TLinkAddress address) { var link = Links.GetLink(address); @@ -136,28 +151,28 @@ public string GetFileContent(TLinkAddress address) throw new InvalidOperationException("Link is not a file."); } - /// - /// - /// Deletes the link. - /// - /// - /// - /// - /// The link. - /// - /// + /// + /// + /// Deletes the link. + /// + /// + /// + /// + /// The link. + /// + /// public void Delete(TLinkAddress link) => Links.Delete(link); - /// - /// - /// Gets the all files. - /// - /// - /// - /// - /// The files. - /// - /// + /// + /// + /// Gets the all files. + /// + /// + /// + /// + /// The files. + /// + /// public List GetAllFiles() { List files = new() { }; @@ -168,16 +183,16 @@ public List GetAllFiles() return files; } - /// - /// - /// Alls the links to string. - /// - /// - /// - /// - /// The string - /// - /// + /// + /// + /// Alls the links to string. + /// + /// + /// + /// + /// The string + /// + /// public string AllLinksToString() { StringBuilder builder = new(); @@ -190,76 +205,76 @@ public string AllLinksToString() return builder.ToString(); } - /// - /// - /// Adds the file using the specified content. - /// - /// - /// - /// - /// The content. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Adds the file using the specified content. + /// + /// + /// + /// + /// The content. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress AddFile(string content) => Links.GetOrCreate(_fileMarker, _stringToUnicodeSequenceConverter.Convert(content)); - /// - /// - /// Creates the file set using the specified file set name. - /// - /// - /// - /// - /// The file set name. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Creates the file set using the specified file set name. + /// + /// + /// + /// + /// The file set name. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress CreateFileSet(string fileSetName) => Links.GetOrCreate(_setMarker, Convert(fileSetName)); - /// - /// - /// Adds the file to set using the specified set. - /// - /// - /// - /// - /// The set. - /// - /// - /// - /// The file. - /// - /// - /// - /// The path. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Adds the file to set using the specified set. + /// + /// + /// + /// + /// The set. + /// + /// + /// + /// The file. + /// + /// + /// + /// The path. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress AddFileToSet(TLinkAddress set, TLinkAddress file, string path) => Links.GetOrCreate(set, Links.GetOrCreate(Convert(path), file)); - /// - /// - /// Gets the file set using the specified file set name. - /// - /// - /// - /// - /// The file set name. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Gets the file set using the specified file set name. + /// + /// + /// + /// + /// The file set name. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress GetFileSet(string fileSetName) => Links.SearchOrDefault(_setMarker, Convert(fileSetName)); private IList> GetFilesLinksFromSet(string set) { @@ -268,20 +283,20 @@ private IList> GetFilesLinksFromSet(string set) return list; } - /// - /// - /// Gets the files from set using the specified set. - /// - /// - /// - /// - /// The set. - /// - /// - /// - /// The files. - /// - /// + /// + /// + /// Gets the files from set using the specified set. + /// + /// + /// + /// + /// The set. + /// + /// + /// + /// The files. + /// + /// public List GetFilesFromSet(string set) { List files = new(); From 62179ab82eed12b72116fe3d32a946e2cbc5f0c0 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Wed, 5 Jan 2022 17:21:01 +0300 Subject: [PATCH 02/11] Delete LinksPlatformDiscordBor directory --- .../LinksPlatformDiscordBor.csproj | 16 ----- LinksPlatformDiscordBor/Program.cs | 63 ------------------- 2 files changed, 79 deletions(-) delete mode 100644 LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj delete mode 100644 LinksPlatformDiscordBor/Program.cs diff --git a/LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj b/LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj deleted file mode 100644 index 64badeba..00000000 --- a/LinksPlatformDiscordBor/LinksPlatformDiscordBor.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - - diff --git a/LinksPlatformDiscordBor/Program.cs b/LinksPlatformDiscordBor/Program.cs deleted file mode 100644 index 4b157cc4..00000000 --- a/LinksPlatformDiscordBor/Program.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Discord; -using Discord.WebSocket; -using System; -using System.Threading.Tasks; - -namespace LinksPlatformDiscordBot -{ - public class BotStartup - { - private Storage.Local.FileStorage LinksStorage { get; set; } - - private string Token { get; set; } - - private DiscordSocketClient Client { get; set; } - - public BotStartup(string token, string DBFilename) - { - LinksStorage = new Storage.Local.FileStorage(DBFilename); - Client = new DiscordSocketClient(); - Token = token; - } - public async Task Main() - { - Client.Log += Log; - Client.MessageReceived += MessageReceived; - await Client.LoginAsync(TokenType.Bot, Token); - await Client.StartAsync(); - - await Task.Delay(-1); - } - private async Task MessageReceived(SocketMessage message) - { - if (message.Content.Contains("https://github.com")) - { - if (message.Channel.Name == "#main") - await message.Channel.SendMessageAsync("@konard look at this dude"); - } - if (message.Content.Contains("/accept")) - { - if (message.Author.Username == "Konstantin Dyachenko#8793") - { - await message.Channel.SendMessageAsync("accepted."); - string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; - LinksStorage.AddLinkToIvite(link); - foreach (var a in LinksStorage.GetLinksToInvite()) - { - Console.WriteLine(a); - } - } - } - } - public void CreateInvite(string link) - { - - } - - private Task Log(LogMessage msg) - { - Console.WriteLine(msg.ToString()); - return Task.CompletedTask; - } - } -} \ No newline at end of file From c7c42237861cfd23d3b4762f795f38c80af5c213 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Wed, 5 Jan 2022 17:20:27 +0300 Subject: [PATCH 03/11] Add Discrod side --- Bot.sln | 23 +- csharp/DiscordBot/DiscordBot.csproj | 14 + csharp/DiscordBot/DiscrodBot.cs | 63 ++++ csharp/Platform.Bot/Platform.Bot.csproj | 1 + csharp/Platform.Bot/Program.cs | 2 + csharp/Storage/LocalStorage/File.cs | 36 +-- csharp/Storage/LocalStorage/FileStorage.cs | 355 +++++++++++---------- 7 files changed, 302 insertions(+), 192 deletions(-) create mode 100644 csharp/DiscordBot/DiscordBot.csproj create mode 100644 csharp/DiscordBot/DiscrodBot.cs diff --git a/Bot.sln b/Bot.sln index 53dd800f..5213f46b 100644 --- a/Bot.sln +++ b/Bot.sln @@ -1,12 +1,17 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Bot", "csharp\Platform.Bot\Platform.Bot.csproj", "{81D55AD3-9698-4BEC-B7EC-26ED7B8E6E53}" +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Platform.Bot", "csharp\Platform.Bot\Platform.Bot.csproj", "{81D55AD3-9698-4BEC-B7EC-26ED7B8E6E53}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileManager", "csharp\FileManager\FileManager.csproj", "{2F40CB1A-A1FD-4433-B998-BC3AEA2EFEB3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileManager", "csharp\FileManager\FileManager.csproj", "{2F40CB1A-A1FD-4433-B998-BC3AEA2EFEB3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interfaces", "csharp\Interfaces\Interfaces.csproj", "{CF4AF09D-456A-4F85-9879-99AE74839B35}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interfaces", "csharp\Interfaces\Interfaces.csproj", "{CF4AF09D-456A-4F85-9879-99AE74839B35}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Storage", "csharp\Storage\Storage.csproj", "{E81C2E82-9F15-478C-8388-E9BD53686E36}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Storage", "csharp\Storage\Storage.csproj", "{E81C2E82-9F15-478C-8388-E9BD53686E36}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBot", "DiscordBot\DiscordBot.csproj", "{3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -30,5 +35,15 @@ Global {E81C2E82-9F15-478C-8388-E9BD53686E36}.Debug|Any CPU.Build.0 = Debug|Any CPU {E81C2E82-9F15-478C-8388-E9BD53686E36}.Release|Any CPU.ActiveCfg = Release|Any CPU {E81C2E82-9F15-478C-8388-E9BD53686E36}.Release|Any CPU.Build.0 = Release|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F6862B5F-1B9D-4EE5-92DA-19F07B85A78C} EndGlobalSection EndGlobal diff --git a/csharp/DiscordBot/DiscordBot.csproj b/csharp/DiscordBot/DiscordBot.csproj new file mode 100644 index 00000000..c5f4dd14 --- /dev/null +++ b/csharp/DiscordBot/DiscordBot.csproj @@ -0,0 +1,14 @@ + + + + net5.0 + + + + + + + + + + diff --git a/csharp/DiscordBot/DiscrodBot.cs b/csharp/DiscordBot/DiscrodBot.cs new file mode 100644 index 00000000..6f24c9fa --- /dev/null +++ b/csharp/DiscordBot/DiscrodBot.cs @@ -0,0 +1,63 @@ +using Discord; +using Discord.WebSocket; +using System; +using System.Threading.Tasks; + +namespace LinksPlatformDiscordBot +{ + public class BotStartup + { + private Storage.Local.FileStorage LinksStorage { get; set; } + + private string Token { get; set; } + + private DiscordSocketClient Client { get; set; } + + public BotStartup(string token, Storage.Local.FileStorage storage) + { + LinksStorage = storage; + Client = new DiscordSocketClient(); + Token = token; + } + public async Task StartupAsync() + { + Client.Log += Log; + Client.MessageReceived += MessageReceived; + await Client.LoginAsync(TokenType.Bot, Token); + await Client.StartAsync(); + + await Task.Delay(-1); + } + private async Task MessageReceived(SocketMessage message) + { + if (message.Content.Contains("https://github.com")) + { + if (message.Channel.Name == "main") + await message.Channel.SendMessageAsync("@konard look at this dude"); + } + if (message.Content.Contains("accept")) + { + if (message.Author.Username == "FirstAfterGod") + { + await message.Channel.SendMessageAsync("accepted."); + string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; + LinksStorage.AddLinkToIvite(link); + foreach (var a in LinksStorage.GetLinksToInvite()) + { + Console.WriteLine(a); + } + } + } + } + public void CreateInvite(string link) + { + + } + + private Task Log(LogMessage msg) + { + Console.WriteLine(msg.ToString()); + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/csharp/Platform.Bot/Platform.Bot.csproj b/csharp/Platform.Bot/Platform.Bot.csproj index 06fa2c68..7ab7131e 100644 --- a/csharp/Platform.Bot/Platform.Bot.csproj +++ b/csharp/Platform.Bot/Platform.Bot.csproj @@ -13,6 +13,7 @@ + diff --git a/csharp/Platform.Bot/Program.cs b/csharp/Platform.Bot/Program.cs index ccf53106..d79705a8 100644 --- a/csharp/Platform.Bot/Program.cs +++ b/csharp/Platform.Bot/Program.cs @@ -28,8 +28,10 @@ private static void Main(string[] args) var appName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "App Name", args); var databaseFileName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Database file name", args); var fileSetName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "File set name ", args); + var discordToken = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Token for discord bot", args); var dbContext = new FileStorage(databaseFileName); Console.WriteLine($"Bot has been started. {Environment.NewLine}Press CTRL+C to close"); + new LinksPlatformDiscordBot.BotStartup(discordToken, dbContext).StartupAsync(); try { var api = new GitHubStorage(username, token, appName); diff --git a/csharp/Storage/LocalStorage/File.cs b/csharp/Storage/LocalStorage/File.cs index aff476cc..98d7e82e 100644 --- a/csharp/Storage/LocalStorage/File.cs +++ b/csharp/Storage/LocalStorage/File.cs @@ -1,28 +1,28 @@ namespace Storage.Local { - /// - /// - /// Represents the file. - /// - /// - /// + /// + /// + /// Represents the file. + /// + /// + /// public class File { - /// - /// - /// Gets or sets the path value. - /// - /// - /// + /// + /// + /// Gets or sets the path value. + /// + /// + /// public string Path { get; set; } - /// - /// - /// Gets or sets the content value. - /// - /// - /// + /// + /// + /// Gets or sets the content value. + /// + /// + /// public string Content { get; set; } } } diff --git a/csharp/Storage/LocalStorage/FileStorage.cs b/csharp/Storage/LocalStorage/FileStorage.cs index 0758a91d..484844f4 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -18,12 +18,12 @@ namespace Storage.Local { - /// - /// - /// Represents the file storage. - /// - /// - /// + /// + /// + /// Represents the file storage. + /// + /// + /// public class FileStorage { private readonly TLinkAddress _unicodeSequenceMarker; @@ -36,20 +36,21 @@ public class FileStorage private readonly TLinkAddress _unicodeSymbolMarker; private readonly TLinkAddress _setMarker; private readonly TLinkAddress _fileMarker; + private readonly TLinkAddress _linksToInviteToTheOrganizationMarker; private readonly TLinkAddress Any; private TLinkAddress GetOrCreateNextMapping(TLinkAddress currentMappingIndex) => Links.Exists(currentMappingIndex) ? currentMappingIndex : Links.CreateAndUpdate(_meaningRoot, Links.Constants.Itself); private TLinkAddress GetOrCreateMeaningRoot(TLinkAddress meaningRootIndex) => Links.Exists(meaningRootIndex) ? meaningRootIndex : Links.CreatePoint(); - /// - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// A db filename. - /// - /// + /// + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// A db filename. + /// + /// public FileStorage(string DBFilename) { var linksConstants = new LinksConstants(enableExternalReferencesSupport: true); @@ -64,6 +65,7 @@ public FileStorage(string DBFilename) _unicodeSequenceMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); _setMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); _fileMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _linksToInviteToTheOrganizationMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); _addressToNumberConverter = new AddressToRawNumberConverter(); _numberToAddressConverter = new RawNumberToAddressConverter(); var balancedVariantConverter = new BalancedVariantConverter(Links); @@ -76,56 +78,69 @@ public FileStorage(string DBFilename) _unicodeSequenceToStringConverter = new CachingConverterDecorator(new UnicodeSequenceToStringConverter(Links, unicodeSequenceCriterionMatcher, sequenceWalker, unicodeSymbolToCharConverter)); } - /// - /// - /// Converts the str. - /// - /// - /// - /// - /// The str. - /// - /// - /// - /// The link address - /// - /// + public void AddLinkToIvite(string linkToInvite) => Links.GetOrCreate(_linksToInviteToTheOrganizationMarker, _stringToUnicodeSequenceConverter.Convert(linkToInvite)); + + public List GetLinksToInvite() + { + List links = new(); + var list = Links.All(new Link(index: Any, source: _linksToInviteToTheOrganizationMarker, target: Any)); + foreach (var link in list) + { + links.Add(Convert(Links.GetTarget(link))); + } + return links; + } + + /// + /// + /// Converts the str. + /// + /// + /// + /// + /// The str. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress Convert(string str) => _stringToUnicodeSequenceConverter.Convert(str); - /// - /// - /// Converts the address. - /// - /// - /// - /// - /// The address. - /// - /// - /// - /// The string - /// - /// + /// + /// + /// Converts the address. + /// + /// + /// + /// + /// The address. + /// + /// + /// + /// The string + /// + /// public string Convert(TLinkAddress address) => _unicodeSequenceToStringConverter.Convert(address); - /// - /// - /// Gets the file content using the specified address. - /// - /// - /// - /// - /// The address. - /// - /// - /// - /// Link is not a file. - /// - /// - /// - /// The string - /// - /// + /// + /// + /// Gets the file content using the specified address. + /// + /// + /// + /// + /// The address. + /// + /// + /// + /// Link is not a file. + /// + /// + /// + /// The string + /// + /// public string GetFileContent(TLinkAddress address) { var link = Links.GetLink(address); @@ -136,28 +151,28 @@ public string GetFileContent(TLinkAddress address) throw new InvalidOperationException("Link is not a file."); } - /// - /// - /// Deletes the link. - /// - /// - /// - /// - /// The link. - /// - /// + /// + /// + /// Deletes the link. + /// + /// + /// + /// + /// The link. + /// + /// public void Delete(TLinkAddress link) => Links.Delete(link); - /// - /// - /// Gets the all files. - /// - /// - /// - /// - /// The files. - /// - /// + /// + /// + /// Gets the all files. + /// + /// + /// + /// + /// The files. + /// + /// public List GetAllFiles() { List files = new() { }; @@ -168,16 +183,16 @@ public List GetAllFiles() return files; } - /// - /// - /// Alls the links to string. - /// - /// - /// - /// - /// The string - /// - /// + /// + /// + /// Alls the links to string. + /// + /// + /// + /// + /// The string + /// + /// public string AllLinksToString() { StringBuilder builder = new(); @@ -190,76 +205,76 @@ public string AllLinksToString() return builder.ToString(); } - /// - /// - /// Adds the file using the specified content. - /// - /// - /// - /// - /// The content. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Adds the file using the specified content. + /// + /// + /// + /// + /// The content. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress AddFile(string content) => Links.GetOrCreate(_fileMarker, _stringToUnicodeSequenceConverter.Convert(content)); - /// - /// - /// Creates the file set using the specified file set name. - /// - /// - /// - /// - /// The file set name. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Creates the file set using the specified file set name. + /// + /// + /// + /// + /// The file set name. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress CreateFileSet(string fileSetName) => Links.GetOrCreate(_setMarker, Convert(fileSetName)); - /// - /// - /// Adds the file to set using the specified set. - /// - /// - /// - /// - /// The set. - /// - /// - /// - /// The file. - /// - /// - /// - /// The path. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Adds the file to set using the specified set. + /// + /// + /// + /// + /// The set. + /// + /// + /// + /// The file. + /// + /// + /// + /// The path. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress AddFileToSet(TLinkAddress set, TLinkAddress file, string path) => Links.GetOrCreate(set, Links.GetOrCreate(Convert(path), file)); - /// - /// - /// Gets the file set using the specified file set name. - /// - /// - /// - /// - /// The file set name. - /// - /// - /// - /// The link address - /// - /// + /// + /// + /// Gets the file set using the specified file set name. + /// + /// + /// + /// + /// The file set name. + /// + /// + /// + /// The link address + /// + /// public TLinkAddress GetFileSet(string fileSetName) => Links.SearchOrDefault(_setMarker, Convert(fileSetName)); private IList> GetFilesLinksFromSet(string set) { @@ -268,20 +283,20 @@ private IList> GetFilesLinksFromSet(string set) return list; } - /// - /// - /// Gets the files from set using the specified set. - /// - /// - /// - /// - /// The set. - /// - /// - /// - /// The files. - /// - /// + /// + /// + /// Gets the files from set using the specified set. + /// + /// + /// + /// + /// The set. + /// + /// + /// + /// The files. + /// + /// public List GetFilesFromSet(string set) { List files = new(); From 20634ccec7570fcd3a095b6246f9217671a7d2b4 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Wed, 5 Jan 2022 17:22:58 +0300 Subject: [PATCH 04/11] Delete DiscordBot directory --- DiscordBot/DiscordBot.csproj | 14 -------- DiscordBot/DiscrodBot.cs | 63 ------------------------------------ 2 files changed, 77 deletions(-) delete mode 100644 DiscordBot/DiscordBot.csproj delete mode 100644 DiscordBot/DiscrodBot.cs diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj deleted file mode 100644 index c5f4dd14..00000000 --- a/DiscordBot/DiscordBot.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net5.0 - - - - - - - - - - diff --git a/DiscordBot/DiscrodBot.cs b/DiscordBot/DiscrodBot.cs deleted file mode 100644 index 6f24c9fa..00000000 --- a/DiscordBot/DiscrodBot.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Discord; -using Discord.WebSocket; -using System; -using System.Threading.Tasks; - -namespace LinksPlatformDiscordBot -{ - public class BotStartup - { - private Storage.Local.FileStorage LinksStorage { get; set; } - - private string Token { get; set; } - - private DiscordSocketClient Client { get; set; } - - public BotStartup(string token, Storage.Local.FileStorage storage) - { - LinksStorage = storage; - Client = new DiscordSocketClient(); - Token = token; - } - public async Task StartupAsync() - { - Client.Log += Log; - Client.MessageReceived += MessageReceived; - await Client.LoginAsync(TokenType.Bot, Token); - await Client.StartAsync(); - - await Task.Delay(-1); - } - private async Task MessageReceived(SocketMessage message) - { - if (message.Content.Contains("https://github.com")) - { - if (message.Channel.Name == "main") - await message.Channel.SendMessageAsync("@konard look at this dude"); - } - if (message.Content.Contains("accept")) - { - if (message.Author.Username == "FirstAfterGod") - { - await message.Channel.SendMessageAsync("accepted."); - string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; - LinksStorage.AddLinkToIvite(link); - foreach (var a in LinksStorage.GetLinksToInvite()) - { - Console.WriteLine(a); - } - } - } - } - public void CreateInvite(string link) - { - - } - - private Task Log(LogMessage msg) - { - Console.WriteLine(msg.ToString()); - return Task.CompletedTask; - } - } -} \ No newline at end of file From 11fe1ad29f48c854b6161a8a267a9a582c4499b6 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Thu, 6 Jan 2022 15:48:37 +0300 Subject: [PATCH 05/11] Add invite to org --- csharp/Platform.Bot/Program.cs | 4 ++ .../Trackers/InviteToOrgTracker.cs | 43 +++++++++++++++++++ csharp/Storage/LocalStorage/FileStorage.cs | 4 ++ csharp/Storage/RemoteStorage/GitHubStorage.cs | 7 ++- 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs diff --git a/csharp/Platform.Bot/Program.cs b/csharp/Platform.Bot/Program.cs index d79705a8..a2b1fca5 100644 --- a/csharp/Platform.Bot/Program.cs +++ b/csharp/Platform.Bot/Program.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using Platform.Bot.Trackers; using Platform.Bot.Triggers; +using System.Threading.Tasks; namespace Platform.Bot { @@ -29,12 +30,15 @@ private static void Main(string[] args) var databaseFileName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Database file name", args); var fileSetName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "File set name ", args); var discordToken = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Token for discord bot", args); + var OrgName = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Name of the organization",args); var dbContext = new FileStorage(databaseFileName); Console.WriteLine($"Bot has been started. {Environment.NewLine}Press CTRL+C to close"); new LinksPlatformDiscordBot.BotStartup(discordToken, dbContext).StartupAsync(); try { var api = new GitHubStorage(username, token, appName); + Task.Run(() => new InviteToOrgTracker(OrgName, 1000, dbContext, api).Start(cancellation.Token)); + new IssueTracker( new List> { new HelloWorldTrigger(api, dbContext, fileSetName), diff --git a/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs b/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs new file mode 100644 index 00000000..5d6bca8c --- /dev/null +++ b/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs @@ -0,0 +1,43 @@ +using Storage.Local; +using Storage.Remote.GitHub; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Platform.Bot.Trackers +{ + public class InviteToOrgTracker + { + private string OrgName {get;set;} + + private int MinimumInteractionInterval = 1000; + + private FileStorage Storage { get; set; } + + GitHubStorage GitHubStorage { get; set; } + + public InviteToOrgTracker(string orgName,int minimumInteractionInterval,FileStorage storage, GitHubStorage gitHubStorage) + { + OrgName = orgName; + MinimumInteractionInterval = minimumInteractionInterval; + Storage = storage; + GitHubStorage = gitHubStorage; + } + + public void Start(CancellationToken cancellationToken) + { + while (!cancellationToken.IsCancellationRequested) + { + foreach (var link in Storage.GetLinksToInvite()) + { + Console.WriteLine(link); + GitHubStorage.InviteToOrg(OrgName, link.Replace("https://github.com/", "")); + } + Thread.Sleep(MinimumInteractionInterval); + } + } + } +} diff --git a/csharp/Storage/LocalStorage/FileStorage.cs b/csharp/Storage/LocalStorage/FileStorage.cs index 484844f4..31137e1d 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -88,6 +88,10 @@ public List GetLinksToInvite() { links.Add(Convert(Links.GetTarget(link))); } + foreach(var link in list) + { + Links.Delete(link); + } return links; } diff --git a/csharp/Storage/RemoteStorage/GitHubStorage.cs b/csharp/Storage/RemoteStorage/GitHubStorage.cs index 3d38524a..ce6f54d4 100644 --- a/csharp/Storage/RemoteStorage/GitHubStorage.cs +++ b/csharp/Storage/RemoteStorage/GitHubStorage.cs @@ -121,7 +121,12 @@ public IReadOnlyList GetCommits(string owner, string reposiroty) public IReadOnlyList GetCommits(string owner, string reposiroty, DateTime date) { - return Client.Repository.Commit.GetAll(owner, reposiroty, new CommitRequest() { Since = date }).Result; + return Client.Repository.Commit.GetAll(owner, reposiroty, new CommitRequest() { Since = date }).Result; + } + + public void InviteToOrg(string org, string user) + { + Client.Organization.Member.AddOrUpdateOrganizationMembership(org, user, new OrganizationMembershipUpdate { Role = MembershipRole.Member}); } /// From 88b1418ee97e630b277d1c8f930d0939f1f65ed7 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Thu, 6 Jan 2022 17:06:19 +0300 Subject: [PATCH 06/11] bug fix --- Bot.sln | 4 +-- csharp/DiscordBot/DiscordBot.csproj | 2 +- csharp/DiscordBot/DiscrodBot.cs | 27 ++++++++-------- csharp/FileManager/Context.cs | 36 +++++++++++----------- csharp/FileManager/FileManager.csproj | 2 +- csharp/FileManager/Program.cs | 24 +++++++-------- csharp/Platform.Bot/Platform.Bot.csproj | 2 +- csharp/Storage/LocalStorage/FileStorage.cs | 6 ++++ csharp/Storage/Storage.csproj | 2 +- 9 files changed, 57 insertions(+), 48 deletions(-) diff --git a/Bot.sln b/Bot.sln index 5213f46b..b8f05e2c 100644 --- a/Bot.sln +++ b/Bot.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31919.166 @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interfaces", "csharp\Interf EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Storage", "csharp\Storage\Storage.csproj", "{E81C2E82-9F15-478C-8388-E9BD53686E36}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBot", "DiscordBot\DiscordBot.csproj", "{3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBot", "csharp\DiscordBot\DiscordBot.csproj", "{3A87CAD8-A2F8-462A-B1F9-2AB6883B815C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/csharp/DiscordBot/DiscordBot.csproj b/csharp/DiscordBot/DiscordBot.csproj index c5f4dd14..f2c7fdb7 100644 --- a/csharp/DiscordBot/DiscordBot.csproj +++ b/csharp/DiscordBot/DiscordBot.csproj @@ -9,6 +9,6 @@ - + diff --git a/csharp/DiscordBot/DiscrodBot.cs b/csharp/DiscordBot/DiscrodBot.cs index 6f24c9fa..62aaee60 100644 --- a/csharp/DiscordBot/DiscrodBot.cs +++ b/csharp/DiscordBot/DiscrodBot.cs @@ -30,21 +30,24 @@ public async Task StartupAsync() } private async Task MessageReceived(SocketMessage message) { - if (message.Content.Contains("https://github.com")) + if (!message.Author.IsBot) { - if (message.Channel.Name == "main") - await message.Channel.SendMessageAsync("@konard look at this dude"); - } - if (message.Content.Contains("accept")) - { - if (message.Author.Username == "FirstAfterGod") + if (message.Content.Contains("https://github.com")) + { + if (message.Channel.Name == "main") + await message.Channel.SendMessageAsync("@konard would we accept " + "@" + message.Author.Username + " as our new team member?"); + } + if (message.Content.Contains("accept")) { - await message.Channel.SendMessageAsync("accepted."); - string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; - LinksStorage.AddLinkToIvite(link); - foreach (var a in LinksStorage.GetLinksToInvite()) + if (message.Author.Username == "Konstantin Dyachenko" || message.Author.Username == "konard" || message.Author.Username == "FirstAfterGod") { - Console.WriteLine(a); + string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; + LinksStorage.AddLinkToIvite(link); + await message.Channel.SendMessageAsync("@" + message.Author.Username + " please accept invitation to our organization either by going to http://github.com/linksplatform or via email that was sent to you from GitHub."); + foreach (var a in LinksStorage.GetLinksToInvite()) + { + Console.WriteLine(a); + } } } } diff --git a/csharp/FileManager/Context.cs b/csharp/FileManager/Context.cs index 5fe14d41..b2a0106e 100644 --- a/csharp/FileManager/Context.cs +++ b/csharp/FileManager/Context.cs @@ -2,28 +2,28 @@ namespace FileManager { - /// - /// - /// Represents the context. - /// - /// - /// + /// + /// + /// Represents the context. + /// + /// + /// public class Context { - /// - /// - /// Gets or sets the args value. - /// - /// - /// + /// + /// + /// Gets or sets the args value. + /// + /// + /// public string[] Args { get; set; } - /// - /// - /// Gets or sets the file storage value. - /// - /// - /// + /// + /// + /// Gets or sets the file storage value. + /// + /// + /// public FileStorage FileStorage { get; set; } } } diff --git a/csharp/FileManager/FileManager.csproj b/csharp/FileManager/FileManager.csproj index e55392a3..c7a16e10 100644 --- a/csharp/FileManager/FileManager.csproj +++ b/csharp/FileManager/FileManager.csproj @@ -6,7 +6,7 @@ - + diff --git a/csharp/FileManager/Program.cs b/csharp/FileManager/Program.cs index 519dcbc0..504a0daf 100644 --- a/csharp/FileManager/Program.cs +++ b/csharp/FileManager/Program.cs @@ -7,20 +7,20 @@ namespace FileManager { - /// - /// - /// Represents the program. - /// - /// - /// + /// + /// + /// Represents the program. + /// + /// + /// internal class Program { - /// - /// - /// The get files by file set name trigger. - /// - /// - /// + /// + /// + /// The get files by file set name trigger. + /// + /// + /// public static List> Handlers = new() { new CreateTrigger(), diff --git a/csharp/Platform.Bot/Platform.Bot.csproj b/csharp/Platform.Bot/Platform.Bot.csproj index 7ab7131e..ed84108a 100644 --- a/csharp/Platform.Bot/Platform.Bot.csproj +++ b/csharp/Platform.Bot/Platform.Bot.csproj @@ -13,7 +13,7 @@ - + diff --git a/csharp/Storage/LocalStorage/FileStorage.cs b/csharp/Storage/LocalStorage/FileStorage.cs index 31137e1d..17270073 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -83,8 +83,14 @@ public FileStorage(string DBFilename) public List GetLinksToInvite() { List links = new(); + Console.WriteLine("Before: " + Links.Count()); var list = Links.All(new Link(index: Any, source: _linksToInviteToTheOrganizationMarker, target: Any)); foreach (var link in list) + { + Links.Delete(link); + } + Console.WriteLine("After: " + Links.Count()); + foreach (var link in list) { links.Add(Convert(Links.GetTarget(link))); } diff --git a/csharp/Storage/Storage.csproj b/csharp/Storage/Storage.csproj index 932cd3de..95f00bc9 100644 --- a/csharp/Storage/Storage.csproj +++ b/csharp/Storage/Storage.csproj @@ -6,7 +6,7 @@ - + From 2395b8a65271347f58e8c8318bccf9db029ea337 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Thu, 6 Jan 2022 17:43:50 +0300 Subject: [PATCH 07/11] fix another bugs --- csharp/Storage/LocalStorage/FileStorage.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/csharp/Storage/LocalStorage/FileStorage.cs b/csharp/Storage/LocalStorage/FileStorage.cs index 17270073..183d57af 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -85,16 +85,12 @@ public List GetLinksToInvite() List links = new(); Console.WriteLine("Before: " + Links.Count()); var list = Links.All(new Link(index: Any, source: _linksToInviteToTheOrganizationMarker, target: Any)); - foreach (var link in list) - { - Links.Delete(link); - } Console.WriteLine("After: " + Links.Count()); foreach (var link in list) { links.Add(Convert(Links.GetTarget(link))); } - foreach(var link in list) + foreach (var link in list) { Links.Delete(link); } From 7a9d4916a83b77b943d3de62053a1bf7a0ba39f2 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Thu, 6 Jan 2022 18:31:44 +0300 Subject: [PATCH 08/11] fix versions --- csharp/FileManager/FileManager.csproj | 2 +- csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs | 1 - csharp/Platform.Bot/Trackers/IssueTracker.cs | 1 + csharp/Storage/LocalStorage/FileStorage.cs | 2 -- csharp/Storage/Storage.csproj | 2 +- 5 files changed, 3 insertions(+), 5 deletions(-) diff --git a/csharp/FileManager/FileManager.csproj b/csharp/FileManager/FileManager.csproj index c7a16e10..e55392a3 100644 --- a/csharp/FileManager/FileManager.csproj +++ b/csharp/FileManager/FileManager.csproj @@ -6,7 +6,7 @@ - + diff --git a/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs b/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs index 5d6bca8c..6ee391c5 100644 --- a/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs +++ b/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs @@ -33,7 +33,6 @@ public void Start(CancellationToken cancellationToken) { foreach (var link in Storage.GetLinksToInvite()) { - Console.WriteLine(link); GitHubStorage.InviteToOrg(OrgName, link.Replace("https://github.com/", "")); } Thread.Sleep(MinimumInteractionInterval); diff --git a/csharp/Platform.Bot/Trackers/IssueTracker.cs b/csharp/Platform.Bot/Trackers/IssueTracker.cs index f718716e..69e6f7b0 100644 --- a/csharp/Platform.Bot/Trackers/IssueTracker.cs +++ b/csharp/Platform.Bot/Trackers/IssueTracker.cs @@ -73,6 +73,7 @@ public IssueTracker(List> triggers, GitHubStorage gitHubApi) /// public void Start(CancellationToken cancellationToken) { + Console.WriteLine("issue Trecker has been started"); while (!cancellationToken.IsCancellationRequested) { foreach (var trigger in Triggers) diff --git a/csharp/Storage/LocalStorage/FileStorage.cs b/csharp/Storage/LocalStorage/FileStorage.cs index 183d57af..98afa0ac 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -83,9 +83,7 @@ public FileStorage(string DBFilename) public List GetLinksToInvite() { List links = new(); - Console.WriteLine("Before: " + Links.Count()); var list = Links.All(new Link(index: Any, source: _linksToInviteToTheOrganizationMarker, target: Any)); - Console.WriteLine("After: " + Links.Count()); foreach (var link in list) { links.Add(Convert(Links.GetTarget(link))); diff --git a/csharp/Storage/Storage.csproj b/csharp/Storage/Storage.csproj index 95f00bc9..932cd3de 100644 --- a/csharp/Storage/Storage.csproj +++ b/csharp/Storage/Storage.csproj @@ -6,7 +6,7 @@ - + From 7f57b2f6464f666d58a6f3f282a4bff54614a7f0 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Sun, 9 Jan 2022 14:14:20 +0300 Subject: [PATCH 09/11] Added try catch in issueTracker --- csharp/Platform.Bot/Trackers/IssueTracker.cs | 13 ++++++++++--- csharp/Storage/RemoteStorage/GitHubStorage.cs | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/csharp/Platform.Bot/Trackers/IssueTracker.cs b/csharp/Platform.Bot/Trackers/IssueTracker.cs index 69e6f7b0..98f40b02 100644 --- a/csharp/Platform.Bot/Trackers/IssueTracker.cs +++ b/csharp/Platform.Bot/Trackers/IssueTracker.cs @@ -78,13 +78,20 @@ public void Start(CancellationToken cancellationToken) { foreach (var trigger in Triggers) { - foreach (var issue in GitHubApi.GetIssues()) + try { - if (trigger.Condition(issue)) + foreach (var issue in GitHubApi.GetIssues()) { - trigger.Action(issue); + if (trigger.Condition(issue)) + { + trigger.Action(issue); + } } } + catch (Exception ex) + { + Console.WriteLine(ex); + } } Thread.Sleep(MinimumInteractionInterval); } diff --git a/csharp/Storage/RemoteStorage/GitHubStorage.cs b/csharp/Storage/RemoteStorage/GitHubStorage.cs index ce6f54d4..f05418e0 100644 --- a/csharp/Storage/RemoteStorage/GitHubStorage.cs +++ b/csharp/Storage/RemoteStorage/GitHubStorage.cs @@ -38,6 +38,7 @@ public class GitHubStorage /// /// public TimeSpan MinimumInteractionInterval { get; } + private DateTimeOffset lastIssue = DateTimeOffset.Now.Subtract(TimeSpan.FromDays(14)); /// From 77814644863a14468958dae0bd1a5fccebc6f4cd Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Fri, 14 Jan 2022 21:50:44 +0300 Subject: [PATCH 10/11] added ping when calling commands --- csharp/DiscordBot/DiscrodBot.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/csharp/DiscordBot/DiscrodBot.cs b/csharp/DiscordBot/DiscrodBot.cs index 62aaee60..10990968 100644 --- a/csharp/DiscordBot/DiscrodBot.cs +++ b/csharp/DiscordBot/DiscrodBot.cs @@ -35,7 +35,8 @@ private async Task MessageReceived(SocketMessage message) if (message.Content.Contains("https://github.com")) { if (message.Channel.Name == "main") - await message.Channel.SendMessageAsync("@konard would we accept " + "@" + message.Author.Username + " as our new team member?"); + + await message.Channel.SendMessageAsync($"<@214371962187808778> would we accept " + "<@" + message.Author.Id + "> as our new team member?"); } if (message.Content.Contains("accept")) { @@ -43,7 +44,7 @@ private async Task MessageReceived(SocketMessage message) { string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; LinksStorage.AddLinkToIvite(link); - await message.Channel.SendMessageAsync("@" + message.Author.Username + " please accept invitation to our organization either by going to http://github.com/linksplatform or via email that was sent to you from GitHub."); + await message.Channel.SendMessageAsync("<@" + message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Author.Id + "> please accept invitation to our organization either by going to http://github.com/linksplatform or via email that was sent to you from GitHub."); foreach (var a in LinksStorage.GetLinksToInvite()) { Console.WriteLine(a); From e16d1ef0ee9e5cddc098f258396cb6fa204907f5 Mon Sep 17 00:00:00 2001 From: Alexander <65162943+FirstAfterGod2501@users.noreply.github.com> Date: Tue, 8 Mar 2022 19:57:43 +0300 Subject: [PATCH 11/11] removed issue tracker and addded invite to org tracker --- csharp/DiscordBot/DiscrodBot.cs | 2 +- csharp/Platform.Bot/Platform.Bot.csproj | 3 +++ csharp/Platform.Bot/Program.cs | 10 +--------- csharp/Storage/LocalStorage/FileStorage.cs | 5 +++++ csharp/db.links | Bin 35904 -> 0 bytes 5 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 csharp/db.links diff --git a/csharp/DiscordBot/DiscrodBot.cs b/csharp/DiscordBot/DiscrodBot.cs index 10990968..59fa5396 100644 --- a/csharp/DiscordBot/DiscrodBot.cs +++ b/csharp/DiscordBot/DiscrodBot.cs @@ -42,7 +42,7 @@ private async Task MessageReceived(SocketMessage message) { if (message.Author.Username == "Konstantin Dyachenko" || message.Author.Username == "konard" || message.Author.Username == "FirstAfterGod") { - string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; + string link = message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Content; LinksStorage.AddLinkToIvite(link); await message.Channel.SendMessageAsync("<@" + message.Channel.GetMessageAsync(message.Reference.MessageId.Value).Result.Author.Id + "> please accept invitation to our organization either by going to http://github.com/linksplatform or via email that was sent to you from GitHub."); foreach (var a in LinksStorage.GetLinksToInvite()) diff --git a/csharp/Platform.Bot/Platform.Bot.csproj b/csharp/Platform.Bot/Platform.Bot.csproj index ed84108a..c4d0eb2b 100644 --- a/csharp/Platform.Bot/Platform.Bot.csproj +++ b/csharp/Platform.Bot/Platform.Bot.csproj @@ -3,9 +3,12 @@ Exe net5.0 + Linux + ..\.. + diff --git a/csharp/Platform.Bot/Program.cs b/csharp/Platform.Bot/Program.cs index a2b1fca5..b3b7aec6 100644 --- a/csharp/Platform.Bot/Program.cs +++ b/csharp/Platform.Bot/Program.cs @@ -39,15 +39,7 @@ private static void Main(string[] args) var api = new GitHubStorage(username, token, appName); Task.Run(() => new InviteToOrgTracker(OrgName, 1000, dbContext, api).Start(cancellation.Token)); - new IssueTracker( - new List> { - new HelloWorldTrigger(api, dbContext, fileSetName), - new OrganizationLastMonthActivityTrigger(api), - new LastCommitActivityTrigger(api), - new ProtectMainBranchTrigger(api), - }, - api - ).Start(cancellation.Token); + new InviteToOrgTracker("LinksPlatfrom", 1200, dbContext, api).Start(cancellation.Token); new PullRequestTracker(new List> { new MergeDependabotBumpsTrigger(api) }, api).Start(cancellation.Token); } catch (Exception ex) diff --git a/csharp/Storage/LocalStorage/FileStorage.cs b/csharp/Storage/LocalStorage/FileStorage.cs index 98afa0ac..0cb66908 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -95,6 +95,11 @@ public List GetLinksToInvite() return links; } + public IList> GetLink(TLinkAddress adr) + { + return Links.All(); + } + /// /// /// Converts the str. diff --git a/csharp/db.links b/csharp/db.links deleted file mode 100644 index d4f914a946cd19e1ffe024bc06348e9c990ae4e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35904 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 Bj)(vN