@@ -0,0 +1,312 @@
|
||||
package sourcemod
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/app/appg"
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/constant/redisconst"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.Source
|
||||
|
||||
const (
|
||||
pingListCacheKey = "source:ping-list:v1"
|
||||
pingListCacheTTL = time.Minute
|
||||
)
|
||||
|
||||
type pingListCache struct {
|
||||
Domains []string `json:"domains"`
|
||||
Sources []*SourceRes `json:"sources"`
|
||||
}
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 索引设置
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "type", Value: 1}},
|
||||
Options: options.Index().SetUnique(true).SetSparse(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "domain", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "isActive", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: -1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
// PingList 返回
|
||||
func PingList() (rd []string, rs []*SourceRes) {
|
||||
// 域名配置体积较大且更新频率低,通过共享缓存避免每次启动请求都读取 MongoDB。
|
||||
result := pingListCache{}
|
||||
_, err := cachev2.Classes().
|
||||
CacheTime(pingListCacheTTL).
|
||||
Key(pingListCacheKey).
|
||||
ResBind(&result).
|
||||
Cache(loadPingList)
|
||||
if err != nil {
|
||||
log.Error("PingList cache error", log.E(err))
|
||||
result = loadPingList()
|
||||
}
|
||||
return result.Domains, result.Sources
|
||||
}
|
||||
|
||||
func loadPingList() pingListCache {
|
||||
return buildPingList(List())
|
||||
}
|
||||
|
||||
func buildPingList(data []*SourceRes) pingListCache {
|
||||
if len(data) == 0 {
|
||||
return pingListCache{}
|
||||
}
|
||||
dataLen := len(data)
|
||||
d := make([]string, 0, dataLen)
|
||||
s := make([]*SourceRes, 0, dataLen)
|
||||
for _, v := range data {
|
||||
switch v.Type {
|
||||
case Ping:
|
||||
for _, v := range v.Domain {
|
||||
d = append(d, v.Url)
|
||||
}
|
||||
case Image, Audio, Common, Group, Telegram, Guide, PROXYRULE, FAQ, QRCODE, WELFARE, ACT, PromoteURL, AppStore, BusinessCooperation, ShareURL, PreSaleBgImg:
|
||||
s = append(s, v)
|
||||
case Vid:
|
||||
s = append(s, v)
|
||||
}
|
||||
}
|
||||
d = d[:len(d):len(d)]
|
||||
s = s[:len(s):len(s)]
|
||||
return pingListCache{Domains: d, Sources: s}
|
||||
}
|
||||
|
||||
func clearPingListCache() {
|
||||
if _, err := cachev2.Classes().Delete(pingListCacheKey); err != nil {
|
||||
log.Error("clear PingList cache error", log.E(err))
|
||||
}
|
||||
}
|
||||
|
||||
// GetCdnURL GetCdnURL
|
||||
func GetCdnURL() (rd []Domain) {
|
||||
data := List()
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
var d []Domain
|
||||
for _, v := range data {
|
||||
switch v.Type {
|
||||
case Common, Vid:
|
||||
d = append(d, v.Domain...)
|
||||
}
|
||||
}
|
||||
rd = d
|
||||
return
|
||||
}
|
||||
|
||||
// List 返回
|
||||
func List() (array []*SourceRes) {
|
||||
if err := coll(nil).Find(&array, bson.M{"isActive": true}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "List", table, "Find", err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// List 返回
|
||||
func WebList() (array []*SourceRes) {
|
||||
if err := coll(nil).Find(&array, bson.M{}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "WebList", table, "Find", err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetCustomerStat 获取客服状态
|
||||
func GetCustomerStat() bool {
|
||||
var s *SourceRes
|
||||
if err := coll(nil).FindOne(&s, bson.M{"type": Customer}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCustomerStat", table, "FindOne", err))
|
||||
return true
|
||||
}
|
||||
if s == nil {
|
||||
return true
|
||||
}
|
||||
return s.IsActive
|
||||
}
|
||||
|
||||
// 随机获取推广页域名
|
||||
func GetRandomPromotionURL() string {
|
||||
if cnt, err := appg.Redis.SCard(redisconst.LandDomainCacheKey); cnt == 0 || err != nil {
|
||||
purls := GetPromoteURLArray()
|
||||
if len(purls) > 0 {
|
||||
_, _ = appg.Redis.SAdd(redisconst.LandDomainCacheKey, purls)
|
||||
}
|
||||
}
|
||||
purl, err := appg.Redis.SRandMember(redisconst.LandDomainCacheKey)
|
||||
if err != nil {
|
||||
return getPromoteURL()
|
||||
}
|
||||
return purl
|
||||
}
|
||||
|
||||
// 获取推广url数组
|
||||
func GetPromoteURLArray() []string {
|
||||
data := GetPromoteURLList()
|
||||
purls := make([]string, 0)
|
||||
if data != nil {
|
||||
purls = make([]string, 0, len(data.Domain))
|
||||
for _, v := range data.Domain {
|
||||
purls = append(purls, v.Url)
|
||||
}
|
||||
}
|
||||
return purls
|
||||
}
|
||||
|
||||
// GetPromoteURLList 返回
|
||||
func GetPromoteURLList() (data *SourceWebRes) {
|
||||
if err := coll(nil).FindOne(&data, bson.M{"type": PromoteURL, "isActive": true}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetPromoteURLList", table, "FindOne", err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// getPromoteURL 返回
|
||||
func getPromoteURL() string {
|
||||
var s *SourceRes
|
||||
if err := coll(nil).FindOne(&s, bson.M{"type": PromoteURL, "isActive": true}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "getPromoteURL", table, "FindOne", err))
|
||||
}
|
||||
if s != nil {
|
||||
return s.Domain[0].Url
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Insert SourceInsert
|
||||
func Insert(s *Source) error {
|
||||
s.UpdatedAt = time.Now()
|
||||
s.CreatedAt = time.Now()
|
||||
if _, err := coll(nil).InsertOne(&s); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
|
||||
return err
|
||||
}
|
||||
clearPingListCache()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update 修改
|
||||
func Update(id primitive.ObjectID, sType SourceType, set *SourceEdit) error {
|
||||
set.UpdatedAt = time.Now()
|
||||
if _, err := coll(nil).UpdateOne(bson.M{"_id": id, "type": sType}, bson.M{"$set": set}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateOne", err),
|
||||
log.Any("id", id),
|
||||
log.Any("sType", sType),
|
||||
log.Any("set", set),
|
||||
)
|
||||
return err
|
||||
}
|
||||
clearPingListCache()
|
||||
return nil
|
||||
}
|
||||
|
||||
// EditDomain 修改
|
||||
func EditDomain(id primitive.ObjectID, edit *SourceEdit) error {
|
||||
edit.UpdatedAt = time.Now()
|
||||
update, _ := common.ToBsonM(edit)
|
||||
if _, err := coll(nil).UpdateOne(bson.M{"_id": id}, bson.M{"$set": update}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "EditDomain", table, "UpdateOne", err),
|
||||
log.Any("id", id),
|
||||
log.Any("edit", *edit),
|
||||
)
|
||||
return err
|
||||
}
|
||||
clearPingListCache()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove SourceRemove
|
||||
func Remove(ids []primitive.ObjectID) error {
|
||||
if _, err := coll(nil).DeleteMany(bson.M{"_id": bson.M{"$in": ids}}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Remove", table, "DeleteMany", err),
|
||||
log.Any("ids", ids),
|
||||
)
|
||||
return err
|
||||
}
|
||||
clearPingListCache()
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetWeightCdnURL() string {
|
||||
var cho []common.Choice
|
||||
data, err := appg.Redis.Get(redisconst.CdnCacheKey)
|
||||
//不存在cdn缓存
|
||||
if err != nil || data == nil {
|
||||
var choice []common.Choice
|
||||
cdn := GetCdnURL()
|
||||
for _, v := range cdn {
|
||||
if v.Weight == 0 {
|
||||
continue
|
||||
}
|
||||
choice = append(choice, common.Choice{Weight: int(v.Weight), Item: v.Url})
|
||||
}
|
||||
cbyte, _ := json.Marshal(choice)
|
||||
_ = appg.Redis.Set(redisconst.CdnCacheKey, cbyte, redisconst.CdnCacheExpire)
|
||||
c, err := common.WeightedChoice(choice)
|
||||
if err != nil {
|
||||
if len(cdn) > 0 {
|
||||
return cdn[0].Url
|
||||
}
|
||||
}
|
||||
return c.Item.(string)
|
||||
}
|
||||
_ = json.Unmarshal([]byte(*data), &cho)
|
||||
c, _ := common.WeightedChoice(cho)
|
||||
return c.Item.(string)
|
||||
}
|
||||
|
||||
func GetVideoAndImgCdn() (videoCdn []string, imgCdn []string) {
|
||||
data := List()
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
dataLen := len(data)
|
||||
videoCdn = make([]string, 0, dataLen)
|
||||
imgCdn = make([]string, 0, dataLen)
|
||||
for _, v := range data {
|
||||
if v.Type == Vid {
|
||||
for _, d := range v.Domain {
|
||||
videoCdn = append(videoCdn, d.Url)
|
||||
}
|
||||
}
|
||||
if v.Type == Image {
|
||||
for _, d := range v.Domain {
|
||||
imgCdn = append(imgCdn, d.Url)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user