async get requests
This commit is contained in:
parent
5e6f81a527
commit
f477cc7fdd
90
api.go
90
api.go
@ -2,6 +2,7 @@ package request
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -16,12 +17,47 @@ func url(path string) string {
|
|||||||
return string("https://forum.0cd.xyz/" + path)
|
return string("https://forum.0cd.xyz/" + path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTPResp Async HTTP Request
|
||||||
|
type HTTPResp struct {
|
||||||
|
ID int
|
||||||
|
Resp []byte
|
||||||
|
Err logger.HTTPError
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsyncGet sends Async GET requests
|
||||||
|
func AsyncGet(urls map[int]string) ([]*HTTPResp, *logger.HTTPError) {
|
||||||
|
ch := make(chan *HTTPResp)
|
||||||
|
response := []*HTTPResp{}
|
||||||
|
|
||||||
|
for id, url := range urls {
|
||||||
|
go func(i int, u string) {
|
||||||
|
resp, err := Request("t/" + u)
|
||||||
|
err = logger.HTTPErr(http.StatusOK)
|
||||||
|
ch <- &HTTPResp{i, resp, *err}
|
||||||
|
}(id, url)
|
||||||
|
}
|
||||||
|
loop:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case r := <-ch:
|
||||||
|
response = append(response, r)
|
||||||
|
if len(response) == len(urls) {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
case <-time.After(120 * time.Millisecond):
|
||||||
|
fmt.Printf(".")
|
||||||
|
//return nil, logger.HTTPErr(http.StatusRequestTimeout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Request sends GET to path
|
// Request sends GET to path
|
||||||
func Request(path string) ([]byte, *logger.HTTPError) {
|
func Request(path string) ([]byte, *logger.HTTPError) {
|
||||||
req, err := http.NewRequest("GET", url(path), nil)
|
req, err := http.NewRequest("GET", url(path), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorLog("Error reading request. ", err)
|
logger.ErrorLog("Error reading request. ", err)
|
||||||
return nil, &logger.HTTPError{Status: "500 Internal Server Error", StatusCode: http.StatusInternalServerError}
|
return nil, logger.HTTPErr(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
head, er := Header()
|
head, er := Header()
|
||||||
@ -36,12 +72,14 @@ func Request(path string) ([]byte, *logger.HTTPError) {
|
|||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorLog("Error reading request. ", err)
|
logger.ErrorLog("Error reading request. ", err)
|
||||||
return nil, &logger.HTTPError{Status: "500 Internal Server Error", StatusCode: http.StatusInternalServerError}
|
fmt.Println(err)
|
||||||
|
return nil, logger.HTTPErr(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorLog("Error reading request. ", err)
|
logger.ErrorLog("Error reading request. ", err)
|
||||||
return nil, &logger.HTTPError{Status: "500 Internal Server Error", StatusCode: http.StatusInternalServerError}
|
fmt.Println(err)
|
||||||
|
return nil, logger.HTTPErr(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
@ -49,7 +87,7 @@ func Request(path string) ([]byte, *logger.HTTPError) {
|
|||||||
return body, nil
|
return body, nil
|
||||||
}
|
}
|
||||||
logger.GetLog("GET %d %s\n", resp.StatusCode, html.EscapeString(url(path)))
|
logger.GetLog("GET %d %s\n", resp.StatusCode, html.EscapeString(url(path)))
|
||||||
return nil, &logger.HTTPError{Status: resp.Status, StatusCode: resp.StatusCode}
|
return nil, logger.HTTPErr(resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Category returns category json data
|
// Category returns category json data
|
||||||
@ -101,6 +139,50 @@ func GetTopics(path string) (topics TagTopics, err *logger.HTTPError) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTopics2 gets topic list from tag
|
||||||
|
func GetTopics2(path string) (m map[int]string) {
|
||||||
|
resp, err := Request("tags/" + path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var topics TagTopics
|
||||||
|
json.Unmarshal(resp, &topics)
|
||||||
|
m = make(map[int]string)
|
||||||
|
for _, topics := range topics.TopicList.Topics {
|
||||||
|
m[topics.ID] = topics.Slug
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsyncTopics request for topics using async
|
||||||
|
func AsyncTopics(path string) map[string]interface{} {
|
||||||
|
var topic TopicsList
|
||||||
|
resp, err := AsyncGet(GetTopics2(path))
|
||||||
|
if err != nil {
|
||||||
|
m := structs.Map(err)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
for _, topics := range resp {
|
||||||
|
var t Topic
|
||||||
|
json.Unmarshal(topics.Resp, &t)
|
||||||
|
for i := 0; i < len(t.PostStream.Posts); i++ {
|
||||||
|
if t.PostStream.Posts[i].PostNumber != 1 {
|
||||||
|
t.PostStream.Posts[i].Cooked = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Details.CreatedBy.AvatarTemplate = strings.ReplaceAll(t.Details.CreatedBy.AvatarTemplate, "{size}", "120")
|
||||||
|
s := strings.SplitAfter(t.PostStream.Posts[0].Cooked, "</p>")
|
||||||
|
t.PostStream.Posts[0].Cooked = s[0]
|
||||||
|
r := strings.ReplaceAll(t.PostStream.Posts[0].Cooked, "href=\"/u/", "href=\""+url("")+"u/")
|
||||||
|
t.PostStream.Posts[0].Cooked = r
|
||||||
|
ts, _ := time.Parse("2006-01-02T15:04:05Z07:00", t.CreatedAt)
|
||||||
|
t.CreatedAt = ts.Format("January 2, 2006")
|
||||||
|
topic.Topic = append(topic.Topic, t)
|
||||||
|
}
|
||||||
|
m := structs.Map(topic)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
// Topics n/a
|
// Topics n/a
|
||||||
func Topics(path string) map[string]interface{} {
|
func Topics(path string) map[string]interface{} {
|
||||||
var topic TopicsList
|
var topic TopicsList
|
||||||
|
67
data.go
67
data.go
@ -25,6 +25,12 @@ type Options struct {
|
|||||||
BaseDir string `json:"BaseDir"`
|
BaseDir string `json:"BaseDir"`
|
||||||
} `json:"ace"`
|
} `json:"ace"`
|
||||||
} `json:"options"`
|
} `json:"options"`
|
||||||
|
Database struct {
|
||||||
|
Server string `json:"server"`
|
||||||
|
DB string `json:"db"`
|
||||||
|
User string `json:"user"`
|
||||||
|
Passwd string `json:"passwd"`
|
||||||
|
} `json:"database"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contacts lists contact information
|
// Contacts lists contact information
|
||||||
@ -48,9 +54,66 @@ type Tags struct {
|
|||||||
|
|
||||||
// TagTopics list of topics via tag
|
// TagTopics list of topics via tag
|
||||||
type TagTopics struct {
|
type TagTopics struct {
|
||||||
TopicList struct {
|
Users []struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
AvatarTemplate string `json:"avatar_template"`
|
||||||
|
} `json:"users"`
|
||||||
|
PrimaryGroups []interface{} `json:"primary_groups"`
|
||||||
|
TopicList struct {
|
||||||
|
CanCreateTopic bool `json:"can_create_topic"`
|
||||||
|
Draft interface{} `json:"draft"`
|
||||||
|
DraftKey string `json:"draft_key"`
|
||||||
|
DraftSequence int `json:"draft_sequence"`
|
||||||
|
PerPage int `json:"per_page"`
|
||||||
|
TopTags []string `json:"top_tags"`
|
||||||
|
Tags []struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
TopicCount int `json:"topic_count"`
|
||||||
|
Staff bool `json:"staff"`
|
||||||
|
} `json:"tags"`
|
||||||
Topics []struct {
|
Topics []struct {
|
||||||
Slug string `json:"slug"`
|
ID int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
FancyTitle string `json:"fancy_title"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
PostsCount int `json:"posts_count"`
|
||||||
|
ReplyCount int `json:"reply_count"`
|
||||||
|
HighestPostNumber int `json:"highest_post_number"`
|
||||||
|
ImageURL string `json:"image_url"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
LastPostedAt time.Time `json:"last_posted_at"`
|
||||||
|
Bumped bool `json:"bumped"`
|
||||||
|
BumpedAt time.Time `json:"bumped_at"`
|
||||||
|
Unseen bool `json:"unseen"`
|
||||||
|
LastReadPostNumber int `json:"last_read_post_number"`
|
||||||
|
Unread int `json:"unread"`
|
||||||
|
NewPosts int `json:"new_posts"`
|
||||||
|
Pinned bool `json:"pinned"`
|
||||||
|
Unpinned interface{} `json:"unpinned"`
|
||||||
|
Visible bool `json:"visible"`
|
||||||
|
Closed bool `json:"closed"`
|
||||||
|
Archived bool `json:"archived"`
|
||||||
|
NotificationLevel int `json:"notification_level"`
|
||||||
|
Bookmarked bool `json:"bookmarked"`
|
||||||
|
Liked bool `json:"liked"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Views int `json:"views"`
|
||||||
|
LikeCount int `json:"like_count"`
|
||||||
|
HasSummary bool `json:"has_summary"`
|
||||||
|
Archetype string `json:"archetype"`
|
||||||
|
LastPosterUsername string `json:"last_poster_username"`
|
||||||
|
CategoryID int `json:"category_id"`
|
||||||
|
PinnedGlobally bool `json:"pinned_globally"`
|
||||||
|
FeaturedLink interface{} `json:"featured_link"`
|
||||||
|
Posters []struct {
|
||||||
|
Extras string `json:"extras"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
PrimaryGroupID interface{} `json:"primary_group_id"`
|
||||||
|
} `json:"posters"`
|
||||||
} `json:"topics"`
|
} `json:"topics"`
|
||||||
} `json:"topic_list"`
|
} `json:"topic_list"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user