gifs/api
gifs/api/storage.go
Remove user info from memstore. Remove all the user related methods and properties from the memstore, as those are all going to be superseded by code.secondbit.org/auth anyways.
1 package api
3 import (
4 "errors"
5 "io"
6 "io/ioutil"
7 "log"
8 "net/http"
10 "code.google.com/p/google-api-go-client/googleapi"
11 "code.google.com/p/google-api-go-client/storage/v1beta2"
12 )
14 var (
15 BucketNotFoundError = errors.New("bucket not found")
16 BlobNotFoundError = errors.New("blob not found")
17 )
19 type Storage interface {
20 Upload(bucket, tmp string, r io.Reader, errs chan error, done chan struct{})
21 Delete(bucket, tmp string) error
22 Move(srcBucket, src, dstBucket, dst string) error
23 Download(bucket, id string, w io.Writer) (int64, error)
24 }
26 type GoogleCloudStorage struct {
27 *storage.Service
28 }
30 func (gcs *GoogleCloudStorage) Upload(bucket, tmp string, r io.Reader, errs chan error, done chan struct{}) {
31 if errs != nil {
32 defer close(errs)
33 }
34 if done != nil {
35 defer close(done)
36 }
37 object := &storage.Object{Name: tmp}
38 _, err := gcs.Objects.Insert(bucket, object).Media(r).Do()
39 if err != nil && errs != nil {
40 errs <- err
41 }
42 }
44 func (gcs *GoogleCloudStorage) Delete(bucket, tmp string) error {
45 return gcs.Objects.Delete(bucket, tmp).Do()
46 }
48 func (gcs *GoogleCloudStorage) Move(srcBucket, src, dstBucket, dst string) error {
49 _, err := gcs.Objects.Get(dstBucket, dst).Do()
50 if err == nil {
51 go gcs.del(srcBucket, src)
52 return nil
53 }
54 if e, ok := err.(*googleapi.Error); !ok || e.Code != 404 {
55 return err
56 }
57 _, err = gcs.Objects.Copy(srcBucket, src, dstBucket, dst, nil).Do()
58 if err != nil {
59 return err
60 }
61 objectAcl := &storage.ObjectAccessControl{
62 Bucket: dstBucket, Entity: "allUsers", Object: dst, Role: "READER",
63 }
64 _, err = gcs.ObjectAccessControls.Insert(dstBucket, dst, objectAcl).Do()
65 if err != nil {
66 return err
67 }
68 go gcs.del(srcBucket, src)
69 return nil
70 }
72 func (gcs *GoogleCloudStorage) del(bucket, tmp string) {
73 err := gcs.Delete(bucket, tmp)
74 if err != nil {
75 log.Printf("Error deleting temporary upload %s in %s: %s\n", tmp, bucket, err)
76 }
77 }
79 func (gcs *GoogleCloudStorage) Download(bucket, id string, w io.Writer) (int64, error) {
80 res, err := gcs.Objects.Get(bucket, id).Do()
81 if err != nil {
82 return 0, err
83 }
84 resp, err := http.Get(res.MediaLink)
85 if err != nil {
86 return 0, err
87 }
88 defer resp.Body.Close()
89 return io.Copy(w, resp.Body)
90 }
92 type Memstorage map[string]Bucket
94 type Bucket map[string][]byte
96 func (m Memstorage) Upload(bucket, tmp string, r io.Reader, errs chan error, done chan struct{}) {
97 if errs != nil {
98 defer close(errs)
99 }
100 if done != nil {
101 defer close(done)
102 }
103 if _, ok := m[bucket]; !ok {
104 m[bucket] = make(Bucket)
105 }
106 bytes, err := ioutil.ReadAll(r)
107 if err != nil {
108 errs <- err
109 return
110 }
111 m[bucket][tmp] = bytes
112 }
114 func (m Memstorage) Delete(bucket, tmp string) error {
115 delete(m[bucket], tmp)
116 return nil
117 }
119 func (m Memstorage) Move(srcBucket, src, dstBucket, dst string) error {
120 if _, ok := m[srcBucket]; !ok {
121 return BucketNotFoundError
122 }
123 if _, ok := m[srcBucket][src]; !ok {
124 return BlobNotFoundError
125 }
126 if _, ok := m[dstBucket]; !ok {
127 m[dstBucket] = make(Bucket)
128 }
129 m[dstBucket][dst] = m[srcBucket][src]
130 return m.Delete(srcBucket, src)
131 }
133 func (m Memstorage) Download(bucket, id string, w io.Writer) (int64, error) {
134 if _, ok := m[bucket]; !ok {
135 return 0, BucketNotFoundError
136 }
137 if _, ok := m[bucket][id]; !ok {
138 return 0, BlobNotFoundError
139 }
140 n, err := w.Write(m[bucket][id])
141 return int64(n), err
142 }