content: package com.java2nb.novel.core.listener;
  
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.java2nb.novel.core.crawl.CrawlParser;
  import com.java2nb.novel.core.crawl.RuleBean;
  import com.java2nb.novel.entity.Book;
  import com.java2nb.novel.entity.BookIndex;
  import com.java2nb.novel.entity.CrawlSingleTask;
  import com.java2nb.novel.entity.CrawlSource;
  import com.java2nb.novel.service.BookService;
  import com.java2nb.novel.service.CrawlService;
  import com.java2nb.novel.utils.Constants;
  import jakarta.servlet.ServletContext;
  import lombok.RequiredArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
  import org.apache.commons.lang3.time.DateUtils;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.boot.web.servlet.ServletContextInitializer;
  import org.springframework.stereotype.Component;
  
  import java.util.Date;
  import java.util.List;
  import java.util.Map;
  import java.util.concurrent.TimeUnit;
  
  /**
   * @author Administrator
   */
  @Component
  @Slf4j
  @RequiredArgsConstructor
  public class StarterListener implements ServletContextInitializer {
  
      private final BookService bookService;
  
      private final CrawlService crawlService;
  
      private final CrawlParser crawlParser;
  
      @Value("${crawl.update.thread}")
      private int updateThreadCount;
  
      @Override
      public void onStartup(ServletContext servletContext) {
          for (int i = 0; i < updateThreadCount; i++) {
              new Thread(() -> {
                  log.info("程序启动,开始执行自动更新线程。。。");
                  while (true) {
                      try {
                          //1.查询最新目录更新时间在一个月之内的前100条需要更新的数据
                          Date currentDate = new Date();
                          Date startDate = DateUtils.addDays(currentDate, -30);
                          List<Book> bookList;
                          synchronized (this) {
                              bookList = bookService.queryNeedUpdateBook(startDate, 100);
                          }
                          for (Book needUpdateBook : bookList) {
                              try {
                                  //查询爬虫源规则
                                  CrawlSource source = crawlService.queryCrawlSource(needUpdateBook.getCrawlSourceId());
                                  RuleBean ruleBean = new ObjectMapper().readValue(source.getCrawlRule(), RuleBean.class);
                                  //解析小说基本信息
                                  crawlParser.parseBook(ruleBean, needUpdateBook.getCrawlBookId(), book -> {
                                      //这里只做老书更新
                                      book.setId(needUpdateBook.getId());
                                      book.setWordCount(needUpdateBook.getWordCount());
                                      if (needUpdateBook.getPicUrl() != null && needUpdateBook.getPicUrl()
                                          .contains(Constants.LOCAL_PIC_PREFIX)) {
                                          //本地图片则不更新
                                          book.setPicUrl(null);
                                      }
                                      //查询已存在的章节
                                      Map<Integer, BookIndex> existBookIndexMap = bookService.queryExistBookIndexMap(
                                          needUpdateBook.getId());
                                      //解析章节目录
                                      crawlParser.parseBookIndexAndContent(needUpdateBook.getCrawlBookId(), book,
                                          ruleBean, needUpdateBook.getCrawlSourceId(), existBookIndexMap,
                                          chapter -> bookService.updateBookAndIndexAndContent(book,
                                              chapter.getBookIndexList(),
                                              chapter.getBookContentList(), existBookIndexMap), null);
                                  });
                              } catch (Exception e) {
                                  log.error(e.getMessage(), e);
                              }
  
                          }
                          //  休眠10分钟
                          TimeUnit.MINUTES.sleep(10);
                      } catch (Exception e) {
                          log.error(e.getMessage(), e);
                      }
  
                  }
              }).start();
  
  
          }
  
          new Thread(() -> {
              log.info("程序启动,开始执行单本采集任务线程。。。");
              while (true) {
                  CrawlSingleTask task = null;
                  byte crawlStatus = 0;
                  try {
                      //获取采集任务
                      task = crawlService.getCrawlSingleTask();
  
                      if (task != null) {
                          //查询爬虫规则
                          CrawlSource source = crawlService.queryCrawlSource(task.getSourceId());
                          RuleBean ruleBean = new ObjectMapper().readValue(source.getCrawlRule(), RuleBean.class);
                          if (crawlService.parseBookAndSave(task.getCatId(), ruleBean, task.getSourceId(),
                              task.getSourceBookId(), task)) {
                              //采集成功
                              crawlStatus = 1;
                          }
  
                      }
  
                      //休眠1分钟
                      TimeUnit.MINUTES.sleep(1);
  
                  } catch (Exception e) {
                      log.error(e.getMessage(), e);
                  }
  
                  if (task != null) {
                      crawlService.updateCrawlSingleTask(task, crawlStatus);
                  }
  
              }
          }).start();
      }
  }
  