mirror of
https://github.com/jxxghp/MoviePilot-Plugins.git
synced 2026-03-27 10:05:57 +00:00
add CustomIndexer
This commit is contained in:
251
README.md
251
README.md
@@ -147,3 +147,254 @@ class EventType(Enum):
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 5. 如何扩展内建索引器的索引站点?
|
||||
- 通过调用 `SitesHelper().add_indexer(domain: str, indexer: dict)` 方法,新增或修改内建索引器的支持范围,其中`indexer`为站点配置Json,格式示例如下:
|
||||
|
||||
示例一:
|
||||
```json
|
||||
{
|
||||
"id": "nyaa",
|
||||
"name": "Nyaa",
|
||||
"domain": "https://nyaa.si/",
|
||||
"encoding": "UTF-8",
|
||||
"public": true,
|
||||
"proxy": true,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "?f=0&c=0_0&q={keyword}",
|
||||
"method": "get"
|
||||
}
|
||||
]
|
||||
},
|
||||
"browse": {
|
||||
"path": "?p={page}",
|
||||
"start": 1
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrent-list > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"id": {
|
||||
"selector": "a[href*=\"/view/\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": [
|
||||
"\\d+",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"title": {
|
||||
"selector": "td:nth-child(2) > a"
|
||||
},
|
||||
"details": {
|
||||
"selector": "td:nth-child(2) > a",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "td:nth-child(3) > a[href*=\"/download/\"]",
|
||||
"attribute": "href"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"*": 0
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"*": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
示例二:
|
||||
```json
|
||||
{
|
||||
"id": "xxx",
|
||||
"name": "站点名称",
|
||||
"domain": "https://www.xxx.com/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"method": "get"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}",
|
||||
"search_area": 4
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
}
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": 401,
|
||||
"cat": "Movies",
|
||||
"desc": "Movies电影"
|
||||
},
|
||||
{
|
||||
"id": 405,
|
||||
"cat": "Anime",
|
||||
"desc": "Animations动漫"
|
||||
},
|
||||
{
|
||||
"id": 404,
|
||||
"cat": "Documentary",
|
||||
"desc": "Documentaries纪录片"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": 402,
|
||||
"cat": "TV",
|
||||
"desc": "TV Series电视剧"
|
||||
},
|
||||
{
|
||||
"id": 403,
|
||||
"cat": "TV",
|
||||
"desc": "TV Shows综艺"
|
||||
},
|
||||
{
|
||||
"id": 404,
|
||||
"cat": "Documentary",
|
||||
"desc": "Documentaries纪录片"
|
||||
},
|
||||
{
|
||||
"id": 405,
|
||||
"cat": "Anime",
|
||||
"desc": "Animations动漫"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(\"table.torrentname\")"
|
||||
},
|
||||
"fields": {
|
||||
"id": {
|
||||
"selector": "a[href*=\"details.php?id=\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": [
|
||||
"\\d+",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"title_default": {
|
||||
"selector": "a[href*=\"details.php?id=\"]"
|
||||
},
|
||||
"title_optional": {
|
||||
"optional": true,
|
||||
"selector": "a[title][href*=\"details.php?id=\"]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*=\"details.php?id=\"]",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*=\"download.php?id=\"]",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "div.imdb_100 > a",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": [
|
||||
"tt\\d+",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"optional": true
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title",
|
||||
"optional": true
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td:nth-child(2) > table > tr > td.embedded > span[style]",
|
||||
"contents": -1
|
||||
},
|
||||
"labels": {
|
||||
"selector": "td:nth-child(2) > table > tr > td.embedded > span.tags"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- 需要注意的是,如果你没有完成用户认证,通过插件配置进去的索引站点也是无法正常使用的。
|
||||
BIN
icons/spider.png
Normal file
BIN
icons/spider.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -310,5 +310,13 @@
|
||||
"icon": "Element_A.png",
|
||||
"author": "叮叮当",
|
||||
"level": 1
|
||||
},
|
||||
"CustomIndexer": {
|
||||
"name": "自定义索引站点",
|
||||
"description": "修改或扩展内建索引器支持的站点",
|
||||
"version": "1.0",
|
||||
"icon": "spider.png",
|
||||
"author": "jxxghp",
|
||||
"level": 1
|
||||
}
|
||||
}
|
||||
|
||||
154
plugins/customindexer/__init__.py
Normal file
154
plugins/customindexer/__init__.py
Normal file
@@ -0,0 +1,154 @@
|
||||
import base64
|
||||
import json
|
||||
from typing import List, Tuple, Dict, Any
|
||||
|
||||
from app.helper.sites import SitesHelper
|
||||
from app.log import logger
|
||||
from app.plugins import _PluginBase
|
||||
|
||||
|
||||
class CustomIndexer(_PluginBase):
|
||||
# 插件名称
|
||||
plugin_name = "自定义索引站点"
|
||||
# 插件描述
|
||||
plugin_desc = "修改或扩展内建索引器支持的站点。"
|
||||
# 插件图标
|
||||
plugin_icon = "spider.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.0"
|
||||
# 插件作者
|
||||
plugin_author = "jxxghp"
|
||||
# 作者主页
|
||||
author_url = "https://github.com/jxxghp"
|
||||
# 插件配置项ID前缀
|
||||
plugin_config_prefix = "customindexer_"
|
||||
# 加载顺序
|
||||
plugin_order = 30
|
||||
# 可使用的用户级别
|
||||
auth_level = 2
|
||||
|
||||
# 私有属性
|
||||
siteshelper = None
|
||||
_enabled = False
|
||||
_confstr = ""
|
||||
|
||||
def init_plugin(self, config: dict = None):
|
||||
self.siteshelper = SitesHelper()
|
||||
# 读取配置
|
||||
if config:
|
||||
self._enabled = config.get("enabled")
|
||||
self._confstr = config.get("confstr") or ""
|
||||
if self._enabled and self._confstr:
|
||||
# 配置生效
|
||||
indexers = self._confstr.split("\n")
|
||||
for indexer in indexers:
|
||||
if not indexer:
|
||||
continue
|
||||
try:
|
||||
[domain, jsonstr] = indexer.split("|")
|
||||
if not domain or not jsonstr:
|
||||
continue
|
||||
jsonstr = base64.b64decode(jsonstr).decode('utf-8')
|
||||
self.siteshelper.add_indexer(domain, json.loads(jsonstr))
|
||||
except Exception as err:
|
||||
logger.error(f"自定义索引站点配置错误:{err}")
|
||||
self.systemmessage.put(f"自定义索引站点配置错误:{err}")
|
||||
continue
|
||||
|
||||
def get_state(self) -> bool:
|
||||
return self._enabled
|
||||
|
||||
@staticmethod
|
||||
def get_command() -> List[Dict[str, Any]]:
|
||||
pass
|
||||
|
||||
def get_api(self) -> List[Dict[str, Any]]:
|
||||
pass
|
||||
|
||||
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
|
||||
"""
|
||||
拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构
|
||||
"""
|
||||
return [
|
||||
{
|
||||
'component': 'VForm',
|
||||
'content': [
|
||||
{
|
||||
'component': 'VRow',
|
||||
'content': [
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
'md': 6
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VSwitch',
|
||||
'props': {
|
||||
'model': 'enabled',
|
||||
'label': '启用插件',
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VRow',
|
||||
'content': [
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VTextarea',
|
||||
'props': {
|
||||
'model': 'confstr',
|
||||
'label': '站点索引配置',
|
||||
'rows': 10,
|
||||
'placeholder': '一行一个站点,配置格式:域名|配置json的base64编码(utf-8)'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VRow',
|
||||
'content': [
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VAlert',
|
||||
'props': {
|
||||
'type': 'info',
|
||||
'variant': 'tonal',
|
||||
'text': '域名只取后两段,如:www.baidu.com,只需填写baidu.com;索引配置Json需使用utf-8进行base64编码;如站点域名已被内建索引器支持,则会覆盖内建配置;索引配置的格式请参考README。'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
], {
|
||||
"enabled": False,
|
||||
"hosts": ""
|
||||
}
|
||||
|
||||
def get_page(self) -> List[dict]:
|
||||
pass
|
||||
|
||||
def stop_service(self):
|
||||
"""
|
||||
退出插件
|
||||
"""
|
||||
pass
|
||||
Reference in New Issue
Block a user