diff --git a/hostr/cmd/deploy/deploy.go b/hostr/cmd/deploy/deploy.go index d873d31..1d05d86 100644 --- a/hostr/cmd/deploy/deploy.go +++ b/hostr/cmd/deploy/deploy.go @@ -3,145 +3,27 @@ package deploy import ( "bufio" "bytes" - "context" "fmt" "net/url" "os" "path/filepath" "strings" - "sync" "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" "github.com/studiokaiji/nostr-webhost/hostr/cmd/consts" "github.com/studiokaiji/nostr-webhost/hostr/cmd/keystore" "github.com/studiokaiji/nostr-webhost/hostr/cmd/relays" - "github.com/studiokaiji/nostr-webhost/hostr/cmd/tools" + "golang.org/x/exp/slices" "golang.org/x/net/html" ) -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) -} - -var allRelays []string - -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) - uploadedFilesCount := 0 - - var wg sync.WaitGroup - - go func() { - wg.Add(1) - tools.DisplayProgressBar(&uploadedFilesCount, &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() // ロックして排他制御 - uploadedFilesCount++ // カウントアップ - mutex.Unlock() // ロック解除 - wg.Done() // ゴルーチンの終了を通知 - }(ev) - } - - wg.Wait() - - if uploadedFilesCount < allEventsCount { - fmt.Println("Failed to deploy", allEventsCount-uploadedFilesCount, "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 isExternalURL(urlStr string) bool { u, err := url.Parse(urlStr) return err == nil && u.Scheme != "" && u.Host != "" } -func isValidFileType(str string) bool { - return strings.HasSuffix(str, ".html") || strings.HasSuffix(str, ".css") || strings.HasSuffix(str, ".js") -} - -func Deploy(basePath string, replaceable bool, htmlIdentifier string) (string, string, string, error) { +func Deploy(basePath string, replaceable bool, htmlIdentifier string) (string, string, error) { // 引数からデプロイしたいサイトのパスを受け取る。 filePath := filepath.Join(basePath, "index.html") @@ -149,26 +31,26 @@ func Deploy(basePath string, replaceable bool, htmlIdentifier string) (string, s content, err := os.ReadFile(filePath) if err != nil { fmt.Println("❌ Failed to read index.html:", err) - return "", "", "", err + return "", "", err } // HTMLの解析 doc, err := html.Parse(bytes.NewReader(content)) if err != nil { fmt.Println("❌ Failed to parse index.html:", err) - return "", "", "", err + return "", "", err } // Eventの取得に必要になるキーペアを取得 priKey, err := keystore.GetSecret() if err != nil { fmt.Println("❌ Failed to get private key:", err) - return "", "", "", err + return "", "", err } pubKey, err := nostr.GetPublicKey(priKey) if err != nil { fmt.Println("❌ Failed to get public key:", err) - return "", "", "", err + return "", "", err } // htmlIdentifierの存在チェック @@ -187,7 +69,16 @@ func Deploy(basePath string, replaceable bool, htmlIdentifier string) (string, s // リレーを取得 allRelays, err = relays.GetAllRelays() if err != nil { - return "", "", "", err + fmt.Println("❌ Failed to get all relays:", err) + return "", "", err + } + + + // basePath以下のMedia Fileのパスを全て羅列しアップロード + err = uploadAllValidStaticMediaFiles(priKey, pubKey, basePath) + if err != nil { + fmt.Println("❌ Failed to upload media:", err) + return "", "", err } // リンクの解析と変換 @@ -215,66 +106,103 @@ func Deploy(basePath string, replaceable bool, htmlIdentifier string) (string, s event, err := getEvent(priKey, pubKey, strHtml, indexHtmlKind, tags) if err != nil { fmt.Println("❌ Failed to get public key:", err) - return "", "", "", err + return "", "", err } addNostrEventQueue(event) fmt.Println("Added", filePath, "event to publish queue") eventId, encoded := publishEventsFromQueue(replaceable) - return eventId, encoded, htmlIdentifier, err + return eventId, encoded, err } -func convertLinks(priKey, pubKey, basePath string, replaceable bool, indexHtmlIdentifier string, n *html.Node) { - //