-
Notifications
You must be signed in to change notification settings - Fork 1
/
getQuestionInfo.go
111 lines (94 loc) · 3.42 KB
/
getQuestionInfo.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
package helpers
import (
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
)
type QuestionOwner struct {
AccountID int `json:"account_id"`
Reputation int `json:"reputation"`
UserID int `json:"user_id"`
UserType string `json:"user_type"`
AcceptRate int `json:"accept_rate"`
ProfileImage string `json:"profile_image"`
DisplayName string `json:"display_name"`
Link string `json:"link"`
}
type QuestionItems struct {
Tags []string `json:"tags"`
Owner QuestionOwner `json:"owner"`
IsAnswered bool `json:"is_answered"`
ViewCount int `json:"view_count"`
ProtectedDate int `json:"protected_date"`
AcceptedAnswerID int `json:"accepted_answer_id"`
AnswerCount int `json:"answer_count"`
CommunityOwnedDate int `json:"community_owned_date"`
Score int `json:"score"`
LockedDate int `json:"locked_date"`
LastActivityDate int `json:"last_activity_date"`
CreationDate int `json:"creation_date"`
LastEditDate int `json:"last_edit_date"`
QuestionID int `json:"question_id"`
ContentLicense string `json:"content_license"`
Link string `json:"link"`
Title string `json:"title"`
}
type QuestionResponse struct {
Items []QuestionItems `json:"items"`
HasMore bool `json:"has_more"`
QuotaMax int `json:"quota_max"`
QuotaRemaining int `json:"quota_remaining"`
}
type CleanQuestion struct {
Title string
Question string
Answer string
Tags []string
}
func parseSEURL(url string) (string, string, error) {
regex, err := regexp.Compile(`.*(askubuntu|serverfault|stackoverflow|superuser)\.com/questions/([^/]+)/([^/]+)`)
if err != nil {
return "", "", fmt.Errorf("[parseSEURL][regexp.Compile]: %w", err)
}
matches := regex.FindStringSubmatch(url)
if len(matches) == 3 {
return matches[1], matches[2], nil
}
return "", "", fmt.Errorf("[parseSEURL]: No matches found%w", nil)
}
// DOCS: https://api.stackexchange.com/docs/questions-by-ids#order=desc&sort=activity&ids=34230208&filter=default&site=stackoverflow&run=true
func GetQuestionInfo(url string) (CleanQuestion, error) {
site, id, err := parseSEURL(url)
if err != nil {
return CleanQuestion{}, fmt.Errorf("[GetQuestionInfo]%w", err)
}
queryURL := fmt.Sprintf("https://api.stackexchange.com/2.3/questions/%s?order=desc&sort=activity&site=%s", id, site)
resp, err := http.Get(queryURL)
if err != nil {
return CleanQuestion{}, fmt.Errorf("[GetQuestionInfo][http.NewRequest]: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return CleanQuestion{}, fmt.Errorf("[GetQuestionInfo][io.ReadAll]: %w", err)
}
var questionResponse QuestionResponse
err = json.Unmarshal(body, &questionResponse)
if err != nil {
return CleanQuestion{}, fmt.Errorf("[GetQuestionInfo][json.Unmarshal]: %w", err)
}
questionItem := questionResponse.Items[0]
question := fmt.Sprintf("https://%s.com/q/%d", site, questionItem.QuestionID)
answer := ""
if questionItem.IsAnswered {
answer = fmt.Sprintf("https://%s.com/a/%d", site, questionItem.AcceptedAnswerID)
}
return CleanQuestion{
Title: questionItem.Title,
Question: question,
Answer: answer,
Tags: questionItem.Tags,
}, nil
}