github.com/pbberlin/tools@v0.0.0-20160910141205-7aa5421c2169/os/fsi/dsfs/21_fs_new.go (about)

     1  package dsfs
     2  
     3  import (
     4  	"os"
     5  	"sort"
     6  
     7  	"github.com/pbberlin/tools/os/fsi"
     8  
     9  	"golang.org/x/net/context"
    10  	"google.golang.org/appengine/datastore"
    11  
    12  	aelog "google.golang.org/appengine/log"
    13  )
    14  
    15  // AeContext is an option func, adding ae context to the filesystem
    16  func AeContext(c context.Context) func(fsi.FileSystem) {
    17  	return func(fs fsi.FileSystem) {
    18  		fst := fs.(*dsFileSys)
    19  		fst.c = c
    20  	}
    21  }
    22  
    23  // MountName is an option func, adding a specific mount name to the filesystem
    24  func MountName(mnt string) func(fsi.FileSystem) {
    25  	return func(fs fsi.FileSystem) {
    26  		fst := fs.(*dsFileSys)
    27  		fst.mount = mnt
    28  	}
    29  }
    30  
    31  // Default sort for ReadDir... is ByNameAsc
    32  // We may want to change this; for instance sort byDate
    33  func DirSort(srt string) func(fsi.FileSystem) {
    34  	return func(fs fsi.FileSystem) {
    35  		fst := fs.(*dsFileSys)
    36  		switch srt {
    37  		case "byDateAsc":
    38  			fst.dirsorter = func(fis []os.FileInfo) { sort.Sort(FileInfoByDateAsc(fis)) }
    39  			fst.filesorter = func(fis []DsFile) { sort.Sort(DsFileByDateAsc(fis)) }
    40  		case "byDateDesc":
    41  			fst.dirsorter = func(fis []os.FileInfo) { sort.Sort(FileInfoByDateDesc(fis)) }
    42  			fst.filesorter = func(fis []DsFile) { sort.Sort(DsFileByDateDesc(fis)) }
    43  		case "byName":
    44  			fst.dirsorter = func(fis []os.FileInfo) { sort.Sort(FileInfoByName(fis)) }
    45  			fst.filesorter = func(fis []DsFile) { sort.Sort(DsFileByName(fis)) }
    46  		}
    47  	}
    48  }
    49  
    50  // New creates a new appengine datastore filesystem.
    51  // Notice that variadic options are submitted as functions,
    52  // as is explained and justified here:
    53  // http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
    54  func New(options ...func(fsi.FileSystem)) *dsFileSys {
    55  
    56  	fs := dsFileSys{}
    57  
    58  	fs.dirsorter = func(fis []os.FileInfo) { sort.Sort(FileInfoByName(fis)) }
    59  	fs.filesorter = func(fis []DsFile) { sort.Sort(DsFileByName(fis)) }
    60  
    61  	for _, option := range options {
    62  		option(&fs)
    63  	}
    64  
    65  	if fs.mount == "" {
    66  		fs.mount = MountPointLast()
    67  	}
    68  
    69  	if fs.c == nil {
    70  		panic("this type of filesystem needs appengine context, submitted as option")
    71  	}
    72  
    73  	rt, err := fs.dirByPath(fs.mount)
    74  	_ = rt
    75  	if err == datastore.ErrNoSuchEntity {
    76  		rt, err = fs.saveDirByPath(fs.mount) // fine
    77  		if err != nil {
    78  			aelog.Errorf(fs.c, "could not create mount %v => %v", fs.mount, err)
    79  		} else {
    80  		}
    81  	} else if err != nil {
    82  		aelog.Errorf(fs.c, "could read mount dir %v => %v", fs.mount, err)
    83  	} else {
    84  		// fs.Ctx().Infof("Found rtdr %v  %v  %v ", rt.Dir, rt.BName, rt.Key)
    85  	}
    86  
    87  	return &fs
    88  }
    89  
    90  func (fs *dsFileSys) Ctx() context.Context {
    91  	return fs.c
    92  }
    93  
    94  func (fs *dsFileSys) RootDir() string {
    95  	return fs.mount + sep
    96  }
    97  
    98  func (fs *dsFileSys) RootName() string {
    99  	return fs.mount
   100  }
   101  
   102  func Unwrap(fs fsi.FileSystem) (*dsFileSys, bool) {
   103  	fsc, ok := fs.(*dsFileSys)
   104  	return fsc, ok
   105  }