github.com/puellanivis/breton@v0.2.16/lib/files/home/home.go (about) 1 // Package home implements a URL scheme "home:" which references files according to user home directories. 2 package home 3 4 import ( 5 "context" 6 "io/ioutil" 7 "net/url" 8 "os" 9 "path/filepath" 10 11 "github.com/puellanivis/breton/lib/files" 12 "github.com/puellanivis/breton/lib/os/user" 13 ) 14 15 var userDir string 16 17 type handler struct{} 18 19 func init() { 20 var err error 21 22 // Short-circuit figuring out the whole User, in case we're on Windows. 23 userDir, err = user.CurrentHomeDir() 24 if err != nil { 25 return 26 } 27 28 files.RegisterScheme(&handler{}, "home") 29 } 30 31 // Filename takes a given url, and returns a filename that is an absolute path 32 // for the specific default user if home:filename, or a specific user if home://user@/filename. 33 func Filename(uri *url.URL) (string, error) { 34 if uri.Host != "" { 35 return "", os.ErrInvalid 36 } 37 38 path := uri.Path 39 if path == "" { 40 path = uri.Opaque 41 } 42 43 dir := userDir 44 45 if uri.User != nil { 46 u, err := user.Lookup(uri.User.Username()) 47 if err != nil { 48 return "", err 49 } 50 51 if u.HomeDir != "" { 52 dir = u.HomeDir 53 } 54 } 55 56 return filepath.Join(dir, path), nil 57 } 58 59 func (h *handler) Open(ctx context.Context, uri *url.URL) (files.Reader, error) { 60 filename, err := Filename(uri) 61 if err != nil { 62 return nil, files.PathError("open", uri.String(), err) 63 } 64 65 return os.Open(filename) 66 } 67 68 func (h *handler) Create(ctx context.Context, uri *url.URL) (files.Writer, error) { 69 filename, err := Filename(uri) 70 if err != nil { 71 return nil, files.PathError("create", uri.String(), err) 72 } 73 74 return os.Create(filename) 75 } 76 77 func (h *handler) List(ctx context.Context, uri *url.URL) ([]os.FileInfo, error) { 78 filename, err := Filename(uri) 79 if err != nil { 80 return nil, files.PathError("readdir", uri.String(), err) 81 } 82 83 return ioutil.ReadDir(filename) 84 }