WIP Refactor stuff
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Râu Cao 2024-10-18 18:15:52 +02:00
parent 04a9061663
commit 79ef9fa6d5
Signed by: raucao
GPG Key ID: 37036C356E56CC51
7 changed files with 97 additions and 88 deletions

View File

@ -2,9 +2,9 @@
module Settings
class NostrRelayStatusComponent < ViewComponent::Base
def initialize(relay_urls:)
if relay_urls.present?
if relay_urls.any? { |r| r.include?("wss://nostr.kosmos.org") }
def initialize(nip65_event:)
if nip65_event.present?
if relay_urls(nip65_event).any? { |r| r.include?("wss://nostr.kosmos.org") }
@text = "You have a relay list, and the Kosmos relay is part of it"
@icon_name = "check-circle"
@icon_color = "emerald-500"
@ -19,5 +19,13 @@ module Settings
@icon_color = "amber-500"
end
end
private
def relay_urls(nip65_event)
nip65_event["tags"].select{ |t| t[0] == "r" }.map{ |t| t[1] }
# @inbox_relay_urls = relay_tags&.select{ |t| t[2] == "read" }&.map{ |t| t[1] }
# @outbox_relay_urls = relay_tags&.select{ |t| t[2] != "read" }&.map{ |t| t[1] }
end
end
end

View File

@ -136,10 +136,11 @@ class SettingsController < ApplicationController
def fetch_nostr_user_metadata
if @user.nostr_pubkey.present?
if @nip65_event = NostrManager::DiscoverUserRelays.call(pubkey: @user.nostr_pubkey)
@relay_urls = @nip65_event["tags"].select{ |t| t[0] == "r" }&.map{ |t| t[1] }
relay_tags = @nip65_event["tags"].select{ |t| t[0] == "r" }
outbox_relay_urls = relay_tags&.select{ |t| t[2] != "read" }&.map{ |t| t[1] }
end
@profile = NostrManager::DiscoverUserProfile.call(pubkey: @user.nostr_pubkey, relays: @relay_urls)
@profile = NostrManager::DiscoverUserProfile.call(pubkey: @user.nostr_pubkey, relays: outbox_relay_urls)
else
@relays, @profile = [nil, nil]
end

View File

@ -1,36 +1,21 @@
module NostrManager
class DiscoverUserProfile < NostrManagerService
MAX_EVENTS = 2
def initialize(pubkey:, relays: nil)
@pubkey = pubkey
@relays = relays.present? ? relays : Setting.nostr_discovery_relays
end
def call
received_events = 0
profile_events = []
filter = Nostr::Filter.new(
authors: [@pubkey],
kinds: [0],
limit: 1,
)
@relays.each do |url|
event = NostrManager::FetchLatestEvent.call(filter: filter, relay_url: url)
if event.present?
profile_events << event if profile_events.none? { |e| e["id"] == event["id"] }
received_events += 1
end
if received_events >= MAX_EVENTS
puts "Found #{MAX_EVENTS} events, ending the search"
break
end
end
profile_events.min_by { |e| e["created_at"] }
NostrManager::FetchLatestEvent.call(
relays: @relays,
filter: filter
)
end
end
end

View File

@ -1,37 +1,21 @@
module NostrManager
class DiscoverUserRelays < NostrManagerService
MAX_EVENTS = 2
def initialize(pubkey:)
@pubkey = pubkey
@relays = Setting.nostr_discovery_relays
end
def call
received_events = 0
nip65_events = []
user_relays = []
filter = Nostr::Filter.new(
authors: [@pubkey],
kinds: [10002],
limit: 1,
)
@relays.each do |url|
event = NostrManager::FetchLatestEvent.call(filter: filter, relay_url: url)
if event.present?
nip65_events << event if nip65_events.none? { |e| e["id"] == event["id"] }
received_events += 1
end
if received_events >= MAX_EVENTS
puts "Found #{MAX_EVENTS} events, ending the search"
break
end
end
nip65_events.min_by { |e| e["created_at"] }
NostrManager::FetchLatestEvent.call(
relays: @relays,
filter: filter
)
end
end
end

View File

@ -0,0 +1,59 @@
module NostrManager
class FetchEvent < NostrManagerService
TIMEOUT = 1
def initialize(filter:, relay_url:)
@filter = filter
@relay = new_relay(relay_url)
@client = Nostr::Client.new
end
def call
filter, client, relay = @filter, @client, @relay
event = nil
mutex = Mutex.new
received_event = ConditionVariable.new
log_prefix = "[nostr][#{@relay.name}]"
thread = Thread.new do
client.on :connect do
client.subscribe(filter: filter)
end
client.on :error do |e|
Rails.logger.info "#{log_prefix} Error: #{e}"
Thread.current.exit
end
client.on :message do |m|
msg = JSON.parse(m) rescue nil
if msg && msg[0] == "EVENT" && msg[2]
puts "#{log_prefix} Event received: #{msg[2]["id"]}"
mutex.synchronize do
event = msg[2]
received_event.signal
end
elsif msg && msg[0] == "EOSE"
Thread.current.exit
end
end
client.connect relay
end
begin
Timeout.timeout(TIMEOUT) do
mutex.synchronize do
received_event.wait(mutex) if event.nil?
end
end
rescue Timeout::Error
puts "#{log_prefix} Timeout: No event received within #{TIMEOUT} seconds"
ensure
thread.exit
end
event
end
end
end

View File

@ -1,59 +1,31 @@
module NostrManager
class FetchLatestEvent < NostrManagerService
TIMEOUT = 1
def initialize(filter:, relay_url:)
def initialize(relays:, filter:, max_events: 2)
@relays = relays
@filter = filter
@relay = new_relay(relay_url)
@client = Nostr::Client.new
@max_events = max_events
end
def call
filter, client, relay = @filter, @client, @relay
latest_event = nil
mutex = Mutex.new
received_event = ConditionVariable.new
log_prefix = "[nostr][#{@relay.name}]"
received_events = 0
events = []
thread = Thread.new do
client.on :connect do
client.subscribe(filter: filter)
@relays.each do |url|
event = NostrManager::FetchEvent.call(filter: @filter, relay_url: url)
if event.present?
events << event if events.none? { |e| e["id"] == event["id"] }
received_events += 1
end
client.on :error do |e|
Rails.logger.info "#{log_prefix} Error: #{e}"
Thread.current.exit
if received_events >= @max_events
puts "Found #{@max_events} events, ending the search"
break
end
client.on :message do |m|
msg = JSON.parse(m) rescue nil
if msg && msg[0] == "EVENT" && msg[2]
puts "#{log_prefix} Event received: #{msg[2]["id"]}"
mutex.synchronize do
latest_event = msg[2]
received_event.signal
end
elsif msg && msg[0] == "EOSE"
Thread.current.exit
end
end
client.connect relay
end
begin
Timeout.timeout(TIMEOUT) do
mutex.synchronize do
received_event.wait(mutex) if latest_event.nil?
end
end
rescue Timeout::Error
puts "#{log_prefix} Timeout: No event received within #{TIMEOUT} seconds"
ensure
thread.exit
end
latest_event
events.min_by { |e| e["created_at"] }
end
end
end

View File

@ -9,7 +9,7 @@
<section>
<h3>Relays</h3>
<%= render Settings::NostrRelayStatusComponent.new(
relay_urls: @relay_urls
nip65_event: @nip65_event
) %>
</section>
<% end %>