github.com/vlifesystems/rulehunter@v0.0.0-20180501090014-673078aa4a83/html/tag.go (about)

     1  // Copyright (C) 2016-2017 vLife Systems Ltd <http://vlifesystems.com>
     2  // Licensed under an MIT licence.  Please see LICENSE.md for details.
     3  
     4  package html
     5  
     6  import (
     7  	"fmt"
     8  	"html/template"
     9  	"io/ioutil"
    10  	"path/filepath"
    11  
    12  	"github.com/vlifesystems/rulehunter/config"
    13  	"github.com/vlifesystems/rulehunter/progress"
    14  	"github.com/vlifesystems/rulehunter/report"
    15  )
    16  
    17  func generateTagPages(
    18  	cfg *config.Config,
    19  	pm *progress.Monitor,
    20  ) error {
    21  	reportFiles, err := ioutil.ReadDir(filepath.Join(cfg.BuildDir, "reports"))
    22  	if err != nil {
    23  		return err
    24  	}
    25  
    26  	tagsLen := make(map[string]int)
    27  	for _, file := range reportFiles {
    28  		if !file.IsDir() {
    29  			report, err := report.LoadJSON(cfg, file.Name(), maxReportLoadAttempts)
    30  			if err != nil {
    31  				return err
    32  			}
    33  			for _, tag := range report.Tags {
    34  				escapedTag := escapeString(tag)
    35  				if _, ok := tagsLen[escapedTag]; !ok ||
    36  					len(tag) < tagsLen[escapedTag] {
    37  					if err := generateTagPage(cfg, tag); err != nil {
    38  						return err
    39  					}
    40  					// Use the shortest tag out of those that resolve to the
    41  					// same escaped tag
    42  					tagsLen[escapedTag] = len(tag)
    43  				}
    44  			}
    45  		}
    46  	}
    47  
    48  	if err := generateTagPage(cfg, ""); err != nil {
    49  		return err
    50  	}
    51  	tagsLen[""] = 0
    52  	return nil
    53  }
    54  
    55  func generateTagPage(cfg *config.Config, tagName string) error {
    56  	type TplData struct {
    57  		Tag     string
    58  		Reports []*TplReport
    59  		Html    map[string]template.HTML
    60  	}
    61  
    62  	reportFiles, err := ioutil.ReadDir(filepath.Join(cfg.BuildDir, "reports"))
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	numReportFiles := countFiles(reportFiles)
    68  	tplReports := make([]*TplReport, numReportFiles)
    69  
    70  	i := 0
    71  	for _, file := range reportFiles {
    72  		if !file.IsDir() {
    73  			report, err := report.LoadJSON(cfg, file.Name())
    74  			if err != nil {
    75  				return err
    76  			}
    77  			escapedTagname := escapeString(tagName)
    78  			if len(report.Tags) > 0 {
    79  				for _, reportTag := range report.Tags {
    80  					if escapedTagname == escapeString(reportTag) {
    81  						tplReports[i] = newTplReport(
    82  							report.Mode,
    83  							report.Title,
    84  							makeTagLinks(report.Tags),
    85  							report.Category,
    86  							makeCategoryLink(report.Category),
    87  							genReportURLDir(report.Mode, report.Category, report.Title),
    88  							report.Stamp,
    89  						)
    90  						i++
    91  					}
    92  				}
    93  			} else {
    94  				if len(escapedTagname) == 0 {
    95  					tplReports[i] = newTplReport(
    96  						report.Mode,
    97  						report.Title,
    98  						makeTagLinks(report.Tags),
    99  						report.Category,
   100  						makeCategoryLink(report.Category),
   101  						genReportURLDir(report.Mode, report.Category, report.Title),
   102  						report.Stamp,
   103  					)
   104  					i++
   105  				}
   106  			}
   107  		}
   108  	}
   109  	tplReports = tplReports[:i]
   110  	sortTplReportsByDate(tplReports)
   111  	tplData := TplData{
   112  		Tag:     tagName,
   113  		Reports: tplReports,
   114  		Html:    makeHtml(cfg, "tag"),
   115  	}
   116  	outputFilename := filepath.Join(
   117  		"reports",
   118  		"tag",
   119  		escapeString(tagName),
   120  		"index.html",
   121  	)
   122  	if len(escapeString(tagName)) == 0 {
   123  		outputFilename = filepath.Join("reports", "notag", "index.html")
   124  	}
   125  	return writeTemplate(cfg, outputFilename, tagTpl, tplData)
   126  }
   127  
   128  func makeTagLinks(tags []string) map[string]string {
   129  	links := make(map[string]string, len(tags))
   130  	for _, tag := range tags {
   131  		if escapeString(tag) != "" {
   132  			links[tag] = makeTagLink(tag)
   133  		}
   134  	}
   135  	return links
   136  }
   137  
   138  func makeTagLink(tag string) string {
   139  	return fmt.Sprintf(
   140  		"reports/tag/%s/",
   141  		escapeString(tag),
   142  	)
   143  }