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  }