github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/web/template_helpers.go (about)

     1  package web
     2  
     3  import (
     4  	"crypto/md5"
     5  	"encoding/json"
     6  	"fmt"
     7  	"html/template"
     8  	"io"
     9  	"reflect"
    10  	"regexp"
    11  	"strings"
    12  
    13  	"github.com/evergreen-ci/evergreen"
    14  	"github.com/evergreen-ci/evergreen/util"
    15  )
    16  
    17  type timePeriod struct {
    18  	secs      int
    19  	unit      string
    20  	units     string
    21  	unitShort string
    22  }
    23  
    24  var Chunks = []timePeriod{
    25  	{60 * 60 * 24, "day", "days", "d"},
    26  	{60 * 60, "hour", "hours", "h"},
    27  	{60, "min", "min", "m"},
    28  	{1, "sec", "sec", "s"},
    29  }
    30  
    31  // Because Go's templating language for some reason doesn't allow assignments,
    32  // use this to get around it.
    33  type MutableVar struct {
    34  	Value interface{}
    35  }
    36  
    37  func (self *MutableVar) Get() interface{} {
    38  	return self.Value
    39  }
    40  
    41  func (self *MutableVar) Set(v interface{}) interface{} {
    42  	self.Value = v
    43  	return ""
    44  }
    45  
    46  //Create function Mappings - Add functions here to
    47  //make them usable in the template language
    48  func MakeCommonFunctionMap(settings *evergreen.Settings) (template.FuncMap,
    49  	error) {
    50  	funcs := map[string]interface{}{}
    51  
    52  	//Equals function
    53  	funcs["Eq"] = reflect.DeepEqual
    54  
    55  	//Greater than function, with an optional threshold
    56  	funcs["Gte"] = func(a, b, threshold int) bool {
    57  		return a+threshold >= b
    58  	}
    59  
    60  	//Convenience function for ternary operator in templates
    61  	// condition ? iftrue : otherwise
    62  	funcs["Tern"] = func(condition bool, iftrue interface{}, otherwise interface{}) interface{} {
    63  		if condition {
    64  			return iftrue
    65  		}
    66  		return otherwise
    67  	}
    68  
    69  	// Unescape HTML. Be very careful that you don't pass any user input through
    70  	// this, that would be an XSS vulnerability.
    71  	funcs["Unescape"] = func(s string) interface{} {
    72  		return template.HTML(s)
    73  	}
    74  
    75  	// return the base name for a file
    76  	funcs["Basename"] = func(str string) string {
    77  		lastSlash := strings.LastIndex(str, "/")
    78  		if lastSlash == -1 || lastSlash == len(str)-1 {
    79  			// try to find the index using windows-style filesystem separators
    80  			lastSlash = strings.LastIndex(str, "\\")
    81  			if lastSlash == -1 || lastSlash == len(str)-1 {
    82  				return str
    83  			}
    84  		}
    85  		return str[lastSlash+1:]
    86  	}
    87  
    88  	// Get 50x50 Gravatar profile pic URL for given email
    89  	funcs["Gravatar"] = func(email string) string {
    90  		h := md5.New()
    91  		io.WriteString(h, email)
    92  
    93  		return fmt.Sprintf("http://www.gravatar.com/avatar/%x?s=50", h.Sum(nil))
    94  	}
    95  
    96  	// jsonifying
    97  	funcs["Json"] = func(obj interface{}) (string, error) {
    98  		v, err := json.Marshal(obj)
    99  		if err != nil {
   100  			return "", err
   101  		}
   102  		uninterpolateLeft := strings.Replace(string(v), "[[", "[[", -1)
   103  		uninterpolateRight := strings.Replace(uninterpolateLeft, "]]", "]]", -1)
   104  		return uninterpolateRight, nil
   105  	}
   106  
   107  	//Truncate a string to the desired length.
   108  	funcs["Trunc"] = util.Truncate
   109  
   110  	funcs["IsProd"] = func() bool {
   111  		return settings.IsProd
   112  	}
   113  
   114  	/* Unpleasant hack to make Go's templating language support assignments */
   115  	funcs["MutableVar"] = func() interface{} {
   116  		return &MutableVar{""}
   117  	}
   118  
   119  	//A map of systemwide globals, set up only once, which can be accessed via
   120  	//template function for usage on the front-end.
   121  	GLOBALS := make(map[string]string)
   122  	GLOBALS["revision"] = "none" //evergreen.GetCurrentRevision()
   123  	GLOBALS["uiUrl"] = settings.Ui.Url
   124  	funcs["Global"] = func(key string) string {
   125  		val, present := GLOBALS[key]
   126  		if !present {
   127  			return ""
   128  		} else {
   129  			return val
   130  		}
   131  	}
   132  
   133  	// Remove ANSI color sequences in cases where it doesn't make sense to include
   134  	// them, e.g. raw task logs
   135  	funcs["RemoveANSI"] = func(line string) string {
   136  		re, err := regexp.Compile("\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]")
   137  		if err != nil {
   138  			return ""
   139  		}
   140  		return re.ReplaceAllString(line, "")
   141  	}
   142  
   143  	return funcs, nil
   144  }