blob: f85f1acfa5d4fc0d1146f56b961306ed0c437a48 [file] [log] [blame]
Jon Perritt8c93a302014-09-28 22:35:57 -05001package objects
2
3import (
4 "fmt"
Jon Perritt8c93a302014-09-28 22:35:57 -05005 "strings"
6
Ash Wilsonaf262872014-10-20 09:32:29 -04007 "github.com/rackspace/gophercloud"
Jon Perritt8c93a302014-09-28 22:35:57 -05008 "github.com/rackspace/gophercloud/pagination"
Jon Perrittea4e3012014-10-09 22:03:19 -05009
10 "github.com/mitchellh/mapstructure"
Jon Perritt8c93a302014-09-28 22:35:57 -050011)
12
13// Object is a structure that holds information related to a storage object.
Jon Perritt8aa40262014-09-29 15:41:32 -050014type Object struct {
Jon Perrittf3171c12014-09-30 17:39:31 -050015 Bytes int `json:"bytes" mapstructure:"bytes"`
16 ContentType string `json:"content_type" mapstructure:"content_type"`
17 Hash string `json:"hash" mapstructure:"hash"`
18 LastModified string `json:"last_modified" mapstructure:"last_modified"`
19 Name string `json:"name" mapstructure:"name"`
Jon Perritt8aa40262014-09-29 15:41:32 -050020}
Jon Perritt8c93a302014-09-28 22:35:57 -050021
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +020022// ObjectPage is a single page of objects that is returned from a call to the
23// List function.
Jon Perritt8c93a302014-09-28 22:35:57 -050024type ObjectPage struct {
25 pagination.MarkerPageBase
26}
27
28// IsEmpty returns true if a ListResult contains no object names.
29func (r ObjectPage) IsEmpty() (bool, error) {
30 names, err := ExtractNames(r)
31 if err != nil {
32 return true, err
33 }
34 return len(names) == 0, nil
35}
36
37// LastMarker returns the last object name in a ListResult.
38func (r ObjectPage) LastMarker() (string, error) {
39 names, err := ExtractNames(r)
40 if err != nil {
41 return "", err
42 }
43 if len(names) == 0 {
44 return "", nil
45 }
46 return names[len(names)-1], nil
47}
48
Jon Perritt8c93a302014-09-28 22:35:57 -050049// ExtractInfo is a function that takes a page of objects and returns their full information.
50func ExtractInfo(page pagination.Page) ([]Object, error) {
51 untyped := page.(ObjectPage).Body.([]interface{})
52 results := make([]Object, len(untyped))
53 for index, each := range untyped {
Jon Perritt8aa40262014-09-29 15:41:32 -050054 object := each.(map[string]interface{})
Jon Perrittfdac6e52014-09-29 19:43:45 -050055 err := mapstructure.Decode(object, &results[index])
Jon Perritt8aa40262014-09-29 15:41:32 -050056 if err != nil {
57 return results, err
58 }
Jon Perritt8c93a302014-09-28 22:35:57 -050059 }
60 return results, nil
61}
62
63// ExtractNames is a function that takes a page of objects and returns only their names.
64func ExtractNames(page pagination.Page) ([]string, error) {
65 casted := page.(ObjectPage)
Ash Wilson72e4d2c2014-10-20 10:27:30 -040066 ct := casted.Header.Get("Content-Type")
Jon Perritt8c93a302014-09-28 22:35:57 -050067 switch {
68 case strings.HasPrefix(ct, "application/json"):
69 parsed, err := ExtractInfo(page)
70 if err != nil {
71 return nil, err
72 }
73
74 names := make([]string, 0, len(parsed))
75 for _, object := range parsed {
Jon Perritt8aa40262014-09-29 15:41:32 -050076 names = append(names, object.Name)
Jon Perritt8c93a302014-09-28 22:35:57 -050077 }
Jon Perrittfdac6e52014-09-29 19:43:45 -050078
Jon Perritt8c93a302014-09-28 22:35:57 -050079 return names, nil
80 case strings.HasPrefix(ct, "text/plain"):
81 names := make([]string, 0, 50)
82
83 body := string(page.(ObjectPage).Body.([]uint8))
84 for _, name := range strings.Split(body, "\n") {
85 if len(name) > 0 {
86 names = append(names, name)
87 }
88 }
89
90 return names, nil
Jon Perrittfdac6e52014-09-29 19:43:45 -050091 case strings.HasPrefix(ct, "text/html"):
92 return []string{}, nil
Jon Perritt8c93a302014-09-28 22:35:57 -050093 default:
94 return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct)
95 }
96}
97
Jon Perritt2b36fa32014-10-24 15:44:23 -050098type commonResult struct {
99 gophercloud.Result
100}
101
Jon Perritt5db08922014-09-30 21:32:48 -0500102// DownloadResult is a *http.Response that is returned from a call to the Download function.
103type DownloadResult struct {
Jon Perritt2b36fa32014-10-24 15:44:23 -0500104 commonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500105}
106
Jon Perritt8c93a302014-09-28 22:35:57 -0500107// ExtractContent is a function that takes a DownloadResult (of type *http.Response)
108// and returns the object's content.
109func (dr DownloadResult) ExtractContent() ([]byte, error) {
110 if dr.Err != nil {
Ash Wilsonaf262872014-10-20 09:32:29 -0400111 return nil, dr.Err
Jon Perritt8c93a302014-09-28 22:35:57 -0500112 }
Ash Wilsond3dc2542014-10-20 10:10:48 -0400113 return dr.Body.([]byte), nil
Jon Perritt8c93a302014-09-28 22:35:57 -0500114}
115
Jon Perritt5db08922014-09-30 21:32:48 -0500116// GetResult is a *http.Response that is returned from a call to the Get function.
117type GetResult struct {
Jon Perritt2b36fa32014-10-24 15:44:23 -0500118 commonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500119}
120
Jon Perritt8c93a302014-09-28 22:35:57 -0500121// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
122// and returns the custom metadata associated with the object.
123func (gr GetResult) ExtractMetadata() (map[string]string, error) {
124 if gr.Err != nil {
125 return nil, gr.Err
126 }
127 metadata := make(map[string]string)
Ash Wilson72e4d2c2014-10-20 10:27:30 -0400128 for k, v := range gr.Header {
Jon Perritt8c93a302014-09-28 22:35:57 -0500129 if strings.HasPrefix(k, "X-Object-Meta-") {
130 key := strings.TrimPrefix(k, "X-Object-Meta-")
131 metadata[key] = v[0]
132 }
133 }
134 return metadata, nil
135}
Jon Perritt5db08922014-09-30 21:32:48 -0500136
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200137// CreateResult represents the result of a create operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500138type CreateResult struct {
Jon Perritt2b36fa32014-10-24 15:44:23 -0500139 commonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500140}
141
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200142// UpdateResult represents the result of an update operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500143type UpdateResult struct {
Jon Perritt2b36fa32014-10-24 15:44:23 -0500144 commonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500145}
146
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200147// DeleteResult represents the result of a delete operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500148type DeleteResult struct {
Jon Perritt2b36fa32014-10-24 15:44:23 -0500149 commonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500150}
151
Jamie Hannafordc9cdc8f2014-10-06 16:32:56 +0200152// CopyResult represents the result of a copy operation.
Jon Perritt5db08922014-09-30 21:32:48 -0500153type CopyResult struct {
Jon Perritt2b36fa32014-10-24 15:44:23 -0500154 commonResult
Jon Perritt5db08922014-09-30 21:32:48 -0500155}