You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
5.4 KiB
244 lines
5.4 KiB
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 |
|
}
|
|
|