diff --git a/app/app.go b/app/app.go index f5a3999..9d6e6a2 100644 --- a/app/app.go +++ b/app/app.go @@ -1,15 +1,10 @@ package app import ( - "context" "grain/server/db" relay "grain/server/types" "html/template" "net/http" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" ) type PageData struct { @@ -78,38 +73,4 @@ func PrependDir(dir string, files []string) []string { return fullPaths } -// FetchTopTenRecentEvents queries the database and returns the top ten most recent events. -func FetchTopTenRecentEvents(client *mongo.Client) ([]relay.Event, error) { - var results []relay.Event - collections, err := client.Database("grain").ListCollectionNames(context.TODO(), bson.M{}) - if err != nil { - return nil, err - } - - for _, collectionName := range collections { - collection := client.Database("grain").Collection(collectionName) - filter := bson.D{} - opts := options.Find().SetSort(bson.D{{Key: "createdat", Value: -1}}).SetLimit(10) - - cursor, err := collection.Find(context.TODO(), filter, opts) - if err != nil { - return nil, err - } - defer cursor.Close(context.TODO()) - - for cursor.Next(context.TODO()) { - var event relay.Event - if err := cursor.Decode(&event); err != nil { - return nil, err - } - results = append(results, event) - } - - if err := cursor.Err(); err != nil { - return nil, err - } - } - - return results, nil -} diff --git a/app/fetchRecentEvents.go b/app/fetchRecentEvents.go new file mode 100644 index 0000000..cac3a6d --- /dev/null +++ b/app/fetchRecentEvents.go @@ -0,0 +1,47 @@ +package app + +import ( + "context" + relay "grain/server/types" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +// FetchTopTenRecentEvents queries the database and returns the top ten most recent events. +func FetchTopTenRecentEvents(client *mongo.Client) ([]relay.Event, error) { + var results []relay.Event + + collections, err := client.Database("grain").ListCollectionNames(context.TODO(), bson.M{}) + if err != nil { + return nil, err + } + + for _, collectionName := range collections { + collection := client.Database("grain").Collection(collectionName) + filter := bson.D{} + opts := options.Find().SetSort(bson.D{{Key: "createdat", Value: -1}}).SetLimit(10) + + cursor, err := collection.Find(context.TODO(), filter, opts) + if err != nil { + return nil, err + } + defer cursor.Close(context.TODO()) + + for cursor.Next(context.TODO()) { + var event relay.Event + if err := cursor.Decode(&event); err != nil { + return nil, err + } + results = append(results, event) + } + + if err := cursor.Err(); err != nil { + return nil, err + } + } + + return results, nil +} + diff --git a/app/importEvents.go b/app/importEvents.go new file mode 100644 index 0000000..ede2003 --- /dev/null +++ b/app/importEvents.go @@ -0,0 +1,113 @@ +package app + +import ( + "context" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "strings" + + "grain/server/db" + relay "grain/server/types" + + "go.mongodb.org/mongo-driver/mongo" + "golang.org/x/net/websocket" +) + +func ImportEventsHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + return + } + + pubkey := r.FormValue("pubkey") + relayUrls := r.FormValue("relayUrls") + urls := strings.Split(relayUrls, ",") + + for _, url := range urls { + events, err := fetchEventsFromRelay(pubkey, url) + if err != nil { + log.Printf("Error fetching events from relay %s: %v", url, err) + http.Error(w, fmt.Sprintf("Error fetching events from relay %s", url), http.StatusInternalServerError) + return + } + + err = storeEvents(events) + if err != nil { + log.Printf("Error storing events: %v", err) + http.Error(w, "Error storing events", http.StatusInternalServerError) + return + } + } + + http.Redirect(w, r, "/", http.StatusSeeOther) +} + +func fetchEventsFromRelay(pubkey, relayUrl string) ([]relay.Event, error) { + log.Printf("Connecting to relay: %s", relayUrl) + conn, err := websocket.Dial(relayUrl, "", "http://localhost/") + if err != nil { + log.Printf("Error connecting to relay %s: %v", relayUrl, err) + return nil, err + } + defer conn.Close() + log.Printf("Connected to relay: %s", relayUrl) + + reqMessage := fmt.Sprintf(`["REQ", "import-sub", {"authors": ["%s"]}]`, pubkey) + log.Printf("Sending request: %s", reqMessage) + if _, err := conn.Write([]byte(reqMessage)); err != nil { + log.Printf("Error sending request to relay %s: %v", relayUrl, err) + return nil, err + } + + var events []relay.Event + for { + var msg []byte + if err := websocket.Message.Receive(conn, &msg); err != nil { + if err == io.EOF { + break + } + log.Printf("Error receiving message from relay %s: %v", relayUrl, err) + return nil, err + } + + log.Printf("Received message: %s", string(msg)) + + var response []interface{} + if err := json.Unmarshal(msg, &response); err != nil { + log.Printf("Error unmarshaling message from relay %s: %v", relayUrl, err) + return nil, err + } + + if response[0] == "EVENT" { + eventData, err := json.Marshal(response[2]) // Change index from 1 to 2 + if err != nil { + log.Printf("Error marshaling event data from relay %s: %v", relayUrl, err) + continue + } + var event relay.Event + if err := json.Unmarshal(eventData, &event); err != nil { + log.Printf("Error unmarshaling event data from relay %s: %v", relayUrl, err) + continue + } + events = append(events, event) + } + } + + log.Printf("Fetched %d events from relay %s", len(events), relayUrl) + return events, nil +} + +func storeEvents(events []relay.Event) error { + for _, event := range events { + collection := db.GetCollection(event.Kind) + _, err := collection.InsertOne(context.TODO(), event) + if err != nil && !mongo.IsDuplicateKeyError(err) { + log.Printf("Error inserting event into MongoDB: %v", err) + return err + } + } + return nil +} \ No newline at end of file diff --git a/app/views/index.html b/app/views/index.html index a32e50b..75434eb 100644 --- a/app/views/index.html +++ b/app/views/index.html @@ -1,7 +1,7 @@ {{define "view"}}
You are now viewing the {{.Title}}
-

Top Ten Most Recent Events

+ +
+
+
+ + +
+
+ + +
+ +
+
{{end}} diff --git a/main.go b/main.go index 604d523..b006a75 100644 --- a/main.go +++ b/main.go @@ -47,6 +47,7 @@ func main() { func setupRoutes() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/", ListenAndServe) + mux.HandleFunc("/import-events", app.ImportEventsHandler) mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("app/static")))) mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "app/static/img/favicon.ico")