From a4ce10535ef6a9fa6ba690b33458076ffecf8155 Mon Sep 17 00:00:00 2001 From: studiokaiji Date: Tue, 24 Oct 2023 22:54:07 +0900 Subject: [PATCH] =?UTF-8?q?Nostr=E7=89=B9=E6=9C=89=E3=81=AE=E3=83=AD?= =?UTF-8?q?=E3=82=B8=E3=83=83=E3=82=AF=E3=82=92=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hostr/cmd/deploy/deploy.go | 354 ++++++++++++++++++------------------- hostr/cmd/deploy/nostr.go | 139 +++++++++++++++ 2 files changed, 312 insertions(+), 181 deletions(-) create mode 100644 hostr/cmd/deploy/nostr.go diff --git a/hostr/cmd/deploy/deploy.go b/hostr/cmd/deploy/deploy.go index bbed854..c3b96aa 100644 --- a/hostr/cmd/deploy/deploy.go +++ b/hostr/cmd/deploy/deploy.go @@ -3,144 +3,31 @@ package deploy import ( "bufio" "bytes" - "context" + "encoding/base64" + "encoding/json" "fmt" + "io" + "mime/multipart" + "net/http" "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 isValidBasicFileType(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, error) { // 引数からデプロイしたいサイトのパスを受け取る。 filePath := filepath.Join(basePath, "index.html") @@ -193,6 +80,13 @@ func Deploy(basePath string, replaceable bool, htmlIdentifier string) (string, s // リンクの解析と変換 convertLinks(priKey, pubKey, basePath, replaceable, htmlIdentifier, doc) + if len(mediaUploadRequestQueue) > 0 { + // メディアのアップロード + fmt.Println("📷 Uploading media files") + uploadMediaFilesFromQueue() + fmt.Println("📷 Media upload finished.") + } + // 更新されたHTML var buf bytes.Buffer html.Render(&buf, doc) @@ -226,55 +120,170 @@ func Deploy(basePath string, replaceable bool, htmlIdentifier string) (string, s } func convertLinks(priKey, pubKey, basePath string, replaceable bool, indexHtmlIdentifier string, n *html.Node) { - //