♻️ Package refactor
This commit is contained in:
parent
fe6abc89bc
commit
5112c12848
|
@ -0,0 +1,32 @@
|
|||
PROJECT_NAMESPACE := $(CI_PROJECT_NAMESPACE)
|
||||
PROJECT_NAME := $(CI_PROJECT_NAME)
|
||||
PROJECT_PATH := $(PROJECT_NAMESPACE)/$(PROJECT_NAME)
|
||||
PACKAGE_NAME := "gitlab.com/$(PROJECT_PATH)"
|
||||
PACKAGE_PATH := $(GOPATH)/src/$(PACKAGE_NAME)
|
||||
PACKAGE_LIST := $(shell go list $(PACKAGE_NAME)/... | grep -v /vendor/)
|
||||
GO_FILES := $(shell find . -name '*.go' | grep -v /vendor/ | grep -v _test.go)
|
||||
|
||||
.PHONY: all lint test rase coverage dep build clean
|
||||
|
||||
all: build
|
||||
|
||||
lint: ## Lint the files
|
||||
@gocritic check-project $(PACKAGE_PATH)
|
||||
|
||||
test: ## Run unittests
|
||||
@go test -short ${PACKAGE_LIST}
|
||||
|
||||
race: dep ## Run data race detector
|
||||
@go test -race -short ${PACKAGE_LIST}
|
||||
|
||||
coverage: ## Generate global code coverage report
|
||||
@go test -cover -v -coverpkg=$(PACKAGE_NAME) ${PACKAGE_LIST}
|
||||
|
||||
dep: ## Get the dependencies
|
||||
@go get -v -d -t ${PACKAGE_LIST}
|
||||
|
||||
clean: ## Remove previous build
|
||||
@rm -f $(PROJECT_NAME)
|
||||
|
||||
help: ## Display this help screen
|
||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
56
content.go
56
content.go
|
@ -2,69 +2,38 @@ package telegraph
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
type (
|
||||
// Node is abstract object represents a DOM Node. It can be a String which represents a DOM text
|
||||
// node or a NodeElement object.
|
||||
Node interface{}
|
||||
|
||||
// NodeElement represents a DOM element node.
|
||||
NodeElement struct {
|
||||
// Name of the DOM element.
|
||||
// Available tags: a, aside, b, blockquote, br, code, em, figcaption, figure, h3,
|
||||
// h4, hr, i, iframe, img, li, ol, p, pre, s, strong, u, ul, video.
|
||||
Tag string `json:"tag"`
|
||||
|
||||
// Attributes of the DOM element. Key of object represents name of attribute,
|
||||
// value represents value of attribute.
|
||||
// Available attributes: href, src.
|
||||
Attrs map[string]string `json:"attrs,omitempty"` // optional
|
||||
|
||||
// List of child nodes for the DOM element.
|
||||
Children []Node `json:"children,omitempty"` // optional
|
||||
}
|
||||
)
|
||||
|
||||
// ErrInvalidDataType is returned when ContentFormat function are passed a data argument of invalid
|
||||
// type.
|
||||
var ErrInvalidDataType = errors.New("invalid data type")
|
||||
|
||||
// ContentFormat transforms data to a DOM-based format to represent the content of the page.
|
||||
func ContentFormat(data interface{}) ([]Node, error) {
|
||||
var doc html.Node
|
||||
switch dst := data.(type) {
|
||||
// ContentFormat transforms data to a DOM-based format to represent the content
|
||||
// of the page.
|
||||
func ContentFormat(data interface{}) (n []Node, err error) {
|
||||
dst := new(html.Node)
|
||||
switch src := data.(type) {
|
||||
case string:
|
||||
dom, err := html.Parse(strings.NewReader(dst))
|
||||
dst, err = html.Parse(strings.NewReader(src))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doc = *dom
|
||||
case []byte:
|
||||
dom, err := html.Parse(bytes.NewReader(dst))
|
||||
dst, err = html.Parse(bytes.NewReader(src))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doc = *dom
|
||||
case io.Reader:
|
||||
dom, err := html.Parse(dst)
|
||||
dst, err = html.Parse(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doc = *dom
|
||||
default:
|
||||
return nil, ErrInvalidDataType
|
||||
}
|
||||
|
||||
var content []Node
|
||||
content = append(content, domToNode(doc.FirstChild))
|
||||
|
||||
return content, nil
|
||||
n = append(n, domToNode(dst.FirstChild))
|
||||
return
|
||||
}
|
||||
|
||||
func domToNode(domNode *html.Node) interface{} {
|
||||
|
@ -78,8 +47,9 @@ func domToNode(domNode *html.Node) interface{} {
|
|||
|
||||
var nodeElement NodeElement
|
||||
switch strings.ToLower(domNode.Data) {
|
||||
case "a", "aside", "b", "blockquote", "br", "code", "em", "figcaption", "figure", "h3", "h4",
|
||||
"hr", "i", "iframe", "img", "li", "ol", "p", "pre", "s", "strong", "u", "ul", "video":
|
||||
case "a", "aside", "b", "blockquote", "br", "code", "em", "figcaption",
|
||||
"figure", "h3", "h4", "hr", "i", "iframe", "img", "li", "ol",
|
||||
"p", "pre", "s", "strong", "u", "ul", "video":
|
||||
nodeElement.Tag = domNode.Data
|
||||
|
||||
for i := range domNode.Attr {
|
||||
|
|
|
@ -5,58 +5,29 @@ import (
|
|||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Account represents a Telegraph account.
|
||||
type Account struct {
|
||||
// Only returned by the createAccount and revokeAccessToken method. Access token
|
||||
// of the Telegraph account.
|
||||
AccessToken string `json:"access_token"` // optional
|
||||
|
||||
// URL to authorize a browser on telegra.ph and connect it to a Telegraph
|
||||
// account. This URL is valid for only one use and for 5 minutes only.
|
||||
AuthURL string `json:"auth_url,omitempty"` // optional
|
||||
|
||||
// Account name, helps users with several accounts remember which they are
|
||||
// currently using. Displayed to the user above the "Edit/Publish" button on
|
||||
// Telegra.ph, other users don't see this name.
|
||||
ShortName string `json:"short_name"`
|
||||
|
||||
// Default author name used when creating new articles.
|
||||
AuthorName string `json:"author_name"`
|
||||
|
||||
// Profile link, opened when users click on the author's name below the title.
|
||||
// Can be any link, not necessarily to a Telegram profile or channel.
|
||||
AuthorURL string `json:"author_url"`
|
||||
|
||||
// Number of pages belonging to the Telegraph account.
|
||||
PageCount int `json:"page_count,omitempty"` // optional
|
||||
}
|
||||
|
||||
// CreateAccount create a new Telegraph account. Most users only need one account, but this can be
|
||||
// useful for channel administrators who would like to keep individual author names and profile links
|
||||
// for each of their channels. On success, returns an Account object with the regular fields and an
|
||||
// additional access_token field.
|
||||
func CreateAccount(account *Account) (*Account, error) {
|
||||
args := http.AcquireArgs()
|
||||
|
||||
// Account name, helps users with several accounts remember which they are currently using.
|
||||
// Displayed to the user above the "Edit/Publish" button on Telegra.ph, other users don't see
|
||||
// this name.
|
||||
args.Add("short_name", account.ShortName) // required
|
||||
|
||||
// Default author name used when creating new articles.
|
||||
args.Add("author_name", account.AuthorName)
|
||||
|
||||
// Default profile link, opened when users click on the author's name below the title. Can be any
|
||||
// link, not necessarily to a Telegram profile or channel.
|
||||
args.Add("author_url", account.AuthorURL)
|
||||
|
||||
body, err := request("createAccount", "", args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// CreateAccount create a new Telegraph account. Most users only need one
|
||||
// account, but this can be useful for channel administrators who would like to
|
||||
// keep individual author names and profile links for each of their channels. On
|
||||
// success, returns an Account object with the regular fields and an additional
|
||||
// access_token field.
|
||||
func CreateAccount(account *Account) (r *Account, err error) {
|
||||
if account == nil {
|
||||
return nil, ErrNoInputData
|
||||
}
|
||||
|
||||
var resp Account
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
args := http.AcquireArgs()
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("short_name", account.ShortName) // required
|
||||
args.Add("author_name", account.AuthorName)
|
||||
args.Add("author_url", account.AuthorURL)
|
||||
|
||||
return &resp, err
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest("createAccount", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r = new(Account)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -7,80 +7,34 @@ import (
|
|||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Page represents a page on Telegraph.
|
||||
type Page struct {
|
||||
// Path to the page.
|
||||
Path string `json:"path"`
|
||||
|
||||
// URL of the page.
|
||||
URL string `json:"url"`
|
||||
|
||||
// Title of the page.
|
||||
Title string `json:"title"`
|
||||
|
||||
// Description of the page.
|
||||
Description string `json:"description"`
|
||||
|
||||
// Name of the author, displayed below the title.
|
||||
AuthorName string `json:"author_name,omitempty"` // optional
|
||||
|
||||
// Profile link, opened when users click on the author's name below the title.
|
||||
// Can be any link, not necessarily to a Telegram profile or channel.
|
||||
AuthorURL string `json:"author_url,omitempty"` // optional
|
||||
|
||||
// Image URL of the page.
|
||||
ImageURL string `json:"image_url,omitempty"` // optional
|
||||
|
||||
// Content of the page.
|
||||
Content []Node `json:"content,omitempty"` // optional
|
||||
|
||||
// Number of page views for the page.
|
||||
Views int `json:"views"`
|
||||
|
||||
// Only returned if access_token passed. True, if the target Telegraph account
|
||||
// can edit the page.
|
||||
CanEdit bool `json:"can_edit,omitempty"` // optional
|
||||
}
|
||||
|
||||
// CreatePage create a new Telegraph page. On success, returns a Page object.
|
||||
func (account *Account) CreatePage(page *Page, returnContent bool) (*Page, error) {
|
||||
func (a *Account) CreatePage(page *Page, returnContent bool) (r *Page, err error) {
|
||||
if page == nil {
|
||||
return nil, ErrNoInputData
|
||||
}
|
||||
|
||||
var src []byte
|
||||
src, err = json.Marshal(page.Content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
args := http.AcquireArgs()
|
||||
|
||||
// Access token of the Telegraph account.
|
||||
args.Add("access_token", account.AccessToken) // required
|
||||
|
||||
// Page title.
|
||||
args.Add("title", page.Title) // required
|
||||
|
||||
if page.AuthorName != "" {
|
||||
// Author name, displayed below the article's title.
|
||||
args.Add("author_name", page.AuthorName)
|
||||
}
|
||||
|
||||
if page.AuthorURL != "" {
|
||||
// Profile link, opened when users click on the author's name below the title. Can be any
|
||||
// link, not necessarily to a Telegram profile or channel.
|
||||
args.Add("author_url", page.AuthorURL)
|
||||
}
|
||||
|
||||
// If true, a content field will be returned in the Page object.
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("access_token", a.AccessToken) // required
|
||||
args.Add("title", page.Title) // required
|
||||
args.Add("author_name", a.AuthorName)
|
||||
args.Add("author_url", a.AuthorURL)
|
||||
args.Add("content", string(src))
|
||||
args.Add("return_content", strconv.FormatBool(returnContent))
|
||||
|
||||
content, err := json.Marshal(page.Content)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest("createPage", args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Content of the page.
|
||||
args.Add("content", string(content)) // required
|
||||
|
||||
body, err := request("createPage", "", args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp Page
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(Page)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,31 +5,28 @@ import (
|
|||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// EditAccountInfo update information about a Telegraph account. Pass only the parameters that you
|
||||
// want to edit. On success, returns an Account object with the default fields.
|
||||
func (account *Account) EditAccountInfo(update *Account) (*Account, error) {
|
||||
// EditAccountInfo update information about a Telegraph account. Pass only the
|
||||
// parameters that you want to edit. On success, returns an Account object with
|
||||
// the default fields.
|
||||
func (a *Account) EditAccountInfo(update *Account) (r *Account, err error) {
|
||||
if update == nil {
|
||||
return nil, ErrNoInputData
|
||||
}
|
||||
|
||||
args := http.AcquireArgs()
|
||||
|
||||
// Access token of the Telegraph account.
|
||||
args.Add("access_token", account.AccessToken) // required
|
||||
|
||||
// New account name.
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("access_token", a.AccessToken) // required
|
||||
args.Add("short_name", update.ShortName)
|
||||
|
||||
// New default author name used when creating new articles.
|
||||
args.Add("author_name", update.AuthorName)
|
||||
|
||||
// New default profile link, opened when users click on the author's name below the title. Can be
|
||||
// any link, not necessarily to a Telegram profile or channel.
|
||||
args.Add("author_url", update.AuthorURL)
|
||||
|
||||
body, err := request("editAccountInfo", "", args)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest("editAccountInfo", args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp Account
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(Account)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
57
edit_page.go
57
edit_page.go
|
@ -1,6 +1,7 @@
|
|||
package telegraph
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
json "github.com/pquerna/ffjson/ffjson"
|
||||
|
@ -8,44 +9,34 @@ import (
|
|||
)
|
||||
|
||||
// EditPage edit an existing Telegraph page. On success, returns a Page object.
|
||||
func (account *Account) EditPage(update *Page, returnContent bool) (*Page, error) {
|
||||
func (a *Account) EditPage(update *Page, returnContent bool) (r *Page, err error) {
|
||||
if update == nil {
|
||||
return nil, ErrNoInputData
|
||||
}
|
||||
|
||||
var src []byte
|
||||
src, err = json.Marshal(update.Content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
args := http.AcquireArgs()
|
||||
|
||||
// Access token of the Telegraph account.
|
||||
args.Add("access_token", account.AccessToken) // required
|
||||
|
||||
// Page title.
|
||||
args.Add("title", update.Title) // required
|
||||
|
||||
if update.AuthorName != "" {
|
||||
// Author name, displayed below the article's title.
|
||||
args.Add("author_name", update.AuthorName)
|
||||
}
|
||||
|
||||
if update.AuthorURL != "" {
|
||||
// Profile link, opened when users click on the author's name below the title. Can be any
|
||||
// link, not necessarily to a Telegram profile or channel.
|
||||
args.Add("author_url", update.AuthorURL)
|
||||
}
|
||||
|
||||
// If true, a content field will be returned in the Page object.
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("access_token", a.AccessToken) // required
|
||||
args.Add("path", update.Path) // required
|
||||
args.Add("title", update.Title) // required
|
||||
args.Add("content", string(src)) // required
|
||||
args.Add("author_name", a.AuthorName)
|
||||
args.Add("author_url", a.AuthorURL)
|
||||
args.Add("return_content", strconv.FormatBool(returnContent))
|
||||
|
||||
content, err := json.Marshal(update.Content)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest(path.Join("editPage", update.Path), args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Content of the page.
|
||||
args.Add("content", string(content)) // required
|
||||
|
||||
body, err := request("editPage", update.Path, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp Page
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(Page)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@ package telegraph_test
|
|||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/toby3d/telegraph"
|
||||
"gitlab.com/toby3d/telegraph"
|
||||
)
|
||||
|
||||
// Content in a string format (for this example).
|
||||
|
@ -22,8 +23,8 @@ const data = `
|
|||
`
|
||||
|
||||
var (
|
||||
account *telegraph.Account
|
||||
page *telegraph.Page
|
||||
account = new(telegraph.Account)
|
||||
page = new(telegraph.Page)
|
||||
content []telegraph.Node
|
||||
)
|
||||
|
||||
|
@ -168,7 +169,10 @@ func ExampleAccount_GetPageList() {
|
|||
|
||||
func ExampleGetViews() {
|
||||
pagePath := "Sample-Page-12-15"
|
||||
views, err := telegraph.GetViews(pagePath, 2016, 12, 0, -1)
|
||||
views, err := telegraph.GetViews(
|
||||
pagePath,
|
||||
time.Date(2016, 12, 0, 0, 0, 0, 0, nil),
|
||||
)
|
||||
errCheck(err)
|
||||
|
||||
log.Println(pagePath, "has been viewed", views.Views, "times")
|
||||
|
|
|
@ -1,50 +1,26 @@
|
|||
package telegraph
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
json "github.com/pquerna/ffjson/ffjson"
|
||||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
const (
|
||||
// FieldShortName used as GetAccountInfo argument for getting account name.
|
||||
FieldShortName = "short_name"
|
||||
|
||||
// FieldAuthorName used as GetAccountInfo argument for getting author name.
|
||||
FieldAuthorName = "author_name"
|
||||
|
||||
// FieldAuthorURL used as GetAccountInfo argument for getting profile link.
|
||||
FieldAuthorURL = "author_url"
|
||||
|
||||
// FieldAuthURL used as GetAccountInfo argument for getting URL to authorize
|
||||
// a browser on telegra.ph.
|
||||
FieldAuthURL = "auth_url"
|
||||
|
||||
// FieldPageCount used as GetAccountInfo argument for getting number of pages
|
||||
// belonging to the Telegraph account.
|
||||
FieldPageCount = "page_count"
|
||||
)
|
||||
|
||||
// GetAccountInfo get information about a Telegraph account. Returns an Account object on success.
|
||||
func (account *Account) GetAccountInfo(fields ...string) (*Account, error) {
|
||||
func (a *Account) GetAccountInfo(fields ...string) (r *Account, err error) {
|
||||
args := http.AcquireArgs()
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("access_token", a.AccessToken) // required
|
||||
args.Add("fields", `["`+strings.Join(fields, `","`)+`"]`)
|
||||
|
||||
// Access token of the Telegraph account.
|
||||
args.Add("access_token", account.AccessToken) // required
|
||||
|
||||
// List of account fields to return.
|
||||
// Available fields: short_name, author_name, author_url, auth_url, page_count.
|
||||
args.Add("fields", fmt.Sprint(`["`, strings.Join(fields, `","`), `"]`))
|
||||
|
||||
body, err := request("getAccountInfo", "", args)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest("getAccountInfo", args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp Account
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(Account)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
17
get_page.go
17
get_page.go
|
@ -1,6 +1,7 @@
|
|||
package telegraph
|
||||
|
||||
import (
|
||||
gopath "path"
|
||||
"strconv"
|
||||
|
||||
json "github.com/pquerna/ffjson/ffjson"
|
||||
|
@ -8,19 +9,19 @@ import (
|
|||
)
|
||||
|
||||
// GetPage get a Telegraph page. Returns a Page object on success.
|
||||
func GetPage(path string, returnContent bool) (*Page, error) {
|
||||
func GetPage(path string, returnContent bool) (r *Page, err error) {
|
||||
args := http.AcquireArgs()
|
||||
|
||||
// If true, content field will be returned in Page object.
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("path", path) // required
|
||||
args.Add("return_content", strconv.FormatBool(returnContent))
|
||||
|
||||
body, err := request("getPage", path, args)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest(gopath.Join("getPage", path), args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp Page
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(Page)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -7,37 +7,22 @@ import (
|
|||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// PageList represents a list of Telegraph articles belonging to an account. Most recently created
|
||||
// articles first.
|
||||
type PageList struct {
|
||||
// Total number of pages belonging to the target Telegraph account.
|
||||
TotalCount int `json:"total_count"`
|
||||
|
||||
// Requested pages of the target Telegraph account.
|
||||
Pages []*Page `json:"pages"`
|
||||
}
|
||||
|
||||
// GetPageList get a list of pages belonging to a Telegraph account. Returns a PageList object, sorted
|
||||
// by most recently created pages first.
|
||||
func (account *Account) GetPageList(offset, limit int) (*PageList, error) {
|
||||
func (a *Account) GetPageList(offset, limit int) (r *PageList, err error) {
|
||||
args := http.AcquireArgs()
|
||||
|
||||
// Access token of the Telegraph account.
|
||||
args.Add("access_token", account.AccessToken) // required
|
||||
|
||||
// Sequential number of the first page to be returned.
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("access_token", a.AccessToken) // required
|
||||
args.Add("offset", strconv.Itoa(offset))
|
||||
|
||||
// Limits the number of pages to be retrieved.
|
||||
args.Add("limit", strconv.Itoa(limit))
|
||||
|
||||
body, err := request("getPageList", "", args)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest("getPageList", args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp PageList
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(PageList)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
49
get_views.go
49
get_views.go
|
@ -1,53 +1,32 @@
|
|||
package telegraph
|
||||
|
||||
import (
|
||||
gopath "path"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
json "github.com/pquerna/ffjson/ffjson"
|
||||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// PageViews represents the number of page views for a Telegraph article.
|
||||
type PageViews struct {
|
||||
// Number of page views for the target page.
|
||||
Views int `json:"views"`
|
||||
}
|
||||
|
||||
// GetViews get the number of views for a Telegraph article. By default, the total number of page
|
||||
// views will be returned. Returns a PageViews object on success.
|
||||
func GetViews(path string, year, month, day, hour int) (*PageViews, error) {
|
||||
func GetViews(path string, date time.Time) (r *PageViews, err error) {
|
||||
args := http.AcquireArgs()
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("path", path) // required
|
||||
args.Add("year", strconv.Itoa(date.Year()))
|
||||
args.Add("month", strconv.Itoa(int(date.Month())))
|
||||
args.Add("day", strconv.Itoa(date.Day()))
|
||||
args.Add("hour", strconv.Itoa(date.Hour()))
|
||||
|
||||
if hour > -1 {
|
||||
// If passed, the number of page views for the requested hour will be returned.
|
||||
args.Add("hour", strconv.Itoa(hour))
|
||||
}
|
||||
|
||||
if day > 0 {
|
||||
// Required if hour is passed. If passed, the number of page views for the requested day will
|
||||
// be returned.
|
||||
args.Add("day", strconv.Itoa(day))
|
||||
}
|
||||
|
||||
if month > 0 {
|
||||
// Required if day is passed. If passed, the number of page views for the requested month will
|
||||
// be returned.
|
||||
args.Add("month", strconv.Itoa(month))
|
||||
}
|
||||
|
||||
if year > 0 {
|
||||
// Required if month is passed. If passed, the number of page views for the requested year
|
||||
// will be returned.
|
||||
args.Add("year", strconv.Itoa(year))
|
||||
}
|
||||
|
||||
body, err := request("getViews", path, args)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest(gopath.Join("getViews", path), args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp PageViews
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(PageViews)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
63
request.go
63
request.go
|
@ -3,48 +3,63 @@ package telegraph
|
|||
import (
|
||||
gojson "encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/kirillDanshin/dlog"
|
||||
json "github.com/pquerna/ffjson/ffjson"
|
||||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// response represents a response from the Telegram API with the result stored raw. If ok equals true,
|
||||
// the request was successful, and the result of the query can be found in the result field. In case of
|
||||
// an unsuccessful request, ok equals false, and the error is explained in the error field (e.g.
|
||||
// Response contains a JSON object, which always has a Boolean field ok. If ok
|
||||
// equals true, the request was successful, and the result of the query can be
|
||||
// found in the result field. In case of an unsuccessful request, ok equals
|
||||
// false, and the error is explained in the error field (e.g.
|
||||
// SHORT_NAME_REQUIRED).
|
||||
type response struct {
|
||||
type Response struct {
|
||||
Ok bool `json:"ok"`
|
||||
Error string `json:"error"`
|
||||
Result *gojson.RawMessage `json:"result"`
|
||||
Result *gojson.RawMessage `json:"result,omitempty"`
|
||||
}
|
||||
|
||||
func request(method, path string, args *http.Args) (*response, error) {
|
||||
defer http.ReleaseArgs(args)
|
||||
requestURI := &url.URL{
|
||||
Scheme: "https",
|
||||
Host: "api.telegra.ph",
|
||||
Path: method,
|
||||
}
|
||||
var defaultURL = url.URL{
|
||||
Scheme: "https",
|
||||
Host: "api.telegra.ph",
|
||||
}
|
||||
|
||||
if path != "" {
|
||||
requestURI.Path += fmt.Sprint("/", path)
|
||||
}
|
||||
func makeRequest(path string, args *http.Args) (r *Response, err error) {
|
||||
requestURL := defaultURL
|
||||
requestURL.Path = path
|
||||
requestURL.RawQuery = args.String()
|
||||
|
||||
_, body, err := http.Post(nil, requestURI.String(), args)
|
||||
req := http.AcquireRequest()
|
||||
defer http.ReleaseRequest(req)
|
||||
req.Header.SetMethod("GET")
|
||||
req.SetRequestURI(requestURL.String())
|
||||
req.Header.SetUserAgent("toby3d/telegraph")
|
||||
req.Header.SetContentType("application/json;charset=utf-8")
|
||||
|
||||
dlog.Ln("request:")
|
||||
dlog.D(req)
|
||||
|
||||
resp := http.AcquireResponse()
|
||||
defer http.ReleaseResponse(resp)
|
||||
err = http.Do(req, resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
dlog.Ln(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var resp response
|
||||
if err := json.Unmarshal(body, &resp); err != nil {
|
||||
return nil, err
|
||||
dlog.Ln("response:")
|
||||
dlog.D(resp)
|
||||
|
||||
r = new(Response)
|
||||
if err = json.Unmarshal(resp.Body(), r); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !resp.Ok {
|
||||
return nil, errors.New(resp.Error)
|
||||
if !r.Ok {
|
||||
err = errors.New(r.Error)
|
||||
}
|
||||
|
||||
return &resp, nil
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,22 +5,26 @@ import (
|
|||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
type revokeAccessTokenParameters struct {
|
||||
// Access token of the Telegraph account.
|
||||
AccessToken string `json:"access_token"` // required
|
||||
}
|
||||
|
||||
// RevokeAccessToken revoke access_token and generate a new one, for example, if the user would
|
||||
// like to reset all connected sessions, or you have reasons to believe the token was compromised. On
|
||||
// success, returns an Account object with new access_token and auth_url fields.
|
||||
func (account *Account) RevokeAccessToken() (*Account, error) {
|
||||
func (a *Account) RevokeAccessToken() (r *Account, err error) {
|
||||
args := http.AcquireArgs()
|
||||
defer http.ReleaseArgs(args)
|
||||
args.Add("access_token", a.AccessToken)
|
||||
|
||||
// Access token of the Telegraph account.
|
||||
args.Add("access_token", account.AccessToken) // required
|
||||
|
||||
body, err := request("revokeAccessToken", "", args)
|
||||
dst := new(Response)
|
||||
dst, err = makeRequest("revokeAccessToken", args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
|
||||
var resp Account
|
||||
err = json.Unmarshal(*body.Result, &resp)
|
||||
|
||||
return &resp, err
|
||||
r = new(Account)
|
||||
err = json.Unmarshal(*dst.Result, r)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@ package telegraph_test
|
|||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/toby3d/telegraph"
|
||||
"gitlab.com/toby3d/telegraph"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -12,7 +13,7 @@ const (
|
|||
invalidContent = 42
|
||||
)
|
||||
|
||||
var invalidAccount = &telegraph.Account{}
|
||||
var invalidAccount = new(telegraph.Account)
|
||||
|
||||
func TestInvalidContentFormat(t *testing.T) {
|
||||
if _, err := telegraph.ContentFormat(invalidContent); err != telegraph.ErrInvalidDataType {
|
||||
|
@ -60,7 +61,10 @@ func testInvalidEditPage(t *testing.T) {
|
|||
}
|
||||
|
||||
func testInvalidGetAccountInfo(t *testing.T) {
|
||||
if _, err := invalidAccount.GetAccountInfo(telegraph.FieldShortName, telegraph.FieldPageCount); err == nil {
|
||||
if _, err := invalidAccount.GetAccountInfo(
|
||||
telegraph.FieldShortName,
|
||||
telegraph.FieldPageCount,
|
||||
); err == nil {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
@ -90,31 +94,46 @@ func TestInvalidGetPage(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestInvalidGetViewsByPage(t *testing.T) {
|
||||
if _, err := telegraph.GetViews(invalidPageURL, 2016, 12, 0, -1); err == nil {
|
||||
if _, err := telegraph.GetViews(
|
||||
invalidPageURL,
|
||||
time.Date(2016, time.December, 0, 0, 0, 0, 0, time.UTC),
|
||||
); err == nil {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidGetViewsByHour(t *testing.T) {
|
||||
if _, err := telegraph.GetViews(validPageURL, 0, 0, 0, 42); err == nil {
|
||||
if _, err := telegraph.GetViews(
|
||||
validPageURL,
|
||||
time.Date(0, 0, 0, 42, 0, 0, 0, time.UTC),
|
||||
); err == nil {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidGetViewsByDay(t *testing.T) {
|
||||
if _, err := telegraph.GetViews(validPageURL, 0, 0, 42, 23); err == nil {
|
||||
if _, err := telegraph.GetViews(
|
||||
validPageURL,
|
||||
time.Date(0, 0, 42, 23, 0, 0, 0, time.UTC),
|
||||
); err == nil {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidGetViewsByMonth(t *testing.T) {
|
||||
if _, err := telegraph.GetViews(validPageURL, 0, 22, 24, 23); err == nil {
|
||||
if _, err := telegraph.GetViews(
|
||||
validPageURL,
|
||||
time.Date(0, 22, 24, 23, 0, 0, 0, time.UTC),
|
||||
); err == nil {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidGetViewsByYear(t *testing.T) {
|
||||
if _, err := telegraph.GetViews(validPageURL, 1980, 12, 24, 23); err == nil {
|
||||
if _, err := telegraph.GetViews(
|
||||
validPageURL,
|
||||
time.Date(1980, time.December, 24, 23, 0, 0, 0, time.UTC),
|
||||
); err == nil {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@ package telegraph_test
|
|||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/toby3d/telegraph"
|
||||
"gitlab.com/toby3d/telegraph"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -16,10 +17,10 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
validAccount *telegraph.Account
|
||||
validPage *telegraph.Page
|
||||
validContentDOM []telegraph.Node
|
||||
|
||||
validAccount = new(telegraph.Account)
|
||||
validPage = new(telegraph.Page)
|
||||
validContent = `<p>Hello, World!</p>`
|
||||
)
|
||||
|
||||
|
@ -50,8 +51,8 @@ func testValidContentFormatByBytes(t *testing.T) {
|
|||
func TestValidCreateAccount(t *testing.T) {
|
||||
var err error
|
||||
validAccount, err = telegraph.CreateAccount(&telegraph.Account{
|
||||
ShortName: validShortName,
|
||||
AuthorName: validAuthorName,
|
||||
ShortName: validShortName,
|
||||
// AuthorName: validAuthorName,
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
|
@ -117,7 +118,10 @@ func testValidEditPage(t *testing.T) {
|
|||
}
|
||||
|
||||
func testValidGetAccountInfo(t *testing.T) {
|
||||
info, err := validAccount.GetAccountInfo(telegraph.FieldShortName, telegraph.FieldPageCount)
|
||||
info, err := validAccount.GetAccountInfo(
|
||||
telegraph.FieldShortName,
|
||||
telegraph.FieldPageCount,
|
||||
)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
t.FailNow()
|
||||
|
@ -152,15 +156,16 @@ func testValidGetPageList(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestValidGetViews(t *testing.T) {
|
||||
stats, err := telegraph.GetViews(validPageURL, 2016, 12, 0, -1)
|
||||
stats, err := telegraph.GetViews(
|
||||
validPageURL,
|
||||
time.Date(2016, time.December, 0, 0, 0, 0, 0, time.UTC),
|
||||
)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if stats.Views <= 0 {
|
||||
t.Error("get 0 views")
|
||||
}
|
||||
t.Log("get", stats.Views, "views")
|
||||
}
|
||||
|
||||
func testValidRevokeAccessToken(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
// All types used in the Telegraph API responses are represented as JSON-objects.
|
||||
// Optional fields may be not returned when irrelevant.
|
||||
package telegraph
|
||||
|
||||
import "errors"
|
||||
|
||||
type (
|
||||
// Account represents a Telegraph account.
|
||||
Account struct {
|
||||
// Only returned by the createAccount and revokeAccessToken
|
||||
// method. Access token of the Telegraph account.
|
||||
AccessToken string `json:"access_token"` // optional
|
||||
|
||||
// URL to authorize a browser on telegra.ph and connect it to a
|
||||
// Telegraph account. This URL is valid for only one use and for
|
||||
// 5 minutes only.
|
||||
AuthURL string `json:"auth_url,omitempty"` // optional
|
||||
|
||||
// Account name, helps users with several accounts remember which
|
||||
// they are currently using. Displayed to the user above the
|
||||
// "Edit/Publish" button on Telegra.ph, other users don't see
|
||||
// this name.
|
||||
ShortName string `json:"short_name"`
|
||||
|
||||
// Default author name used when creating new articles.
|
||||
AuthorName string `json:"author_name"`
|
||||
|
||||
// Profile link, opened when users click on the author's name
|
||||
// below the title. Can be any link, not necessarily to a
|
||||
// Telegram profile or channel.
|
||||
AuthorURL string `json:"author_url"`
|
||||
|
||||
// Number of pages belonging to the Telegraph account.
|
||||
PageCount int `json:"page_count,omitempty"` // optional
|
||||
}
|
||||
|
||||
// PageList represents a list of Telegraph articles belonging to an
|
||||
// account. Most recently created articles first.
|
||||
PageList struct {
|
||||
// Total number of pages belonging to the target Telegraph
|
||||
// account.
|
||||
TotalCount int `json:"total_count"`
|
||||
|
||||
// Requested pages of the target Telegraph account.
|
||||
Pages []Page `json:"pages"`
|
||||
}
|
||||
|
||||
// Page represents a page on Telegraph.
|
||||
Page struct {
|
||||
// Path to the page.
|
||||
Path string `json:"path"`
|
||||
|
||||
// URL of the page.
|
||||
URL string `json:"url"`
|
||||
|
||||
// Title of the page.
|
||||
Title string `json:"title"`
|
||||
|
||||
// Description of the page.
|
||||
Description string `json:"description"`
|
||||
|
||||
// Name of the author, displayed below the title.
|
||||
AuthorName string `json:"author_name,omitempty"` // optional
|
||||
|
||||
// Profile link, opened when users click on the author's name
|
||||
// below the title. Can be any link, not necessarily to a
|
||||
// Telegram profile or channel.
|
||||
AuthorURL string `json:"author_url,omitempty"` // optional
|
||||
|
||||
// Image URL of the page.
|
||||
ImageURL string `json:"image_url,omitempty"` // optional
|
||||
|
||||
// Content of the page.
|
||||
Content []Node `json:"content,omitempty"` // optional
|
||||
|
||||
// Number of page views for the page.
|
||||
Views int `json:"views"`
|
||||
|
||||
// Only returned if access_token passed. True, if the target
|
||||
// Telegraph account can edit the page.
|
||||
CanEdit bool `json:"can_edit,omitempty"` // optional
|
||||
}
|
||||
|
||||
// PageViews represents the number of page views for a Telegraph article.
|
||||
PageViews struct {
|
||||
// Number of page views for the target page.
|
||||
Views int `json:"views"`
|
||||
}
|
||||
|
||||
// Node is abstract object represents a DOM Node. It can be a String
|
||||
// which represents a DOM text node or a NodeElement object.
|
||||
Node interface{}
|
||||
|
||||
// NodeElement represents a DOM element node.
|
||||
NodeElement struct {
|
||||
// Name of the DOM element.
|
||||
// Available tags: a, aside, b, blockquote, br, code, em,
|
||||
// figcaption, figure, h3, h4, hr, i, iframe, img, li, ol, p,
|
||||
// pre, s, strong, u, ul, video.
|
||||
Tag string `json:"tag"`
|
||||
|
||||
// Attributes of the DOM element. Key of object represents name
|
||||
// of attribute, value represents value of attribute.
|
||||
// Available attributes: href, src.
|
||||
Attrs map[string]string `json:"attrs,omitempty"` // optional
|
||||
|
||||
// List of child nodes for the DOM element.
|
||||
Children []Node `json:"children,omitempty"` // optional
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
// FieldShortName used as GetAccountInfo argument for getting account name.
|
||||
FieldShortName = "short_name"
|
||||
|
||||
// FieldAuthorName used as GetAccountInfo argument for getting author name.
|
||||
FieldAuthorName = "author_name"
|
||||
|
||||
// FieldAuthorURL used as GetAccountInfo argument for getting profile link.
|
||||
FieldAuthorURL = "author_url"
|
||||
|
||||
// FieldAuthURL used as GetAccountInfo argument for getting URL to authorize
|
||||
// a browser on telegra.ph.
|
||||
FieldAuthURL = "auth_url"
|
||||
|
||||
// FieldPageCount used as GetAccountInfo argument for getting number of pages
|
||||
// belonging to the Telegraph account.
|
||||
FieldPageCount = "page_count"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidDataType is returned when ContentFormat function are passed
|
||||
// a data argument of invalid type.
|
||||
ErrInvalidDataType = errors.New("invalid data type")
|
||||
|
||||
// ErrNoInputData is returned when any method get nil argument.
|
||||
ErrNoInputData = errors.New("no input data")
|
||||
)
|
Loading…
Reference in New Issue