mirror of
https://github.com/studiokaiji/nostr-webhost.git
synced 2025-12-17 06:44:28 +01:00
146 lines
3.3 KiB
Go
146 lines
3.3 KiB
Go
package deploy
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/nbd-wtf/go-nostr"
|
|
"github.com/nbd-wtf/go-nostr/nip19"
|
|
"github.com/studiokaiji/nostr-webhost/cmd/consts"
|
|
"github.com/studiokaiji/nostr-webhost/cmd/tools"
|
|
)
|
|
|
|
var allRelays []string
|
|
|
|
func getEvent(priKey, pubKey, content string, kind int, tags nostr.Tags) (*nostr.Event, error) {
|
|
ev := nostr.Event{
|
|
PubKey: pubKey,
|
|
CreatedAt: nostr.Now(),
|
|
Kind: kind,
|
|
Content: content,
|
|
Tags: tags,
|
|
}
|
|
|
|
err := ev.Sign(priKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ev, err
|
|
}
|
|
|
|
func isValidBasicFileType(str string) bool {
|
|
return strings.HasSuffix(str, ".html") || strings.HasSuffix(str, ".css") || strings.HasSuffix(str, ".js")
|
|
}
|
|
func publishEventsFromQueue(replaceable bool) (string, string) {
|
|
ctx := context.Background()
|
|
|
|
fmt.Println("Publishing...")
|
|
|
|
// 各リレーに接続
|
|
var relays []*nostr.Relay
|
|
|
|
for _, url := range allRelays {
|
|
relay, err := nostr.RelayConnect(ctx, url)
|
|
if err != nil {
|
|
fmt.Println("❌ Failed to connect to:", url)
|
|
continue
|
|
}
|
|
relays = append(relays, relay)
|
|
}
|
|
|
|
// Publishの進捗状況を表示
|
|
allEventsCount := len(nostrEventsQueue)
|
|
uploadedMediaFilesCount := 0
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
go func() {
|
|
wg.Add(1)
|
|
tools.DisplayProgressBar(&uploadedMediaFilesCount, &allEventsCount)
|
|
wg.Done()
|
|
}()
|
|
|
|
var mutex sync.Mutex
|
|
|
|
// リレーへpublish
|
|
for _, ev := range nostrEventsQueue {
|
|
wg.Add(1)
|
|
go func(event *nostr.Event) {
|
|
for _, relay := range relays {
|
|
_, err := relay.Publish(ctx, *event)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
continue
|
|
}
|
|
}
|
|
mutex.Lock() // ロックして排他制御
|
|
uploadedMediaFilesCount++ // カウントアップ
|
|
mutex.Unlock() // ロック解除
|
|
wg.Done() // ゴルーチンの終了を通知
|
|
}(ev)
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
if uploadedMediaFilesCount < allEventsCount {
|
|
fmt.Println("Failed to deploy", allEventsCount-uploadedMediaFilesCount, "files.")
|
|
}
|
|
|
|
indexEvent := nostrEventsQueue[len(nostrEventsQueue)-1]
|
|
|
|
encoded := ""
|
|
if !replaceable {
|
|
if enc, err := nip19.EncodeEvent(indexEvent.ID, allRelays, indexEvent.PubKey); err == nil {
|
|
encoded = enc
|
|
} else {
|
|
fmt.Println("❌ Failed to covert nevent:", err)
|
|
}
|
|
}
|
|
|
|
return indexEvent.ID, encoded
|
|
}
|
|
|
|
func pathToKind(path string, replaceable bool) (int, error) {
|
|
// パスを分割
|
|
separatedPath := strings.Split(path, ".")
|
|
// 拡張子を取得
|
|
ex := separatedPath[len(separatedPath)-1]
|
|
// replaceable(NIP-33)の場合はReplaceableなkindを返す
|
|
switch ex {
|
|
case "html":
|
|
if replaceable {
|
|
return consts.KindWebhostHTML, nil
|
|
} else {
|
|
return consts.KindWebhostReplaceableHTML, nil
|
|
}
|
|
case "css":
|
|
if replaceable {
|
|
return consts.KindWebhostReplaceableCSS, nil
|
|
} else {
|
|
return consts.KindWebhostCSS, nil
|
|
}
|
|
case "js":
|
|
if replaceable {
|
|
return consts.KindWebhostReplaceableJS, nil
|
|
} else {
|
|
return consts.KindWebhostJS, nil
|
|
}
|
|
default:
|
|
return 0, fmt.Errorf("Invalid path")
|
|
}
|
|
}
|
|
|
|
// Replaceableにする場合のidentifier(dタグ)を取得
|
|
func getReplaceableIdentifier(indexHtmlIdentifier, filePath string) string {
|
|
return indexHtmlIdentifier + "/" + filePath[1:]
|
|
}
|
|
|
|
var nostrEventsQueue []*nostr.Event
|
|
|
|
func addNostrEventQueue(event *nostr.Event) {
|
|
nostrEventsQueue = append(nostrEventsQueue, event)
|
|
}
|