Skip to content

Commit

Permalink
Merge pull request #27 from ochronus/highlights
Browse files Browse the repository at this point in the history
Highlights
  • Loading branch information
ochronus authored Oct 6, 2020
2 parents 855b4c5 + b144318 commit f372722
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 66 deletions.
80 changes: 32 additions & 48 deletions instapaper/bookmarks.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,14 @@ type BookmarkAddRequestParams struct {
PrivateSourceName string
}

// BookmarkService defines the interface for all bookmark related API operations
type bookmarkService interface {
List(BookmarkListRequestParams) ([]Bookmark, error)
GetText(int) (string, error)
Star(int) error
UnStar(int) error
Archive(int) error
UnArchive(int) error
DeletePermanently(int) error
Move(int, string) error
UpdateReadProgress(int, float32, int64)
Add(BookmarkAddRequestParams) (Bookmark, error)
}

// BookmarkServiceOp is the implementation of the bookmark related parts of the API client, conforming to the BookmarkService interface
type BookmarkServiceOp struct {
// BookmarkService is the implementation of the bookmark related parts of the API client, conforming to the BookmarkService interface
type BookmarkService struct {
Client Client
}

// List returns the list of bookmarks. By default it returns (maximum) 500 of the unread bookmarks
// see BookmarkListRequestParams for filtering options
func (svc *BookmarkServiceOp) List(p BookmarkListRequestParams) (*BookmarkListResponse, error) {
func (svc *BookmarkService) List(p BookmarkListRequestParams) (*BookmarkListResponse, error) {
params := url.Values{}
params.Set("limit", strconv.Itoa(p.Limit))
if p.CustomHaveParam != "" {
Expand All @@ -97,37 +83,35 @@ func (svc *BookmarkServiceOp) List(p BookmarkListRequestParams) (*BookmarkListRe
res, err := svc.Client.Call("/bookmarks/list", params)
if err != nil {
return &BookmarkListResponse{}, err
} else {
var bookmarkList BookmarkListResponse
bodyBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, &APIError{
}
var bookmarkList BookmarkListResponse
bodyBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, &APIError{
StatusCode: res.StatusCode,
Message: err.Error(),
ErrorCode: ErrHTTPError,
WrappedError: err,
}
}
bodyString := string(bodyBytes)
bookmarkList.RawResponse = bodyString
err = json.Unmarshal([]byte(bodyString), &bookmarkList)
if err != nil {
return &BookmarkListResponse{
RawResponse: bodyString,
}, &APIError{
StatusCode: res.StatusCode,
Message: err.Error(),
ErrorCode: ErrHTTPError,
ErrorCode: ErrUnmarshalError,
WrappedError: err,
}
}
bodyString := string(bodyBytes)
bookmarkList.RawResponse = bodyString
err = json.Unmarshal([]byte(bodyString), &bookmarkList)
if err != nil {
return &BookmarkListResponse{
RawResponse: bodyString,
}, &APIError{
StatusCode: res.StatusCode,
Message: err.Error(),
ErrorCode: ErrUnmarshalError,
WrappedError: err,
}
}
return &bookmarkList, nil
}

return &bookmarkList, nil
}

// GetText returns the specified bookmark's processed text-view HTML, which is always text/html encoded as UTF-8.
func (svc *BookmarkServiceOp) GetText(bookmarkID int) (string, error) {
func (svc *BookmarkService) GetText(bookmarkID int) (string, error) {
params := url.Values{}
params.Set("bookmark_id", strconv.Itoa(bookmarkID))
res, err := svc.Client.Call("/bookmarks/get_text", params)
Expand All @@ -148,47 +132,47 @@ func (svc *BookmarkServiceOp) GetText(bookmarkID int) (string, error) {
}

// Star stars the specified bookmark
func (svc *BookmarkServiceOp) Star(bookmarkID int) error {
func (svc *BookmarkService) Star(bookmarkID int) error {
params := url.Values{}
params.Set("bookmark_id", strconv.Itoa(bookmarkID))
_, err := svc.Client.Call("/bookmarks/star", params)
return err
}

// UnStar un-stars the specified bookmark
func (svc *BookmarkServiceOp) UnStar(bookmarkID int) error {
func (svc *BookmarkService) UnStar(bookmarkID int) error {
params := url.Values{}
params.Set("bookmark_id", strconv.Itoa(bookmarkID))
_, err := svc.Client.Call("/bookmarks/unstar", params)
return err
}

// Archive archives the specified bookmark
func (svc *BookmarkServiceOp) Archive(bookmarkID int) error {
func (svc *BookmarkService) Archive(bookmarkID int) error {
params := url.Values{}
params.Set("bookmark_id", strconv.Itoa(bookmarkID))
_, err := svc.Client.Call("/bookmarks/archive", params)
return err
}

// UnArchive un-archives the specified bookmark
func (svc *BookmarkServiceOp) UnArchive(bookmarkID int) error {
func (svc *BookmarkService) UnArchive(bookmarkID int) error {
params := url.Values{}
params.Set("bookmark_id", strconv.Itoa(bookmarkID))
_, err := svc.Client.Call("/bookmarks/unarchive", params)
return err
}

// DeletePermanently PERMANENTLY deletes the specified bookmark
func (svc *BookmarkServiceOp) DeletePermanently(bookmarkID int) error {
func (svc *BookmarkService) DeletePermanently(bookmarkID int) error {
params := url.Values{}
params.Set("bookmark_id", strconv.Itoa(bookmarkID))
_, err := svc.Client.Call("/bookmarks/delete", params)
return err
}

// Move moves the specified bookmark to the specified folder
func (svc *BookmarkServiceOp) Move(bookmarkID int, folderID string) error {
func (svc *BookmarkService) Move(bookmarkID int, folderID string) error {
params := url.Values{}
params.Set("bookmark_id", strconv.Itoa(bookmarkID))
params.Set("folder_id", folderID)
Expand All @@ -199,7 +183,7 @@ func (svc *BookmarkServiceOp) Move(bookmarkID int, folderID string) error {
// UpdateReadProgress updates the read progress on the bookmark
// progress is between 0.0 and 1.0 - a percentage
// when - Unix timestamp - optionally specify when the update happened. If it's set to 0 the current timestamp is used.
func (svc *BookmarkServiceOp) UpdateReadProgress(bookmarkID int, progress float32, when int64) error {
func (svc *BookmarkService) UpdateReadProgress(bookmarkID int, progress float32, when int64) error {
if when == 0 {
when = time.Now().Unix()
}
Expand All @@ -212,7 +196,7 @@ func (svc *BookmarkServiceOp) UpdateReadProgress(bookmarkID int, progress float3
}

// Add adds a new bookmark from the specified URL
func (svc *BookmarkServiceOp) Add(p BookmarkAddRequestParams) (*Bookmark, error) {
func (svc *BookmarkService) Add(p BookmarkAddRequestParams) (*Bookmark, error) {
params := url.Values{}
params.Set("url", p.URL)
if p.Description != "" {
Expand Down
12 changes: 6 additions & 6 deletions instapaper/bookmarks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestWithoutAuthentication(t *testing.T) {
client.Credentials = nil
mux.HandleFunc("/bookmarks/list", func(w http.ResponseWriter, r *http.Request) {
})
svc := BookmarkServiceOp{
svc := BookmarkService{
Client: client,
}
_, err := svc.List(DefaultBookmarkListRequestParams)
Expand All @@ -59,7 +59,7 @@ func TestBogusValidResponse(t *testing.T) {
}
fmt.Fprint(w, rawResponse)
})
svc := BookmarkServiceOp{
svc := BookmarkService{
Client: client,
}
bookmarkList, err := svc.List(DefaultBookmarkListRequestParams)
Expand All @@ -80,7 +80,7 @@ func TestInvalidResponse(t *testing.T) {
mux.HandleFunc("/bookmarks/list", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, rawResponse)
})
svc := BookmarkServiceOp{
svc := BookmarkService{
Client: client,
}
bookmarkList, err := svc.List(DefaultBookmarkListRequestParams)
Expand All @@ -100,7 +100,7 @@ func TestNot200OKResponse(t *testing.T) {
mux.HandleFunc("/bookmarks/list", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
})
svc := BookmarkServiceOp{
svc := BookmarkService{
Client: client,
}
bookmarkList, err := svc.List(DefaultBookmarkListRequestParams)
Expand Down Expand Up @@ -173,7 +173,7 @@ func TestValidResponse(t *testing.T) {
BookmarkID: 123456,
Text: "That said, I do have some feelings on the matter.",
Note: "",
Time: 1601797631,
Time: "1601797631",
Position: 0,
},
},
Expand All @@ -185,7 +185,7 @@ func TestValidResponse(t *testing.T) {
}
fmt.Fprint(w, rawResponse)
})
svc := BookmarkServiceOp{
svc := BookmarkService{
Client: client,
}
bookmarkList, err := svc.List(DefaultBookmarkListRequestParams)
Expand Down
17 changes: 6 additions & 11 deletions instapaper/folders.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,13 @@ const FolderIDStarred = "starred"
// FolderIDArchive is a built-in folder for archived bookmarks
const FolderIDArchive = "archive"

type folderService interface {
List() ([]Folder, error)
}

// FolderServiceOp encapsulates all folder operations
type FolderServiceOp struct {
// FolderService encapsulates all folder operations
type FolderService struct {
Client Client
}

// List returns the list of *custom created* folders. It does not return any of the built in ones!
func (svc *FolderServiceOp) List() ([]Folder, error) {
func (svc *FolderService) List() ([]Folder, error) {
res, err := svc.Client.Call("/folders/list", nil)
if err != nil {
return nil, err
Expand All @@ -60,12 +56,11 @@ func (svc *FolderServiceOp) List() ([]Folder, error) {
WrappedError: err,
}
}
fmt.Println(string(bodyBytes))
return folderList, nil
}

// Add creates a folder and returns with it if there wasn't already one with the same title - in that case it returns an error
func (svc *FolderServiceOp) Add(title string) (*Folder, error) {
func (svc *FolderService) Add(title string) (*Folder, error) {
params := url.Values{}
params.Set("title", title)
res, err := svc.Client.Call("/folders/add", params)
Expand Down Expand Up @@ -95,7 +90,7 @@ func (svc *FolderServiceOp) Add(title string) (*Folder, error) {
}

// Delete removes a folder and moves all of its bookmark entries to the archive
func (svc *FolderServiceOp) Delete(folderID string) error {
func (svc *FolderService) Delete(folderID string) error {
params := url.Values{}
params.Set("folder_id", folderID)
_, err := svc.Client.Call("/folders/delete", params)
Expand All @@ -111,7 +106,7 @@ func (svc *FolderServiceOp) Delete(folderID string) error {
// the order of the pairs in the list does not matter.
// You should include all folders for consistency.
// !!!No errors returned for missing or invalid folders!!!
func (svc *FolderServiceOp) SetOrder(folderOrderlist string) ([]Folder, error) {
func (svc *FolderService) SetOrder(folderOrderlist string) ([]Folder, error) {
params := url.Values{}
params.Set("order", folderOrderlist)
res, err := svc.Client.Call("/folders/set_order", params)
Expand Down
85 changes: 84 additions & 1 deletion instapaper/highlights.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,94 @@
package instapaper

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/url"
"strconv"
)

// Highlight represents a highlight within a bookmark
type Highlight struct {
ID int `json:"highlight_id"`
BookmarkID int `json:"bookmark_id"`
Text string
Note string
Time int
Time json.Number
Position int
}

type HighlightService struct {
Client Client
}

// List fetches all highlights for the specified bookmark
func (svc *HighlightService) List(bookmarkID int) ([]Highlight, error) {
path := fmt.Sprintf("/bookmarks/%d/highlights", bookmarkID)
res, err := svc.Client.Call(path, nil)
if err != nil {
return nil, err
}
bodyBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, &APIError{
StatusCode: res.StatusCode,
Message: err.Error(),
ErrorCode: ErrHTTPError,
WrappedError: err,
}
}
var highlightList []Highlight
err = json.Unmarshal(bodyBytes, &highlightList)
if err != nil {
return nil, &APIError{
StatusCode: res.StatusCode,
Message: err.Error(),
ErrorCode: ErrUnmarshalError,
WrappedError: err,
}
}
return highlightList, nil
}

// Delete removes the specified highlight
func (svc *HighlightService) Delete(highlightID int) error {
path := fmt.Sprintf("/highlights/%d/delete", highlightID)
_, err := svc.Client.Call(path, nil)
if err != nil {
return err
}
return nil
}

// Add adds a highlight for the specified bookmark
func (svc *HighlightService) Add(bookmarkID int, text string, position int) (*Highlight, error) {
path := fmt.Sprintf("/bookmarks/%d/highlight", bookmarkID)
params := url.Values{}
params.Set("text", text)
params.Set("position", strconv.Itoa(position))
res, err := svc.Client.Call(path, params)
if err != nil {
return nil, err
}
bodyBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, &APIError{
StatusCode: res.StatusCode,
Message: err.Error(),
ErrorCode: ErrHTTPError,
WrappedError: err,
}
}
var highlightList []Highlight
err = json.Unmarshal(bodyBytes, &highlightList)
if err != nil {
return nil, &APIError{
StatusCode: res.StatusCode,
Message: err.Error(),
ErrorCode: ErrUnmarshalError,
WrappedError: err,
}
}
return &highlightList[0], nil
}

0 comments on commit f372722

Please sign in to comment.