139 lines
3.4 KiB
Go
139 lines
3.4 KiB
Go
// internal/api/global_relay_service.go
|
|
package api
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.sovbit.dev/Enki/nostr-poster/internal/db"
|
|
"git.sovbit.dev/Enki/nostr-poster/internal/models"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// GlobalRelayService provides functionality for managing global relays
|
|
type GlobalRelayService struct {
|
|
db *db.DB
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewGlobalRelayService creates a new GlobalRelayService
|
|
func NewGlobalRelayService(db *db.DB, logger *zap.Logger) *GlobalRelayService {
|
|
return &GlobalRelayService{
|
|
db: db,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// GetUserGlobalRelays gets all global relays for a user
|
|
func (s *GlobalRelayService) GetUserGlobalRelays(ownerPubkey string) ([]*models.Relay, error) {
|
|
query := `
|
|
SELECT id, url, read, write, owner_pubkey
|
|
FROM global_relays
|
|
WHERE owner_pubkey = ?
|
|
ORDER BY id
|
|
`
|
|
|
|
var relays []*models.Relay
|
|
err := s.db.Select(&relays, query, ownerPubkey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get global relays: %w", err)
|
|
}
|
|
|
|
return relays, nil
|
|
}
|
|
|
|
// AddGlobalRelay adds a global relay for a user
|
|
func (s *GlobalRelayService) AddGlobalRelay(relay *models.Relay) error {
|
|
query := `
|
|
INSERT INTO global_relays (url, read, write, owner_pubkey)
|
|
VALUES (?, ?, ?, ?)
|
|
`
|
|
|
|
_, err := s.db.Exec(query, relay.URL, relay.Read, relay.Write, relay.OwnerPubkey)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to add global relay: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateGlobalRelay updates a global relay
|
|
func (s *GlobalRelayService) UpdateGlobalRelay(relay *models.Relay) error {
|
|
query := `
|
|
UPDATE global_relays
|
|
SET url = ?, read = ?, write = ?
|
|
WHERE id = ? AND owner_pubkey = ?
|
|
`
|
|
|
|
_, err := s.db.Exec(query, relay.URL, relay.Read, relay.Write, relay.ID, relay.OwnerPubkey)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update global relay: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeleteGlobalRelay deletes a global relay
|
|
func (s *GlobalRelayService) DeleteGlobalRelay(relayID int64, ownerPubkey string) error {
|
|
query := `
|
|
DELETE FROM global_relays
|
|
WHERE id = ? AND owner_pubkey = ?
|
|
`
|
|
|
|
_, err := s.db.Exec(query, relayID, ownerPubkey)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete global relay: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetAllRelaysForPosting gets a combined list of bot-specific and global relays for posting
|
|
func (s *GlobalRelayService) GetAllRelaysForPosting(botID int64, ownerPubkey string) ([]*models.Relay, error) {
|
|
// First, get bot-specific relays
|
|
query1 := `
|
|
SELECT id, bot_id, url, read, write
|
|
FROM relays
|
|
WHERE bot_id = ?
|
|
`
|
|
|
|
var botRelays []*models.Relay
|
|
err := s.db.Select(&botRelays, query1, botID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get bot relays: %w", err)
|
|
}
|
|
|
|
// Then, get global relays
|
|
query2 := `
|
|
SELECT id, url, read, write, owner_pubkey
|
|
FROM global_relays
|
|
WHERE owner_pubkey = ?
|
|
`
|
|
|
|
var globalRelays []*models.Relay
|
|
err = s.db.Select(&globalRelays, query2, ownerPubkey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get global relays: %w", err)
|
|
}
|
|
|
|
// Combine both sets, avoiding duplicates
|
|
// We'll consider a relay a duplicate if it has the same URL
|
|
urlMap := make(map[string]bool)
|
|
var combined []*models.Relay
|
|
|
|
// Add bot relays first (they take precedence)
|
|
for _, relay := range botRelays {
|
|
urlMap[relay.URL] = true
|
|
combined = append(combined, relay)
|
|
}
|
|
|
|
// Add global relays if they don't conflict
|
|
for _, relay := range globalRelays {
|
|
if !urlMap[relay.URL] {
|
|
// Set the bot ID for consistency
|
|
relay.BotID = botID
|
|
combined = append(combined, relay)
|
|
}
|
|
}
|
|
|
|
return combined, nil
|
|
} |