blob: 1dda7a3bb1786dc0585724e9fb26426292c477e8 [file] [log] [blame]
Jon Perritt8c93a302014-09-28 22:35:57 -05001package objects
2
3import (
4 "fmt"
5 "io/ioutil"
Jon Perritt8c93a302014-09-28 22:35:57 -05006 "strings"
7
Jon Perrittea4e3012014-10-09 22:03:19 -05008 objectstorage "github.com/rackspace/gophercloud/openstack/objectstorage/v1"
Jon Perritt8c93a302014-09-28 22:35:57 -05009 "github.com/rackspace/gophercloud/pagination"
Jon Perrittea4e3012014-10-09 22:03:19 -050010
11 "github.com/mitchellh/mapstructure"
Jon Perritt8c93a302014-09-28 22:35:57 -050012)
13
14// Object is a structure that holds information related to a storage object.
Jon Perritt8aa40262014-09-29 15:41:32 -050015type Object struct {
Jon Perrittf3171c12014-09-30 17:39:31 -050016 Bytes int `json:"bytes" mapstructure:"bytes"`
17 ContentType string `json:"content_type" mapstructure:"content_type"`
18 Hash string `json:"hash" mapstructure:"hash"`
19 LastModified string `json:"last_modified" mapstructure:"last_modified"`
20 Name string `json:"name" mapstructure:"name"`
Jon Perritt8aa40262014-09-29 15:41:32 -050021}
Jon Perritt8c93a302014-09-28 22:35:57 -050022
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +020023// ObjectPage is a single page of objects that is returned from a call to the
24// List function.
Jon Perritt8c93a302014-09-28 22:35:57 -050025type ObjectPage struct {
26 pagination.MarkerPageBase
27}
28
29// IsEmpty returns true if a ListResult contains no object names.
30func (r ObjectPage) IsEmpty() (bool, error) {
31 names, err := ExtractNames(r)
32 if err != nil {
33 return true, err
34 }
35 return len(names) == 0, nil
36}
37
38// LastMarker returns the last object name in a ListResult.
39func (r ObjectPage) LastMarker() (string, error) {
40 names, err := ExtractNames(r)
41 if err != nil {
42 return "", err
43 }
44 if len(names) == 0 {
45 return "", nil
46 }
47 return names[len(names)-1], nil
48}
49
Jon Perritt8c93a302014-09-28 22:35:57 -050050// ExtractInfo is a function that takes a page of objects and returns their full information.
51func ExtractInfo(page pagination.Page) ([]Object, error) {
52 untyped := page.(ObjectPage).Body.([]interface{})
53 results := make([]Object, len(untyped))
54 for index, each := range untyped {
Jon Perritt8aa40262014-09-29 15:41:32 -050055 object := each.(map[string]interface{})
Jon Perrittfdac6e52014-09-29 19:43:45 -050056 err := mapstructure.Decode(object, &results[index])
Jon Perritt8aa40262014-09-29 15:41:32 -050057 if err != nil {
58 return results, err
59 }
Jon Perritt8c93a302014-09-28 22:35:57 -050060 }
61 return results, nil
62}
63
64// ExtractNames is a function that takes a page of objects and returns only their names.
65func ExtractNames(page pagination.Page) ([]string, error) {
66 casted := page.(ObjectPage)
67 ct := casted.Header.Get("Content-Type")
Jon Perritt8c93a302014-09-28 22:35:57 -050068 switch {
69 case strings.HasPrefix(ct, "application/json"):
70 parsed, err := ExtractInfo(page)
71 if err != nil {
72 return nil, err
73 }
74
75 names := make([]string, 0, len(parsed))
76 for _, object := range parsed {
Jon Perritt8aa40262014-09-29 15:41:32 -050077 names = append(names, object.Name)
Jon Perritt8c93a302014-09-28 22:35:57 -050078 }
Jon Perrittfdac6e52014-09-29 19:43:45 -050079
Jon Perritt8c93a302014-09-28 22:35:57 -050080 return names, nil
81 case strings.HasPrefix(ct, "text/plain"):
82 names := make([]string, 0, 50)
83
84 body := string(page.(ObjectPage).Body.([]uint8))
85 for _, name := range strings.Split(body, "\n") {
86 if len(name) > 0 {
87 names = append(names, name)
88 }
89 }
90
91 return names, nil
Jon Perrittfdac6e52014-09-29 19:43:45 -050092 case strings.HasPrefix(ct, "text/html"):
93 return []string{}, nil
Jon Perritt8c93a302014-09-28 22:35:57 -050094 default:
95 return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct)
96 }
97}
98
Jon Perritt5db08922014-09-30 21:32:48 -050099// DownloadResult is a *http.Response that is returned from a call to the Download function.
100type DownloadResult struct {
Jon Perrittea4e3012014-10-09 22:03:19 -0500101 objectstorage.CommonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500102}
103
Jon Perritt8c93a302014-09-28 22:35:57 -0500104// ExtractContent is a function that takes a DownloadResult (of type *http.Response)
105// and returns the object's content.
106func (dr DownloadResult) ExtractContent() ([]byte, error) {
107 if dr.Err != nil {
108 return nil, nil
109 }
110 var body []byte
111 defer dr.Resp.Body.Close()
112 body, err := ioutil.ReadAll(dr.Resp.Body)
113 if err != nil {
114 return body, fmt.Errorf("Error trying to read DownloadResult body: %v", err)
115 }
116 return body, nil
117}
118
Jon Perritt5db08922014-09-30 21:32:48 -0500119// GetResult is a *http.Response that is returned from a call to the Get function.
120type GetResult struct {
Jon Perrittea4e3012014-10-09 22:03:19 -0500121 objectstorage.CommonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500122}
123
Jon Perritt8c93a302014-09-28 22:35:57 -0500124// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
125// and returns the custom metadata associated with the object.
126func (gr GetResult) ExtractMetadata() (map[string]string, error) {
127 if gr.Err != nil {
128 return nil, gr.Err
129 }
130 metadata := make(map[string]string)
131 for k, v := range gr.Resp.Header {
132 if strings.HasPrefix(k, "X-Object-Meta-") {
133 key := strings.TrimPrefix(k, "X-Object-Meta-")
134 metadata[key] = v[0]
135 }
136 }
137 return metadata, nil
138}
Jon Perritt5db08922014-09-30 21:32:48 -0500139
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200140// CreateResult represents the result of a create operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500141type CreateResult struct {
Jon Perrittea4e3012014-10-09 22:03:19 -0500142 objectstorage.CommonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500143}
144
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200145// UpdateResult represents the result of an update operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500146type UpdateResult struct {
Jon Perrittea4e3012014-10-09 22:03:19 -0500147 objectstorage.CommonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500148}
149
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200150// DeleteResult represents the result of a delete operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500151type DeleteResult struct {
Jon Perrittea4e3012014-10-09 22:03:19 -0500152 objectstorage.CommonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500153}
154
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200155// CopyResult represents the result of a copy operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500156type CopyResult struct {
Jon Perrittea4e3012014-10-09 22:03:19 -0500157 objectstorage.CommonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500158}