hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

filename_filter_fs.go (3982B)

    1 // Copyright 2021 The Hugo Authors. All rights reserved.
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 // http://www.apache.org/licenses/LICENSE-2.0
    7 //
    8 // Unless required by applicable law or agreed to in writing, software
    9 // distributed under the License is distributed on an "AS IS" BASIS,
   10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   11 // See the License for the specific language governing permissions and
   12 // limitations under the License.
   13 
   14 package hugofs
   15 
   16 import (
   17 	"os"
   18 	"strings"
   19 	"syscall"
   20 	"time"
   21 
   22 	"github.com/gohugoio/hugo/hugofs/glob"
   23 	"github.com/spf13/afero"
   24 )
   25 
   26 var (
   27 	_ FilesystemUnwrapper = (*filenameFilterFs)(nil)
   28 )
   29 
   30 func newFilenameFilterFs(fs afero.Fs, base string, filter *glob.FilenameFilter) afero.Fs {
   31 	return &filenameFilterFs{
   32 		fs:     fs,
   33 		base:   base,
   34 		filter: filter,
   35 	}
   36 }
   37 
   38 // filenameFilterFs is a filesystem that filters by filename.
   39 type filenameFilterFs struct {
   40 	base string
   41 	fs   afero.Fs
   42 
   43 	filter *glob.FilenameFilter
   44 }
   45 
   46 func (fs *filenameFilterFs) UnwrapFilesystem() afero.Fs {
   47 	return fs.fs
   48 }
   49 
   50 func (fs *filenameFilterFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
   51 	fi, b, err := fs.fs.(afero.Lstater).LstatIfPossible(name)
   52 	if err != nil {
   53 		return nil, false, err
   54 	}
   55 	if !fs.filter.Match(name, fi.IsDir()) {
   56 		return nil, false, os.ErrNotExist
   57 	}
   58 	return fi, b, nil
   59 }
   60 
   61 func (fs *filenameFilterFs) Open(name string) (afero.File, error) {
   62 	fi, err := fs.fs.Stat(name)
   63 	if err != nil {
   64 		return nil, err
   65 	}
   66 
   67 	if !fs.filter.Match(name, fi.IsDir()) {
   68 		return nil, os.ErrNotExist
   69 	}
   70 
   71 	f, err := fs.fs.Open(name)
   72 	if err != nil {
   73 		return nil, err
   74 	}
   75 
   76 	if !fi.IsDir() {
   77 		return f, nil
   78 	}
   79 
   80 	return &filenameFilterDir{
   81 		File:   f,
   82 		base:   fs.base,
   83 		filter: fs.filter,
   84 	}, nil
   85 }
   86 
   87 func (fs *filenameFilterFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
   88 	return fs.Open(name)
   89 }
   90 
   91 func (fs *filenameFilterFs) Stat(name string) (os.FileInfo, error) {
   92 	fi, _, err := fs.LstatIfPossible(name)
   93 	return fi, err
   94 }
   95 
   96 func (fs *filenameFilterFs) getOpener(name string) func() (afero.File, error) {
   97 	return func() (afero.File, error) {
   98 		return fs.Open(name)
   99 	}
  100 }
  101 
  102 type filenameFilterDir struct {
  103 	afero.File
  104 	base   string
  105 	filter *glob.FilenameFilter
  106 }
  107 
  108 func (f *filenameFilterDir) Readdir(count int) ([]os.FileInfo, error) {
  109 	fis, err := f.File.Readdir(-1)
  110 	if err != nil {
  111 		return nil, err
  112 	}
  113 
  114 	var result []os.FileInfo
  115 	for _, fi := range fis {
  116 		fim := fi.(FileMetaInfo)
  117 		if f.filter.Match(strings.TrimPrefix(fim.Meta().Filename, f.base), fim.IsDir()) {
  118 			result = append(result, fi)
  119 		}
  120 	}
  121 
  122 	return result, nil
  123 }
  124 
  125 func (f *filenameFilterDir) Readdirnames(count int) ([]string, error) {
  126 	dirsi, err := f.Readdir(count)
  127 	if err != nil {
  128 		return nil, err
  129 	}
  130 
  131 	dirs := make([]string, len(dirsi))
  132 	for i, d := range dirsi {
  133 		dirs[i] = d.Name()
  134 	}
  135 	return dirs, nil
  136 }
  137 
  138 func (fs *filenameFilterFs) Chmod(n string, m os.FileMode) error {
  139 	return syscall.EPERM
  140 }
  141 
  142 func (fs *filenameFilterFs) Chtimes(n string, a, m time.Time) error {
  143 	return syscall.EPERM
  144 }
  145 
  146 func (fs *filenameFilterFs) Chown(n string, uid, gid int) error {
  147 	return syscall.EPERM
  148 }
  149 
  150 func (fs *filenameFilterFs) ReadDir(name string) ([]os.FileInfo, error) {
  151 	panic("not implemented")
  152 }
  153 
  154 func (fs *filenameFilterFs) Remove(n string) error {
  155 	return syscall.EPERM
  156 }
  157 
  158 func (fs *filenameFilterFs) RemoveAll(p string) error {
  159 	return syscall.EPERM
  160 }
  161 
  162 func (fs *filenameFilterFs) Rename(o, n string) error {
  163 	return syscall.EPERM
  164 }
  165 func (fs *filenameFilterFs) Create(n string) (afero.File, error) {
  166 	return nil, syscall.EPERM
  167 }
  168 func (fs *filenameFilterFs) Name() string {
  169 	return "FinameFilterFS"
  170 }
  171 
  172 func (fs *filenameFilterFs) Mkdir(n string, p os.FileMode) error {
  173 	return syscall.EPERM
  174 }
  175 
  176 func (fs *filenameFilterFs) MkdirAll(n string, p os.FileMode) error {
  177 	return syscall.EPERM
  178 }