...

Source file src/codeberg.org/tslocum/sriracha/util/util.go

Documentation: codeberg.org/tslocum/sriracha/util

     1  // Package util provides constants, variables and functions related to Sriracha.
     2  package util
     3  
     4  import (
     5  	"fmt"
     6  	"html/template"
     7  	"math"
     8  	"net/http"
     9  	"net/mail"
    10  	"regexp"
    11  	"sort"
    12  	"strconv"
    13  	"strings"
    14  	"time"
    15  
    16  	"golang.org/x/exp/constraints"
    17  )
    18  
    19  const NewDirPermission = 0755
    20  const NewFilePermission = 0644
    21  
    22  var (
    23  	AlphaNumericAndSymbols = regexp.MustCompile(`^[0-9A-Za-z_\-]+$`)
    24  	FileNamePattern        = regexp.MustCompile(`^[0-9A-Za-z_\-.]+$`)
    25  	FilePathPattern        = regexp.MustCompile(`^[0-9A-Za-z_\-/.]+$`)
    26  
    27  	QuotePattern = regexp.MustCompile(`^>(.*)$`)
    28  
    29  	RefLinkPattern   = regexp.MustCompile(`>>([0-9]+)`)
    30  	BoardLinkPattern = regexp.MustCompile(`>>>\/([0-9A-Za-z_-]+)?\/?`)
    31  
    32  	URLPattern     = regexp.MustCompile(`(?i)(((f|ht)tp(s)?:\/\/)[-a-zA-Zа-яА-Я()0-9@%\!_+.,~#?&;:|\'\/=]+)`)
    33  	FixURLPattern1 = regexp.MustCompile(`(?i)\(\<a href\=\"(.*)\)"\ target\=\"\_blank\">(.*)\)\<\/a>`)
    34  	FixURLPattern2 = regexp.MustCompile(`(?i)\<a href\=\"(.*)\."\ target\=\"\_blank\">(.*)\.\<\/a>`)
    35  	FixURLPattern3 = regexp.MustCompile(`(?i)\<a href\=\"(.*)\,"\ target\=\"\_blank\">(.*)\,\<\/a>`)
    36  )
    37  
    38  func ParseInt(v string) int {
    39  	i, err := strconv.Atoi(v)
    40  	if err == nil && i > 0 {
    41  		return i
    42  	}
    43  	return 0
    44  }
    45  
    46  func ParseInt64(v string) int64 {
    47  	i, err := strconv.ParseInt(v, 10, 64)
    48  	if err == nil && i > 0 {
    49  		return i
    50  	}
    51  	return 0
    52  }
    53  
    54  func ParseFloat(v string) float64 {
    55  	i, err := strconv.ParseFloat(v, 64)
    56  	if err == nil && i > 0 {
    57  		return i
    58  	}
    59  	return 0
    60  }
    61  
    62  func FormString(r *http.Request, key string) string {
    63  	return strings.TrimSpace(r.FormValue(key))
    64  }
    65  
    66  func FormMultiString(r *http.Request, key string) []string {
    67  	formKeys := make([]string, len(r.Form))
    68  	var i int
    69  	for key := range r.Form {
    70  		formKeys[i] = key
    71  		i++
    72  	}
    73  	sort.Slice(formKeys, func(i, j int) bool {
    74  		return formKeys[i] < formKeys[j]
    75  	})
    76  	var values []string
    77  	for _, formKey := range formKeys {
    78  		formValues := r.Form[formKey]
    79  		if strings.HasPrefix(formKey, key+"_") {
    80  			for _, v := range formValues {
    81  				if strings.TrimSpace(v) == "" {
    82  					continue
    83  				}
    84  				values = append(values, v)
    85  			}
    86  		}
    87  	}
    88  	return values
    89  }
    90  
    91  func FormInt(r *http.Request, key string) int {
    92  	v, err := strconv.Atoi(FormString(r, key))
    93  	if err == nil && v >= 0 {
    94  		return v
    95  	}
    96  	return 0
    97  }
    98  
    99  func FormInt64(r *http.Request, key string) int64 {
   100  	v, err := strconv.ParseInt(FormString(r, key), 10, 64)
   101  	if err == nil && v >= 0 {
   102  		return v
   103  	}
   104  	return 0
   105  }
   106  
   107  func FormNegInt(r *http.Request, key string) int {
   108  	v, err := strconv.Atoi(FormString(r, key))
   109  	if err == nil {
   110  		return v
   111  	}
   112  	return 0
   113  }
   114  
   115  func FormBool(r *http.Request, key string) bool {
   116  	return FormInt(r, key) == 1
   117  }
   118  
   119  func FormRange[T constraints.Integer](r *http.Request, key string, min T, max T) T {
   120  	v := FormNegInt(r, key)
   121  	if v >= int(min) && v <= int(max) {
   122  		return T(v)
   123  	}
   124  	return min
   125  }
   126  
   127  func PathInt(r *http.Request, prefix string) int {
   128  	pathValue := PathString(r, prefix)
   129  	if pathValue != "" {
   130  		v, err := strconv.Atoi(pathValue)
   131  		if err == nil && v > 0 {
   132  			return v
   133  		}
   134  	}
   135  	return 0
   136  }
   137  
   138  func PathString(r *http.Request, prefix string) string {
   139  	if !strings.HasPrefix(r.URL.Path, prefix) {
   140  		return ""
   141  	}
   142  	return strings.TrimPrefix(r.URL.Path, prefix)
   143  }
   144  
   145  func ParseEmail(address string) string {
   146  	a, err := mail.ParseAddress(address)
   147  	if err != nil {
   148  		return ""
   149  	}
   150  	return a.Address
   151  }
   152  
   153  func MIMEToExt(mimeType string) string {
   154  	switch mimeType {
   155  	case "image/jpeg", "image/pjpeg":
   156  		return "jpg"
   157  	case "image/gif":
   158  		return "gif"
   159  	case "image/png":
   160  		return "png"
   161  	default:
   162  		return ""
   163  	}
   164  }
   165  
   166  func FormatTimestamp(timestamp int64) template.HTML {
   167  	return template.HTML(time.Unix(timestamp, 0).Format("2006/01/02<wbr>(Mon)<wbr>15:04:05"))
   168  }
   169  
   170  func FormatRawTimestamp(timestamp int64) string {
   171  	return time.Unix(timestamp, 0).Format("2006/01/02(Mon)15:04:05")
   172  }
   173  
   174  func FormatFileSize(size int64) string {
   175  	v := float64(size)
   176  	for _, unit := range []string{"", "K", "M", "G", "T", "P", "E", "Z"} {
   177  		if math.Abs(v) < 1024.0 {
   178  			return fmt.Sprintf("%.0f%sB", v, unit)
   179  		}
   180  		v /= 1024.0
   181  	}
   182  	return fmt.Sprintf("%.0fYB", v)
   183  }
   184  
   185  func FormatDuration(d time.Duration) string {
   186  	var out string
   187  	if d.Hours() >= 24*365 {
   188  		out += fmt.Sprintf("%.0fy ", d.Hours()/(24*365))
   189  		d %= 24 * time.Hour * 365
   190  	}
   191  	if d.Hours() >= 24 {
   192  		out += fmt.Sprintf("%.0fd ", d.Hours()/24)
   193  		d %= 24 * time.Hour
   194  	}
   195  	return out + fmt.Sprintf("%s", d.Truncate(time.Second))
   196  }
   197  

View as plain text