// Copyright 2014 The Gogs Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package base import ( "crypto/md5" "encoding/hex" "fmt" "html/template" "time" ) // Encode string to md5 hex value func EncodeMd5(str string) string { m := md5.New() m.Write([]byte(str)) return hex.EncodeToString(m.Sum(nil)) } // Seconds-based time units const ( Minute = 60 Hour = 60 * Minute Day = 24 * Hour Week = 7 * Day Month = 30 * Day Year = 12 * Month ) func Str2html(raw string) template.HTML { return template.HTML(raw) } // TimeSince calculates the time interval and generate user-friendly string. func TimeSince(then time.Time) string { now := time.Now() lbl := "ago" diff := now.Unix() - then.Unix() if then.After(now) { lbl = "from now" diff = then.Unix() - now.Unix() } switch { case diff <= 0: return "now" case diff <= 2: return fmt.Sprintf("1 second %s", lbl) case diff < 1*Minute: return fmt.Sprintf("%d seconds %s", diff, lbl) case diff < 2*Minute: return fmt.Sprintf("1 minute %s", lbl) case diff < 1*Hour: return fmt.Sprintf("%d minutes %s", diff/Minute, lbl) case diff < 2*Hour: return fmt.Sprintf("1 hour %s", lbl) case diff < 1*Day: return fmt.Sprintf("%d hours %s", diff/Hour, lbl) case diff < 2*Day: return fmt.Sprintf("1 day %s", lbl) case diff < 1*Week: return fmt.Sprintf("%d days %s", diff/Day, lbl) case diff < 2*Week: return fmt.Sprintf("1 week %s", lbl) case diff < 1*Month: return fmt.Sprintf("%d weeks %s", diff/Week, lbl) case diff < 2*Month: return fmt.Sprintf("1 month %s", lbl) case diff < 1*Year: return fmt.Sprintf("%d months %s", diff/Month, lbl) case diff < 18*Month: return fmt.Sprintf("1 year %s", lbl) } return then.String() } // Subtract deals with subtraction of all types of number. func Subtract(left interface{}, right interface{}) interface{} { var rleft, rright int64 var fleft, fright float64 var isInt bool = true switch left.(type) { case int: rleft = int64(left.(int)) case int8: rleft = int64(left.(int8)) case int16: rleft = int64(left.(int16)) case int32: rleft = int64(left.(int32)) case int64: rleft = left.(int64) case float32: fleft = float64(left.(float32)) isInt = false case float64: fleft = left.(float64) isInt = false } switch right.(type) { case int: rright = int64(right.(int)) case int8: rright = int64(right.(int8)) case int16: rright = int64(right.(int16)) case int32: rright = int64(right.(int32)) case int64: rright = right.(int64) case float32: fright = float64(left.(float32)) isInt = false case float64: fleft = left.(float64) isInt = false } if isInt { return rleft - rright } else { return fleft + float64(rleft) - (fright + float64(rright)) } } type Actioner interface { GetOpType() int GetActUserName() string GetRepoName() string } // ActionIcon accepts a int that represents action operation type // and returns a icon class name. func ActionIcon(opType int) string { switch opType { case 1: // Create repository. return "plus-circle" default: return "invalid type" } } const ( CreateRepoTpl = `%s created repository %s` ) // ActionDesc accepts int that represents action operation type // and returns the description. func ActionDesc(act Actioner) string { actUserName := act.GetActUserName() repoName := act.GetRepoName() switch act.GetOpType() { case 1: // Create repository. return fmt.Sprintf(CreateRepoTpl, actUserName, actUserName, actUserName, repoName, repoName) default: return "invalid type" } }