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  }