summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-10-01 23:32:19 +0300
committerPaul Buetow <paul@buetow.org>2025-10-01 23:32:19 +0300
commite8342798e51d9678d6109cf4c62309f13b1269c4 (patch)
tree01dd37e73c6ee0e4eaa99eedd4d1ef0276158297
parent1c7d78db93d177ae3142967603d8b76a464e3f56 (diff)
add readme
-rw-r--r--README.md5
-rw-r--r--main.go87
-rw-r--r--yoga.pngbin0 -> 263358 bytes
3 files changed, 83 insertions, 9 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1ea7a30
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# Yoga
+
+A yoga video selector. Fully vibe-coded.
+
+![Yoga](yoga.png)
diff --git a/main.go b/main.go
index 9879af2..762581d 100644
--- a/main.go
+++ b/main.go
@@ -391,21 +391,90 @@ func progressTickerCmd(progress *loadProgress) tea.Cmd {
})
}
-func loadVideos(root string, cache *durationCache, progress *loadProgress) ([]video, []string, error) {
+func collectVideoPaths(root string) ([]string, error) {
+ info, err := os.Stat(root)
+ if err != nil {
+ return nil, err
+ }
+ if !info.IsDir() {
+ if isVideo(root) {
+ return []string{root}, nil
+ }
+ return nil, nil
+ }
+ visited := make(map[string]struct{})
var paths []string
- err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
+ if err := traverseVideoPaths(root, root, visited, &paths); err != nil {
+ return nil, err
+ }
+ sort.Strings(paths)
+ return paths, nil
+}
+
+func traverseVideoPaths(displayPath, realPath string, visited map[string]struct{}, acc *[]string) error {
+ resolved, err := filepath.EvalSymlinks(realPath)
+ if err != nil {
+ resolved = realPath
+ }
+ resolved = filepath.Clean(resolved)
+ if _, seen := visited[resolved]; seen {
+ return nil
+ }
+ visited[resolved] = struct{}{}
+
+ entries, err := os.ReadDir(resolved)
+ if err != nil {
+ return err
+ }
+ for _, entry := range entries {
+ displayChild := filepath.Join(displayPath, entry.Name())
+ realChild := filepath.Join(resolved, entry.Name())
+ fi, err := entry.Info()
if err != nil {
return err
}
- if d.IsDir() {
- return nil
+ mode := fi.Mode()
+ if mode&os.ModeSymlink != 0 {
+ targetPath, err := filepath.EvalSymlinks(realChild)
+ if err != nil {
+ if isVideo(displayChild) {
+ *acc = append(*acc, displayChild)
+ }
+ continue
+ }
+ targetInfo, err := os.Stat(targetPath)
+ if err != nil {
+ if isVideo(displayChild) {
+ *acc = append(*acc, displayChild)
+ }
+ continue
+ }
+ if targetInfo.IsDir() {
+ if err := traverseVideoPaths(displayChild, targetPath, visited, acc); err != nil {
+ return err
+ }
+ continue
+ }
+ if isVideo(displayChild) || isVideo(targetPath) {
+ *acc = append(*acc, displayChild)
+ }
+ continue
+ }
+ if fi.IsDir() {
+ if err := traverseVideoPaths(displayChild, realChild, visited, acc); err != nil {
+ return err
+ }
+ continue
}
- if !isVideo(path) {
- return nil
+ if isVideo(displayChild) {
+ *acc = append(*acc, displayChild)
}
- paths = append(paths, path)
- return nil
- })
+ }
+ return nil
+}
+
+func loadVideos(root string, cache *durationCache, progress *loadProgress) ([]video, []string, error) {
+ paths, err := collectVideoPaths(root)
if err != nil {
return nil, nil, err
}
diff --git a/yoga.png b/yoga.png
new file mode 100644
index 0000000..7ca195d
--- /dev/null
+++ b/yoga.png
Binary files differ