mirror of
https://github.com/taigrr/wtf
synced 2026-03-26 22:32:18 -07:00
210
vendor/github.com/VictorAvelar/devto-api-go/devto/articles.go
generated
vendored
210
vendor/github.com/VictorAvelar/devto-api-go/devto/articles.go
generated
vendored
@@ -4,102 +4,224 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
//ArticlesResource implements the APIResource interface
|
||||
//for devto articles.
|
||||
// ArticlesResource implements the APIResource interface
|
||||
// for devto articles.
|
||||
type ArticlesResource struct {
|
||||
API *Client
|
||||
}
|
||||
|
||||
//List will return the articles uploaded to devto, the result
|
||||
//can be narrowed down, filtered or enhanced using query
|
||||
// List will return the articles uploaded to devto, the result
|
||||
// can be narrowed down, filtered or enhanced using query
|
||||
// parameters as specified on the documentation.
|
||||
//See: https://docs.dev.to/api/#tag/articles/paths/~1articles/get
|
||||
func (ar *ArticlesResource) List(ctx context.Context, opt ArticleListOptions) ([]Article, error) {
|
||||
var l []Article
|
||||
// See: https://docs.dev.to/api/#tag/articles/paths/~1articles/get
|
||||
func (ar *ArticlesResource) List(ctx context.Context, opt ArticleListOptions) ([]ListedArticle, error) {
|
||||
q, err := query.Values(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, _ := ar.API.NewRequest(http.MethodGet, fmt.Sprintf("api/articles?%s", q.Encode()), nil)
|
||||
res, _ := ar.API.HTTPClient.Do(req)
|
||||
cont, err := ioutil.ReadAll(res.Body)
|
||||
req, err := ar.API.NewRequest(http.MethodGet, fmt.Sprintf("api/articles?%s", q.Encode()), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
json.Unmarshal(cont, &l)
|
||||
return l, nil
|
||||
}
|
||||
|
||||
//Find will retrieve an Article matching the ID passed.
|
||||
func (ar *ArticlesResource) Find(ctx context.Context, id uint32) (Article, error) {
|
||||
var art Article
|
||||
req, _ := ar.API.NewRequest(http.MethodGet, fmt.Sprintf("api/articles/%d", id), nil)
|
||||
res, err := ar.API.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return art, err
|
||||
return nil, err
|
||||
}
|
||||
cont, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
|
||||
if nonSuccessfulResponse(res) {
|
||||
return nil, unmarshalErrorResponse(res)
|
||||
}
|
||||
var articles []ListedArticle
|
||||
if err := json.NewDecoder(res.Body).Decode(&articles); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
// ListForTag is a convenience method for retrieving articles
|
||||
// for a particular tag, calling the base List method.
|
||||
func (ar *ArticlesResource) ListForTag(ctx context.Context, tag string, page int) ([]ListedArticle, error) {
|
||||
return ar.List(ctx, ArticleListOptions{Tags: tag, Page: page})
|
||||
}
|
||||
|
||||
// ListForUser is a convenience method for retrieving articles
|
||||
// written by a particular user, calling the base List method.
|
||||
func (ar *ArticlesResource) ListForUser(ctx context.Context, username string, page int) ([]ListedArticle, error) {
|
||||
return ar.List(ctx, ArticleListOptions{Username: username, Page: page})
|
||||
}
|
||||
|
||||
// ListMyPublishedArticles lists all published articles
|
||||
// written by the user authenticated with this client,
|
||||
// erroring if the caller is not authenticated. Articles in
|
||||
// the response will be listed in reverse chronological order
|
||||
// by their publication times.
|
||||
//
|
||||
// If opts is nil, then no query parameters will be sent; the
|
||||
// page number will be 1 and the page size will be 30
|
||||
// articles.
|
||||
func (ar *ArticlesResource) ListMyPublishedArticles(ctx context.Context, opts *MyArticlesOptions) ([]ListedArticle, error) {
|
||||
return ar.listMyArticles(ctx, "api/articles/me/published", opts)
|
||||
}
|
||||
|
||||
// ListMyUnpublishedArticles lists all unpublished articles
|
||||
// written by the user authenticated with this client,
|
||||
// erroring if the caller is not authenticated. Articles in
|
||||
// the response will be listed in reverse chronological order
|
||||
// by their creation times.
|
||||
//
|
||||
// If opts is nil, then no query parameters will be sent; the
|
||||
// page number will be 1 and the page size will be 30
|
||||
// articles.
|
||||
func (ar *ArticlesResource) ListMyUnpublishedArticles(ctx context.Context, opts *MyArticlesOptions) ([]ListedArticle, error) {
|
||||
return ar.listMyArticles(ctx, "api/articles/me/unpublished", opts)
|
||||
}
|
||||
|
||||
// ListAllMyArticles lists all articles written by the user
|
||||
// authenticated with this client, erroring if the caller is
|
||||
// not authenticated. Articles in the response will be listed
|
||||
// in reverse chronological order by their creation times,
|
||||
// with unpublished articles listed before published articles.
|
||||
//
|
||||
// If opts is nil, then no query parameters will be sent; the
|
||||
// page number will be 1 and the page size will be 30
|
||||
// articles.
|
||||
func (ar *ArticlesResource) ListAllMyArticles(ctx context.Context, opts *MyArticlesOptions) ([]ListedArticle, error) {
|
||||
return ar.listMyArticles(ctx, "api/articles/me/all", opts)
|
||||
}
|
||||
|
||||
// listMyArticles serves for handling roundtrips to the
|
||||
// /api/articles/me/* endpoints, requesting articles from the
|
||||
// endpoint passed in, and returning a list of articles.
|
||||
func (ar *ArticlesResource) listMyArticles(
|
||||
ctx context.Context,
|
||||
endpoint string,
|
||||
opts *MyArticlesOptions,
|
||||
) ([]ListedArticle, error) {
|
||||
if ar.API.Config.InsecureOnly {
|
||||
return nil, ErrProtectedEndpoint
|
||||
}
|
||||
|
||||
req, err := ar.API.NewRequest(http.MethodGet, endpoint, nil)
|
||||
if err != nil {
|
||||
return art, err
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add(APIKeyHeader, ar.API.Config.APIKey)
|
||||
|
||||
if opts != nil {
|
||||
q, err := query.Values(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
res, err := ar.API.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if nonSuccessfulResponse(res) {
|
||||
return nil, unmarshalErrorResponse(res)
|
||||
}
|
||||
var articles []ListedArticle
|
||||
if err := json.NewDecoder(res.Body).Decode(&articles); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
// Find will retrieve an Article matching the ID passed.
|
||||
func (ar *ArticlesResource) Find(ctx context.Context, id uint32) (Article, error) {
|
||||
req, err := ar.API.NewRequest(http.MethodGet, fmt.Sprintf("api/articles/%d", id), nil)
|
||||
if err != nil {
|
||||
return Article{}, err
|
||||
}
|
||||
|
||||
res, err := ar.API.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return Article{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if nonSuccessfulResponse(res) {
|
||||
return Article{}, unmarshalErrorResponse(res)
|
||||
}
|
||||
var art Article
|
||||
if err := json.NewDecoder(res.Body).Decode(&art); err != nil {
|
||||
return Article{}, err
|
||||
}
|
||||
json.Unmarshal(cont, &art)
|
||||
return art, nil
|
||||
}
|
||||
|
||||
//New will create a new article on dev.to
|
||||
func (ar *ArticlesResource) New(ctx context.Context, a Article) (Article, error) {
|
||||
// New will create a new article on dev.to
|
||||
func (ar *ArticlesResource) New(ctx context.Context, u ArticleUpdate) (Article, error) {
|
||||
if ar.API.Config.InsecureOnly {
|
||||
return a, ErrProtectedEndpoint
|
||||
return Article{}, ErrProtectedEndpoint
|
||||
}
|
||||
cont, err := json.Marshal(a)
|
||||
cont, err := json.Marshal(&u)
|
||||
if err != nil {
|
||||
return a, err
|
||||
return Article{}, err
|
||||
}
|
||||
req, err := ar.API.NewRequest(http.MethodPost, "api/articles", strings.NewReader(string(cont)))
|
||||
if err != nil {
|
||||
return a, err
|
||||
return Article{}, err
|
||||
}
|
||||
req.Header.Add(APIKeyHeader, ar.API.Config.APIKey)
|
||||
res, err := ar.API.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return a, err
|
||||
return Article{}, err
|
||||
}
|
||||
content, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return a, err
|
||||
defer res.Body.Close()
|
||||
|
||||
if nonSuccessfulResponse(res) {
|
||||
return Article{}, unmarshalErrorResponse(res)
|
||||
}
|
||||
|
||||
var a Article
|
||||
if err := json.NewDecoder(res.Body).Decode(&a); err != nil {
|
||||
return Article{}, err
|
||||
}
|
||||
json.Unmarshal(content, &a)
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (ar *ArticlesResource) Update(ctx context.Context, a Article) (Article, error) {
|
||||
// Update will mutate the resource by id, and all the changes
|
||||
// performed to the Article will be applied, thus validation
|
||||
// on the API side.
|
||||
func (ar *ArticlesResource) Update(ctx context.Context, u ArticleUpdate, id uint32) (Article, error) {
|
||||
if ar.API.Config.InsecureOnly {
|
||||
return a, ErrProtectedEndpoint
|
||||
return Article{}, ErrProtectedEndpoint
|
||||
}
|
||||
cont, err := json.Marshal(a)
|
||||
cont, err := json.Marshal(&u)
|
||||
if err != nil {
|
||||
return a, err
|
||||
return Article{}, err
|
||||
}
|
||||
req, err := ar.API.NewRequest(http.MethodPut, fmt.Sprintf("api/articles/%d", a.ID), strings.NewReader(string(cont)))
|
||||
req, err := ar.API.NewRequest(http.MethodPut, fmt.Sprintf("api/articles/%d", id), strings.NewReader(string(cont)))
|
||||
if err != nil {
|
||||
return a, err
|
||||
return Article{}, err
|
||||
}
|
||||
req.Header.Add(APIKeyHeader, ar.API.Config.APIKey)
|
||||
res, err := ar.API.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return a, err
|
||||
return Article{}, err
|
||||
}
|
||||
content, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return a, err
|
||||
defer res.Body.Close()
|
||||
|
||||
if nonSuccessfulResponse(res) {
|
||||
return Article{}, unmarshalErrorResponse(res)
|
||||
}
|
||||
|
||||
var a Article
|
||||
if err := json.NewDecoder(res.Body).Decode(&a); err != nil {
|
||||
return Article{}, err
|
||||
}
|
||||
json.Unmarshal(content, &a)
|
||||
return a, nil
|
||||
}
|
||||
|
||||
16
vendor/github.com/VictorAvelar/devto-api-go/devto/config.go
generated
vendored
16
vendor/github.com/VictorAvelar/devto-api-go/devto/config.go
generated
vendored
@@ -2,25 +2,25 @@ package devto
|
||||
|
||||
import "errors"
|
||||
|
||||
//Confugration errors
|
||||
// Configuration errors
|
||||
var (
|
||||
ErrMissingRequiredParameter = errors.New("a required parameter is missing")
|
||||
)
|
||||
|
||||
//Config contains the elements required to initialize a
|
||||
// Config contains the elements required to initialize a
|
||||
// devto client.
|
||||
type Config struct {
|
||||
APIKey string
|
||||
InsecureOnly bool
|
||||
}
|
||||
|
||||
//NewConfig build a devto configuration instance with the
|
||||
//required parameters.
|
||||
// NewConfig build a devto configuration instance with the
|
||||
// required parameters.
|
||||
//
|
||||
//It takes a boolean (p) as first parameter to indicate if
|
||||
//you need access to endpoints which require authentication,
|
||||
//and a API key as second paramenter, if p is set to true and
|
||||
//you don't provide an API key, it will return an error.
|
||||
// It takes a boolean (p) as first parameter to indicate if
|
||||
// you need access to endpoints which require authentication,
|
||||
// and a API key as second parameter, if p is set to true and
|
||||
// you don't provide an API key, it will return an error.
|
||||
func NewConfig(p bool, k string) (c *Config, err error) {
|
||||
if p == true && k == "" {
|
||||
return nil, ErrMissingRequiredParameter
|
||||
|
||||
17
vendor/github.com/VictorAvelar/devto-api-go/devto/devto.go
generated
vendored
17
vendor/github.com/VictorAvelar/devto-api-go/devto/devto.go
generated
vendored
@@ -15,7 +15,7 @@ const (
|
||||
APIKeyHeader string = "api-key"
|
||||
)
|
||||
|
||||
//devto client errors
|
||||
// devto client errors
|
||||
var (
|
||||
ErrMissingConfig = errors.New("missing configuration")
|
||||
ErrProtectedEndpoint = errors.New("to use this resource you need to provide an authentication method")
|
||||
@@ -25,8 +25,8 @@ type httpClient interface {
|
||||
Do(req *http.Request) (res *http.Response, err error)
|
||||
}
|
||||
|
||||
//Client is the main data structure for performing actions
|
||||
//against dev.to API
|
||||
// Client is the main data structure for performing actions
|
||||
// against dev.to API
|
||||
type Client struct {
|
||||
Context context.Context
|
||||
BaseURL *url.URL
|
||||
@@ -35,8 +35,8 @@ type Client struct {
|
||||
Articles *ArticlesResource
|
||||
}
|
||||
|
||||
//NewClient takes a context, a configuration pointer and optionally a
|
||||
//base http client (bc) to build an Client instance.
|
||||
// NewClient takes a context, a configuration pointer and optionally a
|
||||
// base http client (bc) to build an Client instance.
|
||||
func NewClient(ctx context.Context, conf *Config, bc httpClient, bu string) (dev *Client, err error) {
|
||||
if bc == nil {
|
||||
bc = http.DefaultClient
|
||||
@@ -54,7 +54,10 @@ func NewClient(ctx context.Context, conf *Config, bc httpClient, bu string) (dev
|
||||
bu = BaseURL
|
||||
}
|
||||
|
||||
u, _ := url.Parse(bu)
|
||||
u, err := url.Parse(bu)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Client{
|
||||
Context: ctx,
|
||||
@@ -66,7 +69,7 @@ func NewClient(ctx context.Context, conf *Config, bc httpClient, bu string) (dev
|
||||
return c, nil
|
||||
}
|
||||
|
||||
//NewRequest build the request relative to the client BaseURL
|
||||
// NewRequest build the request relative to the client BaseURL
|
||||
func (c *Client) NewRequest(method string, uri string, body io.Reader) (*http.Request, error) {
|
||||
u, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
|
||||
10
vendor/github.com/VictorAvelar/devto-api-go/devto/doc.go
generated
vendored
Normal file
10
vendor/github.com/VictorAvelar/devto-api-go/devto/doc.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Package devto is a wrapper around dev.to REST API
|
||||
//
|
||||
// Where programmers share ideas and help each other grow.
|
||||
// It is an online community for sharing and discovering great ideas,
|
||||
// having debates, and making friends. Anyone can share articles,
|
||||
// questions, discussions, etc. as long as they have the rights to the
|
||||
// words they are sharing. Cross-posting from your own blog is welcome.
|
||||
//
|
||||
// See: https://docs.dev.to/api
|
||||
package devto
|
||||
217
vendor/github.com/VictorAvelar/devto-api-go/devto/types.go
generated
vendored
217
vendor/github.com/VictorAvelar/devto-api-go/devto/types.go
generated
vendored
@@ -1,12 +1,14 @@
|
||||
package devto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//User contains information about a devto account
|
||||
// User contains information about a devto account
|
||||
type User struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
@@ -17,8 +19,8 @@ type User struct {
|
||||
ProfileImage90 *WebURL `json:"profile_image_90,omitempty"`
|
||||
}
|
||||
|
||||
//Organization describes a company or group that
|
||||
//publishes content to devto.
|
||||
// Organization describes a company or group that
|
||||
// publishes content to devto.
|
||||
type Organization struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
@@ -27,40 +29,161 @@ type Organization struct {
|
||||
ProfileImage90 *WebURL `json:"profile_image_90,omitempty"`
|
||||
}
|
||||
|
||||
//Tags are a group of topics related to an article
|
||||
type Tags []string
|
||||
|
||||
//Article contains all the information related to a single
|
||||
//information resource from devto.
|
||||
type Article struct {
|
||||
TypeOf string `json:"type_of,omitempty"`
|
||||
ID uint32 `json:"id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CoverImage *WebURL `json:"cover_image,omitempty"`
|
||||
SocialImage *WebURL `json:"social_image,omitempty"`
|
||||
PublishedAt *time.Time `json:"published_at,omitempty"`
|
||||
EditedAt *time.Time `json:"edited_at,omitempty"`
|
||||
CrossPostedAt *time.Time `json:"crossposted_at,omitempty"`
|
||||
LastCommentAt *time.Time `json:"last_comment_at,omitempty"`
|
||||
TagList Tags `json:"tag_list,omitempty"`
|
||||
Tags string `json:"tags,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Path *WebURL `json:"path,omitempty"`
|
||||
URL *WebURL `json:"url,omitempty"`
|
||||
CanonicalURL *WebURL `json:"canonical_url,omitempty"`
|
||||
CommentsCount uint `json:"comments_count,omitempty"`
|
||||
PositiveReactionsCount uint `json:"positive_reactions_count,omitempty"`
|
||||
PublishedTimestamp *time.Time `json:"published_timestamp,omitempty"`
|
||||
User User `json:"user,omitempty"`
|
||||
Organization Organization `json:"organization,omitempty"`
|
||||
BodyHTML string `json:"body_html,omitempty"`
|
||||
BodyMarkdown string `json:"body_markdown,omitempty"`
|
||||
Published bool `json:"published,omitempty"`
|
||||
// FlareTag represents an article's flare tag, if the article
|
||||
// has one.
|
||||
type FlareTag struct {
|
||||
Name string `json:"name"`
|
||||
BGColorHex string `json:"bg_color_hex"`
|
||||
TextColorHex string `json:"text_color_hex"`
|
||||
}
|
||||
|
||||
//ArticleListOptions holds the query values to pass as
|
||||
//query string parameter to the Articles List action.
|
||||
// Tags are a group of topics related to an article
|
||||
type Tags []string
|
||||
|
||||
// This deserialization logic is so that if a listed article
|
||||
// originates from the /articles endpoint instead of
|
||||
// /articles/me/*, its Published field is returned as true,
|
||||
// since /articles exclusively returns articles that have been
|
||||
// published.
|
||||
type listedArticleJSON struct {
|
||||
TypeOf string `json:"type_of,omitempty"`
|
||||
ID uint32 `json:"id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CoverImage *WebURL `json:"cover_image,omitempty"`
|
||||
PublishedAt *time.Time `json:"published_at,omitempty"`
|
||||
PublishedTimestamp string `json:"published_timestamp,omitempty"`
|
||||
TagList Tags `json:"tag_list,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
URL *WebURL `json:"url,omitempty"`
|
||||
CanonicalURL *WebURL `json:"canonical_url,omitempty"`
|
||||
CommentsCount uint `json:"comments_count,omitempty"`
|
||||
PositiveReactionsCount uint `json:"positive_reactions_count,omitempty"`
|
||||
User User `json:"user,omitempty"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
FlareTag *FlareTag `json:"flare_tag,omitempty"`
|
||||
BodyMarkdown string `json:"body_markdown,omitempty"`
|
||||
Published *bool `json:"published,omitempty"`
|
||||
}
|
||||
|
||||
func (j *listedArticleJSON) listedArticle() ListedArticle {
|
||||
a := ListedArticle{
|
||||
TypeOf: j.TypeOf,
|
||||
ID: j.ID,
|
||||
Title: j.Title,
|
||||
Description: j.Description,
|
||||
CoverImage: j.CoverImage,
|
||||
PublishedAt: j.PublishedAt,
|
||||
PublishedTimestamp: j.PublishedTimestamp,
|
||||
TagList: j.TagList,
|
||||
Slug: j.Slug,
|
||||
Path: j.Path,
|
||||
URL: j.URL,
|
||||
CanonicalURL: j.CanonicalURL,
|
||||
CommentsCount: j.CommentsCount,
|
||||
PositiveReactionsCount: j.PositiveReactionsCount,
|
||||
User: j.User,
|
||||
Organization: j.Organization,
|
||||
FlareTag: j.FlareTag,
|
||||
BodyMarkdown: j.BodyMarkdown,
|
||||
}
|
||||
|
||||
if j.Published != nil {
|
||||
a.Published = *j.Published
|
||||
} else {
|
||||
// "published" currently is included in the API
|
||||
// response for dev.to's /articles/me/* endpoints,
|
||||
// but not in /articles, so we are setting this
|
||||
// to true since /articles only returns articles
|
||||
// that are published.
|
||||
a.Published = true
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// ListedArticle represents an article returned from one of
|
||||
// the list articles endpoints (/articles, /articles/me/*).
|
||||
type ListedArticle struct {
|
||||
TypeOf string `json:"type_of,omitempty"`
|
||||
ID uint32 `json:"id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CoverImage *WebURL `json:"cover_image,omitempty"`
|
||||
PublishedAt *time.Time `json:"published_at,omitempty"`
|
||||
PublishedTimestamp string `json:"published_timestamp,omitempty"`
|
||||
TagList Tags `json:"tag_list,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
URL *WebURL `json:"url,omitempty"`
|
||||
CanonicalURL *WebURL `json:"canonical_url,omitempty"`
|
||||
CommentsCount uint `json:"comments_count,omitempty"`
|
||||
PositiveReactionsCount uint `json:"positive_reactions_count,omitempty"`
|
||||
User User `json:"user,omitempty"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
FlareTag *FlareTag `json:"flare_tag,omitempty"`
|
||||
// Only present in "/articles/me/*" endpoints
|
||||
BodyMarkdown string `json:"body_markdown,omitempty"`
|
||||
Published bool `json:"published,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the JSON Unmarshaler interface.
|
||||
func (a *ListedArticle) UnmarshalJSON(b []byte) error {
|
||||
var j listedArticleJSON
|
||||
if err := json.Unmarshal(b, &j); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*a = j.listedArticle()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Article contains all the information related to a single
|
||||
// information resource from devto.
|
||||
type Article struct {
|
||||
TypeOf string `json:"type_of,omitempty"`
|
||||
ID uint32 `json:"id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CoverImage *WebURL `json:"cover_image,omitempty"`
|
||||
SocialImage *WebURL `json:"social_image,omitempty"`
|
||||
ReadablePublishDate string `json:"readable_publish_date"`
|
||||
Published bool `json:"published,omitempty"`
|
||||
PublishedAt *time.Time `json:"published_at,omitempty"`
|
||||
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||
EditedAt *time.Time `json:"edited_at,omitempty"`
|
||||
CrossPostedAt *time.Time `json:"crossposted_at,omitempty"`
|
||||
LastCommentAt *time.Time `json:"last_comment_at,omitempty"`
|
||||
TagList string `json:"tag_list,omitempty"`
|
||||
Tags Tags `json:"tags,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Path *WebURL `json:"path,omitempty"`
|
||||
URL *WebURL `json:"url,omitempty"`
|
||||
CanonicalURL *WebURL `json:"canonical_url,omitempty"`
|
||||
CommentsCount uint `json:"comments_count,omitempty"`
|
||||
PositiveReactionsCount uint `json:"positive_reactions_count,omitempty"`
|
||||
User User `json:"user,omitempty"`
|
||||
BodyHTML string `json:"body_html,omitempty"`
|
||||
BodyMarkdown string `json:"body_markdown,omitempty"`
|
||||
}
|
||||
|
||||
// ArticleUpdate represents an update to an article; it is
|
||||
// used as the payload in POST and PUT requests for writing
|
||||
// articles.
|
||||
type ArticleUpdate struct {
|
||||
Title string `json:"title"`
|
||||
BodyMarkdown string `json:"body_markdown"`
|
||||
Published bool `json:"published"`
|
||||
Series *string `json:"series"`
|
||||
MainImage string `json:"main_image,omitempty"`
|
||||
CanonicalURL string `json:"canonical_url,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
OrganizationID int32 `json:"organization_id,omitempty"`
|
||||
}
|
||||
|
||||
// ArticleListOptions holds the query values to pass as
|
||||
// query string parameter to the Articles List action.
|
||||
type ArticleListOptions struct {
|
||||
Tags string `url:"tag,omitempty"`
|
||||
Username string `url:"username,omitempty"`
|
||||
@@ -69,12 +192,21 @@ type ArticleListOptions struct {
|
||||
Page int `url:"page,omitempty"`
|
||||
}
|
||||
|
||||
// MyArticlesOptions defines pagination options used as query
|
||||
// params in the dev.to "list my articles" endpoints.
|
||||
type MyArticlesOptions struct {
|
||||
Page int `url:"page,omitempty"`
|
||||
PerPage int `url:"per_page,omitempty"`
|
||||
}
|
||||
|
||||
// WebURL is a class embed to override default unmarshal
|
||||
// behavior.
|
||||
type WebURL struct {
|
||||
*url.URL
|
||||
}
|
||||
|
||||
//UnmarshalJSON overrides the default unmarshal behaviour
|
||||
//for URL
|
||||
// UnmarshalJSON overrides the default unmarshal behaviour
|
||||
// for URL
|
||||
func (s *WebURL) UnmarshalJSON(b []byte) error {
|
||||
c := string(b)
|
||||
c = strings.Trim(c, "\"")
|
||||
@@ -85,3 +217,14 @@ func (s *WebURL) UnmarshalJSON(b []byte) error {
|
||||
s.URL = uri
|
||||
return nil
|
||||
}
|
||||
|
||||
// ErrorResponse is an error returned from a dev.to API
|
||||
// endpoint.
|
||||
type ErrorResponse struct {
|
||||
ErrorMessage string `json:"error"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
func (e *ErrorResponse) Error() string {
|
||||
return fmt.Sprintf(`%d error: "%s"`, e.Status, e.ErrorMessage)
|
||||
}
|
||||
|
||||
38
vendor/github.com/VictorAvelar/devto-api-go/devto/utilities.go
generated
vendored
Normal file
38
vendor/github.com/VictorAvelar/devto-api-go/devto/utilities.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package devto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// nonSuccessfulResponse indicates that the status code for
|
||||
// the HTTP response passed in was not one of the "success"
|
||||
// (2XX) status codes
|
||||
func nonSuccessfulResponse(res *http.Response) bool { return res.StatusCode/100 != 2 }
|
||||
|
||||
// attempt to deserialize the error response; if it succeeds,
|
||||
// the error will be an ErrorResponse, otherwise it will be
|
||||
// an error indicating that the error response could not be
|
||||
// deserialized.
|
||||
func unmarshalErrorResponse(res *http.Response) error {
|
||||
var e ErrorResponse
|
||||
if err := json.NewDecoder(res.Body).Decode(&e); err != nil {
|
||||
return fmt.Errorf(
|
||||
`unexpected error deserializing %d response: "%v"`,
|
||||
res.StatusCode,
|
||||
err,
|
||||
)
|
||||
}
|
||||
return &e
|
||||
}
|
||||
|
||||
func decodeResponse(r *http.Response) []byte {
|
||||
c, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return []byte("")
|
||||
}
|
||||
defer r.Body.Close()
|
||||
return c
|
||||
}
|
||||
Reference in New Issue
Block a user