show file count for directories

This commit is contained in:
Timon Ringwald 2022-08-16 22:12:26 +02:00
parent 51c6ca56ac
commit 10f892323e
4 changed files with 102 additions and 18 deletions

View File

@ -2,6 +2,7 @@ package main
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@ -9,9 +10,14 @@ import (
) )
type DirectoryEntry struct { type DirectoryEntry struct {
path string path string
size *uint64 size *uint64
modSize *uint64 modSize *uint64
fileCount *uint64
modFileCount *uint64
entries []Entry entries []Entry
parent Entry parent Entry
@ -54,13 +60,34 @@ func (e *DirectoryEntry) Entries() []Entry {
func (e *DirectoryEntry) String() string { func (e *DirectoryEntry) String() string {
if e.removal { if e.removal {
return ColorRed.Sprintf("%s %s (%s)", icon("folder"), e.Name(), fmtSize(e.SizeModified())) return ColorRed.Sprintf("%s %s (%s, %s)",
icon("folder"),
e.Name(),
fmtSize(e.SizeModified()),
Translate("%s files", Translate("fileCountFormat", e.FileCountModified())),
)
} }
if e.Size() == e.SizeModified() { if e.Size() == e.SizeModified() {
return ColorBlue.Sprintf("%s %s (%s)", icon("folder"), e.Name(), fmtSize(e.Size())) return ColorBlue.Sprintf("%s %s (%s, %s)",
icon("folder"),
e.Name(),
fmtSize(e.Size()),
Translate("%s files", Translate("fileCountFormat", e.FileCount())),
)
} else { } else {
return ColorBlue.Sprintf("%s %s (%s / %s)", icon("folder"), e.Name(), ColorRed.Sprintf(fmtSize(e.SizeModified())), fmtSize(e.Size())) return ColorBlue.Sprintf("%s %s (%s / %s, %s)",
icon("folder"),
e.Name(),
ColorRed.Sprintf(fmtSize(e.SizeModified())),
fmtSize(e.Size()),
Translate("%s files",
fmt.Sprintf("%s / %s",
ColorRed.Sprintf(Translate("fileCountFormat", e.FileCountModified())),
Translate("fileCountFormat", e.FileCount()),
),
),
)
} }
} }
@ -155,10 +182,12 @@ func (e *DirectoryEntry) SizeModified() uint64 {
return *e.modSize return *e.modSize
} }
func (e *DirectoryEntry) modifySize(modifier uint64) { func (e *DirectoryEntry) modify(size uint64, fileCount uint64) {
*e.modSize += modifier *e.modSize += size
*e.modFileCount += fileCount
if e.parent != nil { if e.parent != nil {
e.parent.modifySize(modifier) e.parent.modify(size, fileCount)
// recalculate order of parent entries // recalculate order of parent entries
pentries := e.Parent().Entries() pentries := e.Parent().Entries()
@ -180,3 +209,26 @@ func (e *DirectoryEntry) RemovalStats(stats *RemovalStats) {
entry.RemovalStats(stats) entry.RemovalStats(stats)
} }
} }
func (e *DirectoryEntry) FileCount() uint64 {
if e.fileCount == nil {
fileCount := uint64(0)
for _, c := range e.Entries() {
fileCount += c.FileCount()
}
e.fileCount = &fileCount
e.modFileCount = new(uint64)
*e.modFileCount = *e.fileCount
}
return *e.fileCount
}
func (e *DirectoryEntry) FileCountModified() uint64 {
if e.fileCount == nil {
e.FileCount()
}
return *e.modFileCount
}

View File

@ -15,8 +15,13 @@ type Entry interface {
Name() string Name() string
Path() string Path() string
Size() uint64 Size() uint64
SizeModified() uint64 SizeModified() uint64
FileCount() uint64
FileCountModified() uint64
Entries() []Entry Entries() []Entry
Entry(path string) Entry Entry(path string) Entry
@ -24,7 +29,7 @@ type Entry interface {
RemovalMark() bool RemovalMark() bool
RemovalStats(stats *RemovalStats) RemovalStats(stats *RemovalStats)
modifySize(modifier uint64) modify(size uint64, fileCount uint64)
IsDir() bool IsDir() bool

View File

@ -10,10 +10,15 @@ import (
) )
type FileEntry struct { type FileEntry struct {
path string path string
size *uint64 size *uint64
modSize *uint64 modSize *uint64
parent Entry
fileCount *uint64
modFileCount *uint64
parent Entry
removal bool removal bool
noPerm bool noPerm bool
@ -93,10 +98,15 @@ func (e *FileEntry) Scan(ch chan<- string, mounts map[string]struct{}) {
} else if errors.Is(err, os.ErrPermission) { } else if errors.Is(err, os.ErrPermission) {
e.noPerm = true e.noPerm = true
} }
e.size = &s
e.size = &s
e.modSize = new(uint64) e.modSize = new(uint64)
*e.modSize = *e.size *e.modSize = *e.size
f := uint64(1)
e.fileCount = &f
e.modFileCount = new(uint64)
*e.modFileCount = *e.fileCount
} }
func (e *FileEntry) Parent() Entry { func (e *FileEntry) Parent() Entry {
@ -114,9 +124,9 @@ func (e *FileEntry) IsDir() bool {
func (e *FileEntry) SetRemovalMark(mark bool) { func (e *FileEntry) SetRemovalMark(mark bool) {
e.removal = mark e.removal = mark
if mark { if mark {
e.modifySize(-*e.size) e.modify(-*e.size, -*e.fileCount) // underflow that is cancelling out perfectly
} else { } else {
e.modifySize(*e.size) e.modify(*e.size, *e.fileCount)
} }
// recalculate order of parent entries // recalculate order of parent entries
@ -138,10 +148,11 @@ func (e *FileEntry) SizeModified() uint64 {
return *e.modSize return *e.modSize
} }
func (e *FileEntry) modifySize(modifier uint64) { func (e *FileEntry) modify(size uint64, fileCount uint64) {
*e.modSize += modifier *e.modSize = *e.modSize + size
*e.modFileCount = *e.modFileCount + fileCount
if e.parent != nil { if e.parent != nil {
e.parent.modifySize(modifier) e.parent.modify(size, fileCount)
} }
} }
@ -154,3 +165,11 @@ func (e *FileEntry) RemovalStats(stats *RemovalStats) {
} }
} }
} }
func (e *FileEntry) FileCount() uint64 {
return *e.fileCount
}
func (e *FileEntry) FileCountModified() uint64 {
return *e.modFileCount
}

View File

@ -7,7 +7,13 @@ import (
) )
var Languages = map[string]map[string]string{ var Languages = map[string]map[string]string{
"de": map[string]string{ "en": {
"fileCountFormat": "%d",
},
"de": {
"fileCountFormat": "%d",
"%s files": "%s Dateien",
"Scanning ": "Verarbeite ", "Scanning ": "Verarbeite ",
"Scanning took %s": "Verarbeitung dauerte %s", "Scanning took %s": "Verarbeitung dauerte %s",
"'%s' is not a directory": "'%s' ist kein Verzeichnis", "'%s' is not a directory": "'%s' ist kein Verzeichnis",
@ -29,7 +35,9 @@ var Languages = map[string]map[string]string{
"Use command 'exit' for exiting properly": "Nutze den Befehl 'exit', um das Programm ordnungsgemäß zu beenden", "Use command 'exit' for exiting properly": "Nutze den Befehl 'exit', um das Programm ordnungsgemäß zu beenden",
"exit? [y/N]: ": "Beenden? [y/N]: ", "exit? [y/N]: ": "Beenden? [y/N]: ",
}, },
"ja": map[string]string{ "ja": {
"fileCountFormat": "%d個",
"%s files": "%s",
"Scanning ": "処理 ", "Scanning ": "処理 ",
"Scanning took %s": "処理が %s かかりました", "Scanning took %s": "処理が %s かかりました",
"'%s' is not a directory": "「%s」はディレクトリではありません", "'%s' is not a directory": "「%s」はディレクトリではありません",