-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
29d49d4
commit 8094b3e
Showing
4 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package readonly | ||
|
||
import ( | ||
"errors" | ||
"net/url" | ||
|
||
"github.com/graymeta/stow" | ||
) | ||
|
||
const ( | ||
ConfigWrappedKind = "wrapped_kind" | ||
ConfigWrapped = "wrapped" | ||
) | ||
|
||
// Kind is the kid of Location this package provides | ||
const Kind = "readonly" | ||
|
||
func init() { | ||
validatefn := func(config stow.Config) error { | ||
wrappedKind, ok := config.Config(ConfigWrappedKind) | ||
if !ok || wrappedKind == "" { | ||
return errors.New("missing wrapped kind") | ||
} | ||
wrappedConfig, ok := config.NestedConfig(ConfigWrapped) | ||
if !ok { | ||
return errors.New("missing config for wrapped") | ||
} | ||
return stow.Validate(wrappedKind, wrappedConfig) | ||
} | ||
makefn := func(config stow.Config) (stow.Location, error) { | ||
wrappedKind, ok := config.Config(ConfigWrappedKind) | ||
if !ok || wrappedKind == "" { | ||
return nil, errors.New("missing wrapped kind") | ||
} | ||
wrappedConfig, ok := config.NestedConfig(ConfigWrapped) | ||
if !ok { | ||
return nil, errors.New("missing config for wrapped") | ||
} | ||
|
||
w, err := stow.Dial(wrappedKind, wrappedConfig) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &location{wrapped: w}, nil | ||
} | ||
kindfn := func(u *url.URL) bool { | ||
return u.Scheme == Kind | ||
} | ||
|
||
stow.Register(Kind, makefn, kindfn, validatefn) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package readonly | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
|
||
"github.com/graymeta/stow" | ||
) | ||
|
||
type container struct { | ||
wrapped stow.Container | ||
} | ||
|
||
// ID gets a unique string describing this Container. | ||
func (c *container) ID() string { | ||
return c.wrapped.ID() | ||
} | ||
|
||
// Name gets a human-readable name describing this Container. | ||
func (c *container) Name() string { | ||
return c.wrapped.Name() | ||
} | ||
|
||
// Item gets an item by its ID. | ||
func (c *container) Item(id string) (stow.Item, error) { | ||
it, err := c.wrapped.Item(id) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &item{wrapped: it}, nil | ||
} | ||
|
||
// Items gets a page of items with the specified | ||
// prefix for this Container. | ||
// The specified cursor is a pointer to the start of | ||
// the items to get. It it obtained from a previous | ||
// call to this method, or should be CursorStart for the | ||
// first page. | ||
// count is the number of items to return per page. | ||
// The returned cursor can be checked with IsCursorEnd to | ||
// decide if there are any more items or not. | ||
func (c *container) Items(prefix, cursor string, count int) ([]stow.Item, string, error) { | ||
its, startAfter, err := c.wrapped.Items(prefix, cursor, count) | ||
if err != nil { | ||
return nil, "", err | ||
} | ||
|
||
wrapped := make([]stow.Item, len(its)) | ||
for i, val := range its { | ||
wrapped[i] = &item{wrapped: val} | ||
} | ||
|
||
return wrapped, startAfter, nil | ||
} | ||
|
||
// RemoveItem removes the Item with the specified ID. | ||
func (c *container) RemoveItem(id string) error { | ||
return errors.New("readonly") | ||
} | ||
|
||
// Put creates a new Item with the specified name, and contents | ||
// read from the reader. | ||
func (c *container) Put(name string, r io.Reader, size int64, metadata map[string]interface{}) (stow.Item, error) { | ||
return nil, errors.New("readonly") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package readonly | ||
|
||
import ( | ||
"io" | ||
"net/url" | ||
"time" | ||
|
||
"github.com/graymeta/stow" | ||
) | ||
|
||
type item struct { | ||
wrapped stow.Item | ||
} | ||
|
||
// ID gets a unique string describing this Item. | ||
func (i *item) ID() string { | ||
return i.wrapped.ID() | ||
} | ||
|
||
// Name gets a human-readable name describing this Item. | ||
func (i *item) Name() string { | ||
return i.wrapped.Name() | ||
} | ||
|
||
// URL gets a URL for this item. | ||
// For example: | ||
// local: file:///path/to/something | ||
// azure: azure://host:port/api/something | ||
// s3: s3://host:post/etc | ||
func (i *item) URL() *url.URL { | ||
return i.wrapped.URL() | ||
} | ||
|
||
// Size gets the size of the Item's contents in bytes. | ||
func (i *item) Size() (int64, error) { | ||
return i.wrapped.Size() | ||
} | ||
|
||
// Open opens the Item for reading. | ||
// Calling code must close the io.ReadCloser. | ||
func (i *item) Open() (io.ReadCloser, error) { | ||
return i.wrapped.Open() | ||
} | ||
|
||
// ETag is a string that is different when the Item is | ||
// different, and the same when the item is the same. | ||
// Usually this is the last modified datetime. | ||
func (i *item) ETag() (string, error) { | ||
return i.wrapped.ETag() | ||
} | ||
|
||
// LastMod returns the last modified date of the file. | ||
func (i *item) LastMod() (time.Time, error) { | ||
return i.wrapped.LastMod() | ||
} | ||
|
||
// Metadata gets a map of key/values that belong | ||
// to this Item. | ||
func (i *item) Metadata() (map[string]interface{}, error) { | ||
return i.wrapped.Metadata() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package readonly | ||
|
||
import ( | ||
"errors" | ||
"net/url" | ||
|
||
"github.com/graymeta/stow" | ||
) | ||
|
||
type location struct { | ||
wrapped stow.Location | ||
} | ||
|
||
// Closes the underlying location. | ||
func (l *location) Close() error { | ||
return l.wrapped.Close() | ||
} | ||
|
||
// CreateContainer creates a new Container with the | ||
// specified name. | ||
func (l *location) CreateContainer(name string) (stow.Container, error) { | ||
return nil, errors.New("readonly") | ||
} | ||
|
||
// Containers gets a page of containers | ||
// with the specified prefix from this Location. | ||
// The specified cursor is a pointer to the start of | ||
// the containers to get. It it obtained from a previous | ||
// call to this method, or should be CursorStart for the | ||
// first page. | ||
// count is the number of items to return per page. | ||
// The returned cursor can be checked with IsCursorEnd to | ||
// decide if there are any more items or not. | ||
func (l *location) Containers(prefix string, cursor string, count int) ([]stow.Container, string, error) { | ||
cs, startAfter, err := l.wrapped.Containers(prefix, cursor, count) | ||
if err != nil { | ||
return nil, "", err | ||
} | ||
|
||
wrapped := make([]stow.Container, len(cs)) | ||
for i, val := range cs { | ||
wrapped[i] = &container{wrapped: val} | ||
} | ||
|
||
return wrapped, startAfter, nil | ||
} | ||
|
||
// Container gets the Container with the specified | ||
// identifier. | ||
func (l *location) Container(id string) (stow.Container, error) { | ||
c, err := l.wrapped.Container(id) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &container{wrapped: c}, nil | ||
} | ||
|
||
// RemoveContainer removes the container with the specified ID. | ||
func (l *location) RemoveContainer(id string) error { | ||
return errors.New("readonly") | ||
} | ||
|
||
// ItemByURL gets an Item at this location with the | ||
// specified URL. | ||
func (l *location) ItemByURL(url *url.URL) (stow.Item, error) { | ||
i, err := l.wrapped.ItemByURL(url) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &item{wrapped: i}, nil | ||
} |