github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/net/http/repo/6_dir_digest_2.go (about) 1 package repo 2 3 import ( 4 "net/http" 5 "sort" 6 "strings" 7 8 "github.com/pbberlin/tools/net/http/loghttp" 9 "github.com/pbberlin/tools/os/osutilpb" 10 ) 11 12 func DiveToDeepestMatch(dirTree *DirTree, uriPrefixIncl string) (*DirTree, string) { 13 14 var subtree *DirTree 15 subtree = dirTree 16 head, dir, remainder := "", "", uriPrefixIncl 17 18 if uriPrefixIncl == "/" || uriPrefixIncl == "" || uriPrefixIncl == "." { 19 // exception for root 20 head = "" // not "/" 21 } else { 22 // recur deeper 23 for { 24 dir, remainder, _ = osutilpb.PathDirReverse(remainder) 25 head += dir 26 // lg(" %-10q %-10q %-10q - head - dir - remainder", head, dir, remainder) 27 if newSubtr, ok := subtree.Dirs[dir]; ok { 28 subtree = &newSubtr 29 // lg(" recursion found %-10v %-10v for %v (%v)", dir, subtree.Name, uriPrefixIncl, subtree.Name) 30 } else { 31 // lg(" recursion failed %-10v %-10v for %v (%v)", dir, subtree.Name, uriPrefixIncl, subtree.Name) 32 33 // Calling off searching on this level 34 // StuffStage() itsself can step up if it wants to 35 // 36 // *not* setting subtree = nil 37 // would keep us one level higher than this level. 38 subtree = nil 39 40 break 41 } 42 43 if remainder == "" { 44 break 45 } 46 } 47 } 48 49 return subtree, head 50 } 51 52 func LevelWiseDeeper(w http.ResponseWriter, r *http.Request, dtree *DirTree, opt LevelWiseDeeperOptions) []FullArticle { 53 54 lg, lge := loghttp.Logger(w, r) 55 _ = lge 56 57 depthRump := strings.Count(opt.Rump, "/") 58 59 arts := []FullArticle{} 60 61 var fc func(string, *DirTree, int) 62 63 fc = func(rmp1 string, dr1 *DirTree, lvl int) { 64 65 // lg(" lvl %2v %v", lvl, dr1.Name) 66 keys := make([]string, 0, len(dr1.Dirs)) 67 for k, _ := range dr1.Dirs { 68 keys = append(keys, k) 69 } 70 // We could sort by LastFound 71 // but we rather seek most current 72 // files *later* 73 sort.Strings(keys) // for debugging clarity 74 for _, key := range keys { 75 dr2 := dr1.Dirs[key] 76 rmp2 := rmp1 + dr2.Name 77 78 // lg(" %v", rmp2) 79 80 // 81 // rmp2 a candidate? 82 if len(arts) > opt.MaxNumber-1 { 83 return 84 } 85 86 if !dr2.EndPoint { 87 continue 88 } 89 90 semanticUri := condenseTrailingDir(rmp2, opt.CondenseTrailingDirs) 91 depthUri := strings.Count(semanticUri, "/") 92 if depthUri-depthRump <= opt.MaxDepthDiff && 93 depthUri-depthRump >= opt.MinDepthDiff { 94 } else { 95 continue // we could also "break" 96 } 97 98 if opt.ExcludeDir == rmp2 { 99 lg(" exclude dir %v", opt.ExcludeDir) 100 continue 101 } 102 103 // lg(" including %v", semanticUri) 104 art := FullArticle{Url: rmp2} 105 if dr2.SrcRSS { 106 art.Mod = dr2.LastFound 107 } 108 arts = append(arts, art) 109 110 } 111 112 // 113 // recurse horizontally 114 for _, key := range keys { 115 dr2 := dr1.Dirs[key] 116 rmp2 := rmp1 + dr2.Name 117 if len(dr2.Dirs) == 0 { 118 // lg(" LevelWiseDeeper - no children") 119 continue 120 } 121 fc(rmp2, &dr2, lvl+1) 122 } 123 124 } 125 126 fc(opt.Rump, dtree, 0) 127 128 return arts 129 130 }