From 7ccdbd3c268a5921799784218bef48a1faed05f0 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 9 Apr 2025 15:25:31 +0200 Subject: [PATCH] wip --- Framework/WebUtils/Http.cs | 9 - Framework/WebUtils/HttpFactory.cs | 24 ++- Tools/BiblioTech/CodexCidChecker.cs | 167 ------------------- Tools/BiblioTech/CodexTwoWayChecker.cs | 59 +++++++ Tools/BiblioTech/Commands/CheckCidCommand.cs | 4 +- Tools/BiblioTech/Program.cs | 2 +- 6 files changed, 84 insertions(+), 181 deletions(-) delete mode 100644 Tools/BiblioTech/CodexCidChecker.cs create mode 100644 Tools/BiblioTech/CodexTwoWayChecker.cs diff --git a/Framework/WebUtils/Http.cs b/Framework/WebUtils/Http.cs index 7c9a91ad..e4931996 100644 --- a/Framework/WebUtils/Http.cs +++ b/Framework/WebUtils/Http.cs @@ -20,11 +20,6 @@ namespace WebUtils private readonly Action onClientCreated; private readonly string id; - internal Http(string id, ILog log, IWebCallTimeSet timeSet) - : this(id, log, timeSet, DoNothing) - { - } - internal Http(string id, ILog log, IWebCallTimeSet timeSet, Action onClientCreated) { this.id = id; @@ -89,9 +84,5 @@ namespace WebUtils onClientCreated(client); return client; } - - private static void DoNothing(HttpClient client) - { - } } } diff --git a/Framework/WebUtils/HttpFactory.cs b/Framework/WebUtils/HttpFactory.cs index 4d5d7c4c..8120527c 100644 --- a/Framework/WebUtils/HttpFactory.cs +++ b/Framework/WebUtils/HttpFactory.cs @@ -13,16 +13,28 @@ namespace WebUtils { private readonly ILog log; private readonly IWebCallTimeSet defaultTimeSet; + private readonly Action factoryOnClientCreated; public HttpFactory(ILog log) : this (log, new DefaultWebCallTimeSet()) { } + public HttpFactory(ILog log, Action onClientCreated) + : this(log, new DefaultWebCallTimeSet(), onClientCreated) + { + } + public HttpFactory(ILog log, IWebCallTimeSet defaultTimeSet) + : this(log, defaultTimeSet, DoNothing) + { + } + + public HttpFactory(ILog log, IWebCallTimeSet defaultTimeSet, Action onClientCreated) { this.log = log; this.defaultTimeSet = defaultTimeSet; + this.factoryOnClientCreated = onClientCreated; } public IHttp CreateHttp(string id, Action onClientCreated) @@ -32,12 +44,20 @@ namespace WebUtils public IHttp CreateHttp(string id, Action onClientCreated, IWebCallTimeSet ts) { - return new Http(id, log, ts, onClientCreated); + return new Http(id, log, ts, (c) => + { + factoryOnClientCreated(c); + onClientCreated(c); + }); } public IHttp CreateHttp(string id) { - return new Http(id, log, defaultTimeSet); + return new Http(id, log, defaultTimeSet, factoryOnClientCreated); + } + + private static void DoNothing(HttpClient client) + { } } } diff --git a/Tools/BiblioTech/CodexCidChecker.cs b/Tools/BiblioTech/CodexCidChecker.cs deleted file mode 100644 index dd3b30c7..00000000 --- a/Tools/BiblioTech/CodexCidChecker.cs +++ /dev/null @@ -1,167 +0,0 @@ -using CodexClient; -using Logging; -using Utils; - -namespace BiblioTech -{ - public class CodexCidChecker - { - private static readonly string nl = Environment.NewLine; - private readonly Configuration config; - private readonly ILog log; - private readonly Mutex checkMutex = new Mutex(); - private readonly CodexNodeFactory factory; - private ICodexNode? currentCodexNode; - - public CodexCidChecker(Configuration config, ILog log) - { - this.config = config; - this.log = log; - - factory = new CodexNodeFactory(log, dataDir: config.DataPath); - - if (!string.IsNullOrEmpty(config.CodexEndpointAuth) && config.CodexEndpointAuth.Contains(":")) - { - throw new Exception("Todo: codexnodefactory httpfactory support basicauth!"); - //var tokens = config.CodexEndpointAuth.Split(':'); - //if (tokens.Length != 2) throw new Exception("Expected ':' in CodexEndpointAuth parameter."); - //client.SetBasicAuthentication(tokens[0], tokens[1]); - } - } - - public CheckResponse PerformCheck(string cid) - { - if (string.IsNullOrEmpty(config.CodexEndpoint)) - { - return new CheckResponse(false, "Codex CID checker is not (yet) available."); - } - - try - { - checkMutex.WaitOne(); - var codex = GetCodex(); - var nodeCheck = CheckCodex(codex); - if (!nodeCheck) return new CheckResponse(false, "Codex node is not available. Cannot perform check."); - - return PerformCheck(codex, cid); - } - finally - { - checkMutex.ReleaseMutex(); - } - } - - private CheckResponse PerformCheck(ICodexNode codex, string cid) - { - try - { - var manifest = codex.DownloadManifestOnly(new ContentId(cid)); - return SuccessMessage(manifest); - } - catch - { - return FailedMessage(); - } - } - - #region Response formatting - - private CheckResponse SuccessMessage(LocalDataset content) - { - return FormatResponse( - success: true, - title: $"Success", - $"cid: '{content.Cid}'", - $"size: {content.Manifest.OriginalBytes} bytes", - $"blockSize: {content.Manifest.BlockSize} bytes", - $"protected: {content.Manifest.Protected}" - ); - } - - private CheckResponse FailedMessage() - { - var msg = "Could not download content."; - - return FormatResponse( - success: false, - title: "Failed", - msg, - $"Connection trouble? See 'https://docs.codex.storage/learn/troubleshoot'" - ); - } - - private CheckResponse FormatResponse(bool success, string title, params string[] content) - { - var msg = string.Join(nl, - new string[] - { - title, - "```" - } - .Concat(content) - .Concat(new string[] - { - "```" - }) - ) + nl + nl; - - return new CheckResponse(success, msg); - } - - #endregion - - #region Codex Node API - - private ICodexNode GetCodex() - { - if (currentCodexNode == null) currentCodexNode = CreateCodex(); - return currentCodexNode; - } - - private bool CheckCodex(ICodexNode node) - { - try - { - var info = node.GetDebugInfo(); - if (info == null || string.IsNullOrEmpty(info.Id)) return false; - return true; - } - catch (Exception e) - { - log.Error(e.ToString()); - return false; - } - } - - private ICodexNode CreateCodex() - { - var endpoint = config.CodexEndpoint; - var splitIndex = endpoint.LastIndexOf(':'); - var host = endpoint.Substring(0, splitIndex); - var port = Convert.ToInt32(endpoint.Substring(splitIndex + 1)); - - var address = new Address( - logName: $"cdx@{host}:{port}", - host: host, - port: port - ); - - var instance = CodexInstance.CreateFromApiEndpoint("ac", address); - return factory.CreateCodexNode(instance); - } - - #endregion - } - - public class CheckResponse - { - public CheckResponse(bool success, string message) - { - Success = success; - Message = message; - } - - public bool Success { get; } - public string Message { get; } - } -} diff --git a/Tools/BiblioTech/CodexTwoWayChecker.cs b/Tools/BiblioTech/CodexTwoWayChecker.cs new file mode 100644 index 00000000..8aa27f5b --- /dev/null +++ b/Tools/BiblioTech/CodexTwoWayChecker.cs @@ -0,0 +1,59 @@ +using CodexClient; +using IdentityModel.Client; +using Logging; +using Utils; +using WebUtils; + +namespace BiblioTech +{ + public class CodexTwoWayChecker + { + private static readonly string nl = Environment.NewLine; + private readonly Configuration config; + private readonly ILog log; + private readonly CodexNodeFactory factory; + private ICodexNode? currentCodexNode; + + public CodexTwoWayChecker(Configuration config, ILog log) + { + this.config = config; + this.log = log; + + var httpFactory = CreateHttpFactory(); + + factory = new CodexNodeFactory(log, httpFactory, dataDir: config.DataPath); + } + + // down check: + // generate unique data + // upload to cloud node + // give CID to user to download + // user inputs unique data into command to clear this check + + // up check: + // generate unique data + // create file and send it to user via discord api + // user uploads and gives CID via command + // download manifest: file is not larger than expected + // download file: contents is unique data -> clear this check + + // both checks: altruistic role + + private HttpFactory CreateHttpFactory() + { + if (string.IsNullOrEmpty(config.CodexEndpointAuth) && config.CodexEndpointAuth.Contains(":")) + { + return new HttpFactory(log); + } + + var tokens = config.CodexEndpointAuth.Split(':'); + if (tokens.Length != 2) throw new Exception("Expected ':' in CodexEndpointAuth parameter."); + + return new HttpFactory(log, onClientCreated: client => + { + client.SetBasicAuthentication(tokens[0], tokens[1]); + }); + } + + } +} diff --git a/Tools/BiblioTech/Commands/CheckCidCommand.cs b/Tools/BiblioTech/Commands/CheckCidCommand.cs index 1c5d6138..f19a33f5 100644 --- a/Tools/BiblioTech/Commands/CheckCidCommand.cs +++ b/Tools/BiblioTech/Commands/CheckCidCommand.cs @@ -10,10 +10,10 @@ namespace BiblioTech.Commands name: "cid", description: "Codex Content-Identifier", isRequired: true); - private readonly CodexCidChecker checker; + private readonly CodexTwoWayChecker checker; private readonly CidStorage cidStorage; - public CheckCidCommand(CodexCidChecker checker) + public CheckCidCommand(CodexTwoWayChecker checker) { this.checker = checker; this.cidStorage = new CidStorage(Path.Combine(Program.Config.DataPath, "valid_cids.txt")); diff --git a/Tools/BiblioTech/Program.cs b/Tools/BiblioTech/Program.cs index 46dee29c..ffc4f86d 100644 --- a/Tools/BiblioTech/Program.cs +++ b/Tools/BiblioTech/Program.cs @@ -80,7 +80,7 @@ namespace BiblioTech client = new DiscordSocketClient(); client.Log += ClientLog; - var checker = new CodexCidChecker(Config, Log); + var checker = new CodexTwoWayChecker(Config, Log); var notifyCommand = new NotifyCommand(); var associateCommand = new UserAssociateCommand(notifyCommand); var sprCommand = new SprCommand();