diff --git a/cmd/cache.go b/cmd/cache.go index a56eb86..2abd50a 100644 --- a/cmd/cache.go +++ b/cmd/cache.go @@ -15,24 +15,24 @@ import ( "seedno.de/seednode/roulette/types" ) -type FileIndex struct { +type fileCache struct { mutex sync.RWMutex list []string } -func (i *FileIndex) Index() []string { - i.mutex.RLock() - val := i.list - i.mutex.RUnlock() +func (cache *fileCache) List() []string { + cache.mutex.RLock() + val := cache.list + cache.mutex.RUnlock() return val } -func (i *FileIndex) Remove(path string) { - i.mutex.RLock() - tempIndex := make([]string, len(i.list)) - copy(tempIndex, i.list) - i.mutex.RUnlock() +func (cache *fileCache) remove(path string) { + cache.mutex.RLock() + tempIndex := make([]string, len(cache.list)) + copy(tempIndex, cache.list) + cache.mutex.RUnlock() var position int @@ -46,39 +46,39 @@ func (i *FileIndex) Remove(path string) { tempIndex[position] = tempIndex[len(tempIndex)-1] - i.mutex.Lock() - i.list = make([]string, len(tempIndex)-1) - copy(i.list, tempIndex[:len(tempIndex)-1]) - i.mutex.Unlock() + cache.mutex.Lock() + cache.list = make([]string, len(tempIndex)-1) + copy(cache.list, tempIndex[:len(tempIndex)-1]) + cache.mutex.Unlock() } -func (i *FileIndex) setIndex(val []string) { - i.mutex.Lock() - i.list = val - i.mutex.Unlock() +func (cache *fileCache) set(val []string) { + cache.mutex.Lock() + cache.list = val + cache.mutex.Unlock() } -func (i *FileIndex) generateCache(args []string, formats *types.Types) { - i.mutex.Lock() - i.list = []string{} - i.mutex.Unlock() +func (cache *fileCache) generate(args []string, formats *types.Types) { + cache.mutex.Lock() + cache.list = []string{} + cache.mutex.Unlock() - fileList(args, &Filters{}, "", i, formats) + fileList(args, &filters{}, "", cache, formats) if Cache && CacheFile != "" { - i.Export(CacheFile) + cache.Export(CacheFile) } } -func (i *FileIndex) IsEmpty() bool { - i.mutex.RLock() - length := len(i.list) - i.mutex.RUnlock() +func (cache *fileCache) isEmpty() bool { + cache.mutex.RLock() + length := len(cache.list) + cache.mutex.RUnlock() return length == 0 } -func (i *FileIndex) Export(path string) error { +func (cache *fileCache) Export(path string) error { file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err @@ -93,16 +93,14 @@ func (i *FileIndex) Export(path string) error { enc := gob.NewEncoder(z) - i.mutex.RLock() - - enc.Encode(&i.list) - - i.mutex.RUnlock() + cache.mutex.RLock() + enc.Encode(&cache.list) + cache.mutex.RUnlock() return nil } -func (i *FileIndex) Import(path string) error { +func (cache *fileCache) Import(path string) error { file, err := os.OpenFile(path, os.O_RDONLY, 0600) if err != nil { return err @@ -117,11 +115,11 @@ func (i *FileIndex) Import(path string) error { dec := gob.NewDecoder(z) - i.mutex.Lock() + cache.mutex.Lock() - err = dec.Decode(&i.list) + err = dec.Decode(&cache.list) - i.mutex.Unlock() + cache.mutex.Unlock() if err != nil { return err @@ -130,9 +128,9 @@ func (i *FileIndex) Import(path string) error { return nil } -func serveCacheClear(args []string, index *FileIndex, formats *types.Types) httprouter.Handle { +func serveCacheClear(args []string, cache *fileCache, formats *types.Types) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - index.generateCache(args, formats) + cache.generate(args, formats) w.Header().Set("Content-Type", "text/plain") diff --git a/cmd/errors.go b/cmd/errors.go index 9af51b8..f526a45 100644 --- a/cmd/errors.go +++ b/cmd/errors.go @@ -24,7 +24,7 @@ func newErrorPage(title, body string) string { var htmlBody strings.Builder htmlBody.WriteString(``) - htmlBody.WriteString(FaviconHtml) + htmlBody.WriteString(faviconHtml) htmlBody.WriteString(``) htmlBody.WriteString(fmt.Sprintf("%s", title)) htmlBody.WriteString(fmt.Sprintf("%s", body)) @@ -32,13 +32,13 @@ func newErrorPage(title, body string) string { return htmlBody.String() } -func notFound(w http.ResponseWriter, r *http.Request, filePath string) error { +func notFound(w http.ResponseWriter, r *http.Request, path string) error { startTime := time.Now() if Verbose { fmt.Printf("%s | Unavailable file %s requested by %s\n", - startTime.Format(LogDate), - filePath, + startTime.Format(logDate), + path, r.RemoteAddr, ) } @@ -59,7 +59,7 @@ func serverError(w http.ResponseWriter, r *http.Request, i interface{}) { if Verbose { fmt.Printf("%s | Invalid request for %s from %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), r.URL.Path, r.RemoteAddr, ) diff --git a/cmd/favicons.go b/cmd/favicons.go index 4d54056..5350529 100644 --- a/cmd/favicons.go +++ b/cmd/favicons.go @@ -18,7 +18,7 @@ import ( var favicons embed.FS const ( - FaviconHtml string = ` + faviconHtml string = ` diff --git a/cmd/files.go b/cmd/files.go index bc2a6af..15c6845 100644 --- a/cmd/files.go +++ b/cmd/files.go @@ -31,51 +31,51 @@ const ( maxFileScans maxConcurrency = 256 ) -type Regexes struct { +type regexes struct { alphanumeric *regexp.Regexp filename *regexp.Regexp } -type Concurrency struct { +type concurrency struct { directoryScans chan int fileScans chan int } -type Files struct { +type files struct { mutex sync.RWMutex list map[string][]string } -func (f *Files) Append(directory, path string) { +func (f *files) append(directory, path string) { f.mutex.Lock() f.list[directory] = append(f.list[directory], path) f.mutex.Unlock() } -type ScanStats struct { +type scanStats struct { filesMatched atomic.Uint32 filesSkipped atomic.Uint32 directoriesMatched atomic.Uint32 directoriesSkipped atomic.Uint32 } -type Path struct { +type splitPath struct { base string number int extension string } -func (p *Path) increment() { - p.number = p.number + 1 +func (splitPath *splitPath) increment() { + splitPath.number = splitPath.number + 1 } -func (p *Path) decrement() { - p.number = p.number - 1 +func (splitPath *splitPath) decrement() { + splitPath.number = splitPath.number - 1 } -func contains(s []string, e string) bool { - for _, a := range s { - if a == e { +func contains(slice []string, value string) bool { + for _, v := range slice { + if v == value { return true } } @@ -102,15 +102,15 @@ func humanReadableSize(bytes int) string { func preparePath(path string) string { if runtime.GOOS == "windows" { - return fmt.Sprintf("%s/%s", MediaPrefix, filepath.ToSlash(path)) + return fmt.Sprintf("%s/%s", mediaPrefix, filepath.ToSlash(path)) } - return MediaPrefix + path + return mediaPrefix + path } -func appendPath(directory, path string, files *Files, stats *ScanStats, formats *types.Types, shouldCache bool) error { +func appendPath(directory, path string, files *files, stats *scanStats, formats *types.Types, shouldCache bool) error { if shouldCache { - registered, _, _, err := types.FileType(path, formats) + registered, _, _, err := formats.FileType(path) if err != nil { return err } @@ -120,15 +120,15 @@ func appendPath(directory, path string, files *Files, stats *ScanStats, formats } } - files.Append(directory, path) + files.append(directory, path) stats.filesMatched.Add(1) return nil } -func appendPaths(path string, files *Files, filters *Filters, stats *ScanStats, formats *types.Types) error { - shouldCache := Cache && filters.IsEmpty() +func appendPaths(path string, files *files, filters *filters, stats *scanStats, formats *types.Types) error { + shouldCache := Cache && filters.isEmpty() absolutePath, err := filepath.Abs(path) if err != nil { @@ -139,11 +139,11 @@ func appendPaths(path string, files *Files, filters *Filters, stats *ScanStats, filename = strings.ToLower(filename) - if filters.HasExcludes() { - for i := 0; i < len(filters.excludes); i++ { + if filters.hasExcludes() { + for i := 0; i < len(filters.excluded); i++ { if strings.Contains( filename, - filters.excludes[i], + filters.excluded[i], ) { stats.filesSkipped.Add(1) @@ -152,11 +152,11 @@ func appendPaths(path string, files *Files, filters *Filters, stats *ScanStats, } } - if filters.HasIncludes() { - for i := 0; i < len(filters.includes); i++ { + if filters.hasIncludes() { + for i := 0; i < len(filters.included); i++ { if strings.Contains( filename, - filters.includes[i], + filters.included[i], ) { err := appendPath(directory, path, files, stats, formats, shouldCache) if err != nil { @@ -180,38 +180,38 @@ func appendPaths(path string, files *Files, filters *Filters, stats *ScanStats, return nil } -func newFile(paths []string, filters *Filters, sortOrder string, Regexes *Regexes, index *FileIndex, formats *types.Types) (string, error) { - filePath, err := pickFile(paths, filters, sortOrder, index, formats) +func newFile(paths []string, filters *filters, sortOrder string, regexes *regexes, index *fileCache, formats *types.Types) (string, error) { + path, err := pickFile(paths, filters, sortOrder, index, formats) if err != nil { return "", nil } - path, err := splitPath(filePath, Regexes) + splitPath, err := split(path, regexes) if err != nil { return "", err } - path.number = 1 + splitPath.number = 1 switch { case sortOrder == "asc": - filePath, err = tryExtensions(path, formats) + path, err = tryExtensions(splitPath, formats) if err != nil { return "", err } case sortOrder == "desc": for { - path.increment() + splitPath.increment() - filePath, err = tryExtensions(path, formats) + path, err = tryExtensions(splitPath, formats) if err != nil { return "", err } - if filePath == "" { - path.decrement() + if path == "" { + splitPath.decrement() - filePath, err = tryExtensions(path, formats) + path, err = tryExtensions(splitPath, formats) if err != nil { return "", err } @@ -221,25 +221,25 @@ func newFile(paths []string, filters *Filters, sortOrder string, Regexes *Regexe } } - return filePath, nil + return path, nil } -func nextFile(filePath, sortOrder string, Regexes *Regexes, formats *types.Types) (string, error) { - path, err := splitPath(filePath, Regexes) +func nextFile(path, sortOrder string, regexes *regexes, formats *types.Types) (string, error) { + splitPath, err := split(path, regexes) if err != nil { return "", err } switch { case sortOrder == "asc": - path.increment() + splitPath.increment() case sortOrder == "desc": - path.decrement() + splitPath.decrement() default: return "", nil } - fileName, err := tryExtensions(path, formats) + fileName, err := tryExtensions(splitPath, formats) if err != nil { return "", err } @@ -247,21 +247,21 @@ func nextFile(filePath, sortOrder string, Regexes *Regexes, formats *types.Types return fileName, err } -func splitPath(path string, Regexes *Regexes) (*Path, error) { - p := Path{} +func split(path string, regexes *regexes) (*splitPath, error) { + p := splitPath{} var err error - split := Regexes.filename.FindAllStringSubmatch(path, -1) + split := regexes.filename.FindAllStringSubmatch(path, -1) if len(split) < 1 || len(split[0]) < 3 { - return &Path{}, nil + return &splitPath{}, nil } p.base = split[0][1] p.number, err = strconv.Atoi(split[0][2]) if err != nil { - return &Path{}, err + return &splitPath{}, err } p.extension = split[0][3] @@ -269,11 +269,11 @@ func splitPath(path string, Regexes *Regexes) (*Path, error) { return &p, nil } -func tryExtensions(p *Path, formats *types.Types) (string, error) { +func tryExtensions(splitPath *splitPath, formats *types.Types) (string, error) { var fileName string for extension := range formats.Extensions { - fileName = fmt.Sprintf("%s%.3d%s", p.base, p.number, extension) + fileName = fmt.Sprintf("%s%.3d%s", splitPath.base, splitPath.number, extension) exists, err := fileExists(fileName) if err != nil { @@ -300,11 +300,11 @@ func fileExists(path string) (bool, error) { } } -func pathIsValid(filePath string, paths []string) bool { +func pathIsValid(path string, paths []string) bool { var matchesPrefix = false for i := 0; i < len(paths); i++ { - if strings.HasPrefix(filePath, paths[i]) { + if strings.HasPrefix(path, paths[i]) { matchesPrefix = true } } @@ -312,8 +312,8 @@ func pathIsValid(filePath string, paths []string) bool { switch { case Verbose && !matchesPrefix: fmt.Printf("%s | Error: Failed to serve file outside specified path(s): %s\n", - time.Now().Format(LogDate), - filePath, + time.Now().Format(logDate), + path, ) return false @@ -336,7 +336,7 @@ func pathHasSupportedFiles(path string, formats *types.Types) (bool, error) { case !Recursive && info.IsDir() && p != path: return filepath.SkipDir case !info.IsDir(): - registered, _, _, err := types.FileType(p, formats) + registered, _, _, err := formats.FileType(p) if err != nil { return err } @@ -381,7 +381,7 @@ func pathCount(path string) (uint32, uint32, error) { return files, directories, nil } -func scanPath(path string, files *Files, filters *Filters, stats *ScanStats, concurrency *Concurrency, formats *types.Types) error { +func scanPath(path string, files *files, filters *filters, stats *scanStats, concurrency *concurrency, formats *types.Types) error { var wg sync.WaitGroup err := filepath.WalkDir(path, func(p string, info os.DirEntry, err error) error { @@ -442,26 +442,26 @@ func scanPath(path string, files *Files, filters *Filters, stats *ScanStats, con return nil } -func fileList(paths []string, filters *Filters, sort string, index *FileIndex, formats *types.Types) ([]string, bool) { - if Cache && filters.IsEmpty() && !index.IsEmpty() { - return index.Index(), true +func fileList(paths []string, filters *filters, sort string, cache *fileCache, formats *types.Types) ([]string, bool) { + if Cache && filters.isEmpty() && !cache.isEmpty() { + return cache.List(), true } var fileList []string - files := &Files{ + files := &files{ mutex: sync.RWMutex{}, list: make(map[string][]string), } - stats := &ScanStats{ + stats := &scanStats{ filesMatched: atomic.Uint32{}, filesSkipped: atomic.Uint32{}, directoriesMatched: atomic.Uint32{}, directoriesSkipped: atomic.Uint32{}, } - concurrency := &Concurrency{ + concurrency := &concurrency{ directoryScans: make(chan int, maxDirectoryScans), fileScans: make(chan int, maxFileScans), } @@ -498,7 +498,7 @@ func fileList(paths []string, filters *Filters, sort string, index *FileIndex, f if Verbose { fmt.Printf("%s | Indexed %d/%d files across %d/%d directories in %s\n", - time.Now().Format(LogDate), + time.Now().Format(logDate), stats.filesMatched.Load(), stats.filesMatched.Load()+stats.filesSkipped.Load(), stats.directoriesMatched.Load(), @@ -507,8 +507,8 @@ func fileList(paths []string, filters *Filters, sort string, index *FileIndex, f ) } - if Cache && filters.IsEmpty() { - index.setIndex(fileList) + if Cache && filters.isEmpty() { + cache.set(fileList) } return fileList, false @@ -532,7 +532,7 @@ func prepareDirectory(directory []string) []string { } } -func prepareDirectories(files *Files, sort string) []string { +func prepareDirectories(files *files, sort string) []string { directories := []string{} keys := make([]string, len(files.list)) @@ -556,8 +556,8 @@ func prepareDirectories(files *Files, sort string) []string { return directories } -func pickFile(args []string, filters *Filters, sort string, index *FileIndex, formats *types.Types) (string, error) { - fileList, fromCache := fileList(args, filters, sort, index, formats) +func pickFile(args []string, filters *filters, sort string, cache *fileCache, formats *types.Types) (string, error) { + fileList, fromCache := fileList(args, filters, sort, cache, formats) fileCount := len(fileList) if fileCount < 1 { @@ -581,22 +581,22 @@ func pickFile(args []string, filters *Filters, sort string, index *FileIndex, fo val++ } - filePath := fileList[val] + path := fileList[val] if !fromCache { - registered, _, _, err := types.FileType(filePath, formats) + registered, _, _, err := formats.FileType(path) if err != nil { return "", err } if registered { - return filePath, nil + return path, nil } continue } - return filePath, nil + return path, nil } return "", ErrNoMediaFound diff --git a/cmd/filters.go b/cmd/filters.go index ea2c55d..f66b695 100644 --- a/cmd/filters.go +++ b/cmd/filters.go @@ -6,27 +6,27 @@ package cmd import "strings" -type Filters struct { - includes []string - excludes []string +type filters struct { + included []string + excluded []string } -func (f *Filters) IsEmpty() bool { - return !(f.HasIncludes() || f.HasExcludes()) +func (filters *filters) isEmpty() bool { + return !(filters.hasIncludes() || filters.hasExcludes()) } -func (f *Filters) HasIncludes() bool { - return len(f.includes) != 0 +func (filters *filters) hasIncludes() bool { + return len(filters.included) != 0 } -func (f *Filters) Includes() string { - return strings.Join(f.includes, ",") +func (filters *filters) includes() string { + return strings.Join(filters.included, ",") } -func (f *Filters) HasExcludes() bool { - return len(f.excludes) != 0 +func (filters *filters) hasExcludes() bool { + return len(filters.excluded) != 0 } -func (f *Filters) Excludes() string { - return strings.Join(f.excludes, ",") +func (filters *filters) excludes() string { + return strings.Join(filters.excluded, ",") } diff --git a/cmd/info.go b/cmd/info.go index d57e3bf..b77bf75 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -19,13 +19,13 @@ import ( "seedno.de/seednode/roulette/types" ) -func serveIndexHtml(args []string, index *FileIndex, paginate bool) httprouter.Handle { +func serveIndexHtml(args []string, cache *fileCache, paginate bool) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { w.Header().Set("Content-Type", "text/html") startTime := time.Now() - indexDump := index.Index() + indexDump := cache.List() fileCount := len(indexDump) @@ -54,7 +54,7 @@ func serveIndexHtml(args []string, index *FileIndex, paginate bool) httprouter.H var htmlBody strings.Builder htmlBody.WriteString(``) - htmlBody.WriteString(FaviconHtml) + htmlBody.WriteString(faviconHtml) htmlBody.WriteString(``) htmlBody.WriteString(fmt.Sprintf("Index contains %d files", fileCount)) @@ -65,7 +65,7 @@ func serveIndexHtml(args []string, index *FileIndex, paginate bool) httprouter.H if Sorting { shouldSort = "?sort=asc" } - htmlBody.WriteString(fmt.Sprintf("\n", MediaPrefix, v, shouldSort, v)) + htmlBody.WriteString(fmt.Sprintf("\n", mediaPrefix, v, shouldSort, v)) } } if PageLength != 0 { @@ -124,7 +124,7 @@ func serveIndexHtml(args []string, index *FileIndex, paginate bool) httprouter.H if Verbose { fmt.Printf("%s | Served HTML index page (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), humanReadableSize(b), realIP(r), time.Since(startTime).Round(time.Microsecond), @@ -133,18 +133,18 @@ func serveIndexHtml(args []string, index *FileIndex, paginate bool) httprouter.H } } -func serveIndexJson(args []string, index *FileIndex) httprouter.Handle { +func serveIndexJson(args []string, index *fileCache) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { w.Header().Set("Content-Type", "application/json") startTime := time.Now() - indexDump := index.Index() + cachedFiles := index.List() - fileCount := len(indexDump) + fileCount := len(cachedFiles) - sort.SliceStable(indexDump, func(p, q int) bool { - return strings.ToLower(indexDump[p]) < strings.ToLower(indexDump[q]) + sort.SliceStable(cachedFiles, func(p, q int) bool { + return strings.ToLower(cachedFiles[p]) < strings.ToLower(cachedFiles[q]) }) var startIndex, stopIndex int @@ -159,14 +159,14 @@ func serveIndexJson(args []string, index *FileIndex) httprouter.Handle { } if startIndex > (fileCount - 1) { - indexDump = []string{} + cachedFiles = []string{} } if stopIndex > fileCount { stopIndex = fileCount } - response, err := json.MarshalIndent(indexDump[startIndex:stopIndex], "", " ") + response, err := json.MarshalIndent(cachedFiles[startIndex:stopIndex], "", " ") if err != nil { fmt.Println(err) @@ -179,7 +179,7 @@ func serveIndexJson(args []string, index *FileIndex) httprouter.Handle { if Verbose { fmt.Printf("%s | Served JSON index page (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), humanReadableSize(len(response)), realIP(r), time.Since(startTime).Round(time.Microsecond), @@ -200,7 +200,7 @@ func serveAvailableExtensions() httprouter.Handle { if Verbose { fmt.Printf("%s | Served available extensions list (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), humanReadableSize(len(response)), realIP(r), time.Since(startTime).Round(time.Microsecond), @@ -221,7 +221,7 @@ func serveEnabledExtensions(formats *types.Types) httprouter.Handle { if Verbose { fmt.Printf("%s | Served registered extensions list (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), humanReadableSize(len(response)), realIP(r), time.Since(startTime).Round(time.Microsecond), @@ -242,7 +242,7 @@ func serveAvailableMimeTypes() httprouter.Handle { if Verbose { fmt.Printf("%s | Served available MIME types list (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), humanReadableSize(len(response)), realIP(r), time.Since(startTime).Round(time.Microsecond), @@ -263,7 +263,7 @@ func serveEnabledMimeTypes(formats *types.Types) httprouter.Handle { if Verbose { fmt.Printf("%s | Served registered MIME types list (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), humanReadableSize(len(response)), realIP(r), time.Since(startTime).Round(time.Microsecond), diff --git a/cmd/root.go b/cmd/root.go index f6345fe..07ec4dc 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,7 +12,7 @@ import ( ) const ( - ReleaseVersion string = "0.76.0" + ReleaseVersion string = "0.77.0" ) var ( diff --git a/cmd/stats.go b/cmd/stats.go index 25d4a4b..1a28a5b 100644 --- a/cmd/stats.go +++ b/cmd/stats.go @@ -40,7 +40,7 @@ func (s *ServeStats) incrementCounter(file string, timestamp time.Time, filesize s.count[file]++ - s.times[file] = append(s.times[file], timestamp.Format(LogDate)) + s.times[file] = append(s.times[file], timestamp.Format(logDate)) _, exists := s.size[file] if !exists { @@ -233,7 +233,7 @@ func serveStats(args []string, stats *ServeStats) httprouter.Handle { if Verbose { fmt.Printf("%s | Served statistics page (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), humanReadableSize(len(response)), realIP(r), time.Since(startTime).Round(time.Microsecond), diff --git a/cmd/uri.go b/cmd/uri.go index c9db41a..32703c0 100644 --- a/cmd/uri.go +++ b/cmd/uri.go @@ -34,7 +34,7 @@ func refreshInterval(r *http.Request) (int64, string) { } } -func SortOrder(r *http.Request) string { +func sortOrder(r *http.Request) string { sortOrder := r.URL.Query().Get("sort") if sortOrder == "asc" || sortOrder == "desc" { return sortOrder @@ -43,7 +43,7 @@ func SortOrder(r *http.Request) string { return "" } -func splitQueryParams(query string, Regexes *Regexes) []string { +func splitQueryParams(query string, regexes *regexes) []string { results := []string{} if query == "" { @@ -53,7 +53,7 @@ func splitQueryParams(query string, Regexes *Regexes) []string { params := strings.Split(query, ",") for i := 0; i < len(params); i++ { - if Regexes.alphanumeric.MatchString(params[i]) { + if regexes.alphanumeric.MatchString(params[i]) { results = append(results, strings.ToLower(params[i])) } } @@ -61,7 +61,7 @@ func splitQueryParams(query string, Regexes *Regexes) []string { return results } -func generateQueryParams(filters *Filters, sortOrder, refreshInterval string) string { +func generateQueryParams(filters *filters, sortOrder, refreshInterval string) string { var hasParams bool var queryParams strings.Builder @@ -70,13 +70,13 @@ func generateQueryParams(filters *Filters, sortOrder, refreshInterval string) st if Filtering { queryParams.WriteString("include=") - if filters.HasIncludes() { - queryParams.WriteString(filters.Includes()) + if filters.hasIncludes() { + queryParams.WriteString(filters.includes()) } queryParams.WriteString("&exclude=") - if filters.HasExcludes() { - queryParams.WriteString(filters.Excludes()) + if filters.hasExcludes() { + queryParams.WriteString(filters.excludes()) } hasParams = true @@ -100,8 +100,8 @@ func generateQueryParams(filters *Filters, sortOrder, refreshInterval string) st return queryParams.String() } -func stripQueryParams(u string) (string, error) { - uri, err := url.Parse(u) +func stripQueryParams(request string) (string, error) { + uri, err := url.Parse(request) if err != nil { return "", err } @@ -123,7 +123,7 @@ func stripQueryParams(u string) (string, error) { func generateFileUri(path string) string { var uri strings.Builder - uri.WriteString(SourcePrefix) + uri.WriteString(sourcePrefix) if runtime.GOOS == "windows" { uri.WriteString(`/`) } diff --git a/cmd/web.go b/cmd/web.go index 4f990a8..cbcd710 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -35,16 +35,16 @@ import ( ) const ( - LogDate string = `2006-01-02T15:04:05.000-07:00` - SourcePrefix string = `/source` - MediaPrefix string = `/view` + logDate string = `2006-01-02T15:04:05.000-07:00` + sourcePrefix string = `/source` + mediaPrefix string = `/view` RedirectStatusCode int = http.StatusSeeOther - Timeout time.Duration = 10 * time.Second + timeout time.Duration = 10 * time.Second ) -func serveStaticFile(paths []string, stats *ServeStats, index *FileIndex) httprouter.Handle { +func serveStaticFile(paths []string, stats *ServeStats, cache *fileCache) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - path := strings.TrimPrefix(r.URL.Path, SourcePrefix) + path := strings.TrimPrefix(r.URL.Path, sourcePrefix) prefixedFilePath, err := stripQueryParams(path) if err != nil { @@ -55,7 +55,7 @@ func serveStaticFile(paths []string, stats *ServeStats, index *FileIndex) httpro return } - filePath, err := filepath.EvalSymlinks(strings.TrimPrefix(prefixedFilePath, SourcePrefix)) + filePath, err := filepath.EvalSymlinks(strings.TrimPrefix(prefixedFilePath, sourcePrefix)) if err != nil { fmt.Println(err) @@ -111,13 +111,13 @@ func serveStaticFile(paths []string, stats *ServeStats, index *FileIndex) httpro } if Cache { - index.Remove(filePath) + cache.remove(filePath) } } if Verbose { fmt.Printf("%s | Served %s (%s) to %s in %s\n", - startTime.Format(LogDate), + startTime.Format(logDate), filePath, fileSize, realIP(r), @@ -132,7 +132,7 @@ func serveStaticFile(paths []string, stats *ServeStats, index *FileIndex) httpro } } -func serveRoot(paths []string, Regexes *Regexes, index *FileIndex, formats *types.Types) httprouter.Handle { +func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *types.Types) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { refererUri, err := stripQueryParams(refererToUri(r.Referer())) if err != nil { @@ -143,21 +143,21 @@ func serveRoot(paths []string, Regexes *Regexes, index *FileIndex, formats *type return } - strippedRefererUri := strings.TrimPrefix(refererUri, MediaPrefix) + strippedRefererUri := strings.TrimPrefix(refererUri, mediaPrefix) - filters := &Filters{ - includes: splitQueryParams(r.URL.Query().Get("include"), Regexes), - excludes: splitQueryParams(r.URL.Query().Get("exclude"), Regexes), + filters := &filters{ + included: splitQueryParams(r.URL.Query().Get("include"), regexes), + excluded: splitQueryParams(r.URL.Query().Get("exclude"), regexes), } - sortOrder := SortOrder(r) + sortOrder := sortOrder(r) _, refreshInterval := refreshInterval(r) var filePath string if refererUri != "" { - filePath, err = nextFile(strippedRefererUri, sortOrder, Regexes, formats) + filePath, err = nextFile(strippedRefererUri, sortOrder, regexes, formats) if err != nil { fmt.Println(err) @@ -168,7 +168,7 @@ func serveRoot(paths []string, Regexes *Regexes, index *FileIndex, formats *type } loop: - for timeout := time.After(Timeout); ; { + for timeout := time.After(timeout); ; { select { case <-timeout: break loop @@ -179,7 +179,7 @@ func serveRoot(paths []string, Regexes *Regexes, index *FileIndex, formats *type break loop } - filePath, err = newFile(paths, filters, sortOrder, Regexes, index, formats) + filePath, err = newFile(paths, filters, sortOrder, regexes, cache, formats) switch { case err != nil && err == ErrNoMediaFound: notFound(w, r, filePath) @@ -205,22 +205,22 @@ func serveRoot(paths []string, Regexes *Regexes, index *FileIndex, formats *type } } -func serveMedia(paths []string, Regexes *Regexes, index *FileIndex, formats *types.Types) httprouter.Handle { +func serveMedia(paths []string, regexes *regexes, formats *types.Types) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - filters := &Filters{ - includes: splitQueryParams(r.URL.Query().Get("include"), Regexes), - excludes: splitQueryParams(r.URL.Query().Get("exclude"), Regexes), + filters := &filters{ + included: splitQueryParams(r.URL.Query().Get("include"), regexes), + excluded: splitQueryParams(r.URL.Query().Get("exclude"), regexes), } - sortOrder := SortOrder(r) + sortOrder := sortOrder(r) - filePath := strings.TrimPrefix(r.URL.Path, MediaPrefix) + path := strings.TrimPrefix(r.URL.Path, mediaPrefix) if runtime.GOOS == "windows" { - filePath = strings.TrimPrefix(filePath, "/") + path = strings.TrimPrefix(path, "/") } - exists, err := fileExists(filePath) + exists, err := fileExists(path) if err != nil { fmt.Println(err) @@ -229,12 +229,12 @@ func serveMedia(paths []string, Regexes *Regexes, index *FileIndex, formats *typ return } if !exists { - notFound(w, r, filePath) + notFound(w, r, path) return } - registered, fileType, mimeType, err := types.FileType(filePath, formats) + registered, fileType, mimeType, err := formats.FileType(path) if err != nil { fmt.Println(err) @@ -244,14 +244,14 @@ func serveMedia(paths []string, Regexes *Regexes, index *FileIndex, formats *typ } if !registered { - notFound(w, r, filePath) + notFound(w, r, path) return } - fileUri := generateFileUri(filePath) + fileUri := generateFileUri(path) - fileName := filepath.Base(filePath) + fileName := filepath.Base(path) w.Header().Add("Content-Type", "text/html") @@ -261,16 +261,16 @@ func serveMedia(paths []string, Regexes *Regexes, index *FileIndex, formats *typ var htmlBody strings.Builder htmlBody.WriteString(``) - htmlBody.WriteString(FaviconHtml) + htmlBody.WriteString(faviconHtml) htmlBody.WriteString(fmt.Sprintf(``, fileType.Css())) - htmlBody.WriteString((fileType.Title(queryParams, fileUri, filePath, fileName, mimeType))) + htmlBody.WriteString((fileType.Title(queryParams, fileUri, path, fileName, mimeType))) htmlBody.WriteString(``) if refreshInterval != "0ms" { htmlBody.WriteString(fmt.Sprintf("", queryParams, refreshTimer)) } - htmlBody.WriteString((fileType.Body(queryParams, fileUri, filePath, fileName, mimeType))) + htmlBody.WriteString((fileType.Body(queryParams, fileUri, path, fileName, mimeType))) htmlBody.WriteString(``) _, err = io.WriteString(w, gohtml.Format(htmlBody.String())) @@ -322,25 +322,25 @@ func ServePage(args []string) error { } if Audio || All { - formats.Add(audio.Format{}) + formats.Add(audio.New()) } if Flash || All { - formats.Add(flash.Format{}) + formats.Add(flash.New()) } if Text || All { - formats.Add(text.Format{}) + formats.Add(text.New()) } if Videos || All { - formats.Add(video.Format{}) + formats.Add(video.New()) } // enable image support if no other flags are passed, to retain backwards compatibility // to be replaced with rootCmd.MarkFlagsOneRequired on next spf13/cobra update if Images || All || len(formats.Extensions) == 0 { - formats.Add(images.Format{}) + formats.Add(images.New()) } paths, err := normalizePaths(args, formats) @@ -356,12 +356,12 @@ func ServePage(args []string) error { fmt.Printf("WARNING! Files *will* be deleted after serving!\n\n") } - index := &FileIndex{ + cache := &fileCache{ mutex: sync.RWMutex{}, list: []string{}, } - regexes := &Regexes{ + regexes := ®exes{ filename: regexp.MustCompile(`(.+)([0-9]{3})(\..+)`), alphanumeric: regexp.MustCompile(`^[A-z0-9]*$`), } @@ -384,15 +384,15 @@ func ServePage(args []string) error { mux.PanicHandler = serverErrorHandler() - mux.GET("/", serveRoot(paths, regexes, index, formats)) + mux.GET("/", serveRoot(paths, regexes, cache, formats)) mux.GET("/favicons/*favicon", serveFavicons()) mux.GET("/favicon.ico", serveFavicons()) - mux.GET(MediaPrefix+"/*media", serveMedia(paths, regexes, index, formats)) + mux.GET(mediaPrefix+"/*media", serveMedia(paths, regexes, formats)) - mux.GET(SourcePrefix+"/*static", serveStaticFile(paths, stats, index)) + mux.GET(sourcePrefix+"/*static", serveStaticFile(paths, stats, cache)) mux.GET("/version", serveVersion()) @@ -400,29 +400,29 @@ func ServePage(args []string) error { skipIndex := false if CacheFile != "" { - err := index.Import(CacheFile) + err := cache.Import(CacheFile) if err == nil { skipIndex = true } } if !skipIndex { - index.generateCache(args, formats) + cache.generate(args, formats) } - mux.GET("/clear_cache", serveCacheClear(args, index, formats)) + mux.GET("/clear_cache", serveCacheClear(args, cache, formats)) } if Info { if Cache { - mux.GET("/html/", serveIndexHtml(args, index, false)) + mux.GET("/html/", serveIndexHtml(args, cache, false)) if PageLength != 0 { - mux.GET("/html/:page", serveIndexHtml(args, index, true)) + mux.GET("/html/:page", serveIndexHtml(args, cache, true)) } - mux.GET("/json", serveIndexJson(args, index)) + mux.GET("/json", serveIndexJson(args, cache)) if PageLength != 0 { - mux.GET("/json/:page", serveIndexJson(args, index)) + mux.GET("/json/:page", serveIndexJson(args, cache)) } } diff --git a/types/audio/audio.go b/types/audio/audio.go index 2b9be5b..1f106de 100644 --- a/types/audio/audio.go +++ b/types/audio/audio.go @@ -57,8 +57,10 @@ func (t Format) Validate(filePath string) bool { return true } -func init() { - format := Format{} - - types.Register(format) +func New() Format { + return Format{} +} + +func init() { + types.SupportedFormats.Register(New()) } diff --git a/types/flash/flash.go b/types/flash/flash.go index b5a446e..6c18678 100644 --- a/types/flash/flash.go +++ b/types/flash/flash.go @@ -51,8 +51,10 @@ func (t Format) Validate(filePath string) bool { return true } -func init() { - format := Format{} - - types.Register(format) +func New() Format { + return Format{} +} + +func init() { + types.SupportedFormats.Register(New()) } diff --git a/types/images/images.go b/types/images/images.go index 0362c55..4ba00e5 100644 --- a/types/images/images.go +++ b/types/images/images.go @@ -123,8 +123,10 @@ func ImageDimensions(path string) (*dimensions, error) { return &dimensions{width: decodedConfig.Width, height: decodedConfig.Height}, nil } -func init() { - format := Format{} - - types.Register(format) +func New() Format { + return Format{} +} + +func init() { + types.SupportedFormats.Register(New()) } diff --git a/types/text/text.go b/types/text/text.go index 78f6b4c..fcac42d 100644 --- a/types/text/text.go +++ b/types/text/text.go @@ -85,8 +85,10 @@ func (t Format) Validate(filePath string) bool { return utf8.Valid(head) } -func init() { - format := Format{} - - types.Register(format) +func New() Format { + return Format{} +} + +func init() { + types.SupportedFormats.Register(New()) } diff --git a/types/types.go b/types/types.go index ffb6960..203c229 100644 --- a/types/types.go +++ b/types/types.go @@ -32,23 +32,23 @@ type Types struct { MimeTypes map[string]Type } -func (s *Types) Add(t Type) { - for k, v := range t.Extensions() { - _, exists := s.Extensions[k] +func (t *Types) Add(format Type) { + for k, v := range format.Extensions() { + _, exists := t.Extensions[k] if !exists { - s.Extensions[k] = v + t.Extensions[k] = v } } - for _, v := range t.MimeTypes() { - _, exists := s.Extensions[v] + for _, v := range format.MimeTypes() { + _, exists := t.Extensions[v] if !exists { - s.MimeTypes[v] = t + t.MimeTypes[v] = format } } } -func FileType(path string, registeredFormats *Types) (bool, Type, string, error) { +func (t *Types) FileType(path string) (bool, Type, string, error) { file, err := os.Open(path) switch { case errors.Is(err, os.ErrNotExist): @@ -64,15 +64,15 @@ func FileType(path string, registeredFormats *Types) (bool, Type, string, error) mimeType := http.DetectContentType(head) // try identifying files by mime types first - fileType, exists := registeredFormats.MimeTypes[mimeType] + fileType, exists := t.MimeTypes[mimeType] if exists { return fileType.Validate(path), fileType, mimeType, nil } // if mime type detection fails, use the file extension - mimeType, exists = registeredFormats.Extensions[filepath.Ext(path)] + mimeType, exists = t.Extensions[filepath.Ext(path)] if exists { - fileType, exists := registeredFormats.MimeTypes[mimeType] + fileType, exists := t.MimeTypes[mimeType] if exists { return fileType.Validate(path), fileType, mimeType, nil @@ -82,11 +82,11 @@ func FileType(path string, registeredFormats *Types) (bool, Type, string, error) return false, nil, "", nil } -func Register(t Type) { - SupportedFormats.Add(t) +func (t *Types) Register(format Type) { + t.Add(format) } -func (t Types) GetExtensions() string { +func (t *Types) GetExtensions() string { var output strings.Builder extensions := make([]string, len(t.Extensions)) @@ -107,7 +107,7 @@ func (t Types) GetExtensions() string { return output.String() } -func (t Types) GetMimeTypes() string { +func (t *Types) GetMimeTypes() string { var output strings.Builder mimeTypes := make([]string, len(t.MimeTypes)) diff --git a/types/video/video.go b/types/video/video.go index ce5106b..0e017f5 100644 --- a/types/video/video.go +++ b/types/video/video.go @@ -57,8 +57,10 @@ func (t Format) Validate(filePath string) bool { return true } -func init() { - format := Format{} - - types.Register(format) +func New() Format { + return Format{} +} + +func init() { + types.SupportedFormats.Register(New()) }
%s
%s