-
Notifications
You must be signed in to change notification settings - Fork 20
/
client.go
152 lines (130 loc) · 4.36 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package gphotos
import (
"context"
"net/http"
"github.com/hashicorp/go-retryablehttp"
"github.com/gphotosuploader/google-photos-api-client-go/v2/albums"
"github.com/gphotosuploader/google-photos-api-client-go/v2/media_items"
"github.com/gphotosuploader/google-photos-api-client-go/v2/uploader/basic"
)
// Client is a Google Photos client with enhanced capabilities.
type Client struct {
Albums AlbumsService
MediaItems MediaItemsService
Uploader MediaUploader
}
// UploadFileToLibrary uploads the specified file to Google Photos.
func (c Client) UploadFileToLibrary(ctx context.Context, filePath string) (media_items.MediaItem, error) {
token, err := c.Uploader.UploadFile(ctx, filePath)
if err != nil {
return media_items.MediaItem{}, err
}
return c.MediaItems.Create(ctx, media_items.SimpleMediaItem{
UploadToken: token,
FileName: filePath,
})
}
// UploadFileToAlbum uploads the specified file to the album in Google Photos.
func (c Client) UploadFileToAlbum(ctx context.Context, albumId string, filePath string) (media_items.MediaItem, error) {
token, err := c.Uploader.UploadFile(ctx, filePath)
if err != nil {
return media_items.MediaItem{}, err
}
item := media_items.SimpleMediaItem{
UploadToken: token,
FileName: filePath,
}
return c.MediaItems.CreateToAlbum(ctx, albumId, item)
}
// clientWithRetryPolicy returns a HTTP client with a retry policy.
func clientWithRetryPolicy(authenticatedClient *http.Client) *http.Client {
client := retryablehttp.NewClient()
client.CheckRetry = defaultGPhotosRetryPolicy
client.Logger = nil // Disable DEBUG logs
client.HTTPClient = authenticatedClient
return client.StandardClient()
}
// defaultGPhotosClient returns a gphotos client using the defaults.
// The client is an HTTP client used for calling Google Photos. It needs the proper authentication in place.
// By default it will use a in memory cache for Albums repository and implements retries with Exponential backoff.
func defaultGPhotosClient(authenticatedClient *http.Client) (*Client, error) {
client := clientWithRetryPolicy(authenticatedClient)
var albumsService AlbumsService = albums.NewCachedAlbumsService(client)
var upldr MediaUploader
upldr, err := basic.NewBasicUploader(client)
if err != nil {
return nil, err
}
var mediaItemsService MediaItemsService
mediaItemsService, err = media_items.NewHttpMediaItemsService(client)
if err != nil {
return nil, err
}
return &Client{
Albums: albumsService,
MediaItems: mediaItemsService,
Uploader: upldr,
}, nil
}
// NewClient constructs a new gphotos.Client from the provided HTTP client and the given options.
// The client is an HTTP client used for calling Google Photos. It needs the proper authentication in place.
//
// By default it will use a in memory cache for Albums repository and implements retries with Exponential backoff.
//
// Use WithUploader(), WithAlbumsService(), WithMediaItemsService() to customize it.
//
// There is a resumable uploader implemented on uploader.NewResumableUploader().
func NewClient(authenticatedClient *http.Client, options ...Option) (*Client, error) {
client, err := defaultGPhotosClient(authenticatedClient)
if err != nil {
return nil, err
}
for _, o := range options {
switch o.Name() {
case optkeyUploader:
client.Uploader = o.Value().(MediaUploader)
case optkeyAlbumsService:
client.Albums = o.Value().(AlbumsService)
case optkeyMediaItemsService:
client.MediaItems = o.Value().(MediaItemsService)
}
}
return client, nil
}
const (
optkeyUploader = "uploader"
optkeyAlbumsService = "albumService"
optkeyMediaItemsService = "mediaItemsService"
)
// Option represents a configurable parameter.
type Option interface {
Name() string
Value() interface{}
}
type option struct {
name string
value interface{}
}
func (o option) Name() string { return o.name }
func (o option) Value() interface{} { return o.value }
// WithUploader configures the Media Uploader.
func WithUploader(s MediaUploader) *option {
return &option{
name: optkeyUploader,
value: s,
}
}
// WithAlbumsService configures the Albums Service.
func WithAlbumsService(s AlbumsService) *option {
return &option{
name: optkeyAlbumsService,
value: s,
}
}
// WithMediaItemsService configures the Media Items Service.
func WithMediaItemsService(s MediaItemsService) *option {
return &option{
name: optkeyMediaItemsService,
value: s,
}
}