From a1dc18dc59f2e78f8e020615983e17bd1250329e Mon Sep 17 00:00:00 2001 From: mr0x50 <24775431+mroxso@users.noreply.github.com> Date: Sun, 23 Feb 2025 22:28:58 +0100 Subject: [PATCH] trending algo in own file and change go.mod project path --- relay/go.mod | 2 +- relay/main.go | 62 ++---------------------------------- relay/trending/kinds.go | 69 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 60 deletions(-) create mode 100644 relay/trending/kinds.go diff --git a/relay/go.mod b/relay/go.mod index 880fa3c..4542e54 100644 --- a/relay/go.mod +++ b/relay/go.mod @@ -1,4 +1,4 @@ -module git.v0l.io/highperfocused/scrapestr/relay +module git.highperfocused.tech/highperfocused/lumina-relay/relay go 1.23.4 diff --git a/relay/main.go b/relay/main.go index e22954d..e4c92f4 100644 --- a/relay/main.go +++ b/relay/main.go @@ -7,6 +7,7 @@ import ( "os" "time" + "git.highperfocused.tech/highperfocused/lumina-relay/relay/trending" "github.com/fiatjaf/eventstore/postgresql" "github.com/fiatjaf/khatru" "github.com/fiatjaf/khatru/policies" @@ -251,68 +252,11 @@ func main() { mux.HandleFunc("/api/trending/kind20", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - // This query joins kind 20 posts with their reactions (kind 7) - // and counts the number of reactions in the last 24 hours using lateral join - query := ` - WITH reactions AS ( - SELECT - tags_expanded.value->1 #>> '{}' AS original_event_id, - COUNT(*) as reaction_count - FROM event e - CROSS JOIN LATERAL jsonb_array_elements(tags) as tags_expanded(value) - WHERE e.kind::text = '7' - AND e.created_at >= extract(epoch from now() - interval '24 hours')::bigint - AND tags_expanded.value->0 #>> '{}' = 'e' - GROUP BY tags_expanded.value->1 #>> '{}' - ) - SELECT - e.id, - e.pubkey, - to_timestamp(e.created_at) as created_at, - e.kind, - e.content, - e.tags, - COALESCE(r.reaction_count, 0) as reaction_count - FROM event e - LEFT JOIN reactions r ON e.id = r.original_event_id - WHERE e.kind::text = '20' - AND e.created_at >= extract(epoch from now() - interval '24 hours')::bigint - ORDER BY reaction_count DESC, e.created_at DESC - LIMIT 20 - ` - - rows, err := db.DB.Query(query) + trendingPosts, err := trending.GetTrendingKind20(db.DB.DB) if err != nil { - http.Error(w, fmt.Sprintf("Error querying trending posts: %v", err), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("Error getting trending posts: %v", err), http.StatusInternalServerError) return } - defer rows.Close() - - type TrendingPost struct { - ID string `json:"id"` - PubKey string `json:"pubkey"` - CreatedAt time.Time `json:"created_at"` - Kind string `json:"kind"` - Content string `json:"content"` - Tags [][]string `json:"tags"` - ReactionCount int `json:"reaction_count"` - } - - var trendingPosts []TrendingPost - for rows.Next() { - var post TrendingPost - var tagsJSON []byte - if err := rows.Scan(&post.ID, &post.PubKey, &post.CreatedAt, &post.Kind, &post.Content, &tagsJSON, &post.ReactionCount); err != nil { - http.Error(w, fmt.Sprintf("Error scanning row: %v", err), http.StatusInternalServerError) - return - } - // Parse the tags JSON - if err := json.Unmarshal(tagsJSON, &post.Tags); err != nil { - http.Error(w, fmt.Sprintf("Error parsing tags: %v", err), http.StatusInternalServerError) - return - } - trendingPosts = append(trendingPosts, post) - } response := map[string]interface{}{ "trending": trendingPosts, diff --git a/relay/trending/kinds.go b/relay/trending/kinds.go new file mode 100644 index 0000000..dbbefe9 --- /dev/null +++ b/relay/trending/kinds.go @@ -0,0 +1,69 @@ +package trending + +import ( + "database/sql" + "encoding/json" + "time" +) + +type Post struct { + ID string `json:"id"` + PubKey string `json:"pubkey"` + CreatedAt time.Time `json:"created_at"` + Kind string `json:"kind"` + Content string `json:"content"` + Tags [][]string `json:"tags"` + ReactionCount int `json:"reaction_count"` +} + +// GetTrendingKind20 returns the top 20 trending posts of kind 20 from the last 24 hours +func GetTrendingKind20(db *sql.DB) ([]Post, error) { + query := ` + WITH reactions AS ( + SELECT + tags_expanded.value->1 #>> '{}' AS original_event_id, + COUNT(*) as reaction_count + FROM event e + CROSS JOIN LATERAL jsonb_array_elements(tags) as tags_expanded(value) + WHERE e.kind::text = '7' + AND e.created_at >= extract(epoch from now() - interval '24 hours')::bigint + AND tags_expanded.value->0 #>> '{}' = 'e' + GROUP BY tags_expanded.value->1 #>> '{}' + ) + SELECT + e.id, + e.pubkey, + to_timestamp(e.created_at) as created_at, + e.kind, + e.content, + e.tags, + COALESCE(r.reaction_count, 0) as reaction_count + FROM event e + LEFT JOIN reactions r ON e.id = r.original_event_id + WHERE e.kind::text = '20' + AND e.created_at >= extract(epoch from now() - interval '24 hours')::bigint + ORDER BY reaction_count DESC, e.created_at DESC + LIMIT 20 + ` + + rows, err := db.Query(query) + if err != nil { + return nil, err + } + defer rows.Close() + + var trendingPosts []Post + for rows.Next() { + var post Post + var tagsJSON []byte + if err := rows.Scan(&post.ID, &post.PubKey, &post.CreatedAt, &post.Kind, &post.Content, &tagsJSON, &post.ReactionCount); err != nil { + return nil, err + } + if err := json.Unmarshal(tagsJSON, &post.Tags); err != nil { + return nil, err + } + trendingPosts = append(trendingPosts, post) + } + + return trendingPosts, nil +}