Skip to content

Commit

Permalink
Add Notes endpoints
Browse files Browse the repository at this point in the history
Pinboard notes are basically bookmarks with text bodies. The API only
allows listing all or retrieving a singular notes, and the schema
between the two are incompatible. Using a single type anyways, the API
docs cover this well enough. The date format is unique and requires
another unmarshaler (NotesDate).
  • Loading branch information
drags committed Nov 10, 2019
1 parent 9f266f6 commit 0064cc4
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
15 changes: 14 additions & 1 deletion encoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,21 @@ func (u UTCDate) MarshalText() ([]byte, error) {

func (u *UTCDate) UnmarshalText(text []byte) error {
d, err := time.Parse("2006-01-02", string(text))

*u = UTCDate{d}
return err
}

type NotesDate struct {
time.Time
}

func (n NotesDate) MarshalText() ([]byte, error) {
s := n.UTC().Format("2006-01-02 15:04:05")
return []byte(s), nil
}

func (n *NotesDate) UnmarshalText(text []byte) error {
d, err := time.Parse("2006-01-02 15:04:05", string(text))
*n = NotesDate{d}
return err
}
66 changes: 66 additions & 0 deletions notes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package pinboard

import (
"encoding/xml"
"fmt"
"net/url"
"regexp"
)

type Notes struct {
XMLName xml.Name `xml:"notes"`
Notes []Note `xml:"note"`
}

type Note struct {
XMLName xml.Name `xml:"note"`
ID string `xml:"id,attr"`
Title string `xml:"title"`
Hash string `xml:"hash"`
Created NotesDate `xml:"created_at"`
Updated NotesDate `xml:"updated_at"`
Length int `xml:"length"`
Text string `xml:"text"`
}

func (p *Pinboard) Notes() ([]Note, error) {
u, err := url.Parse(apiBase + "notes/list")
if err != nil {
return []Note{}, fmt.Errorf("Failed to parse Notes list API URL: %v", err)
}

resp, err := p.Get(u)
if err != nil {
return []Note{}, err
}

tmp, err := parseResponse(resp, &Notes{})
if err != nil {
return []Note{}, fmt.Errorf("Failed to parse Notes response: %v", err)
}
notes := tmp.(*Notes)
return notes.Notes, err
}

func (p *Pinboard) Note(noteID string) (Note, error) {
if m, _ := regexp.Match("[a-z0-9]{20}", []byte(noteID)); !m {
return Note{}, fmt.Errorf("Note ID must be a 20 character sha1 hash")
}

u, err := url.Parse(apiBase + "notes/" + noteID)
if err != nil {
return Note{}, fmt.Errorf("Failed to parse note URL: %v", err)
}

resp, err := p.Get(u)
if err != nil {
return Note{}, fmt.Errorf("Error getting note: %v", err)
}

tmp, err := parseResponse(resp, &Note{})
if err != nil {
return Note{}, fmt.Errorf("Failed to parse Note response: %v", err)
}
note := tmp.(*Note)
return *note, err
}

0 comments on commit 0064cc4

Please sign in to comment.