Files
go-common/app/service/main/push/model/functions.go
2019-04-22 18:49:16 +08:00

245 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"bytes"
"crypto/md5"
"encoding/json"
"fmt"
"math"
"net/url"
"strconv"
"strings"
"time"
"go-common/library/log"
"github.com/dgryski/go-farm"
)
// SplitInts splts string to int-slice by ,
func SplitInts(s string) (res []int) {
if s == "" {
return
}
ints := strings.Split(s, ",")
for _, v := range ints {
i, _ := strconv.Atoi(v)
res = append(res, i)
}
return
}
// JoinInts merges int slice to string.
func JoinInts(ints []int) string {
if len(ints) == 0 {
return ""
}
if len(ints) == 1 {
return strconv.Itoa(ints[0])
}
buf := bytes.Buffer{}
for _, v := range ints {
buf.WriteString(strconv.Itoa(v))
buf.WriteString(",")
}
if buf.Len() > 0 {
buf.Truncate(buf.Len() - 1)
}
return buf.String()
}
// ExistsInt judge if item in the ints.
func ExistsInt(ints []int, item int) (exists bool) {
for _, i := range ints {
if i == item {
return true
}
}
return false
}
// HashToken gets token's hash value.
func HashToken(token string) int64 {
return int64(farm.Hash64([]byte(token)) % math.MaxInt64)
}
// RealTime culculates real time by timezone.
func RealTime(reportZone int) time.Time {
now := time.Now()
_, offset := now.Zone()
return now.Add(time.Duration(reportZone-offset/3600) * time.Hour)
}
// Scheme gets uri scheme.
func Scheme(typ int8, val string, platform, build int) (uri string) {
switch typ {
case LinkTypeBangumi: // 番剧
if platform == PlatformAndroid {
uri = SchemeBangumiSeasonAndroid + val
} else {
uri = SchemeBangumiSeasonIOS + val
}
case LinkTypeVideo: // 视频
if platform == PlatformAndroid {
uri = SchemeVideoAndroid + val
} else {
uri = SchemeVideoIOS + val
}
case LinkTypeLive:
var (
param string
parts = strings.Split(val, ",") // 值可能为 1 或者 1,0
)
if len(parts) == 2 {
param = "?broadcast_type=" + parts[1]
}
uri = SchemeLive + parts[0] + param
if platform == PlatformAndroid && build < 5290000 {
uri = SchemeLiveAndroid + parts[0]
}
case LinkTypeSplist: // 专题
uri = SchemeSplist + val
case LinkTypeAuthor: // 个人空间
if platform == PlatformAndroid {
uri = SchemeAuthorAndroid + val
} else {
uri = SchemeAuthorIOS + val
}
case LinkTypeSearch: // 搜索
if platform == PlatformAndroid {
uri = SchemeSearchAndroid + val
} else {
uri = SchemeSearchIOS + val
}
case LinkTypeBrowser: // H5
if platform == PlatformAndroid {
uri = SchemeBrowserAndroid + url.QueryEscape(val)
} else {
// 容错逻辑,标准写法是 SchemeBrowserIOS + val且 val 需要业务方进行 urlencode
// 但是老客户端有bug客户端会强制encode客户端从 5.28 开始修了这个bug
// 版本覆盖完全后,可改成标准写法
uri = val
}
case LinkTypeVipBuy:
uri = SchemeVipBuy + val
case LinkTypeCustom:
uri = val
default:
uri = ""
}
return
}
// ParseBuild parses string to build struct.
func ParseBuild(s string) (builds map[int]*Build) {
builds = make(map[int]*Build)
if s == "" {
return
}
temp := make(map[string]*Build)
if err := json.Unmarshal([]byte(s), &temp); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", s, err)
return
}
for plat, build := range temp {
p, _ := strconv.Atoi(plat)
builds[p] = build
}
return
}
// TempTaskID gen temporary task ID.
func TempTaskID() string {
n := time.Now().UnixNano()
m := md5.Sum([]byte(strconv.FormatInt(n, 10)))
return TempTaskPrefix + fmt.Sprintf("%x", m)[:8] // 要把taskid当作jobkey参数jobkey要求长度最多9位, 1位prefix+8位时间hash值前段
}
// JobName gen job name.
func JobName(timestamp int64, content, linkValue, group string) int64 {
s := []byte(fmt.Sprintf("%d%s%s%s%s", timestamp, time.Now().Format("20060102"), content, linkValue, group))
return int64(farm.Hash64(s) % math.MaxInt64)
}
// Hash gen hash value by solt.
func Hash(salt string) string {
s := salt + strconv.FormatInt(time.Now().UnixNano(), 10)
return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}
// 免打扰时间默认值
const (
_defaultSilentBeginHour = 22
_defaultSilentEndHour = 8
_defaultSilentBeginMinute = 0
_defaultSilentEndMinute = 0
)
// ParseSilentTime .
func ParseSilentTime(s string) (st BusinessSilentTime) {
st = BusinessSilentTime{
BeginHour: _defaultSilentBeginHour,
EndHour: _defaultSilentEndHour,
BeginMinute: _defaultSilentBeginMinute,
EndMinute: _defaultSilentEndMinute,
}
s = strings.Trim(s, " ")
if s == "" {
return
}
r := strings.Split(s, "-")
if len(r) != 2 {
return
}
begin := strings.Split(r[0], ":")
if len(begin) == 2 {
st.BeginHour, _ = strconv.Atoi(begin[0])
st.BeginMinute, _ = strconv.Atoi(begin[1])
}
end := strings.Split(r[1], ":")
if len(end) == 2 {
st.EndHour, _ = strconv.Atoi(end[0])
st.EndMinute, _ = strconv.Atoi(end[1])
}
return st
}
// IsAndroid .
func IsAndroid(platformID int) bool {
m := map[int]bool{
PlatformIPhone: true,
PlatformIPad: true,
}
return !m[platformID]
}
// ValidateBuild checks token&platform valid.
func ValidateBuild(platform, build int, builds map[int]*Build) bool {
if len(builds) == 0 {
return true
}
if IsAndroid(platform) {
platform = PlatformAndroid
}
if builds[platform] == nil {
return true
}
c := builds[platform].Condition
b := builds[platform].Build
switch c {
case "gt":
return build > b
case "gte":
return build >= b
case "lt":
return build < b
case "lte":
return build <= b
case "eq":
return build == b
case "ne":
return build != b
}
return false
}