snappy/pkg/items.go

340 lines
6.6 KiB
Go
Raw Normal View History

package sn
import (
"encoding/json"
"fmt"
"time"
)
type Item struct {
Id int `json:"id,string"`
ParentId int `json:"parentId,string"`
Title string `json:"title"`
Url string `json:"url"`
Sats int `json:"sats"`
CreatedAt time.Time `json:"createdAt"`
Comments []Comment `json:"comments"`
NComments int `json:"ncomments"`
User User `json:"user"`
}
type Comment struct {
Id int `json:"id,string"`
ParentId int `json:"parentId,string"`
CreatedAt time.Time `json:"createdAt"`
Text string `json:"text"`
User User `json:"user"`
Comments []Comment `json:"comments"`
}
type ItemsQuery struct {
Sub string
Sort string
Type string
Cursor string
Name string
When string
By string
Limit int
}
type ItemsCursor struct {
Items []Item `json:"items"`
Cursor string `json:"cursor"`
}
type ItemsResponse struct {
Errors []GqlError `json:"errors"`
Data struct {
Items ItemsCursor `json:"items"`
} `json:"data"`
}
type UpsertDiscussionResponse struct {
Errors []GqlError `json:"errors"`
Data struct {
UpsertDiscussion Item `json:"upsertDiscussion"`
} `json:"data"`
}
type UpsertLinkResponse struct {
Errors []GqlError `json:"errors"`
Data struct {
UpsertLink Item `json:"upsertLink"`
} `json:"data"`
}
type CreateCommentsResponse struct {
Errors []GqlError `json:"errors"`
Data struct {
CreateComment Comment `json:"createComment"`
} `json:"data"`
}
type Dupe struct {
Id int `json:"id,string"`
Url string `json:"url"`
Title string `json:"title"`
User User `json:"user"`
CreatedAt time.Time `json:"createdAt"`
Sats int `json:"sats"`
NComments int `json:"ncomments"`
}
type DupesResponse struct {
Errors []GqlError `json:"errors"`
Data struct {
Dupes []Dupe `json:"dupes"`
} `json:"data"`
}
type DupesError struct {
Url string
Dupes []Dupe
}
func (c *Client) Items(query *ItemsQuery) (*ItemsCursor, error) {
if query == nil {
query = &ItemsQuery{}
}
body := GqlBody{
Query: `
query items($sub: String, $sort: String, $cursor: String, $type: String, $name: String, $when: String, $by: String, $limit: Limit) {
items(sub: $sub, sort: $sort, cursor: $cursor, type: $type, name: $name, when: $when, by: $by, limit: $limit) {
cursor
items {
id
parentId
createdAt
deletedAt
title
url
user {
id
name
}
otsHash
position
sats
boost
bounty
bountyPaidTo
path
upvotes
meSats
meDontLikeSats
meBookmark
meSubscription
outlawed
freebie
ncomments
commentSats
lastCommentAt
maxBid
isJob
company
location
remote
subName
pollCost
status
uploadId
mine
position
},
}
}`,
Variables: map[string]interface{}{
"sub": query.Sub,
"sort": query.Sort,
"type": query.Type,
"cursor": query.Cursor,
"name": query.Name,
"when": query.When,
"by": query.By,
"limit": query.Limit,
},
}
if query.Limit == 0 {
body.Variables["limit"] = 21
}
resp, err := c.callApi(body)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var respBody ItemsResponse
err = json.NewDecoder(resp.Body).Decode(&respBody)
if err != nil {
err = fmt.Errorf("error decoding items: %w", err)
return nil, err
}
err = c.checkForErrors(respBody.Errors)
if err != nil {
return nil, err
}
return &respBody.Data.Items, nil
}
func (c *Client) PostDiscussion(title string, text string, sub string) (int, error) {
body := GqlBody{
Query: `
mutation upsertDiscussion($title: String!, $text: String, $sub: String) {
upsertDiscussion(title: $title, text: $text, sub: $sub) {
id
}
}`,
Variables: map[string]interface{}{
"title": title,
"text": text,
"sub": sub,
},
}
resp, err := c.callApi(body)
if err != nil {
return -1, err
}
defer resp.Body.Close()
var respBody UpsertDiscussionResponse
err = json.NewDecoder(resp.Body).Decode(&respBody)
if err != nil {
err = fmt.Errorf("error decoding upsertDiscussion: %w", err)
return -1, err
}
err = c.checkForErrors(respBody.Errors)
if err != nil {
return -1, err
}
return respBody.Data.UpsertDiscussion.Id, nil
}
func (c *Client) PostLink(url string, title string, text string, sub string) (int, error) {
body := GqlBody{
Query: `
mutation upsertLink($url: String!, $title: String!, $text: String, $sub: String!) {
upsertLink(url: $url, title: $title, text: $text, sub: $sub) {
id
}
}`,
Variables: map[string]interface{}{
"url": url,
"title": title,
"text": text,
"sub": sub,
},
}
resp, err := c.callApi(body)
if err != nil {
return -1, err
}
defer resp.Body.Close()
var respBody UpsertLinkResponse
err = json.NewDecoder(resp.Body).Decode(&respBody)
if err != nil {
err = fmt.Errorf("error decoding upsertLink: %w", err)
return -1, err
}
err = c.checkForErrors(respBody.Errors)
if err != nil {
return -1, err
}
return respBody.Data.UpsertLink.Id, nil
}
func (c *Client) CreateComment(parentId int, text string) (int, error) {
body := GqlBody{
Query: `
mutation upsertComment($parentId: ID!, $text: String!) {
upsertComment(parentId: $parentId, text: $text) {
id
}
}`,
Variables: map[string]interface{}{
"parentId": parentId,
"text": text,
},
}
resp, err := c.callApi(body)
if err != nil {
return -1, err
}
defer resp.Body.Close()
var respBody CreateCommentsResponse
err = json.NewDecoder(resp.Body).Decode(&respBody)
if err != nil {
err = fmt.Errorf("error decoding upsertComment: %w", err)
return -1, err
}
err = c.checkForErrors(respBody.Errors)
if err != nil {
return -1, err
}
return respBody.Data.CreateComment.Id, nil
}
func (c *Client) Dupes(url string) (*[]Dupe, error) {
body := GqlBody{
Query: `
query Dupes($url: String!) {
dupes(url: $url) {
id
url
title
user {
name
}
createdAt
sats
ncomments
}
}`,
Variables: map[string]interface{}{
"url": url,
},
}
resp, err := c.callApi(body)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var respBody DupesResponse
err = json.NewDecoder(resp.Body).Decode(&respBody)
if err != nil {
err = fmt.Errorf("error decoding dupes: %w", err)
return nil, err
}
err = c.checkForErrors(respBody.Errors)
if err != nil {
return nil, err
}
return &respBody.Data.Dupes, nil
}
func (c *Client) HasDupes(url string) (bool, error) {
dupes, err := c.Dupes(url)
if err != nil {
return false, err
}
return len(*dupes) > 0, nil
}