-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlers.go
143 lines (126 loc) · 4.78 KB
/
handlers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/samratjha96/hecate/internal/database"
"github.com/samratjha96/hecate/internal/hecate"
)
const (
statusOK = http.StatusOK
statusCreated = http.StatusCreated
statusBadReq = http.StatusBadRequest
statusIntError = http.StatusInternalServerError
)
// ingestSubredditHandler handles the ingestion of a single subreddit
func ingestSubredditHandler(db *database.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var subreddit hecate.SubscribeFrontendRequest
if err := decodeJSONBody(w, r, &subreddit); err != nil {
log.Printf("Failed to decode request body: %v", err)
return
}
log.Printf("Ingesting subreddit: %s", subreddit.Subreddit.Name)
subscriptions, err := hecate.IngestSubreddit(r.Context(), db, subreddit.Subreddit)
if err != nil {
log.Printf("Failed to ingest subreddit %s: %v", subreddit.Subreddit.Name, err)
respondWithError(w, statusIntError, fmt.Sprintf("Failed to ingest subreddit: %v", err))
return
}
log.Printf("Successfully ingested subreddit: %s", subreddit.Subreddit.Name)
respondWithJson(w, statusCreated, subscriptions)
}
}
// ingestAllSubredditsHandler handles the ingestion of all subreddits
func ingestAllSubredditsHandler(db *database.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var request hecate.IngestAllFrontendRequest
if err := decodeJSONBody(w, r, &request); err != nil {
log.Printf("Failed to decode request body: %v", err)
return
}
log.Printf("Ingesting all subreddits with sort: %s", request.SortBy)
if err := hecate.IngestAllSubreddit(r.Context(), db, request.SortBy); err != nil {
log.Printf("Failed to ingest all subreddits: %v", err)
respondWithError(w, statusIntError, fmt.Sprintf("Failed to ingest all subreddits: %v", err))
return
}
log.Println("Successfully ingested all subreddits")
respondWithJson(w, statusOK, map[string]string{"status": "success"})
}
}
// subredditGetHandler handles retrieving all subreddits
func subredditGetHandler(db *database.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
log.Println("Retrieving all subreddits")
subreddits, err := hecate.GetAllSubreddits(db)
if err != nil {
log.Printf("Failed to retrieve subreddits: %v", err)
respondWithError(w, statusIntError, fmt.Sprintf("Failed to retrieve subreddits: %v", err))
return
}
log.Printf("Retrieved %d subreddits", len(subreddits))
respondWithJson(w, statusOK, subreddits)
}
}
// subredditPostsGetHandler handles retrieving posts for a specific subreddit
func subredditPostsGetHandler(db *database.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
subredditName := chi.URLParam(r, "subredditName")
log.Printf("Retrieving posts for subreddit: %s", subredditName)
posts, err := hecate.GetAllPostsForSubreddit(db, subredditName)
if err != nil {
log.Printf("Failed to retrieve posts for subreddit %s: %v", subredditName, err)
respondWithError(w, statusIntError, fmt.Sprintf("Failed to retrieve posts: %v", err))
return
}
log.Printf("Retrieved %d posts for subreddit: %s", len(posts), subredditName)
respondWithJson(w, statusOK, posts)
}
}
// searchPostsHandler handles searching posts across all subreddits
func searchPostsHandler(db *database.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
if query == "" {
respondWithError(w, statusBadReq, "Search query is required")
return
}
log.Printf("Searching posts with query: %s", query)
posts, err := db.SearchPosts(query)
if err != nil {
log.Printf("Failed to search posts: %v", err)
respondWithError(w, statusIntError, fmt.Sprintf("Failed to search posts: %v", err))
return
}
response := hecate.SearchPostsResponse{
Posts: make([]hecate.SubredditPostFrontendResponse, len(posts)),
}
for i, post := range posts {
response.Posts[i] = hecate.SubredditPostFrontendResponse{
Title: post.Title,
Content: post.Content,
DiscussionURL: post.DiscussionURL,
CommentCount: post.CommentCount,
Upvotes: post.Upvotes,
SubredditName: post.SubredditName,
}
}
log.Printf("Found %d posts matching query: %s", len(posts), query)
respondWithJson(w, statusOK, response)
}
}
// decodeJSONBody decodes the JSON body of a request into a given struct
func decodeJSONBody(w http.ResponseWriter, r *http.Request, v interface{}) error {
if r.Body == nil {
return fmt.Errorf("request body is empty")
}
defer r.Body.Close()
if err := json.NewDecoder(r.Body).Decode(v); err != nil {
respondWithError(w, statusBadReq, fmt.Sprintf("Invalid request body: %v", err))
return fmt.Errorf("failed to decode JSON body: %w", err)
}
return nil
}