From 5418bc64792825e7e5dc6262074cfbcc0e54bc5e Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Fri, 18 Nov 2022 22:41:18 +1100 Subject: [PATCH] Catalogs, threads, parse json array response of threads (For catalog), ahndle scuffed time format for bumped/date/edited --- app/board.go | 36 ++++++++++++++++++++++++++++++++++++ app/jschan.go | 13 +++++++++++-- app/models/post.go | 20 +++++++++++++++----- app/thread.go | 37 +++++++++++++++++++++++++++++++++++++ example.go | 20 +++++++++++++------- 5 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 app/board.go create mode 100644 app/thread.go diff --git a/app/board.go b/app/board.go new file mode 100644 index 0000000..11f45e9 --- /dev/null +++ b/app/board.go @@ -0,0 +1,36 @@ +package jschan + +import ( + "context" + "fmt" + "jschan/app/models" + "net/http" +) + +type GetCatalogOptions struct { + Board string +} + +type CatalogResponse []models.Post + +func (c *Client) GetCatalog(ctx context.Context, options *GetCatalogOptions) (CatalogResponse, error) { + + url := fmt.Sprintf("%s/%s/catalog.json", c.BaseURL, options.Board) + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return nil, err + } + + req = req.WithContext(ctx) + + res := CatalogResponse{} + if err := c.sendRequest(req, &res, nil); err != nil { + return nil, err + } + + return res, nil + +} + +//TODO: GetIndex, GetLogs, etc diff --git a/app/jschan.go b/app/jschan.go index 28e3e78..1099846 100644 --- a/app/jschan.go +++ b/app/jschan.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" "net/http" "time" ) @@ -92,8 +93,16 @@ func (c *Client) sendRequest(req *http.Request, v interface{}, h *ReturnHeaders) if v != nil { fullResponse := v - if err = json.NewDecoder(res.Body).Decode(&fullResponse); err != nil { - return err + err := json.NewDecoder(res.Body).Decode(&fullResponse) + if err != nil { + body, err2 := ioutil.ReadAll(res.Body) + if err2 != nil { + return err + } + err3 := json.Unmarshal(body, &fullResponse) + if err3 != nil { + return err + } } } diff --git a/app/models/post.go b/app/models/post.go index 8412636..47ce82b 100644 --- a/app/models/post.go +++ b/app/models/post.go @@ -1,12 +1,22 @@ package models import ( + "encoding/json" "time" ) +type ScuffedTime time.Time + +func (m *ScuffedTime) UnmarshalJSON(data []byte) error { + if string(data) == "null" || string(data) == `""` || string(data) == "0" { + return nil + } + return json.Unmarshal(data, (*time.Time)(m)) +} + type Post struct { ID string `json:"_id"` - Date time.Time `json:"date"` + Date ScuffedTime `json:"date"` U int64 `json:"u"` Name string `json:"name"` Country interface{} `json:"country"` @@ -32,9 +42,9 @@ type Post struct { Locked int `json:"locked"` Bumplocked int `json:"bumplocked"` Cyclic int `json:"cyclic"` - Bumped time.Time `json:"bumped"` + Bumped ScuffedTime `json:"bumped,omitempty"` PostID int `json:"postId"` - Replies []Post `json:"replies"` + Replies []Post `json:"replies,omitempty"` Previewbacklinks []interface{} `json:"previewbacklinks,omitempty"` Omittedfiles int `json:"omittedfiles,omitempty"` Omittedposts int `json:"omittedposts,omitempty"` @@ -82,6 +92,6 @@ type Backlinks struct { } type Edited struct { - Username string `json:"username"` - Date time.Time `json:"date"` + Username string `json:"username"` + Date ScuffedTime `json:"date"` } diff --git a/app/thread.go b/app/thread.go new file mode 100644 index 0000000..61c59cc --- /dev/null +++ b/app/thread.go @@ -0,0 +1,37 @@ +package jschan + +import ( + "context" + "fmt" + "jschan/app/models" + "net/http" +) + +type GetThreadOptions struct { + Board string + ThreadId int +} + +type GetThreadResponse struct { + *models.Post +} + +func (c *Client) GetThread(ctx context.Context, options *GetThreadOptions) (*GetThreadResponse, error) { + + url := fmt.Sprintf("%s/%s/thread/%d.json", c.BaseURL, options.Board, options.ThreadId) + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return nil, err + } + + req = req.WithContext(ctx) + + res := GetThreadResponse{} + if err := c.sendRequest(req, &res, nil); err != nil { + return nil, err + } + + return &res, nil + +} diff --git a/example.go b/example.go index ba0f7c4..487a8a9 100644 --- a/example.go +++ b/example.go @@ -19,7 +19,10 @@ func main() { err := jschanClient.Login(ctx, loginOptions) if err != nil { fmt.Println(err) - return + //return + } + if jschanClient.SessionCookie != "" { + fmt.Printf("Logged in as user %s\n", loginOptions.Username) } overboardOptions := &jschan.GetOverboardOptions{ @@ -30,14 +33,17 @@ func main() { fmt.Println(err) return } + fmt.Printf("Fetched overboard catalog with %d threads\n", len(res.Threads)) - if len(res.Threads) > 0 { - firstThread := res.Threads[0] - fmt.Printf("Name = %s\n", firstThread.Name) - fmt.Printf("Message = %s\n", firstThread.Nomarkup) - } else { - fmt.Println("No threads") + getCatalogOptions := &jschan.GetCatalogOptions{ + Board: "t", + } + res2, err2 := jschanClient.GetCatalog(ctx, getCatalogOptions) + if err2 != nil { + fmt.Println(err2) + return } + fmt.Printf("Fetched board %s catalog with %d threads\n", getCatalogOptions.Board, len(res2)) return }