diff --git a/README.md b/README.md index ca91805..ff53a2c 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,7 @@ Flags: --profile register net/http/pprof handlers -r, --recursive recurse into subdirectories --refresh-interval string force refresh interval equal to this duration (minimum 500ms) + --russian remove selected images after serving -s, --sort enable sorting --stats expose stats endpoint --stats-file string path to optional persistent stats file diff --git a/cmd/files.go b/cmd/files.go index 885cc0f..c6e7c41 100644 --- a/cmd/files.go +++ b/cmd/files.go @@ -546,6 +546,10 @@ func fileList(paths []string, filters *Filters, sort string, index *Index) ([]st fileList = prepareDirectories(files, sort) + if stats.filesMatched.Load() < 1 { + return []string{}, false + } + if verbose { fmt.Printf("%s | Indexed %d/%d files across %d/%d directories in %s\n", time.Now().Format(LogDate), @@ -614,7 +618,7 @@ func pickFile(args []string, filters *Filters, sort string, index *Index) (strin return "", ErrNoImagesFound } - r := rand.Intn(fileCount - 1) + r := rand.Intn(fileCount) for i := 0; i < fileCount; i++ { if r >= (fileCount - 1) { diff --git a/cmd/root.go b/cmd/root.go index a3034c6..63790b4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,7 +17,7 @@ var ( ) const ( - Version string = "0.58.2" + Version string = "0.59.0" ) var ( @@ -33,6 +33,7 @@ var ( profile bool recursive bool refreshInterval string + russian bool sorting bool statistics bool statisticsFile string @@ -86,6 +87,7 @@ func init() { rootCmd.Flags().BoolVar(&profile, "profile", false, "register net/http/pprof handlers") rootCmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "recurse into subdirectories") rootCmd.Flags().StringVar(&refreshInterval, "refresh-interval", "", "force refresh interval equal to this duration (minimum 500ms)") + rootCmd.Flags().BoolVar(&russian, "russian", false, "remove selected images after serving") rootCmd.Flags().BoolVarP(&sorting, "sort", "s", false, "enable sorting") rootCmd.Flags().BoolVar(&statistics, "stats", false, "expose stats endpoint") rootCmd.Flags().StringVar(&statisticsFile, "stats-file", "", "path to optional persistent stats file") @@ -95,6 +97,8 @@ func init() { rootCmd.CompletionOptions.HiddenDefaultCmd = true + // rootCmd.MarkFlagsMutuallyExclusive("cache", "russian") + rootCmd.SilenceErrors = true rootCmd.SetHelpCommand(&cobra.Command{ Hidden: true, diff --git a/cmd/web.go b/cmd/web.go index 2f82983..43c2bd7 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -97,6 +97,30 @@ func (i *Index) Index() []string { return val } +func (i *Index) Remove(path string) { + i.mutex.RLock() + tempIndex := make([]string, len(i.list)) + copy(tempIndex, i.list) + i.mutex.RUnlock() + + var position int + + for k, v := range tempIndex { + if path == v { + position = k + + break + } + } + + 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() +} + func (i *Index) setIndex(val []string) { i.mutex.Lock() i.list = val @@ -581,7 +605,6 @@ func serveCacheClear(args []string, index *Index) httprouter.Handle { func serveStats(args []string, stats *ServeStats) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - w.Header().Set("Content-Type", "application/json") startTime := time.Now() @@ -599,6 +622,8 @@ func serveStats(args []string, stats *ServeStats) httprouter.Handle { return } + w.Header().Set("Content-Type", "application/json") + w.Write(response) if verbose { @@ -624,27 +649,27 @@ func serveDebugHtml(args []string, index *Index, paginate bool) httprouter.Handl indexDump := index.Index() + fileCount := len(indexDump) + var startIndex, stopIndex int page, err := strconv.Atoi(p.ByName("page")) if err != nil || page <= 0 { startIndex = 0 - stopIndex = len(indexDump) - 1 + stopIndex = fileCount } else { startIndex = ((page - 1) * int(pageLength)) stopIndex = (startIndex + int(pageLength)) } - if startIndex > len(indexDump)-1 { + if startIndex > (fileCount - 1) { indexDump = []string{} } - if stopIndex > len(indexDump)-1 { - stopIndex = len(indexDump) - 1 + if stopIndex > fileCount { + stopIndex = fileCount } - fileCount := strconv.Itoa(len(indexDump)) - sort.SliceStable(indexDump, func(p, q int) bool { return strings.ToLower(indexDump[p]) < strings.ToLower(indexDump[q]) }) @@ -654,7 +679,7 @@ func serveDebugHtml(args []string, index *Index, paginate bool) httprouter.Handl htmlBody.WriteString(FaviconHtml) htmlBody.WriteString(``) - htmlBody.WriteString(fmt.Sprintf("Index contains %s files", fileCount)) + htmlBody.WriteString(fmt.Sprintf("Index contains %d files
", fileCount)) if len(indexDump) > 0 { for _, v := range indexDump[startIndex:stopIndex] { var shouldSort = "" @@ -667,8 +692,8 @@ func serveDebugHtml(args []string, index *Index, paginate bool) httprouter.Handl } if pageLength != 0 { nextPage := page + 1 - if nextPage > (len(indexDump) / int(pageLength)) { - nextPage = len(indexDump) / int(pageLength) + if nextPage > (fileCount / int(pageLength)) { + nextPage = fileCount / int(pageLength) } prevPage := page - 1 @@ -708,6 +733,8 @@ func serveDebugJson(args []string, index *Index) httprouter.Handle { indexDump := index.Index() + fileCount := len(indexDump) + sort.SliceStable(indexDump, func(p, q int) bool { return strings.ToLower(indexDump[p]) < strings.ToLower(indexDump[q]) }) @@ -717,18 +744,18 @@ func serveDebugJson(args []string, index *Index) httprouter.Handle { page, err := strconv.Atoi(p.ByName("page")) if err != nil || page <= 0 { startIndex = 0 - stopIndex = len(indexDump) - 1 + stopIndex = fileCount } else { startIndex = ((page - 1) * int(pageLength)) stopIndex = (startIndex + int(pageLength)) } - if startIndex > len(indexDump)-1 { + if startIndex > (fileCount - 1) { indexDump = []string{} } - if stopIndex > len(indexDump)-1 { - stopIndex = len(indexDump) - 1 + if stopIndex > fileCount { + stopIndex = fileCount } response, err := json.MarshalIndent(indexDump[startIndex:stopIndex], "", " ") @@ -811,6 +838,17 @@ func serveStaticFile(paths []string, stats *ServeStats) httprouter.Handle { fileSize := humanReadableSize(len(buf)) + if russian { + err = os.Remove(filePath) + if err != nil { + fmt.Println(err) + + serverError(w, r, nil) + + return + } + } + if verbose { fmt.Printf("%s | Served %s (%s) to %s in %s\n", startTime.Format(LogDate), @@ -824,6 +862,7 @@ func serveStaticFile(paths []string, stats *ServeStats) httprouter.Handle { if statistics { stats.incrementCounter(filePath, startTime, fileSize) } + } } @@ -998,6 +1037,10 @@ func serveImage(paths []string, Regexes *Regexes, index *Index) httprouter.Handl return } + + if russian && cache { + index.Remove(filePath) + } } } @@ -1136,6 +1179,10 @@ func ServePage(args []string) error { mux.HandlerFunc("GET", "/debug/pprof/trace", pprof.Trace) } + if russian { + fmt.Printf("WARNING! Files *will* be deleted after serving!\n\n") + } + if statistics { if statisticsFile != "" { stats.Import(statisticsFile)