github.com/readium/readium-lcp-server@v0.0.0-20240101192032-6e95190e99f1/storage/fs.go (about) 1 // Copyright (c) 2016 Readium Foundation 2 // 3 // Redistribution and use in source and binary forms, with or without modification, 4 // are permitted provided that the following conditions are met: 5 // 6 // 1. Redistributions of source code must retain the above copyright notice, this 7 // list of conditions and the following disclaimer. 8 // 2. Redistributions in binary form must reproduce the above copyright notice, 9 // this list of conditions and the following disclaimer in the documentation and/or 10 // other materials provided with the distribution. 11 // 3. Neither the name of the organization nor the names of its contributors may be 12 // used to endorse or promote products derived from this software without specific 13 // prior written permission 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26 package storage 27 28 import ( 29 "io" 30 "io/ioutil" 31 "os" 32 "path/filepath" 33 ) 34 35 type fsStorage struct { 36 fspath string 37 url string 38 } 39 40 type fsItem struct { 41 name string 42 storageDir string 43 baseURL string 44 } 45 46 func (i fsItem) Key() string { 47 return i.name 48 } 49 50 func (i fsItem) PublicURL() string { 51 return i.baseURL + "/" + i.name 52 } 53 54 func (i fsItem) Contents() (io.ReadCloser, error) { 55 return os.Open(filepath.Join(i.storageDir, i.name)) 56 } 57 58 func (s fsStorage) Add(key string, r io.ReadSeeker) (Item, error) { 59 file, err := os.Create(filepath.Join(s.fspath, key)) 60 if err != nil { 61 return nil, err 62 } 63 defer file.Close() 64 io.Copy(file, r) 65 66 if err != nil { 67 return nil, err 68 } 69 return &fsItem{name: key, storageDir: s.fspath, baseURL: s.url}, nil 70 } 71 72 // Get returns an Item in the storage, by its key 73 // the key is the file name 74 // 75 func (s fsStorage) Get(key string) (Item, error) { 76 _, err := os.Stat(filepath.Join(s.fspath, key)) 77 if err != nil { 78 if os.IsNotExist(err) { 79 return nil, ErrNotFound 80 } 81 return nil, err 82 } 83 return &fsItem{name: key, storageDir: s.fspath, baseURL: s.url}, nil 84 } 85 86 func (s fsStorage) Remove(key string) error { 87 return os.Remove(filepath.Join(s.fspath, key)) 88 } 89 90 func (s fsStorage) List() ([]Item, error) { 91 var items []Item 92 93 files, err := ioutil.ReadDir(s.fspath) 94 if err != nil { 95 return nil, err 96 } 97 98 for _, fi := range files { 99 items = append(items, &fsItem{name: fi.Name(), storageDir: s.fspath, baseURL: s.url}) 100 } 101 102 return items, nil 103 } 104 105 // NewFileSystem creates a new storage 106 // 107 func NewFileSystem(dir, basePath string) Store { 108 return fsStorage{dir, basePath} 109 }