From 2f7fcbc05681b2f6d5c13574adc607f6e0a87862 Mon Sep 17 00:00:00 2001
From: LuckyPuppy514 <122154133@qq.com>
Date: Fri, 7 Apr 2023 23:11:37 +0800
Subject: [PATCH] =?UTF-8?q?v3.0.3=20=E6=A0=87=E9=A2=98=E5=8C=B9=E9=85=8D?=
=?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
.../java/com/lckp/jproxy/Application.java | 58 +-
.../com/lckp/jproxy/model/FormatResult.java | 30 +
.../jproxy/service/ISonarrTitleService.java | 197 +++---
.../impl/SonarrExampleServiceImpl.java | 249 +++----
.../impl/SonarrIndexerServiceImpl.java | 306 ++++-----
.../service/impl/SonarrTitleServiceImpl.java | 636 +++++++++---------
.../java/com/lckp/jproxy/util/FormatUtil.java | 309 ++++-----
.../resources/database/changelog/v3.0.3.sql | 5 +
.../resources/rule/radarr@LuckyPuppy514.json | 2 +-
.../resources/rule/sonarr@LuckyPuppy514.json | 2 +-
.../com/lckp/jproxy/ApplicationTests.java | 32 +-
12 files changed, 941 insertions(+), 887 deletions(-)
create mode 100644 src/main/java/com/lckp/jproxy/model/FormatResult.java
create mode 100644 src/main/resources/database/changelog/v3.0.3.sql
diff --git a/pom.xml b/pom.xml
index 1efa28a..b2207a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
com.lckp
jproxy
- 3.0.2
+ 3.0.3
JProxy
介于 Sonarr/Radarr 和 Jackett/Prowlarr 之间的代理,主要用于优化查询和提升识别率
diff --git a/src/main/java/com/lckp/jproxy/Application.java b/src/main/java/com/lckp/jproxy/Application.java
index 275d6f8..0e6e457 100644
--- a/src/main/java/com/lckp/jproxy/Application.java
+++ b/src/main/java/com/lckp/jproxy/Application.java
@@ -1,29 +1,29 @@
-package com.lckp.jproxy;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.web.servlet.ServletComponentScan;
-import org.springframework.cache.annotation.EnableCaching;
-import org.springframework.context.annotation.EnableAspectJAutoProxy;
-
-/**
- *
- *
- * 主类
- *
- *
- * @author LuckyPuppy514
- * @date 2023-03-04
- */
-@SpringBootApplication
-@MapperScan("com.lckp.jproxy.mapper")
-@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
-@ServletComponentScan
-@EnableCaching
-public class Application {
-
- public static void main(String[] args) {
- SpringApplication.run(Application.class, args);
- }
-}
+package com.lckp.jproxy;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+/**
+ *
+ *
+ * 主类
+ *
+ *
+ * @author LuckyPuppy514
+ * @date 2023-03-04
+ */
+@SpringBootApplication
+@MapperScan("com.lckp.jproxy.mapper")
+@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
+@ServletComponentScan
+@EnableCaching
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/src/main/java/com/lckp/jproxy/model/FormatResult.java b/src/main/java/com/lckp/jproxy/model/FormatResult.java
new file mode 100644
index 0000000..b3d1485
--- /dev/null
+++ b/src/main/java/com/lckp/jproxy/model/FormatResult.java
@@ -0,0 +1,30 @@
+package com.lckp.jproxy.model;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 格式化结果
+ *
+ *
+ * @author LuckyPuppy514
+ * @date 2023-04-07
+ */
+@Getter
+@Setter
+public class FormatResult implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * 格式化结果
+ */
+ private String formatText;
+
+ /*
+ * 剩余信息
+ */
+ private String restText;
+}
diff --git a/src/main/java/com/lckp/jproxy/service/ISonarrTitleService.java b/src/main/java/com/lckp/jproxy/service/ISonarrTitleService.java
index 58499ef..15a9ab5 100644
--- a/src/main/java/com/lckp/jproxy/service/ISonarrTitleService.java
+++ b/src/main/java/com/lckp/jproxy/service/ISonarrTitleService.java
@@ -1,98 +1,99 @@
-package com.lckp.jproxy.service;
-
-import java.util.List;
-import java.util.Map;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.lckp.jproxy.entity.SonarrRule;
-import com.lckp.jproxy.entity.SonarrTitle;
-import com.lckp.jproxy.model.request.SonarrTitleQueryRequest;
-
-/**
- *
- * SonarrTitle 服务类
- *
- *
- * @author LuckyPuppy514
- * @since 2023-03-19
- */
-public interface ISonarrTitleService extends IService {
- /**
- *
- * 同步
- *
- * boolean
- */
- public boolean sync();
-
- /**
- *
- * 查询需要同步 TMDB 标题的 tvdbId
- *
- * @return List
- */
- public List queryNeedSyncTmdbTitle();
-
- /**
- *
- * 根据标题查询
- *
- * @param title
- * @return SonarrTitle
- */
- public SonarrTitle queryByTitle(String title);
-
- /**
- *
- * 查询所有标题
- *
- * @return List
- */
- public List queryAll();
-
- /**
- *
- * 格式化标题
- *
- * @param text
- * @param format
- * @param cleanTitleRegex
- * @param sonarrRuleList
- * @param sonarrTitleList
- * @return String
- */
- public String formatTitle(String text, String format, String cleanTitleRegex,
- List sonarrRuleList, List sonarrTitleList);
-
- /**
- *
- * 格式化
- *
- * @param text
- * @param format
- * @param tokenRuleMap
- * @return String
- */
- public String format(String text, String format, Map> tokenRuleMap);
-
- /**
- *
- * 格式化并缓存
- *
- * @param text
- * @param format
- * @param tokenRuleMap
- * @return String
- */
- public String formatWithCache(String text, String format, Map> tokenRuleMap);
-
- /**
- *
- * 分页查询
- *
- * @param request
- * @return IPage
- */
- public IPage query(SonarrTitleQueryRequest request);
-}
+package com.lckp.jproxy.service;
+
+import java.util.List;
+import java.util.Map;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.lckp.jproxy.entity.SonarrRule;
+import com.lckp.jproxy.entity.SonarrTitle;
+import com.lckp.jproxy.model.FormatResult;
+import com.lckp.jproxy.model.request.SonarrTitleQueryRequest;
+
+/**
+ *
+ * SonarrTitle 服务类
+ *
+ *
+ * @author LuckyPuppy514
+ * @since 2023-03-19
+ */
+public interface ISonarrTitleService extends IService {
+ /**
+ *
+ * 同步
+ *
+ * boolean
+ */
+ public boolean sync();
+
+ /**
+ *
+ * 查询需要同步 TMDB 标题的 tvdbId
+ *
+ * @return List
+ */
+ public List queryNeedSyncTmdbTitle();
+
+ /**
+ *
+ * 根据标题查询
+ *
+ * @param title
+ * @return SonarrTitle
+ */
+ public SonarrTitle queryByTitle(String title);
+
+ /**
+ *
+ * 查询所有标题
+ *
+ * @return List
+ */
+ public List queryAll();
+
+ /**
+ *
+ * 格式化标题
+ *
+ * @param text
+ * @param format
+ * @param cleanTitleRegex
+ * @param sonarrRuleList
+ * @param sonarrTitleList
+ * @return FormatResult
+ */
+ public FormatResult formatTitle(String text, String format, String cleanTitleRegex,
+ List sonarrRuleList, List sonarrTitleList);
+
+ /**
+ *
+ * 格式化
+ *
+ * @param text
+ * @param format
+ * @param tokenRuleMap
+ * @return String
+ */
+ public String format(String text, String format, Map> tokenRuleMap);
+
+ /**
+ *
+ * 格式化并缓存
+ *
+ * @param text
+ * @param format
+ * @param tokenRuleMap
+ * @return String
+ */
+ public String formatWithCache(String text, String format, Map> tokenRuleMap);
+
+ /**
+ *
+ * 分页查询
+ *
+ * @param request
+ * @return IPage
+ */
+ public IPage query(SonarrTitleQueryRequest request);
+}
diff --git a/src/main/java/com/lckp/jproxy/service/impl/SonarrExampleServiceImpl.java b/src/main/java/com/lckp/jproxy/service/impl/SonarrExampleServiceImpl.java
index 69f89e5..b537caa 100644
--- a/src/main/java/com/lckp/jproxy/service/impl/SonarrExampleServiceImpl.java
+++ b/src/main/java/com/lckp/jproxy/service/impl/SonarrExampleServiceImpl.java
@@ -1,124 +1,125 @@
-package com.lckp.jproxy.service.impl;
-
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.aop.framework.AopContext;
-import org.springframework.context.MessageSource;
-import org.springframework.stereotype.Service;
-
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.lckp.jproxy.constant.Messages;
-import com.lckp.jproxy.constant.SystemConfigKey;
-import com.lckp.jproxy.constant.TableField;
-import com.lckp.jproxy.constant.Token;
-import com.lckp.jproxy.constant.ValidStatus;
-import com.lckp.jproxy.entity.SonarrExample;
-import com.lckp.jproxy.entity.SonarrRule;
-import com.lckp.jproxy.entity.SonarrTitle;
-import com.lckp.jproxy.mapper.SonarrExampleMapper;
-import com.lckp.jproxy.model.request.SonarrExampleQueryRequest;
-import com.lckp.jproxy.service.ISonarrExampleService;
-import com.lckp.jproxy.service.ISonarrRuleService;
-import com.lckp.jproxy.service.ISonarrTitleService;
-import com.lckp.jproxy.service.ISystemConfigService;
-import com.lckp.jproxy.util.FormatUtil;
-
-import lombok.RequiredArgsConstructor;
-
-/**
- *
- * SonarrExample 服务实现类
- *
- *
- * @author LuckyPuppy514
- * @since 2023-03-30
- */
-@Service
-@RequiredArgsConstructor
-public class SonarrExampleServiceImpl extends ServiceImpl
- implements ISonarrExampleService {
-
- private final ISystemConfigService systemConfigService;
-
- private final ISonarrRuleService sonarrRuleService;
-
- private final ISonarrTitleService sonarrTitleService;
-
- private final MessageSource messageSource;
-
- private final ISonarrExampleService proxy() {
- return (ISonarrExampleService) AopContext.currentProxy();
- }
-
- /**
- * @param request
- * @return
- * @see com.lckp.jproxy.service.ISonarrExampleService#query(com.lckp.jproxy.model.request.SonarrExampleQueryRequest)
- */
- @Override
- public IPage query(SonarrExampleQueryRequest request, Locale locale) {
- QueryWrapper wrapper = new QueryWrapper<>();
- if (StringUtils.isNotBlank(request.getOriginalText())) {
- wrapper.like(TableField.ORIGINAL_TEXT, request.getOriginalText().trim());
- }
- wrapper.orderByDesc(TableField.UPDATE_TIME);
- Page result = request.mybatisPlusPage();
- List resultList = null;
- if (request.getValidStatus() == null) {
- result = page(request.mybatisPlusPage(), wrapper);
- resultList = result.getRecords();
- } else {
- resultList = proxy().list(wrapper);
- }
- if (!resultList.isEmpty()) {
- String format = systemConfigService.queryValueByKey(SystemConfigKey.SONARR_INDEXER_FORMAT);
- String cleanTitleRegex = systemConfigService.queryValueByKey(SystemConfigKey.CLEAN_TITLE_REGEX);
- Map> tokenRuleMap = new ConcurrentHashMap<>();
- Matcher matcher = Pattern.compile(Token.REGEX).matcher(format);
- while (matcher.find()) {
- String token = matcher.group(1);
- tokenRuleMap.put(token, sonarrRuleService.query(token));
- }
- List sonarrTitleList = sonarrTitleService.queryAll();
- for (SonarrExample sonarrExample : resultList) {
- sonarrExample.setFormatText(sonarrExample.getOriginalText());
- sonarrExample.setValidStatus(ValidStatus.INVALID.getCode());
- String formatText = sonarrTitleService.formatTitle(sonarrExample.getOriginalText(), format,
- cleanTitleRegex, tokenRuleMap.get(Token.TITLE), sonarrTitleList);
- if (formatText.contains("{" + Token.TITLE + "}")) {
- formatText = FormatUtil.replaceToken(Token.TITLE,
- messageSource.getMessage(Messages.EXAMPLE_MATCH_TITLE_FAIL, null, locale),
- formatText);
- }
- formatText = sonarrTitleService.format(sonarrExample.getOriginalText(), formatText,
- tokenRuleMap);
- sonarrExample.setFormatText(formatText);
- if (!sonarrExample.getOriginalText().equals(sonarrExample.getFormatText())) {
- sonarrExample.setValidStatus(ValidStatus.VALID.getCode());
- }
- }
- }
- // 手动分页
- if (request.getValidStatus() != null && !resultList.isEmpty()) {
- resultList = resultList.stream()
- .filter(example -> request.getValidStatus().equals(example.getValidStatus())).toList();
- result.setTotal(resultList.size());
- result.setPages((long) Math.ceil(result.getTotal() / 1.0 / result.getSize()));
- int si = (int) ((result.getCurrent() - 1) * result.getSize());
- int ei = (int) (si + result.getSize());
- ei = ei <= resultList.size() ? ei : resultList.size();
- result.setRecords((resultList.subList(si, ei)));
- }
- return result;
- }
-
-}
+package com.lckp.jproxy.service.impl;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.aop.framework.AopContext;
+import org.springframework.context.MessageSource;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.lckp.jproxy.constant.Messages;
+import com.lckp.jproxy.constant.SystemConfigKey;
+import com.lckp.jproxy.constant.TableField;
+import com.lckp.jproxy.constant.Token;
+import com.lckp.jproxy.constant.ValidStatus;
+import com.lckp.jproxy.entity.SonarrExample;
+import com.lckp.jproxy.entity.SonarrRule;
+import com.lckp.jproxy.entity.SonarrTitle;
+import com.lckp.jproxy.mapper.SonarrExampleMapper;
+import com.lckp.jproxy.model.FormatResult;
+import com.lckp.jproxy.model.request.SonarrExampleQueryRequest;
+import com.lckp.jproxy.service.ISonarrExampleService;
+import com.lckp.jproxy.service.ISonarrRuleService;
+import com.lckp.jproxy.service.ISonarrTitleService;
+import com.lckp.jproxy.service.ISystemConfigService;
+import com.lckp.jproxy.util.FormatUtil;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ *
+ * SonarrExample 服务实现类
+ *
+ *
+ * @author LuckyPuppy514
+ * @since 2023-03-30
+ */
+@Service
+@RequiredArgsConstructor
+public class SonarrExampleServiceImpl extends ServiceImpl
+ implements ISonarrExampleService {
+
+ private final ISystemConfigService systemConfigService;
+
+ private final ISonarrRuleService sonarrRuleService;
+
+ private final ISonarrTitleService sonarrTitleService;
+
+ private final MessageSource messageSource;
+
+ private final ISonarrExampleService proxy() {
+ return (ISonarrExampleService) AopContext.currentProxy();
+ }
+
+ /**
+ * @param request
+ * @return
+ * @see com.lckp.jproxy.service.ISonarrExampleService#query(com.lckp.jproxy.model.request.SonarrExampleQueryRequest)
+ */
+ @Override
+ public IPage query(SonarrExampleQueryRequest request, Locale locale) {
+ QueryWrapper wrapper = new QueryWrapper<>();
+ if (StringUtils.isNotBlank(request.getOriginalText())) {
+ wrapper.like(TableField.ORIGINAL_TEXT, request.getOriginalText().trim());
+ }
+ wrapper.orderByDesc(TableField.UPDATE_TIME);
+ Page result = request.mybatisPlusPage();
+ List resultList = null;
+ if (request.getValidStatus() == null) {
+ result = page(request.mybatisPlusPage(), wrapper);
+ resultList = result.getRecords();
+ } else {
+ resultList = proxy().list(wrapper);
+ }
+ if (!resultList.isEmpty()) {
+ String format = systemConfigService.queryValueByKey(SystemConfigKey.SONARR_INDEXER_FORMAT);
+ String cleanTitleRegex = systemConfigService.queryValueByKey(SystemConfigKey.CLEAN_TITLE_REGEX);
+ Map> tokenRuleMap = new ConcurrentHashMap<>();
+ Matcher matcher = Pattern.compile(Token.REGEX).matcher(format);
+ while (matcher.find()) {
+ String token = matcher.group(1);
+ tokenRuleMap.put(token, sonarrRuleService.query(token));
+ }
+ List sonarrTitleList = sonarrTitleService.queryAll();
+ for (SonarrExample sonarrExample : resultList) {
+ sonarrExample.setFormatText(sonarrExample.getOriginalText());
+ sonarrExample.setValidStatus(ValidStatus.INVALID.getCode());
+ FormatResult formatResult = sonarrTitleService.formatTitle(sonarrExample.getOriginalText(),
+ format, cleanTitleRegex, tokenRuleMap.get(Token.TITLE), sonarrTitleList);
+ String formatText = formatResult.getFormatText();
+ if (formatText.contains("{" + Token.TITLE + "}")) {
+ formatText = FormatUtil.replaceToken(Token.TITLE,
+ messageSource.getMessage(Messages.EXAMPLE_MATCH_TITLE_FAIL, null, locale),
+ formatText);
+ }
+ formatText = sonarrTitleService.format(formatResult.getRestText(), formatText, tokenRuleMap);
+ sonarrExample.setFormatText(formatText);
+ if (!sonarrExample.getOriginalText().equals(sonarrExample.getFormatText())) {
+ sonarrExample.setValidStatus(ValidStatus.VALID.getCode());
+ }
+ }
+ }
+ // 手动分页
+ if (request.getValidStatus() != null && !resultList.isEmpty()) {
+ resultList = resultList.stream()
+ .filter(example -> request.getValidStatus().equals(example.getValidStatus())).toList();
+ result.setTotal(resultList.size());
+ result.setPages((long) Math.ceil(result.getTotal() / 1.0 / result.getSize()));
+ int si = (int) ((result.getCurrent() - 1) * result.getSize());
+ int ei = (int) (si + result.getSize());
+ ei = ei <= resultList.size() ? ei : resultList.size();
+ result.setRecords((resultList.subList(si, ei)));
+ }
+ return result;
+ }
+
+}
diff --git a/src/main/java/com/lckp/jproxy/service/impl/SonarrIndexerServiceImpl.java b/src/main/java/com/lckp/jproxy/service/impl/SonarrIndexerServiceImpl.java
index b3b968c..c2b14b1 100644
--- a/src/main/java/com/lckp/jproxy/service/impl/SonarrIndexerServiceImpl.java
+++ b/src/main/java/com/lckp/jproxy/service/impl/SonarrIndexerServiceImpl.java
@@ -1,152 +1,154 @@
-package com.lckp.jproxy.service.impl;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.dom4j.Document;
-import org.dom4j.DocumentException;
-import org.dom4j.DocumentHelper;
-import org.dom4j.Element;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-
-import com.lckp.jproxy.constant.ApiField;
-import com.lckp.jproxy.constant.CacheName;
-import com.lckp.jproxy.constant.SystemConfigKey;
-import com.lckp.jproxy.constant.TableField;
-import com.lckp.jproxy.constant.Token;
-import com.lckp.jproxy.entity.SonarrRule;
-import com.lckp.jproxy.entity.SonarrTitle;
-import com.lckp.jproxy.entity.TmdbTitle;
-import com.lckp.jproxy.service.ISonarrIndexerService;
-import com.lckp.jproxy.service.ISonarrRuleService;
-import com.lckp.jproxy.service.ISonarrTitleService;
-import com.lckp.jproxy.service.ISystemConfigService;
-import com.lckp.jproxy.service.ITmdbTitleService;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- *
- * Sonarr 索引器服务实现类
- *
- *
- * @author LuckyPuppy514
- * @date 2023-03-20
- */
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class SonarrIndexerServiceImpl extends IndexerServiceImpl implements ISonarrIndexerService {
-
- protected final ISonarrTitleService sonarrTitleService;
-
- protected final ISonarrRuleService sonarrRuleService;
-
- protected final ITmdbTitleService tmdbTitleService;
-
- protected final ISystemConfigService systemConfigService;
-
- /**
- *
- * @param title
- * @return
- * @see com.lckp.jproxy.service.impl.IndexerServiceImpl#getSearchTitle(java.lang.String)
- */
- @Override
- @Cacheable(cacheNames = CacheName.SONARR_SEARCH_TITLE, key = "#title")
- public List getSearchTitle(String title) {
- List searchTitleList = new ArrayList<>();
- SonarrTitle sonarrTitle = sonarrTitleService.queryByTitle(title);
- if (sonarrTitle == null) {
- sonarrTitle = syncAndGetSonarrTitle(title);
- }
- searchTitleList.add(sonarrTitle.getTitle());
- // 主标题追加 TMDB 标题
- if (Integer.valueOf(0).equals(sonarrTitle.getSno())) {
- List tmdbTitleList = tmdbTitleService.query()
- .eq(TableField.TVDB_ID, sonarrTitle.getTvdbId()).list();
- for (TmdbTitle tmdbTitle : tmdbTitleList) {
- searchTitleList.add(tmdbTitle.getTitle());
- }
- }
- return searchTitleList;
- }
-
- /**
- * @param xml
- * @return
- * @see com.lckp.jproxy.service.ISonarrIndexerService#executeFormatRule(java.lang.String)
- */
- @Override
- public String executeFormatRule(String xml) {
- if (StringUtils.isBlank(xml) || !xml.contains("<" + ApiField.INDEXER_ITEM + ">")) {
- return xml;
- }
- try {
- String format = systemConfigService.queryValueByKey(SystemConfigKey.SONARR_INDEXER_FORMAT);
- Map> tokenRuleMap = new ConcurrentHashMap<>();
- Matcher matcher = Pattern.compile(Token.REGEX).matcher(format);
- while (matcher.find()) {
- String token = matcher.group(1);
- tokenRuleMap.put(token, sonarrRuleService.query(token));
- }
- if (!tokenRuleMap.containsKey(Token.TITLE)) {
- return xml;
- }
- String cleanTitleRegex = systemConfigService.queryValueByKey(SystemConfigKey.CLEAN_TITLE_REGEX);
- List sonarrTitleList = sonarrTitleService.queryAll();
- Document document = DocumentHelper.parseText(xml);
- Element root = document.getRootElement();
- Element channel = root.element(ApiField.INDEXER_CHANNEL);
- for (Iterator items = channel.elementIterator(ApiField.INDEXER_ITEM); items.hasNext();) {
- Element item = items.next();
- Element titleElement = item.element(ApiField.INDEXER_TITLE);
- String text = titleElement.getText();
- String newText = sonarrTitleService.formatTitle(text, format, cleanTitleRegex,
- tokenRuleMap.get(Token.TITLE), sonarrTitleList);
- if (newText.contains("{" + Token.TITLE + "}")) {
- log.debug("索引器格式化失败:{} ==> 未匹配到标题", text);
- continue;
- }
- newText = sonarrTitleService.format(text, newText, tokenRuleMap);
- titleElement.setText(newText);
- log.debug("索引器格式化:{} ==> {}", text, newText);
- }
- return document.asXML();
- } catch (DocumentException e) {
- log.error("xml 解析出错:{}", e);
- }
- return xml;
- }
-
- /**
- *
- * 同步后再次获取 Sonarr 标题
- *
- * @param title
- * @return SonarrTitle
- */
- private synchronized SonarrTitle syncAndGetSonarrTitle(String title) {
- SonarrTitle sonarrTitle = sonarrTitleService.queryByTitle(title);
- if (sonarrTitle == null) {
- sonarrTitleService.sync();
- sonarrTitle = sonarrTitleService.queryByTitle(title);
- if (sonarrTitle == null) {
- log.error("找不到匹配的标题:{}", title);
- sonarrTitle = new SonarrTitle();
- sonarrTitle.setTitle(title);
- } else {
- tmdbTitleService.sync(sonarrTitleService.queryNeedSyncTmdbTitle());
- }
- }
- return sonarrTitle;
- }
-}
+package com.lckp.jproxy.service.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import com.lckp.jproxy.constant.ApiField;
+import com.lckp.jproxy.constant.CacheName;
+import com.lckp.jproxy.constant.SystemConfigKey;
+import com.lckp.jproxy.constant.TableField;
+import com.lckp.jproxy.constant.Token;
+import com.lckp.jproxy.entity.SonarrRule;
+import com.lckp.jproxy.entity.SonarrTitle;
+import com.lckp.jproxy.entity.TmdbTitle;
+import com.lckp.jproxy.model.FormatResult;
+import com.lckp.jproxy.service.ISonarrIndexerService;
+import com.lckp.jproxy.service.ISonarrRuleService;
+import com.lckp.jproxy.service.ISonarrTitleService;
+import com.lckp.jproxy.service.ISystemConfigService;
+import com.lckp.jproxy.service.ITmdbTitleService;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ *
+ * Sonarr 索引器服务实现类
+ *
+ *
+ * @author LuckyPuppy514
+ * @date 2023-03-20
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class SonarrIndexerServiceImpl extends IndexerServiceImpl implements ISonarrIndexerService {
+
+ protected final ISonarrTitleService sonarrTitleService;
+
+ protected final ISonarrRuleService sonarrRuleService;
+
+ protected final ITmdbTitleService tmdbTitleService;
+
+ protected final ISystemConfigService systemConfigService;
+
+ /**
+ *
+ * @param title
+ * @return
+ * @see com.lckp.jproxy.service.impl.IndexerServiceImpl#getSearchTitle(java.lang.String)
+ */
+ @Override
+ @Cacheable(cacheNames = CacheName.SONARR_SEARCH_TITLE, key = "#title")
+ public List getSearchTitle(String title) {
+ List searchTitleList = new ArrayList<>();
+ SonarrTitle sonarrTitle = sonarrTitleService.queryByTitle(title);
+ if (sonarrTitle == null) {
+ sonarrTitle = syncAndGetSonarrTitle(title);
+ }
+ searchTitleList.add(sonarrTitle.getTitle());
+ // 主标题追加 TMDB 标题
+ if (Integer.valueOf(0).equals(sonarrTitle.getSno())) {
+ List tmdbTitleList = tmdbTitleService.query()
+ .eq(TableField.TVDB_ID, sonarrTitle.getTvdbId()).list();
+ for (TmdbTitle tmdbTitle : tmdbTitleList) {
+ searchTitleList.add(tmdbTitle.getTitle());
+ }
+ }
+ return searchTitleList;
+ }
+
+ /**
+ * @param xml
+ * @return
+ * @see com.lckp.jproxy.service.ISonarrIndexerService#executeFormatRule(java.lang.String)
+ */
+ @Override
+ public String executeFormatRule(String xml) {
+ if (StringUtils.isBlank(xml) || !xml.contains("<" + ApiField.INDEXER_ITEM + ">")) {
+ return xml;
+ }
+ try {
+ String format = systemConfigService.queryValueByKey(SystemConfigKey.SONARR_INDEXER_FORMAT);
+ Map> tokenRuleMap = new ConcurrentHashMap<>();
+ Matcher matcher = Pattern.compile(Token.REGEX).matcher(format);
+ while (matcher.find()) {
+ String token = matcher.group(1);
+ tokenRuleMap.put(token, sonarrRuleService.query(token));
+ }
+ if (!tokenRuleMap.containsKey(Token.TITLE)) {
+ return xml;
+ }
+ String cleanTitleRegex = systemConfigService.queryValueByKey(SystemConfigKey.CLEAN_TITLE_REGEX);
+ List sonarrTitleList = sonarrTitleService.queryAll();
+ Document document = DocumentHelper.parseText(xml);
+ Element root = document.getRootElement();
+ Element channel = root.element(ApiField.INDEXER_CHANNEL);
+ for (Iterator items = channel.elementIterator(ApiField.INDEXER_ITEM); items.hasNext();) {
+ Element item = items.next();
+ Element titleElement = item.element(ApiField.INDEXER_TITLE);
+ String text = titleElement.getText();
+ FormatResult formatResult = sonarrTitleService.formatTitle(text, format, cleanTitleRegex,
+ tokenRuleMap.get(Token.TITLE), sonarrTitleList);
+ String formatText = formatResult.getFormatText();
+ if (formatText.contains("{" + Token.TITLE + "}")) {
+ log.debug("索引器格式化失败:{} ==> 未匹配到标题", text);
+ continue;
+ }
+ formatText = sonarrTitleService.format(formatResult.getRestText(), formatText, tokenRuleMap);
+ titleElement.setText(formatText);
+ log.debug("索引器格式化:{} ==> {}", text, formatText);
+ }
+ return document.asXML();
+ } catch (DocumentException e) {
+ log.error("xml 解析出错:{}", e);
+ }
+ return xml;
+ }
+
+ /**
+ *
+ * 同步后再次获取 Sonarr 标题
+ *
+ * @param title
+ * @return SonarrTitle
+ */
+ private synchronized SonarrTitle syncAndGetSonarrTitle(String title) {
+ SonarrTitle sonarrTitle = sonarrTitleService.queryByTitle(title);
+ if (sonarrTitle == null) {
+ sonarrTitleService.sync();
+ sonarrTitle = sonarrTitleService.queryByTitle(title);
+ if (sonarrTitle == null) {
+ log.error("找不到匹配的标题:{}", title);
+ sonarrTitle = new SonarrTitle();
+ sonarrTitle.setTitle(title);
+ } else {
+ tmdbTitleService.sync(sonarrTitleService.queryNeedSyncTmdbTitle());
+ }
+ }
+ return sonarrTitle;
+ }
+}
diff --git a/src/main/java/com/lckp/jproxy/service/impl/SonarrTitleServiceImpl.java b/src/main/java/com/lckp/jproxy/service/impl/SonarrTitleServiceImpl.java
index 51ee35d..6e3efc4 100644
--- a/src/main/java/com/lckp/jproxy/service/impl/SonarrTitleServiceImpl.java
+++ b/src/main/java/com/lckp/jproxy/service/impl/SonarrTitleServiceImpl.java
@@ -1,315 +1,321 @@
-package com.lckp.jproxy.service.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.aop.framework.AopContext;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.client.RestTemplate;
-
-import com.alibaba.fastjson2.JSON;
-import com.alibaba.fastjson2.JSONArray;
-import com.alibaba.fastjson2.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.lckp.jproxy.constant.ApiField;
-import com.lckp.jproxy.constant.CacheName;
-import com.lckp.jproxy.constant.Common;
-import com.lckp.jproxy.constant.Monitored;
-import com.lckp.jproxy.constant.SystemConfigKey;
-import com.lckp.jproxy.constant.TableField;
-import com.lckp.jproxy.constant.Token;
-import com.lckp.jproxy.entity.SonarrRule;
-import com.lckp.jproxy.entity.SonarrTitle;
-import com.lckp.jproxy.mapper.SonarrTitleMapper;
-import com.lckp.jproxy.model.request.SonarrTitleQueryRequest;
-import com.lckp.jproxy.service.ISonarrTitleService;
-import com.lckp.jproxy.service.ISystemConfigService;
-import com.lckp.jproxy.util.FormatUtil;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- *
- * SonarrTitle 服务实现类
- *
- *
- * @author LuckyPuppy514
- * @since 2023-03-19
- */
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class SonarrTitleServiceImpl extends ServiceImpl
- implements ISonarrTitleService {
-
- private final ISystemConfigService systemConfigService;
-
- private final SonarrTitleMapper sonarrTitleMapper;
-
- private final RedisTemplate