diff --git a/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BTCPayServer.Plugins.BitcoinSwitch.csproj b/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BTCPayServer.Plugins.BitcoinSwitch.csproj index 8e83521..dc0fe54 100644 --- a/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BTCPayServer.Plugins.BitcoinSwitch.csproj +++ b/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BTCPayServer.Plugins.BitcoinSwitch.csproj @@ -9,7 +9,7 @@ Bitcoin Switch Control harwdare using the POS as a switch - 1.0.1 + 1.0.2 true diff --git a/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchPlugin.cs b/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchPlugin.cs index 82247c0..7fed6d6 100644 --- a/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchPlugin.cs +++ b/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchPlugin.cs @@ -1,5 +1,8 @@ -using BTCPayServer.Abstractions.Contracts; +using System.Linq; +using BTCPayServer.Abstractions.Contracts; +using BTCPayServer.Abstractions.Form; using BTCPayServer.Abstractions.Models; +using BTCPayServer.Forms; using BTCPayServer.Plugins.FileSeller; using Microsoft.Extensions.DependencyInjection; @@ -17,7 +20,35 @@ public class BitcoinSwitchPlugin : BaseBTCPayServerPlugin applicationBuilder.AddSingleton(); applicationBuilder.AddHostedService(provider => provider.GetRequiredService()); applicationBuilder.AddUIExtension("app-template-editor-item-detail", "BitcoinSwitch/BitcoinSwitchPluginTemplateEditorItemDetail"); - + var regsitration = applicationBuilder.Single(descriptor => + descriptor.ServiceType == typeof(IFormComponentProvider) && + descriptor.ImplementationType == typeof(HtmlInputFormProvider)); + applicationBuilder.Remove(regsitration); + applicationBuilder.AddSingleton(); base.Execute(applicationBuilder); } +} + +public class HtmlInput2FormProvider : HtmlInputFormProvider +{ + + public override void Validate(Form form, Field field) + { + base.Validate(form, field); + + if (field.ValidationErrors.Count != 0) + { + return; + } + + if (field.AdditionalData.TryGetValue("regex", out var regex) && regex.ToString() is {} regexStr&& + !System.Text.RegularExpressions.Regex.IsMatch(GetValue(form, field), regexStr)) + { + var regexErrorMessage = field.AdditionalData.TryGetValue("regex-error-message", out var regexError) + ? regexError.ToString() + : "The value is not valid"; + + field.ValidationErrors.Add(regexErrorMessage); + } + } } \ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchService.cs b/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchService.cs index 6aec58b..0c42481 100644 --- a/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchService.cs +++ b/Plugins/BTCPayServer.Plugins.BitcoinSwitch/BitcoinSwitchService.cs @@ -20,7 +20,7 @@ namespace BTCPayServer.Plugins.FileSeller public class BitcoinSwitchEvent { public string AppId { get; set; } - public string SwitchSettings { get; set; } + public List SwitchSettings { get; set; } } public class BitcoinSwitchService : EventHostedServiceBase @@ -63,6 +63,9 @@ List cartItems = null; { return; } + // + // invoiceEvent.Invoice.Metadata.AdditionalData + // .TryGetValue("bitcoinswitchsettings", out var explicitBitcoinswitchSettings); var appIds = AppService.GetAppInternalTags(invoiceEvent.Invoice); @@ -119,19 +122,26 @@ List cartItems = null; { var appId = valueTuple.Data.Id; var gpio = item1.AdditionalData["bitcoinswitch"].Value(); - - - PushEvent(new BitcoinSwitchEvent() - { - AppId = appId, - SwitchSettings = gpio - }); + if (ParseActions(gpio) is { } actions) + PushEvent(new BitcoinSwitchEvent() + { + AppId = appId, + SwitchSettings = actions + }); } } - - + // if(explicitBitcoinswitchSettings is not null) + // { + // if (ParseActions(explicitBitcoinswitchSettings.Value()) is { } actions) + // PushEvent(new BitcoinSwitchEvent() + // { + // SwitchSettings = actions + // }); + // } + invoiceEvent.Invoice.Metadata.SetAdditionalData("bitcoinswitchactivated", "true"); + await _invoiceRepository.UpdateInvoiceMetadata(invoiceEvent.InvoiceId, invoiceEvent.Invoice.StoreId, invoiceEvent.Invoice.Metadata.ToJObject()); @@ -143,10 +153,9 @@ List cartItems = null; private async Task HandleGPIOMessages(CancellationToken cancellationToken, BitcoinSwitchEvent bitcoinSwitchEvent) { - // Parse switch settings into actions - var actions = ParseActions(bitcoinSwitchEvent.SwitchSettings); - + + var actions = bitcoinSwitchEvent.SwitchSettings; try { // Execute each action sequentially @@ -181,42 +190,49 @@ List cartItems = null; { Logs.PayServer.LogError(ex, "Error sending BitcoinSwitchEvent to socket"); } - - - return; } /// /// Parses a settings string like "25-5000.0,delay 1000,23-200.0" into a sequence of actions. /// - private static List ParseActions(string settings) + private List? ParseActions(string settings) { - var actions = new List(); - var segments = settings.Split(',', StringSplitOptions.RemoveEmptyEntries); - foreach (var seg in segments.Select(s => s.Trim())) + try { - if (seg.StartsWith("delay ", StringComparison.OrdinalIgnoreCase)) + var actions = new List(); + var segments = settings.Split(',', StringSplitOptions.RemoveEmptyEntries); + foreach (var seg in segments.Select(s => s.Trim())) { - // Delay segment - var parts = seg.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (parts.Length == 2 && int.TryParse(parts[1], out var ms)) + if (seg.StartsWith("delay ", StringComparison.OrdinalIgnoreCase)) { - actions.Add(SwitchAction.Delay(ms)); - } - } - else - { - // Pin-duration segment - var parts = seg.Split('-', StringSplitOptions.RemoveEmptyEntries); - if (parts.Length == 2 - && int.TryParse(parts[0], out var pin) - && double.TryParse(parts[1], out var duration)) - { - actions.Add(SwitchAction.Command(pin, duration)); + // Delay segment + var parts = seg.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (parts.Length == 2 && int.TryParse(parts[1], out var ms)) + { + actions.Add(SwitchAction.Delay(ms)); + } + } + else + { + // Pin-duration segment + var parts = seg.Split('-', StringSplitOptions.RemoveEmptyEntries); + if (parts.Length == 2 + && int.TryParse(parts[0], out var pin) + && double.TryParse(parts[1], out var duration)) + { + actions.Add(SwitchAction.Command(pin, duration)); + } } } + return actions; } - return actions; + catch (Exception e) + { + Logs.PayServer.LogError(e, "Error parsing BitcoinSwitchEvent settings"); + return null; + } + + } }