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 }