diff --git a/Bot.sln b/Bot.sln index 53dd800f..b8f05e2c 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", "csharp\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..f2c7fdb7 --- /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..59fa5396 --- /dev/null +++ b/csharp/DiscordBot/DiscrodBot.cs @@ -0,0 +1,67 @@ +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.Author.IsBot) + { + if (message.Content.Contains("https://github.com")) + { + if (message.Channel.Name == "main") + + await message.Channel.SendMessageAsync($"<@214371962187808778> would we accept " + "<@" + message.Author.Id + "> as our new team member?"); + } + if (message.Content.Contains("accept")) + { + 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; + 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()) + { + 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/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/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 7dc37e21..3b106243 100644 --- a/csharp/Platform.Bot/Platform.Bot.csproj +++ b/csharp/Platform.Bot/Platform.Bot.csproj @@ -5,14 +5,15 @@ net6 enable - + + diff --git a/csharp/Platform.Bot/Program.cs b/csharp/Platform.Bot/Program.cs index 5e40be80..26921aa2 100644 --- a/csharp/Platform.Bot/Program.cs +++ b/csharp/Platform.Bot/Program.cs @@ -10,6 +10,7 @@ using System.Threading; using Platform.Bot.Trackers; using Platform.Bot.Triggers; +using System.Threading.Tasks; namespace Platform.Bot { @@ -29,28 +30,21 @@ private static void Main(string[] args) var token = ConsoleHelpers.GetOrReadArgument(argumentIndex++, "Token", 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 minimumInteractionIntervalStringInputInSeconds = ConsoleHelpers.GetOrReadArgument(argumentIndex, "Minimum interaction interval in seconds", args); - var minimumInteractionInterval = TimeSpan.FromSeconds(Int32.Parse(minimumInteractionIntervalStringInputInSeconds)); + 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 { - while (true) - { - var api = new GitHubStorage(username, token, appName); - var issueTracker = new IssueTracker(api, - new HelloWorldTrigger(api, dbContext, fileSetName), - new OrganizationLastMonthActivityTrigger(api), - new LastCommitActivityTrigger(api), - new ProtectMainBranchTrigger(api)); - var pullRequenstTracker = new PullRequestTracker(api, new MergeDependabotBumpsTrigger(api)); - var timestampTracker = new DateTimeTracker(api, new CreateAndSaveOrganizationRepositoriesMigrationTrigger(api, dbContext, Path.Combine(Directory.GetCurrentDirectory(), "/github-migrations"))); - issueTracker.Start(cancellation.Token); - pullRequenstTracker.Start(cancellation.Token); - timestampTracker.Start(cancellation.Token); - Thread.Sleep(minimumInteractionInterval); - } + var api = new GitHubStorage(username, token, appName); + Task.Run(() => new InviteToOrgTracker(OrgName, 1000, dbContext, 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/Platform.Bot/Trackers/InviteToOrgTracker.cs b/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs new file mode 100644 index 00000000..6ee391c5 --- /dev/null +++ b/csharp/Platform.Bot/Trackers/InviteToOrgTracker.cs @@ -0,0 +1,42 @@ +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()) + { + 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 a2a467c5..e65b42cb 100644 --- a/csharp/Platform.Bot/Trackers/IssueTracker.cs +++ b/csharp/Platform.Bot/Trackers/IssueTracker.cs @@ -62,17 +62,26 @@ public IssueTracker(GitHubStorage gitHubApi, params ITrigger[] triggers) /// public void Start(CancellationToken cancellationToken) { - foreach (var trigger in _triggers) + Console.WriteLine("issue Trecker has been started"); + while (!cancellationToken.IsCancellationRequested) + { foreach (var issue in _storage.GetIssues()) { - if (cancellationToken.IsCancellationRequested) + try { - return; + foreach (var issue in GitHubApi.GetIssues()) + { + if (trigger.Condition(issue)) + { + trigger.Action(issue); + } + } + } - if (trigger.Condition(issue)) + catch (Exception ex) { - trigger.Action(issue); + Console.WriteLine(ex); } } } 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 ebf7f669..8817ec6a 100644 --- a/csharp/Storage/LocalStorage/FileStorage.cs +++ b/csharp/Storage/LocalStorage/FileStorage.cs @@ -1,336 +1,661 @@ -using Platform.Collections.Stacks; -using Platform.Converters; -using Platform.Data; -using Platform.Data.Doublets; -using Platform.Data.Doublets.CriterionMatchers; -using Platform.Data.Doublets.Memory; -using Platform.Data.Doublets.Memory.United.Generic; -using Platform.Data.Doublets.Sequences.Converters; -using Platform.Data.Doublets.Sequences.Walkers; -using Platform.Data.Doublets.Unicode; -using Platform.Data.Numbers.Raw; -using Platform.Memory; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Text; -using Platform.Data.Doublets.Numbers.Raw; -using Platform.Disposables; -using TLinkAddress = System.UInt64; - -namespace Storage.Local -{ - /// - /// - /// Represents the file storage. - /// - /// - /// - public class FileStorage : DisposableBase - { - private readonly TLinkAddress _unicodeSequenceMarker; - private readonly TLinkAddress _meaningRoot; - private readonly AddressToRawNumberConverter _addressToNumberConverter; - private readonly RawNumberToAddressConverter _numberToAddressConverter; - private readonly IConverter _stringToUnicodeSequenceConverter; - private readonly IConverter _unicodeSequenceToStringConverter; - private readonly IConverter, TLinkAddress> _listToSequenceConverter; - private readonly IConverter _bigIntederToRawNumberConverter; - private readonly IConverter _rawNumberToBigIntegerConverter; - private readonly TLinkAddress _negativeNumberIndex; - private readonly UnitedMemoryLinks _disposableLinks; - private readonly SynchronizedLinks _synchronizedLinks; - private readonly TLinkAddress _unicodeSymbolMarker; - private readonly TLinkAddress _setMarker; - private readonly TLinkAddress _fileMarker; - private readonly TLinkAddress _gitHubLastMigrationTimestampMarker; - private readonly TLinkAddress Any; - private TLinkAddress GetOrCreateNextMapping(TLinkAddress currentMappingIndex) => _synchronizedLinks.Exists(currentMappingIndex) ? currentMappingIndex : _synchronizedLinks.CreateAndUpdate(_meaningRoot, _synchronizedLinks.Constants.Itself); - private TLinkAddress GetOrCreateMeaningRoot(TLinkAddress meaningRootIndex) => _synchronizedLinks.Exists(meaningRootIndex) ? meaningRootIndex : _synchronizedLinks.CreatePoint(); - - /// - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// A db filename. - /// - /// - public FileStorage(string DBFilename) - { - var linksConstants = new LinksConstants(enableExternalReferencesSupport: true); - var dataMemory = new FileMappedResizableDirectMemory(DBFilename); - _disposableLinks = new UnitedMemoryLinks(dataMemory, UnitedMemoryLinks.DefaultLinksSizeStep, linksConstants, IndexTreeType.Default); - _synchronizedLinks = new SynchronizedLinks(_disposableLinks); - var link = _synchronizedLinks.Create(); - link = _synchronizedLinks.Update(link, newSource: link, newTarget: link); - ushort currentMappingLinkIndex = 1; - Any = _synchronizedLinks.Constants.Any; - _meaningRoot = GetOrCreateMeaningRoot(currentMappingLinkIndex++); - _unicodeSymbolMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); - _unicodeSequenceMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); - _negativeNumberIndex = GetOrCreateNextMapping(currentMappingLinkIndex++); - _setMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); - _fileMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); - _gitHubLastMigrationTimestampMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); - _addressToNumberConverter = new AddressToRawNumberConverter(); - _numberToAddressConverter = new RawNumberToAddressConverter(); - var balancedVariantConverter = new BalancedVariantConverter(_synchronizedLinks); - var unicodeSymbolCriterionMatcher = new TargetMatcher(_synchronizedLinks, _unicodeSymbolMarker); - var unicodeSequenceCriterionMatcher = new TargetMatcher(_synchronizedLinks, _unicodeSequenceMarker); - var charToUnicodeSymbolConverter = new CharToUnicodeSymbolConverter(_synchronizedLinks, _addressToNumberConverter, _unicodeSymbolMarker); - var unicodeSymbolToCharConverter = new UnicodeSymbolToCharConverter(_synchronizedLinks, _numberToAddressConverter, unicodeSymbolCriterionMatcher); - var sequenceWalker = new RightSequenceWalker(_synchronizedLinks, new DefaultStack(), unicodeSymbolCriterionMatcher.IsMatched); - _stringToUnicodeSequenceConverter = new CachingConverterDecorator(new StringToUnicodeSequenceConverter(_synchronizedLinks, charToUnicodeSymbolConverter, balancedVariantConverter, _unicodeSequenceMarker)); - _unicodeSequenceToStringConverter = new CachingConverterDecorator(new UnicodeSequenceToStringConverter(_synchronizedLinks, unicodeSequenceCriterionMatcher, sequenceWalker, unicodeSymbolToCharConverter)); - _listToSequenceConverter = new BalancedVariantConverter(_synchronizedLinks); - _bigIntederToRawNumberConverter = new BigIntegerToRawNumberSequenceConverter(_synchronizedLinks, _addressToNumberConverter, _listToSequenceConverter, _negativeNumberIndex); - _rawNumberToBigIntegerConverter = new RawNumberSequenceToBigIntegerConverter(_synchronizedLinks, _numberToAddressConverter, _negativeNumberIndex); - } - - /// - /// - /// Converts the str. - /// - /// - /// - /// - /// The str. - /// - /// - /// - /// The link address - /// - /// - public TLinkAddress CreateString(string str) => _stringToUnicodeSequenceConverter.Convert(str); - - /// - /// - /// Converts the address. - /// - /// - /// - /// - /// The address. - /// - /// - /// - /// The string - /// - /// - public string GetString(TLinkAddress address) => _unicodeSequenceToStringConverter.Convert(address); - - /// - /// - /// - /// - /// - public TLinkAddress CreateBigInteger(BigInteger bigInteger) => _bigIntederToRawNumberConverter.Convert(bigInteger); - - /// - /// - /// - /// - /// - public BigInteger GetBigInteger(TLinkAddress address) => _rawNumberToBigIntegerConverter.Convert(address); - - /// - /// - /// Gets the file content using the specified address. - /// - /// - /// - /// - /// The address. - /// - /// - /// - /// Link is not a file. - /// - /// - /// - /// The string - /// - /// - public string GetFileContent(TLinkAddress address) - { - var link = _synchronizedLinks.GetLink(address); - if (_synchronizedLinks.GetSource(link) == _fileMarker) - { - return GetString(_synchronizedLinks.GetTarget(link)); - } - throw new InvalidOperationException("Link is not a file."); - } - - /// - /// - /// Deletes the link. - /// - /// - /// - /// - /// The link. - /// - /// - public void Delete(TLinkAddress link) => _synchronizedLinks.Delete(link); - - /// - /// - /// Gets the all files. - /// - /// - /// - /// - /// The files. - /// - /// - public List GetAllFiles() - { - List files = new() { }; - foreach (var file in _synchronizedLinks.All(new Link(index: Any, source: _fileMarker, target: Any))) - { - files.Add(new File { Path = file.ToString(), Content = GetString(_synchronizedLinks.GetTarget(file)) }); - } - return files; - } - - /// - /// - /// Alls the links to string. - /// - /// - /// - /// - /// The string - /// - /// - public string AllLinksToString() - { - StringBuilder builder = new(); - var query = new Link(index: Any, source: Any, target: Any); - _synchronizedLinks.Each(link => - { - builder.AppendLine(_synchronizedLinks.Format(link)); - return _synchronizedLinks.Constants.Continue; - }, query); - return builder.ToString(); - } - - /// - /// - /// Adds the file using the specified content. - /// - /// - /// - /// - /// The content. - /// - /// - /// - /// The link address - /// - /// - public TLinkAddress AddFile(string content) => _synchronizedLinks.GetOrCreate(_fileMarker, _stringToUnicodeSequenceConverter.Convert(content)); - - /// - /// - /// Creates the file set using the specified file set name. - /// - /// - /// - /// - /// The file set name. - /// - /// - /// - /// The link address - /// - /// - public TLinkAddress CreateFileSet(string fileSetName) => _synchronizedLinks.GetOrCreate(_setMarker, CreateString(fileSetName)); - - /// - /// - /// 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) => _synchronizedLinks.GetOrCreate(set, _synchronizedLinks.GetOrCreate(CreateString(path), file)); - - /// - /// - /// Gets the file set using the specified file set name. - /// - /// - /// - /// - /// The file set name. - /// - /// - /// - /// The link address - /// - /// - public TLinkAddress GetFileSet(string fileSetName) => _synchronizedLinks.SearchOrDefault(_setMarker, CreateString(fileSetName)); - private IList?> GetFilesLinksFromSet(string set) - { - var fileSet = GetFileSet(set); - var list = _synchronizedLinks.All(new Link(index: Any, source: fileSet, target: Any)); - return list; - } - - /// - /// - /// Gets the files from set using the specified set. - /// - /// - /// - /// - /// The set. - /// - /// - /// - /// The files. - /// - /// - public List GetFilesFromSet(string set) - { - List files = new(); - foreach (var file in GetFilesLinksFromSet(set)) - { - var pathAndFile = _synchronizedLinks.GetTarget(file); - files.Add(new File() - { - Path = GetString(_synchronizedLinks.GetSource(pathAndFile)), - Content = GetFileContent(_synchronizedLinks.GetTarget(pathAndFile)) - }); - } - return files; - } - - // public void SetLastGithubMigrationTimeStamp() - - protected override void Dispose(bool manual, bool wasDisposed) - { - _disposableLinks.Dispose(); - } - } -} +using Platform.Collections.Stacks; +using Platform.Converters; +using Platform.Data; +using Platform.Data.Doublets; +using Platform.Data.Doublets.CriterionMatchers; +using Platform.Data.Doublets.Memory; +using Platform.Data.Doublets.Memory.United.Generic; +using Platform.Data.Doublets.Sequences.Converters; +using Platform.Data.Doublets.Sequences.Walkers; +using Platform.Data.Doublets.Unicode; +using Platform.Data.Numbers.Raw; +using Platform.Memory; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using TLinkAddress = System.UInt64; + +namespace Storage.Local +{ + /// + /// + /// Represents the file storage. + /// + /// + /// + public class FileStorage + { + private readonly TLinkAddress _unicodeSequenceMarker; + private readonly TLinkAddress _meaningRoot; + private readonly AddressToRawNumberConverter _addressToNumberConverter; + private readonly RawNumberToAddressConverter _numberToAddressConverter; + private readonly IConverter _stringToUnicodeSequenceConverter; + private readonly IConverter _unicodeSequenceToStringConverter; + private readonly UnitedMemoryLinks Links; + 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. + /// + /// + public FileStorage(string DBFilename) + { + var linksConstants = new LinksConstants(enableExternalReferencesSupport: true); + var dataMemory = new FileMappedResizableDirectMemory(DBFilename); + Links = new UnitedMemoryLinks(dataMemory, UnitedMemoryLinks.DefaultLinksSizeStep, linksConstants, IndexTreeType.Default); + var link = Links.Create(); + link = Links.Update(link, newSource: link, newTarget: link); + ushort currentMappingLinkIndex = 1; + Any = Links.Constants.Any; + _meaningRoot = GetOrCreateMeaningRoot(currentMappingLinkIndex++); + _unicodeSymbolMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _unicodeSequenceMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _setMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _fileMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _linksToInviteToTheOrganizationMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _addressToNumberConverter = new AddressToRawNumberConverter(); + _numberToAddressConverter = new RawNumberToAddressConverter(); + var balancedVariantConverter = new BalancedVariantConverter(Links); + var unicodeSymbolCriterionMatcher = new TargetMatcher(Links, _unicodeSymbolMarker); + var unicodeSequenceCriterionMatcher = new TargetMatcher(Links, _unicodeSequenceMarker); + var charToUnicodeSymbolConverter = new CharToUnicodeSymbolConverter(Links, _addressToNumberConverter, _unicodeSymbolMarker); + var unicodeSymbolToCharConverter = new UnicodeSymbolToCharConverter(Links, _numberToAddressConverter, unicodeSymbolCriterionMatcher); + var sequenceWalker = new RightSequenceWalker(Links, new DefaultStack(), unicodeSymbolCriterionMatcher.IsMatched); + _stringToUnicodeSequenceConverter = new CachingConverterDecorator(new StringToUnicodeSequenceConverter(Links, charToUnicodeSymbolConverter, balancedVariantConverter, _unicodeSequenceMarker)); + _unicodeSequenceToStringConverter = new CachingConverterDecorator(new UnicodeSequenceToStringConverter(Links, unicodeSequenceCriterionMatcher, sequenceWalker, unicodeSymbolToCharConverter)); + } + + 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))); + } + foreach (var link in list) + { + Links.Delete(link); + } + return links; + } + + public IList> GetLink(TLinkAddress adr) + { + return Links.All(); + } + + /// + /// + /// Converts the str. + /// + /// + /// + /// + /// The str. + /// + /// + /// + /// The link address + /// + /// + public TLinkAddress Convert(string str) => _stringToUnicodeSequenceConverter.Convert(str); + + /// + /// + /// 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 + /// + /// + public string GetFileContent(TLinkAddress address) + { + var link = Links.GetLink(address); + if (Links.GetSource(link) == _fileMarker) + { + return Convert(Links.GetTarget(link)); + } + throw new InvalidOperationException("Link is not a file."); + } + + /// + /// + /// Deletes the link. + /// + /// + /// + /// + /// The link. + /// + /// + public void Delete(TLinkAddress link) => Links.Delete(link); + + /// + /// + /// Gets the all files. + /// + /// + /// + /// + /// The files. + /// + /// + public List GetAllFiles() + { + List files = new() { }; + foreach (var file in Links.All(new Link(index: Any, source: _fileMarker, target: Any))) + { + files.Add(new File { Path = file.ToString(), Content = Convert(Links.GetTarget(file)) }); + } + return files; + } + + /// + /// + /// Alls the links to string. + /// + /// + /// + /// + /// The string + /// + /// + public string AllLinksToString() + { + StringBuilder builder = new(); + var query = new Link(index: Any, source: Any, target: Any); + Links.Each(link => + { + builder.AppendLine(Links.Format(link)); + return Links.Constants.Continue; + }, query); + return builder.ToString(); + } + + /// + /// + /// 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 + /// + /// + 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 + /// + /// + 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 + /// + /// + public TLinkAddress GetFileSet(string fileSetName) => Links.SearchOrDefault(_setMarker, Convert(fileSetName)); + private IList> GetFilesLinksFromSet(string set) + { + var fileSet = GetFileSet(set); + var list = Links.All(new Link(index: Any, source: fileSet, target: Any)); + return list; + } + + /// + /// + /// Gets the files from set using the specified set. + /// + /// + /// + /// + /// The set. + /// + /// + /// + /// The files. + /// + /// + public List GetFilesFromSet(string set) + { + List files = new(); + foreach (var file in GetFilesLinksFromSet(set)) + { + var pathAndFile = Links.GetTarget(file); + files.Add(new File() + { + Path = Convert(Links.GetSource(pathAndFile)), + Content = GetFileContent(Links.GetTarget(pathAndFile)) + }); + } + return files; + } + } +} +======= +using Platform.Collections.Stacks; +using Platform.Converters; +using Platform.Data; +using Platform.Data.Doublets; +using Platform.Data.Doublets.CriterionMatchers; +using Platform.Data.Doublets.Memory; +using Platform.Data.Doublets.Memory.United.Generic; +using Platform.Data.Doublets.Sequences.Converters; +using Platform.Data.Doublets.Sequences.Walkers; +using Platform.Data.Doublets.Unicode; +using Platform.Data.Numbers.Raw; +using Platform.Memory; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using Platform.Data.Doublets.Numbers.Raw; +using Platform.Disposables; +using TLinkAddress = System.UInt64; + +namespace Storage.Local +{ + /// + /// + /// Represents the file storage. + /// + /// + /// + public class FileStorage : DisposableBase + { + private readonly TLinkAddress _unicodeSequenceMarker; + private readonly TLinkAddress _meaningRoot; + private readonly AddressToRawNumberConverter _addressToNumberConverter; + private readonly RawNumberToAddressConverter _numberToAddressConverter; + private readonly IConverter _stringToUnicodeSequenceConverter; + private readonly IConverter _unicodeSequenceToStringConverter; + private readonly IConverter, TLinkAddress> _listToSequenceConverter; + private readonly IConverter _bigIntederToRawNumberConverter; + private readonly IConverter _rawNumberToBigIntegerConverter; + private readonly TLinkAddress _negativeNumberIndex; + private readonly UnitedMemoryLinks _disposableLinks; + private readonly SynchronizedLinks _synchronizedLinks; + private readonly TLinkAddress _unicodeSymbolMarker; + private readonly TLinkAddress _setMarker; + private readonly TLinkAddress _fileMarker; + private readonly TLinkAddress _gitHubLastMigrationTimestampMarker; + private readonly TLinkAddress Any; + private TLinkAddress GetOrCreateNextMapping(TLinkAddress currentMappingIndex) => _synchronizedLinks.Exists(currentMappingIndex) ? currentMappingIndex : _synchronizedLinks.CreateAndUpdate(_meaningRoot, _synchronizedLinks.Constants.Itself); + private TLinkAddress GetOrCreateMeaningRoot(TLinkAddress meaningRootIndex) => _synchronizedLinks.Exists(meaningRootIndex) ? meaningRootIndex : _synchronizedLinks.CreatePoint(); + + /// + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// A db filename. + /// + /// + public FileStorage(string DBFilename) + { + var linksConstants = new LinksConstants(enableExternalReferencesSupport: true); + var dataMemory = new FileMappedResizableDirectMemory(DBFilename); + _disposableLinks = new UnitedMemoryLinks(dataMemory, UnitedMemoryLinks.DefaultLinksSizeStep, linksConstants, IndexTreeType.Default); + _synchronizedLinks = new SynchronizedLinks(_disposableLinks); + var link = _synchronizedLinks.Create(); + link = _synchronizedLinks.Update(link, newSource: link, newTarget: link); + ushort currentMappingLinkIndex = 1; + Any = _synchronizedLinks.Constants.Any; + _meaningRoot = GetOrCreateMeaningRoot(currentMappingLinkIndex++); + _unicodeSymbolMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _unicodeSequenceMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _negativeNumberIndex = GetOrCreateNextMapping(currentMappingLinkIndex++); + _setMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _fileMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _gitHubLastMigrationTimestampMarker = GetOrCreateNextMapping(currentMappingLinkIndex++); + _addressToNumberConverter = new AddressToRawNumberConverter(); + _numberToAddressConverter = new RawNumberToAddressConverter(); + var balancedVariantConverter = new BalancedVariantConverter(_synchronizedLinks); + var unicodeSymbolCriterionMatcher = new TargetMatcher(_synchronizedLinks, _unicodeSymbolMarker); + var unicodeSequenceCriterionMatcher = new TargetMatcher(_synchronizedLinks, _unicodeSequenceMarker); + var charToUnicodeSymbolConverter = new CharToUnicodeSymbolConverter(_synchronizedLinks, _addressToNumberConverter, _unicodeSymbolMarker); + var unicodeSymbolToCharConverter = new UnicodeSymbolToCharConverter(_synchronizedLinks, _numberToAddressConverter, unicodeSymbolCriterionMatcher); + var sequenceWalker = new RightSequenceWalker(_synchronizedLinks, new DefaultStack(), unicodeSymbolCriterionMatcher.IsMatched); + _stringToUnicodeSequenceConverter = new CachingConverterDecorator(new StringToUnicodeSequenceConverter(_synchronizedLinks, charToUnicodeSymbolConverter, balancedVariantConverter, _unicodeSequenceMarker)); + _unicodeSequenceToStringConverter = new CachingConverterDecorator(new UnicodeSequenceToStringConverter(_synchronizedLinks, unicodeSequenceCriterionMatcher, sequenceWalker, unicodeSymbolToCharConverter)); + _listToSequenceConverter = new BalancedVariantConverter(_synchronizedLinks); + _bigIntederToRawNumberConverter = new BigIntegerToRawNumberSequenceConverter(_synchronizedLinks, _addressToNumberConverter, _listToSequenceConverter, _negativeNumberIndex); + _rawNumberToBigIntegerConverter = new RawNumberSequenceToBigIntegerConverter(_synchronizedLinks, _numberToAddressConverter, _negativeNumberIndex); + } + + /// + /// + /// Converts the str. + /// + /// + /// + /// + /// The str. + /// + /// + /// + /// The link address + /// + /// + public TLinkAddress CreateString(string str) => _stringToUnicodeSequenceConverter.Convert(str); + + /// + /// + /// Converts the address. + /// + /// + /// + /// + /// The address. + /// + /// + /// + /// The string + /// + /// + public string GetString(TLinkAddress address) => _unicodeSequenceToStringConverter.Convert(address); + + /// + /// + /// + /// + /// + public TLinkAddress CreateBigInteger(BigInteger bigInteger) => _bigIntederToRawNumberConverter.Convert(bigInteger); + + /// + /// + /// + /// + /// + public BigInteger GetBigInteger(TLinkAddress address) => _rawNumberToBigIntegerConverter.Convert(address); + + /// + /// + /// Gets the file content using the specified address. + /// + /// + /// + /// + /// The address. + /// + /// + /// + /// Link is not a file. + /// + /// + /// + /// The string + /// + /// + public string GetFileContent(TLinkAddress address) + { + var link = _synchronizedLinks.GetLink(address); + if (_synchronizedLinks.GetSource(link) == _fileMarker) + { + return GetString(_synchronizedLinks.GetTarget(link)); + } + throw new InvalidOperationException("Link is not a file."); + } + + /// + /// + /// Deletes the link. + /// + /// + /// + /// + /// The link. + /// + /// + public void Delete(TLinkAddress link) => _synchronizedLinks.Delete(link); + + /// + /// + /// Gets the all files. + /// + /// + /// + /// + /// The files. + /// + /// + public List GetAllFiles() + { + List files = new() { }; + foreach (var file in _synchronizedLinks.All(new Link(index: Any, source: _fileMarker, target: Any))) + { + files.Add(new File { Path = file.ToString(), Content = GetString(_synchronizedLinks.GetTarget(file)) }); + } + return files; + } + + /// + /// + /// Alls the links to string. + /// + /// + /// + /// + /// The string + /// + /// + public string AllLinksToString() + { + StringBuilder builder = new(); + var query = new Link(index: Any, source: Any, target: Any); + _synchronizedLinks.Each(link => + { + builder.AppendLine(_synchronizedLinks.Format(link)); + return _synchronizedLinks.Constants.Continue; + }, query); + return builder.ToString(); + } + + /// + /// + /// Adds the file using the specified content. + /// + /// + /// + /// + /// The content. + /// + /// + /// + /// The link address + /// + /// + public TLinkAddress AddFile(string content) => _synchronizedLinks.GetOrCreate(_fileMarker, _stringToUnicodeSequenceConverter.Convert(content)); + + /// + /// + /// Creates the file set using the specified file set name. + /// + /// + /// + /// + /// The file set name. + /// + /// + /// + /// The link address + /// + /// + public TLinkAddress CreateFileSet(string fileSetName) => _synchronizedLinks.GetOrCreate(_setMarker, CreateString(fileSetName)); + + /// + /// + /// 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) => _synchronizedLinks.GetOrCreate(set, _synchronizedLinks.GetOrCreate(CreateString(path), file)); + + /// + /// + /// Gets the file set using the specified file set name. + /// + /// + /// + /// + /// The file set name. + /// + /// + /// + /// The link address + /// + /// + public TLinkAddress GetFileSet(string fileSetName) => _synchronizedLinks.SearchOrDefault(_setMarker, CreateString(fileSetName)); + private IList?> GetFilesLinksFromSet(string set) + { + var fileSet = GetFileSet(set); + var list = _synchronizedLinks.All(new Link(index: Any, source: fileSet, target: Any)); + return list; + } + + /// + /// + /// Gets the files from set using the specified set. + /// + /// + /// + /// + /// The set. + /// + /// + /// + /// The files. + /// + /// + public List GetFilesFromSet(string set) + { + List files = new(); + foreach (var file in GetFilesLinksFromSet(set)) + { + var pathAndFile = _synchronizedLinks.GetTarget(file); + files.Add(new File() + { + Path = GetString(_synchronizedLinks.GetSource(pathAndFile)), + Content = GetFileContent(_synchronizedLinks.GetTarget(pathAndFile)) + }); + } + return files; + } + + // public void SetLastGithubMigrationTimeStamp() + + protected override void Dispose(bool manual, bool wasDisposed) + { + _disposableLinks.Dispose(); + } + } +} diff --git a/csharp/Storage/RemoteStorage/GitHubStorage.cs b/csharp/Storage/RemoteStorage/GitHubStorage.cs index e11dd54e..c4882b37 100644 --- a/csharp/Storage/RemoteStorage/GitHubStorage.cs +++ b/csharp/Storage/RemoteStorage/GitHubStorage.cs @@ -41,6 +41,7 @@ public class GitHubStorage /// /// public TimeSpan MinimumInteractionInterval { get; } + private DateTimeOffset lastIssue = DateTimeOffset.Now.Subtract(TimeSpan.FromDays(14)); /// @@ -124,7 +125,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}); } /// diff --git a/csharp/db.links b/csharp/db.links deleted file mode 100644 index d4f914a9..00000000 Binary files a/csharp/db.links and /dev/null differ