github.com/coreos/mantle@v0.13.0/storage/index/job.go (about)

     1  // Copyright 2016 CoreOS, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package index
    16  
    17  import (
    18  	"golang.org/x/net/context"
    19  
    20  	"github.com/coreos/mantle/lang/worker"
    21  	"github.com/coreos/mantle/storage"
    22  )
    23  
    24  type IndexJob struct {
    25  	Bucket *storage.Bucket
    26  
    27  	name                *string
    28  	prefix              *string
    29  	enableDirectoryHTML bool
    30  	enableIndexHTML     bool
    31  	enableDelete        bool
    32  	notRecursive        bool // inverted because recursive is default
    33  }
    34  
    35  func NewIndexJob(bucket *storage.Bucket) *IndexJob {
    36  	return &IndexJob{Bucket: bucket}
    37  }
    38  
    39  // Name overrides Bucket's name in page titles.
    40  func (ij *IndexJob) Name(name string) {
    41  	ij.name = &name
    42  }
    43  
    44  // Prefix overrides Bucket's default prefix.
    45  func (ij *IndexJob) Prefix(p string) {
    46  	p = storage.FixPrefix(p)
    47  	ij.prefix = &p
    48  }
    49  
    50  // DirectoryHTML toggles generation of HTML pages to mimic directories.
    51  func (ij *IndexJob) DirectoryHTML(enable bool) {
    52  	ij.enableDirectoryHTML = enable
    53  }
    54  
    55  // IndexHTML toggles generation of index.html pages for each directory.
    56  func (ij *IndexJob) IndexHTML(enable bool) {
    57  	ij.enableIndexHTML = enable
    58  }
    59  
    60  // Delete toggles deletion of stale indexes for now empty directories.
    61  func (ij *IndexJob) Delete(enable bool) {
    62  	ij.enableDelete = enable
    63  }
    64  
    65  // Recursive toggles generation of indexes for subdirectories (the default).
    66  func (sj *IndexJob) Recursive(enable bool) {
    67  	sj.notRecursive = !enable
    68  }
    69  
    70  func (ij *IndexJob) doDir(wg *worker.WorkerGroup, ix *Indexer) error {
    71  	if ij.enableDirectoryHTML && !ix.Empty() {
    72  		if err := wg.Start(ix.UpdateRedirect); err != nil {
    73  			return err
    74  		}
    75  		if err := wg.Start(ix.UpdateDirectoryHTML); err != nil {
    76  			return err
    77  		}
    78  	} else if ij.enableDelete {
    79  		if err := wg.Start(ix.DeleteRedirect); err != nil {
    80  			return err
    81  		}
    82  		if err := wg.Start(ix.DeleteDirectory); err != nil {
    83  			return err
    84  		}
    85  	}
    86  
    87  	if ij.enableIndexHTML && !ix.Empty() {
    88  		if err := wg.Start(ix.UpdateIndexHTML); err != nil {
    89  			return err
    90  		}
    91  	} else if ij.enableDelete {
    92  		if err := wg.Start(ix.DeleteIndexHTML); err != nil {
    93  			return err
    94  		}
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  func (ij *IndexJob) Do(ctx context.Context) error {
   101  	if ij.name == nil {
   102  		name := ij.Bucket.Name()
   103  		ij.name = &name
   104  	}
   105  	if ij.prefix == nil {
   106  		prefix := ij.Bucket.Prefix()
   107  		ij.prefix = &prefix
   108  	}
   109  
   110  	tree := NewIndexTree(ij.Bucket, ij.notRecursive)
   111  	wg := worker.NewWorkerGroup(ctx, storage.MaxConcurrentRequests)
   112  
   113  	if ij.notRecursive {
   114  		ix := tree.Indexer(*ij.name, *ij.prefix)
   115  		return wg.WaitError(ij.doDir(wg, ix))
   116  	}
   117  
   118  	for _, prefix := range tree.Prefixes(*ij.prefix) {
   119  		ix := tree.Indexer(*ij.name, prefix)
   120  		if err := ij.doDir(wg, ix); err != nil {
   121  			return wg.WaitError(err)
   122  		}
   123  	}
   124  
   125  	return wg.Wait()
   126  }