@@ -0,0 +1,266 @@
|
||||
package laosijiser
|
||||
|
||||
import (
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/laosiji"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/v/mediacontentmod"
|
||||
"91porn-server/models/v/mediamod"
|
||||
"91porn-server/web/service/vidser"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
func ComicsSearch(ctx context.Context, param laosiji.ComicsSearchListReq) (resp laosiji.ComicsSearchListResp, err error) {
|
||||
comicsResp, err := laosiji.ComicsSearch(ctx, param)
|
||||
if err != nil {
|
||||
log.Error("MovieSearch", log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
//是否导入
|
||||
lsjIds := make([]string, 0)
|
||||
for _, v := range comicsResp.Data {
|
||||
lsjIds = append(lsjIds, v.Id)
|
||||
}
|
||||
comicsList, _ := mediamod.GetListByLsjIds(lsjIds)
|
||||
|
||||
// 处理域名
|
||||
resp = laosiji.ComicsSearchListResp{
|
||||
Data: make([]laosiji.ComicsSearchInfo, 0),
|
||||
Total: comicsResp.Total,
|
||||
Current_page: comicsResp.Current_page,
|
||||
Page_size: comicsResp.Page_size,
|
||||
Last_page: comicsResp.Last_page,
|
||||
}
|
||||
for _, comicsInfo := range comicsResp.Data {
|
||||
//comicsInfo.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, comicsInfo.Img)
|
||||
comicsInfo.Img = common.JoinUrlPath("laosiji", comicsInfo.Img)
|
||||
|
||||
for _, comicsIn := range comicsList {
|
||||
if comicsIn.LsjId == comicsInfo.Id {
|
||||
comicsInfo.IsAdd = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
resp.Data = append(resp.Data, comicsInfo)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func ComicsDetail(ctx context.Context, param laosiji.ComicsDetailReq) (resp laosiji.ComicsDetailResp, serr error) {
|
||||
resp, serr = laosiji.ComicsDetail(ctx, param)
|
||||
if serr != nil {
|
||||
log.Error("MovieSearch", log.E(serr))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理域名
|
||||
//resp.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, resp.Img)
|
||||
resp.Img = common.JoinUrlPath("laosiji", resp.Img)
|
||||
if resp.Chapter != nil && len(resp.Chapter) > 0 {
|
||||
for i, cha := range resp.Chapter {
|
||||
if len(cha.Img) > 0 {
|
||||
//resp.Chapter[i].Img = common.JoinUrlPath(laosiji.IMAGEYUAN, resp.Chapter[i].Img)
|
||||
resp.Chapter[i].Img = common.JoinUrlPath("laosiji", resp.Chapter[i].Img)
|
||||
}
|
||||
if cha.Content != nil && len(cha.Content) > 0 {
|
||||
for y, content := range cha.Content {
|
||||
//resp.Chapter[i].Content[y].F = common.JoinUrlPath(laosiji.IMAGEYUAN, content.F)
|
||||
resp.Chapter[i].Content[y].F = common.JoinUrlPath("laosiji", content.F)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ComicsAddList(ctx context.Context, param laosiji.ComicsSyncReq, manager string) (hits []vidser.SensitiveHit, err error) {
|
||||
if param.Ids == nil || len(param.Ids) <= 0 {
|
||||
return
|
||||
}
|
||||
// 批量查询所有详情
|
||||
comicsDetails := make([]laosiji.ComicsDetailResp, 0)
|
||||
for _, id := range param.Ids {
|
||||
var comicsDetail laosiji.ComicsDetailResp
|
||||
req := laosiji.ComicsDetailReq{
|
||||
Id: id,
|
||||
}
|
||||
comicsDetail, err = laosiji.ComicsDetail(ctx, req)
|
||||
if err != nil {
|
||||
log.Warn("ComicsAddList laosiji.ComicsDetail failed", log.Any("id", id), log.E(err))
|
||||
continue
|
||||
}
|
||||
// 处理域名
|
||||
//comicsDetail.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, comicsDetail.Img)
|
||||
comicsDetail.Img = common.JoinUrlPath("laosiji", comicsDetail.Img)
|
||||
if comicsDetail.Chapter != nil && len(comicsDetail.Chapter) > 0 {
|
||||
for i, cha := range comicsDetail.Chapter {
|
||||
if len(cha.Img) > 0 {
|
||||
comicsDetail.Chapter[i].Img = common.JoinUrlPath("laosiji", comicsDetail.Chapter[i].Img)
|
||||
}
|
||||
if cha.Content != nil && len(cha.Content) > 0 {
|
||||
for y, content := range cha.Content {
|
||||
comicsDetail.Chapter[i].Content[y].F = common.JoinUrlPath("laosiji", content.F)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
comicsDetails = append(comicsDetails, comicsDetail)
|
||||
}
|
||||
if len(comicsDetails) <= 0 {
|
||||
log.Warn("ComicsAddList laosiji.ComicsDetailResp len is 0")
|
||||
err = errors.New("laosiji.ComicsDetailResp len is 0")
|
||||
return
|
||||
}
|
||||
// 批量处理标签
|
||||
tags := make(map[string]struct{})
|
||||
for _, comicsDetail := range comicsDetails {
|
||||
if comicsDetail.Tags != nil && len(comicsDetail.Tags) > 0 {
|
||||
for _, tag := range comicsDetail.Tags {
|
||||
tags[tag.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
tagMaps := make(map[string]primitive.ObjectID)
|
||||
if len(tags) > 0 {
|
||||
tagList := make([]string, 0)
|
||||
for k, _ := range tags {
|
||||
tagList = append(tagList, k)
|
||||
}
|
||||
tagMaps, err = checkInsertMediaTag(tagList, 2)
|
||||
if err != nil {
|
||||
log.Error("ComicsAdd checkInsertMediaTag failed", log.E(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
terms := vidser.LoadEnabledSensitiveTerms()
|
||||
hits = make([]vidser.SensitiveHit, 0)
|
||||
failedIds := make([]string, 0)
|
||||
for _, comicsDetail := range comicsDetails {
|
||||
hit, oneErr := syncOneComics(comicsDetail, tagMaps, manager, terms)
|
||||
if oneErr != nil {
|
||||
log.Warn("ComicsAdd syncOneComics failed", log.Any("id", comicsDetail.Id), log.E(oneErr))
|
||||
failedIds = append(failedIds, comicsDetail.Id)
|
||||
continue
|
||||
}
|
||||
if hit != nil {
|
||||
hits = append(hits, *hit)
|
||||
}
|
||||
}
|
||||
if len(failedIds) > 0 {
|
||||
err = errors.New(fmt.Sprintf("需要同步%d部漫画,失败%d,失败Id[%s]", len(param.Ids), len(failedIds), strings.Join(failedIds, ",")))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func syncOneComics(comicsDetail laosiji.ComicsDetailResp, tagMaps map[string]primitive.ObjectID, manager string, terms []string) (*vidser.SensitiveHit, error) {
|
||||
now := time.Now()
|
||||
mediaTemp, err := mediamod.GetListByLsjId(comicsDetail.Id)
|
||||
if err != nil {
|
||||
log.Warn("syncOneComics GetListByLsjId failed", log.Any("id", comicsDetail.Id), log.Any("err", err))
|
||||
return nil, err
|
||||
}
|
||||
if !mediaTemp.ID.IsZero() {
|
||||
return nil, nil
|
||||
}
|
||||
mediaTemp = mediamod.Media{
|
||||
ID: primitive.NewObjectID(),
|
||||
LsjId: comicsDetail.Id,
|
||||
Title: comicsDetail.Name,
|
||||
HorizontalCover: comicsDetail.Img,
|
||||
VerticalCover: comicsDetail.Img,
|
||||
Tags: make([]primitive.ObjectID, 0),
|
||||
TagDetails: make([]mediamod.TagDetail, 0),
|
||||
Summary: comicsDetail.Description,
|
||||
FreeEpisode: 0,
|
||||
CurrentEpisode: 0,
|
||||
MediaType: mediamod.MediaTypeImage,
|
||||
Kind: 5,
|
||||
PermissionIconHide: false,
|
||||
Permission: 2,
|
||||
Price: 0,
|
||||
ContentsPrice: 0,
|
||||
Status: 1,
|
||||
CreatedAt: now,
|
||||
UpdateTime: now,
|
||||
UpdatedAct: manager,
|
||||
}
|
||||
mediaTemp.TotalEpisode, _ = strconv.Atoi(comicsDetail.Chapter_count)
|
||||
mediaTemp.UpdateStatus, _ = strconv.Atoi(comicsDetail.Update_status)
|
||||
mediaTemp.Price, _ = strconv.ParseInt(comicsDetail.Money, 10, 64)
|
||||
if mediaTemp.Price > 0 {
|
||||
mediaTemp.Permission = 1
|
||||
}
|
||||
//if mediaTemp.UpdateStatus == 1 {
|
||||
// mediaTemp.UpdatedDesc = fmt.Sprintf("已完结%d话", mediaTemp.TotalEpisode)
|
||||
//} else {
|
||||
// mediaTemp.UpdatedDesc = fmt.Sprintf("更新至%d话", mediaTemp.TotalEpisode)
|
||||
//}
|
||||
for _, tag := range comicsDetail.Tags {
|
||||
if v, ok := tagMaps[tag.Name]; ok {
|
||||
mediaTemp.TagDetails = append(mediaTemp.TagDetails, mediamod.TagDetail{
|
||||
Id: v,
|
||||
Name: tag.Name,
|
||||
})
|
||||
mediaTemp.Tags = append(mediaTemp.Tags, v)
|
||||
}
|
||||
}
|
||||
contents := make([]mediacontentmod.MediaContent, 0)
|
||||
if len(comicsDetail.Chapter) > 0 {
|
||||
for i, chapter := range comicsDetail.Chapter {
|
||||
mediaContent := mediacontentmod.MediaContent{
|
||||
ID: primitive.NewObjectID(),
|
||||
MediaID: mediaTemp.ID,
|
||||
EpisodeNumber: i + 1,
|
||||
ListenPermission: mediaTemp.Permission,
|
||||
Price: mediaTemp.Price,
|
||||
Name: fmt.Sprintf("第%d话", i+1),
|
||||
Text: "",
|
||||
Md5: "",
|
||||
VideoUrl: "",
|
||||
UrlSet: make([]string, 0),
|
||||
Status: 1,
|
||||
IsActive: true,
|
||||
UpdatedAct: manager,
|
||||
CreatedAt: now,
|
||||
UpdateTime: now,
|
||||
HashId: chapter.Id,
|
||||
}
|
||||
mediaContent.Height, _ = strconv.Atoi(chapter.Content[0].H)
|
||||
mediaContent.Weight, _ = strconv.Atoi(chapter.Content[0].W)
|
||||
if chapter.Content != nil && len(chapter.Content) > 0 {
|
||||
for _, content := range chapter.Content {
|
||||
mediaContent.UrlSet = append(mediaContent.UrlSet, content.F)
|
||||
}
|
||||
}
|
||||
contents = append(contents, mediaContent)
|
||||
}
|
||||
}
|
||||
mediaTemp.CurrentEpisode = len(contents)
|
||||
// 敏感词命中 → 强制下架(Status=0)
|
||||
hit := vidser.CheckTextHits(terms, comicsDetail.Id, mediaTemp.Title, mediaTemp.Summary, "")
|
||||
if hit != nil {
|
||||
mediaTemp.Status = 0
|
||||
log.Warn("syncOneComics sensitive hit, forced offline",
|
||||
log.Any("sourceId", hit.SourceID),
|
||||
log.Any("title", hit.Title),
|
||||
log.Any("detail", hit.Detail))
|
||||
}
|
||||
_, err = mediamod.Insert(nil, mediaTemp)
|
||||
if err != nil {
|
||||
log.Warn("syncOneComics InsertMedia failed", log.Any("media", mediaTemp.ID), log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
if len(contents) > 0 {
|
||||
_ = mediacontentmod.InsetBatch(nil, contents)
|
||||
}
|
||||
return hit, nil
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
package laosijiser
|
||||
|
||||
import (
|
||||
"91porn-server/common/laosiji"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/v/mediacontentmod"
|
||||
"91porn-server/models/v/mediamod"
|
||||
"91porn-server/models/v/mediatagmod"
|
||||
"91porn-server/web/service/vidser"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
func checkInsertMediaTag(names []string, typ int) (data map[string]primitive.ObjectID, err error) {
|
||||
data, err = mediatagmod.FindOneTagByNames(names, typ)
|
||||
if err != nil {
|
||||
log.Error("checkInsertMediaTag FindOneTagByiNames failed", log.Any("tags", names), log.E(err))
|
||||
return
|
||||
}
|
||||
insertTags := make([]mediatagmod.MediaTag, 0)
|
||||
for _, tag := range names {
|
||||
if _, ok := data[tag]; !ok {
|
||||
insertTag := mediatagmod.MediaTag{
|
||||
ID: primitive.NewObjectID(),
|
||||
Type: typ,
|
||||
Name: tag,
|
||||
Active: true,
|
||||
Sort: 0,
|
||||
IsDiscovery: false,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
insertTags = append(insertTags, insertTag)
|
||||
data[tag] = insertTag.ID
|
||||
}
|
||||
}
|
||||
if len(insertTags) > 0 {
|
||||
err = mediatagmod.InsertMany(nil, insertTags)
|
||||
if err != nil {
|
||||
log.Warn("checkInsertMediaTag InsertMany failed", log.Any("tags", insertTags), log.E(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func syncCartoonList(movieDetails []laosiji.MovieDetailResp, tags map[string]struct{}, manager string, terms []string) ([]vidser.SensitiveHit, error) {
|
||||
hits := make([]vidser.SensitiveHit, 0)
|
||||
tagMaps := make(map[string]primitive.ObjectID)
|
||||
var err error
|
||||
if len(tags) > 0 {
|
||||
tagList := make([]string, 0)
|
||||
for k, _ := range tags {
|
||||
tagList = append(tagList, k)
|
||||
}
|
||||
tagMaps, err = checkInsertMediaTag(tagList, 1)
|
||||
if err != nil {
|
||||
log.Error("syncCartoonList checkInsertVidTags failed", log.E(err))
|
||||
return hits, err
|
||||
}
|
||||
}
|
||||
failedIds := make([]string, 0)
|
||||
for _, movieDetail := range movieDetails {
|
||||
hit, oneErr := syncOneCartoon(movieDetail, tagMaps, manager, terms)
|
||||
if oneErr != nil {
|
||||
log.Warn("syncCartoonList syncOneCartoon failed", log.Any("id", movieDetail.Id), log.E(oneErr))
|
||||
failedIds = append(failedIds, movieDetail.Id)
|
||||
continue
|
||||
}
|
||||
if hit != nil {
|
||||
hits = append(hits, *hit)
|
||||
}
|
||||
}
|
||||
if len(failedIds) > 0 {
|
||||
return hits, errors.New(fmt.Sprintf("需要同步%d部动漫,失败%d,失败Id[%s]", len(movieDetails), len(failedIds), strings.Join(failedIds, ",")))
|
||||
}
|
||||
return hits, nil
|
||||
}
|
||||
|
||||
func syncOneCartoon(movieDetail laosiji.MovieDetailResp, tagMaps map[string]primitive.ObjectID, manager string, terms []string) (*vidser.SensitiveHit, error) {
|
||||
now := time.Now()
|
||||
mediaTemp, err := mediamod.GetListByLsjId(movieDetail.Id)
|
||||
if err != nil {
|
||||
log.Warn("syncOneCartoon GetListByLsjId failed", log.Any("id", movieDetail.Id), log.Any("err", err))
|
||||
return nil, err
|
||||
}
|
||||
if !mediaTemp.ID.IsZero() {
|
||||
return nil, syncExistingCartoonH265(mediaTemp.ID, movieDetail.Links, manager)
|
||||
}
|
||||
mediaTemp = mediamod.Media{
|
||||
ID: primitive.NewObjectID(),
|
||||
LsjId: movieDetail.Id,
|
||||
Title: movieDetail.Name,
|
||||
HorizontalCover: movieDetail.Img_x,
|
||||
VerticalCover: movieDetail.Img_y,
|
||||
Tags: make([]primitive.ObjectID, 0),
|
||||
TagDetails: make([]mediamod.TagDetail, 0),
|
||||
Summary: movieDetail.Description,
|
||||
MediaType: mediamod.MediaTypeVideo,
|
||||
Kind: 1,
|
||||
PermissionIconHide: false,
|
||||
Permission: 2,
|
||||
Status: 1,
|
||||
CreatedAt: now,
|
||||
UpdateTime: now,
|
||||
UpdatedAct: manager,
|
||||
Anchor: movieDetail.Director,
|
||||
}
|
||||
|
||||
mediaTemp.UpdateStatus, _ = strconv.Atoi(movieDetail.Update_status)
|
||||
|
||||
//if mediaTemp.UpdateStatus == 1 {
|
||||
// mediaTemp.UpdatedDesc = fmt.Sprintf("已完结%d话", mediaTemp.TotalEpisode)
|
||||
//} else {
|
||||
// mediaTemp.UpdatedDesc = fmt.Sprintf("更新至%d话", mediaTemp.TotalEpisode)
|
||||
//}
|
||||
for _, tag := range movieDetail.Tags {
|
||||
if v, ok := tagMaps[tag.Name]; ok {
|
||||
mediaTemp.TagDetails = append(mediaTemp.TagDetails, mediamod.TagDetail{
|
||||
Id: v,
|
||||
Name: tag.Name,
|
||||
})
|
||||
mediaTemp.Tags = append(mediaTemp.Tags, v)
|
||||
}
|
||||
}
|
||||
contents := make([]mediacontentmod.MediaContent, 0)
|
||||
if len(movieDetail.Links) > 0 {
|
||||
for i, chapter := range movieDetail.Links {
|
||||
mediaContent := mediacontentmod.MediaContent{
|
||||
ID: primitive.NewObjectID(),
|
||||
MediaID: mediaTemp.ID,
|
||||
EpisodeNumber: i + 1,
|
||||
ListenPermission: mediaTemp.Permission,
|
||||
Price: mediaTemp.Price,
|
||||
Name: chapter.Name,
|
||||
VideoUrl: chapter.M3u8_url,
|
||||
H265Url: strings.TrimSpace(chapter.Hevc_m3u8_url),
|
||||
UrlSet: make([]string, 0),
|
||||
Status: 1,
|
||||
IsActive: true,
|
||||
UpdatedAct: manager,
|
||||
CreatedAt: now,
|
||||
UpdateTime: now,
|
||||
HashId: chapter.Id,
|
||||
}
|
||||
contents = append(contents, mediaContent)
|
||||
}
|
||||
}
|
||||
|
||||
mediaTemp.CurrentEpisode = len(contents)
|
||||
mediaTemp.TotalEpisode = mediaTemp.CurrentEpisode
|
||||
|
||||
// 敏感词命中 → 强制下架(Status=0)
|
||||
hit := vidser.CheckTextHits(terms, movieDetail.Id, mediaTemp.Title, mediaTemp.Summary, "")
|
||||
if hit != nil {
|
||||
mediaTemp.Status = 0
|
||||
log.Warn("syncOneCartoon sensitive hit, forced offline",
|
||||
log.Any("sourceId", hit.SourceID),
|
||||
log.Any("title", hit.Title),
|
||||
log.Any("detail", hit.Detail))
|
||||
}
|
||||
|
||||
_, err = mediamod.Insert(nil, mediaTemp)
|
||||
if err != nil {
|
||||
log.Warn("syncOneCartoon InsertMedia failed", log.Any("media", mediaTemp.ID), log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
if len(contents) > 0 {
|
||||
_ = mediacontentmod.InsetBatch(nil, contents)
|
||||
}
|
||||
return hit, nil
|
||||
}
|
||||
|
||||
// syncExistingCartoonH265 允许重复导入老司机动漫时回填历史章节的 H.265 地址。
|
||||
// 只接受上游非空地址,不改动现有 H.264 地址,也不会用空值覆盖已入库资源。
|
||||
func syncExistingCartoonH265(mediaID primitive.ObjectID, links []laosiji.LinkInfo, manager string) error {
|
||||
updatedIDs := make([]primitive.ObjectID, 0)
|
||||
for _, chapter := range links {
|
||||
h265URL := strings.TrimSpace(chapter.Hevc_m3u8_url)
|
||||
if h265URL == "" || strings.TrimSpace(chapter.Id) == "" {
|
||||
continue
|
||||
}
|
||||
content, err := mediacontentmod.GetInfoByHashId(mediaID, chapter.Id)
|
||||
if err == mediacontentmod.MediaContentNotFound {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.TrimSpace(content.H265Url) == h265URL {
|
||||
continue
|
||||
}
|
||||
if _, err = mediacontentmod.UpdateByID(nil, content.ID, map[string]interface{}{
|
||||
"h265Url": h265URL,
|
||||
"updatedAct": manager,
|
||||
"updateTime": time.Now(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
updatedIDs = append(updatedIDs, content.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
package laosijiser
|
||||
|
||||
import (
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/crypt"
|
||||
"91porn-server/common/httputil"
|
||||
"91porn-server/common/laosiji"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/v/mediacontentmod"
|
||||
"91porn-server/models/v/mediamod"
|
||||
"91porn-server/web/webg"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
func NovelSearch(ctx context.Context, param laosiji.NovelSearchListReq) (resp laosiji.NovelSearchListResp, err error) {
|
||||
novelResp, err := laosiji.NovelSearch(ctx, param)
|
||||
if err != nil {
|
||||
log.Error("MovieSearch", log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
resp = laosiji.NovelSearchListResp{
|
||||
Data: make([]laosiji.NovelSearchInfo, 0),
|
||||
Total: novelResp.Total,
|
||||
Current_page: novelResp.Current_page,
|
||||
Page_size: novelResp.Page_size,
|
||||
Last_page: novelResp.Last_page,
|
||||
}
|
||||
//是否导入
|
||||
taskIds := make([]string, 0)
|
||||
for _, v := range novelResp.Data {
|
||||
taskIds = append(taskIds, v.Id)
|
||||
}
|
||||
novelList, _ := mediamod.GetListByLsjIds(taskIds)
|
||||
|
||||
// 处理域名
|
||||
for _, novelInfo := range novelResp.Data {
|
||||
//novelInfo.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, novelInfo.Img)
|
||||
novelInfo.Img = common.JoinUrlPath("laosiji", novelInfo.Img)
|
||||
|
||||
for _, novelIn := range novelList {
|
||||
if novelIn.LsjId == novelInfo.Id {
|
||||
novelInfo.IsAdd = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
resp.Data = append(resp.Data, novelInfo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NovelDetail(ctx context.Context, param laosiji.NovelDetailReq) (resp laosiji.NovelDetailResp, err error) {
|
||||
resp, err = laosiji.NovelDetail(ctx, param)
|
||||
if err != nil {
|
||||
log.Error("MovieSearch", log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理域名
|
||||
//resp.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, resp.Img)
|
||||
resp.Img = common.JoinUrlPath("laosiji", resp.Img)
|
||||
if resp.Chapter != nil && len(resp.Chapter) > 0 {
|
||||
for i, cha := range resp.Chapter {
|
||||
if len(cha.Img) > 0 {
|
||||
//resp.Chapter[i].Img = common.JoinUrlPath(laosiji.IMAGEYUAN, resp.Chapter[i].Img)
|
||||
resp.Chapter[i].Img = common.JoinUrlPath("laosiji", resp.Chapter[i].Img)
|
||||
}
|
||||
if len(cha.Content) > 0 {
|
||||
if cha.Is_audio == "y" {
|
||||
resp.Chapter[i].Content = common.JoinUrlPath("laosiji/m3m", resp.Chapter[i].Content)
|
||||
} else {
|
||||
resp.Chapter[i].Content = common.JoinUrlPath("laosiji", resp.Chapter[i].Content)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NovelAddList(ctx context.Context, param laosiji.NovelAddListReq, manager string) (err error) {
|
||||
if param.Ids == nil || len(param.Ids) <= 0 {
|
||||
return
|
||||
}
|
||||
novelDetails := make([]laosiji.NovelDetailResp, 0)
|
||||
for _, id := range param.Ids {
|
||||
var novelDetail laosiji.NovelDetailResp
|
||||
req := laosiji.NovelDetailReq{
|
||||
Id: id,
|
||||
}
|
||||
novelDetail, err = laosiji.NovelDetail(ctx, req)
|
||||
if err != nil {
|
||||
log.Warn("NovelAddList laosiji.NovelDetail failed", log.Any("id", id), log.E(err))
|
||||
continue
|
||||
}
|
||||
// 处理域名
|
||||
//novelDetail.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, novelDetail.Img)
|
||||
novelDetail.Img = common.JoinUrlPath("laosiji/", novelDetail.Img)
|
||||
if novelDetail.Chapter != nil && len(novelDetail.Chapter) > 0 {
|
||||
for i, cha := range novelDetail.Chapter {
|
||||
if len(cha.Img) > 0 {
|
||||
novelDetail.Chapter[i].Img = common.JoinUrlPath("laosiji/", novelDetail.Chapter[i].Img)
|
||||
}
|
||||
if len(cha.Content) > 0 {
|
||||
if cha.Is_audio == "y" {
|
||||
return errors.New("暂不支持有声小说!!")
|
||||
//novelDetail.Chapter[i].Content = common.JoinUrlPath("laosiji/m3m", novelDetail.Chapter[i].Content)
|
||||
} else {
|
||||
novelDetail.Chapter[i].Content = common.JoinUrlPath("laosiji", novelDetail.Chapter[i].Content)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
novelDetails = append(novelDetails, novelDetail)
|
||||
}
|
||||
if len(novelDetails) <= 0 {
|
||||
log.Warn("NovelAddList laosiji.NovelDetailResp len is 0")
|
||||
err = errors.New("laosiji.NovelDetailResp len is 0")
|
||||
return
|
||||
}
|
||||
// 批量处理标签
|
||||
tagMaps := make(map[string]primitive.ObjectID)
|
||||
tagList := make([]string, 0) // 减少重复循环
|
||||
tagList2 := make([]string, 0) // 减少重复循环
|
||||
tagTmpMap := map[int]map[string]any{ // 区分类别和去重
|
||||
3: make(map[string]any), // 文本
|
||||
4: make(map[string]any), // 有声
|
||||
}
|
||||
for _, comicsDetail := range novelDetails {
|
||||
for _, tag := range comicsDetail.Tags {
|
||||
if len(comicsDetail.Chapter) > 0 && comicsDetail.Chapter[0].Is_audio == "y" {
|
||||
if _, ok := tagTmpMap[4][tag.Name]; !ok {
|
||||
tagTmpMap[4][tag.Name] = nil
|
||||
tagList = append(tagList, tag.Name)
|
||||
}
|
||||
} else {
|
||||
if _, ok := tagTmpMap[3][tag.Name]; !ok {
|
||||
tagTmpMap[3][tag.Name] = nil
|
||||
tagList2 = append(tagList, tag.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(tagTmpMap[3]) > 0 {
|
||||
tagMaps, err = checkInsertMediaTag(tagList, 3)
|
||||
if err != nil {
|
||||
log.Error("NovelAddList checkInsertMediaTag failed", log.E(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(tagTmpMap[4]) > 0 {
|
||||
tagMaps2, err := checkInsertMediaTag(tagList2, 4)
|
||||
if err != nil {
|
||||
log.Error("NovelAddList checkInsertMediaTag failed", log.E(err))
|
||||
return err
|
||||
}
|
||||
for k, id := range tagMaps2 {
|
||||
tagMaps[k] = id
|
||||
}
|
||||
}
|
||||
|
||||
failedIds := make([]string, 0)
|
||||
wg := sync.WaitGroup{}
|
||||
for index, _ := range novelDetails {
|
||||
wg.Add(1)
|
||||
common.GoParam(index, func(i int) {
|
||||
defer wg.Done()
|
||||
comicsDetail := novelDetails[i]
|
||||
err = syncOneNovel(comicsDetail, tagMaps, manager)
|
||||
if err != nil {
|
||||
log.Warn("NovelAddList syncOneNovel failed", log.Any("id", comicsDetail.Id), log.E(err))
|
||||
failedIds = append(failedIds, comicsDetail.Id)
|
||||
}
|
||||
})
|
||||
}
|
||||
wg.Wait()
|
||||
if len(failedIds) > 0 {
|
||||
err = errors.New(fmt.Sprintf("需要同步%d部小说,失败%d,失败Id[%s]", len(param.Ids), len(failedIds), strings.Join(failedIds, ",")))
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func syncOneNovel(novelDetail laosiji.NovelDetailResp, tagMaps map[string]primitive.ObjectID, manager string) error {
|
||||
now := time.Now()
|
||||
mediaTemp, err := mediamod.GetListByLsjId(novelDetail.Id)
|
||||
if err != nil {
|
||||
log.Warn("syncOneNovel GetListByLsjId failed", log.Any("id", novelDetail.Id), log.Any("err", err))
|
||||
return err
|
||||
}
|
||||
if !mediaTemp.ID.IsZero() {
|
||||
return nil
|
||||
}
|
||||
mediaTemp = mediamod.Media{
|
||||
ID: primitive.NewObjectID(),
|
||||
LsjId: novelDetail.Id,
|
||||
Title: novelDetail.Name,
|
||||
HorizontalCover: novelDetail.Img,
|
||||
VerticalCover: novelDetail.Img,
|
||||
Tags: make([]primitive.ObjectID, 0),
|
||||
TagDetails: make([]mediamod.TagDetail, 0),
|
||||
Summary: novelDetail.Description,
|
||||
FreeEpisode: 0,
|
||||
CurrentEpisode: 0,
|
||||
MediaType: mediamod.MediaTypeText,
|
||||
Kind: 7,
|
||||
Anchor: novelDetail.Author,
|
||||
PermissionIconHide: false,
|
||||
Permission: 2,
|
||||
Price: 0,
|
||||
ContentsPrice: 0,
|
||||
Status: 1,
|
||||
CreatedAt: now,
|
||||
UpdateTime: now,
|
||||
UpdatedAct: manager,
|
||||
}
|
||||
isAudo := false
|
||||
mediaTemp.TotalEpisode, _ = strconv.Atoi(novelDetail.Chapter_count)
|
||||
mediaTemp.UpdateStatus, _ = strconv.Atoi(novelDetail.Update_status)
|
||||
mediaTemp.Price, _ = strconv.ParseInt(novelDetail.Money, 10, 64)
|
||||
if mediaTemp.Price > 0 {
|
||||
mediaTemp.Permission = 1
|
||||
}
|
||||
//if mediaTemp.UpdateStatus == 1 {
|
||||
// mediaTemp.UpdatedDesc = fmt.Sprintf("已完结%d话", mediaTemp.TotalEpisode)
|
||||
//} else {
|
||||
// mediaTemp.UpdatedDesc = fmt.Sprintf("更新至%d话", mediaTemp.TotalEpisode)
|
||||
//}
|
||||
for _, tag := range novelDetail.Tags {
|
||||
if v, ok := tagMaps[tag.Name]; ok {
|
||||
mediaTemp.TagDetails = append(mediaTemp.TagDetails, mediamod.TagDetail{
|
||||
Id: v,
|
||||
Name: tag.Name,
|
||||
})
|
||||
mediaTemp.Tags = append(mediaTemp.Tags, v)
|
||||
}
|
||||
}
|
||||
contents := make([]mediacontentmod.MediaContent, 0)
|
||||
if len(novelDetail.Chapter) > 0 {
|
||||
for i, chapter := range novelDetail.Chapter {
|
||||
mediaContent := mediacontentmod.MediaContent{
|
||||
ID: primitive.NewObjectID(),
|
||||
MediaID: mediaTemp.ID,
|
||||
EpisodeNumber: i + 1,
|
||||
ListenPermission: mediaTemp.Permission,
|
||||
Price: mediaTemp.Price,
|
||||
Name: fmt.Sprintf("第%d章", i+1),
|
||||
UrlSet: make([]string, 0),
|
||||
Status: 1,
|
||||
IsActive: true,
|
||||
Author: mediaTemp.Anchor,
|
||||
IsDelete: false,
|
||||
UpdatedAct: manager,
|
||||
CreatedAt: now,
|
||||
UpdateTime: now,
|
||||
HashId: chapter.Id,
|
||||
}
|
||||
if chapter.Is_audio == "y" {
|
||||
mediaContent.AudioUrl = chapter.Content
|
||||
isAudo = true
|
||||
} else {
|
||||
content, err := textNovelContent(chapter.Content)
|
||||
if err != nil {
|
||||
log.Warn("syncOneNovel textNovelContent failed", log.Any("err", err))
|
||||
return err
|
||||
}
|
||||
mediaContent.Text = content
|
||||
}
|
||||
contents = append(contents, mediaContent)
|
||||
}
|
||||
}
|
||||
|
||||
if isAudo {
|
||||
mediaTemp.MediaSubType = 1
|
||||
}
|
||||
_, err = mediamod.Insert(nil, mediaTemp)
|
||||
if err != nil {
|
||||
log.Warn("syncOneNovel InsertMedia failed", log.Any("media", mediaTemp.ID), log.E(err))
|
||||
return err
|
||||
}
|
||||
|
||||
if len(contents) > 0 {
|
||||
_ = mediacontentmod.InsetBatch(nil, contents)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func textNovelContent(url string) (string, error) {
|
||||
decKey := "525202f9149e061d"
|
||||
path := fmt.Sprintf("%s/%s", webg.Conf.URL.LaoSiJiTSCdn, url)
|
||||
resp, err := httputil.DefaultClientGet(path, make(map[string]string))
|
||||
if err != nil {
|
||||
log.Warn("textNovelContent http client get failed", log.Any("url", path), log.Any("err", err))
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Warn("textNovelContent read response body failed", log.Any("err", err))
|
||||
return "", err
|
||||
}
|
||||
b := crypt.AESECBDecrypt(body, []byte(decKey))
|
||||
return string(b), nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package laosijiser
|
||||
|
||||
import (
|
||||
"91porn-server/common/crypt"
|
||||
"91porn-server/common/httputil"
|
||||
"91porn-server/common/log"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNovelDetail(t *testing.T) {
|
||||
url := "laosiji/media/novel/cbd/cbd5b05ea5677797958895694211582c.bnc"
|
||||
key := "525202f9149e061d"
|
||||
domain := "https://tssdaa.hlvwcn.cn"
|
||||
//req, err := http.NewRequest("GET", url, nil)
|
||||
//if err != nil {
|
||||
// t.Fatal(err)
|
||||
// return
|
||||
//}
|
||||
resp, err := httputil.ClientGet(30, fmt.Sprintf("%s/%s", domain, url), make(map[string]string))
|
||||
if err != nil {
|
||||
log.Warn("http client get failed", log.Any("err", err))
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Warn("read response body failed", log.Any("err", err))
|
||||
return
|
||||
}
|
||||
b := crypt.AESECBDecrypt(body, []byte(key))
|
||||
log.Info(string(b))
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
package laosijiser
|
||||
|
||||
import (
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/laosiji"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/vidmod"
|
||||
"91porn-server/web/service/vidser"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
func PostSearch(ctx context.Context, param laosiji.PostSearchListReq) (resp laosiji.PostSearchListResp, err error) {
|
||||
postResp, err := laosiji.PostSearch(ctx, param)
|
||||
if err != nil {
|
||||
log.Error("MovieSearch", log.E(err))
|
||||
return
|
||||
}
|
||||
resp = laosiji.PostSearchListResp{
|
||||
Data: make([]laosiji.PostSearchInfo, 0),
|
||||
Total: postResp.Total,
|
||||
Current_page: postResp.Current_page,
|
||||
Page_size: postResp.Page_size,
|
||||
Last_page: postResp.Last_page,
|
||||
}
|
||||
|
||||
//是否导入
|
||||
taskIds := make([]string, 0)
|
||||
for _, v := range postResp.Data {
|
||||
taskIds = append(taskIds, v.Id)
|
||||
}
|
||||
postList, _ := vidmod.GetList(bson.M{"sourceID": bson.M{"$in": taskIds}})
|
||||
|
||||
// 处理域名
|
||||
for _, postInfo := range postResp.Data {
|
||||
//postInfo.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, postInfo.Img)
|
||||
postInfo.Img = common.JoinUrlPath("laosiji", postInfo.Img)
|
||||
|
||||
for _, postIn := range postList {
|
||||
if postIn.SourceID == postInfo.Id {
|
||||
postInfo.IsAdd = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
resp.Data = append(resp.Data, postInfo)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
func PostDetail(ctx context.Context, param laosiji.PostDetailReq) (resp laosiji.PostDetailResp, err error) {
|
||||
resp, err = laosiji.PostDetail(ctx, param)
|
||||
if err != nil {
|
||||
log.Error("MovieSearch", log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理域名
|
||||
//resp.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, resp.Img)
|
||||
resp.Img = common.JoinUrlPath("laosiji", resp.Img)
|
||||
if resp.Files != nil && len(resp.Files) > 0 {
|
||||
for i, file := range resp.Files {
|
||||
if len(file.Image) > 0 {
|
||||
//resp.Files[i].Image = common.JoinUrlPath(laosiji.IMAGEYUAN, file.Image)
|
||||
resp.Files[i].Image = common.JoinUrlPath("laosiji", file.Image)
|
||||
}
|
||||
if len(file.Video_link) > 0 {
|
||||
resp.Files[i].Video_link = common.JoinUrlPath(laosiji.APIUrl+"/m3m", file.Video_link)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func PostAddList(ctx context.Context, param laosiji.PostAddListReq, manager string) (hits []vidser.SensitiveHit, err error) {
|
||||
if param.Ids == nil || len(param.Ids) <= 0 {
|
||||
return
|
||||
}
|
||||
// 批量查询所有详情
|
||||
postDetails := make([]laosiji.PostDetailResp, 0)
|
||||
for _, id := range param.Ids {
|
||||
var postDetail laosiji.PostDetailResp
|
||||
req := laosiji.PostDetailReq{
|
||||
Id: id,
|
||||
}
|
||||
postDetail, err = laosiji.PostDetail(ctx, req)
|
||||
if err != nil {
|
||||
log.Warn("PostAddList laosiji.PostDetail failed", log.Any("id", id), log.E(err))
|
||||
continue
|
||||
}
|
||||
//postDetail.Img = common.JoinUrlPath(laosiji.IMAGEYUAN, postDetail.Img)
|
||||
postDetail.Img = common.JoinUrlPath("laosiji", postDetail.Img)
|
||||
if postDetail.Files != nil && len(postDetail.Files) > 0 {
|
||||
for i, file := range postDetail.Files {
|
||||
if len(file.Image) > 0 {
|
||||
postDetail.Files[i].Image = common.JoinUrlPath("laosiji", file.Image)
|
||||
}
|
||||
if len(file.Video_link) > 0 {
|
||||
postDetail.Files[i].Video_link = common.JoinUrlPath("laosiji/m3m/", file.Video_link)
|
||||
}
|
||||
}
|
||||
}
|
||||
postDetails = append(postDetails, postDetail)
|
||||
}
|
||||
if len(postDetails) <= 0 {
|
||||
log.Warn("PostAddList laosiji.PostDetailResp len is 0")
|
||||
err = errors.New("laosiji.PostDetailResp len is 0")
|
||||
return
|
||||
}
|
||||
|
||||
users, err := usermod.FindMany(bson.M{"uid": bson.M{"$gt": 300000}}, &options.FindOptions{}, 0, 300)
|
||||
if err != nil {
|
||||
log.Warn("PostAddList FindManyUser failed", log.E(err))
|
||||
return
|
||||
}
|
||||
terms := vidser.LoadEnabledSensitiveTerms()
|
||||
hits = make([]vidser.SensitiveHit, 0)
|
||||
failedIds := make([]string, 0)
|
||||
for _, postDetail := range postDetails {
|
||||
hit, oneErr := addOnePost(postDetail, nil, users, manager, terms)
|
||||
if oneErr != nil {
|
||||
log.Warn("PostAddList addOnePost failed", log.Any("id", postDetail.Id), log.E(oneErr))
|
||||
failedIds = append(failedIds, postDetail.Id)
|
||||
continue
|
||||
}
|
||||
if hit != nil {
|
||||
hits = append(hits, *hit)
|
||||
}
|
||||
}
|
||||
if len(failedIds) > 0 {
|
||||
err = errors.New(fmt.Sprintf("需要同步%d个帖子,失败%d,失败Id[%s]", len(param.Ids), len(failedIds), strings.Join(failedIds, ",")))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func addOnePost(postDetail laosiji.PostDetailResp, tagMaps map[string]primitive.ObjectID, upUsers []*usermod.User, manager string, terms []string) (*vidser.SensitiveHit, error) {
|
||||
//
|
||||
// 有的帖子是图文节点 前端格式不支持 这里屏蔽
|
||||
//
|
||||
if len(postDetail.Files) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
postList, err := vidmod.GetList(bson.M{"sourceID": bson.M{"$in": []string{postDetail.Id}}})
|
||||
if err != nil {
|
||||
log.Warn("addOnePost GetList failed", log.Any("id", postDetail.Id), log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
if postList != nil && len(postList) > 0 {
|
||||
return nil, nil
|
||||
}
|
||||
postInfo := vidmod.VideoModel{
|
||||
ID: primitive.NewObjectID(),
|
||||
NewsType: vidmod.COVER,
|
||||
Title: postDetail.Title,
|
||||
Content: postDetail.Content,
|
||||
Tags: make([]primitive.ObjectID, 0),
|
||||
MimeType: "video/mp4",
|
||||
Cover: postDetail.Img,
|
||||
CoverThumb: postDetail.Img,
|
||||
SeriesCover: make([]string, 0),
|
||||
Via: "laosiji",
|
||||
Status: vidmod.CheckPass,
|
||||
Location: primitive.ObjectID{},
|
||||
NewUpdatedAt: "laosiji",
|
||||
ReviewAt: now,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
ReviewAccount: manager,
|
||||
SourceID: postDetail.Id,
|
||||
VerticalCover: postDetail.Img,
|
||||
}
|
||||
postInfo.SeriesNum, _ = strconv.Atoi(postDetail.Img_count)
|
||||
postInfo.Coins, _ = strconv.ParseInt(postDetail.Money, 10, 64)
|
||||
uIndex := rand.Intn(len(upUsers))
|
||||
u := upUsers[uIndex]
|
||||
postInfo.PublisherID = u.UID
|
||||
//if postInfo.Coins > 0 {
|
||||
// postInfo.Permission = 1
|
||||
//} else {
|
||||
// postInfo.Permission = 2
|
||||
// postInfo.FreeArea = true
|
||||
// postInfo.FreeAreaDate = now
|
||||
//}
|
||||
//节点 处理
|
||||
if postDetail.Files != nil && len(postDetail.Files) > 0 {
|
||||
for _, file := range postDetail.Files {
|
||||
if file.Type == "image" {
|
||||
if len(file.Image) > 0 {
|
||||
postInfo.SeriesCover = append(postInfo.SeriesCover, file.Image)
|
||||
}
|
||||
}
|
||||
if file.Type == "video" {
|
||||
postInfo.SourceURL = file.Video_link
|
||||
postInfo.PlayTime = 1
|
||||
postInfo.Filename = file.Tips
|
||||
postInfo.SourceID = postDetail.Id
|
||||
}
|
||||
}
|
||||
}
|
||||
if postDetail.Rich_content != nil && len(postDetail.Rich_content) > 0 {
|
||||
for _, file := range postDetail.Rich_content {
|
||||
postInfo.RichText += fmt.Sprintf("%s\n", file)
|
||||
}
|
||||
}
|
||||
// 敏感词命中 → 强制为待审核(WaitingCheck=0),写库后由后台逐条告警
|
||||
hit := vidser.CheckTextHits(terms, postDetail.Id, postInfo.Title, postInfo.Content, postInfo.RichText)
|
||||
if hit != nil {
|
||||
postInfo.Status = vidmod.WaitingCheck
|
||||
log.Warn("addOnePost sensitive hit, forced offline",
|
||||
log.Any("sourceId", hit.SourceID),
|
||||
log.Any("title", hit.Title),
|
||||
log.Any("detail", hit.Detail))
|
||||
}
|
||||
if _, err = vidmod.InsertBase(postInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hit, nil
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
package laosijiser
|
||||
|
||||
import (
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/constant/redisconst"
|
||||
"91porn-server/common/laosiji"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/v/mediamod"
|
||||
"91porn-server/models/v/tagmod"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/vidmod"
|
||||
"91porn-server/web/service/vidser"
|
||||
"91porn-server/web/webg"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
func MovieSearch(ctx context.Context, param laosiji.MovieSearchReq) (resp laosiji.MovieSearchResp, err error) {
|
||||
var yuanresp laosiji.MovieSearchResp
|
||||
yuanresp, err = laosiji.MovieSearch(ctx, param)
|
||||
if err != nil {
|
||||
log.Error("MovieSearch", log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
//是否导入
|
||||
taskIds := make([]string, 0)
|
||||
for _, v := range yuanresp.Data {
|
||||
taskIds = append(taskIds, v.Id)
|
||||
}
|
||||
resp = laosiji.MovieSearchResp{
|
||||
Data: make([]laosiji.MovieInfo, 0),
|
||||
Total: yuanresp.Total,
|
||||
Current_page: yuanresp.Current_page,
|
||||
Page_size: yuanresp.Page_size,
|
||||
Last_page: yuanresp.Last_page,
|
||||
}
|
||||
if param.Position == "guochan" || param.Position == "av" || param.Position == "douyin" || param.Position == "dark" {
|
||||
videoList, _ := vidmod.GetList(bson.M{"sourceID": bson.M{"$in": taskIds}})
|
||||
// 处理域名
|
||||
for _, movieInfo := range yuanresp.Data {
|
||||
//movieInfo.Img_x = common.JoinUrlPath(laosiji.IMAGEYUAN, movieInfo.Img_x)
|
||||
//movieInfo.Img_y = common.JoinUrlPath(laosiji.IMAGEYUAN, movieInfo.Img_y)
|
||||
movieInfo.Img_x = common.JoinUrlPath("laosiji", movieInfo.Img_x)
|
||||
movieInfo.Img_y = common.JoinUrlPath("laosiji", movieInfo.Img_y)
|
||||
|
||||
for _, videoInfo := range videoList {
|
||||
if videoInfo.SourceID == movieInfo.Id {
|
||||
movieInfo.IsAdd = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
resp.Data = append(resp.Data, movieInfo)
|
||||
}
|
||||
} else if param.Position == "cartoon" {
|
||||
mediaList, _ := mediamod.GetListByLsjIds(taskIds)
|
||||
for _, movieInfo := range yuanresp.Data {
|
||||
//movieInfo.Img_x = common.JoinUrlPath(laosiji.IMAGEYUAN, movieInfo.Img_x)
|
||||
//movieInfo.Img_y = common.JoinUrlPath(laosiji.IMAGEYUAN, movieInfo.Img_y)
|
||||
movieInfo.Img_x = common.JoinUrlPath("laosiji", movieInfo.Img_x)
|
||||
movieInfo.Img_y = common.JoinUrlPath("laosiji", movieInfo.Img_y)
|
||||
for _, videoInfo := range mediaList {
|
||||
if videoInfo.LsjId == movieInfo.Id {
|
||||
movieInfo.IsAdd = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
resp.Data = append(resp.Data, movieInfo)
|
||||
}
|
||||
|
||||
} else {
|
||||
err = errors.New("该资源暂不支持")
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func MovieDetail(ctx context.Context, param laosiji.MovieDetailReq) (resp laosiji.MovieDetailResp, err error) {
|
||||
resp, err = laosiji.MovieDetail(ctx, param)
|
||||
if err != nil {
|
||||
log.Error("MovieSearch", log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理域名
|
||||
//resp.Img_x = common.JoinUrlPath(laosiji.IMAGEYUAN, resp.Img_x)
|
||||
//resp.Img_y = common.JoinUrlPath(laosiji.IMAGEYUAN, resp.Img_y)
|
||||
resp.Img_x = common.JoinUrlPath("laosiji", resp.Img_x)
|
||||
resp.Img_y = common.JoinUrlPath("laosiji", resp.Img_y)
|
||||
for key, value := range resp.Preview_images {
|
||||
//resp.Preview_images[key] = common.JoinUrlPath(laosiji.IMAGEYUAN, value)
|
||||
resp.Preview_images[key] = common.JoinUrlPath("laosiji", value)
|
||||
}
|
||||
for key, value := range resp.Links {
|
||||
resp.Links[key].M3u8_url = laosiji.MovieM3u8OriginURL(value.M3u8_url)
|
||||
resp.Links[key].Preview_m3u8_url = laosiji.MovieM3u8OriginURL(value.Preview_m3u8_url)
|
||||
resp.Links[key].Hevc_m3u8_url = laosiji.MovieM3u8OriginURL(value.Hevc_m3u8_url)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func MovieAddList(ctx context.Context, param laosiji.MovieAddListReq, manager string) ([]vidser.SensitiveHit, error) {
|
||||
if param.Ids == nil || len(param.Ids) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
movieDetails := make([]laosiji.MovieDetailResp, 0)
|
||||
for _, id := range param.Ids {
|
||||
var movieDetail laosiji.MovieDetailResp
|
||||
req := laosiji.MovieDetailReq{
|
||||
Id: id,
|
||||
}
|
||||
movieDetail, err := laosiji.MovieDetail(ctx, req)
|
||||
if err != nil {
|
||||
log.Warn("MovieAddList laosiji.MovieDetail failed", log.Any("id", id), log.E(err))
|
||||
continue
|
||||
}
|
||||
for i, linkInfo := range movieDetail.Links {
|
||||
linkInfo.M3u8_url = laosiji.MovieM3u8SourcePath(linkInfo.M3u8_url)
|
||||
linkInfo.Preview_m3u8_url = laosiji.MovieM3u8SourcePath(linkInfo.Preview_m3u8_url)
|
||||
linkInfo.Hevc_m3u8_url = laosiji.MovieM3u8SourcePath(linkInfo.Hevc_m3u8_url)
|
||||
movieDetail.Links[i] = linkInfo
|
||||
}
|
||||
if len(movieDetail.Img_y) > 0 {
|
||||
movieDetail.Img_y = common.JoinUrlPath("laosiji/", movieDetail.Img_y)
|
||||
}
|
||||
if len(movieDetail.Img_x) > 0 {
|
||||
movieDetail.Img_x = common.JoinUrlPath("laosiji/", movieDetail.Img_x)
|
||||
}
|
||||
movieDetails = append(movieDetails, movieDetail)
|
||||
}
|
||||
if len(movieDetails) <= 0 {
|
||||
log.Warn("MovieAddList laosiji.MovieDetailResp len is 0")
|
||||
return nil, errors.New("laosiji.MovieDetailResp len is 0")
|
||||
}
|
||||
// 批量处理标签
|
||||
tags := make(map[string]struct{})
|
||||
for _, comicsDetail := range movieDetails {
|
||||
if comicsDetail.Tags != nil && len(comicsDetail.Tags) > 0 {
|
||||
for _, tag := range comicsDetail.Tags {
|
||||
tags[tag.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
terms := vidser.LoadEnabledSensitiveTerms()
|
||||
hits := make([]vidser.SensitiveHit, 0)
|
||||
if param.Position == "cartoon" {
|
||||
return syncCartoonList(movieDetails, tags, manager, terms)
|
||||
} else if param.Position == "av" || param.Position == "guochan" || param.Position == "douyin" || param.Position == "dark" {
|
||||
tagMaps := make(map[string]primitive.ObjectID)
|
||||
var err error
|
||||
if len(tags) > 0 {
|
||||
tagList := make([]string, 0)
|
||||
for k, _ := range tags {
|
||||
tagList = append(tagList, k)
|
||||
}
|
||||
tagMaps, err = checkInsertVidTags(tagList)
|
||||
if err != nil {
|
||||
log.Error("MovieAddList checkInsertVidTags failed", log.E(err))
|
||||
return hits, err
|
||||
}
|
||||
}
|
||||
users, err := usermod.FindMany(bson.M{"uid": bson.M{"$gt": 300000}}, &options.FindOptions{}, 0, 300)
|
||||
if err != nil {
|
||||
log.Warn("PostAddList FindManyUser failed", log.E(err))
|
||||
return hits, err
|
||||
}
|
||||
failedIds := make([]string, 0)
|
||||
for _, comicsDetail := range movieDetails {
|
||||
hit, oneErr := syncOneMovie(comicsDetail, tagMaps, users, manager, terms)
|
||||
if oneErr != nil {
|
||||
log.Warn("MovieAddList syncOneMovie failed", log.Any("id", comicsDetail.Id), log.E(oneErr))
|
||||
failedIds = append(failedIds, comicsDetail.Id)
|
||||
continue
|
||||
}
|
||||
if hit != nil {
|
||||
hits = append(hits, *hit)
|
||||
}
|
||||
}
|
||||
if len(failedIds) > 0 {
|
||||
return hits, errors.New(fmt.Sprintf("需要同步%d部资源,失败%d,失败Id[%s]", len(param.Ids), len(failedIds), strings.Join(failedIds, ",")))
|
||||
}
|
||||
return hits, nil
|
||||
}
|
||||
return hits, errors.New("该资源暂不支持")
|
||||
}
|
||||
|
||||
func syncOneMovie(movieDetail laosiji.MovieDetailResp, tags map[string]primitive.ObjectID, upUsers []*usermod.User, manager string, terms []string) (*vidser.SensitiveHit, error) {
|
||||
now := time.Now()
|
||||
postList, err := vidmod.GetList(bson.M{"sourceID": bson.M{"$in": []string{movieDetail.Id}}})
|
||||
if err != nil {
|
||||
log.Warn("syncOneMovie GetList failed", log.Any("id", movieDetail.Id), log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
if postList != nil && len(postList) > 0 {
|
||||
h265URL := movieH265SourceURL(movieDetail.Links)
|
||||
if h265URL == "" {
|
||||
return nil, nil
|
||||
}
|
||||
video := postList[0]
|
||||
if err = vidmod.MarkH265Success(video.ID, h265URL); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if webg.Redis != nil {
|
||||
cacheKey := fmt.Sprintf(redisconst.VideoInfoKey(), video.ID.Hex())
|
||||
if _, err = webg.Redis.Del(cacheKey); err != nil {
|
||||
log.Warn("syncOneMovie clear video cache failed",
|
||||
log.Any("id", video.ID),
|
||||
log.Any("cacheKey", cacheKey),
|
||||
log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
vidInfo := vidmod.VideoModel{
|
||||
ID: primitive.NewObjectID(),
|
||||
Title: movieDetail.Name,
|
||||
Content: movieDetail.Description,
|
||||
Tags: make([]primitive.ObjectID, 0),
|
||||
MimeType: "video/mp4",
|
||||
SeriesCover: make([]string, 0),
|
||||
Via: "laosiji",
|
||||
Status: vidmod.CheckPass,
|
||||
Location: primitive.ObjectID{},
|
||||
Actor: movieDetail.Actor,
|
||||
NewUpdatedAt: "laosiji",
|
||||
ReviewAt: now,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
ReviewAccount: manager,
|
||||
VerticalCover: movieDetail.Img_y,
|
||||
}
|
||||
|
||||
if movieDetail.Img_type == "short" && len(movieDetail.Img_y) > 0 {
|
||||
vidInfo.NewsType = vidmod.SHORT
|
||||
vidInfo.Cover = movieDetail.Img_y
|
||||
vidInfo.CoverThumb = movieDetail.Img_y
|
||||
vidInfo.Direction = "vertical"
|
||||
} else {
|
||||
vidInfo.NewsType = vidmod.SP
|
||||
vidInfo.Cover = movieDetail.Img_x
|
||||
vidInfo.CoverThumb = movieDetail.Img_x
|
||||
vidInfo.Direction = "horizontal"
|
||||
}
|
||||
playTime, _ := strconv.Atoi(movieDetail.Duration)
|
||||
vidInfo.PlayTime = uint(playTime)
|
||||
uIndex := rand.Intn(len(upUsers))
|
||||
u := upUsers[uIndex]
|
||||
vidInfo.PublisherID = u.UID
|
||||
if movieDetail.Links != nil && len(movieDetail.Links) > 0 {
|
||||
vidInfo.SourceURL = movieDetail.Links[0].M3u8_url
|
||||
vidInfo.Filename = movieDetail.Links[0].Name
|
||||
vidInfo.PreviewURL = movieDetail.Links[0].Preview_m3u8_url
|
||||
vidInfo.H265Url = movieH265SourceURL(movieDetail.Links)
|
||||
if vidInfo.H265Url != "" {
|
||||
vidInfo.H265Status = vidmod.H265StatusSuccess
|
||||
}
|
||||
}
|
||||
vidInfo.SourceID = movieDetail.Id
|
||||
|
||||
if movieDetail.Tags != nil && len(movieDetail.Tags) > 0 {
|
||||
for _, tag := range movieDetail.Tags {
|
||||
if k, ok := tags[tag.Name]; ok {
|
||||
vidInfo.Tags = append(vidInfo.Tags, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 敏感词命中 → 强制为待审核(WaitingCheck=0)
|
||||
hit := vidser.CheckTextHits(terms, movieDetail.Id, vidInfo.Title, vidInfo.Content, "")
|
||||
if hit != nil {
|
||||
vidInfo.Status = vidmod.WaitingCheck
|
||||
log.Warn("syncOneMovie sensitive hit, forced offline",
|
||||
log.Any("sourceId", hit.SourceID),
|
||||
log.Any("title", hit.Title),
|
||||
log.Any("detail", hit.Detail))
|
||||
}
|
||||
if vidInfo.H265Url == "" && vidInfo.SourceURL != "" && vidInfo.Status == vidmod.CheckPass && vidInfo.NewsType == vidmod.SP {
|
||||
vidInfo.H265Status = vidmod.H265StatusQueued
|
||||
vidInfo.H265QueuedAt = now
|
||||
}
|
||||
if _, err = vidmod.InsertBase(vidInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hit, nil
|
||||
}
|
||||
|
||||
// movieH265SourceURL 返回首个播放链接对应的 H.265 地址。
|
||||
// syncOneMovie 的 H.264 也固定使用 links[0],不能拿后续分集的 H.265 与首集混用。
|
||||
func movieH265SourceURL(links []laosiji.LinkInfo) string {
|
||||
if len(links) == 0 {
|
||||
return ""
|
||||
}
|
||||
return laosiji.MovieM3u8SourcePath(links[0].Hevc_m3u8_url)
|
||||
}
|
||||
|
||||
func checkInsertVidTags(names []string) (data map[string]vidmod.ObjectID, err error) {
|
||||
data = make(map[string]vidmod.ObjectID)
|
||||
tags, err := tagmod.FindOneTagByNames(names)
|
||||
if err != nil {
|
||||
log.Warn("checkInsertVidTags tagmod.FindOneTagByNames", log.E(err), log.Any("name", names))
|
||||
return
|
||||
}
|
||||
for _, tag := range tags {
|
||||
data[tag.TagName] = tag.ID
|
||||
}
|
||||
insertTags := make([]tagmod.Tag, 0)
|
||||
for _, tag := range tags {
|
||||
if _, ok := data[tag.TagName]; !ok {
|
||||
insertTag := tagmod.Tag{
|
||||
ID: primitive.NewObjectID(),
|
||||
TagName: tag.TagName,
|
||||
IsActive: true,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
insertTags = append(insertTags, insertTag)
|
||||
data[tag.TagName] = insertTag.ID
|
||||
}
|
||||
}
|
||||
if len(insertTags) > 0 {
|
||||
err = tagmod.InsertMany(insertTags)
|
||||
if err != nil {
|
||||
log.Warn("checkInsertVidTags InsertMany failed", log.Any("tags", insertTags), log.E(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package laosijiser
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"91porn-server/common/laosiji"
|
||||
)
|
||||
|
||||
func TestMovieH265SourceURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
links []laosiji.LinkInfo
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
links: []laosiji.LinkInfo{
|
||||
{Hevc_m3u8_url: " "},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "does not mix a later episode with first H264 link",
|
||||
links: []laosiji.LinkInfo{
|
||||
{Hevc_m3u8_url: ""},
|
||||
{Hevc_m3u8_url: "https://cdn.example.com/m3m/movie/hevc.m3u8?token=ignored"},
|
||||
{Hevc_m3u8_url: "other.m3u8"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "first link normalized",
|
||||
links: []laosiji.LinkInfo{
|
||||
{Hevc_m3u8_url: "https://cdn.example.com/m3m/movie/hevc.m3u8?token=ignored"},
|
||||
{Hevc_m3u8_url: "other.m3u8"},
|
||||
},
|
||||
want: "laosiji/m3m/movie/hevc.m3u8",
|
||||
},
|
||||
{
|
||||
name: "already normalized",
|
||||
links: []laosiji.LinkInfo{
|
||||
{Hevc_m3u8_url: "laosiji/rk130/hevc/movie/index.m3u8"},
|
||||
},
|
||||
want: "laosiji/rk130/hevc/movie/index.m3u8",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if got := movieH265SourceURL(test.links); got != test.want {
|
||||
t.Fatalf("movieH265SourceURL() = %q, want %q", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user