1
0
Fork 0
photos/pkg/bucket/bucket.go

107 lines
2.2 KiB
Go

package bucket
import (
"errors"
"fmt"
"net/url"
"strings"
)
type Bucket string
const bucketMetadataPrefix = "metadata/"
var ErrorInvalidBucket = errors.New("invalid bucket")
func (b Bucket) Validate() error {
// Ensure is URL
u, err := url.ParseRequestURI(string(b))
if err != nil {
return fmt.Errorf("%w: %v: %v", ErrorInvalidBucket, err.Error(), b)
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("%w: %v", ErrorInvalidBucket, b)
}
if u.Host == "" || !strings.HasSuffix(u.Path, "/") {
return fmt.Errorf("%w: %v", ErrorInvalidBucket, b)
}
return nil
}
func (b Bucket) String() string {
return string(b)
}
func (b Bucket) URL(p Pathable) *url.URL {
u, _ := url.ParseRequestURI(string(b))
path := p.Path()
u.Path = pathJoin(u.Path, path.Path)
u.RawQuery = path.RawQuery
return u
}
func (b Bucket) ListURL(maxKeys int, startAfter string) *url.URL {
list := newList(photoPrefix, maxKeys, startAfter)
return b.URL(list)
}
func pathJoin(paths ...string) string {
cleanedPaths := make([]string, 0, len(paths))
for i, path := range paths {
cleanedPath := strings.TrimPrefix(path, "/")
if i != len(paths)-1 {
cleanedPath = strings.TrimSuffix(cleanedPath, "/")
}
if i == 0 && len(cleanedPath) == 0 {
continue
}
cleanedPaths = append(cleanedPaths, cleanedPath)
}
return "/" + strings.Join(cleanedPaths, "/")
}
type Pathable interface {
Path() *url.URL
}
type BucketMetadata string
func (b Bucket) Metadata(name string) BucketMetadata {
return BucketMetadata(bucketMetadataPrefix + name)
}
func (m BucketMetadata) String() string {
return string(m)
}
func (m BucketMetadata) Path() *url.URL {
return &url.URL{
Path: string(m),
}
}
func (b Bucket) MetadataTitle() BucketMetadata {
return b.Metadata("title")
}
func (b Bucket) MetadataDescription() BucketMetadata {
return b.Metadata("description")
}
func (b Bucket) MetadataOrdering() BucketMetadata {
return b.Metadata("ordering")
}
type index string
func (i index) Path() *url.URL {
return &url.URL{
Path: "/" + string(i) + "index.html",
}
}
func (b Bucket) ViewURL() *url.URL {
return b.URL(index(""))
}
func (b Bucket) ManageURL() *url.URL {
return b.URL(index("manage/"))
}