♻️ Package refactor

This commit is contained in:
Maxim Lebedev 2018-07-27 16:51:14 +05:00
parent fe6abc89bc
commit 5112c12848
No known key found for this signature in database
GPG Key ID: F8978F46FF0FFA4F
16 changed files with 409 additions and 368 deletions

32
Makefile Normal file
View File

@ -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}'

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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")

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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()
}
}

View File

@ -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) {

138
types.go Normal file
View File

@ -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")
)