mirror of
https://github.com/miniflux/v2.git
synced 2025-06-27 16:36:00 +00:00
Add first integration test
This commit is contained in:
parent
71bf7e4358
commit
142e8b3e0c
14 changed files with 891 additions and 12 deletions
9
vendor/github.com/miniflux/miniflux-go/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/miniflux/miniflux-go/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
notifications:
|
||||
email: false
|
||||
language: go
|
||||
go:
|
||||
- 1.9
|
||||
before_install:
|
||||
- go get -u github.com/golang/lint/golint
|
||||
script:
|
||||
- golint *.go
|
21
vendor/github.com/miniflux/miniflux-go/LICENSE
generated
vendored
Normal file
21
vendor/github.com/miniflux/miniflux-go/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Frédéric Guillot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
50
vendor/github.com/miniflux/miniflux-go/README.md
generated
vendored
Normal file
50
vendor/github.com/miniflux/miniflux-go/README.md
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
Go Library for Miniflux
|
||||
=======================
|
||||
[](https://travis-ci.org/miniflux/miniflux-go)
|
||||
[](https://godoc.org/github.com/miniflux/miniflux-go)
|
||||
|
||||
Client library for Miniflux REST API.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- Miniflux >= 2.0.0
|
||||
- Go >= 1.9
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```bash
|
||||
go get -u github.com/miniflux/miniflux-go
|
||||
```
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/miniflux/miniflux-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
client := miniflux.NewClient("https://api.example.org", "admin", "secret")
|
||||
|
||||
// Fetch all feeds.
|
||||
feeds, err := userClient.Feeds()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
fmt.Println(feeds)
|
||||
}
|
||||
```
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
- Author: Frédéric Guillot
|
||||
- Distributed under MIT License
|
354
vendor/github.com/miniflux/miniflux-go/client.go
generated
vendored
Normal file
354
vendor/github.com/miniflux/miniflux-go/client.go
generated
vendored
Normal file
|
@ -0,0 +1,354 @@
|
|||
// Copyright 2017 Frédéric Guillot. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package miniflux
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Client represents a Miniflux client.
|
||||
type Client struct {
|
||||
request *request
|
||||
}
|
||||
|
||||
// Users returns all users.
|
||||
func (c *Client) Users() (Users, error) {
|
||||
body, err := c.request.Get("/v1/users")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var users Users
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&users); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// User returns a single user.
|
||||
func (c *Client) User(userID int64) (*User, error) {
|
||||
body, err := c.request.Get(fmt.Sprintf("/v1/users/%d", userID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var user User
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&user); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// CreateUser creates a new user in the system.
|
||||
func (c *Client) CreateUser(username, password string, isAdmin bool) (*User, error) {
|
||||
body, err := c.request.Post("/v1/users", &User{Username: username, Password: password, IsAdmin: isAdmin})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var user *User
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&user); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// UpdateUser updates a user in the system.
|
||||
func (c *Client) UpdateUser(user *User) (*User, error) {
|
||||
body, err := c.request.Put(fmt.Sprintf("/v1/users/%d", user.ID), user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var u *User
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&u); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// DeleteUser removes a user from the system.
|
||||
func (c *Client) DeleteUser(userID int64) error {
|
||||
body, err := c.request.Delete(fmt.Sprintf("/v1/users/%d", userID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Discover try to find subscriptions from a website.
|
||||
func (c *Client) Discover(url string) (Subscriptions, error) {
|
||||
body, err := c.request.Post("/v1/discover", map[string]string{"url": url})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var subscriptions Subscriptions
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&subscriptions); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return subscriptions, nil
|
||||
}
|
||||
|
||||
// Categories gets the list of categories.
|
||||
func (c *Client) Categories() (Categories, error) {
|
||||
body, err := c.request.Get("/v1/categories")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var categories Categories
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&categories); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return categories, nil
|
||||
}
|
||||
|
||||
// CreateCategory creates a new category.
|
||||
func (c *Client) CreateCategory(title string) (*Category, error) {
|
||||
body, err := c.request.Post("/v1/categories", map[string]interface{}{
|
||||
"title": title,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var category *Category
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&category); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return category, nil
|
||||
}
|
||||
|
||||
// UpdateCategory updates a category.
|
||||
func (c *Client) UpdateCategory(categoryID int64, title string) (*Category, error) {
|
||||
body, err := c.request.Put(fmt.Sprintf("/v1/categories/%d", categoryID), map[string]interface{}{
|
||||
"title": title,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var category *Category
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&category); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return category, nil
|
||||
}
|
||||
|
||||
// DeleteCategory removes a category.
|
||||
func (c *Client) DeleteCategory(categoryID int64) error {
|
||||
body, err := c.request.Delete(fmt.Sprintf("/v1/categories/%d", categoryID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Feeds gets all feeds.
|
||||
func (c *Client) Feeds() (Feeds, error) {
|
||||
body, err := c.request.Get("/v1/feeds")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var feeds Feeds
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&feeds); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return feeds, nil
|
||||
}
|
||||
|
||||
// Feed gets a new feed.
|
||||
func (c *Client) Feed(feedID int64) (*Feed, error) {
|
||||
body, err := c.request.Get(fmt.Sprintf("/v1/feeds/%d", feedID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var feed *Feed
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&feed); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return feed, nil
|
||||
}
|
||||
|
||||
// CreateFeed creates a new feed.
|
||||
func (c *Client) CreateFeed(url string, categoryID int64) (*Feed, error) {
|
||||
body, err := c.request.Post("/v1/feeds", map[string]interface{}{
|
||||
"feed_url": url,
|
||||
"category_id": categoryID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var feed *Feed
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&feed); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return feed, nil
|
||||
}
|
||||
|
||||
// UpdateFeed updates a feed.
|
||||
func (c *Client) UpdateFeed(feed *Feed) (*Feed, error) {
|
||||
body, err := c.request.Put(fmt.Sprintf("/v1/feeds/%d", feed.ID), feed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var f *Feed
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&f); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// RefreshFeed refresh a feed.
|
||||
func (c *Client) RefreshFeed(feedID int64) error {
|
||||
body, err := c.request.Put(fmt.Sprintf("/v1/feeds/%d/refresh", feedID), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteFeed removes a feed.
|
||||
func (c *Client) DeleteFeed(feedID int64) error {
|
||||
body, err := c.request.Delete(fmt.Sprintf("/v1/feeds/%d", feedID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Entry gets a single feed entry.
|
||||
func (c *Client) Entry(feedID, entryID int64) (*Entry, error) {
|
||||
body, err := c.request.Get(fmt.Sprintf("/v1/feeds/%d/entries/%d", feedID, entryID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var entry *Entry
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&entry); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
// Entries gets feed entries.
|
||||
func (c *Client) Entries(feedID int64, filter *Filter) (*EntryResultSet, error) {
|
||||
path := fmt.Sprintf("/v1/feeds/%d/entries", feedID)
|
||||
|
||||
if filter != nil {
|
||||
values := url.Values{}
|
||||
|
||||
if filter.Status != "" {
|
||||
values.Set("status", filter.Status)
|
||||
}
|
||||
|
||||
if filter.Direction != "" {
|
||||
values.Set("direction", filter.Direction)
|
||||
}
|
||||
|
||||
if filter.Order != "" {
|
||||
values.Set("order", filter.Order)
|
||||
}
|
||||
|
||||
if filter.Limit != 0 {
|
||||
values.Set("limit", strconv.Itoa(filter.Limit))
|
||||
}
|
||||
|
||||
if filter.Offset != 0 {
|
||||
values.Set("offset", strconv.Itoa(filter.Offset))
|
||||
}
|
||||
|
||||
path = fmt.Sprintf("%s?%s", path, values.Encode())
|
||||
}
|
||||
|
||||
body, err := c.request.Get(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
var result EntryResultSet
|
||||
decoder := json.NewDecoder(body)
|
||||
if err := decoder.Decode(&result); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: response error (%v)", err)
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// UpdateEntries updates the status of a list of entries.
|
||||
func (c *Client) UpdateEntries(entryIDs []int64, status string) error {
|
||||
type payload struct {
|
||||
EntryIDs []int64 `json:"entry_ids"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
body, err := c.request.Put("/v1/entries", &payload{EntryIDs: entryIDs, Status: status})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewClient returns a new Client.
|
||||
func NewClient(endpoint, username, password string) *Client {
|
||||
return &Client{request: &request{endpoint: endpoint, username: username, password: password}}
|
||||
}
|
31
vendor/github.com/miniflux/miniflux-go/doc.go
generated
vendored
Normal file
31
vendor/github.com/miniflux/miniflux-go/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2017 Frédéric Guillot. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
|
||||
Package miniflux implements a client library for the Miniflux REST API.
|
||||
|
||||
Examples
|
||||
|
||||
This code snippet fetch the list of users.
|
||||
|
||||
client := miniflux.NewClient("https://api.example.org", "admin", "secret")
|
||||
users, err := client.Users()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
fmt.Println(users, err)
|
||||
|
||||
This one discover subscriptions on a website.
|
||||
|
||||
subscriptions, err := client.Discover("https://example.org/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
fmt.Println(subscriptions)
|
||||
|
||||
*/
|
||||
package miniflux
|
131
vendor/github.com/miniflux/miniflux-go/miniflux.go
generated
vendored
Normal file
131
vendor/github.com/miniflux/miniflux-go/miniflux.go
generated
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2017 Frédéric Guillot. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package miniflux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Entry statuses.
|
||||
const (
|
||||
EntryStatusUnread = "unread"
|
||||
EntryStatusRead = "read"
|
||||
EntryStatusRemoved = "removed"
|
||||
)
|
||||
|
||||
// User represents a user in the system.
|
||||
type User struct {
|
||||
ID int64 `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password,omitempty"`
|
||||
IsAdmin bool `json:"is_admin"`
|
||||
Theme string `json:"theme"`
|
||||
Language string `json:"language"`
|
||||
Timezone string `json:"timezone"`
|
||||
LastLoginAt *time.Time `json:"last_login_at"`
|
||||
}
|
||||
|
||||
func (u User) String() string {
|
||||
return fmt.Sprintf("#%d - %s (admin=%v)", u.ID, u.Username, u.IsAdmin)
|
||||
}
|
||||
|
||||
// Users represents a list of users.
|
||||
type Users []User
|
||||
|
||||
// Category represents a category in the system.
|
||||
type Category struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
UserID int64 `json:"user_id,omitempty"`
|
||||
}
|
||||
|
||||
func (c Category) String() string {
|
||||
return fmt.Sprintf("#%d %s", c.ID, c.Title)
|
||||
}
|
||||
|
||||
// Categories represents a list of categories.
|
||||
type Categories []*Category
|
||||
|
||||
// Subscription represents a feed subscription.
|
||||
type Subscription struct {
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
func (s Subscription) String() string {
|
||||
return fmt.Sprintf(`Title="%s", URL="%s", Type="%s"`, s.Title, s.URL, s.Type)
|
||||
}
|
||||
|
||||
// Subscriptions represents a list of subscriptions.
|
||||
type Subscriptions []*Subscription
|
||||
|
||||
// Feed represents a Miniflux feed.
|
||||
type Feed struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
FeedURL string `json:"feed_url"`
|
||||
SiteURL string `json:"site_url"`
|
||||
Title string `json:"title"`
|
||||
CheckedAt time.Time `json:"checked_at,omitempty"`
|
||||
EtagHeader string `json:"etag_header,omitempty"`
|
||||
LastModifiedHeader string `json:"last_modified_header,omitempty"`
|
||||
ParsingErrorMsg string `json:"parsing_error_message,omitempty"`
|
||||
ParsingErrorCount int `json:"parsing_error_count,omitempty"`
|
||||
Category *Category `json:"category,omitempty"`
|
||||
Entries Entries `json:"entries,omitempty"`
|
||||
}
|
||||
|
||||
// Feeds represents a list of feeds.
|
||||
type Feeds []*Feed
|
||||
|
||||
// Entry represents a subscription item in the system.
|
||||
type Entry struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
FeedID int64 `json:"feed_id"`
|
||||
Status string `json:"status"`
|
||||
Hash string `json:"hash"`
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
Date time.Time `json:"published_at"`
|
||||
Content string `json:"content"`
|
||||
Author string `json:"author"`
|
||||
Enclosures Enclosures `json:"enclosures,omitempty"`
|
||||
Feed *Feed `json:"feed,omitempty"`
|
||||
Category *Category `json:"category,omitempty"`
|
||||
}
|
||||
|
||||
// Entries represents a list of entries.
|
||||
type Entries []*Entry
|
||||
|
||||
// Enclosure represents an attachment.
|
||||
type Enclosure struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
EntryID int64 `json:"entry_id"`
|
||||
URL string `json:"url"`
|
||||
MimeType string `json:"mime_type"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
// Enclosures represents a list of attachments.
|
||||
type Enclosures []*Enclosure
|
||||
|
||||
// Filter is used to filter entries.
|
||||
type Filter struct {
|
||||
Status string
|
||||
Offset int
|
||||
Limit int
|
||||
Order string
|
||||
Direction string
|
||||
}
|
||||
|
||||
// EntryResultSet represents the response when fetching entries.
|
||||
type EntryResultSet struct {
|
||||
Total int `json:"total"`
|
||||
Entries Entries `json:"entries"`
|
||||
}
|
136
vendor/github.com/miniflux/miniflux-go/request.go
generated
vendored
Normal file
136
vendor/github.com/miniflux/miniflux-go/request.go
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
// Copyright 2017 Frédéric Guillot. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package miniflux
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
userAgent = "Miniflux Client Library <https://github.com/miniflux/miniflux-go>"
|
||||
defaultTimeout = 80
|
||||
)
|
||||
|
||||
var (
|
||||
errNotAuthorized = errors.New("miniflux: unauthorized (bad credentials)")
|
||||
errForbidden = errors.New("miniflux: access forbidden")
|
||||
errServerError = errors.New("miniflux: internal server error")
|
||||
)
|
||||
|
||||
type errorResponse struct {
|
||||
ErrorMessage string `json:"error_message"`
|
||||
}
|
||||
|
||||
type request struct {
|
||||
endpoint string
|
||||
username string
|
||||
password string
|
||||
}
|
||||
|
||||
func (r *request) Get(path string) (io.ReadCloser, error) {
|
||||
return r.execute(http.MethodGet, path, nil)
|
||||
}
|
||||
|
||||
func (r *request) Post(path string, data interface{}) (io.ReadCloser, error) {
|
||||
return r.execute(http.MethodPost, path, data)
|
||||
}
|
||||
|
||||
func (r *request) Put(path string, data interface{}) (io.ReadCloser, error) {
|
||||
return r.execute(http.MethodPut, path, data)
|
||||
}
|
||||
|
||||
func (r *request) Delete(path string) (io.ReadCloser, error) {
|
||||
return r.execute(http.MethodDelete, path, nil)
|
||||
}
|
||||
|
||||
func (r *request) execute(method, path string, data interface{}) (io.ReadCloser, error) {
|
||||
u, err := url.Parse(r.endpoint + path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request := &http.Request{
|
||||
URL: u,
|
||||
Method: method,
|
||||
Header: r.buildHeaders(),
|
||||
}
|
||||
request.SetBasicAuth(r.username, r.password)
|
||||
|
||||
if data != nil {
|
||||
request.Body = ioutil.NopCloser(bytes.NewBuffer(r.toJSON(data)))
|
||||
}
|
||||
|
||||
client := r.buildClient()
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch response.StatusCode {
|
||||
case http.StatusUnauthorized:
|
||||
return nil, errNotAuthorized
|
||||
case http.StatusForbidden:
|
||||
return nil, errForbidden
|
||||
case http.StatusInternalServerError:
|
||||
return nil, errServerError
|
||||
case http.StatusBadRequest:
|
||||
defer response.Body.Close()
|
||||
|
||||
var resp errorResponse
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
if err := decoder.Decode(&resp); err != nil {
|
||||
return nil, fmt.Errorf("miniflux: bad request error (%v)", err)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("miniflux: bad request (%s)", resp.ErrorMessage)
|
||||
}
|
||||
|
||||
if response.StatusCode >= 400 {
|
||||
return nil, fmt.Errorf("miniflux: server error (statusCode=%d)", response.StatusCode)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
||||
|
||||
func (r *request) buildClient() http.Client {
|
||||
return http.Client{
|
||||
Timeout: time.Duration(defaultTimeout * time.Second),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *request) buildHeaders() http.Header {
|
||||
headers := make(http.Header)
|
||||
headers.Add("User-Agent", userAgent)
|
||||
headers.Add("Content-Type", "application/json")
|
||||
headers.Add("Accept", "application/json")
|
||||
return headers
|
||||
}
|
||||
|
||||
func (r *request) toJSON(v interface{}) []byte {
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
log.Println("Unable to convert interface to JSON:", err)
|
||||
return []byte("")
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func newRequest(endpoint, username, password string) *request {
|
||||
return &request{
|
||||
endpoint: endpoint,
|
||||
username: username,
|
||||
password: password,
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue