Skip to content

Commit 8bca075

Browse files
committed
Initial commit
0 parents  commit 8bca075

File tree

10 files changed

+612
-0
lines changed

10 files changed

+612
-0
lines changed

attachments.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dribbble
2+
3+
import "fmt"
4+
5+
// Attachments client
6+
type Attachments struct {
7+
*Client
8+
}
9+
10+
// DeleteAttachment requires the user to be authenticated with the upload scope
11+
// The authenticated user must also own the attachment
12+
func (c *Attachments) DeleteAttachment(shotID int, attachmentID int) error {
13+
body, err := c.call("DELETE", fmt.Sprintf("/shots/%d/attachments/%d", shotID, attachmentID), nil)
14+
if err != nil {
15+
return err
16+
}
17+
defer body.Close()
18+
19+
return nil
20+
}

client.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package dribbble
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"io"
7+
"net/http"
8+
"net/url"
9+
"strings"
10+
)
11+
12+
// Client struct
13+
type Client struct {
14+
*Config
15+
User *User
16+
Projects *Projects
17+
Shots *Shots
18+
Jobs *Jobs
19+
Likes *Likes
20+
Attachments *Attachments
21+
}
22+
23+
// New returns new instance of Dribbble client
24+
func New(config *Config) *Client {
25+
c := &Client{Config: config}
26+
c.User = &User{c}
27+
c.Projects = &Projects{c}
28+
c.Shots = &Shots{c}
29+
c.Jobs = &Jobs{c}
30+
c.Likes = &Likes{c}
31+
c.Attachments = &Attachments{c}
32+
return c
33+
}
34+
35+
func (c *Client) call(method string, path string, body interface{}) (io.ReadCloser, error) {
36+
ep := "https://api.dribbble.com/v2" + path
37+
u, err := url.Parse(ep)
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
var buf io.ReadWriter
43+
if body != nil {
44+
buf = new(bytes.Buffer)
45+
err := json.NewEncoder(buf).Encode(body)
46+
if err != nil {
47+
return nil, err
48+
}
49+
}
50+
51+
req, err := http.NewRequest(method, u.String(), buf)
52+
if err != nil {
53+
return nil, err
54+
}
55+
56+
req.Header.Set("Authorization", "Bearer "+c.AccessToken)
57+
req.Header.Set("Content-Type", "application/json")
58+
59+
r, _, err := c.do(req)
60+
return r, err
61+
}
62+
63+
func (c *Client) do(req *http.Request) (io.ReadCloser, int64, error) {
64+
res, err := c.HTTPClient.Do(req)
65+
if err != nil {
66+
return nil, 0, err
67+
}
68+
69+
if res.StatusCode < 400 {
70+
return res.Body, res.ContentLength, err
71+
}
72+
73+
defer res.Body.Close()
74+
75+
e := &Error{
76+
StatusCode: res.StatusCode,
77+
Message: res.Status,
78+
}
79+
80+
ct := res.Header.Get("Content-Type")
81+
if strings.Contains(ct, "text/html") {
82+
return nil, 0, e
83+
}
84+
85+
if err := json.NewDecoder(res.Body).Decode(e); err != nil {
86+
return nil, 0, err
87+
}
88+
89+
return nil, 0, e
90+
}

config.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package dribbble
2+
3+
import "net/http"
4+
5+
// Config for Dribbble Auth
6+
type Config struct {
7+
AccessToken string
8+
HTTPClient *http.Client
9+
}
10+
11+
// NewConfig for auth
12+
func NewConfig(accessToken string) *Config {
13+
return &Config{
14+
AccessToken: accessToken,
15+
HTTPClient: http.DefaultClient,
16+
}
17+
}

doc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package dribbble is Go library for interacting with Dribbble API v2
2+
package dribbble

error.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package dribbble
2+
3+
// Error response.
4+
type Error struct {
5+
StatusCode int
6+
Message string `json:"message"`
7+
}
8+
9+
// Error string.
10+
func (e *Error) Error() string {
11+
return e.Message
12+
}

jobs.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package dribbble
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"time"
7+
)
8+
9+
// Jobs client
10+
// In order to use this part of API, you will need special token
11+
type Jobs struct {
12+
*Client
13+
}
14+
15+
// JobOut schema
16+
type JobOut struct {
17+
ID int `json:"id"`
18+
OrganizationName string `json:"organization_name"`
19+
Title string `json:"title"`
20+
Location string `json:"location"`
21+
URL string `json:"url"`
22+
CreatedAt time.Time `json:"created_at"`
23+
UpdatedAt time.Time `json:"updated_at"`
24+
Active bool `json:"active"`
25+
StartsAt time.Time `json:"starts_at"`
26+
EndsAt time.Time `json:"ends_at"`
27+
Team interface{} `json:"team"`
28+
}
29+
30+
// JobIn schema
31+
type JobIn struct {
32+
OrganizationName string `json:"organization_name"`
33+
Title string `json:"title"`
34+
Location string `json:"location"`
35+
URL string `json:"url"`
36+
Active bool `json:"active"`
37+
Team interface{} `json:"team"`
38+
}
39+
40+
// GetJob with given id
41+
func (c *Jobs) GetJob(id int) (out *JobOut, err error) {
42+
body, err := c.call("GET", fmt.Sprintf("/jobs/%d", id), nil)
43+
if err != nil {
44+
return nil, err
45+
}
46+
defer body.Close()
47+
48+
err = json.NewDecoder(body).Decode(&out)
49+
return
50+
}
51+
52+
// CreateJob with given payload
53+
func (c *Jobs) CreateJob(in *JobIn) (out *JobOut, err error) {
54+
body, err := c.call("POST", "/jobs/", in)
55+
if err != nil {
56+
return nil, err
57+
}
58+
defer body.Close()
59+
60+
err = json.NewDecoder(body).Decode(&out)
61+
return
62+
}
63+
64+
// UpdateJob with given id and payload
65+
func (c *Jobs) UpdateJob(id int, in *JobIn) (out *JobOut, err error) {
66+
body, err := c.call("PUT", fmt.Sprintf("/jobs/%d", id), in)
67+
if err != nil {
68+
return nil, err
69+
}
70+
defer body.Close()
71+
72+
err = json.NewDecoder(body).Decode(&out)
73+
return
74+
}

likes.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package dribbble
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"time"
7+
)
8+
9+
// Likes client
10+
type Likes struct {
11+
*Client
12+
}
13+
14+
// LikeOut response structure
15+
type LikeOut struct {
16+
ID int `json:"id"`
17+
CreatedAt time.Time `json:"created_at"`
18+
Shot struct {
19+
ID int `json:"id"`
20+
Title string `json:"title"`
21+
Description string `json:"description"`
22+
Images struct {
23+
Hidpi interface{} `json:"hidpi"`
24+
Normal string `json:"normal"`
25+
Teaser string `json:"teaser"`
26+
} `json:"images"`
27+
PublishedAt time.Time `json:"published_at"`
28+
HTMLURL string `json:"html_url"`
29+
Height int `json:"height"`
30+
Width int `json:"width"`
31+
} `json:"shot"`
32+
User struct {
33+
ID int `json:"id"`
34+
Name string `json:"name"`
35+
Login string `json:"login"`
36+
HTMLURL string `json:"html_url"`
37+
} `json:"user"`
38+
}
39+
40+
// LikedShotOut response structure
41+
type LikedShotOut struct {
42+
ID int `json:"id"`
43+
CreatedAt time.Time `json:"created_at"`
44+
}
45+
46+
// GetLikes returns list of authenticated user’s liked shots
47+
// Note: This is available only to select applications with our approval
48+
func (c *Likes) GetLikes() (out *[]LikeOut, err error) {
49+
body, err := c.call("GET", "/user/likes", nil)
50+
if err != nil {
51+
return nil, err
52+
}
53+
defer body.Close()
54+
55+
err = json.NewDecoder(body).Decode(&out)
56+
return
57+
}
58+
59+
// GetShotLike checks if you like a shot
60+
// Note: This is available only to select applications with our approval
61+
func (c *Likes) GetShotLike(id int) (out *LikedShotOut, err error) {
62+
body, err := c.call("GET", fmt.Sprintf("/shots/%d/like", id), nil)
63+
if err != nil {
64+
return nil, err
65+
}
66+
defer body.Close()
67+
68+
err = json.NewDecoder(body).Decode(&out)
69+
return
70+
}
71+
72+
// LikeShot with given id
73+
// Note: This is available only to select applications with our approval
74+
func (c *Likes) LikeShot(id int) (out *LikedShotOut, err error) {
75+
body, err := c.call("POST", fmt.Sprintf("/shots/%d/like", id), nil)
76+
if err != nil {
77+
return nil, err
78+
}
79+
defer body.Close()
80+
81+
err = json.NewDecoder(body).Decode(&out)
82+
return
83+
}
84+
85+
// UnlikeShot with given id
86+
// Note: This is available only to select applications with our approval
87+
// Unliking a shot requires the user to be authenticated with the write scope
88+
func (c *Likes) UnlikeShot(id int) error {
89+
body, err := c.call("DELETE", fmt.Sprintf("/shots/%d/like", id), nil)
90+
if err != nil {
91+
return err
92+
}
93+
defer body.Close()
94+
95+
return nil
96+
}

projects.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package dribbble
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"time"
7+
)
8+
9+
// Projects client
10+
type Projects struct {
11+
*Client
12+
}
13+
14+
// ProjectOut response structure
15+
type ProjectOut struct {
16+
ID int `json:"id"`
17+
Name string `json:"name"`
18+
Description string `json:"description"`
19+
ShotsCount int `json:"shots_count"`
20+
CreatedAt time.Time `json:"created_at"`
21+
UpdatedAt time.Time `json:"updated_at"`
22+
}
23+
24+
// ProjectIn payload structure
25+
type ProjectIn struct {
26+
Name string `json:"name"`
27+
Description string `json:"description"`
28+
}
29+
30+
// GetProjects of authenticated user
31+
func (c *Projects) GetProjects() (out *[]ProjectOut, err error) {
32+
body, err := c.call("GET", "/user/projects", nil)
33+
if err != nil {
34+
return nil, err
35+
}
36+
defer body.Close()
37+
38+
err = json.NewDecoder(body).Decode(&out)
39+
return
40+
}
41+
42+
// CreateProject with given payload
43+
func (c *Projects) CreateProject(in *ProjectIn) (out *ProjectOut, err error) {
44+
body, err := c.call("POST", "/projects", in)
45+
if err != nil {
46+
return nil, err
47+
}
48+
defer body.Close()
49+
50+
err = json.NewDecoder(body).Decode(&out)
51+
return
52+
}
53+
54+
// UpdateProject with given id
55+
func (c *Projects) UpdateProject(id int, in *ProjectIn) (out *ProjectOut, err error) {
56+
body, err := c.call("PUT", fmt.Sprintf("/projects/%d", id), in)
57+
if err != nil {
58+
return nil, err
59+
}
60+
defer body.Close()
61+
62+
err = json.NewDecoder(body).Decode(&out)
63+
return
64+
}
65+
66+
// DeleteProject with given id
67+
func (c *Projects) DeleteProject(id int) error {
68+
body, err := c.call("DELETE", fmt.Sprintf("/projects/%d", id), nil)
69+
if err != nil {
70+
return err
71+
}
72+
defer body.Close()
73+
74+
return nil
75+
}

0 commit comments

Comments
 (0)